diff options
Diffstat (limited to 'drivers/video/via/viafbdev.c')
-rw-r--r-- | drivers/video/via/viafbdev.c | 186 |
1 files changed, 65 insertions, 121 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 7626325ed7f8..03f98d683205 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -25,7 +25,6 @@ | |||
25 | 25 | ||
26 | #include "global.h" | 26 | #include "global.h" |
27 | 27 | ||
28 | static int MAX_CURS = 32; | ||
29 | static struct fb_var_screeninfo default_var; | 28 | static struct fb_var_screeninfo default_var; |
30 | static char *viafb_name = "Via"; | 29 | static char *viafb_name = "Via"; |
31 | static u32 pseudo_pal[17]; | 30 | static u32 pseudo_pal[17]; |
@@ -856,150 +855,99 @@ static void viafb_imageblit(struct fb_info *info, | |||
856 | 855 | ||
857 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 856 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
858 | { | 857 | { |
859 | u32 temp, xx, yy, bg_col = 0, fg_col = 0; | 858 | struct viafb_par *viapar = info->par; |
860 | int i, j = 0; | 859 | u32 temp, xx, yy, bg_color = 0, fg_color = 0, |
861 | static int hw_cursor; | 860 | chip_name = viapar->shared->chip_info.gfx_chip_name; |
862 | struct viafb_par *p_viafb_par; | 861 | int i, j = 0, cur_size = 64; |
863 | |||
864 | if (viafb_accel) | ||
865 | hw_cursor = 1; | ||
866 | |||
867 | if (!viafb_accel) { | ||
868 | if (hw_cursor) { | ||
869 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | ||
870 | hw_cursor = 0; | ||
871 | } | ||
872 | return -ENODEV; | ||
873 | } | ||
874 | 862 | ||
875 | if ((((struct viafb_par *)(info->par))->iga_path == IGA2) | 863 | if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo) |
876 | && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) | ||
877 | return -ENODEV; | 864 | return -ENODEV; |
878 | 865 | ||
879 | /* When duoview and using lcd , use soft cursor */ | 866 | if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2) |
880 | if (viafb_LCD_ON || (!viafb_SAMM_ON && | ||
881 | viafb_LCD2_ON + viafb_DVI_ON + viafb_CRT_ON == 2)) | ||
882 | return -ENODEV; | 867 | return -ENODEV; |
883 | 868 | ||
884 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | 869 | viafb_show_hw_cursor(info, HW_Cursor_OFF); |
885 | viacursor = *cursor; | ||
886 | 870 | ||
887 | if (cursor->set & FB_CUR_SETHOT) { | 871 | if (cursor->set & FB_CUR_SETHOT) { |
888 | viacursor.hot = cursor->hot; | 872 | temp = (cursor->hot.x << 16) + cursor->hot.y; |
889 | temp = ((viacursor.hot.x) << 16) + viacursor.hot.y; | 873 | writel(temp, viapar->io_virt + VIA_REG_CURSOR_ORG); |
890 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); | ||
891 | } | 874 | } |
892 | 875 | ||
893 | if (cursor->set & FB_CUR_SETPOS) { | 876 | if (cursor->set & FB_CUR_SETPOS) { |
894 | viacursor.image.dx = cursor->image.dx; | ||
895 | viacursor.image.dy = cursor->image.dy; | ||
896 | yy = cursor->image.dy - info->var.yoffset; | 877 | yy = cursor->image.dy - info->var.yoffset; |
897 | xx = cursor->image.dx - info->var.xoffset; | 878 | xx = cursor->image.dx - info->var.xoffset; |
898 | temp = yy & 0xFFFF; | 879 | temp = yy & 0xFFFF; |
899 | temp |= (xx << 16); | 880 | temp |= (xx << 16); |
900 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS); | 881 | writel(temp, viapar->io_virt + VIA_REG_CURSOR_POS); |
901 | } | 882 | } |
902 | 883 | ||
903 | if (cursor->set & FB_CUR_SETSIZE) { | 884 | if (cursor->image.width <= 32 && cursor->image.height <= 32) |
904 | temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | 885 | cur_size = 32; |
886 | else if (cursor->image.width <= 64 && cursor->image.height <= 64) | ||
887 | cur_size = 64; | ||
888 | else { | ||
889 | printk(KERN_WARNING "viafb_cursor: The cursor is too large " | ||
890 | "%dx%d", cursor->image.width, cursor->image.height); | ||
891 | return -ENXIO; | ||
892 | } | ||
905 | 893 | ||
906 | if ((cursor->image.width <= 32) | 894 | if (cursor->set & FB_CUR_SETSIZE) { |
907 | && (cursor->image.height <= 32)) { | 895 | temp = readl(viapar->io_virt + VIA_REG_CURSOR_MODE); |
908 | MAX_CURS = 32; | 896 | if (cur_size == 32) |
909 | temp |= 0x2; | 897 | temp |= 0x2; |
910 | } else if ((cursor->image.width <= 64) | 898 | else |
911 | && (cursor->image.height <= 64)) { | 899 | temp &= ~0x2; |
912 | MAX_CURS = 64; | ||
913 | temp &= 0xFFFFFFFD; | ||
914 | } else { | ||
915 | DEBUG_MSG(KERN_INFO | ||
916 | "The cursor image is biger than 64x64 bits...\n"); | ||
917 | return -ENXIO; | ||
918 | } | ||
919 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
920 | 900 | ||
921 | viacursor.image.height = cursor->image.height; | 901 | writel(temp, viapar->io_virt + VIA_REG_CURSOR_MODE); |
922 | viacursor.image.width = cursor->image.width; | ||
923 | } | 902 | } |
924 | 903 | ||
925 | if (cursor->set & FB_CUR_SETCMAP) { | 904 | if (cursor->set & FB_CUR_SETCMAP) { |
926 | viacursor.image.fg_color = cursor->image.fg_color; | 905 | fg_color = cursor->image.fg_color; |
927 | viacursor.image.bg_color = cursor->image.bg_color; | 906 | bg_color = cursor->image.bg_color; |
928 | 907 | if (chip_name == UNICHROME_CX700 || | |
929 | switch (info->var.bits_per_pixel) { | 908 | chip_name == UNICHROME_VX800) { |
930 | case 8: | 909 | fg_color = |
931 | case 16: | 910 | ((info->cmap.red[fg_color] & 0xFFC0) << 14) | |
932 | case 32: | 911 | ((info->cmap.green[fg_color] & 0xFFC0) << 4) | |
933 | bg_col = | 912 | ((info->cmap.blue[fg_color] & 0xFFC0) >> 6); |
934 | (0xFF << 24) | | 913 | bg_color = |
935 | (((info->cmap.red)[viacursor.image.bg_color] & | 914 | ((info->cmap.red[bg_color] & 0xFFC0) << 14) | |
936 | 0xFF00) << 8) | | 915 | ((info->cmap.green[bg_color] & 0xFFC0) << 4) | |
937 | ((info->cmap.green)[viacursor.image.bg_color] & | 916 | ((info->cmap.blue[bg_color] & 0xFFC0) >> 6); |
938 | 0xFF00) | | 917 | } else { |
939 | (((info->cmap.blue)[viacursor.image.bg_color] & | 918 | fg_color = |
940 | 0xFF00) >> 8); | 919 | ((info->cmap.red[fg_color] & 0xFF00) << 8) | |
941 | fg_col = | 920 | (info->cmap.green[fg_color] & 0xFF00) | |
942 | (0xFF << 24) | | 921 | ((info->cmap.blue[fg_color] & 0xFF00) >> 8); |
943 | (((info->cmap.red)[viacursor.image.fg_color] & | 922 | bg_color = |
944 | 0xFF00) << 8) | | 923 | ((info->cmap.red[bg_color] & 0xFF00) << 8) | |
945 | ((info->cmap.green)[viacursor.image.fg_color] & | 924 | (info->cmap.green[bg_color] & 0xFF00) | |
946 | 0xFF00) | | 925 | ((info->cmap.blue[bg_color] & 0xFF00) >> 8); |
947 | (((info->cmap.blue)[viacursor.image.fg_color] & | ||
948 | 0xFF00) >> 8); | ||
949 | break; | ||
950 | default: | ||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | /* This is indeed a patch for VT3324/VT3353 */ | ||
955 | if (!info->par) | ||
956 | return 0; | ||
957 | p_viafb_par = (struct viafb_par *)info->par; | ||
958 | |||
959 | if ((p_viafb_par->chip_info->gfx_chip_name == | ||
960 | UNICHROME_CX700) || | ||
961 | ((p_viafb_par->chip_info->gfx_chip_name == | ||
962 | UNICHROME_VX800))) { | ||
963 | bg_col = | ||
964 | (((info->cmap.red)[viacursor.image.bg_color] & | ||
965 | 0xFFC0) << 14) | | ||
966 | (((info->cmap.green)[viacursor.image.bg_color] & | ||
967 | 0xFFC0) << 4) | | ||
968 | (((info->cmap.blue)[viacursor.image.bg_color] & | ||
969 | 0xFFC0) >> 6); | ||
970 | fg_col = | ||
971 | (((info->cmap.red)[viacursor.image.fg_color] & | ||
972 | 0xFFC0) << 14) | | ||
973 | (((info->cmap.green)[viacursor.image.fg_color] & | ||
974 | 0xFFC0) << 4) | | ||
975 | (((info->cmap.blue)[viacursor.image.fg_color] & | ||
976 | 0xFFC0) >> 6); | ||
977 | } | 926 | } |
978 | 927 | ||
979 | writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); | 928 | writel(bg_color, viapar->io_virt + VIA_REG_CURSOR_BG); |
980 | writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); | 929 | writel(fg_color, viapar->io_virt + VIA_REG_CURSOR_FG); |
981 | } | 930 | } |
982 | 931 | ||
983 | if (cursor->set & FB_CUR_SETSHAPE) { | 932 | if (cursor->set & FB_CUR_SETSHAPE) { |
984 | struct { | 933 | struct { |
985 | u8 data[CURSOR_SIZE / 8]; | 934 | u8 data[CURSOR_SIZE]; |
986 | u32 bak[CURSOR_SIZE / 32]; | 935 | u32 bak[CURSOR_SIZE / 4]; |
987 | } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); | 936 | } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); |
988 | int size = | 937 | int size = ((cursor->image.width + 7) >> 3) * |
989 | ((viacursor.image.width + 7) >> 3) * | 938 | cursor->image.height; |
990 | viacursor.image.height; | ||
991 | 939 | ||
992 | if (cr_data == NULL) | 940 | if (!cr_data) |
993 | goto out; | 941 | return -ENOMEM; |
994 | 942 | ||
995 | if (MAX_CURS == 32) { | 943 | if (cur_size == 32) { |
996 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | 944 | for (i = 0; i < (CURSOR_SIZE / 4); i++) { |
997 | cr_data->bak[i] = 0x0; | 945 | cr_data->bak[i] = 0x0; |
998 | cr_data->bak[i + 1] = 0xFFFFFFFF; | 946 | cr_data->bak[i + 1] = 0xFFFFFFFF; |
999 | i += 1; | 947 | i += 1; |
1000 | } | 948 | } |
1001 | } else if (MAX_CURS == 64) { | 949 | } else { |
1002 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | 950 | for (i = 0; i < (CURSOR_SIZE / 4); i++) { |
1003 | cr_data->bak[i] = 0x0; | 951 | cr_data->bak[i] = 0x0; |
1004 | cr_data->bak[i + 1] = 0x0; | 952 | cr_data->bak[i + 1] = 0x0; |
1005 | cr_data->bak[i + 2] = 0xFFFFFFFF; | 953 | cr_data->bak[i + 2] = 0xFFFFFFFF; |
@@ -1008,27 +956,27 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1008 | } | 956 | } |
1009 | } | 957 | } |
1010 | 958 | ||
1011 | switch (viacursor.rop) { | 959 | switch (cursor->rop) { |
1012 | case ROP_XOR: | 960 | case ROP_XOR: |
1013 | for (i = 0; i < size; i++) | 961 | for (i = 0; i < size; i++) |
1014 | cr_data->data[i] = viacursor.mask[i]; | 962 | cr_data->data[i] = cursor->mask[i]; |
1015 | break; | 963 | break; |
1016 | case ROP_COPY: | 964 | case ROP_COPY: |
1017 | 965 | ||
1018 | for (i = 0; i < size; i++) | 966 | for (i = 0; i < size; i++) |
1019 | cr_data->data[i] = viacursor.mask[i]; | 967 | cr_data->data[i] = cursor->mask[i]; |
1020 | break; | 968 | break; |
1021 | default: | 969 | default: |
1022 | break; | 970 | break; |
1023 | } | 971 | } |
1024 | 972 | ||
1025 | if (MAX_CURS == 32) { | 973 | if (cur_size == 32) { |
1026 | for (i = 0; i < size; i++) { | 974 | for (i = 0; i < size; i++) { |
1027 | cr_data->bak[j] = (u32) cr_data->data[i]; | 975 | cr_data->bak[j] = (u32) cr_data->data[i]; |
1028 | cr_data->bak[j + 1] = ~cr_data->bak[j]; | 976 | cr_data->bak[j + 1] = ~cr_data->bak[j]; |
1029 | j += 2; | 977 | j += 2; |
1030 | } | 978 | } |
1031 | } else if (MAX_CURS == 64) { | 979 | } else { |
1032 | for (i = 0; i < size; i++) { | 980 | for (i = 0; i < size; i++) { |
1033 | cr_data->bak[j] = (u32) cr_data->data[i]; | 981 | cr_data->bak[j] = (u32) cr_data->data[i]; |
1034 | cr_data->bak[j + 1] = 0x0; | 982 | cr_data->bak[j + 1] = 0x0; |
@@ -1038,14 +986,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1038 | } | 986 | } |
1039 | } | 987 | } |
1040 | 988 | ||
1041 | memcpy(viafbinfo->screen_base + | 989 | memcpy_toio(viafbinfo->screen_base + viapar->shared-> |
1042 | ((struct viafb_par *)(info->par))->cursor_start, | 990 | cursor_vram_addr, cr_data->bak, CURSOR_SIZE); |
1043 | cr_data->bak, CURSOR_SIZE); | ||
1044 | out: | ||
1045 | kfree(cr_data); | 991 | kfree(cr_data); |
1046 | } | 992 | } |
1047 | 993 | ||
1048 | if (viacursor.enable) | 994 | if (cursor->enable) |
1049 | viafb_show_hw_cursor(info, HW_Cursor_ON); | 995 | viafb_show_hw_cursor(info, HW_Cursor_ON); |
1050 | 996 | ||
1051 | return 0; | 997 | return 0; |
@@ -2052,8 +1998,6 @@ static int __devinit via_pci_probe(void) | |||
2052 | viaparinfo->fbmem_free = viaparinfo->memsize; | 1998 | viaparinfo->fbmem_free = viaparinfo->memsize; |
2053 | viaparinfo->fbmem_used = 0; | 1999 | viaparinfo->fbmem_used = 0; |
2054 | if (viafb_accel) { | 2000 | if (viafb_accel) { |
2055 | viaparinfo1->cursor_start = | ||
2056 | viaparinfo->cursor_start - viafb_second_offset; | ||
2057 | viaparinfo1->VQ_start = viaparinfo->VQ_start - | 2001 | viaparinfo1->VQ_start = viaparinfo->VQ_start - |
2058 | viafb_second_offset; | 2002 | viafb_second_offset; |
2059 | viaparinfo1->VQ_end = viaparinfo->VQ_end - | 2003 | viaparinfo1->VQ_end = viaparinfo->VQ_end - |