aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManikanta Maddireddy <mmaddireddy@nvidia.com>2017-09-27 07:58:35 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-10-18 12:27:17 -0400
commit9cea513d8cbc75ee26327d3d8971fe7b58288d8f (patch)
treef80f38100f8c3e5e22e194fd17ced2194037e2fb
parent904fb8e452b4a95490357841291fa523ad1d6442 (diff)
PCI: tegra: Add Tegra186 PCIe support
Add Tegra186 PCIe support. UPHY programming is performed by BPMP; PHY enable calls are not required for Tegra186 PCIe. Power partition ungate is done by BPMP powergate driver. The Tegra186 DT description must include a "power-domains" property, which results in dev->pm_domain being set. Tested-by: Mikko Perttunen <mperttunen@nvidia.com> Tested-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> [bhelgaas: add "power-domains" reference] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> Acked-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/pci/host/pci-tegra.c134
1 files changed, 109 insertions, 25 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index e8e1ddbaabc9..8dd3b3f7d141 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -159,10 +159,13 @@
159#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) 159#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
160#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20) 160#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20)
161#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20) 161#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20)
162#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_401 (0x0 << 20)
162#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) 163#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
163#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20) 164#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20)
164#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20) 165#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20)
166#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211 (0x1 << 20)
165#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20) 167#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20)
168#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111 (0x2 << 20)
166 169
167#define AFI_FUSE 0x104 170#define AFI_FUSE 0x104
168#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2) 171#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
@@ -252,6 +255,7 @@ struct tegra_pcie_soc {
252 bool has_cml_clk; 255 bool has_cml_clk;
253 bool has_gen2; 256 bool has_gen2;
254 bool force_pca_enable; 257 bool force_pca_enable;
258 bool program_uphy;
255}; 259};
256 260
257static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip) 261static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
@@ -1032,10 +1036,12 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
1032 afi_writel(pcie, value, AFI_FUSE); 1036 afi_writel(pcie, value, AFI_FUSE);
1033 } 1037 }
1034 1038
1035 err = tegra_pcie_phy_power_on(pcie); 1039 if (soc->program_uphy) {
1036 if (err < 0) { 1040 err = tegra_pcie_phy_power_on(pcie);
1037 dev_err(dev, "failed to power on PHY(s): %d\n", err); 1041 if (err < 0) {
1038 return err; 1042 dev_err(dev, "failed to power on PHY(s): %d\n", err);
1043 return err;
1044 }
1039 } 1045 }
1040 1046
1041 /* take the PCIe interface module out of reset */ 1047 /* take the PCIe interface module out of reset */
@@ -1068,19 +1074,23 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
1068static void tegra_pcie_power_off(struct tegra_pcie *pcie) 1074static void tegra_pcie_power_off(struct tegra_pcie *pcie)
1069{ 1075{
1070 struct device *dev = pcie->dev; 1076 struct device *dev = pcie->dev;
1077 const struct tegra_pcie_soc *soc = pcie->soc;
1071 int err; 1078 int err;
1072 1079
1073 /* TODO: disable and unprepare clocks? */ 1080 /* TODO: disable and unprepare clocks? */
1074 1081
1075 err = tegra_pcie_phy_power_off(pcie); 1082 if (soc->program_uphy) {
1076 if (err < 0) 1083 err = tegra_pcie_phy_power_off(pcie);
1077 dev_err(dev, "failed to power off PHY(s): %d\n", err); 1084 if (err < 0)
1085 dev_err(dev, "failed to power off PHY(s): %d\n", err);
1086 }
1078 1087
1079 reset_control_assert(pcie->pcie_xrst); 1088 reset_control_assert(pcie->pcie_xrst);
1080 reset_control_assert(pcie->afi_rst); 1089 reset_control_assert(pcie->afi_rst);
1081 reset_control_assert(pcie->pex_rst); 1090 reset_control_assert(pcie->pex_rst);
1082 1091
1083 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 1092 if (!dev->pm_domain)
1093 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
1084 1094
1085 err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies); 1095 err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
1086 if (err < 0) 1096 if (err < 0)
@@ -1097,19 +1107,29 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
1097 reset_control_assert(pcie->afi_rst); 1107 reset_control_assert(pcie->afi_rst);
1098 reset_control_assert(pcie->pex_rst); 1108 reset_control_assert(pcie->pex_rst);
1099 1109
1100 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 1110 if (!dev->pm_domain)
1111 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
1101 1112
1102 /* enable regulators */ 1113 /* enable regulators */
1103 err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies); 1114 err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
1104 if (err < 0) 1115 if (err < 0)
1105 dev_err(dev, "failed to enable regulators: %d\n", err); 1116 dev_err(dev, "failed to enable regulators: %d\n", err);
1106 1117
1107 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, 1118 if (dev->pm_domain) {
1108 pcie->pex_clk, 1119 err = clk_prepare_enable(pcie->pex_clk);
1109 pcie->pex_rst); 1120 if (err) {
1110 if (err) { 1121 dev_err(dev, "failed to enable PEX clock: %d\n", err);
1111 dev_err(dev, "powerup sequence failed: %d\n", err); 1122 return err;
1112 return err; 1123 }
1124 reset_control_deassert(pcie->pex_rst);
1125 } else {
1126 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
1127 pcie->pex_clk,
1128 pcie->pex_rst);
1129 if (err) {
1130 dev_err(dev, "powerup sequence failed: %d\n", err);
1131 return err;
1132 }
1113 } 1133 }
1114 1134
1115 reset_control_deassert(pcie->afi_rst); 1135 reset_control_deassert(pcie->afi_rst);
@@ -1282,6 +1302,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
1282 struct device *dev = pcie->dev; 1302 struct device *dev = pcie->dev;
1283 struct platform_device *pdev = to_platform_device(dev); 1303 struct platform_device *pdev = to_platform_device(dev);
1284 struct resource *pads, *afi, *res; 1304 struct resource *pads, *afi, *res;
1305 const struct tegra_pcie_soc *soc = pcie->soc;
1285 int err; 1306 int err;
1286 1307
1287 err = tegra_pcie_clocks_get(pcie); 1308 err = tegra_pcie_clocks_get(pcie);
@@ -1296,10 +1317,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
1296 return err; 1317 return err;
1297 } 1318 }
1298 1319
1299 err = tegra_pcie_phys_get(pcie); 1320 if (soc->program_uphy) {
1300 if (err < 0) { 1321 err = tegra_pcie_phys_get(pcie);
1301 dev_err(dev, "failed to get PHYs: %d\n", err); 1322 if (err < 0) {
1302 return err; 1323 dev_err(dev, "failed to get PHYs: %d\n", err);
1324 return err;
1325 }
1303 } 1326 }
1304 1327
1305 err = tegra_pcie_power_on(pcie); 1328 err = tegra_pcie_power_on(pcie);
@@ -1361,6 +1384,7 @@ poweroff:
1361static int tegra_pcie_put_resources(struct tegra_pcie *pcie) 1384static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
1362{ 1385{
1363 struct device *dev = pcie->dev; 1386 struct device *dev = pcie->dev;
1387 const struct tegra_pcie_soc *soc = pcie->soc;
1364 int err; 1388 int err;
1365 1389
1366 if (pcie->irq > 0) 1390 if (pcie->irq > 0)
@@ -1368,9 +1392,11 @@ static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
1368 1392
1369 tegra_pcie_power_off(pcie); 1393 tegra_pcie_power_off(pcie);
1370 1394
1371 err = phy_exit(pcie->phy); 1395 if (soc->program_uphy) {
1372 if (err < 0) 1396 err = phy_exit(pcie->phy);
1373 dev_err(dev, "failed to teardown PHY: %d\n", err); 1397 if (err < 0)
1398 dev_err(dev, "failed to teardown PHY: %d\n", err);
1399 }
1374 1400
1375 return 0; 1401 return 0;
1376} 1402}
@@ -1636,8 +1662,32 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
1636 struct device *dev = pcie->dev; 1662 struct device *dev = pcie->dev;
1637 struct device_node *np = dev->of_node; 1663 struct device_node *np = dev->of_node;
1638 1664
1639 if (of_device_is_compatible(np, "nvidia,tegra124-pcie") || 1665 if (of_device_is_compatible(np, "nvidia,tegra186-pcie")) {
1640 of_device_is_compatible(np, "nvidia,tegra210-pcie")) { 1666 switch (lanes) {
1667 case 0x010004:
1668 dev_info(dev, "4x1, 1x1 configuration\n");
1669 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_401;
1670 return 0;
1671
1672 case 0x010102:
1673 dev_info(dev, "2x1, 1X1, 1x1 configuration\n");
1674 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211;
1675 return 0;
1676
1677 case 0x010101:
1678 dev_info(dev, "1x1, 1x1, 1x1 configuration\n");
1679 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111;
1680 return 0;
1681
1682 default:
1683 dev_info(dev, "wrong configuration updated in DT, "
1684 "switching to default 2x1, 1x1, 1x1 "
1685 "configuration\n");
1686 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211;
1687 return 0;
1688 }
1689 } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie") ||
1690 of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
1641 switch (lanes) { 1691 switch (lanes) {
1642 case 0x0000104: 1692 case 0x0000104:
1643 dev_info(dev, "4x1, 1x1 configuration\n"); 1693 dev_info(dev, "4x1, 1x1 configuration\n");
@@ -1757,7 +1807,20 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
1757 struct device_node *np = dev->of_node; 1807 struct device_node *np = dev->of_node;
1758 unsigned int i = 0; 1808 unsigned int i = 0;
1759 1809
1760 if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) { 1810 if (of_device_is_compatible(np, "nvidia,tegra186-pcie")) {
1811 pcie->num_supplies = 4;
1812
1813 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
1814 sizeof(*pcie->supplies),
1815 GFP_KERNEL);
1816 if (!pcie->supplies)
1817 return -ENOMEM;
1818
1819 pcie->supplies[i++].supply = "dvdd-pex";
1820 pcie->supplies[i++].supply = "hvdd-pex-pll";
1821 pcie->supplies[i++].supply = "hvdd-pex";
1822 pcie->supplies[i++].supply = "vddio-pexctl-aud";
1823 } else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
1761 pcie->num_supplies = 6; 1824 pcie->num_supplies = 6;
1762 1825
1763 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies, 1826 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
@@ -2096,6 +2159,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
2096 .has_cml_clk = false, 2159 .has_cml_clk = false,
2097 .has_gen2 = false, 2160 .has_gen2 = false,
2098 .force_pca_enable = false, 2161 .force_pca_enable = false,
2162 .program_uphy = true,
2099}; 2163};
2100 2164
2101static const struct tegra_pcie_soc tegra30_pcie = { 2165static const struct tegra_pcie_soc tegra30_pcie = {
@@ -2111,6 +2175,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
2111 .has_cml_clk = true, 2175 .has_cml_clk = true,
2112 .has_gen2 = false, 2176 .has_gen2 = false,
2113 .force_pca_enable = false, 2177 .force_pca_enable = false,
2178 .program_uphy = true,
2114}; 2179};
2115 2180
2116static const struct tegra_pcie_soc tegra124_pcie = { 2181static const struct tegra_pcie_soc tegra124_pcie = {
@@ -2125,6 +2190,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
2125 .has_cml_clk = true, 2190 .has_cml_clk = true,
2126 .has_gen2 = true, 2191 .has_gen2 = true,
2127 .force_pca_enable = false, 2192 .force_pca_enable = false,
2193 .program_uphy = true,
2128}; 2194};
2129 2195
2130static const struct tegra_pcie_soc tegra210_pcie = { 2196static const struct tegra_pcie_soc tegra210_pcie = {
@@ -2139,9 +2205,27 @@ static const struct tegra_pcie_soc tegra210_pcie = {
2139 .has_cml_clk = true, 2205 .has_cml_clk = true,
2140 .has_gen2 = true, 2206 .has_gen2 = true,
2141 .force_pca_enable = true, 2207 .force_pca_enable = true,
2208 .program_uphy = true,
2209};
2210
2211static const struct tegra_pcie_soc tegra186_pcie = {
2212 .num_ports = 3,
2213 .msi_base_shift = 8,
2214 .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
2215 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
2216 .pads_refclk_cfg0 = 0x80b880b8,
2217 .pads_refclk_cfg1 = 0x000480b8,
2218 .has_pex_clkreq_en = true,
2219 .has_pex_bias_ctrl = true,
2220 .has_intr_prsnt_sense = true,
2221 .has_cml_clk = false,
2222 .has_gen2 = true,
2223 .force_pca_enable = false,
2224 .program_uphy = false,
2142}; 2225};
2143 2226
2144static const struct of_device_id tegra_pcie_of_match[] = { 2227static const struct of_device_id tegra_pcie_of_match[] = {
2228 { .compatible = "nvidia,tegra186-pcie", .data = &tegra186_pcie },
2145 { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie }, 2229 { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
2146 { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie }, 2230 { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
2147 { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie }, 2231 { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },