Commit a809bda2 authored by Florian Tobias Schandinat's avatar Florian Tobias Schandinat Committed by James Toy

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: default avatarFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Scott Fang <ScottFang@viatech.com.cn>
Cc: Joseph Chan <JosephChan@via.com.tw>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent fc06e8cb
...@@ -331,7 +331,7 @@ void viafb_init_accel(struct viafb_shared *shared) ...@@ -331,7 +331,7 @@ void viafb_init_accel(struct viafb_shared *shared)
} }
viaparinfo->fbmem_free -= CURSOR_SIZE; viaparinfo->fbmem_free -= CURSOR_SIZE;
viaparinfo->cursor_start = viaparinfo->fbmem_free; shared->cursor_vram_addr = viaparinfo->fbmem_free;
viaparinfo->fbmem_used += CURSOR_SIZE; viaparinfo->fbmem_used += CURSOR_SIZE;
/* Reverse 8*1024 memory space for cursor image */ /* Reverse 8*1024 memory space for cursor image */
...@@ -487,7 +487,7 @@ void viafb_init_2d_engine(void) ...@@ -487,7 +487,7 @@ void viafb_init_2d_engine(void)
void viafb_hw_cursor_init(void) void viafb_hw_cursor_init(void)
{ {
/* Set Cursor Image Base Address */ /* Set Cursor Image Base Address */
writel(viaparinfo->cursor_start, writel(viaparinfo->shared->cursor_vram_addr,
viaparinfo->io_virt + VIA_REG_CURSOR_MODE); viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
......
...@@ -51,7 +51,6 @@ unsigned int viafb_second_yres = 480; ...@@ -51,7 +51,6 @@ unsigned int viafb_second_yres = 480;
unsigned int viafb_second_virtual_xres; unsigned int viafb_second_virtual_xres;
unsigned int viafb_second_virtual_yres; unsigned int viafb_second_virtual_yres;
int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
struct fb_cursor viacursor;
struct fb_info *viafbinfo; struct fb_info *viafbinfo;
struct fb_info *viafbinfo1; struct fb_info *viafbinfo1;
struct viafb_par *viaparinfo; struct viafb_par *viaparinfo;
......
...@@ -77,7 +77,6 @@ extern int viafb_hotplug_Yres; ...@@ -77,7 +77,6 @@ extern int viafb_hotplug_Yres;
extern int viafb_hotplug_bpp; extern int viafb_hotplug_bpp;
extern int viafb_hotplug_refresh; extern int viafb_hotplug_refresh;
extern int viafb_primary_dev; extern int viafb_primary_dev;
extern struct fb_cursor viacursor;
extern unsigned int viafb_second_xres; extern unsigned int viafb_second_xres;
extern unsigned int viafb_second_yres; extern unsigned int viafb_second_yres;
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "global.h" #include "global.h"
static int MAX_CURS = 32;
static struct fb_var_screeninfo default_var; static struct fb_var_screeninfo default_var;
static char *viafb_name = "Via"; static char *viafb_name = "Via";
static u32 pseudo_pal[17]; static u32 pseudo_pal[17];
...@@ -856,150 +855,99 @@ static void viafb_imageblit(struct fb_info *info, ...@@ -856,150 +855,99 @@ static void viafb_imageblit(struct fb_info *info,
static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{ {
u32 temp, xx, yy, bg_col = 0, fg_col = 0; struct viafb_par *viapar = info->par;
int i, j = 0; u32 temp, xx, yy, bg_color = 0, fg_color = 0,
static int hw_cursor; chip_name = viapar->shared->chip_info.gfx_chip_name;
struct viafb_par *p_viafb_par; int i, j = 0, cur_size = 64;
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;
}
if ((((struct viafb_par *)(info->par))->iga_path == IGA2) if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo)
&& (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
return -ENODEV; return -ENODEV;
/* When duoview and using lcd , use soft cursor */ if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2)
if (viafb_LCD_ON || (!viafb_SAMM_ON &&
viafb_LCD2_ON + viafb_DVI_ON + viafb_CRT_ON == 2))
return -ENODEV; return -ENODEV;
viafb_show_hw_cursor(info, HW_Cursor_OFF); viafb_show_hw_cursor(info, HW_Cursor_OFF);
viacursor = *cursor;
if (cursor->set & FB_CUR_SETHOT) { if (cursor->set & FB_CUR_SETHOT) {
viacursor.hot = cursor->hot; temp = (cursor->hot.x << 16) + cursor->hot.y;
temp = ((viacursor.hot.x) << 16) + viacursor.hot.y; writel(temp, viapar->io_virt + VIA_REG_CURSOR_ORG);
writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
} }
if (cursor->set & FB_CUR_SETPOS) { 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; yy = cursor->image.dy - info->var.yoffset;
xx = cursor->image.dx - info->var.xoffset; xx = cursor->image.dx - info->var.xoffset;
temp = yy & 0xFFFF; temp = yy & 0xFFFF;
temp |= (xx << 16); 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) { if (cursor->image.width <= 32 && cursor->image.height <= 32)
temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 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) if (cursor->set & FB_CUR_SETSIZE) {
&& (cursor->image.height <= 32)) { temp = readl(viapar->io_virt + VIA_REG_CURSOR_MODE);
MAX_CURS = 32; if (cur_size == 32)
temp |= 0x2; temp |= 0x2;
} else if ((cursor->image.width <= 64) else
&& (cursor->image.height <= 64)) { temp &= ~0x2;
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);
viacursor.image.height = cursor->image.height; writel(temp, viapar->io_virt + VIA_REG_CURSOR_MODE);
viacursor.image.width = cursor->image.width;
} }
if (cursor->set & FB_CUR_SETCMAP) { if (cursor->set & FB_CUR_SETCMAP) {
viacursor.image.fg_color = cursor->image.fg_color; fg_color = cursor->image.fg_color;
viacursor.image.bg_color = cursor->image.bg_color; bg_color = cursor->image.bg_color;
if (chip_name == UNICHROME_CX700 ||
switch (info->var.bits_per_pixel) { chip_name == UNICHROME_VX800) {
case 8: fg_color =
case 16: ((info->cmap.red[fg_color] & 0xFFC0) << 14) |
case 32: ((info->cmap.green[fg_color] & 0xFFC0) << 4) |
bg_col = ((info->cmap.blue[fg_color] & 0xFFC0) >> 6);
(0xFF << 24) | bg_color =
(((info->cmap.red)[viacursor.image.bg_color] & ((info->cmap.red[bg_color] & 0xFFC0) << 14) |
0xFF00) << 8) | ((info->cmap.green[bg_color] & 0xFFC0) << 4) |
((info->cmap.green)[viacursor.image.bg_color] & ((info->cmap.blue[bg_color] & 0xFFC0) >> 6);
0xFF00) | } else {
(((info->cmap.blue)[viacursor.image.bg_color] & fg_color =
0xFF00) >> 8); ((info->cmap.red[fg_color] & 0xFF00) << 8) |
fg_col = (info->cmap.green[fg_color] & 0xFF00) |
(0xFF << 24) | ((info->cmap.blue[fg_color] & 0xFF00) >> 8);
(((info->cmap.red)[viacursor.image.fg_color] & bg_color =
0xFF00) << 8) | ((info->cmap.red[bg_color] & 0xFF00) << 8) |
((info->cmap.green)[viacursor.image.fg_color] & (info->cmap.green[bg_color] & 0xFF00) |
0xFF00) | ((info->cmap.blue[bg_color] & 0xFF00) >> 8);
(((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);
} }
writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); writel(bg_color, viapar->io_virt + VIA_REG_CURSOR_BG);
writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); writel(fg_color, viapar->io_virt + VIA_REG_CURSOR_FG);
} }
if (cursor->set & FB_CUR_SETSHAPE) { if (cursor->set & FB_CUR_SETSHAPE) {
struct { struct {
u8 data[CURSOR_SIZE / 8]; u8 data[CURSOR_SIZE];
u32 bak[CURSOR_SIZE / 32]; u32 bak[CURSOR_SIZE / 4];
} *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC);
int size = int size = ((cursor->image.width + 7) >> 3) *
((viacursor.image.width + 7) >> 3) * cursor->image.height;
viacursor.image.height;
if (cr_data == NULL) if (!cr_data)
goto out; return -ENOMEM;
if (MAX_CURS == 32) { if (cur_size == 32) {
for (i = 0; i < (CURSOR_SIZE / 32); i++) { for (i = 0; i < (CURSOR_SIZE / 4); i++) {
cr_data->bak[i] = 0x0; cr_data->bak[i] = 0x0;
cr_data->bak[i + 1] = 0xFFFFFFFF; cr_data->bak[i + 1] = 0xFFFFFFFF;
i += 1; i += 1;
} }
} else if (MAX_CURS == 64) { } else {
for (i = 0; i < (CURSOR_SIZE / 32); i++) { for (i = 0; i < (CURSOR_SIZE / 4); i++) {
cr_data->bak[i] = 0x0; cr_data->bak[i] = 0x0;
cr_data->bak[i + 1] = 0x0; cr_data->bak[i + 1] = 0x0;
cr_data->bak[i + 2] = 0xFFFFFFFF; cr_data->bak[i + 2] = 0xFFFFFFFF;
...@@ -1008,27 +956,27 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -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: case ROP_XOR:
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
cr_data->data[i] = viacursor.mask[i]; cr_data->data[i] = cursor->mask[i];
break; break;
case ROP_COPY: case ROP_COPY:
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
cr_data->data[i] = viacursor.mask[i]; cr_data->data[i] = cursor->mask[i];
break; break;
default: default:
break; break;
} }
if (MAX_CURS == 32) { if (cur_size == 32) {
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
cr_data->bak[j] = (u32) cr_data->data[i]; cr_data->bak[j] = (u32) cr_data->data[i];
cr_data->bak[j + 1] = ~cr_data->bak[j]; cr_data->bak[j + 1] = ~cr_data->bak[j];
j += 2; j += 2;
} }
} else if (MAX_CURS == 64) { } else {
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
cr_data->bak[j] = (u32) cr_data->data[i]; cr_data->bak[j] = (u32) cr_data->data[i];
cr_data->bak[j + 1] = 0x0; cr_data->bak[j + 1] = 0x0;
...@@ -1038,14 +986,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -1038,14 +986,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
} }
} }
memcpy(viafbinfo->screen_base + memcpy_toio(viafbinfo->screen_base + viapar->shared->
((struct viafb_par *)(info->par))->cursor_start, cursor_vram_addr, cr_data->bak, CURSOR_SIZE);
cr_data->bak, CURSOR_SIZE);
out:
kfree(cr_data); kfree(cr_data);
} }
if (viacursor.enable) if (cursor->enable)
viafb_show_hw_cursor(info, HW_Cursor_ON); viafb_show_hw_cursor(info, HW_Cursor_ON);
return 0; return 0;
...@@ -2052,8 +1998,6 @@ static int __devinit via_pci_probe(void) ...@@ -2052,8 +1998,6 @@ static int __devinit via_pci_probe(void)
viaparinfo->fbmem_free = viaparinfo->memsize; viaparinfo->fbmem_free = viaparinfo->memsize;
viaparinfo->fbmem_used = 0; viaparinfo->fbmem_used = 0;
if (viafb_accel) { if (viafb_accel) {
viaparinfo1->cursor_start =
viaparinfo->cursor_start - viafb_second_offset;
viaparinfo1->VQ_start = viaparinfo->VQ_start - viaparinfo1->VQ_start = viaparinfo->VQ_start -
viafb_second_offset; viafb_second_offset;
viaparinfo1->VQ_end = viaparinfo->VQ_end - viaparinfo1->VQ_end = viaparinfo->VQ_end -
......
...@@ -51,6 +51,7 @@ struct viafb_shared { ...@@ -51,6 +51,7 @@ struct viafb_shared {
struct chip_information chip_info; struct chip_information chip_info;
/* hardware acceleration stuff */ /* hardware acceleration stuff */
u32 cursor_vram_addr;
int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, 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, 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, u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
...@@ -65,7 +66,6 @@ struct viafb_par { ...@@ -65,7 +66,6 @@ struct viafb_par {
unsigned int memsize; /*size of fbmem */ unsigned int memsize; /*size of fbmem */
u32 fbmem_free; /* Free FB memory */ u32 fbmem_free; /* Free FB memory */
u32 fbmem_used; /* Use FB memory size */ u32 fbmem_used; /* Use FB memory size */
u32 cursor_start; /* Cursor Start Address */
u32 VQ_start; /* Virtual Queue Start Address */ u32 VQ_start; /* Virtual Queue Start Address */
u32 VQ_end; /* Virtual Queue End Address */ u32 VQ_end; /* Virtual Queue End Address */
u32 iga_path; u32 iga_path;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment