diff options
author | Thierry Reding <treding@nvidia.com> | 2014-08-26 11:11:38 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-09-16 18:55:49 -0400 |
commit | 7f1f054b3fac0b19ec0d74e3e18b73785c26f0a8 (patch) | |
tree | 57fe5853eaa5f0e8763635a29f3c82a1dbbb9337 /drivers/pci/host/pci-tegra.c | |
parent | ec73276204f06b6446a9c9b70173a1c15f6de536 (diff) |
PCI: tegra: Add Tegra124 support
The PCIe controller on Tegra124 has two root ports that can be used in a
x4/x1 or x2/x1 configuration and can run at PCIe 2.0 link speeds (up to
5 GT/s). The PHY programming has been moved into a separate controller, so
the driver now needs to request an external PHY referenced using the device
tree.
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/host/pci-tegra.c')
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 211 |
1 files changed, 180 insertions, 31 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 79fd92c969a9..79a30476036c 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/of_pci.h> | 38 | #include <linux/of_pci.h> |
39 | #include <linux/of_platform.h> | 39 | #include <linux/of_platform.h> |
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/phy/phy.h> | ||
41 | #include <linux/platform_device.h> | 42 | #include <linux/platform_device.h> |
42 | #include <linux/reset.h> | 43 | #include <linux/reset.h> |
43 | #include <linux/sizes.h> | 44 | #include <linux/sizes.h> |
@@ -115,13 +116,20 @@ | |||
115 | 116 | ||
116 | #define AFI_INTR_CODE 0xb8 | 117 | #define AFI_INTR_CODE 0xb8 |
117 | #define AFI_INTR_CODE_MASK 0xf | 118 | #define AFI_INTR_CODE_MASK 0xf |
118 | #define AFI_INTR_AXI_SLAVE_ERROR 1 | 119 | #define AFI_INTR_INI_SLAVE_ERROR 1 |
119 | #define AFI_INTR_AXI_DECODE_ERROR 2 | 120 | #define AFI_INTR_INI_DECODE_ERROR 2 |
120 | #define AFI_INTR_TARGET_ABORT 3 | 121 | #define AFI_INTR_TARGET_ABORT 3 |
121 | #define AFI_INTR_MASTER_ABORT 4 | 122 | #define AFI_INTR_MASTER_ABORT 4 |
122 | #define AFI_INTR_INVALID_WRITE 5 | 123 | #define AFI_INTR_INVALID_WRITE 5 |
123 | #define AFI_INTR_LEGACY 6 | 124 | #define AFI_INTR_LEGACY 6 |
124 | #define AFI_INTR_FPCI_DECODE_ERROR 7 | 125 | #define AFI_INTR_FPCI_DECODE_ERROR 7 |
126 | #define AFI_INTR_AXI_DECODE_ERROR 8 | ||
127 | #define AFI_INTR_FPCI_TIMEOUT 9 | ||
128 | #define AFI_INTR_PE_PRSNT_SENSE 10 | ||
129 | #define AFI_INTR_PE_CLKREQ_SENSE 11 | ||
130 | #define AFI_INTR_CLKCLAMP_SENSE 12 | ||
131 | #define AFI_INTR_RDY4PD_SENSE 13 | ||
132 | #define AFI_INTR_P2P_ERROR 14 | ||
125 | 133 | ||
126 | #define AFI_INTR_SIGNATURE 0xbc | 134 | #define AFI_INTR_SIGNATURE 0xbc |
127 | #define AFI_UPPER_FPCI_ADDRESS 0xc0 | 135 | #define AFI_UPPER_FPCI_ADDRESS 0xc0 |
@@ -152,8 +160,10 @@ | |||
152 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20) | 160 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20) |
153 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) | 161 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) |
154 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20) | 162 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20) |
163 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20) | ||
155 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) | 164 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) |
156 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20) | 165 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20) |
166 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20) | ||
157 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20) | 167 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20) |
158 | 168 | ||
159 | #define AFI_FUSE 0x104 | 169 | #define AFI_FUSE 0x104 |
@@ -165,12 +175,21 @@ | |||
165 | #define AFI_PEX_CTRL_RST (1 << 0) | 175 | #define AFI_PEX_CTRL_RST (1 << 0) |
166 | #define AFI_PEX_CTRL_CLKREQ_EN (1 << 1) | 176 | #define AFI_PEX_CTRL_CLKREQ_EN (1 << 1) |
167 | #define AFI_PEX_CTRL_REFCLK_EN (1 << 3) | 177 | #define AFI_PEX_CTRL_REFCLK_EN (1 << 3) |
178 | #define AFI_PEX_CTRL_OVERRIDE_EN (1 << 4) | ||
179 | |||
180 | #define AFI_PLLE_CONTROL 0x160 | ||
181 | #define AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL (1 << 9) | ||
182 | #define AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN (1 << 1) | ||
168 | 183 | ||
169 | #define AFI_PEXBIAS_CTRL_0 0x168 | 184 | #define AFI_PEXBIAS_CTRL_0 0x168 |
170 | 185 | ||
171 | #define RP_VEND_XP 0x00000F00 | 186 | #define RP_VEND_XP 0x00000F00 |
172 | #define RP_VEND_XP_DL_UP (1 << 30) | 187 | #define RP_VEND_XP_DL_UP (1 << 30) |
173 | 188 | ||
189 | #define RP_PRIV_MISC 0x00000FE0 | ||
190 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0) | ||
191 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0) | ||
192 | |||
174 | #define RP_LINK_CONTROL_STATUS 0x00000090 | 193 | #define RP_LINK_CONTROL_STATUS 0x00000090 |
175 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 | 194 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 |
176 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 | 195 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 |
@@ -197,6 +216,7 @@ | |||
197 | 216 | ||
198 | #define PADS_REFCLK_CFG0 0x000000C8 | 217 | #define PADS_REFCLK_CFG0 0x000000C8 |
199 | #define PADS_REFCLK_CFG1 0x000000CC | 218 | #define PADS_REFCLK_CFG1 0x000000CC |
219 | #define PADS_REFCLK_BIAS 0x000000D0 | ||
200 | 220 | ||
201 | /* | 221 | /* |
202 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit | 222 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit |
@@ -236,6 +256,7 @@ struct tegra_pcie_soc_data { | |||
236 | bool has_pex_bias_ctrl; | 256 | bool has_pex_bias_ctrl; |
237 | bool has_intr_prsnt_sense; | 257 | bool has_intr_prsnt_sense; |
238 | bool has_cml_clk; | 258 | bool has_cml_clk; |
259 | bool has_gen2; | ||
239 | }; | 260 | }; |
240 | 261 | ||
241 | static inline struct tegra_msi *to_tegra_msi(struct msi_chip *chip) | 262 | static inline struct tegra_msi *to_tegra_msi(struct msi_chip *chip) |
@@ -268,6 +289,8 @@ struct tegra_pcie { | |||
268 | struct reset_control *afi_rst; | 289 | struct reset_control *afi_rst; |
269 | struct reset_control *pcie_xrst; | 290 | struct reset_control *pcie_xrst; |
270 | 291 | ||
292 | struct phy *phy; | ||
293 | |||
271 | struct tegra_msi msi; | 294 | struct tegra_msi msi; |
272 | 295 | ||
273 | struct list_head ports; | 296 | struct list_head ports; |
@@ -562,6 +585,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) | |||
562 | if (soc->has_pex_clkreq_en) | 585 | if (soc->has_pex_clkreq_en) |
563 | value |= AFI_PEX_CTRL_CLKREQ_EN; | 586 | value |= AFI_PEX_CTRL_CLKREQ_EN; |
564 | 587 | ||
588 | value |= AFI_PEX_CTRL_OVERRIDE_EN; | ||
589 | |||
565 | afi_writel(port->pcie, value, ctrl); | 590 | afi_writel(port->pcie, value, ctrl); |
566 | 591 | ||
567 | tegra_pcie_port_reset(port); | 592 | tegra_pcie_port_reset(port); |
@@ -699,9 +724,15 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
699 | "Target abort", | 724 | "Target abort", |
700 | "Master abort", | 725 | "Master abort", |
701 | "Invalid write", | 726 | "Invalid write", |
727 | "Legacy interrupt", | ||
702 | "Response decoding error", | 728 | "Response decoding error", |
703 | "AXI response decoding error", | 729 | "AXI response decoding error", |
704 | "Transaction timeout", | 730 | "Transaction timeout", |
731 | "Slot present pin change", | ||
732 | "Slot clock request change", | ||
733 | "TMS clock ramp change", | ||
734 | "TMS ready for power down", | ||
735 | "Peer2Peer error", | ||
705 | }; | 736 | }; |
706 | struct tegra_pcie *pcie = arg; | 737 | struct tegra_pcie *pcie = arg; |
707 | u32 code, signature; | 738 | u32 code, signature; |
@@ -807,30 +838,27 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
807 | afi_writel(pcie, 0, AFI_MSI_BAR_SZ); | 838 | afi_writel(pcie, 0, AFI_MSI_BAR_SZ); |
808 | } | 839 | } |
809 | 840 | ||
810 | static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | 841 | static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout) |
811 | { | 842 | { |
812 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | 843 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; |
813 | struct tegra_pcie_port *port; | 844 | u32 value; |
814 | unsigned int timeout; | ||
815 | unsigned long value; | ||
816 | 845 | ||
817 | /* power down PCIe slot clock bias pad */ | 846 | timeout = jiffies + msecs_to_jiffies(timeout); |
818 | if (soc->has_pex_bias_ctrl) | ||
819 | afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0); | ||
820 | 847 | ||
821 | /* configure mode and disable all ports */ | 848 | while (time_before(jiffies, timeout)) { |
822 | value = afi_readl(pcie, AFI_PCIE_CONFIG); | 849 | value = pads_readl(pcie, soc->pads_pll_ctl); |
823 | value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK; | 850 | if (value & PADS_PLL_CTL_LOCKDET) |
824 | value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config; | 851 | return 0; |
825 | 852 | } | |
826 | list_for_each_entry(port, &pcie->ports, list) | ||
827 | value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index); | ||
828 | 853 | ||
829 | afi_writel(pcie, value, AFI_PCIE_CONFIG); | 854 | return -ETIMEDOUT; |
855 | } | ||
830 | 856 | ||
831 | value = afi_readl(pcie, AFI_FUSE); | 857 | static int tegra_pcie_phy_enable(struct tegra_pcie *pcie) |
832 | value |= AFI_FUSE_PCIE_T0_GEN2_DIS; | 858 | { |
833 | afi_writel(pcie, value, AFI_FUSE); | 859 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; |
860 | u32 value; | ||
861 | int err; | ||
834 | 862 | ||
835 | /* initialize internal PHY, enable up to 16 PCIE lanes */ | 863 | /* initialize internal PHY, enable up to 16 PCIE lanes */ |
836 | pads_writel(pcie, 0x0, PADS_CTL_SEL); | 864 | pads_writel(pcie, 0x0, PADS_CTL_SEL); |
@@ -868,15 +896,11 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
868 | pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); | 896 | pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); |
869 | 897 | ||
870 | /* wait for the PLL to lock */ | 898 | /* wait for the PLL to lock */ |
871 | timeout = 300; | 899 | err = tegra_pcie_pll_wait(pcie, 500); |
872 | do { | 900 | if (err < 0) { |
873 | value = pads_readl(pcie, soc->pads_pll_ctl); | 901 | dev_err(pcie->dev, "PLL failed to lock: %d\n", err); |
874 | usleep_range(1000, 2000); | 902 | return err; |
875 | if (--timeout == 0) { | 903 | } |
876 | pr_err("Tegra PCIe error: timeout waiting for PLL\n"); | ||
877 | return -EBUSY; | ||
878 | } | ||
879 | } while (!(value & PADS_PLL_CTL_LOCKDET)); | ||
880 | 904 | ||
881 | /* turn off IDDQ override */ | 905 | /* turn off IDDQ override */ |
882 | value = pads_readl(pcie, PADS_CTL); | 906 | value = pads_readl(pcie, PADS_CTL); |
@@ -888,6 +912,58 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
888 | value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L; | 912 | value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L; |
889 | pads_writel(pcie, value, PADS_CTL); | 913 | pads_writel(pcie, value, PADS_CTL); |
890 | 914 | ||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | ||
919 | { | ||
920 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | ||
921 | struct tegra_pcie_port *port; | ||
922 | unsigned long value; | ||
923 | int err; | ||
924 | |||
925 | /* enable PLL power down */ | ||
926 | if (pcie->phy) { | ||
927 | value = afi_readl(pcie, AFI_PLLE_CONTROL); | ||
928 | value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL; | ||
929 | value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN; | ||
930 | afi_writel(pcie, value, AFI_PLLE_CONTROL); | ||
931 | } | ||
932 | |||
933 | /* power down PCIe slot clock bias pad */ | ||
934 | if (soc->has_pex_bias_ctrl) | ||
935 | afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0); | ||
936 | |||
937 | /* configure mode and disable all ports */ | ||
938 | value = afi_readl(pcie, AFI_PCIE_CONFIG); | ||
939 | value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK; | ||
940 | value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config; | ||
941 | |||
942 | list_for_each_entry(port, &pcie->ports, list) | ||
943 | value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index); | ||
944 | |||
945 | afi_writel(pcie, value, AFI_PCIE_CONFIG); | ||
946 | |||
947 | if (soc->has_gen2) { | ||
948 | value = afi_readl(pcie, AFI_FUSE); | ||
949 | value &= ~AFI_FUSE_PCIE_T0_GEN2_DIS; | ||
950 | afi_writel(pcie, value, AFI_FUSE); | ||
951 | } else { | ||
952 | value = afi_readl(pcie, AFI_FUSE); | ||
953 | value |= AFI_FUSE_PCIE_T0_GEN2_DIS; | ||
954 | afi_writel(pcie, value, AFI_FUSE); | ||
955 | } | ||
956 | |||
957 | if (!pcie->phy) | ||
958 | err = tegra_pcie_phy_enable(pcie); | ||
959 | else | ||
960 | err = phy_power_on(pcie->phy); | ||
961 | |||
962 | if (err < 0) { | ||
963 | dev_err(pcie->dev, "failed to power on PHY: %d\n", err); | ||
964 | return err; | ||
965 | } | ||
966 | |||
891 | /* take the PCIe interface module out of reset */ | 967 | /* take the PCIe interface module out of reset */ |
892 | reset_control_deassert(pcie->pcie_xrst); | 968 | reset_control_deassert(pcie->pcie_xrst); |
893 | 969 | ||
@@ -921,6 +997,10 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) | |||
921 | 997 | ||
922 | /* TODO: disable and unprepare clocks? */ | 998 | /* TODO: disable and unprepare clocks? */ |
923 | 999 | ||
1000 | err = phy_power_off(pcie->phy); | ||
1001 | if (err < 0) | ||
1002 | dev_warn(pcie->dev, "failed to power off PHY: %d\n", err); | ||
1003 | |||
924 | reset_control_assert(pcie->pcie_xrst); | 1004 | reset_control_assert(pcie->pcie_xrst); |
925 | reset_control_assert(pcie->afi_rst); | 1005 | reset_control_assert(pcie->afi_rst); |
926 | reset_control_assert(pcie->pex_rst); | 1006 | reset_control_assert(pcie->pex_rst); |
@@ -1042,6 +1122,19 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) | |||
1042 | return err; | 1122 | return err; |
1043 | } | 1123 | } |
1044 | 1124 | ||
1125 | pcie->phy = devm_phy_optional_get(pcie->dev, "pcie"); | ||
1126 | if (IS_ERR(pcie->phy)) { | ||
1127 | err = PTR_ERR(pcie->phy); | ||
1128 | dev_err(&pdev->dev, "failed to get PHY: %d\n", err); | ||
1129 | return err; | ||
1130 | } | ||
1131 | |||
1132 | err = phy_init(pcie->phy); | ||
1133 | if (err < 0) { | ||
1134 | dev_err(&pdev->dev, "failed to initialize PHY: %d\n", err); | ||
1135 | return err; | ||
1136 | } | ||
1137 | |||
1045 | err = tegra_pcie_power_on(pcie); | 1138 | err = tegra_pcie_power_on(pcie); |
1046 | if (err) { | 1139 | if (err) { |
1047 | dev_err(&pdev->dev, "failed to power up: %d\n", err); | 1140 | dev_err(&pdev->dev, "failed to power up: %d\n", err); |
@@ -1100,10 +1193,17 @@ poweroff: | |||
1100 | 1193 | ||
1101 | static int tegra_pcie_put_resources(struct tegra_pcie *pcie) | 1194 | static int tegra_pcie_put_resources(struct tegra_pcie *pcie) |
1102 | { | 1195 | { |
1196 | int err; | ||
1197 | |||
1103 | if (pcie->irq > 0) | 1198 | if (pcie->irq > 0) |
1104 | free_irq(pcie->irq, pcie); | 1199 | free_irq(pcie->irq, pcie); |
1105 | 1200 | ||
1106 | tegra_pcie_power_off(pcie); | 1201 | tegra_pcie_power_off(pcie); |
1202 | |||
1203 | err = phy_exit(pcie->phy); | ||
1204 | if (err < 0) | ||
1205 | dev_err(pcie->dev, "failed to teardown PHY: %d\n", err); | ||
1206 | |||
1107 | return 0; | 1207 | return 0; |
1108 | } | 1208 | } |
1109 | 1209 | ||
@@ -1353,7 +1453,19 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, | |||
1353 | { | 1453 | { |
1354 | struct device_node *np = pcie->dev->of_node; | 1454 | struct device_node *np = pcie->dev->of_node; |
1355 | 1455 | ||
1356 | if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | 1456 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { |
1457 | switch (lanes) { | ||
1458 | case 0x0000104: | ||
1459 | dev_info(pcie->dev, "4x1, 1x1 configuration\n"); | ||
1460 | *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1; | ||
1461 | return 0; | ||
1462 | |||
1463 | case 0x0000102: | ||
1464 | dev_info(pcie->dev, "2x1, 1x1 configuration\n"); | ||
1465 | *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1; | ||
1466 | return 0; | ||
1467 | } | ||
1468 | } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | ||
1357 | switch (lanes) { | 1469 | switch (lanes) { |
1358 | case 0x00000204: | 1470 | case 0x00000204: |
1359 | dev_info(pcie->dev, "4x1, 2x1 configuration\n"); | 1471 | dev_info(pcie->dev, "4x1, 2x1 configuration\n"); |
@@ -1461,7 +1573,23 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask) | |||
1461 | struct device_node *np = pcie->dev->of_node; | 1573 | struct device_node *np = pcie->dev->of_node; |
1462 | unsigned int i = 0; | 1574 | unsigned int i = 0; |
1463 | 1575 | ||
1464 | if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | 1576 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { |
1577 | pcie->num_supplies = 7; | ||
1578 | |||
1579 | pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies, | ||
1580 | sizeof(*pcie->supplies), | ||
1581 | GFP_KERNEL); | ||
1582 | if (!pcie->supplies) | ||
1583 | return -ENOMEM; | ||
1584 | |||
1585 | pcie->supplies[i++].supply = "avddio-pex"; | ||
1586 | pcie->supplies[i++].supply = "dvddio-pex"; | ||
1587 | pcie->supplies[i++].supply = "avdd-pex-pll"; | ||
1588 | pcie->supplies[i++].supply = "hvdd-pex"; | ||
1589 | pcie->supplies[i++].supply = "hvdd-pex-pll-e"; | ||
1590 | pcie->supplies[i++].supply = "vddio-pex-ctl"; | ||
1591 | pcie->supplies[i++].supply = "avdd-pll-erefe"; | ||
1592 | } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | ||
1465 | bool need_pexa = false, need_pexb = false; | 1593 | bool need_pexa = false, need_pexb = false; |
1466 | 1594 | ||
1467 | /* VDD_PEXA and AVDD_PEXA supply lanes 0 to 3 */ | 1595 | /* VDD_PEXA and AVDD_PEXA supply lanes 0 to 3 */ |
@@ -1683,6 +1811,12 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port) | |||
1683 | unsigned int retries = 3; | 1811 | unsigned int retries = 3; |
1684 | unsigned long value; | 1812 | unsigned long value; |
1685 | 1813 | ||
1814 | /* override presence detection */ | ||
1815 | value = readl(port->base + RP_PRIV_MISC); | ||
1816 | value &= ~RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT; | ||
1817 | value |= RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT; | ||
1818 | writel(value, port->base + RP_PRIV_MISC); | ||
1819 | |||
1686 | do { | 1820 | do { |
1687 | unsigned int timeout = TEGRA_PCIE_LINKUP_TIMEOUT; | 1821 | unsigned int timeout = TEGRA_PCIE_LINKUP_TIMEOUT; |
1688 | 1822 | ||
@@ -1763,6 +1897,7 @@ static const struct tegra_pcie_soc_data tegra20_pcie_data = { | |||
1763 | .has_pex_bias_ctrl = false, | 1897 | .has_pex_bias_ctrl = false, |
1764 | .has_intr_prsnt_sense = false, | 1898 | .has_intr_prsnt_sense = false, |
1765 | .has_cml_clk = false, | 1899 | .has_cml_clk = false, |
1900 | .has_gen2 = false, | ||
1766 | }; | 1901 | }; |
1767 | 1902 | ||
1768 | static const struct tegra_pcie_soc_data tegra30_pcie_data = { | 1903 | static const struct tegra_pcie_soc_data tegra30_pcie_data = { |
@@ -1774,9 +1909,23 @@ static const struct tegra_pcie_soc_data tegra30_pcie_data = { | |||
1774 | .has_pex_bias_ctrl = true, | 1909 | .has_pex_bias_ctrl = true, |
1775 | .has_intr_prsnt_sense = true, | 1910 | .has_intr_prsnt_sense = true, |
1776 | .has_cml_clk = true, | 1911 | .has_cml_clk = true, |
1912 | .has_gen2 = false, | ||
1913 | }; | ||
1914 | |||
1915 | static const struct tegra_pcie_soc_data tegra124_pcie_data = { | ||
1916 | .num_ports = 2, | ||
1917 | .msi_base_shift = 8, | ||
1918 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | ||
1919 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | ||
1920 | .has_pex_clkreq_en = true, | ||
1921 | .has_pex_bias_ctrl = true, | ||
1922 | .has_intr_prsnt_sense = true, | ||
1923 | .has_cml_clk = true, | ||
1924 | .has_gen2 = true, | ||
1777 | }; | 1925 | }; |
1778 | 1926 | ||
1779 | static const struct of_device_id tegra_pcie_of_match[] = { | 1927 | static const struct of_device_id tegra_pcie_of_match[] = { |
1928 | { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie_data }, | ||
1780 | { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data }, | 1929 | { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data }, |
1781 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, | 1930 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, |
1782 | { }, | 1931 | { }, |