aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-11-14 13:11:35 -0500
committerBjorn Helgaas <bhelgaas@google.com>2017-11-14 13:11:35 -0500
commitd238be6957b2e57913f602fc4429813ca6027e93 (patch)
tree534e0557a95e05add9dbb12fe33b066b5238483e /drivers
parent2b61a44e115e346dcf248b4b35ae2aafed99bb78 (diff)
parent9cea513d8cbc75ee26327d3d8971fe7b58288d8f (diff)
Merge branch 'pci/host-tegra' into next
* pci/host-tegra: PCI: tegra: Add Tegra186 PCIe support dt-bindings: pci: tegra: Document Tegra186 PCIe DT PCI: tegra: Use generic accessors where possible
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/host/pci-tegra.c158
1 files changed, 131 insertions, 27 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 9c40da54f88a..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)
@@ -491,12 +495,32 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
491 return addr; 495 return addr;
492} 496}
493 497
498static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
499 int where, int size, u32 *value)
500{
501 if (bus->number == 0)
502 return pci_generic_config_read32(bus, devfn, where, size,
503 value);
504
505 return pci_generic_config_read(bus, devfn, where, size, value);
506}
507
508static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
509 int where, int size, u32 value)
510{
511 if (bus->number == 0)
512 return pci_generic_config_write32(bus, devfn, where, size,
513 value);
514
515 return pci_generic_config_write(bus, devfn, where, size, value);
516}
517
494static struct pci_ops tegra_pcie_ops = { 518static struct pci_ops tegra_pcie_ops = {
495 .add_bus = tegra_pcie_add_bus, 519 .add_bus = tegra_pcie_add_bus,
496 .remove_bus = tegra_pcie_remove_bus, 520 .remove_bus = tegra_pcie_remove_bus,
497 .map_bus = tegra_pcie_map_bus, 521 .map_bus = tegra_pcie_map_bus,
498 .read = pci_generic_config_read32, 522 .read = tegra_pcie_config_read,
499 .write = pci_generic_config_write32, 523 .write = tegra_pcie_config_write,
500}; 524};
501 525
502static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) 526static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
@@ -1012,10 +1036,12 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
1012 afi_writel(pcie, value, AFI_FUSE); 1036 afi_writel(pcie, value, AFI_FUSE);
1013 } 1037 }
1014 1038
1015 err = tegra_pcie_phy_power_on(pcie); 1039 if (soc->program_uphy) {
1016 if (err < 0) { 1040 err = tegra_pcie_phy_power_on(pcie);
1017 dev_err(dev, "failed to power on PHY(s): %d\n", err); 1041 if (err < 0) {
1018 return err; 1042 dev_err(dev, "failed to power on PHY(s): %d\n", err);
1043 return err;
1044 }
1019 } 1045 }
1020 1046
1021 /* take the PCIe interface module out of reset */ 1047 /* take the PCIe interface module out of reset */
@@ -1048,19 +1074,23 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
1048static void tegra_pcie_power_off(struct tegra_pcie *pcie) 1074static void tegra_pcie_power_off(struct tegra_pcie *pcie)
1049{ 1075{
1050 struct device *dev = pcie->dev; 1076 struct device *dev = pcie->dev;
1077 const struct tegra_pcie_soc *soc = pcie->soc;
1051 int err; 1078 int err;
1052 1079
1053 /* TODO: disable and unprepare clocks? */ 1080 /* TODO: disable and unprepare clocks? */
1054 1081
1055 err = tegra_pcie_phy_power_off(pcie); 1082 if (soc->program_uphy) {
1056 if (err < 0) 1083 err = tegra_pcie_phy_power_off(pcie);
1057 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 }
1058 1087
1059 reset_control_assert(pcie->pcie_xrst); 1088 reset_control_assert(pcie->pcie_xrst);
1060 reset_control_assert(pcie->afi_rst); 1089 reset_control_assert(pcie->afi_rst);
1061 reset_control_assert(pcie->pex_rst); 1090 reset_control_assert(pcie->pex_rst);
1062 1091
1063 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 1092 if (!dev->pm_domain)
1093 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
1064 1094
1065 err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies); 1095 err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
1066 if (err < 0) 1096 if (err < 0)
@@ -1077,19 +1107,29 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
1077 reset_control_assert(pcie->afi_rst); 1107 reset_control_assert(pcie->afi_rst);
1078 reset_control_assert(pcie->pex_rst); 1108 reset_control_assert(pcie->pex_rst);
1079 1109
1080 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 1110 if (!dev->pm_domain)
1111 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
1081 1112
1082 /* enable regulators */ 1113 /* enable regulators */
1083 err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies); 1114 err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
1084 if (err < 0) 1115 if (err < 0)
1085 dev_err(dev, "failed to enable regulators: %d\n", err); 1116 dev_err(dev, "failed to enable regulators: %d\n", err);
1086 1117
1087 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, 1118 if (dev->pm_domain) {
1088 pcie->pex_clk, 1119 err = clk_prepare_enable(pcie->pex_clk);
1089 pcie->pex_rst); 1120 if (err) {
1090 if (err) { 1121 dev_err(dev, "failed to enable PEX clock: %d\n", err);
1091 dev_err(dev, "powerup sequence failed: %d\n", err); 1122 return err;
1092 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 }
1093 } 1133 }
1094 1134
1095 reset_control_deassert(pcie->afi_rst); 1135 reset_control_deassert(pcie->afi_rst);
@@ -1262,6 +1302,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
1262 struct device *dev = pcie->dev; 1302 struct device *dev = pcie->dev;
1263 struct platform_device *pdev = to_platform_device(dev); 1303 struct platform_device *pdev = to_platform_device(dev);
1264 struct resource *pads, *afi, *res; 1304 struct resource *pads, *afi, *res;
1305 const struct tegra_pcie_soc *soc = pcie->soc;
1265 int err; 1306 int err;
1266 1307
1267 err = tegra_pcie_clocks_get(pcie); 1308 err = tegra_pcie_clocks_get(pcie);
@@ -1276,10 +1317,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
1276 return err; 1317 return err;
1277 } 1318 }
1278 1319
1279 err = tegra_pcie_phys_get(pcie); 1320 if (soc->program_uphy) {
1280 if (err < 0) { 1321 err = tegra_pcie_phys_get(pcie);
1281 dev_err(dev, "failed to get PHYs: %d\n", err); 1322 if (err < 0) {
1282 return err; 1323 dev_err(dev, "failed to get PHYs: %d\n", err);
1324 return err;
1325 }
1283 } 1326 }
1284 1327
1285 err = tegra_pcie_power_on(pcie); 1328 err = tegra_pcie_power_on(pcie);
@@ -1341,6 +1384,7 @@ poweroff:
1341static int tegra_pcie_put_resources(struct tegra_pcie *pcie) 1384static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
1342{ 1385{
1343 struct device *dev = pcie->dev; 1386 struct device *dev = pcie->dev;
1387 const struct tegra_pcie_soc *soc = pcie->soc;
1344 int err; 1388 int err;
1345 1389
1346 if (pcie->irq > 0) 1390 if (pcie->irq > 0)
@@ -1348,9 +1392,11 @@ static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
1348 1392
1349 tegra_pcie_power_off(pcie); 1393 tegra_pcie_power_off(pcie);
1350 1394
1351 err = phy_exit(pcie->phy); 1395 if (soc->program_uphy) {
1352 if (err < 0) 1396 err = phy_exit(pcie->phy);
1353 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 }
1354 1400
1355 return 0; 1401 return 0;
1356} 1402}
@@ -1616,8 +1662,32 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
1616 struct device *dev = pcie->dev; 1662 struct device *dev = pcie->dev;
1617 struct device_node *np = dev->of_node; 1663 struct device_node *np = dev->of_node;
1618 1664
1619 if (of_device_is_compatible(np, "nvidia,tegra124-pcie") || 1665 if (of_device_is_compatible(np, "nvidia,tegra186-pcie")) {
1620 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")) {
1621 switch (lanes) { 1691 switch (lanes) {
1622 case 0x0000104: 1692 case 0x0000104:
1623 dev_info(dev, "4x1, 1x1 configuration\n"); 1693 dev_info(dev, "4x1, 1x1 configuration\n");
@@ -1737,7 +1807,20 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
1737 struct device_node *np = dev->of_node; 1807 struct device_node *np = dev->of_node;
1738 unsigned int i = 0; 1808 unsigned int i = 0;
1739 1809
1740 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")) {
1741 pcie->num_supplies = 6; 1824 pcie->num_supplies = 6;
1742 1825
1743 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies, 1826 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
@@ -2076,6 +2159,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
2076 .has_cml_clk = false, 2159 .has_cml_clk = false,
2077 .has_gen2 = false, 2160 .has_gen2 = false,
2078 .force_pca_enable = false, 2161 .force_pca_enable = false,
2162 .program_uphy = true,
2079}; 2163};
2080 2164
2081static const struct tegra_pcie_soc tegra30_pcie = { 2165static const struct tegra_pcie_soc tegra30_pcie = {
@@ -2091,6 +2175,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
2091 .has_cml_clk = true, 2175 .has_cml_clk = true,
2092 .has_gen2 = false, 2176 .has_gen2 = false,
2093 .force_pca_enable = false, 2177 .force_pca_enable = false,
2178 .program_uphy = true,
2094}; 2179};
2095 2180
2096static const struct tegra_pcie_soc tegra124_pcie = { 2181static const struct tegra_pcie_soc tegra124_pcie = {
@@ -2105,6 +2190,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
2105 .has_cml_clk = true, 2190 .has_cml_clk = true,
2106 .has_gen2 = true, 2191 .has_gen2 = true,
2107 .force_pca_enable = false, 2192 .force_pca_enable = false,
2193 .program_uphy = true,
2108}; 2194};
2109 2195
2110static const struct tegra_pcie_soc tegra210_pcie = { 2196static const struct tegra_pcie_soc tegra210_pcie = {
@@ -2119,9 +2205,27 @@ static const struct tegra_pcie_soc tegra210_pcie = {
2119 .has_cml_clk = true, 2205 .has_cml_clk = true,
2120 .has_gen2 = true, 2206 .has_gen2 = true,
2121 .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,
2122}; 2225};
2123 2226
2124static 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 },
2125 { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie }, 2229 { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
2126 { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie }, 2230 { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
2127 { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie }, 2231 { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },