Commit df3aafd5 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds

cirrusfb: GD5434 (aka SD64) support fixed

Fix handling of the Cirrus Logic GD5434 chip.  Distinguish this chip from the
GD5430.  It allows detecting memory size for both models correctly.
Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8f19e15b
...@@ -145,7 +145,9 @@ static const struct cirrusfb_board_info_rec { ...@@ -145,7 +145,9 @@ static const struct cirrusfb_board_info_rec {
.scrn_start_bit19 = true, .scrn_start_bit19 = true,
.sr07 = 0xF0, .sr07 = 0xF0,
.sr07_1bpp = 0xF0, .sr07_1bpp = 0xF0,
.sr07_1bpp_mux = 0xF6,
.sr07_8bpp = 0xF1, .sr07_8bpp = 0xF1,
.sr07_8bpp_mux = 0xF7,
.sr1f = 0x1E .sr1f = 0x1E
}, },
[BT_PICCOLO] = { [BT_PICCOLO] = {
...@@ -262,8 +264,8 @@ static const struct cirrusfb_board_info_rec { ...@@ -262,8 +264,8 @@ static const struct cirrusfb_board_info_rec {
static struct pci_device_id cirrusfb_pci_table[] = { static struct pci_device_id cirrusfb_pci_table[] = {
CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
...@@ -341,6 +343,7 @@ struct cirrusfb_info { ...@@ -341,6 +343,7 @@ struct cirrusfb_info {
unsigned char SFR; /* Shadow of special function register */ unsigned char SFR; /* Shadow of special function register */
int multiplexing; int multiplexing;
int doubleVCLK;
int blank_mode; int blank_mode;
u32 pseudo_palette[16]; u32 pseudo_palette[16];
...@@ -496,18 +499,15 @@ static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var, ...@@ -496,18 +499,15 @@ static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
break; break;
} }
} }
#if 0
/* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where /* If we have a 1MB 5434, we need to put ourselves in a mode where
* the VCLK is double the pixel clock. */ * the VCLK is double the pixel clock. */
switch (var->bits_per_pixel) { cinfo->doubleVCLK = 0;
case 16: if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
case 24: var->bits_per_pixel == 16) {
if (var->xres <= 800) cinfo->doubleVCLK = 1;
/* Xbh has this type of clock for 32-bit */
freq /= 2;
break;
} }
#endif
return 0; return 0;
} }
...@@ -830,10 +830,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -830,10 +830,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
vga_wcrt(regbase, CL_CRT1A, tmp); vga_wcrt(regbase, CL_CRT1A, tmp);
freq = PICOS2KHZ(var->pixclock); freq = PICOS2KHZ(var->pixclock);
if (cinfo->btype == BT_ALPINE && var->bits_per_pixel == 24) if (var->bits_per_pixel == 24)
if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
freq *= 3; freq *= 3;
if (cinfo->multiplexing) if (cinfo->multiplexing)
freq /= 2; freq /= 2;
if (cinfo->doubleVCLK)
freq *= 2;
bestclock(freq, &nom, &den, &div); bestclock(freq, &nom, &den, &div);
...@@ -851,11 +854,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -851,11 +854,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
* as clock source * as clock source
*/ */
int divMCLK = cirrusfb_check_mclk(info, freq); int divMCLK = cirrusfb_check_mclk(info, freq);
if (divMCLK) { if (divMCLK)
nom = 0; nom = 0;
cirrusfb_set_mclk_as_source(info, divMCLK); cirrusfb_set_mclk_as_source(info, divMCLK);
} }
}
if (is_laguna(cinfo)) { if (is_laguna(cinfo)) {
long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc); long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407); unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
...@@ -885,14 +887,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -885,14 +887,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
(cinfo->btype == BT_GD5480)) (cinfo->btype == BT_GD5480))
tmp |= 0x80; tmp |= 0x80;
dev_dbg(info->device, "CL_SEQR1B: %d\n", (int) tmp);
/* Laguna chipset has reversed clock registers */ /* Laguna chipset has reversed clock registers */
if (is_laguna(cinfo)) { if (is_laguna(cinfo)) {
vga_wseq(regbase, CL_SEQRE, tmp); vga_wseq(regbase, CL_SEQRE, tmp);
vga_wseq(regbase, CL_SEQR1E, nom); vga_wseq(regbase, CL_SEQR1E, nom);
} else { } else {
vga_wseq(regbase, CL_SEQRB, nom); vga_wseq(regbase, CL_SEQRE, nom);
vga_wseq(regbase, CL_SEQR1B, tmp); vga_wseq(regbase, CL_SEQR1E, tmp);
} }
} }
...@@ -911,15 +912,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -911,15 +912,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
else else
vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
/* adjust horizontal/vertical sync type (low/high) */ /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
/* enable display memory & CRTC I/O address for color mode */ /* enable display memory & CRTC I/O address for color mode */
tmp = 0x03; tmp = 0x03 | 0xc;
if (var->sync & FB_SYNC_HOR_HIGH_ACT) if (var->sync & FB_SYNC_HOR_HIGH_ACT)
tmp |= 0x40; tmp |= 0x40;
if (var->sync & FB_SYNC_VERT_HIGH_ACT) if (var->sync & FB_SYNC_VERT_HIGH_ACT)
tmp |= 0x80; tmp |= 0x80;
if (is_laguna(cinfo))
tmp |= 0xc;
WGen(cinfo, VGA_MIS_W, tmp); WGen(cinfo, VGA_MIS_W, tmp);
/* text cursor on and start line */ /* text cursor on and start line */
...@@ -1052,9 +1051,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1052,9 +1051,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
vga_wseq(regbase, CL_SEQRF, 0xb8); vga_wseq(regbase, CL_SEQRF, 0xb8);
#endif #endif
case BT_ALPINE: case BT_ALPINE:
/* We already set SRF and SR1F */
break;
case BT_SD64: case BT_SD64:
case BT_GD5480: case BT_GD5480:
case BT_LAGUNA: case BT_LAGUNA:
...@@ -1103,7 +1099,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1103,7 +1099,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_PICASSO4: case BT_PICASSO4:
case BT_ALPINE: case BT_ALPINE:
/* Extended Sequencer Mode: 256c col. mode */ /* Extended Sequencer Mode: 256c col. mode */
vga_wseq(regbase, CL_SEQR7, 0xa7); vga_wseq(regbase, CL_SEQR7,
cinfo->doubleVCLK ? 0xa3 : 0xa7);
break; break;
case BT_GD5480: case BT_GD5480:
...@@ -1128,7 +1125,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1128,7 +1125,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
/* mode register: 256 color mode */ /* mode register: 256 color mode */
vga_wgfx(regbase, VGA_GFX_MODE, 64); vga_wgfx(regbase, VGA_GFX_MODE, 64);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
WHDR(cinfo, 0xc1); /* Copy Xbh */ WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
#elif defined(CONFIG_ZORRO) #elif defined(CONFIG_ZORRO)
/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
...@@ -1529,7 +1526,9 @@ static void init_vgachip(struct fb_info *info) ...@@ -1529,7 +1526,9 @@ static void init_vgachip(struct fb_info *info)
case BT_LAGUNAB: case BT_LAGUNAB:
break; break;
case BT_SD64: case BT_SD64:
#ifdef CONFIG_ZORRO
vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
#endif
break; break;
default: default:
vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
...@@ -1604,7 +1603,8 @@ static void init_vgachip(struct fb_info *info) ...@@ -1604,7 +1603,8 @@ static void init_vgachip(struct fb_info *info)
/* Bit Mask: no mask at all */ /* Bit Mask: no mask at all */
vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
if (cinfo->btype == BT_ALPINE || is_laguna(cinfo)) if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
is_laguna(cinfo))
/* (5434 can't have bit 3 set for bitblt) */ /* (5434 can't have bit 3 set for bitblt) */
vga_wgfx(cinfo->regbase, CL_GRB, 0x20); vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
else else
...@@ -1809,9 +1809,11 @@ static void cirrusfb_imageblit(struct fb_info *info, ...@@ -1809,9 +1809,11 @@ static void cirrusfb_imageblit(struct fb_info *info,
if (info->state != FBINFO_STATE_RUNNING) if (info->state != FBINFO_STATE_RUNNING)
return; return;
/* Alpine acceleration does not work at 24bpp ?!? */ /* Alpine/SD64 does not work at 24bpp ??? */
if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1 || if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
(cinfo->btype == BT_ALPINE && op == 0xc)) cfb_imageblit(info, image);
else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
op == 0xc)
cfb_imageblit(info, image); cfb_imageblit(info, image);
else { else {
unsigned size = ((image->width + 7) >> 3) * image->height; unsigned size = ((image->width + 7) >> 3) * image->height;
...@@ -1895,7 +1897,7 @@ static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info, ...@@ -1895,7 +1897,7 @@ static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
/* If DRAM bank switching is enabled, there must be /* If DRAM bank switching is enabled, there must be
* twice as much memory installed. (4MB on the 5434) * twice as much memory installed. (4MB on the 5434)
*/ */
if (SRF & 0x80) if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
mem *= 2; mem *= 2;
} }
...@@ -2553,7 +2555,7 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch ...@@ -2553,7 +2555,7 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch
if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
is_laguna(cinfo)) { cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
/* but DAC data register IS, at least for Picasso II */ /* but DAC data register IS, at least for Picasso II */
if (cinfo->btype == BT_PICASSO) if (cinfo->btype == BT_PICASSO)
data += 0xfff; data += 0xfff;
......
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