gbefb: cmap FIFO timeout

Writes to the cmap fifo while the display is blanked caused cmap FIFO
timeout messages and a wrong colormap.  To avoid this the driver now
maintains a colormap in memory and updates the colormap after the display
is unblanked.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Thomas Bogendoerfer 2008-07-29 22:33:49 -07:00 committed by Linus Torvalds
parent 6af8bf3d86
commit 8d0b1c51eb
1 changed files with 34 additions and 16 deletions

View File

@ -87,6 +87,8 @@ static int gbe_revision;
static int ypan, ywrap;
static uint32_t pseudo_palette[16];
static uint32_t gbe_cmap[256];
static int gbe_turned_on; /* 0 turned off, 1 turned on */
static char *mode_option __initdata = NULL;
@ -208,6 +210,8 @@ void gbe_turn_off(void)
int i;
unsigned int val, x, y, vpixen_off;
gbe_turned_on = 0;
/* check if pixel counter is on */
val = gbe->vt_xy;
if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
@ -371,6 +375,22 @@ static void gbe_turn_on(void)
}
if (i == 10000)
printk(KERN_ERR "gbefb: turn on DMA timed out\n");
gbe_turned_on = 1;
}
static void gbe_loadcmap(void)
{
int i, j;
for (i = 0; i < 256; i++) {
for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
udelay(10);
if (j == 1000)
printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
gbe->cmap[i] = gbe_cmap[i];
}
}
/*
@ -382,6 +402,7 @@ static int gbefb_blank(int blank, struct fb_info *info)
switch (blank) {
case FB_BLANK_UNBLANK: /* unblank */
gbe_turn_on();
gbe_loadcmap();
break;
case FB_BLANK_NORMAL: /* blank */
@ -796,16 +817,10 @@ static int gbefb_set_par(struct fb_info *info)
gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
/* Initialize the color map */
for (i = 0; i < 256; i++) {
int j;
for (i = 0; i < 256; i++)
gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
udelay(10);
if (j == 1000)
printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
gbe->cmap[i] = (i << 8) | (i << 16) | (i << 24);
}
gbe_loadcmap();
return 0;
}
@ -855,14 +870,17 @@ static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
blue >>= 8;
if (info->var.bits_per_pixel <= 8) {
/* wait for the color map FIFO to have a free entry */
for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
udelay(10);
if (i == 1000) {
printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
return 1;
gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
if (gbe_turned_on) {
/* wait for the color map FIFO to have a free entry */
for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
udelay(10);
if (i == 1000) {
printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
return 1;
}
gbe->cmap[regno] = gbe_cmap[regno];
}
gbe->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
} else if (regno < 16) {
switch (info->var.bits_per_pixel) {
case 15: