viafb: cleanup viafb_cursor
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>
Tue, 22 Sep 2009 23:47:28 +0000 (16:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Sep 2009 14:39:53 +0000 (07:39 -0700)
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>
drivers/video/via/accel.c
drivers/video/via/global.c
drivers/video/via/global.h
drivers/video/via/viafbdev.c
drivers/video/via/viafbdev.h

index 8ac02515a18d23408e0dac3dc6952384d1d6b989..503f9d8e5bd07f2fd92339fec84763373d93ba9c 100644 (file)
@@ -331,7 +331,7 @@ void viafb_init_accel(struct viafb_shared *shared)
        }
 
        viaparinfo->fbmem_free -= CURSOR_SIZE;
-       viaparinfo->cursor_start = viaparinfo->fbmem_free;
+       shared->cursor_vram_addr = viaparinfo->fbmem_free;
        viaparinfo->fbmem_used += CURSOR_SIZE;
 
        /* Reverse 8*1024 memory space for cursor image */
@@ -487,7 +487,7 @@ void viafb_init_2d_engine(void)
 void viafb_hw_cursor_init(void)
 {
        /* Set Cursor Image Base Address */
-       writel(viaparinfo->cursor_start,
+       writel(viaparinfo->shared->cursor_vram_addr,
                viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
        writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
        writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
index 1096fd5de2bf1ca919a8398651a62d82afaf13fe..33e7c45b2b78a2634a3f6e655d620818e646aac0 100644 (file)
@@ -51,7 +51,6 @@ unsigned int viafb_second_yres = 480;
 unsigned int viafb_second_virtual_xres;
 unsigned int viafb_second_virtual_yres;
 int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
-struct fb_cursor viacursor;
 struct fb_info *viafbinfo;
 struct fb_info *viafbinfo1;
 struct viafb_par *viaparinfo;
index 11382e5daf35879405d4ac17c2b46426114ec44c..d69d0ca99c2fb7cc3951fbe50a7f14416c35bb80 100644 (file)
@@ -77,7 +77,6 @@ extern int viafb_hotplug_Yres;
 extern int viafb_hotplug_bpp;
 extern int viafb_hotplug_refresh;
 extern int viafb_primary_dev;
-extern struct fb_cursor viacursor;
 
 extern unsigned int viafb_second_xres;
 extern unsigned int viafb_second_yres;
index 7626325ed7f86a954494ad70360f9eea62241623..03f98d68320573602c46bdfaaba754b761c581ed 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "global.h"
 
-static int MAX_CURS = 32;
 static struct fb_var_screeninfo default_var;
 static char *viafb_name = "Via";
 static u32 pseudo_pal[17];
@@ -856,150 +855,99 @@ static void viafb_imageblit(struct fb_info *info,
 
 static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       u32 temp, xx, yy, bg_col = 0, fg_col = 0;
-       int i, j = 0;
-       static int hw_cursor;
-       struct viafb_par *p_viafb_par;
-
-       if (viafb_accel)
-               hw_cursor = 1;
-
-       if (!viafb_accel) {
-               if (hw_cursor) {
-                       viafb_show_hw_cursor(info, HW_Cursor_OFF);
-                       hw_cursor = 0;
-               }
-               return -ENODEV;
-       }
+       struct viafb_par *viapar = info->par;
+       u32 temp, xx, yy, bg_color = 0, fg_color = 0,
+               chip_name = viapar->shared->chip_info.gfx_chip_name;
+       int i, j = 0, cur_size = 64;
 
-       if ((((struct viafb_par *)(info->par))->iga_path == IGA2)
-           && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
+       if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo)
                return -ENODEV;
 
-       /* When duoview and using lcd , use soft cursor */
-       if (viafb_LCD_ON || (!viafb_SAMM_ON &&
-               viafb_LCD2_ON + viafb_DVI_ON + viafb_CRT_ON == 2))
+       if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2)
                return -ENODEV;
 
        viafb_show_hw_cursor(info, HW_Cursor_OFF);
-       viacursor = *cursor;
 
        if (cursor->set & FB_CUR_SETHOT) {
-               viacursor.hot = cursor->hot;
-               temp = ((viacursor.hot.x) << 16) + viacursor.hot.y;
-               writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
+               temp = (cursor->hot.x << 16) + cursor->hot.y;
+               writel(temp, viapar->io_virt + VIA_REG_CURSOR_ORG);
        }
 
        if (cursor->set & FB_CUR_SETPOS) {
-               viacursor.image.dx = cursor->image.dx;
-               viacursor.image.dy = cursor->image.dy;
                yy = cursor->image.dy - info->var.yoffset;
                xx = cursor->image.dx - info->var.xoffset;
                temp = yy & 0xFFFF;
                temp |= (xx << 16);
-               writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
+               writel(temp, viapar->io_virt + VIA_REG_CURSOR_POS);
        }
 
-       if (cursor->set & FB_CUR_SETSIZE) {
-               temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+       if (cursor->image.width <= 32 && cursor->image.height <= 32)
+               cur_size = 32;
+       else if (cursor->image.width <= 64 && cursor->image.height <= 64)
+               cur_size = 64;
+       else {
+               printk(KERN_WARNING "viafb_cursor: The cursor is too large "
+                       "%dx%d", cursor->image.width, cursor->image.height);
+               return -ENXIO;
+       }
 
-               if ((cursor->image.width <= 32)
-                   && (cursor->image.height <= 32)) {
-                       MAX_CURS = 32;
+       if (cursor->set & FB_CUR_SETSIZE) {
+               temp = readl(viapar->io_virt + VIA_REG_CURSOR_MODE);
+               if (cur_size == 32)
                        temp |= 0x2;
-               } else if ((cursor->image.width <= 64)
-                          && (cursor->image.height <= 64)) {
-                       MAX_CURS = 64;
-                       temp &= 0xFFFFFFFD;
-               } else {
-                       DEBUG_MSG(KERN_INFO
-                       "The cursor image is biger than 64x64 bits...\n");
-                       return -ENXIO;
-               }
-               writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+               else
+                       temp &= ~0x2;
 
-               viacursor.image.height = cursor->image.height;
-               viacursor.image.width = cursor->image.width;
+               writel(temp, viapar->io_virt + VIA_REG_CURSOR_MODE);
        }
 
        if (cursor->set & FB_CUR_SETCMAP) {
-               viacursor.image.fg_color = cursor->image.fg_color;
-               viacursor.image.bg_color = cursor->image.bg_color;
-
-               switch (info->var.bits_per_pixel) {
-               case 8:
-               case 16:
-               case 32:
-                       bg_col =
-                           (0xFF << 24) |
-                           (((info->cmap.red)[viacursor.image.bg_color] &
-                           0xFF00) << 8) |
-                           ((info->cmap.green)[viacursor.image.bg_color] &
-                           0xFF00) |
-                           (((info->cmap.blue)[viacursor.image.bg_color] &
-                           0xFF00) >> 8);
-                       fg_col =
-                           (0xFF << 24) |
-                           (((info->cmap.red)[viacursor.image.fg_color] &
-                           0xFF00) << 8) |
-                           ((info->cmap.green)[viacursor.image.fg_color] &
-                           0xFF00) |
-                           (((info->cmap.blue)[viacursor.image.fg_color] &
-                           0xFF00) >> 8);
-                       break;
-               default:
-                       return 0;
-               }
-
-               /* This is indeed a patch for VT3324/VT3353 */
-               if (!info->par)
-                       return 0;
-               p_viafb_par = (struct viafb_par *)info->par;
-
-               if ((p_viafb_par->chip_info->gfx_chip_name ==
-                       UNICHROME_CX700) ||
-                       ((p_viafb_par->chip_info->gfx_chip_name ==
-                       UNICHROME_VX800))) {
-                       bg_col =
-                           (((info->cmap.red)[viacursor.image.bg_color] &
-                           0xFFC0) << 14) |
-                           (((info->cmap.green)[viacursor.image.bg_color] &
-                           0xFFC0) << 4) |
-                           (((info->cmap.blue)[viacursor.image.bg_color] &
-                           0xFFC0) >> 6);
-                       fg_col =
-                           (((info->cmap.red)[viacursor.image.fg_color] &
-                           0xFFC0) << 14) |
-                           (((info->cmap.green)[viacursor.image.fg_color] &
-                           0xFFC0) << 4) |
-                           (((info->cmap.blue)[viacursor.image.fg_color] &
-                           0xFFC0) >> 6);
+               fg_color = cursor->image.fg_color;
+               bg_color = cursor->image.bg_color;
+               if (chip_name == UNICHROME_CX700 ||
+                       chip_name == UNICHROME_VX800) {
+                       fg_color =
+                               ((info->cmap.red[fg_color] & 0xFFC0) << 14) |
+                               ((info->cmap.green[fg_color] & 0xFFC0) << 4) |
+                               ((info->cmap.blue[fg_color] & 0xFFC0) >> 6);
+                       bg_color =
+                               ((info->cmap.red[bg_color] & 0xFFC0) << 14) |
+                               ((info->cmap.green[bg_color] & 0xFFC0) << 4) |
+                               ((info->cmap.blue[bg_color] & 0xFFC0) >> 6);
+               } else {
+                       fg_color =
+                               ((info->cmap.red[fg_color] & 0xFF00) << 8) |
+                               (info->cmap.green[fg_color] & 0xFF00) |
+                               ((info->cmap.blue[fg_color] & 0xFF00) >> 8);
+                       bg_color =
+                               ((info->cmap.red[bg_color] & 0xFF00) << 8) |
+                               (info->cmap.green[bg_color] & 0xFF00) |
+                               ((info->cmap.blue[bg_color] & 0xFF00) >> 8);
                }
 
-               writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
-               writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
+               writel(bg_color, viapar->io_virt + VIA_REG_CURSOR_BG);
+               writel(fg_color, viapar->io_virt + VIA_REG_CURSOR_FG);
        }
 
        if (cursor->set & FB_CUR_SETSHAPE) {
                struct {
-                       u8 data[CURSOR_SIZE / 8];
-                       u32 bak[CURSOR_SIZE / 32];
+                       u8 data[CURSOR_SIZE];
+                       u32 bak[CURSOR_SIZE / 4];
                } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC);
-               int size =
-                   ((viacursor.image.width + 7) >> 3) *
-                   viacursor.image.height;
+               int size = ((cursor->image.width + 7) >> 3) *
+                       cursor->image.height;
 
-               if (cr_data == NULL)
-                       goto out;
+               if (!cr_data)
+                       return -ENOMEM;
 
-               if (MAX_CURS == 32) {
-                       for (i = 0; i < (CURSOR_SIZE / 32); i++) {
+               if (cur_size == 32) {
+                       for (i = 0; i < (CURSOR_SIZE / 4); i++) {
                                cr_data->bak[i] = 0x0;
                                cr_data->bak[i + 1] = 0xFFFFFFFF;
                                i += 1;
                        }
-               } else if (MAX_CURS == 64) {
-                       for (i = 0; i < (CURSOR_SIZE / 32); i++) {
+               } else {
+                       for (i = 0; i < (CURSOR_SIZE / 4); i++) {
                                cr_data->bak[i] = 0x0;
                                cr_data->bak[i + 1] = 0x0;
                                cr_data->bak[i + 2] = 0xFFFFFFFF;
@@ -1008,27 +956,27 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
                        }
                }
 
-               switch (viacursor.rop) {
+               switch (cursor->rop) {
                case ROP_XOR:
                        for (i = 0; i < size; i++)
-                               cr_data->data[i] = viacursor.mask[i];
+                               cr_data->data[i] = cursor->mask[i];
                        break;
                case ROP_COPY:
 
                        for (i = 0; i < size; i++)
-                               cr_data->data[i] = viacursor.mask[i];
+                               cr_data->data[i] = cursor->mask[i];
                        break;
                default:
                        break;
                }
 
-               if (MAX_CURS == 32) {
+               if (cur_size == 32) {
                        for (i = 0; i < size; i++) {
                                cr_data->bak[j] = (u32) cr_data->data[i];
                                cr_data->bak[j + 1] = ~cr_data->bak[j];
                                j += 2;
                        }
-               } else if (MAX_CURS == 64) {
+               } else {
                        for (i = 0; i < size; i++) {
                                cr_data->bak[j] = (u32) cr_data->data[i];
                                cr_data->bak[j + 1] = 0x0;
@@ -1038,14 +986,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
                        }
                }
 
-               memcpy(viafbinfo->screen_base +
-                      ((struct viafb_par *)(info->par))->cursor_start,
-                      cr_data->bak, CURSOR_SIZE);
-out:
+               memcpy_toio(viafbinfo->screen_base + viapar->shared->
+                       cursor_vram_addr, cr_data->bak, CURSOR_SIZE);
                kfree(cr_data);
        }
 
-       if (viacursor.enable)
+       if (cursor->enable)
                viafb_show_hw_cursor(info, HW_Cursor_ON);
 
        return 0;
@@ -2052,8 +1998,6 @@ static int __devinit via_pci_probe(void)
                viaparinfo->fbmem_free = viaparinfo->memsize;
                viaparinfo->fbmem_used = 0;
                if (viafb_accel) {
-                       viaparinfo1->cursor_start =
-                           viaparinfo->cursor_start - viafb_second_offset;
                        viaparinfo1->VQ_start = viaparinfo->VQ_start -
                                viafb_second_offset;
                        viaparinfo1->VQ_end = viaparinfo->VQ_end -
index beb470392db1e036b8cdf79b7cdc5e11bb996a34..ca39ec1689e12887f22f32b06ca9b9bee3f80ece 100644 (file)
@@ -51,6 +51,7 @@ struct viafb_shared {
        struct chip_information chip_info;
 
        /* hardware acceleration stuff */
+       u32 cursor_vram_addr;
        int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height,
                u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
                u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
@@ -65,7 +66,6 @@ struct viafb_par {
        unsigned int memsize;   /*size of fbmem */
        u32 fbmem_free;         /* Free FB memory */
        u32 fbmem_used;         /* Use FB memory size */
-       u32 cursor_start;       /* Cursor Start Address */
        u32 VQ_start;           /* Virtual Queue Start Address */
        u32 VQ_end;             /* Virtual Queue End Address */
        u32 iga_path;