[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);
 }
-