[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--