[parisc-linux-cvs] DIFF -pa75 SBA/LBA ibase/imask

Grant Grundler grundler@puffin.external.hp.com
Sat, 03 Nov 2001 14:28:13 -0700


Grant Grundler wrote:
> -pa75
> fix elroy ibase/imask intialization for multi-IOMMU (L3000 support)
> Missed this on previous pass.

IIRC, thomas tried this on an L3000 and it worked UP...but I'm not
100% sure about that. It boots on SMP A500. Didn't try C3000.

Note a few FIXME's still remain. If anyone trips over them
and thinks they need to be fixed let me know and I can
take a crack at them.

grant

Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.186
diff -u -p -r1.186 Makefile
--- Makefile	2001/11/02 10:24:58	1.186
+++ Makefile	2001/11/03 21:08:47
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 9
-EXTRAVERSION = -pa74
+EXTRAVERSION = -pa75
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/sba_iommu.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/sba_iommu.c,v
retrieving revision 1.55
diff -u -p -r1.55 sba_iommu.c
--- arch/parisc/kernel/sba_iommu.c	2001/10/31 19:22:08	1.55
+++ arch/parisc/kernel/sba_iommu.c	2001/11/03 21:08:47
@@ -237,7 +237,8 @@ struct ioc {
 };
 
 struct sba_device {
-	struct sba_device	*next;	/* list of LBA's in system */
+	struct sba_device	*next;	/* list of SBA's in system */
+	struct parisc_device	*dev;	/* dev found in bus walk */
 	struct parisc_device_id	*iodc;	/* data about dev from firmware */
 	const char 		*name;
 	unsigned long		sba_hpa; /* base address */
@@ -1415,14 +1416,16 @@ PAT_MOD(mod)->mod_info.ioc         = PAT
 
 
 static void
-sba_ioc_init(struct ioc *ioc)
+sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
 {
-	extern void lba_init_iregs(void *, u32, u32);   /* arch.../lba_pci.c */
+	/* lba_set_iregs() is in arch/parisc/kernel/lba_pci.c */
+	extern void lba_set_iregs(struct parisc_device *, u32, u32);
 
 	u32 iova_space_size, iova_space_mask;
 	void * pdir_base;
 	int pdir_size, iov_order;
 	unsigned long physmem;
+	struct parisc_device *lba;
 
 	/*
 	** Determine IOVA Space size from memory size.
@@ -1514,7 +1517,11 @@ sba_ioc_init(struct ioc *ioc)
 	/*
 	** setup Elroy IBASE/IMASK registers as well.
 	*/
-	lba_init_iregs(ioc->ioc_hpa, ioc->ibase, ioc->imask);
+	for (lba = sba->child; lba; lba = lba->sibling) {
+		int rope_num = (lba->hpa >> 13) & 0xf;
+		if (rope_num >> 3 == ioc_num)
+			lba_set_iregs(lba, ioc->ibase, ioc->imask);
+	}
 
 	/*
 	** Program the IOC's ibase and enable IOVA translation
@@ -1595,7 +1602,7 @@ sba_hw_init(struct sba_device *sba_dev)
 		/* flush out the writes */
 		READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
 
-		sba_ioc_init(&(sba_dev->ioc[i]));
+		sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
 	}
 }
 
@@ -1667,8 +1674,7 @@ sba_common_init(struct sba_device *sba_d
 static int sba_proc_info(char *buf, char **start, off_t offset, int len)
 {
 	struct sba_device *sba_dev = sba_list;
-/* FIXME: Multi-IOC support broken! */
-	struct ioc *ioc = &sba_dev->ioc[0];
+	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Multi-IOC support! */
 	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
 	unsigned long i = 0, avg = 0, min, max;
 
@@ -1725,7 +1731,7 @@ static int
 sba_resource_map(char *buf, char **start, off_t offset, int len)
 {
 	struct sba_device *sba_dev = sba_list;
-	struct ioc *ioc = &sba_dev->ioc[0];
+	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Mutli-IOC suppoer! */
 	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
 	int i;
 
@@ -1800,6 +1806,7 @@ sba_driver_callback(struct parisc_device
 	for(i=0; i<MAX_IOC; i++)
 		spin_lock_init(&(sba_dev->ioc[i].res_lock));
 
+	sba_dev->dev = dev;
 	sba_dev->hw_rev = func_class;
 	sba_dev->iodc = &dev->id;
 	sba_dev->name = dev->name;
Index: arch/parisc/kernel/lba_pci.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/lba_pci.c,v
retrieving revision 1.41
diff -u -p -r1.41 lba_pci.c
--- arch/parisc/kernel/lba_pci.c	2001/10/23 06:41:31	1.41
+++ arch/parisc/kernel/lba_pci.c	2001/11/03 21:08:47
@@ -157,9 +157,10 @@
 
 #define LBA_DMA_CTL	0x0278	/* firmware sets this */
 
-/* RESET: ignore DMA stuff until we can measure performance */
-#define LBA_IBASE	0x0300	/* DMA support */
+#define LBA_IBASE	0x0300	/* SBA DMA support */
 #define LBA_IMASK	0x0308
+
+/* FIXME: ignore DMA Hint stuff until we can measure performance */
 #define LBA_HINT_CFG	0x0310
 #define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */
 
@@ -1462,30 +1463,21 @@ void __init lba_init(void)
 
 /*
 ** Initialize the IBASE/IMASK registers for LBA (Elroy).
-** Only called from sba_iommu.c initialization sequence.
+** Only called from sba_iommu.c in order to route ranges (MMIO vs DMA).
+** sba_iommu is responsible for locking (none needed at init time).
 */
 void __init
-lba_init_iregs(void *sba_hpa, u32 ibase, u32 imask)
+lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
 {
-	int i;
+	char * base_addr = lba->hpa;
 
 	imask <<= 2;	/* adjust for hints - 2 more bits */
 
 	ASSERT((ibase & 0x003fffff) == 0);
 	ASSERT((imask & 0x003fffff) == 0);
 	
-	/* FIXME: sba_hpa is intended to search some table to
-	**      determine which LBA's belong to the caller's SBA.
-	** IS_ASTRO: just assume only one SBA for now.
-	*/
 	DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
-
-	for (i = 0; i < pci_hba_count; i++) {
-		struct pci_hba_data *lba = parisc_pci_hba[i];
-		DBG("%s() base_addr %p\n", __FUNCTION__, lba->base_addr);
-		WRITE_REG32( imask, lba->base_addr + LBA_IMASK);
-		WRITE_REG32( ibase, lba->base_addr + LBA_IBASE);
-	}
-	DBG("%s() done\n", __FUNCTION__);
+	WRITE_REG32( imask, base_addr + LBA_IMASK);
+	WRITE_REG32( ibase, base_addr + LBA_IBASE);
 }