diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-12-15 19:24:25 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-12-15 19:24:25 -0500 |
commit | 1e7342e7789fa2ca9202701467428726cbcfd649 (patch) | |
tree | e0ad000924e9875bd2ea17bd0e04382491765a09 /arch/powerpc/sysdev | |
parent | 78c5c68a4cf4329d17abfa469345ddf323d4fd62 (diff) | |
parent | 228d55053397e6d5325ca179c7ffe331de2846d3 (diff) |
Merge remote-tracking branch 'jwb/next' into next
Conflicts:
arch/powerpc/platforms/40x/ppc40x_simple.c
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 85 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.h | 7 |
2 files changed, 84 insertions, 8 deletions
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 862f11b3821e..4f05f7542346 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -185,9 +185,15 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, | |||
185 | out: | 185 | out: |
186 | dma_offset_set = 1; | 186 | dma_offset_set = 1; |
187 | pci_dram_offset = res->start; | 187 | pci_dram_offset = res->start; |
188 | hose->dma_window_base_cur = res->start; | ||
189 | hose->dma_window_size = resource_size(res); | ||
188 | 190 | ||
189 | printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n", | 191 | printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n", |
190 | pci_dram_offset); | 192 | pci_dram_offset); |
193 | printk(KERN_INFO "4xx PCI DMA window base to 0x%016llx\n", | ||
194 | (unsigned long long)hose->dma_window_base_cur); | ||
195 | printk(KERN_INFO "DMA window size 0x%016llx\n", | ||
196 | (unsigned long long)hose->dma_window_size); | ||
191 | return 0; | 197 | return 0; |
192 | } | 198 | } |
193 | 199 | ||
@@ -647,6 +653,7 @@ static unsigned int ppc4xx_pciex_port_count; | |||
647 | 653 | ||
648 | struct ppc4xx_pciex_hwops | 654 | struct ppc4xx_pciex_hwops |
649 | { | 655 | { |
656 | bool want_sdr; | ||
650 | int (*core_init)(struct device_node *np); | 657 | int (*core_init)(struct device_node *np); |
651 | int (*port_init_hw)(struct ppc4xx_pciex_port *port); | 658 | int (*port_init_hw)(struct ppc4xx_pciex_port *port); |
652 | int (*setup_utl)(struct ppc4xx_pciex_port *port); | 659 | int (*setup_utl)(struct ppc4xx_pciex_port *port); |
@@ -916,6 +923,7 @@ static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port) | |||
916 | 923 | ||
917 | static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = | 924 | static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = |
918 | { | 925 | { |
926 | .want_sdr = true, | ||
919 | .core_init = ppc440spe_pciex_core_init, | 927 | .core_init = ppc440spe_pciex_core_init, |
920 | .port_init_hw = ppc440speA_pciex_init_port_hw, | 928 | .port_init_hw = ppc440speA_pciex_init_port_hw, |
921 | .setup_utl = ppc440speA_pciex_init_utl, | 929 | .setup_utl = ppc440speA_pciex_init_utl, |
@@ -924,6 +932,7 @@ static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = | |||
924 | 932 | ||
925 | static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = | 933 | static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = |
926 | { | 934 | { |
935 | .want_sdr = true, | ||
927 | .core_init = ppc440spe_pciex_core_init, | 936 | .core_init = ppc440spe_pciex_core_init, |
928 | .port_init_hw = ppc440speB_pciex_init_port_hw, | 937 | .port_init_hw = ppc440speB_pciex_init_port_hw, |
929 | .setup_utl = ppc440speB_pciex_init_utl, | 938 | .setup_utl = ppc440speB_pciex_init_utl, |
@@ -1034,6 +1043,7 @@ static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port) | |||
1034 | 1043 | ||
1035 | static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = | 1044 | static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = |
1036 | { | 1045 | { |
1046 | .want_sdr = true, | ||
1037 | .core_init = ppc460ex_pciex_core_init, | 1047 | .core_init = ppc460ex_pciex_core_init, |
1038 | .port_init_hw = ppc460ex_pciex_init_port_hw, | 1048 | .port_init_hw = ppc460ex_pciex_init_port_hw, |
1039 | .setup_utl = ppc460ex_pciex_init_utl, | 1049 | .setup_utl = ppc460ex_pciex_init_utl, |
@@ -1181,6 +1191,7 @@ done: | |||
1181 | } | 1191 | } |
1182 | 1192 | ||
1183 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | 1193 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { |
1194 | .want_sdr = true, | ||
1184 | .core_init = ppc460sx_pciex_core_init, | 1195 | .core_init = ppc460sx_pciex_core_init, |
1185 | .port_init_hw = ppc460sx_pciex_init_port_hw, | 1196 | .port_init_hw = ppc460sx_pciex_init_port_hw, |
1186 | .setup_utl = ppc460sx_pciex_init_utl, | 1197 | .setup_utl = ppc460sx_pciex_init_utl, |
@@ -1276,6 +1287,7 @@ static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port) | |||
1276 | 1287 | ||
1277 | static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata = | 1288 | static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata = |
1278 | { | 1289 | { |
1290 | .want_sdr = true, | ||
1279 | .core_init = ppc405ex_pciex_core_init, | 1291 | .core_init = ppc405ex_pciex_core_init, |
1280 | .port_init_hw = ppc405ex_pciex_init_port_hw, | 1292 | .port_init_hw = ppc405ex_pciex_init_port_hw, |
1281 | .setup_utl = ppc405ex_pciex_init_utl, | 1293 | .setup_utl = ppc405ex_pciex_init_utl, |
@@ -1284,6 +1296,52 @@ static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata = | |||
1284 | 1296 | ||
1285 | #endif /* CONFIG_40x */ | 1297 | #endif /* CONFIG_40x */ |
1286 | 1298 | ||
1299 | #ifdef CONFIG_476FPE | ||
1300 | static int __init ppc_476fpe_pciex_core_init(struct device_node *np) | ||
1301 | { | ||
1302 | return 4; | ||
1303 | } | ||
1304 | |||
1305 | static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port) | ||
1306 | { | ||
1307 | u32 timeout_ms = 20; | ||
1308 | u32 val = 0, mask = (PECFG_TLDLP_LNKUP|PECFG_TLDLP_PRESENT); | ||
1309 | void __iomem *mbase = ioremap(port->cfg_space.start + 0x10000000, | ||
1310 | 0x1000); | ||
1311 | |||
1312 | printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); | ||
1313 | |||
1314 | if (mbase == NULL) { | ||
1315 | printk(KERN_WARNING "PCIE%d: failed to get cfg space\n", | ||
1316 | port->index); | ||
1317 | return; | ||
1318 | } | ||
1319 | |||
1320 | while (timeout_ms--) { | ||
1321 | val = in_le32(mbase + PECFG_TLDLP); | ||
1322 | |||
1323 | if ((val & mask) == mask) | ||
1324 | break; | ||
1325 | msleep(10); | ||
1326 | } | ||
1327 | |||
1328 | if (val & PECFG_TLDLP_PRESENT) { | ||
1329 | printk(KERN_INFO "PCIE%d: link is up !\n", port->index); | ||
1330 | port->link = 1; | ||
1331 | } else | ||
1332 | printk(KERN_WARNING "PCIE%d: Link up failed\n", port->index); | ||
1333 | |||
1334 | iounmap(mbase); | ||
1335 | return; | ||
1336 | } | ||
1337 | |||
1338 | static struct ppc4xx_pciex_hwops ppc_476fpe_pcie_hwops __initdata = | ||
1339 | { | ||
1340 | .core_init = ppc_476fpe_pciex_core_init, | ||
1341 | .check_link = ppc_476fpe_pciex_check_link, | ||
1342 | }; | ||
1343 | #endif /* CONFIG_476FPE */ | ||
1344 | |||
1287 | /* Check that the core has been initied and if not, do it */ | 1345 | /* Check that the core has been initied and if not, do it */ |
1288 | static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | 1346 | static int __init ppc4xx_pciex_check_core_init(struct device_node *np) |
1289 | { | 1347 | { |
@@ -1309,6 +1367,10 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | |||
1309 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) | 1367 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) |
1310 | ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; | 1368 | ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; |
1311 | #endif | 1369 | #endif |
1370 | #ifdef CONFIG_476FPE | ||
1371 | if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe")) | ||
1372 | ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; | ||
1373 | #endif | ||
1312 | if (ppc4xx_pciex_hwops == NULL) { | 1374 | if (ppc4xx_pciex_hwops == NULL) { |
1313 | printk(KERN_WARNING "PCIE: unknown host type %s\n", | 1375 | printk(KERN_WARNING "PCIE: unknown host type %s\n", |
1314 | np->full_name); | 1376 | np->full_name); |
@@ -1617,6 +1679,10 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1617 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1679 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1618 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT | 1680 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT |
1619 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1681 | | DCRO_PEGPL_OMRxMSKL_VAL); |
1682 | else if (of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe")) | ||
1683 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | ||
1684 | sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT | ||
1685 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1620 | else | 1686 | else |
1621 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1687 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1622 | sa | DCRO_PEGPL_OMR1MSKL_UOT | 1688 | sa | DCRO_PEGPL_OMR1MSKL_UOT |
@@ -1739,9 +1805,10 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, | |||
1739 | /* Calculate window size */ | 1805 | /* Calculate window size */ |
1740 | sa = (0xffffffffffffffffull << ilog2(size)); | 1806 | sa = (0xffffffffffffffffull << ilog2(size)); |
1741 | if (res->flags & IORESOURCE_PREFETCH) | 1807 | if (res->flags & IORESOURCE_PREFETCH) |
1742 | sa |= 0x8; | 1808 | sa |= PCI_BASE_ADDRESS_MEM_PREFETCH; |
1743 | 1809 | ||
1744 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | 1810 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") || |
1811 | of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe")) | ||
1745 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; | 1812 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; |
1746 | 1813 | ||
1747 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); | 1814 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); |
@@ -1972,13 +2039,15 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) | |||
1972 | } | 2039 | } |
1973 | 2040 | ||
1974 | port->node = of_node_get(np); | 2041 | port->node = of_node_get(np); |
1975 | pval = of_get_property(np, "sdr-base", NULL); | 2042 | if (ppc4xx_pciex_hwops->want_sdr) { |
1976 | if (pval == NULL) { | 2043 | pval = of_get_property(np, "sdr-base", NULL); |
1977 | printk(KERN_ERR "PCIE: missing sdr-base for %s\n", | 2044 | if (pval == NULL) { |
1978 | np->full_name); | 2045 | printk(KERN_ERR "PCIE: missing sdr-base for %s\n", |
1979 | return; | 2046 | np->full_name); |
2047 | return; | ||
2048 | } | ||
2049 | port->sdr_base = *pval; | ||
1980 | } | 2050 | } |
1981 | port->sdr_base = *pval; | ||
1982 | 2051 | ||
1983 | /* Check if device_type property is set to "pci" or "pci-endpoint". | 2052 | /* Check if device_type property is set to "pci" or "pci-endpoint". |
1984 | * Resulting from this setup this PCIe port will be configured | 2053 | * Resulting from this setup this PCIe port will be configured |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index 32ce763a375a..bb4821938ab1 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h | |||
@@ -476,6 +476,13 @@ | |||
476 | #define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002 | 476 | #define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002 |
477 | #define DCRO_PEGPL_OMR3MSKL_IO 0x00000002 | 477 | #define DCRO_PEGPL_OMR3MSKL_IO 0x00000002 |
478 | 478 | ||
479 | /* 476FPE */ | ||
480 | #define PCCFG_LCPA 0x270 | ||
481 | #define PECFG_TLDLP 0x3F8 | ||
482 | #define PECFG_TLDLP_LNKUP 0x00000008 | ||
483 | #define PECFG_TLDLP_PRESENT 0x00000010 | ||
484 | #define DCRO_PEGPL_476FPE_OMR1MSKL_UOT 0x00000004 | ||
485 | |||
479 | /* SDR Bit Mappings */ | 486 | /* SDR Bit Mappings */ |
480 | #define PESDRx_RCSSET_HLDPLB 0x10000000 | 487 | #define PESDRx_RCSSET_HLDPLB 0x10000000 |
481 | #define PESDRx_RCSSET_RSTGU 0x01000000 | 488 | #define PESDRx_RCSSET_RSTGU 0x01000000 |