diff options
author | Vinh Nguyen Huu Tuong <vhtnguyen@apm.com> | 2012-03-14 20:57:19 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@gmail.com> | 2012-03-17 08:49:34 -0400 |
commit | b6bb23b923048be159265004f4cd6aa272da2409 (patch) | |
tree | dc983afe328b9486ef9d28f72bdf21ddbf434858 /arch/powerpc/sysdev | |
parent | 645609c0d9e1fa0febc882f3605457d28484ed2a (diff) |
powerpc/44x: Add support PCI-E for APM821xx SoC and Bluestone board
This patch extends PCI-E driver to support PCI-E for APM821xx SoC on Bluestone
board.
Signed-off-by: Vinh Nguyen Huu Tuong <vhtnguyen@apm.com>
Signed-off-by: Josh Boyer <jwboyer@gmail.com>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 4f05f7542346..56e8b3c3c890 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -1050,6 +1050,74 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = | |||
1050 | .check_link = ppc4xx_pciex_check_link_sdr, | 1050 | .check_link = ppc4xx_pciex_check_link_sdr, |
1051 | }; | 1051 | }; |
1052 | 1052 | ||
1053 | static int __init apm821xx_pciex_core_init(struct device_node *np) | ||
1054 | { | ||
1055 | /* Return the number of pcie port */ | ||
1056 | return 1; | ||
1057 | } | ||
1058 | |||
1059 | static int apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | ||
1060 | { | ||
1061 | u32 val; | ||
1062 | |||
1063 | /* | ||
1064 | * Do a software reset on PCIe ports. | ||
1065 | * This code is to fix the issue that pci drivers doesn't re-assign | ||
1066 | * bus number for PCIE devices after Uboot | ||
1067 | * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000 | ||
1068 | * PT quad port, SAS LSI 1064E) | ||
1069 | */ | ||
1070 | |||
1071 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0); | ||
1072 | mdelay(10); | ||
1073 | |||
1074 | if (port->endpoint) | ||
1075 | val = PTYPE_LEGACY_ENDPOINT << 20; | ||
1076 | else | ||
1077 | val = PTYPE_ROOT_PORT << 20; | ||
1078 | |||
1079 | val |= LNKW_X1 << 12; | ||
1080 | |||
1081 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); | ||
1082 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000); | ||
1083 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000); | ||
1084 | |||
1085 | mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); | ||
1086 | mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130); | ||
1087 | mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); | ||
1088 | |||
1089 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000); | ||
1090 | mdelay(50); | ||
1091 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000); | ||
1092 | |||
1093 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, | ||
1094 | mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | | ||
1095 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); | ||
1096 | |||
1097 | /* Poll for PHY reset */ | ||
1098 | val = PESDR0_460EX_RSTSTA - port->sdr_base; | ||
1099 | if (ppc4xx_pciex_wait_on_sdr(port, val, 0x1, 1, 100)) { | ||
1100 | printk(KERN_WARNING "%s: PCIE: Can't reset PHY\n", __func__); | ||
1101 | return -EBUSY; | ||
1102 | } else { | ||
1103 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, | ||
1104 | (mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) & | ||
1105 | ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | | ||
1106 | PESDRx_RCSSET_RSTPYN); | ||
1107 | |||
1108 | port->has_ibpre = 1; | ||
1109 | return 0; | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | static struct ppc4xx_pciex_hwops apm821xx_pcie_hwops __initdata = { | ||
1114 | .want_sdr = true, | ||
1115 | .core_init = apm821xx_pciex_core_init, | ||
1116 | .port_init_hw = apm821xx_pciex_init_port_hw, | ||
1117 | .setup_utl = ppc460ex_pciex_init_utl, | ||
1118 | .check_link = ppc4xx_pciex_check_link_sdr, | ||
1119 | }; | ||
1120 | |||
1053 | static int __init ppc460sx_pciex_core_init(struct device_node *np) | 1121 | static int __init ppc460sx_pciex_core_init(struct device_node *np) |
1054 | { | 1122 | { |
1055 | /* HSS drive amplitude */ | 1123 | /* HSS drive amplitude */ |
@@ -1362,6 +1430,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | |||
1362 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; | 1430 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; |
1363 | if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) | 1431 | if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) |
1364 | ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; | 1432 | ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; |
1433 | if (of_device_is_compatible(np, "ibm,plb-pciex-apm821xx")) | ||
1434 | ppc4xx_pciex_hwops = &apm821xx_pcie_hwops; | ||
1365 | #endif /* CONFIG_44x */ | 1435 | #endif /* CONFIG_44x */ |
1366 | #ifdef CONFIG_40x | 1436 | #ifdef CONFIG_40x |
1367 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) | 1437 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) |