[linux-yocto] [PATCH 04/15] arch/powerpc: Added PCIe driver support for ACP35xx

Charlie Paul cpaul.windriver at gmail.com
Mon Jan 20 09:56:11 PST 2014


From: SangeethaRao <sangeetha.rao at lsi.com>

Signed-off-by: SangeethaRao <sangeetha.rao at lsi.com>
---
 arch/powerpc/boot/dts/acp35xx.dts |    4 +-
 arch/powerpc/sysdev/lsi_pci.c     |  125 +++++++++++++++++++------------------
 2 files changed, 67 insertions(+), 62 deletions(-)

diff --git a/arch/powerpc/boot/dts/acp35xx.dts b/arch/powerpc/boot/dts/acp35xx.dts
index 83a4c90..a6686fd 100644
--- a/arch/powerpc/boot/dts/acp35xx.dts
+++ b/arch/powerpc/boot/dts/acp35xx.dts
@@ -393,8 +393,8 @@
                         0000 0 0 4 &MPIC 55 2
                 >;
         };
-+	SRIO0: srio0 {
-+		compatible = "acp,rapidio-delta";
+	SRIO0: srio0 {
+		compatible = "acp,rapidio-delta";
                 device_type = "rapidio";
 		enabled = <0>;
 		#size = <0>;    /* 0 = (256, small system)
diff --git a/arch/powerpc/sysdev/lsi_pci.c b/arch/powerpc/sysdev/lsi_pci.c
index ada78ad..ca1506d 100644
--- a/arch/powerpc/sysdev/lsi_pci.c
+++ b/arch/powerpc/sysdev/lsi_pci.c
@@ -20,6 +20,7 @@
 #include <mm/mmu_decl.h>
 
 #include "ppc4xx_pci.h"
+#include "../../../drivers/misc/lsi-ncr.h"
 
 #include <linux/interrupt.h>
 
@@ -49,12 +50,12 @@ fixup_acp_pci_bridge(struct pci_dev *dev)
 {
 	/* if we aren't a PCIe don't bother */
 	if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
-		return ;
+		return;
 
 	/*
 	 * Set the class appropriately for a bridge device
 	 */
-	printk(KERN_INFO
+	pr_info(
 		"PCI: Setting PCI Class to PCI_CLASS_BRIDGE_HOST for"
 		" %04x:%04x\n", dev->vendor, dev->device);
 
@@ -65,11 +66,12 @@ fixup_acp_pci_bridge(struct pci_dev *dev)
 	 */
 	dev->transparent = 1;
 
-	return ;
+	return;
 }
 
 DECLARE_PCI_FIXUP_HEADER(0x1000, 0x5101, fixup_acp_pci_bridge);
 DECLARE_PCI_FIXUP_HEADER(0x1000, 0x5108, fixup_acp_pci_bridge);
+DECLARE_PCI_FIXUP_HEADER(0x1000, 0x5102, fixup_acp_pci_bridge);
 
 static int __init acp_parse_dma_ranges(struct pci_controller *hose,
 					  void __iomem *reg,
@@ -90,7 +92,7 @@ static int __init acp_parse_dma_ranges(struct pci_controller *hose,
 	/* Get dma-ranges property */
 	ranges = of_get_property(hose->dn, "dma-ranges", &rlen);
 	if (ranges == NULL) {
-		printk(KERN_INFO "Not able to parse dma-ranges hence using defaults\n");
+		pr_info("Not able to parse dma-ranges hence using defaults\n");
 		goto out;
 	}
 
@@ -112,8 +114,7 @@ static int __init acp_parse_dma_ranges(struct pci_controller *hose,
 		 * within 32 bits space
 		 */
 		if (cpu_addr != 0 || pci_addr > 0xffffffff) {
-			printk(KERN_WARNING "%s: Ignored unsupported dma range"
-			       " 0x%016llx...0x%016llx -> 0x%016llx\n",
+			pr_warn("%s: Ignored unsupported dma range 0x%016llx...0x%016llx -> 0x%016llx\n",
 			       hose->dn->full_name,
 			       pci_addr, pci_addr + size - 1, cpu_addr);
 			continue;
@@ -137,7 +138,7 @@ static int __init acp_parse_dma_ranges(struct pci_controller *hose,
 
 	/* We only support one global DMA offset */
 	if (dma_offset_set && pci_dram_offset != res->start) {
-		printk(KERN_ERR "%s: dma-ranges(s) mismatch\n",
+		pr_err("%s: dma-ranges(s) mismatch\n",
 		       hose->dn->full_name);
 		return -ENXIO;
 	}
@@ -146,8 +147,7 @@ static int __init acp_parse_dma_ranges(struct pci_controller *hose,
 	 * DMA bounce buffers
 	 */
 	if (size < total_memory) {
-		printk(KERN_ERR "%s: dma-ranges too small "
-		       "(size=%llx total_memory=%llx)\n",
+		pr_err("%s: dma-ranges too small (size=%llx total_memory=%llx)\n",
 		       hose->dn->full_name, size, (u64)total_memory);
 		return -ENXIO;
 	}
@@ -155,14 +155,14 @@ static int __init acp_parse_dma_ranges(struct pci_controller *hose,
 	/* Check we are a power of 2 size and that base is a multiple of size*/
 	if ((size & (size - 1)) != 0  ||
 	    (res->start & (size - 1)) != 0) {
-		printk(KERN_ERR "%s: dma-ranges unaligned\n",
+		pr_err("%s: dma-ranges unaligned\n",
 		       hose->dn->full_name);
 		return -ENXIO;
 	}
 
 	/* Check that we are fully contained within 32 bits space */
 	if (res->end > 0xffffffff) {
-		printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n",
+		pr_err("%s: dma-ranges outside of 32 bits space\n",
 		       hose->dn->full_name);
 		return -ENXIO;
 	}
@@ -174,11 +174,11 @@ out:
 	hose->dma_window_base_cur = res->start;
 	hose->dma_window_size = resource_size(res);
 
-	printk(KERN_INFO "ACP PCI DMA offset set to 0x%08lx\n",
+	pr_info("ACP PCI DMA offset set to 0x%08lx\n",
 	       pci_dram_offset);
-	printk(KERN_INFO "ACP PCI DMA window base to 0x%016llx\n",
+	pr_info("ACP PCI DMA window base to 0x%016llx\n",
 	       (unsigned long long)hose->dma_window_base_cur);
-	printk(KERN_INFO "DMA window size 0x%016llx\n",
+	pr_info("DMA window size 0x%016llx\n",
 	       (unsigned long long)hose->dma_window_size);
 	return 0;
 }
@@ -252,7 +252,7 @@ static int __init acp_pciex_check_core_init(struct device_node *np)
 		acp_pcie_hwops = &hwops;
 
 	if (acp_pcie_hwops == NULL) {
-		printk(KERN_WARNING "PCIE: unknown host type %s\n",
+		pr_warn("PCIE: unknown host type %s\n",
 		       np->full_name);
 		return -ENODEV;
 	}
@@ -266,7 +266,7 @@ static int __init acp_pciex_check_core_init(struct device_node *np)
 			acp_pciex_port_count = count;
 			return 0;
 		}
-		printk(KERN_WARNING "PCIE: failed to allocate ports array\n");
+		pr_warn("PCIE: failed to allocate ports array\n");
 		return -ENOMEM;
 	}
 	return -ENODEV;
@@ -286,8 +286,8 @@ static int acp_pciex_validate_bdf(struct pciex_port *port,
 	/* Check we are within the mapped range */
 	if (bus->number > port->hose->last_busno) {
 		if (!message) {
-			printk(KERN_WARNING "Warning! Probing bus %u"
-			       " out of range !\n", bus->number);
+			pr_warn("Warning! Probing bus %u out of range !\n",
+					bus->number);
 			message++;
 		}
 		return PCIBIOS_DEVICE_NOT_FOUND;
@@ -473,7 +473,7 @@ pciex_acp_read_config(struct pci_bus *bus, unsigned int devfn,
 		__asm__ __volatile__("msync");
 
 #ifdef PRINT_CONFIG_ACCESSES
-		printk(KERN_INFO
+		pr_info(
 		       "acp_read_config : %3d [%3d..%3d] fn=0x%04x o=0x%04x"
 			" l=%d a=0x%08x machine check!! 0x%08x\n",
 		       bus->number, hose->first_busno, hose->last_busno,
@@ -489,7 +489,7 @@ pciex_acp_read_config(struct pci_bus *bus, unsigned int devfn,
 		rc =  PCIBIOS_DEVICE_NOT_FOUND;
 	} else {
 #ifdef PRINT_CONFIG_ACCESSES
-		printk(KERN_INFO
+		pr_info(
 		       "acp_read_config : %3d [%3d..%3d] fn=0x%04x o=0x%04x"
 			" l=%d a=0x%08x v=0x%08x\n",
 		       bus->number, hose->first_busno, hose->last_busno,
@@ -563,7 +563,7 @@ pciex_acp_write_config(struct pci_bus *bus,
 		bus_addr = (u32) addr + (offset << 2) + (offset & 0x3);
 
 #ifdef PRINT_CONFIG_ACCESSES
-	printk(KERN_INFO
+	pr_info(
 	       "acp_write_config: %3d [%3d..%3d] fn=0x%04x o=0x%04x l=%d"
 		" a=0x%08x v=0x%08x\n",
 	       bus->number, hose->first_busno, hose->last_busno,
@@ -614,7 +614,7 @@ static int __init acp_setup_one_pciex_POM(struct pciex_port	*port,
 	if ((index < 2 && size < 0x100000) ||
 	    (index == 2 && size < 0x100) ||
 	    (plb_addr & (size - 1)) != 0) {
-		printk(KERN_WARNING "%s: Resource out of range\n",
+		pr_warn("%s: Resource out of range\n",
 		       hose->dn->full_name);
 		return -1;
 	}
@@ -624,7 +624,7 @@ static int __init acp_setup_one_pciex_POM(struct pciex_port	*port,
 	pcial = RES_TO_U32_LOW(pci_addr);
 		/* ACP X1 setup MPAGE registers */
 
-		printk(KERN_INFO
+		pr_info(
 		       "setting outbound window %d with plb_add=0x%012llx,"
 			" pci_addr=0x%012llx, size=0x%012llx\n",
 		       index, plb_addr, pci_addr, size);
@@ -635,7 +635,7 @@ static int __init acp_setup_one_pciex_POM(struct pciex_port	*port,
 		 *  Calculate how many pages we need
 		 */
 		if (size > (7 * 0x08000000)) {
-			printk(KERN_WARNING "%s: Resource size 0x%012llx out of range\n",
+			pr_warn("%s: Resource size 0x%012llx out of range\n",
 			hose->dn->full_name, size);
 			return -1;
 		}
@@ -671,7 +671,7 @@ static void __init acp_configure_pciex_POMs(struct pciex_port *port,
 		if (!(res->flags & IORESOURCE_MEM))
 			continue;
 		if (j > 1) {
-			printk(KERN_WARNING "%s: Too many ranges\n",
+			pr_warn("%s: Too many ranges\n",
 			       port->node->full_name);
 			break;
 		}
@@ -698,7 +698,7 @@ static void __init acp_configure_pciex_POMs(struct pciex_port *port,
 		if (acp_setup_one_pciex_POM(port, hose, mbase,
 					       hose->isa_mem_phys, 0,
 					       hose->isa_mem_size, 0, j) == 0)
-			printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
+			pr_info("%s: Legacy ISA memory support enabled\n",
 			       hose->dn->full_name);
 
 	/* Configure IO, always 64K starting at 0. We hard wire it to 64K !
@@ -743,7 +743,7 @@ configure_acp_pciex_PIMs(struct pciex_port *port,
 		if (res->flags & IORESOURCE_PREFETCH)
 			sa |= 0x8;
 
-		printk(KERN_INFO
+		pr_info(
 		       "configure inbound mapping from 0x%012llx-0x%012llx "
 		       "(0x%08llx bytes)\n", res->start, res->end, size);
 
@@ -762,7 +762,7 @@ configure_acp_pciex_PIMs(struct pciex_port *port,
 		out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(size));
 
 		if (5 == port->acpChipType) {
-			printk(KERN_WARNING "Setting SIZE for 2500\n");
+			pr_warn("Setting SIZE for 2500\n");
 			out_le32(mbase + 0x11f4, 0xf0000000UL);
 		}
 
@@ -801,7 +801,7 @@ configure_acp_pciex_PIMs(struct pciex_port *port,
 			  tpage size = 512MB, 32bit AXI bus access
 			*/
 			out_le32(tpage_base, 0x00000800);
-			printk(KERN_INFO
+			pr_info(
 			       "configure inbound mapping tpage 7 to "
 			       "0x00000800\n");
 		}
@@ -857,7 +857,7 @@ acp_pcie_isr(int irq, void *arg)
 				/* do nothing */
 				break;
 			default:
-				printk(KERN_INFO
+				pr_info(
 				       "BDF %02x:%02x.%x sent msgtype 0x%02x\n",
 				       bus, dev, fn, msg_type);
 				break;
@@ -878,18 +878,18 @@ acp_pcie_isr(int irq, void *arg)
 			u32 linkStatus;
 			u32 offset;
 
-			printk(KERN_ERR
+			pr_err(
 			       "ACP_PCIE_ISR: got PEI error interrupt 0x%08x\n",
 			       intr_status);
 
 			linkStatus = in_le32(mbase + 0x117c);
-			printk(KERN_ERR
+			pr_err(
 			       "link_status (0x117c) = 0x%08x\n",
 			       linkStatus);
 
 			if (intr_status & 0x00020000) {
 				t2a_err_stat = in_le32(mbase + 0x1170);
-				printk(KERN_ERR
+				pr_err(
 				       "t2a_fn_indp_err_stat = 0x%08x\n",
 				       t2a_err_stat);
 				int_enb = in_le32(mbase + 0x10c4);
@@ -899,7 +899,7 @@ acp_pcie_isr(int irq, void *arg)
 
 			if (intr_status & 0x00040000) {
 				t2a_other_err_stat = in_le32(mbase + 0x1174);
-				printk(KERN_ERR
+				pr_err(
 				       "t2a_fn_indp_other_err_stat = 0x%08x\n",
 				       t2a_other_err_stat);
 				int_enb = in_le32(mbase + 0x10c4);
@@ -908,10 +908,10 @@ acp_pcie_isr(int irq, void *arg)
 			}
 
 			if (intr_status & 0x00000800) {
-				printk(KERN_INFO
+				pr_info(
 				       "pci_config = 0x%08x\n",
 				       in_le32(mbase + 0x1000));
-				printk(KERN_INFO
+				pr_info(
 				       "pci_status = 0x%08x\n",
 				       in_le32(mbase + 0x1004));
 
@@ -924,7 +924,7 @@ acp_pcie_isr(int irq, void *arg)
 			 * dump all the potentially interesting PEI registers
 			 */
 			for (offset = 0x114c; offset <= 0x1180; offset += 4) {
-				printk(KERN_INFO
+				pr_info(
 				       "  0x%04x : 0x%08x\n",
 				       offset, in_le32(mbase + offset));
 			}
@@ -955,6 +955,7 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 	u32 pci_status;
 	u32 link_state;
 	u32 pci_config;
+	u32 version;
 
 	/* Check if primary bridge */
 	if (of_get_property(port->node, "primary", NULL))
@@ -994,7 +995,7 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 		*/
 		cfg_data = ioremap(port->cfg_space.start, 0x100000);
 		if (cfg_data == NULL) {
-			printk(KERN_ERR "%s: Can't map external config space !",
+			pr_err("%s: Can't map external config space !",
 			       port->node->full_name);
 			goto fail;
 		}
@@ -1019,7 +1020,7 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 
 	if (port->endpoint) {
 		/* if we're an endpoint don't do anything else */
-		printk(KERN_INFO
+		pr_info(
 		       "PCIE%d: successfully set as endpoint\n",
 		       port->index);
 		return;
@@ -1030,12 +1031,12 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 
 	pci_status = in_le32(mbase + 0x1004);
 	link_state = (pci_status & 0x3f00) >> 8;
-	printk("PCIE%d status = 0x%08x : PCI link state = 0x%x\n",
+	pr_info("PCIE%d status = 0x%08x : PCI link state = 0x%x\n",
 	port->index, pci_status, link_state);
 
 	/* make sure the ACP device is configured as PCI Root Complex */
 	if ((pci_status & 0x18) != 0x18) {
-		printk(KERN_ERR
+		pr_err(
 		       "ACP device is not PCI Root Complex! status = 0x%08x\n",
 		       pci_status);
 		goto fail;
@@ -1044,7 +1045,7 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 	/* make sure the link is up */
 	if (link_state != 0xb) {
 		/* reset */
-		printk(KERN_WARNING "PCI link in bad state - resetting\n");
+		pr_warn("PCI link in bad state - resetting\n");
 		pci_config |= 1;
 		out_le32(mbase + 0x1000, pci_config);
 		msleep(1000);
@@ -1052,15 +1053,24 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 		pci_status = in_le32(mbase + 0x1004);
 		link_state = (pci_status & 0x3f00) >> 8;
 
-		printk(KERN_INFO "PCI link state now = 0x%x\n", link_state);
+		pr_info("PCI link state now = 0x%x\n", link_state);
 
 		if (link_state != 0xb) {
-			printk(KERN_ERR
+			pr_err(
 			       "PCI link still in bad state - giving up!\n");
 			goto fail;
 		}
 	}
 
+	/* get the device version */
+	if (0 != ncr_read(NCP_REGION_ID(0x16, 0xff), 0x0, 4, &version)) {
+		pr_err("Unable to detect ACP revision!\n");
+		goto fail;
+	}
+	port->acpChipType = (version & 0xff);
+	pr_info("Using PEI register set for ACP chipType %d\n",
+		port->acpChipType);
+
 	/*
 	 * Set bus numbers on our root port
 	*/
@@ -1085,13 +1095,13 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 	/*
 	 * hook up an interrupt handler
 	*/
-	printk(KERN_INFO "PCIE%d mapping interrupt\n", port->index);
+	pr_info("PCIE%d mapping interrupt\n", port->index);
 	mappedIrq = irq_of_parse_and_map(port->node, 0);
 
 	err = request_irq(mappedIrq, acp_pcie_isr,
 			  IRQF_SHARED, "acp_pcie", hose);
 	if (err) {
-		printk(KERN_ERR "request_irq failed!!!!\n");
+		pr_err("request_irq failed!!!!\n");
 		goto fail;
 	}
 
@@ -1111,7 +1121,7 @@ acp_pciex_port_setup_hose(struct pciex_port *port)
 	}
 
 	if (!port->endpoint) {
-		printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
+		pr_info("PCIE%d: successfully set as root-complex\n",
 		       port->index);
 	} else {
 	}
@@ -1141,13 +1151,13 @@ static void __init probe_acp_pciex_bridge(struct device_node *np)
 	/* Get the port number from the device-tree */
 	pval = of_get_property(np, "port", NULL);
 	if (pval == NULL) {
-		printk(KERN_ERR "PCIE: Can't find port number for %s\n",
+		pr_err("PCIE: Can't find port number for %s\n",
 		       np->full_name);
 		return;
 	}
 	portno = *pval;
 	if (portno >= acp_pciex_port_count) {
-		printk(KERN_ERR "PCIE: port number out of range for %s\n",
+		pr_err("PCIE: port number out of range for %s\n",
 		       np->full_name);
 		return;
 	}
@@ -1158,7 +1168,7 @@ static void __init probe_acp_pciex_bridge(struct device_node *np)
 	 * Check if device is enabled
 	 */
 	if (!of_device_is_available(np)) {
-		printk(KERN_INFO "PCIE%d: Port disabled via device-tree\n",
+		pr_info("PCIE%d: Port disabled via device-tree\n",
 		       port->index);
 		return;
 	}
@@ -1167,16 +1177,11 @@ static void __init probe_acp_pciex_bridge(struct device_node *np)
 	field = of_get_property(np, "enabled", NULL);
 
 	if (!field || (field && (0 == *field))) {
-		printk(KERN_INFO "%s: Port disabled via device-tree\n",
+		pr_info("%s: Port disabled via device-tree\n",
 		       np->full_name);
 		return;
 	}
 
-
-	port->acpChipType = 0x2;
-	printk(KERN_INFO "Using PEI register set for ACP chipType %d\n",
-	port->acpChipType);
-
 	/* Check for the PLX work-around. */
 	field = of_get_property(np, "plx", NULL);
 
@@ -1197,21 +1202,21 @@ static void __init probe_acp_pciex_bridge(struct device_node *np)
 	} else if (!strcmp(val, "pci")) {
 		port->endpoint = 0;
 	} else {
-		printk(KERN_ERR "PCIE%d: missing or incorrect device_type for %s\n",
+		pr_err("PCIE%d: missing or incorrect device_type for %s\n",
 		       portno, np->full_name);
 		return;
 	}
 
 	/* Fetch config space registers address */
 	if (of_address_to_resource(np, 0, &port->cfg_space)) {
-		printk(KERN_ERR "%s: Can't get PCI-E config space !",
+		pr_err("%s: Can't get PCI-E config space !",
 		       np->full_name);
 		return;
 	}
 
 	/* Fetch host bridge internal registers address */
 	if (of_address_to_resource(np, 1, &port->utl_regs)) {
-		printk(KERN_ERR "%s: Can't get UTL register base !",
+		pr_err("%s: Can't get UTL register base !",
 		       np->full_name);
 		return;
 	}
@@ -1219,7 +1224,7 @@ static void __init probe_acp_pciex_bridge(struct device_node *np)
 	port->utl_base = ioremap(port->utl_regs.start,
 		resource_size(&port->utl_regs));
 
-	printk(KERN_INFO
+	pr_info(
 	       "%s PCIE%d config base = 0x%012llx (0x%08x virtual)\n",
 	       np->full_name, port->index, port->utl_regs.start,
 	       (u32) port->utl_base);
-- 
1.7.9.5



More information about the linux-yocto mailing list