[parisc-linux-cvs] HCRX support for stifb
Thomas Bogendoerfer
tsbogend@alpha.franken.de
Tue, 9 Oct 2001 00:28:49 +0200
Hi,
the patch below, which I'm going to commit in a couple of seconds,
fixes the panic, if there is an additional framebuffer installed
in an old system. It adds also support for 8 bit HCRX cards (tested
on 715/100 and C100). Since stifb works now on ARTIST, VIS-EG and
HCRX, I've enabled them by default.
Thomas.
Index: sticore.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticore.c,v
retrieving revision 1.23
diff -u -r1.23 sticore.c
--- sticore.c 2001/09/26 18:15:19 1.23
+++ sticore.c 2001/10/08 22:19:20
@@ -839,12 +839,12 @@
rom = dev->addr[0];
}
if (!rom) {
- rom = PAGE0->proc_sti;
- }
- if (!rom) {
rom = dev->hpa;
+ DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
+ if (sti_try_rom_generic(rom, dev->hpa, NULL))
+ return 0;
+ rom = PAGE0->proc_sti;
}
-
DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
if (sti_try_rom_generic(rom, dev->hpa, NULL))
return 0;
Index: stifb.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.21
diff -u -r1.21 stifb.c
--- stifb.c 2001/09/29 16:45:08 1.21
+++ stifb.c 2001/10/08 22:19:22
@@ -165,6 +165,7 @@
#define REG_32 0x21003c
#define REG_33 0x210040
#define REG_34 0x200008
+#define REG_35 0x018010
#define REG_38 0x210020
#define REG_39 0x210120
#define REG_40 0x210130
@@ -401,7 +402,13 @@
#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb_info, fg32) \
WRITE_WORD(fg32, fb_info->iobase + REG_35)
-
+
+#define NGLE_SET_TRANSFERDATA(fb_info, val) \
+ WRITE_WORD(val, fb_info->iobase + REG_8)
+
+#define NGLE_SET_DSTXY(fb_info, val) \
+ WRITE_WORD(val, fb_info->iobase + REG_6)
+
#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) ( \
(unsigned long) (fbaddrbase) + \
( (unsigned int) ( (y) << 13 ) | \
@@ -422,7 +429,10 @@
#define START_COLORMAPLOAD(fb_info, cmapBltCtlData32) \
WRITE_WORD((cmapBltCtlData32), fb_info->iobase + REG_38)
-
+
+#define SET_LENXY_START_RECFILL(fb_info, lenxy) \
+ WRITE_WORD(lenxy, fb_info->iobase + REG_9)
+
static void
HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb_info, int enable)
{
@@ -638,13 +648,90 @@
}
static void
-ngleResetAttrPlanes(struct stifb_info *fb_info, int enable)
+ngleResetAttrPlanes(struct stifb_info *fb_info, unsigned int ctlPlaneReg)
{
- /* FIXME! */
+ int nFreeFifoSlots = 0;
+ unsigned long packed_dst;
+ unsigned long packed_len;
+
+ NGLE_LOCK(fb_info);
+
+ GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 4);
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb_info,
+ BA(IndexedDcd, Otc32, OtsIndirect,
+ AddrLong, BAJustPoint(0),
+ BINattr, BAIndexBase(0)));
+ NGLE_QUICK_SET_CTL_PLN_REG(fb_info, ctlPlaneReg);
+ NGLE_SET_TRANSFERDATA(fb_info, 0xffffffff);
+
+ NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb_info,
+ IBOvals(RopSrc, MaskAddrOffset(0),
+ BitmapExtent08, StaticReg(1),
+ DataDynamic, MaskOtc,
+ BGx(0), FGx(0)));
+ packed_dst = 0;
+ packed_len = (1280 << 16) | 1024;
+ GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 2);
+ NGLE_SET_DSTXY(fb_info, packed_dst);
+ SET_LENXY_START_RECFILL(fb_info, packed_len);
+
+ /*
+ * In order to work around an ELK hardware problem (Buffy doesn't
+ * always flush it's buffers when writing to the attribute
+ * planes), at least 4 pixels must be written to the attribute
+ * planes starting at (X == 1280) and (Y != to the last Y written
+ * by BIF):
+ */
+
+ if (fb_info->id == S9000_ID_A1659A) { /* ELK_DEVICE_ID */
+ /* It's safe to use scanline zero: */
+ packed_dst = (1280 << 16);
+ GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 2);
+ NGLE_SET_DSTXY(fb_info, packed_dst);
+ packed_len = (4 << 16) | 1;
+ SET_LENXY_START_RECFILL(fb_info, packed_len);
+ } /* ELK Hardware Kludge */
+
+ /**** Finally, set the Control Plane Register back to zero: ****/
+ GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 1);
+ NGLE_QUICK_SET_CTL_PLN_REG(fb_info, 0);
+
+ NGLE_UNLOCK(fb_info);
}
+
static void
-ngleClearOverlayPlanes(struct stifb_info *fb_info, int mask, int len)
+ngleClearOverlayPlanes(struct stifb_info *fb_info, int mask, int data)
{
+ int nFreeFifoSlots = 0;
+ unsigned long packed_dst;
+ unsigned long packed_len;
+
+ NGLE_LOCK(fb_info);
+
+ /* Hardware setup */
+ GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 8);
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb_info,
+ BA(IndexedDcd, Otc04, Ots08, AddrLong,
+ BAJustPoint(0), BINovly, BAIndexBase(0)));
+
+ NGLE_SET_TRANSFERDATA(fb_info, 0xffffffff); /* Write foreground color */
+
+ NGLE_REALLY_SET_IMAGE_FG_COLOR(fb_info, data);
+ NGLE_REALLY_SET_IMAGE_PLANEMASK(fb_info, mask);
+
+ packed_dst = 0;
+ packed_len = (1280 << 16) | 1024;
+ NGLE_SET_DSTXY(fb_info, packed_dst);
+
+ /* Write zeroes to overlay planes */
+ NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb_info,
+ IBOvals(RopSrc, MaskAddrOffset(0),
+ BitmapExtent08, StaticReg(0),
+ DataDynamic, MaskOtc, BGx(0), FGx(0)));
+
+ SET_LENXY_START_RECFILL(fb_info, packed_len);
+
+ NGLE_UNLOCK(fb_info);
}
static void
@@ -675,10 +762,7 @@
ngleResetAttrPlanes(fb_info, controlPlaneReg);
/* clear overlay planes */
- if (fb_info->bpp == 8)
- ngleClearOverlayPlanes(fb_info, 0xff, 0);
- else
- ngleClearOverlayPlanes(fb_info, 0xff, 255);
+ ngleClearOverlayPlanes(fb_info, 0xff, 255);
/**************************************************
** Also need to counteract ITE settings
@@ -978,11 +1062,19 @@
p->palette[regno].green = green;
p->palette[regno].blue = blue;
- START_IMAGE_COLORMAP_ACCESS(p);
- WRITE_IMAGE_COLOR(p, regno, color);
-
if (p->id == S9000_ID_HCRX) {
NgleLutBltCtl lutBltCtl;
+ int i;
+
+ START_IMAGE_COLORMAP_ACCESS(p);
+ for (i = 0; i < 256; i++) {
+ color = ((p->palette[i].red << 16) |
+ (p->palette[i].green << 8) |
+ (p->palette[i].blue));
+
+ WRITE_IMAGE_COLOR(p, i, color);
+ }
+
lutBltCtl = setHyperLutBltCtl(p,
0, /* Offset w/i LUT */
256); /* Load entire LUT */
@@ -992,6 +1084,8 @@
START_COLORMAPLOAD(p, lutBltCtl.all);
SETUP_FB(p);
} else {
+ START_IMAGE_COLORMAP_ACCESS(p);
+ WRITE_IMAGE_COLOR(p, regno, color);
/* cleanup colormap hardware */
FINISH_IMAGE_COLORMAP_ACCESS(p);
}
@@ -1176,7 +1270,9 @@
#if 1
/* HACK: Only allow an Artist gfx */
- if (fb_info.id != S9000_ID_ARTIST) {
+ if ((fb_info.id != S9000_ID_ARTIST) &&
+ (fb_info.id != S9000_ID_HCRX) &&
+ (fb_info.id != CRT_ID_VISUALIZE_EG)) {
return -ENXIO;
}
#endif
@@ -1230,15 +1326,18 @@
break;
case S9000_ID_HCRX: /* Hyperdrive/HCRX */
memset(&fb_info.ngle_rom, 0, sizeof(fb_info.ngle_rom));
- fb_info.bpp = 24;
if ((fb_info.sti->regions_phys[0] & 0xfc000000) ==
(fb_info.sti->regions_phys[2] & 0xfc000000))
sti_rom_address = fb_info.sti->regions_phys[2];
else
sti_rom_address = fb_info.sti->regions_phys[3];
+ fb_info.deviceSpecificConfig = gsc_readl(sti_rom_address);
+ if (IS_24_DEVICE((&fb_info)))
+ fb_info.bpp = 24;
+ else
+ fb_info.bpp = 8;
READ_WORD(fb_info.iobase + REG_15);
SETUP_HW(&fb_info);
- fb_info.deviceSpecificConfig = gsc_readl(sti_rom_address);
break;
case CRT_ID_VISUALIZE_EG:
case S9000_ID_ARTIST: /* Artist */
--
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea. [ Alexander Viro on linux-kernel ]