[parisc-linux-cvs] ioremap() and stifb

Helge Deller deller@gmx.de
Mon, 18 Jun 2001 00:40:57 +0200


--------------Boundary-00=_90J3YWS58D6OB5E2FB6R
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 8bit
Subject: 

Modified files:
        .              : Makefile 
        arch/parisc/mm : Makefile ioremap.c 
        drivers/video  : fbmem.c 
        drivers/video/sti: stifb.c 
        include/asm-parisc: io.h pgtable.h 
        include/video  : fbcon.h 

Log message:
- using EXTRAVERSION=-pa27 (assuming tbogend's last commit was -pa26)
- activate compilation of arch/parisc/mm/ioremap.c
- minor cleanups in ioremap.c, addition of #if/#endif for USE_HPPA_IOREMAP
- USE_HPPA_IOREMAP is the flag for usage of ioremap() (in include/asm-parisc/io.h)
"#define USE_HPPA_IOREMAP 0" is the default
- take out hppa specific warning in fbmem.c
- much new code for other graphic cards than artist in stifb.c (unfinished)
- added "#define _PAGE_RW (_PAGE_READ | _PAGE_WRITE)" to pgtable.h
- used gsc_read/write() for fb-access _only_ if USE_HPPA_IOREMAP is zero.

Some more information to the patch:
The following patch activates the compilation of arch/parisc/mm/ioremap.c, but as long as USE_HPPA_IOREMAP in include/asm-parisc/io.h is defined to zero ioremap() will just return the given address back. That way the patch will currently work on older and newer machines and aids me to get more stifb work done. 


--------------Boundary-00=_90J3YWS58D6OB5E2FB6R
Content-Type: text/x-makefile;
  charset="iso-8859-1";
  name="FINAL_DIFF"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="FINAL_DIFF"

Index: Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/Makefile,v
retrieving revision 1.58
diff -u -r1.58 Makefile
--- Makefile	2001/06/14 16:13:12	1.58
+++ Makefile	2001/06/17 22:11:52
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -pa25
+EXTRAVERSION = -pa27
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/mm/Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/mm/Makefile,v
retrieving revision 1.5
diff -u -r1.5 Makefile
--- Makefile	2001/01/28 04:16:40	1.5
+++ Makefile	2001/06/17 22:11:54
@@ -8,6 +8,6 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-obj-y	 := init.o fault.o extable.o
+obj-y	 := init.o fault.o extable.o ioremap.o
 
 include $(TOPDIR)/Rules.make
Index: arch/parisc/mm/ioremap.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/mm/ioremap.c,v
retrieving revision 1.1
diff -u -r1.1 ioremap.c
--- ioremap.c	2001/06/16 17:11:48	1.1
+++ ioremap.c	2001/06/17 22:11:55
@@ -50,7 +50,7 @@
 	if (address >= end)
 		BUG();
 	do {
-		pte_t * pte = pte_alloc(pmd, address); /* pte_alloc(&init_mm, pmd, address); */
+		pte_t * pte = pte_alloc(pmd, address);
 		if (!pte)
 			return -ENOMEM;
 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -75,7 +75,7 @@
 	spin_lock(&init_mm.page_table_lock);
 	do {
 		pmd_t *pmd;
-		pmd = pmd_alloc(dir, address); /* pmd_alloc(&init_mm, dir, address); */
+		pmd = pmd_alloc(dir, address);
 		error = -ENOMEM;
 		if (!pmd)
 			break;
@@ -106,6 +106,11 @@
  */
 void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
+#if !(USE_HPPA_IOREMAP)
+
+	return phys_addr;
+
+#else
 	void * addr;
 	struct vm_struct * area;
 	unsigned long offset, last_addr;
@@ -116,12 +121,6 @@
 		return NULL;
 
 	/*
-	 * Don't remap the low PCI/ISA area, it's always mapped..
-	 */
-//	if (phys_addr >= 0xA0000 && last_addr < 0x100000)
-//		return phys_to_virt(phys_addr);
-
-	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
 	if (phys_addr < virt_to_phys(high_memory)) {
@@ -155,10 +154,15 @@
 		return NULL;
 	}
 	return (void *) (offset + (char *)addr);
+#endif
 }
 
 void iounmap(void *addr)
 {
+#if !(USE_HPPA_IOREMAP)
+	return;
+#else
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+#endif
 }
Index: drivers/video/fbmem.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/fbmem.c,v
retrieving revision 1.11
diff -u -r1.11 fbmem.c
--- fbmem.c	2001/03/02 00:54:55	1.11
+++ fbmem.c	2001/06/17 22:12:10
@@ -607,8 +607,7 @@
 #elif defined(__sh__)
 	pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE;
 #elif defined(__hppa__)
-#warning "****** IS THIS CORRECT FOR HP PARISC ??  (FIXME !!) ************"
-	pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+	pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; 
 #else
 #warning What do we have to do here??
 #endif
Index: drivers/video/sti/stifb.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.14
diff -u -r1.14 stifb.c
--- stifb.c	2001/06/17 21:21:15	1.14
+++ stifb.c	2001/06/17 22:12:11
@@ -68,12 +68,50 @@
 
 extern struct display_switch fbcon_sti; /* fbcon-sti.c */
 
+#define HPPA_IOREMAP(addr,len) \
+	ioremap(addr,len)
+
+#define REGION_BASE(fb_info, index) \
+	PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[index]
+	
+#define NGLEDEVDEPROM_CRT_REGION 1
+
+typedef struct {
+	__s32	video_config_reg;
+	__s32	misc_video_start;
+	__s32	horiz_timing_fmt;
+	__s32	serr_timing_fmt;
+	__s32	vert_timing_fmt;
+	__s32	horiz_state;
+	__s32	vert_state;
+	__s32	vtg_state_elements;
+	__s32	pipeline_delay;
+	__s32	misc_video_end;
+} video_setup_t;
+
+typedef struct {                  
+	__s16	sizeof_ngle_data;
+	__s16	x_size_visible;	    /* visible screen dim in pixels  */
+	__s16	y_size_visible;
+	__s16	pad2[15];
+	__s16	cursor_pipeline_delay;
+	__s16	video_interleaves;
+	__s32	pad3[11];
+} ngle_rom_t;
+
 struct stifb_info {
 	struct fb_info_gen gen;
 	struct sti_struct *sti;
 	__u32 id;
 	unsigned long iobase;
+	unsigned long smem_start; /* Start of frame buffer mem (physical address) */
+	unsigned long smem_len;		/* size of framebuffer */
+	unsigned int  line_length;	/* length of one line in bytes */
+	char *screen_base;		/* Virtual address (io-remapped) */
+	int grayscale;
 	int bpp;
+	int deviceSpecificConfig;
+	ngle_rom_t ngle_rom;
 	struct { u_short red, green, blue; } palette[256];
 };
 
@@ -109,6 +147,7 @@
 #define REG_14  	0x01801c
 #define REG_15b0	0x200000
 #define REG_16b1	0x200005
+#define REG_16b3	0x200007
 #define REG_21		0x200218
 #define REG_22		0x0005a0
 #define REG_23		0x0005c0
@@ -116,6 +155,8 @@
 #define REG_27		0x200308
 #define REG_32		0x21003c
 #define REG_33		0x210040
+#define REG_34		0x200008
+#define REG_38		0x210020
 
 #define READ_BYTE(base)		gsc_readb(base)
 #define READ_WORD(base)		gsc_readl(base)
@@ -125,6 +166,9 @@
 #define ENABLE	1	/* for enabling/disabling screen */	
 #define DISABLE 0
 
+#define NGLE_LOCK(fb_info)
+#define NGLE_UNLOCK(fb_info)
+
 static void
 SETUP_HW(struct stifb_info *fb_info)
 {
@@ -284,6 +328,90 @@
 	}
 }
 
+#define GET_ROMTABLE_INDEX(fb_info) \
+	(READ_BYTE(fb_info->iobase + REG_16b3) - 1)
+
+#define HYPER_CONFIG_PLANES_24 0x00000100
+	
+#define IS_24_DEVICE(fb_info) \
+	(fb_info->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)
+
+#define IS_888_DEVICE(fb_info) \
+	(!(IS_24_DEVICE(fb_info)))
+
+#define GET_FIFO_SLOTS(fb_info, cnt, numslots)			\
+{	while (cnt < numslots) 					\
+		cnt = READ_WORD(fb_info->iobase + REG_34);	\
+	cnt -= numslots;					\
+}
+
+#define	    IndexedDcd	0	/* Pixel data is indexed (pseudo) color */
+#define	    Otc04	2	/* Pixels in each longword transfer (4) */
+#define	    Otc32	5	/* Pixels in each longword transfer (32) */
+#define	    Ots08	3	/* Each pixel is size (8)d transfer (1) */
+#define	    OtsIndirect	6	/* Each bit goes through FG/BG color(8) */
+#define	    AddrLong	5	/* FB address is Long aligned (pixel) */
+#define	    BINovly	0x2	/* 8 bit overlay */
+#define	    BINapp0I	0x0	/* Application Buffer 0, Indexed */
+#define	    BINapp1I	0x1	/* Application Buffer 1, Indexed */
+#define	    BINapp0F8	0xa	/* Application Buffer 0, Fractional 8-8-8 */
+#define	    BINattr	0xd	/* Attribute Bitmap */
+#define	    RopSrc 	0x3
+#define	    BitmapExtent08  3	/* Each write hits ( 8) bits in depth */
+#define	    BitmapExtent32  5	/* Each write hits (32) bits in depth */
+#define	    DataDynamic	    0	/* Data register reloaded by direct access */
+#define	    MaskDynamic	    1	/* Mask register reloaded by direct access */
+#define	    MaskOtc	    0	/* Mask contains Object Count valid bits */
+
+#define MaskAddrOffset(offset) (offset)
+#define StaticReg(en) (en)
+#define BGx(en) (en)
+#define FGx(en) (en)
+
+#define BAJustPoint(offset) (offset)
+#define BAIndexBase(base) (base)
+#define BA(F,C,S,A,J,B,I) \
+	(((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I))
+
+#define IBOvals(R,M,X,S,D,L,B,F) \
+	(((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F))
+
+#define NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb_info, val) \
+	WRITE_WORD(val, fb_info->iobase + REG_14)
+
+#define NGLE_QUICK_SET_DST_BM_ACCESS(fb_info, val) \
+	WRITE_WORD(val, fb_info->iobase + REG_11)
+
+#define NGLE_QUICK_SET_CTL_PLN_REG(fb_info, val) \
+	WRITE_WORD(val, fb_info->iobase + REG_12)
+
+#define NGLE_REALLY_SET_IMAGE_PLANEMASK(fb_info, plnmsk32) \
+	WRITE_WORD(plnmsk32, fb_info->iobase + REG_13)
+
+#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb_info, fg32) \
+	WRITE_WORD(fg32, fb_info->iobase + REG_35)
+	
+#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) (		\
+	(unsigned long) (fbaddrbase) +				\
+	    (	(unsigned int)  ( (y) << 13      ) |		\
+		(unsigned int)  ( (x) << 2       )	)	\
+	)
+
+#define NGLE_BINC_SET_DSTADDR(fb_info, addr) \
+	WRITE_WORD(addr, fb_info->iobase + REG_3)
+
+#define NGLE_BINC_SET_SRCADDR(fb_info, addr) \
+	WRITE_WORD(addr, fb_info->iobase + REG_2)
+
+#define NGLE_BINC_SET_DSTMASK(fb_info, mask) \
+	WRITE_WORD(mask, fb_info->iobase + REG_22)
+
+#define NGLE_BINC_WRITE32(fb_info, data32) \
+	WRITE_WORD(data32, fb_info->iobase + REG_23)
+
+#define START_COLORMAPLOAD(fb_info, cmapBltCtlData32) \
+	WRITE_WORD((cmapBltCtlData32), fb_info->iobase + REG_38)
+	
 static void
 HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb_info, int enable)
 {
@@ -294,7 +422,7 @@
 	if (enable)
 		value |= 0x0A000000;
 	else
-		value &= ~~0x0A000000;
+		value &= ~0x0A000000;
 	WRITE_WORD(value, DregsHypMiscVideo);
 }
 
@@ -351,24 +479,286 @@
 }
 
 
+#define HYPER_CMAP_TYPE				0
+#define NGLE_CMAP_INDEXED0_TYPE			0
+#define NGLE_CMAP_OVERLAY_TYPE			3
+
+/* typedef of LUT (Colormap) BLT Control Register */
+typedef union	/* Note assumption that fields are packed left-to-right */
+{	unsigned long   all;
+	struct
+	{
+		unsigned enable              :  1;
+		unsigned waitBlank           :  1;
+		unsigned reserved1           :  4;
+		unsigned lutOffset           : 10;   /* Within destination LUT */
+		unsigned lutType             :  2;   /* Cursor, image, overlay */
+		unsigned reserved2           :  4;
+		unsigned length              : 10;
+	} fields;
+} NgleLutBltCtl;
+
+
+static NgleLutBltCtl
+setNgleLutBltCtl(struct stifb_info *fb_info, int offsetWithinLut, int length)
+{
+	int depth = fb_info->bpp;
+	NgleLutBltCtl lutBltCtl;
+
+	/* set enable, zero reserved fields */
+	lutBltCtl.all           = 0x80000000;
+	lutBltCtl.fields.length = length;
+
+	switch (fb_info->id) 
+	{
+	case S9000_ID_A1439A:		/* CRX24 */
+		if (depth == 8) {
+			lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE;
+			lutBltCtl.fields.lutOffset = 0;
+		} else {
+			lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+			lutBltCtl.fields.lutOffset = 0 * 256;
+		}
+		break;
+		
+	case S9000_ID_ARTIST:
+		lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+		lutBltCtl.fields.lutOffset = 0 * 256;
+		break;
+		
+	default:
+		lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+		lutBltCtl.fields.lutOffset = 0;
+		break;
+	}
+
+	/* Offset points to start of LUT.  Adjust for within LUT */
+	lutBltCtl.fields.lutOffset += offsetWithinLut;
+
+	return lutBltCtl;
+}
+
+
+static NgleLutBltCtl
+setHyperLutBltCtl(struct stifb_info *fb_info, int offsetWithinLut, int length) 
+{
+	int depth = fb_info->bpp;
+	NgleLutBltCtl lutBltCtl;
+
+	/* set enable, zero reserved fields */
+	lutBltCtl.all = 0x80000000;
+
+	lutBltCtl.fields.length = length;
+	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)
+		lutBltCtl.fields.lutOffset = 2 * 256;
+	else
+		lutBltCtl.fields.lutOffset = 0 * 256;
+
+	/* Offset points to start of LUT.  Adjust for within LUT */
+	lutBltCtl.fields.lutOffset += offsetWithinLut;
+
+	return lutBltCtl;
+}
+
+
+static void hyperUndoITE(struct stifb_info *fb_info)
+{
+	int nFreeFifoSlots = 0;
+	unsigned long fbAddr;
+
+	NGLE_LOCK(fb_info);
+
+	GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 1);
+	WRITE_WORD(0xffffffff, fb_info->iobase + REG_32);
+
+	/* Write overlay transparency mask so only entry 255 is transparent */
+
+	/* Hardware setup for full-depth write to "magic" location */
+	GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 7);
+	NGLE_QUICK_SET_DST_BM_ACCESS(fb_info, 
+		BA(IndexedDcd, Otc04, Ots08, AddrLong,
+		BAJustPoint(0), BINovly, BAIndexBase(0)));
+	NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb_info,
+		IBOvals(RopSrc, MaskAddrOffset(0),
+		BitmapExtent08, StaticReg(0),
+		DataDynamic, MaskOtc, BGx(0), FGx(0)));
+
+	/* Now prepare to write to the "magic" location */
+	fbAddr = NGLE_LONG_FB_ADDRESS(0, 1532, 0);
+	NGLE_BINC_SET_DSTADDR(fb_info, fbAddr);
+	NGLE_REALLY_SET_IMAGE_PLANEMASK(fb_info, 0xffffff);
+	NGLE_BINC_SET_DSTMASK(fb_info, ~0UL);
+
+	/* Finally, write a zero to clear the mask */
+	NGLE_BINC_WRITE32(fb_info, 0);
+
+	NGLE_UNLOCK(fb_info);
+}
+
+static void 
+ngleDepth8_ClearImagePlanes(struct stifb_info *fb_info)
+{
+	/* FIXME! */
+}
+
+static void 
+ngleDepth24_ClearImagePlanes(struct stifb_info *fb_info)
+{
+	/* FIXME! */
+}
+
+static void
+ngleResetAttrPlanes(struct stifb_info *fb_info, int enable)
+{
+	/* FIXME! */
+}
+static void
+ngleClearOverlayPlanes(struct stifb_info *fb_info, int mask, int len)
+{
+}
+
+static void 
+hyperResetPlanes(struct stifb_info *fb_info, int enable)
+{
+	unsigned int controlPlaneReg;
+
+	NGLE_LOCK(fb_info);
+
+	if (IS_24_DEVICE(fb_info))
+		if (fb_info->bpp == 24)
+			controlPlaneReg = 0x04000F00;
+		else
+			controlPlaneReg = 0x00000F00;   /* 0x00000800 should be enought, but lets clear all 4 bits */
+	else
+		controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
+
+	switch (enable) {
+	case 1:		/* SERVER_INIT */
+		/* clear screen */
+		if (IS_24_DEVICE(fb_info))
+			ngleDepth24_ClearImagePlanes(fb_info);
+		else
+			ngleDepth8_ClearImagePlanes(fb_info);
+
+		/* Paint attribute planes for default case.
+		 * On Hyperdrive, this means all windows using overlay cmap 0. */
+		ngleResetAttrPlanes(fb_info, controlPlaneReg);
+
+		/* clear overlay planes */
+		if (fb_info->bpp == 8)
+			ngleClearOverlayPlanes(fb_info, 0xff, 0);
+		else
+			ngleClearOverlayPlanes(fb_info, 0xff, 255);
+
+		/**************************************************
+		 ** Also need to counteract ITE settings 
+		 **************************************************/
+		hyperUndoITE(fb_info);
+		break;
+
+	case 0:		/* SERVER_EXIT */
+		/* clear screen */
+		if (IS_24_DEVICE(fb_info))
+			ngleDepth24_ClearImagePlanes(fb_info);
+		else
+			ngleDepth8_ClearImagePlanes(fb_info);
+		ngleResetAttrPlanes(fb_info, controlPlaneReg);
+		ngleClearOverlayPlanes(fb_info, 0xff, 0);
+		break;
+
+	case -1:	/* SERVER_RECOVERY */
+		hyperUndoITE(fb_info);
+		ngleResetAttrPlanes(fb_info, controlPlaneReg);
+		break;
+    	}
+	
+	NGLE_UNLOCK(fb_info);
+}
+
+/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */
+
+#if 0
+static void 
+ngleGetDeviceRomData(struct stifb_info *fb_info)
+{
+	int	*pBytePerLongDevDepData;/* data byte == LSB */
+	int 	*pRomTable;
+	NgleDevRomData	*pPackedDevRomData;
+	int	sizePackedDevRomData = sizeof(*pPackedDevRomData);
+	char	*pCard8;
+	int	i;
+	char	*mapOrigin = NULL;
+    
+	int romTableIdx;
+
+	pPackedDevRomData = fb_info->ngle_rom;
+
+	SETUP_HW(fb_info);
+	if (fb_info->id == S9000_ID_ARTIST) {
+		pPackedDevRomData->cursor_pipeline_delay = 4;
+		pPackedDevRomData->video_interleaves     = 4;
+	} else {
+		/* Get pointer to unpacked byte/long data in ROM */
+		pBytePerLongDevDepData = fb_info->sti->regions[NGLEDEVDEPROM_CRT_REGION];
+
+		/* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480 */
+		if (fb_info->id == S9000_ID_TOMCAT)
+	{
+	    /*  jump to the correct ROM table  */
+	    GET_ROMTABLE_INDEX(romTableIdx);
+	    while  (romTableIdx > 0)
+	    {
+		pCard8 = (Card8 *) pPackedDevRomData;
+		pRomTable = pBytePerLongDevDepData;
+		/* Pack every fourth byte from ROM into structure */
+		for (i = 0; i < sizePackedDevRomData; i++)
+		{
+		    *pCard8++ = (Card8) (*pRomTable++);
+		}
+
+		pBytePerLongDevDepData = (Card32 *)
+			((Card8 *) pBytePerLongDevDepData +
+			       pPackedDevRomData->sizeof_ngle_data);
+
+		romTableIdx--;
+	    }
+	}
+
+	pCard8 = (Card8 *) pPackedDevRomData;
+
+	/* Pack every fourth byte from ROM into structure */
+	for (i = 0; i < sizePackedDevRomData; i++)
+	{
+	    *pCard8++ = (Card8) (*pBytePerLongDevDepData++);
+	}
+    }
+
+    SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth);
+
+    return(pPackedDevRomData);
+}   /* ngleGetDeviceRomData() */
+#endif
+
 
 /* ------------------- driver specific functions --------------------------- */
 
 static int
 stifb_encode_fix(struct fb_fix_screeninfo *fix,
-	       const void *_par,
-	       struct fb_info_gen *info)
+		const void *_par,
+		struct fb_info_gen *info)
 {
 	const struct stifb_par *par = _par;
-	
+	struct stifb_info *fb_info = info;
+
 	memset(fix, 0, sizeof(*fix));
 	
 	strcpy(fix->id, "stifb");
-	fix->line_length = PTR_STI(fb_info.sti->glob_cfg)->total_x;
-	if (!fix->line_length)
-	    fix->line_length = 2048; /* default */
-	fix->smem_start = PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
-	fix->smem_len = PTR_STI(fb_info.sti->glob_cfg)->total_y * fix->line_length;
+	fix->line_length = fb_info->line_length;
+	fix->smem_start = fb_info->smem_start;
+	fix->smem_len = fb_info->smem_len;
 
 	if (par->bpp == 1) {
 	    fix->type = FB_TYPE_PLANES;	/* well, sort of */
@@ -475,19 +865,38 @@
 	if (regno > 255)
 		return 1;
 	
-	color = (((red & 0xff00) << 8) | (green & 0xff00) |
+	if (p->grayscale) {
+		/* gray = 0.30*R + 0.59*G + 0.11*B */
+		color = red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+	} else {
+		color = (((red & 0xff00) << 8) | (green & 0xff00) |
 			((blue & 0xff00) >> 8) );
+		red >>= 8;
+		green >>= 8;
+		blue >>= 8;
+	}
 	
-	red >>= 8;
-	green >>= 8;
-	blue >>= 8;
 	p->palette[regno].red = red;
 	p->palette[regno].green = green;
 	p->palette[regno].blue = blue;
 
 	START_IMAGE_COLORMAP_ACCESS(p);
-	WRITE_IMAGE_COLOR(p, regno, color); 
-	FINISH_IMAGE_COLORMAP_ACCESS(p);
+	WRITE_IMAGE_COLOR(p, regno, color);
+
+	if (p->id == S9000_ID_HCRX) {
+		NgleLutBltCtl lutBltCtl;
+		lutBltCtl = setHyperLutBltCtl(p, 
+				0,	/* Offset w/i LUT */
+				256);	/* Load entire LUT */
+		NGLE_BINC_SET_SRCADDR(p,
+				NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); 
+				/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
+		START_COLORMAPLOAD(p, lutBltCtl.all);
+		SETUP_FB(p);
+	} else {
+		/* cleanup colormap hardware */
+		FINISH_IMAGE_COLORMAP_ACCESS(p);
+	}
 
 	return 0;
 }
@@ -497,18 +906,18 @@
 		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 =
-		(void *) PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
+	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); 
+	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) {
@@ -614,14 +1023,27 @@
 int __init
 stifb_init(void)
 {
+	/* set struct to a known state */
+	memset(&fb_info, 0, sizeof(fb_info));
+	
 	if (!(fb_info.sti = sti_init_roms()))
 		return -ENXIO;
 
 	/* store upper 32bits of the graphics id */
 	fb_info.id = fb_info.sti->graphics_id[0];
 	
-	/* and the io region base addr */
-	fb_info.iobase = PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[2];
+	/* get io region base addr */
+	fb_info.iobase = REGION_BASE(fb_info,2);
+
+	/* get framebuffer pysical and virtual base addr & len */
+	fb_info.smem_start = REGION_BASE(fb_info,1);
+	fb_info.line_length = PTR_STI(fb_info.sti->glob_cfg)->total_x;
+	if (!fb_info.line_length)
+	    fb_info.line_length = 2048; /* default */
+	fb_info.smem_len = PTR_STI(fb_info.sti->glob_cfg)->total_y *
+				fb_info.line_length;
+	fb_info.screen_base = HPPA_IOREMAP(fb_info.smem_start, 
+				PAGE_ALIGN(2048UL*fb_info.line_length));
 
        	/* Reject any device not in the NGLE family */
 	switch (fb_info.id) {
Index: include/asm-parisc/io.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/io.h,v
retrieving revision 1.17
diff -u -r1.17 io.h
--- io.h	2001/04/11 19:12:50	1.17
+++ io.h	2001/06/17 22:12:14
@@ -1,8 +1,17 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
+/* USE_HPPA_IOREMAP IS THE MAGIC FLAG TO ENABLE OR DISABLE REAL IOREMAP() FUNCTIONALITY */
+/* FOR 712 or 715 MACHINES THIS SHOULD BE ENABLED, 
+   NEWER MACHINES STILL HAVE SOME ISSUES IN THE SCSI AND/OR NETWORK DRIVERS AND 
+   BECAUSE OF THAT I WILL LEAVE IT DISABLED FOR NOW <deller@gmx.de> */
+/* WHEN THOSE ISSUES ARE SOLVED, USE_HPPA_IOREMAP WILL GO AWAY */
+#define USE_HPPA_IOREMAP 0
+
+
 #include <linux/config.h>
 #include <linux/types.h>
+#include <asm/pgtable.h>
 #include <asm/gsc.h>
 
 #define virt_to_phys(a) ((unsigned long)__pa(a))
@@ -46,11 +55,30 @@
 /* IO Port space is :      BBiiii   where BB is HBA number. */
 #define IO_SPACE_LIMIT 0x00ffffff
 
+
+
 /* Right now we don't support Dino-on-a-card and V class which do PCI MMIO
  * through address/data registers. */
+
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+extern inline void * ioremap(unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+{
+        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
+}
+
+extern void iounmap(void *addr);
 
-#define ioremap(__offset, __size)	((void *)(__offset))
-#define iounmap(__addr)
 
 #define dma_cache_inv(_start,_size)		do { flush_kernel_dcache_range(_start,_size); } while(0)
 #define dma_cache_wback(_start,_size)		do { flush_kernel_dcache_range(_start,_size); } while (0)
Index: include/asm-parisc/pgtable.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/pgtable.h,v
retrieving revision 1.36
diff -u -r1.36 pgtable.h
--- pgtable.h	2001/03/22 16:24:19	1.36
+++ pgtable.h	2001/06/17 22:12:14
@@ -62,6 +62,7 @@
 
 #define _PAGE_READ	0x001	/* read access allowed */
 #define _PAGE_WRITE	0x002	/* write access allowed */
+#define _PAGE_RW (_PAGE_READ | _PAGE_WRITE)
 #define _PAGE_EXEC	0x004	/* execute access allowed */
 #define _PAGE_GATEWAY	0x008	/* privilege promotion allowed */
 #define _PAGE_GATEWAY_BIT 28	/* _PAGE_GATEWAY & _PAGE_GATEWAY_BIT need */
Index: include/video/fbcon.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/video/fbcon.h,v
retrieving revision 1.6
diff -u -r1.6 fbcon.h
--- fbcon.h	2001/03/02 00:16:36	1.6
+++ fbcon.h	2001/06/17 22:12:42
@@ -18,7 +18,6 @@
 
 #include <asm/io.h>
 
-
     /*                                  
      *  `switch' for the Low Level Operations
      */
@@ -206,8 +205,11 @@
 #define fb_writel sbus_writel
 #define fb_memset sbus_memset_io
 
-#elif defined(__hppa__)
+#elif defined(__hppa__) && !(USE_HPPA_IOREMAP)
 
+/* When we switch to ioremap() usage the following defines will
+ * be removed and we'll use the arch-independend generic 
+ * functions below instead. */
 #define fb_readb gsc_readb
 #define fb_readw gsc_readw
 #define fb_readl gsc_readl
@@ -215,7 +217,7 @@
 #define fb_writew gsc_writew
 #define fb_writel gsc_writel
 #define fb_memset gsc_memset_io
-
+	
 #elif defined(__i386__) || defined(__alpha__)
 
 #define fb_readb __raw_readb

--------------Boundary-00=_90J3YWS58D6OB5E2FB6R--