aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2009-09-22 19:47:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:53 -0400
commit5016af53ebbd1450c2656c94dfbd1dad15c19f60 (patch)
tree96c6ec0f311d0ce8ff5b0b2e963814dd12632e71 /drivers/video
parentafbd3c12aca5a29f1627c0c68e6bc77f32459935 (diff)
viafb: cleanup viafb_cursor
Clean the hardware cursor handling up. The most notable change is that it no longer buffers the values in viacursor but uses the ones in cursor instead as they are guaranteed to be always valid. Furthermore it uses local instead global variables where possible, moves the cursor variable in shared as only one hardware cursor is supported and returns an error if memory allocation fails. Last but not least it fixes a too small buffer (as u32 has only 4 and not 32 bytes) but this did not produce any known problems. This is mostly a code cleanup, no negative runtime changes are expected. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Scott Fang <ScottFang@viatech.com.cn> Cc: Joseph Chan <JosephChan@via.com.tw> Cc: Harald Welte <laforge@gnumonks.org> Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/via/accel.c4
-rw-r--r--drivers/video/via/global.c1
-rw-r--r--drivers/video/via/global.h1
-rw-r--r--drivers/video/via/viafbdev.c186
-rw-r--r--drivers/video/via/viafbdev.h2
5 files changed, 68 insertions, 126 deletions
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 8ac02515a18d..503f9d8e5bd0 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -331,7 +331,7 @@ void viafb_init_accel(struct viafb_shared *shared)
331 } 331 }
332 332
333 viaparinfo->fbmem_free -= CURSOR_SIZE; 333 viaparinfo->fbmem_free -= CURSOR_SIZE;
334 viaparinfo->cursor_start = viaparinfo->fbmem_free; 334 shared->cursor_vram_addr = viaparinfo->fbmem_free;
335 viaparinfo->fbmem_used += CURSOR_SIZE; 335 viaparinfo->fbmem_used += CURSOR_SIZE;
336 336
337 /* Reverse 8*1024 memory space for cursor image */ 337 /* Reverse 8*1024 memory space for cursor image */
@@ -487,7 +487,7 @@ void viafb_init_2d_engine(void)
487void viafb_hw_cursor_init(void) 487void viafb_hw_cursor_init(void)
488{ 488{
489 /* Set Cursor Image Base Address */ 489 /* Set Cursor Image Base Address */
490 writel(viaparinfo->cursor_start, 490 writel(viaparinfo->shared->cursor_vram_addr,
491 viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 491 viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
492 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); 492 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
493 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); 493 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
index 1096fd5de2bf..33e7c45b2b78 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/via/global.c
@@ -51,7 +51,6 @@ unsigned int viafb_second_yres = 480;
51unsigned int viafb_second_virtual_xres; 51unsigned int viafb_second_virtual_xres;
52unsigned int viafb_second_virtual_yres; 52unsigned int viafb_second_virtual_yres;
53int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; 53int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
54struct fb_cursor viacursor;
55struct fb_info *viafbinfo; 54struct fb_info *viafbinfo;
56struct fb_info *viafbinfo1; 55struct fb_info *viafbinfo1;
57struct viafb_par *viaparinfo; 56struct viafb_par *viaparinfo;
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index 11382e5daf35..d69d0ca99c2f 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -77,7 +77,6 @@ extern int viafb_hotplug_Yres;
77extern int viafb_hotplug_bpp; 77extern int viafb_hotplug_bpp;
78extern int viafb_hotplug_refresh; 78extern int viafb_hotplug_refresh;
79extern int viafb_primary_dev; 79extern int viafb_primary_dev;
80extern struct fb_cursor viacursor;
81 80
82extern unsigned int viafb_second_xres; 81extern unsigned int viafb_second_xres;
83extern unsigned int viafb_second_yres; 82extern unsigned int viafb_second_yres;
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
28static int MAX_CURS = 32;
29static struct fb_var_screeninfo default_var; 28static struct fb_var_screeninfo default_var;
30static char *viafb_name = "Via"; 29static char *viafb_name = "Via";
31static u32 pseudo_pal[17]; 30static u32 pseudo_pal[17];
@@ -856,150 +855,99 @@ static void viafb_imageblit(struct fb_info *info,
856 855
857static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 856static 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);
1044out:
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 -
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index beb470392db1..ca39ec1689e1 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -51,6 +51,7 @@ struct viafb_shared {
51 struct chip_information chip_info; 51 struct chip_information chip_info;
52 52
53 /* hardware acceleration stuff */ 53 /* hardware acceleration stuff */
54 u32 cursor_vram_addr;
54 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, 55 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height,
55 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, 56 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
56 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, 57 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
@@ -65,7 +66,6 @@ struct viafb_par {
65 unsigned int memsize; /*size of fbmem */ 66 unsigned int memsize; /*size of fbmem */
66 u32 fbmem_free; /* Free FB memory */ 67 u32 fbmem_free; /* Free FB memory */
67 u32 fbmem_used; /* Use FB memory size */ 68 u32 fbmem_used; /* Use FB memory size */
68 u32 cursor_start; /* Cursor Start Address */
69 u32 VQ_start; /* Virtual Queue Start Address */ 69 u32 VQ_start; /* Virtual Queue Start Address */
70 u32 VQ_end; /* Virtual Queue End Address */ 70 u32 VQ_end; /* Virtual Queue End Address */
71 u32 iga_path; 71 u32 iga_path;