aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/viafbdev.c
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/via/viafbdev.c
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/via/viafbdev.c')
-rw-r--r--drivers/video/via/viafbdev.c186
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
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 -