[parisc-linux-cvs] pa11, more stifb-code for non-artist gfx's
Helge Deller
deller@gmx.de
Wed, 11 Jul 2001 00:21:54 +0200
- EXTRAVERSION = -pa11
- more code for other gfx chips other than artist
(but still #ifdef'ed out for non-artist chips. Feel free to
take this #if..#endif out and test the code)
Index: Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/Makefile,v
retrieving revision 1.93
diff -u -r1.93 Makefile
--- Makefile 2001/07/10 16:50:51 1.93
+++ Makefile 2001/07/10 22:10:07
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 6
-EXTRAVERSION = -pa10
+EXTRAVERSION = -pa11
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
Index: drivers/video/sti/stifb.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.18
diff -u -r1.18 stifb.c
--- stifb.c 2001/07/08 12:41:57 1.18
+++ stifb.c 2001/07/10 22:10:19
@@ -37,7 +37,16 @@
* for more details.
*/
+/* TODO:
+ * - Artist gfx is the only supported chip atm,
+ * - remove the static fb_info to support multiple cards
+ * - remove the completely untested 1bpp mode
+ * - add support for h/w acceleration
+ * - add hardware cursor
+ * -
+ */
+
/* on supported graphic devices you may:
* #define FALLBACK_TO_1BPP to fall back to 1 bpp, or
* #undef FALLBACK_TO_1BPP to reject support for unsupported cards */
@@ -58,7 +67,6 @@
#include <linux/selection.h>
#include <video/fbcon.h>
-#include <video/fbcon-cfb4.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb24.h>
@@ -100,7 +108,7 @@
struct stifb_info {
struct fb_info_gen gen;
struct sti_struct *sti;
- __u32 id;
+ unsigned int id, real_id;
unsigned long iobase;
unsigned long smem_start; /* Start of frame buffer mem (physical address) */
unsigned long smem_len; /* size of framebuffer */
@@ -108,6 +116,8 @@
char *screen_base; /* Virtual address (io-remapped) */
int grayscale;
int bpp;
+ int screenWidth;
+ int screenHeight;
int deviceSpecificConfig;
ngle_rom_t ngle_rom;
struct { u_short red, green, blue; } palette[256];
@@ -143,6 +153,7 @@
#define REG_12 0x01800c
#define REG_13 0x018018
#define REG_14 0x01801c
+#define REG_15 0x200000
#define REG_15b0 0x200000
#define REG_16b1 0x200005
#define REG_16b3 0x200007
@@ -155,6 +166,12 @@
#define REG_33 0x210040
#define REG_34 0x200008
#define REG_38 0x210020
+#define REG_39 0x210120
+#define REG_40 0x210130
+#define REG_42 0x210028
+#define REG_43 0x21002c
+#define REG_44 0x210030
+#define REG_45 0x210034
#define READ_BYTE(base) readb(base)
#define READ_WORD(base) readl(base)
@@ -184,7 +201,6 @@
SETUP_FB(struct stifb_info *fb_info)
{
unsigned int reg10_value = 0;
- int depth = fb_info->bpp;
SETUP_HW(fb_info);
switch (fb_info->id)
@@ -194,13 +210,13 @@
reg10_value = 0x13601000;
break;
case S9000_ID_A1439A:
- if (depth == 24)
+ if (fb_info->bpp == 24)
reg10_value = 0xBBA0A000;
else
reg10_value = 0x13601000;
break;
case S9000_ID_HCRX:
- if (depth == 24)
+ if (fb_info->bpp == 24)
reg10_value = 0xBBA0A000;
else
reg10_value = 0x13602000;
@@ -470,13 +486,31 @@
ngleSetupAttrPlanes(struct stifb_info *fb_info, int BufferNumber)
{
SETUP_ATTR_ACCESS(fb_info, BufferNumber);
- SET_ATTR_SIZE(fb_info, current_par.x_virt, current_par.y_virt );
- /* XXX: pScreenPriv->screenWidth, pScreenPriv->screenHeight */
+ SET_ATTR_SIZE(fb_info, fb_info->screenWidth, fb_info->screenHeight);
FINISH_ATTR_ACCESS(fb_info);
SETUP_FB(fb_info);
}
+static void
+rattlerSetupPlanes(struct stifb_info *fb_info)
+{
+ CRX24_SETUP_RAMDAC(fb_info);
+
+ /* replacement for: SETUP_FB(fb_info, CRX24_OVERLAY_PLANES); */
+ WRITE_WORD(0x83000300, fb_info->iobase + REG_14);
+ SETUP_HW(fb_info);
+ WRITE_BYTE(1, fb_info->iobase + REG_16b1);
+
+ /* XXX: replace by fb_setmem(), smem_start or screen_base ? */
+ memset_io(fb_info->smem_start, 0xff,
+ fb_info->screenHeight*fb_info->line_length);
+
+ CRX24_SET_OVLY_MASK(fb_info);
+ SETUP_FB(fb_info);
+}
+
+
#define HYPER_CMAP_TYPE 0
#define NGLE_CMAP_INDEXED0_TYPE 0
#define NGLE_CMAP_OVERLAY_TYPE 3
@@ -500,7 +534,6 @@
static NgleLutBltCtl
setNgleLutBltCtl(struct stifb_info *fb_info, int offsetWithinLut, int length)
{
- int depth = fb_info->bpp;
NgleLutBltCtl lutBltCtl;
/* set enable, zero reserved fields */
@@ -510,7 +543,7 @@
switch (fb_info->id)
{
case S9000_ID_A1439A: /* CRX24 */
- if (depth == 8) {
+ if (fb_info->bpp == 8) {
lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE;
lutBltCtl.fields.lutOffset = 0;
} else {
@@ -540,7 +573,6 @@
static NgleLutBltCtl
setHyperLutBltCtl(struct stifb_info *fb_info, int offsetWithinLut, int length)
{
- int depth = fb_info->bpp;
NgleLutBltCtl lutBltCtl;
/* set enable, zero reserved fields */
@@ -550,7 +582,7 @@
lutBltCtl.fields.lutType = HYPER_CMAP_TYPE;
/* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */
- if (depth == 8)
+ if (fb_info->bpp == 8)
lutBltCtl.fields.lutOffset = 2 * 256;
else
lutBltCtl.fields.lutOffset = 0 * 256;
@@ -634,7 +666,7 @@
controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
switch (enable) {
- case 1: /* SERVER_INIT */
+ case 1: /* ENABLE */
/* clear screen */
if (IS_24_DEVICE(fb_info))
ngleDepth24_ClearImagePlanes(fb_info);
@@ -657,7 +689,7 @@
hyperUndoITE(fb_info);
break;
- case 0: /* SERVER_EXIT */
+ case 0: /* DISABLE */
/* clear screen */
if (IS_24_DEVICE(fb_info))
ngleDepth24_ClearImagePlanes(fb_info);
@@ -667,7 +699,7 @@
ngleClearOverlayPlanes(fb_info, 0xff, 0);
break;
- case -1: /* SERVER_RECOVERY */
+ case -1: /* RESET */
hyperUndoITE(fb_info);
ngleResetAttrPlanes(fb_info, controlPlaneReg);
break;
@@ -678,10 +710,11 @@
/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */
-#if 0
static void
ngleGetDeviceRomData(struct stifb_info *fb_info)
{
+#if 0
+XXX: FIXME: !!!
int *pBytePerLongDevDepData;/* data byte == LSB */
int *pRomTable;
NgleDevRomData *pPackedDevRomData;
@@ -733,12 +766,59 @@
*pCard8++ = (Card8) (*pBytePerLongDevDepData++);
}
}
-
- SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth);
- return(pPackedDevRomData);
-} /* ngleGetDeviceRomData() */
+ SETUP_FB(fb_info);
#endif
+}
+
+
+#define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES 4
+#define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE 8
+#define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE 10
+#define HYPERBOWL_MODE2_8_24 15
+
+/* HCRX specific boot-time initialization */
+static void __init
+SETUP_HCRX(struct stifb_info *fb_info)
+{
+ int hyperbowl;
+ int nFreeFifoSlots = 0;
+ unsigned long base = fb_info->iobase;
+
+ if (fb_info->id != S9000_ID_HCRX)
+ return;
+
+ /* Initialize Hyperbowl registers */
+ GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 7);
+
+ if (IS_24_DEVICE(fb_info)) {
+ hyperbowl = (fb_info->bpp == 24) ?
+ HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
+ HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE;
+
+ /* First write to Hyperbowl must happen twice (bug) */
+ WRITE_WORD(hyperbowl, base + REG_40);
+ WRITE_WORD(hyperbowl, base + REG_40);
+
+ WRITE_WORD(HYPERBOWL_MODE2_8_24, base + REG_39);
+
+ WRITE_WORD(0x014c0148, base + REG_42); /* Set lut 0 to be the direct color */
+ WRITE_WORD(0x404c4048, base + REG_43);
+ WRITE_WORD(0x034c0348, base + REG_44);
+ WRITE_WORD(0x444c4448, base + REG_45);
+ } else {
+ hyperbowl = HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES;
+
+ /* First write to Hyperbowl must happen twice (bug) */
+ WRITE_WORD(hyperbowl, base + REG_40);
+ WRITE_WORD(hyperbowl, base + REG_40);
+
+ WRITE_WORD(0x00000000, base + REG_42);
+ WRITE_WORD(0x00000000, base + REG_43);
+ WRITE_WORD(0x00000000, base + REG_44);
+ WRITE_WORD(0x444c4048, base + REG_45);
+ }
+}
/* ------------------- driver specific functions --------------------------- */
@@ -757,6 +837,8 @@
fix->line_length = fb_info->line_length;
fix->smem_start = fb_info->smem_start;
fix->smem_len = fb_info->smem_len;
+ fix->mmio_start = fb_info->iobase; /* ioremap() ? */
+ fix->mmio_len = 0x300000; /* XXX */
if (par->bpp == 1) {
fix->type = FB_TYPE_PLANES; /* well, sort of */
@@ -807,11 +889,26 @@
var->yres_virtual = par->y_virt;
var->xoffset = var->yoffset = 0;
var->bits_per_pixel = par->bpp;
- var->grayscale = 0;
+ var->grayscale = 0; /* XXX: ((struct stifb_info *)info)->grayscale; */
var->height = -1;
var->width = -1;
var->vmode = FB_VMODE_NONINTERLACED;
+ if (par->bpp == 24) {
+ /* correct the RGB masks and offsets */
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+
+ var->red.msb_right =
+ var->green.msb_right =
+ var->blue.msb_right = 8;
+
+ var->red.msb_right =
+ var->green.msb_right =
+ var->blue.msb_right = 0; /* XXX: !=0: Most significant bit is right */
+ }
+
return 0;
}
@@ -819,11 +916,12 @@
stifb_get_par(void *par, struct fb_info_gen *info)
{
if (!current_par_valid) {
- current_par.x = sti_onscreen_x(fb_info.sti);
- current_par.y = sti_onscreen_y(fb_info.sti);
- current_par.x_virt = PTR_STI(fb_info.sti->glob_cfg)->total_x;
- current_par.y_virt = PTR_STI(fb_info.sti->glob_cfg)->total_y;
- current_par.bpp = fb_info.bpp;
+ struct stifb_info *p = (struct stifb_info *) info;
+ current_par.x = p->screenWidth;
+ current_par.y = p->screenHeight;
+ current_par.x_virt = PTR_STI(p->sti->glob_cfg)->total_x;
+ current_par.y_virt = PTR_STI(p->sti->glob_cfg)->total_y;
+ current_par.bpp = p->bpp;
current_par_valid = 1;
}
*(struct stifb_par *)par = current_par;
@@ -900,50 +998,12 @@
}
static void
-stifb_set_disp(const void *_par,
- struct display *disp,
- struct fb_info_gen *info)
-{
- struct stifb_info *fb_info = (struct stifb_info *) info;
- const struct stifb_par *par = _par;
-
- disp->screen_base = fb_info->screen_base;
-
- /* Hack: Currently only Artist-Framebuffer supported ! */
- if (fb_info->id == S9000_ID_ARTIST) {
- // elkSetupPlanes(fb_info); /* XXX */
- ngleSetupAttrPlanes(fb_info, ARTIST_CMAP0);
- // ngleSetupAttrPlanes(fb_info, BUFF0_CMAP0);
- ARTIST_ENABLE_DISABLE_DISPLAY(fb_info, ENABLE);
- SETUP_FB(fb_info);
- }
-
- switch(par->bpp) {
-#ifdef FBCON_HAS_CFB24
- case 24:disp->dispsw = &fbcon_cfb24;
- break;
-#endif
-#ifdef FBCON_HAS_CFB8
- case 8: disp->dispsw = &fbcon_cfb8;
- break;
-#endif
- case 1: disp->dispsw = &fbcon_sti;
- break;
-
- default:
- disp->dispsw = &fbcon_dummy;
- }
-
- disp->scrollmode = SCROLL_YREDRAW;
-}
-
-static void
stifb_detect(void)
{
struct stifb_par par;
- par.x = sti_onscreen_x(fb_info.sti);
- par.y = sti_onscreen_y(fb_info.sti);
+ par.x = fb_info.screenWidth;
+ par.y = fb_info.screenHeight;
par.x_virt = PTR_STI(fb_info.sti->glob_cfg)->total_x;
par.y_virt = PTR_STI(fb_info.sti->glob_cfg)->total_y;
par.bpp = fb_info.bpp;
@@ -985,6 +1045,65 @@
return 1; /* FIXME: should be 0 later ! */
}
+static void
+stifb_set_disp(const void *_par,
+ struct display *disp,
+ struct fb_info_gen *info)
+{
+ struct stifb_info *fb_info = (struct stifb_info *) info;
+ const struct stifb_par *par = _par;
+ int id = fb_info->id;
+
+ disp->screen_base = fb_info->screen_base;
+ disp->scrollmode = SCROLL_YREDRAW;
+
+ /*
+ if (id == S9000_ID_HCRX)
+ hyperInitSprite(fb_info);
+ else
+ ngleInitSprite(fb_info);
+ */
+
+ /* Initialize the image planes. */
+ if (id == S9000_ID_HCRX)
+ hyperResetPlanes(fb_info, ENABLE);
+ else if (id == S9000_ID_A1439A)
+ rattlerSetupPlanes(fb_info);
+ else if (id == S9000_ID_A1659A /* || id == S9000_ID_ARTIST*/)
+ elkSetupPlanes(fb_info);
+
+ /* Clear attribute planes on non HCRX devices. */
+ if (id == S9000_ID_A1659A || id == S9000_ID_A1439A ||
+ id == S9000_ID_ARTIST) {
+ if (fb_info->bpp == 24)
+ ngleSetupAttrPlanes(fb_info, BUFF1_CMAP3);
+ else
+ ngleSetupAttrPlanes(fb_info, (id==S9000_ID_ARTIST) ?
+ ARTIST_CMAP0 : BUFF1_CMAP0);
+ }
+
+ stifb_blank(0, info); /* 0=enable screen */
+
+ SETUP_FB(fb_info);
+
+ switch(par->bpp) {
+#ifdef FBCON_HAS_CFB24
+ case 24:disp->dispsw = &fbcon_cfb24;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB8
+ case 8: disp->dispsw = &fbcon_cfb8;
+ break;
+#endif
+ case 1: disp->dispsw = &fbcon_sti;
+ break;
+
+ default:
+ disp->dispsw = &fbcon_dummy;
+ }
+}
+
+
/* ------------ Interfaces to hardware functions ------------ */
struct fbgen_hwswitch stifb_switch = {
@@ -1022,6 +1141,8 @@
stifb_init(void)
{
static int stifb_initialized;
+ unsigned long sti_rom_address;
+ char *dev_name;
if (stifb_initialized) {
printk(KERN_WARNING "WARNING: Only one stifb will be supported currently.\n");
@@ -1036,6 +1157,14 @@
/* store upper 32bits of the graphics id */
fb_info.id = fb_info.sti->graphics_id[0];
+ fb_info.real_id = fb_info.id; /* save the real id */
+
+#if 1
+ /* HACK: Only allow an Artist gfx */
+ if (fb_info.id != S9000_ID_ARTIST) {
+ return -ENXIO;
+ }
+#endif
/* get (virtual) io region base addr */
fb_info.iobase = REGION_BASE(fb_info,2);
@@ -1049,29 +1178,54 @@
fb_info.line_length;
fb_info.screen_base = (void*) REGION_BASE(fb_info,1);
+ fb_info.screenWidth = sti_onscreen_x(fb_info.sti);
+ fb_info.screenHeight = sti_onscreen_y(fb_info.sti);
+
+ /* default to 8 bpp on most graphic chips */
+ fb_info.bpp = 8;
+
+ ngleGetDeviceRomData(&fb_info);
+
/* Reject any device not in the NGLE family */
- /* FIXME: At this stage only Artist fb is supported! */
switch (fb_info.id) {
- case S9000_ID_A1659A: /* CRX */
- printk("Found CRX/A1659A graphics. Support is not finished yet.\n");
- return -ENODEV;
- case S9000_ID_ELM: /* GRX */
- printk("Found ELM/GRX graphics. Support is not finished yet.\n");
- return -ENODEV;
- case S9000_ID_TIMBER: /* 710 Any */
- printk("Found Timber/710 style graphics. Support is not finished yet.\n");
- return -ENODEV;
- case S9000_ID_TOMCAT: /* Dual CRX */
- printk("Found Tomcat/Dual-CRX graphics. Support is not finished yet.\n");
- return -ENODEV;
- case S9000_ID_A1439A: /* CRX24 */
- printk("Found CRX24/A1439A graphics. Support is not finished yet.\n");
- return -ENODEV;
- case S9000_ID_HCRX: /* Hyperdrive */
- printk("Found Hyperdrive/HCRX graphics. Support is not finished yet.\n");
- return -ENODEV;
+ case S9000_ID_A1659A: /* CRX/A1659A */
+ break;
+ case S9000_ID_ELM: /* GRX, grayscale but else same as A1659A */
+ fb_info.grayscale = 1;
+ fb_info.id = S9000_ID_A1659A;
+ break;
+ case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
+ dev_name = fb_info.sti->outptr.dev_name;
+ if (strstr(dev_name, "GRAYSCALE") ||
+ strstr(dev_name, "Grayscale") ||
+ strstr(dev_name, "grayscale"))
+ fb_info.grayscale = 1;
+ break;
+ case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */
+ /* FIXME: TomCat supports two heads:
+ * fb_info.iobase = REGION_BASE(fb_info,3);
+ * fb_info.screen_base = (void*) REGION_BASE(fb_info,2);
+ * for now we only support the left one ! */
+ fb_info.screenWidth = fb_info.ngle_rom.x_size_visible;
+ fb_info.screenHeight = fb_info.ngle_rom.y_size_visible;
+ fb_info.id = S9000_ID_A1659A;
+ break;
+ case S9000_ID_A1439A: /* CRX24/A1439A */
+ fb_info.bpp = 24;
+ 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];
+ READ_WORD(fb_info.iobase + REG_15);
+ SETUP_HW(&fb_info);
+ fb_info.deviceSpecificConfig = gsc_readl(sti_rom_address);
+ break;
case S9000_ID_ARTIST: /* Artist */
- fb_info.bpp = 8; /* default to 8 bpp */
break;
default:
#ifdef FALLBACK_TO_1BPP
@@ -1089,7 +1243,12 @@
return -ENXIO;
#endif
}
-
+
+ SETUP_FB(&fb_info);
+
+ /* HCRX specific initialization */
+ SETUP_HCRX(&fb_info);
+
strcpy(fb_info.gen.info.modename, "stifb");
fb_info.gen.info.node = -1;
fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;