summaryrefslogtreecommitdiffstats
path: root/drivers/video/via/viafbdev.c
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2009-09-22 16:47:28 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 07:39:53 -0700
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 7626325ed7f..03f98d68320 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -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 -