aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/ppc4xx_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/ppc4xx_pci.c')
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c101
1 files changed, 78 insertions, 23 deletions
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index dbfe96bc878..862f11b3821 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -834,7 +834,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np)
834 return 3; 834 return 3;
835} 835}
836 836
837static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 837static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
838{ 838{
839 u32 val = 1 << 24; 839 u32 val = 1 << 24;
840 840
@@ -872,12 +872,12 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
872 return ppc4xx_pciex_port_reset_sdr(port); 872 return ppc4xx_pciex_port_reset_sdr(port);
873} 873}
874 874
875static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 875static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
876{ 876{
877 return ppc440spe_pciex_init_port_hw(port); 877 return ppc440spe_pciex_init_port_hw(port);
878} 878}
879 879
880static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 880static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
881{ 881{
882 int rc = ppc440spe_pciex_init_port_hw(port); 882 int rc = ppc440spe_pciex_init_port_hw(port);
883 883
@@ -936,7 +936,7 @@ static int __init ppc460ex_pciex_core_init(struct device_node *np)
936 return 2; 936 return 2;
937} 937}
938 938
939static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 939static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
940{ 940{
941 u32 val; 941 u32 val;
942 u32 utlset1; 942 u32 utlset1;
@@ -1092,6 +1092,10 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
1092 mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); 1092 mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
1093 mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); 1093 mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
1094 1094
1095 /* Set HSS PRBS enabled */
1096 mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130);
1097 mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130);
1098
1095 udelay(100); 1099 udelay(100);
1096 1100
1097 /* De-assert PLLRESET */ 1101 /* De-assert PLLRESET */
@@ -1122,7 +1126,7 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
1122 return 2; 1126 return 2;
1123} 1127}
1124 1128
1125static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 1129static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1126{ 1130{
1127 1131
1128 if (port->endpoint) 1132 if (port->endpoint)
@@ -1132,9 +1136,6 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1132 dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, 1136 dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
1133 0, 0x01000000); 1137 0, 0x01000000);
1134 1138
1135 /*Gen-1*/
1136 mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
1137
1138 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 1139 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
1139 (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), 1140 (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
1140 PESDRx_RCSSET_RSTPYN); 1141 PESDRx_RCSSET_RSTPYN);
@@ -1148,14 +1149,42 @@ static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
1148{ 1149{
1149 /* Max 128 Bytes */ 1150 /* Max 128 Bytes */
1150 out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); 1151 out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000);
1152 /* Assert VRB and TXE - per datasheet turn off addr validation */
1153 out_be32(port->utl_base + PEUTL_PCTL, 0x80800000);
1151 return 0; 1154 return 0;
1152} 1155}
1153 1156
1157static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port)
1158{
1159 void __iomem *mbase;
1160 int attempt = 50;
1161
1162 port->link = 0;
1163
1164 mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
1165 if (mbase == NULL) {
1166 printk(KERN_ERR "%s: Can't map internal config space !",
1167 port->node->full_name);
1168 goto done;
1169 }
1170
1171 while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA)
1172 & PECFG_460SX_DLLSTA_LINKUP))) {
1173 attempt--;
1174 mdelay(10);
1175 }
1176 if (attempt)
1177 port->link = 1;
1178done:
1179 iounmap(mbase);
1180
1181}
1182
1154static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { 1183static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
1155 .core_init = ppc460sx_pciex_core_init, 1184 .core_init = ppc460sx_pciex_core_init,
1156 .port_init_hw = ppc460sx_pciex_init_port_hw, 1185 .port_init_hw = ppc460sx_pciex_init_port_hw,
1157 .setup_utl = ppc460sx_pciex_init_utl, 1186 .setup_utl = ppc460sx_pciex_init_utl,
1158 .check_link = ppc4xx_pciex_check_link_sdr, 1187 .check_link = ppc460sx_pciex_check_link,
1159}; 1188};
1160 1189
1161#endif /* CONFIG_44x */ 1190#endif /* CONFIG_44x */
@@ -1189,7 +1218,7 @@ static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port)
1189 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); 1218 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000);
1190} 1219}
1191 1220
1192static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 1221static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1193{ 1222{
1194 u32 val; 1223 u32 val;
1195 1224
@@ -1338,15 +1367,15 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1338 if (rc != 0) 1367 if (rc != 0)
1339 return rc; 1368 return rc;
1340 1369
1341 if (ppc4xx_pciex_hwops->check_link)
1342 ppc4xx_pciex_hwops->check_link(port);
1343
1344 /* 1370 /*
1345 * Initialize mapping: disable all regions and configure 1371 * Initialize mapping: disable all regions and configure
1346 * CFG and REG regions based on resources in the device tree 1372 * CFG and REG regions based on resources in the device tree
1347 */ 1373 */
1348 ppc4xx_pciex_port_init_mapping(port); 1374 ppc4xx_pciex_port_init_mapping(port);
1349 1375
1376 if (ppc4xx_pciex_hwops->check_link)
1377 ppc4xx_pciex_hwops->check_link(port);
1378
1350 /* 1379 /*
1351 * Map UTL 1380 * Map UTL
1352 */ 1381 */
@@ -1360,13 +1389,23 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1360 ppc4xx_pciex_hwops->setup_utl(port); 1389 ppc4xx_pciex_hwops->setup_utl(port);
1361 1390
1362 /* 1391 /*
1363 * Check for VC0 active and assert RDY. 1392 * Check for VC0 active or PLL Locked and assert RDY.
1364 */ 1393 */
1365 if (port->sdr_base) { 1394 if (port->sdr_base) {
1366 if (port->link && 1395 if (of_device_is_compatible(port->node,
1367 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1396 "ibm,plb-pciex-460sx")){
1368 1 << 16, 1 << 16, 5000)) { 1397 if (port->link && ppc4xx_pciex_wait_on_sdr(port,
1369 printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); 1398 PESDRn_RCSSTS,
1399 1 << 12, 1 << 12, 5000)) {
1400 printk(KERN_INFO "PCIE%d: PLL not locked\n",
1401 port->index);
1402 port->link = 0;
1403 }
1404 } else if (port->link &&
1405 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
1406 1 << 16, 1 << 16, 5000)) {
1407 printk(KERN_INFO "PCIE%d: VC0 not active\n",
1408 port->index);
1370 port->link = 0; 1409 port->link = 0;
1371 } 1410 }
1372 1411
@@ -1573,8 +1612,15 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1573 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); 1612 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
1574 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); 1613 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
1575 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); 1614 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
1576 /* Note that 3 here means enabled | single region */ 1615 /*Enabled and single region */
1577 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); 1616 if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
1617 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
1618 sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT
1619 | DCRO_PEGPL_OMRxMSKL_VAL);
1620 else
1621 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
1622 sa | DCRO_PEGPL_OMR1MSKL_UOT
1623 | DCRO_PEGPL_OMRxMSKL_VAL);
1578 break; 1624 break;
1579 case 1: 1625 case 1:
1580 out_le32(mbase + PECFG_POM1LAH, pciah); 1626 out_le32(mbase + PECFG_POM1LAH, pciah);
@@ -1582,8 +1628,8 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1582 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); 1628 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
1583 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); 1629 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
1584 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); 1630 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
1585 /* Note that 3 here means enabled | single region */ 1631 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL,
1586 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); 1632 sa | DCRO_PEGPL_OMRxMSKL_VAL);
1587 break; 1633 break;
1588 case 2: 1634 case 2:
1589 out_le32(mbase + PECFG_POM2LAH, pciah); 1635 out_le32(mbase + PECFG_POM2LAH, pciah);
@@ -1592,7 +1638,9 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1592 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); 1638 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
1593 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); 1639 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
1594 /* Note that 3 here means enabled | IO space !!! */ 1640 /* Note that 3 here means enabled | IO space !!! */
1595 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3); 1641 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL,
1642 sa | DCRO_PEGPL_OMR3MSKL_IO
1643 | DCRO_PEGPL_OMRxMSKL_VAL);
1596 break; 1644 break;
1597 } 1645 }
1598 1646
@@ -1693,6 +1741,9 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
1693 if (res->flags & IORESOURCE_PREFETCH) 1741 if (res->flags & IORESOURCE_PREFETCH)
1694 sa |= 0x8; 1742 sa |= 0x8;
1695 1743
1744 if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
1745 sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
1746
1696 out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); 1747 out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
1697 out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); 1748 out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
1698 1749
@@ -1854,6 +1905,10 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
1854 } 1905 }
1855 out_le16(mbase + 0x202, val); 1906 out_le16(mbase + 0x202, val);
1856 1907
1908 /* Enable Bus master, memory, and io space */
1909 if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
1910 out_le16(mbase + 0x204, 0x7);
1911
1857 if (!port->endpoint) { 1912 if (!port->endpoint) {
1858 /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ 1913 /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
1859 out_le32(mbase + 0x208, 0x06040001); 1914 out_le32(mbase + 0x208, 0x06040001);