Patchwork [05/12,v3] pci: fsl: port PCI ATMU related code

login
register
mail settings
Submitter Minghuan Lian
Date Oct. 23, 2013, 10:41 a.m.
Message ID <1382524894-15164-5-git-send-email-Minghuan.Lian@freescale.com>
Download mbox | patch
Permalink /patch/285622/
State Rejected
Headers show

Comments

Minghuan Lian - Oct. 23, 2013, 10:41 a.m.
The patch ports PCI ATMU related code, just uses general IO API
iowrite32be/ioread32be instead of out_be32/in_be32, uses structure
fsl_pci instead of PowerPC's pci_controller and uses dev_*()
instead of pr_*() to output the information.
The patch also provides the weak function
fsl_arch_pci64_dma_offset(), the architecture-specific driver may
return different offset.

Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 191 ++++++++++++++++++++------------------
 include/linux/fsl/pci-common.h    |   3 +
 2 files changed, 104 insertions(+), 90 deletions(-)

Patch

diff --git a/drivers/pci/host/pci-fsl-common.c b/drivers/pci/host/pci-fsl-common.c
index 505a6a1..f15b605 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -42,6 +42,11 @@ 
 #define INDIRECT_TYPE_BIG_ENDIAN		0x00000010
 #define INDIRECT_TYPE_FSL_CFG_REG_LINK		0x00000040
 
+u64 __weak fsl_arch_pci64_dma_offset(void)
+{
+	return 0;
+}
+
 int __weak fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
 {
 	return PCIBIOS_SUCCESSFUL;
@@ -231,8 +236,8 @@  static int early_fsl_find_capability(struct fsl_pci *pci,
 }
 
 static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-	unsigned int index, const struct resource *res,
-	resource_size_t offset)
+			  unsigned int index, const struct resource *res,
+			  resource_size_t offset)
 {
 	resource_size_t pci_addr = res->start - offset;
 	resource_size_t phys_addr = res->start;
@@ -253,10 +258,10 @@  static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 		if (index + i >= 5)
 			return -1;
 
-		out_be32(&pci->pow[index + i].potar, pci_addr >> 12);
-		out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44);
-		out_be32(&pci->pow[index + i].powbar, phys_addr >> 12);
-		out_be32(&pci->pow[index + i].powar, flags | (bits - 1));
+		iowrite32be(pci_addr >> 12, &pci->pow[index + i].potar);
+		iowrite32be((u64)pci_addr >> 44, &pci->pow[index + i].potear);
+		iowrite32be(phys_addr >> 12, &pci->pow[index + i].powbar);
+		iowrite32be(flags | (bits - 1), &pci->pow[index + i].powar);
 
 		pci_addr += (resource_size_t)1U << bits;
 		phys_addr += (resource_size_t)1U << bits;
@@ -267,21 +272,19 @@  static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 }
 
 /* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose)
+static void setup_pci_atmu(struct fsl_pci *pci)
 {
-	struct ccsr_pci __iomem *pci = hose->private_data;
 	int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
 	u64 mem, sz, paddr_hi = 0;
 	u64 offset = 0, paddr_lo = ULLONG_MAX;
 	u32 pcicsrbar = 0, pcicsrbar_sz;
 	u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
 			PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
-	const char *name = hose->dn->full_name;
 	const u64 *reg;
 	int len;
 
-	if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
-		if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
+	if (pci->is_pcie) {
+		if (in_be32(&pci->regs->block_rev1) >= PCIE_IP_REV_2_2) {
 			win_idx = 2;
 			start_idx = 0;
 			end_idx = 3;
@@ -289,47 +292,54 @@  static void setup_pci_atmu(struct pci_controller *hose)
 	}
 
 	/* Disable all windows (except powar0 since it's ignored) */
-	for(i = 1; i < 5; i++)
-		out_be32(&pci->pow[i].powar, 0);
+	for (i = 1; i < 5; i++)
+		iowrite32be(0, &pci->regs->pow[i].powar);
 	for (i = start_idx; i < end_idx; i++)
-		out_be32(&pci->piw[i].piwar, 0);
+		iowrite32be(0, &pci->regs->piw[i].piwar);
 
 	/* Setup outbound MEM window */
-	for(i = 0, j = 1; i < 3; i++) {
-		if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
+	for (i = 0, j = 1; i < 3; i++) {
+		if (!(pci->mem_resources[i].flags & IORESOURCE_MEM))
 			continue;
 
-		paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start);
-		paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end);
+		paddr_lo = min_t(u64, paddr_lo, pci->mem_resources[i].start);
+		paddr_hi = max_t(u64, paddr_hi, pci->mem_resources[i].end);
 
 		/* We assume all memory resources have the same offset */
-		offset = hose->mem_offset[i];
-		n = setup_one_atmu(pci, j, &hose->mem_resources[i], offset);
+		offset = pci->mem_offset[i];
+		n = setup_one_atmu(pci->regs, j, &pci->mem_resources[i],
+				   offset);
 
 		if (n < 0 || j >= 5) {
-			pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i);
-			hose->mem_resources[i].flags |= IORESOURCE_DISABLED;
+			dev_err(pci->dev,
+				"Ran out of outbound PCI ATMUs for resource %d!\n",
+				i);
+			pci->mem_resources[i].flags |= IORESOURCE_DISABLED;
 		} else
 			j += n;
 	}
 
 	/* Setup outbound IO window */
-	if (hose->io_resource.flags & IORESOURCE_IO) {
-		if (j >= 5) {
-			pr_err("Ran out of outbound PCI ATMUs for IO resource\n");
-		} else {
-			pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
-				 "phy base 0x%016llx.\n",
-				 (u64)hose->io_resource.start,
-				 (u64)resource_size(&hose->io_resource),
-				 (u64)hose->io_base_phys);
-			out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12));
-			out_be32(&pci->pow[j].potear, 0);
-			out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12));
+	if (pci->io_resource.flags & IORESOURCE_IO) {
+		if (j >= 5)
+			dev_err(pci->dev,
+				"Ran out of outbound PCI ATMUs for IO resource\n");
+		else {
+			dev_dbg(pci->dev,
+				 "PCI IO resource start 0x%016llx,"
+				 "size 0x%016llx, phy base 0x%016llx.\n",
+				 (u64)pci->io_resource.start,
+				 (u64)resource_size(&pci->io_resource),
+				 (u64)pci->io_base_phys);
+			iowrite32be(pci->io_resource.start >> 12,
+				    &pci->regs->pow[j].potar);
+			iowrite32be(0, &pci->regs->pow[j].potear);
+			iowrite32be(pci->io_base_phys >> 12,
+				    &pci->regs->pow[j].powbar);
 			/* Enable, IO R/W */
-			out_be32(&pci->pow[j].powar, 0x80088000
-				| (ilog2(hose->io_resource.end
-				- hose->io_resource.start + 1) - 1));
+			iowrite32be(0x80088000 |
+				  (ilog2(resource_size(&pci->io_resource)) - 1),
+				  &pci->regs->pow[j].powar);
 		}
 	}
 
@@ -338,18 +348,20 @@  static void setup_pci_atmu(struct pci_controller *hose)
 	paddr_lo -= offset;
 
 	if (paddr_hi == paddr_lo) {
-		pr_err("%s: No outbound window space\n", name);
+		dev_err(pci->dev, "No outbound window space\n");
 		return;
 	}
 
 	if (paddr_lo == 0) {
-		pr_err("%s: No space for inbound window\n", name);
+		dev_err(pci->dev, "No space for inbound window\n");
 		return;
 	}
 
 	/* setup PCSRBAR/PEXCSRBAR */
-	early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, 0xffffffff);
-	early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
+	early_fsl_write_config_dword(pci, 0, 0, PCI_BASE_ADDRESS_0,
+				     0xffffffff);
+	early_fsl_read_config_dword(pci, 0, 0, PCI_BASE_ADDRESS_0,
+				    &pcicsrbar_sz);
 	pcicsrbar_sz = ~pcicsrbar_sz + 1;
 
 	if (paddr_hi < (0x100000000ull - pcicsrbar_sz) ||
@@ -357,11 +369,12 @@  static void setup_pci_atmu(struct pci_controller *hose)
 		pcicsrbar = 0x100000000ull - pcicsrbar_sz;
 	else
 		pcicsrbar = (paddr_lo - pcicsrbar_sz) & -pcicsrbar_sz;
-	early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, pcicsrbar);
+	early_fsl_write_config_dword(pci, 0, 0, PCI_BASE_ADDRESS_0,
+				     pcicsrbar);
 
-	paddr_lo = min(paddr_lo, (u64)pcicsrbar);
+	paddr_lo = min_t(u64, paddr_lo, pcicsrbar);
 
-	pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar);
+	dev_info(pci->dev, "PCICSRBAR @ 0x%x\n", pcicsrbar);
 
 	/* Setup inbound mem window */
 	mem = memblock_end_of_DRAM();
@@ -378,17 +391,19 @@  static void setup_pci_atmu(struct pci_controller *hose)
 	 * can avoid allocating a new ATMU by extending the DDR ATMU by one
 	 * page.
 	 */
-	reg = of_get_property(hose->dn, "msi-address-64", &len);
+	reg = of_get_property(pci->dn, "msi-address-64", &len);
 	if (reg && (len == sizeof(u64))) {
 		u64 address = be64_to_cpup(reg);
 
 		if ((address >= mem) && (address < (mem + PAGE_SIZE))) {
-			pr_info("%s: extending DDR ATMU to cover MSIIR", name);
+			dev_info(pci->dev,
+				 "extending DDR ATMU to cover MSIIR\n");
 			mem += PAGE_SIZE;
 		} else {
 			/* TODO: Create a new ATMU for MSIIR */
-			pr_warn("%s: msi-address-64 address of %llx is "
-				"unsupported\n", name, address);
+			dev_warn(pci->dev,
+				 "msi-address-64 address of %llx is "
+				 "unsupported\n", address);
 		}
 	}
 
@@ -396,25 +411,26 @@  static void setup_pci_atmu(struct pci_controller *hose)
 	mem_log = ilog2(sz);
 
 	/* PCIe can overmap inbound & outbound since RX & TX are separated */
-	if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+	if (pci->is_pcie) {
 		/* Size window to exact size if power-of-two or one size up */
 		if ((1ull << mem_log) != mem) {
 			mem_log++;
 			if ((1ull << mem_log) > mem)
-				pr_info("%s: Setting PCI inbound window "
-					"greater than memory size\n", name);
+				dev_info(pci->dev,
+					 "Setting PCI inbound window "
+					 "greater than memory size\n");
 		}
 
 		piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
 
 		/* Setup inbound memory window */
-		out_be32(&pci->piw[win_idx].pitar,  0x00000000);
-		out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
-		out_be32(&pci->piw[win_idx].piwar,  piwar);
+		iowrite32be(0, &pci->regs->piw[win_idx].pitar);
+		iowrite32be(0, &pci->regs->piw[win_idx].piwbar);
+		iowrite32be(piwar, &pci->regs->piw[win_idx].piwar);
 		win_idx--;
 
-		hose->dma_window_base_cur = 0x00000000;
-		hose->dma_window_size = (resource_size_t)sz;
+		pci->dma_window_base_cur = 0x00000000;
+		pci->dma_window_size = (resource_size_t)sz;
 
 		/*
 		 * if we have >4G of memory setup second PCI inbound window to
@@ -431,28 +447,22 @@  static void setup_pci_atmu(struct pci_controller *hose)
 			piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
 
 			/* Setup inbound memory window */
-			out_be32(&pci->piw[win_idx].pitar,  0x00000000);
-			out_be32(&pci->piw[win_idx].piwbear,
-					pci64_dma_offset >> 44);
-			out_be32(&pci->piw[win_idx].piwbar,
-					pci64_dma_offset >> 12);
-			out_be32(&pci->piw[win_idx].piwar,  piwar);
-
-			/*
-			 * install our own dma_set_mask handler to fixup dma_ops
-			 * and dma_offset
-			 */
-			ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
-
-			pr_info("%s: Setup 64-bit PCI DMA window\n", name);
+			iowrite32be(0, &pci->regs->piw[win_idx].pitar);
+			iowrite32be(fsl_arch_pci64_dma_offset() >> 44,
+				    &pci->regs->piw[win_idx].piwbear);
+			iowrite32be(fsl_arch_pci64_dma_offset() >> 12,
+				    &pci->regs->piw[win_idx].piwbar);
+			iowrite32be(piwar,
+				    &pci->regs->piw[win_idx].piwar);
 		}
 	} else {
 		u64 paddr = 0;
 
 		/* Setup inbound memory window */
-		out_be32(&pci->piw[win_idx].pitar,  paddr >> 12);
-		out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
-		out_be32(&pci->piw[win_idx].piwar,  (piwar | (mem_log - 1)));
+		iowrite32be(paddr >> 12, &pci->regs->piw[win_idx].pitar);
+		iowrite32be(paddr >> 12, &pci->regs->piw[win_idx].piwbar);
+		iowrite32be((piwar | (mem_log - 1)),
+			    &pci->regs->piw[win_idx].piwar);
 		win_idx--;
 
 		paddr += 1ull << mem_log;
@@ -462,35 +472,36 @@  static void setup_pci_atmu(struct pci_controller *hose)
 			mem_log = ilog2(sz);
 			piwar |= (mem_log - 1);
 
-			out_be32(&pci->piw[win_idx].pitar,  paddr >> 12);
-			out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
-			out_be32(&pci->piw[win_idx].piwar,  piwar);
+			iowrite32be(paddr >> 12,
+				    &pci->regs->piw[win_idx].pitar);
+			iowrite32be(paddr >> 12,
+				    &pci->regs->piw[win_idx].piwbar);
+			iowrite32be(piwar,
+				    &pci->regs->piw[win_idx].piwar);
 			win_idx--;
 
 			paddr += 1ull << mem_log;
 		}
 
-		hose->dma_window_base_cur = 0x00000000;
-		hose->dma_window_size = (resource_size_t)paddr;
+		pci->dma_window_base_cur = 0x00000000;
+		pci->dma_window_size = (resource_size_t)paddr;
 	}
 
-	if (hose->dma_window_size < mem) {
-#ifdef CONFIG_SWIOTLB
-		ppc_swiotlb_enable = 1;
-#else
-		pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to "
-			"map - enable CONFIG_SWIOTLB to avoid dma errors.\n",
-			 name);
+	if (pci->dma_window_size < mem) {
+#ifndef CONFIG_SWIOTLB
+		dev_err(pci->dev,
+			"Memory size exceeds PCI ATMU ability to "
+			"map - enable CONFIG_SWIOTLB to avoid dma errors.\n");
 #endif
 		/* adjusting outbound windows could reclaim space in mem map */
 		if (paddr_hi < 0xffffffffull)
-			pr_warning("%s: WARNING: Outbound window cfg leaves "
+			dev_warn(pci->dev,
+				 "Outbound window cfg leaves "
 				"gaps in memory map. Adjusting the memory map "
-				"could reduce unnecessary bounce buffering.\n",
-				name);
+				"could reduce unnecessary bounce buffering.\n");
 
-		pr_info("%s: DMA window size is 0x%llx\n", name,
-			(u64)hose->dma_window_size);
+		dev_info(pci->dev, "DMA window size is 0x%llx\n",
+			 (u64)pci->dma_window_size);
 	}
 }
 
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index a3aca29..490ee53 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -156,5 +156,8 @@  int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn);
  */
 extern struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr);
 
+/* Return PCI64 DMA offset */
+u64 fsl_arch_pci64_dma_offset(void);
+
 #endif /* __PCI_COMMON_H */
 #endif /* __KERNEL__ */