[parisc-linux-cvs] [PATCH] SBA CSR access size changes
Bjorn Helgaas
bjorn_helgaas@hp.com
Wed, 19 Sep 2001 09:35:19 -0600
This patch changes SBA (Ike, Astro, REO) CSR accesses from 32-bit to
64-bit in 64-bit kernels. This should be no functional change on most
platforms, but is required for Superdome, because it HPMCs on 32-bit CSR
accesses.
Comments please!
Index: arch/parisc/kernel/sba_iommu.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/sba_iommu.c,v
retrieving revision 1.51
diff -u -p -r1.51 sba_iommu.c
--- sba_iommu.c 2001/08/28 08:15:09 1.51
+++ sba_iommu.c 2001/09/19 15:20:33
@@ -48,9 +48,9 @@
/*
** The number of debug flags is a clue - this code is fragile.
** Don't even think about messing with it unless you have
-** plenty of 710's to sacrafice to the computer gods. :^)
+** plenty of 710's to sacrifice to the computer gods. :^)
*/
-#undef DEBUG_SBA_INIT
+#define DEBUG_SBA_INIT
#undef DEBUG_SBA_RUN
#undef DEBUG_SBA_RUN_SG
#undef DEBUG_SBA_RESOURCE
@@ -106,6 +106,8 @@
#define IKE_MERCED_PORT 0x803
#define IKE_ROPES_PORT 0x781
+#define REO_MERCED_PORT 0x804
+#define REO_ROPES_PORT 0x782
#define SBA_FUNC_ID 0x0000 /* function id */
#define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */
@@ -115,6 +117,11 @@
(((id)->hw_type == HPHW_BCPORT) && ((id)->hversion ==
ASTRO_ROPES_PORT)) \
)
+#define IS_IKE(id) ( \
+ (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion ==
IKE_MERCED_PORT)) || \
+ (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion ==
IKE_ROPES_PORT)) \
+)
+
#define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */
#define ASTRO_IOC_OFFSET 0x20000
@@ -267,67 +274,47 @@ static unsigned long sba_mem_ratio = 4;
**
** BE WARNED: register writes are posted.
** (ie follow writes which must reach HW with a read)
+**
+** Superdome (in particular, REO) allows only 64-bit CSR accesses.
*/
-#define READ_U8(addr) gsc_readb(addr)
-#define READ_U16(addr) gsc_readw((u16 *) (addr))
-#define READ_U32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-#define READ_REG8(addr) gsc_readb(addr)
-#define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr)))
-#define WRITE_REG8(value, addr) gsc_writeb(value, addr)
-#define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *)
(addr))
+#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
+#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr)))
#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *)
(addr))
#define WRITE_REG64(value, addr) gsc_writeq(cpu_to_le64(value), (u64 *)
(addr))
+#ifdef __LP64__
+#define READ_REG(addr) READ_REG64(addr)
+#define WRITE_REG(value, addr) WRITE_REG64(value, addr)
+#else
+#define READ_REG(addr) READ_REG32(addr)
+#define WRITE_REG(value, addr) WRITE_REG32(value, addr)
+#endif
+
#ifdef DEBUG_SBA_INIT
+/* When __LP64__ isn't defined, READ_REG64() is two 32-bit reads */
static void
sba_dump_ranges(char *hpa)
{
- printk(KERN_DEBUG "SBA at 0x%p\n", hpa);
- printk(KERN_DEBUG "IOS_DIST_BASE : %08x %08x\n",
- READ_REG32(hpa+IOS_DIST_BASE+4),
- READ_REG32(hpa+IOS_DIST_BASE));
- printk(KERN_DEBUG "IOS_DIST_MASK : %08x %08x\n",
- READ_REG32(hpa+IOS_DIST_MASK+4),
- READ_REG32(hpa+IOS_DIST_MASK));
- printk(KERN_DEBUG "IOS_DIST_ROUTE : %08x %08x\n",
- READ_REG32(hpa+IOS_DIST_ROUTE+4),
- READ_REG32(hpa+IOS_DIST_ROUTE));
- printk(KERN_DEBUG "\n");
- printk(KERN_DEBUG "IOS_DIRECT_BASE : %08x %08x\n",
- READ_REG32(hpa+IOS_DIRECT_BASE+4),
- READ_REG32(hpa+IOS_DIRECT_BASE));
- printk(KERN_DEBUG "IOS_DIRECT_MASK : %08x %08x\n",
- READ_REG32(hpa+IOS_DIRECT_MASK+4),
- READ_REG32(hpa+IOS_DIRECT_MASK));
- printk(KERN_DEBUG "IOS_DIRECT_ROUTE: %08x %08x\n",
- READ_REG32(hpa+IOS_DIRECT_ROUTE+4),
- READ_REG32(hpa+IOS_DIRECT_ROUTE));
+ DBG_INIT("SBA at 0x%p\n", hpa);
+ DBG_INIT("IOS_DIST_BASE : %016lx\n", READ_REG64(hpa+IOS_DIST_BASE));
+ DBG_INIT("IOS_DIST_MASK : %016lx\n", READ_REG64(hpa+IOS_DIST_MASK));
+ DBG_INIT("IOS_DIST_ROUTE : %016lx\n", READ_REG64(hpa+IOS_DIST_ROUTE));
+ DBG_INIT("\n");
+ DBG_INIT("IOS_DIRECT_BASE : %016lx\n", READ_REG64(hpa+IOS_DIRECT_BASE));
+ DBG_INIT("IOS_DIRECT_MASK : %016lx\n", READ_REG64(hpa+IOS_DIRECT_MASK));
+ DBG_INIT("IOS_DIRECT_ROUTE: %016lx\n", READ_REG64(hpa+IOS_DIRECT_ROUTE));
}
static void
sba_dump_tlb(char *hpa)
{
- printk(KERN_DEBUG "IO TLB at 0x%p\n", hpa);
- printk(KERN_DEBUG "IOC_IBASE : %08x %08x\n",
- READ_REG32(hpa+IOC_IBASE+4),
- READ_REG32(hpa+IOC_IBASE));
- printk(KERN_DEBUG "IOC_IMASK : %08x %08x\n",
- READ_REG32(hpa+IOC_IMASK+4),
- READ_REG32(hpa+IOC_IMASK));
- printk(KERN_DEBUG "IOC_TCNFG : %08x %08x\n",
- READ_REG32(hpa+IOC_TCNFG+4),
- READ_REG32(hpa+IOC_TCNFG));
- printk(KERN_DEBUG "IOC_PDIR_BASE: %08x %08x\n",
- READ_REG32(hpa+IOC_PDIR_BASE+4),
- READ_REG32(hpa+IOC_PDIR_BASE));
- printk(KERN_DEBUG "\n");
+ DBG_INIT("IO TLB at 0x%p\n", hpa);
+ DBG_INIT("IOC_IBASE : %016lx\n", READ_REG64(hpa+IOC_IBASE));
+ DBG_INIT("IOC_IMASK : %016lx\n", READ_REG64(hpa+IOC_IMASK));
+ DBG_INIT("IOC_TCNFG : %016lx\n", READ_REG64(hpa+IOC_TCNFG));
+ DBG_INIT("IOC_PDIR_BASE: %016lx\n", READ_REG64(hpa+IOC_PDIR_BASE));
+ DBG_INIT("\n");
}
#endif
@@ -726,7 +713,7 @@ sba_mark_invalid(struct ioc *ioc, dma_ad
} while (byte_cnt > 0);
}
- WRITE_REG32(iovp, ioc->ioc_hpa+IOC_PCOM);
+ WRITE_REG(iovp, ioc->ioc_hpa+IOC_PCOM);
}
static int
@@ -866,13 +853,13 @@ sba_unmap_single(struct pci_dev *dev, dm
}
ioc->saved_cnt = 0;
/* flush purges */
- READ_REG32(ioc->ioc_hpa+IOC_PCOM);
+ READ_REG(ioc->ioc_hpa+IOC_PCOM);
}
#else
sba_mark_invalid(ioc, iova, size);
sba_free_range(ioc, iova, size);
/* flush purges */
- READ_REG32(ioc->ioc_hpa+IOC_PCOM);
+ READ_REG(ioc->ioc_hpa+IOC_PCOM);
#endif
spin_unlock_irqrestore(&ioc->res_lock, flags);
@@ -1352,7 +1339,7 @@ sba_ioc_init(struct ioc *ioc)
/* Verify it's a power of two */
ASSERT((1 << get_order(pdir_size)) == (pdir_size >> PAGE_SHIFT));
- DBG_INIT("%s() hpa 0x%p mem %dMBIOV %dMB (%d bits) PDIR size 0x%0x",
+ DBG_INIT("%s() hpa 0x%p mem %dMB IOV %dMB (%d bits) PDIR size 0x%0x\n",
__FUNCTION__, ioc->ioc_hpa, (int) (physmem>>20),
iova_space_size>>20, iov_order + PAGE_SHIFT, pdir_size);
@@ -1405,17 +1392,17 @@ sba_ioc_init(struct ioc *ioc)
/*
** Program the IOC's ibase and enable IOVA translation
*/
- WRITE_REG32(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
- WRITE_REG32(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
+ WRITE_REG(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
+ WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
/* Set I/O PDIR Page size to 4K */
- WRITE_REG32(0, ioc->ioc_hpa+IOC_TCNFG);
+ WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG);
/*
** Clear I/O TLB of any possible entries.
- ** (Yes. This is a it paranoid...but so what)
+ ** (Yes. This is a bit paranoid...but so what)
*/
- WRITE_REG32(0 | 31, ioc->ioc_hpa+IOC_PCOM);
+ WRITE_REG(0 | 31, ioc->ioc_hpa+IOC_PCOM);
DBG_INIT("%s() DONE\n", __FUNCTION__);
}
@@ -1438,19 +1425,19 @@ sba_hw_init(struct sba_device *sba_dev)
{
int i;
int num_ioc;
- u32 ioc_ctl;
+ u64 ioc_ctl;
- ioc_ctl = READ_REG32(sba_dev->sba_hpa+IOC_CTRL);
- DBG_INIT("%s() hpa 0x%p ioc_ctl 0x%x ->",
- __FUNCTION__, sba_dev->sba_hpa, ioc_ctl );
+ ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
+ DBG_INIT("%s() hpa 0x%p ioc_ctl 0x%016lx ->",
+ __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC);
ASSERT(ioc_ctl & IOC_CTRL_TE); /* astro: firmware enables this */
- WRITE_REG32(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
+ WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
-#ifdef SBA_DEBUG_INIT
- ioc_ctl = READ_REG32(sba_dev->sba_hpa+IOC_CTRL);
- DBG_INIT(" 0x%x\n", ioc_ctl );
+#ifdef DEBUG_SBA_INIT
+ ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
+ DBG_INIT(" 0x%016lx\n", ioc_ctl);
#endif
if (IS_ASTRO(sba_dev->iodc)) {
@@ -1463,24 +1450,23 @@ sba_hw_init(struct sba_device *sba_dev)
}
sba_dev->num_ioc = num_ioc;
- for( i = 0; i < num_ioc; i++)
- {
+ for (i = 0; i < num_ioc; i++) {
(unsigned long) sba_dev->ioc[i].ioc_hpa += (unsigned long)
sba_dev->sba_hpa + IKE_IOC_OFFSET(i);
/*
** Make sure the box crashes if we get any errors on a rope.
*/
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL);
- WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL);
+ WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
/* flush out the writes */
- READ_REG32(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+ READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
sba_ioc_init(&(sba_dev->ioc[i]));
}
@@ -1641,23 +1627,35 @@ sba_driver_callback(struct parisc_device
int i;
char *version;
+#ifdef DEBUG_SBA_INIT
+ sba_dump_ranges(dev->hpa);
+#endif
+
if (IS_ASTRO(&dev->id)) {
static char astro_rev[]="Astro ?.?";
/* Read HW Rev First */
- func_class = READ_REG32(dev->hpa);
+ func_class = READ_REG(dev->hpa);
astro_rev[6] = '1' + (char) (func_class & 0x7);
astro_rev[8] = '0' + (char) ((func_class & 0x18) >> 3);
version = astro_rev;
- } else {
+ } else if (IS_IKE(&dev->id)) {
static char ike_rev[]="Ike rev ?";
/* Read HW Rev First */
- func_class = READ_REG32(dev->hpa + SBA_FCLASS);
+ func_class = READ_REG(dev->hpa + SBA_FCLASS);
ike_rev[8] = '0' + (char) (func_class & 0xff);
version = ike_rev;
+ } else {
+ static char reo_rev[]="REO rev ?";
+
+ /* Read HW Rev First */
+ func_class = READ_REG(dev->hpa + SBA_FCLASS);
+
+ reo_rev[8] = '0' + (char) (func_class & 0xff);
+ version = reo_rev;
}
printk(KERN_INFO "%s found %s at 0x%lx\n",
@@ -1687,8 +1685,10 @@ sba_driver_callback(struct parisc_device
#ifdef CONFIG_PROC_FS
if (IS_ASTRO(&dev->id)) {
create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info);
- } else {
+ } else if (IS_IKE(&dev->id)) {
create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info);
+ } else {
+ create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info);
}
create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map);
#endif
@@ -1699,6 +1699,7 @@ static struct parisc_device_id sba_tbl[]
/* FIXME: why is SVERSION checked? */
{ HPHW_IOA, HVERSION_REV_ANY_ID, ASTRO_RUNWAY_PORT, 0xb },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, ASTRO_ROPES_PORT, 0xb },
+ { HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
#if 0
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xb },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_ROPES_PORT, 0xb },
@@ -1719,10 +1720,5 @@ static struct parisc_driver sba_driver =
*/
void __init sba_init(void)
{
-#ifdef DEBUG_SBA_INIT
- sba_dump_ranges((char *) 0xFED00000L);
-#endif
-
register_parisc_driver(&sba_driver);
}
-