[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