[parisc-linux-cvs] sticon/stifb virtual mode support

Helge Deller deller@gmx.de
Wed, 27 Jun 2001 16:11:35 +0200


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

Modified files:
        .              : Makefile 
        drivers/video/sti: sticon.c sticore.c sticore.h stifb.c 

Log message:
- EXTRAVERSION -pa44
- changes to support calling STI ROM in virtual mode in sticon and
   stifb, based on the value of USE_HPPA_IOREMAP
- updated PCI graphic card support

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

Index: Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/Makefile,v
retrieving revision 1.75
diff -u -r1.75 Makefile
--- Makefile	2001/06/26 06:39:22	1.75
+++ Makefile	2001/06/27 13:55:37
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -pa43
+EXTRAVERSION = -pa44
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: drivers/video/sti/sticon.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticon.c,v
retrieving revision 1.13
diff -u -r1.13 sticon.c
--- sticon.c	2001/06/20 20:24:36	1.13
+++ sticon.c	2001/06/27 13:55:49
@@ -56,7 +56,7 @@
 
 /* Software scrollback */
 
-int sticon_softback_size = 32768;
+static int sticon_softback_size = 32768;
 static unsigned long softback_buf, softback_curr;
 static unsigned long softback_in;
 static unsigned long /* softback_top, */ softback_end;
Index: drivers/video/sti/sticore.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticore.c,v
retrieving revision 1.17
diff -u -r1.17 sticore.c
--- sticore.c	2001/06/25 17:16:51	1.17
+++ sticore.c	2001/06/27 13:55:51
@@ -373,6 +373,7 @@
 	void *save_addr;
 	void *sti_mem_addr;
 	const int save_addr_size = 1024;	/* XXX */
+	int i;
 
 	if (!sti->sti_mem_request)
 		sti->sti_mem_request = 256; /* STI default */
@@ -392,15 +393,47 @@
 
 	glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
 	glob_cfg->save_addr = STI_PTR(save_addr);
-	glob_cfg->region_ptrs[0] = REGION_OFFSET_TO_PHYS(sti->regions[0], rom_address);
-	glob_cfg->region_ptrs[1] = REGION_OFFSET_TO_PHYS(sti->regions[1], hpa);
-	glob_cfg->region_ptrs[2] = REGION_OFFSET_TO_PHYS(sti->regions[2], hpa);
-	glob_cfg->region_ptrs[3] = REGION_OFFSET_TO_PHYS(sti->regions[3], hpa);
-	glob_cfg->region_ptrs[4] = REGION_OFFSET_TO_PHYS(sti->regions[4], hpa);
-	glob_cfg->region_ptrs[5] = REGION_OFFSET_TO_PHYS(sti->regions[5], hpa);
-	glob_cfg->region_ptrs[6] = REGION_OFFSET_TO_PHYS(sti->regions[6], hpa);
-	glob_cfg->region_ptrs[7] = REGION_OFFSET_TO_PHYS(sti->regions[7], hpa);
-	
+	for (i=0; i<8; i++) {
+		unsigned long newhpa, len;
+	       
+		newhpa = (i==0) ? rom_address : hpa;
+		
+		sti->regions_phys[i] =
+			REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa);
+		
+		/* remap virtually */
+		/* FIXME: add BTLB support if btlb==1 */
+		len = sti->regions[i].region_desc.length * 4096;
+		
+		/* PCI cards may use more memory than the 16MB
+		 * which fits into the region_desc.length field. */
+		if (i==1 && sti->pd && len==(16*1024*1024))
+			len = pci_resource_len(sti->pd, 0);
+
+		if (len)
+		   glob_cfg->region_ptrs[i] = (unsigned long) (
+			sti->regions[i].region_desc.cache ?
+			ioremap(sti->regions_phys[i], len) :
+			ioremap_nocache(sti->regions_phys[i], len) );
+		
+		DPRINTK(("region #%d: phys %08lx, virt %08x, len=%lukB, "
+			 "btlb=%d, sysonly=%d, cache=%d, last=%d\n",
+			i, sti->regions_phys[i], glob_cfg->region_ptrs[i],
+			len/1024,
+			sti->regions[i].region_desc.btlb,
+			sti->regions[i].region_desc.sys_only,
+			sti->regions[i].region_desc.cache, 
+			sti->regions[i].region_desc.last));
+
+		/* last entry reached ? */
+		if (sti->regions[i].region_desc.last)
+			break;
+	}
+
+	if (++i<8 && sti->regions[i].region)
+		printk(KERN_WARNING "%s: *future ptr (0x%8x) not yet supported !\n",
+				__FILE__, sti->regions[i].region);
+
 	glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
 
 	sti->glob_cfg = STI_PTR(glob_cfg);
@@ -693,21 +726,6 @@
 	int ok;
 	u32 sig;
 
-test_rom:
-	/* if we can't read the ROM, bail out early.  Not being able
-	 * to read the hpa is okay, for romless sti */
-	if (pdc_add_valid((void*)address))
-		return NULL;
-
-	sig = gsc_readl(address);
-
-	if (((sig>>16)==0x55aa) || ((sig>>16)==0xaa55)) {
-		address += le32_to_cpu(gsc_readl(address+8));
-		printk("sig %04x, PCI STI ROM at %08lx\n",
-		       sig, address);
-		goto test_rom;
-	}
-
 	if (num_sti_roms >= MAX_STI_ROMS) {
 	    printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
 	    return NULL;
@@ -721,6 +739,54 @@
 		    
 	memset(sti, 0, sizeof(*sti));
 	sti->lock = SPIN_LOCK_UNLOCKED;
+
+test_rom:
+	/* if we can't read the ROM, bail out early.  Not being able
+	 * to read the hpa is okay, for romless sti */
+	if (pdc_add_valid((void*)address))
+		goto out_err;
+
+	sig = gsc_readl(address);
+
+	/* check for a PCI ROM structure */
+	if ((le32_to_cpu(sig)==0xaa55)) {
+		unsigned int i, rm_offset;
+		u32 *rm;
+		i = gsc_readl(address+0x04);
+		if (i != 1) {
+			/* FIXME: The ROM could have multiple architecture 
+			 * dependend images (e.g. iA32, parisc,...) */
+			printk(KERN_WARNING 
+				"%s: PCI ROM is not a STI ROM type image (0x%8x)\n",
+				__FILE__, i);
+			goto out_err;
+		}
+		
+		sti->pd = pd;
+
+		i = gsc_readl(address+0x0c);
+		DPRINTK(("PCI ROM size (from header) = %d kB\n",
+			le16_to_cpu(i>>16)*512/1024));
+		rm_offset = le16_to_cpu(i & 0xffff);
+		if (rm_offset) { 
+			/* read 16 bytes from the pci region mapper array */
+			rm = (u32*) &sti->rm_entry;
+			*rm++ = gsc_readl(address+rm_offset+0x00);
+			*rm++ = gsc_readl(address+rm_offset+0x04);
+			*rm++ = gsc_readl(address+rm_offset+0x08);
+			*rm++ = gsc_readl(address+rm_offset+0x0c);
+			DPRINTK(("PCI region Mapper offset = %08x: ",
+				rm_offset));
+			for (i=0; i<16; i++)
+				DPRINTK(("%02x ", sti->rm_entry[i]));
+			DPRINTK(("\n"));
+		}
+
+		address += le32_to_cpu(gsc_readl(address+8));
+		printk("sig %04x, PCI STI ROM at %08lx\n",
+		       sig, address);
+		goto test_rom;
+	}
 	
 	ok = 0;
 	
@@ -736,16 +802,11 @@
 		ok = sti_read_rom(1, sti, address);
 	}
 
-	if (!ok) {
-		kfree(sti);
-		return NULL;
-	}
+	if (!ok)
+		goto out_err;
 
-	if (sti_init_glob_cfg(sti, address, hpa)) {
-	    printk(KERN_ERR "Not enough memory !\n");
-	    kfree(sti);
-	    return NULL;
-	}
+	if (sti_init_glob_cfg(sti, address, hpa))
+		goto out_err; /* not enough memory */
 
 	sti_init_graph(sti);
 
@@ -758,6 +819,10 @@
 	num_sti_roms++;
 	
 	return sti;
+
+out_err:
+	kfree(sti);
+	return NULL;
 }
 
 
@@ -814,18 +879,17 @@
 	
 	pci_enable_device(pd);
 
-	fb_base = pci_resource_start (pd, 0);
-	fb_len = pci_resource_len (pd, 0);
-	rom_base = pci_resource_start (pd, PCI_ROM_RESOURCE);
-	rom_len = pci_resource_len (pd, PCI_ROM_RESOURCE);
+	fb_base = pci_resource_start(pd, 0);
+	fb_len = pci_resource_len(pd, 0);
+	rom_base = pci_resource_start(pd, PCI_ROM_RESOURCE);
+	rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE);
 	if (rom_base) {
-		/* rom_base = fb_base + fb_len; */
 		pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE);
 		printk("STI PCI ROM enabled at 0x%08lx\n", rom_base);
 	}
 
-	printk("PCI graphic found at %08lx (%u MB) and %08lx (%u kB)\n",
-		fb_base, fb_len/1024/1024, rom_base, rom_len/1024);
+	printk("PCI graphic ROM found at %08lx (%u kB), fb @ %08lx (%u MB)\n",
+		rom_base, rom_len/1024, fb_base, fb_len/1024/1024);
 
 	for (i=0; i<DEVICE_COUNT_RESOURCE; i++)
 		printk("PCI region %d: %08lx with %lu kB\n",
@@ -895,11 +959,11 @@
 
 	if (initialized)
 	    goto out;
-	initialized++;
 
-	/* 712, 715 & some other boxes don't have a separate STI ROM,
-	 * but use part of the regular flash. Newer systems may
-	 * set this value to NULL */
+	/* 712 and on the later generation 715 and 725 products
+	 * the STI ROM is part of the regular flash and the PDC
+	 * stored a pointer to the ROM for us at PAGE0->proc_sti.
+	 * On other systems this value will be NULL */
 	flash_rom = PAGE0->proc_sti;
 
 	/* search the possible hpa locations (64bit ready)
@@ -920,8 +984,9 @@
 
 out:
 	/* return default STI if available */
-	if (num_sti_roms && default_sti && default_sti->init_graph)
+	if (num_sti_roms && default_sti && default_sti->init_graph) {
+	    initialized++;
 	    return default_sti;
-	else
+	} else
 	    return NULL;
 }
Index: drivers/video/sti/sticore.h
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticore.h,v
retrieving revision 1.15
diff -u -r1.15 sticore.h
--- sticore.h	2001/06/25 17:16:51	1.15
+++ sticore.h	2001/06/27 13:55:51
@@ -32,22 +32,37 @@
  * 
  * Luckily, the frame buffer guys have the same problem so we can just wait
  * for them to fix it and steal their solution.   prumpf
- *
- * Actually, another long-term viable solution is to completely do STI
- * support in userspace - that way we avoid the potential license issues
- * of using proprietary fonts, too. */
+ */
  
 #define STI_WAIT 1
-#define STI_PTR(p) ( (typeof(p)) virt_to_phys(p) )
-#define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )
 
+#include <asm/io.h> /* for USE_HPPA_IOREMAP */
+
+#if USE_HPPA_IOREMAP
+
+#define STI_PTR(p)	(p)
+#define PTR_STI(p)	(p)
+static int inline STI_CALL( unsigned long func, 
+		void *flags, void *inptr, void *outptr, void *glob_cfg )
+{
+       int (*f)(void *,void *,void *,void *);
+       f = (void*)func;
+       return f(flags, inptr, outptr, glob_cfg);
+}
+
+#else /* !USE_HPPA_IOREMAP */
+
+#define STI_PTR(p)	( (typeof(p)) virt_to_phys(p) )
+#define PTR_STI(p)	( (typeof(p)) phys_to_virt((unsigned long)p) )
 #define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
-	({	 						\
-		pdc_sti_call( func, (unsigned long)STI_PTR(flags), \
-				    (unsigned long)STI_PTR(inptr), \
-				    (unsigned long)STI_PTR(outptr), \
-				    (unsigned long)glob_cfg); \
-	})
+       ({                                                      \
+               pdc_sti_call( func, (unsigned long)STI_PTR(flags), \
+                                   (unsigned long)STI_PTR(inptr), \
+                                   (unsigned long)STI_PTR(outptr), \
+                                   (unsigned long)glob_cfg); \
+       })
+
+#endif /* USE_HPPA_IOREMAP */
 
 
 #define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)
@@ -346,7 +361,7 @@
 	/* all following fields are initialized by the generic routines */
 	int text_planes;
 	region_t regions[STI_REGION_MAX];
-	/* u8 *pci_regions; */
+	unsigned long regions_phys[STI_REGION_MAX];
 
 	struct sti_glob_cfg *glob_cfg;
 	struct sti_cooked_font *font;	/* ptr to selected font (cooked) */
@@ -354,8 +369,9 @@
 	struct sti_conf_outptr outptr; /* configuration */
 	struct sti_conf_outptr_ext outptr_ext;
 
-	/* PCI data structures */
+	/* PCI data structures (pg. 17ff from sti.pdf) */
 	struct pci_dev *pd;
+	u8 rm_entry[16]; /* pci region mapper array == pci config space offset */
 };
 
 
Index: drivers/video/sti/stifb.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.16
diff -u -r1.16 stifb.c
--- stifb.c	2001/06/20 20:24:36	1.16
+++ stifb.c	2001/06/27 13:55:52
@@ -68,9 +68,7 @@
 
 extern struct display_switch fbcon_sti; /* fbcon-sti.c */
 
-#define HPPA_IOREMAP(addr,len) \
-	ioremap(addr,len)
-
+/* return virtual address */
 #define REGION_BASE(fb_info, index) \
 	PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[index]
 	
@@ -158,10 +156,10 @@
 #define REG_34		0x200008
 #define REG_38		0x210020
 
-#define READ_BYTE(base)		gsc_readb(base)
-#define READ_WORD(base)		gsc_readl(base)
-#define WRITE_BYTE(value,base)	gsc_writeb(value,base)
-#define WRITE_WORD(value,base)	gsc_writel(value,base)
+#define READ_BYTE(base)		readb(base)
+#define READ_WORD(base)		readl(base)
+#define WRITE_BYTE(value,base)	writeb(value,base)
+#define WRITE_WORD(value,base)	writel(value,base)
 
 #define ENABLE	1	/* for enabling/disabling screen */	
 #define DISABLE 0
@@ -1023,6 +1021,13 @@
 int __init
 stifb_init(void)
 {
+	static int stifb_initialized;
+
+	if (stifb_initialized) {
+		printk(KERN_WARNING "WARNING: Only one stifb will be supported currently.\n");
+		return -ENODEV;
+	}
+	
 	/* set struct to a known state */
 	memset(&fb_info, 0, sizeof(fb_info));
 	
@@ -1032,28 +1037,40 @@
 	/* store upper 32bits of the graphics id */
 	fb_info.id = fb_info.sti->graphics_id[0];
 	
-	/* get io region base addr */
+	/* get (virtual) 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.smem_start = fb_info.sti->regions_phys[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.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));
+	fb_info.screen_base = REGION_BASE(fb_info,1);
 
        	/* 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 */
-//	case S9000_ID_ELM:	/* GRX */
-//	case S9000_ID_TIMBER:	/* 710 Any */
-//	case S9000_ID_TOMCAT:	/* Dual CRX */
-//	case S9000_ID_A1439A:	/* CRX24 */
+	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_ARTIST:	/* Artist */
-//	case S9000_ID_HCRX:	/* Hyperdrive */
 		fb_info.bpp = 8;	/* default to 8 bpp */
 		break;
 	default: 
@@ -1105,6 +1122,8 @@
 		disp.var.bits_per_pixel,
 		fb_info.id, 
 		fb_info.iobase);
+	
+	stifb_initialized++;
 	
 	return 0;
 }

--------------Boundary-00=_B3ELWORQTLKVS8SDMFAB--