diff options
author | Arnd Bergmann <arnd@arndb.de> | 2016-05-09 10:20:35 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2016-05-09 10:20:35 -0400 |
commit | 675de1d5145bc5e6ef436f2eac00a08516e38e62 (patch) | |
tree | 1a1ca3dff589ec362c6c10b6e4a50ebb3b8fd4a9 | |
parent | 4ace926172a7d93182381a3c7a2d05acb2dd91a4 (diff) | |
parent | 6fe7c187e026c8b610df9dda7d9befc70cbfd169 (diff) |
Merge tag 'tegra-for-4.7-pci' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers
Merge "PCI: tegra: Changes for v4.7-rc1" from Thierry Reding:
These patches update the Tegra PCIe host bridge controller device tree
bindings and driver to cope with per-lane PHYs on Tegra124 and later.
* tag 'tegra-for-4.7-pci' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
PCI: tegra: Support per-lane PHYs
dt-bindings: pci: tegra: Update for per-lane PHYs
-rw-r--r-- | Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 224 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 244 |
2 files changed, 446 insertions, 22 deletions
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt index 75321ae23c08..b8cc395fffea 100644 --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | |||
@@ -60,11 +60,14 @@ Required properties: | |||
60 | - afi | 60 | - afi |
61 | - pcie_x | 61 | - pcie_x |
62 | 62 | ||
63 | Required properties on Tegra124 and later: | 63 | Required properties on Tegra124 and later (deprecated): |
64 | - phys: Must contain an entry for each entry in phy-names. | 64 | - phys: Must contain an entry for each entry in phy-names. |
65 | - phy-names: Must include the following entries: | 65 | - phy-names: Must include the following entries: |
66 | - pcie | 66 | - pcie |
67 | 67 | ||
68 | These properties are deprecated in favour of per-lane PHYs define in each of | ||
69 | the root ports (see below). | ||
70 | |||
68 | Power supplies for Tegra20: | 71 | Power supplies for Tegra20: |
69 | - avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V. | 72 | - avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V. |
70 | - vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. | 73 | - vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. |
@@ -122,11 +125,22 @@ Required properties: | |||
122 | - Root port 0 uses 4 lanes, root port 1 is unused. | 125 | - Root port 0 uses 4 lanes, root port 1 is unused. |
123 | - Both root ports use 2 lanes. | 126 | - Both root ports use 2 lanes. |
124 | 127 | ||
125 | Example: | 128 | Required properties for Tegra124 and later: |
129 | - phys: Must contain an phandle to a PHY for each entry in phy-names. | ||
130 | - phy-names: Must include an entry for each active lane. Note that the number | ||
131 | of entries does not have to (though usually will) be equal to the specified | ||
132 | number of lanes in the nvidia,num-lanes property. Entries are of the form | ||
133 | "pcie-N": where N ranges from 0 to the value specified in nvidia,num-lanes. | ||
134 | |||
135 | Examples: | ||
136 | ========= | ||
137 | |||
138 | Tegra20: | ||
139 | -------- | ||
126 | 140 | ||
127 | SoC DTSI: | 141 | SoC DTSI: |
128 | 142 | ||
129 | pcie-controller { | 143 | pcie-controller@80003000 { |
130 | compatible = "nvidia,tegra20-pcie"; | 144 | compatible = "nvidia,tegra20-pcie"; |
131 | device_type = "pci"; | 145 | device_type = "pci"; |
132 | reg = <0x80003000 0x00000800 /* PADS registers */ | 146 | reg = <0x80003000 0x00000800 /* PADS registers */ |
@@ -186,10 +200,9 @@ SoC DTSI: | |||
186 | }; | 200 | }; |
187 | }; | 201 | }; |
188 | 202 | ||
189 | |||
190 | Board DTS: | 203 | Board DTS: |
191 | 204 | ||
192 | pcie-controller { | 205 | pcie-controller@80003000 { |
193 | status = "okay"; | 206 | status = "okay"; |
194 | 207 | ||
195 | vdd-supply = <&pci_vdd_reg>; | 208 | vdd-supply = <&pci_vdd_reg>; |
@@ -222,3 +235,204 @@ if a device on the PCI bus provides a non-probeable bus such as I2C or SPI, | |||
222 | device nodes need to be added in order to allow the bus' children to be | 235 | device nodes need to be added in order to allow the bus' children to be |
223 | instantiated at the proper location in the operating system's device tree (as | 236 | instantiated at the proper location in the operating system's device tree (as |
224 | illustrated by the optional nodes in the example above). | 237 | illustrated by the optional nodes in the example above). |
238 | |||
239 | Tegra30: | ||
240 | -------- | ||
241 | |||
242 | SoC DTSI: | ||
243 | |||
244 | pcie-controller@00003000 { | ||
245 | compatible = "nvidia,tegra30-pcie"; | ||
246 | device_type = "pci"; | ||
247 | reg = <0x00003000 0x00000800 /* PADS registers */ | ||
248 | 0x00003800 0x00000200 /* AFI registers */ | ||
249 | 0x10000000 0x10000000>; /* configuration space */ | ||
250 | reg-names = "pads", "afi", "cs"; | ||
251 | interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH /* controller interrupt */ | ||
252 | GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */ | ||
253 | interrupt-names = "intr", "msi"; | ||
254 | |||
255 | #interrupt-cells = <1>; | ||
256 | interrupt-map-mask = <0 0 0 0>; | ||
257 | interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | ||
258 | |||
259 | bus-range = <0x00 0xff>; | ||
260 | #address-cells = <3>; | ||
261 | #size-cells = <2>; | ||
262 | |||
263 | ranges = <0x82000000 0 0x00000000 0x00000000 0 0x00001000 /* port 0 configuration space */ | ||
264 | 0x82000000 0 0x00001000 0x00001000 0 0x00001000 /* port 1 configuration space */ | ||
265 | 0x82000000 0 0x00004000 0x00004000 0 0x00001000 /* port 2 configuration space */ | ||
266 | 0x81000000 0 0 0x02000000 0 0x00010000 /* downstream I/O */ | ||
267 | 0x82000000 0 0x20000000 0x20000000 0 0x08000000 /* non-prefetchable memory */ | ||
268 | 0xc2000000 0 0x28000000 0x28000000 0 0x18000000>; /* prefetchable memory */ | ||
269 | |||
270 | clocks = <&tegra_car TEGRA30_CLK_PCIE>, | ||
271 | <&tegra_car TEGRA30_CLK_AFI>, | ||
272 | <&tegra_car TEGRA30_CLK_PLL_E>, | ||
273 | <&tegra_car TEGRA30_CLK_CML0>; | ||
274 | clock-names = "pex", "afi", "pll_e", "cml"; | ||
275 | resets = <&tegra_car 70>, | ||
276 | <&tegra_car 72>, | ||
277 | <&tegra_car 74>; | ||
278 | reset-names = "pex", "afi", "pcie_x"; | ||
279 | status = "disabled"; | ||
280 | |||
281 | pci@1,0 { | ||
282 | device_type = "pci"; | ||
283 | assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>; | ||
284 | reg = <0x000800 0 0 0 0>; | ||
285 | status = "disabled"; | ||
286 | |||
287 | #address-cells = <3>; | ||
288 | #size-cells = <2>; | ||
289 | ranges; | ||
290 | |||
291 | nvidia,num-lanes = <2>; | ||
292 | }; | ||
293 | |||
294 | pci@2,0 { | ||
295 | device_type = "pci"; | ||
296 | assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>; | ||
297 | reg = <0x001000 0 0 0 0>; | ||
298 | status = "disabled"; | ||
299 | |||
300 | #address-cells = <3>; | ||
301 | #size-cells = <2>; | ||
302 | ranges; | ||
303 | |||
304 | nvidia,num-lanes = <2>; | ||
305 | }; | ||
306 | |||
307 | pci@3,0 { | ||
308 | device_type = "pci"; | ||
309 | assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>; | ||
310 | reg = <0x001800 0 0 0 0>; | ||
311 | status = "disabled"; | ||
312 | |||
313 | #address-cells = <3>; | ||
314 | #size-cells = <2>; | ||
315 | ranges; | ||
316 | |||
317 | nvidia,num-lanes = <2>; | ||
318 | }; | ||
319 | }; | ||
320 | |||
321 | Board DTS: | ||
322 | |||
323 | pcie-controller@00003000 { | ||
324 | status = "okay"; | ||
325 | |||
326 | avdd-pexa-supply = <&ldo1_reg>; | ||
327 | vdd-pexa-supply = <&ldo1_reg>; | ||
328 | avdd-pexb-supply = <&ldo1_reg>; | ||
329 | vdd-pexb-supply = <&ldo1_reg>; | ||
330 | avdd-pex-pll-supply = <&ldo1_reg>; | ||
331 | avdd-plle-supply = <&ldo1_reg>; | ||
332 | vddio-pex-ctl-supply = <&sys_3v3_reg>; | ||
333 | hvdd-pex-supply = <&sys_3v3_pexs_reg>; | ||
334 | |||
335 | pci@1,0 { | ||
336 | status = "okay"; | ||
337 | }; | ||
338 | |||
339 | pci@3,0 { | ||
340 | status = "okay"; | ||
341 | }; | ||
342 | }; | ||
343 | |||
344 | Tegra124: | ||
345 | --------- | ||
346 | |||
347 | SoC DTSI: | ||
348 | |||
349 | pcie-controller@01003000 { | ||
350 | compatible = "nvidia,tegra124-pcie"; | ||
351 | device_type = "pci"; | ||
352 | reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ | ||
353 | 0x0 0x01003800 0x0 0x00000800 /* AFI registers */ | ||
354 | 0x0 0x02000000 0x0 0x10000000>; /* configuration space */ | ||
355 | reg-names = "pads", "afi", "cs"; | ||
356 | interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */ | ||
357 | <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */ | ||
358 | interrupt-names = "intr", "msi"; | ||
359 | |||
360 | #interrupt-cells = <1>; | ||
361 | interrupt-map-mask = <0 0 0 0>; | ||
362 | interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | ||
363 | |||
364 | bus-range = <0x00 0xff>; | ||
365 | #address-cells = <3>; | ||
366 | #size-cells = <2>; | ||
367 | |||
368 | ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */ | ||
369 | 0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */ | ||
370 | 0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */ | ||
371 | 0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */ | ||
372 | 0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */ | ||
373 | |||
374 | clocks = <&tegra_car TEGRA124_CLK_PCIE>, | ||
375 | <&tegra_car TEGRA124_CLK_AFI>, | ||
376 | <&tegra_car TEGRA124_CLK_PLL_E>, | ||
377 | <&tegra_car TEGRA124_CLK_CML0>; | ||
378 | clock-names = "pex", "afi", "pll_e", "cml"; | ||
379 | resets = <&tegra_car 70>, | ||
380 | <&tegra_car 72>, | ||
381 | <&tegra_car 74>; | ||
382 | reset-names = "pex", "afi", "pcie_x"; | ||
383 | status = "disabled"; | ||
384 | |||
385 | pci@1,0 { | ||
386 | device_type = "pci"; | ||
387 | assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>; | ||
388 | reg = <0x000800 0 0 0 0>; | ||
389 | status = "disabled"; | ||
390 | |||
391 | #address-cells = <3>; | ||
392 | #size-cells = <2>; | ||
393 | ranges; | ||
394 | |||
395 | nvidia,num-lanes = <2>; | ||
396 | }; | ||
397 | |||
398 | pci@2,0 { | ||
399 | device_type = "pci"; | ||
400 | assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>; | ||
401 | reg = <0x001000 0 0 0 0>; | ||
402 | status = "disabled"; | ||
403 | |||
404 | #address-cells = <3>; | ||
405 | #size-cells = <2>; | ||
406 | ranges; | ||
407 | |||
408 | nvidia,num-lanes = <1>; | ||
409 | }; | ||
410 | }; | ||
411 | |||
412 | Board DTS: | ||
413 | |||
414 | pcie-controller@01003000 { | ||
415 | status = "okay"; | ||
416 | |||
417 | avddio-pex-supply = <&vdd_1v05_run>; | ||
418 | dvddio-pex-supply = <&vdd_1v05_run>; | ||
419 | avdd-pex-pll-supply = <&vdd_1v05_run>; | ||
420 | hvdd-pex-supply = <&vdd_3v3_lp0>; | ||
421 | hvdd-pex-pll-e-supply = <&vdd_3v3_lp0>; | ||
422 | vddio-pex-ctl-supply = <&vdd_3v3_lp0>; | ||
423 | avdd-pll-erefe-supply = <&avdd_1v05_run>; | ||
424 | |||
425 | /* Mini PCIe */ | ||
426 | pci@1,0 { | ||
427 | phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>; | ||
428 | phy-names = "pcie-0"; | ||
429 | status = "okay"; | ||
430 | }; | ||
431 | |||
432 | /* Gigabit Ethernet */ | ||
433 | pci@2,0 { | ||
434 | phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>; | ||
435 | phy-names = "pcie-0"; | ||
436 | status = "okay"; | ||
437 | }; | ||
438 | }; | ||
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 68d1f41b3cbf..c388468c202a 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -295,6 +295,7 @@ struct tegra_pcie { | |||
295 | struct reset_control *afi_rst; | 295 | struct reset_control *afi_rst; |
296 | struct reset_control *pcie_xrst; | 296 | struct reset_control *pcie_xrst; |
297 | 297 | ||
298 | bool legacy_phy; | ||
298 | struct phy *phy; | 299 | struct phy *phy; |
299 | 300 | ||
300 | struct tegra_msi msi; | 301 | struct tegra_msi msi; |
@@ -311,11 +312,14 @@ struct tegra_pcie { | |||
311 | 312 | ||
312 | struct tegra_pcie_port { | 313 | struct tegra_pcie_port { |
313 | struct tegra_pcie *pcie; | 314 | struct tegra_pcie *pcie; |
315 | struct device_node *np; | ||
314 | struct list_head list; | 316 | struct list_head list; |
315 | struct resource regs; | 317 | struct resource regs; |
316 | void __iomem *base; | 318 | void __iomem *base; |
317 | unsigned int index; | 319 | unsigned int index; |
318 | unsigned int lanes; | 320 | unsigned int lanes; |
321 | |||
322 | struct phy **phys; | ||
319 | }; | 323 | }; |
320 | 324 | ||
321 | struct tegra_pcie_bus { | 325 | struct tegra_pcie_bus { |
@@ -860,6 +864,128 @@ static int tegra_pcie_phy_enable(struct tegra_pcie *pcie) | |||
860 | return 0; | 864 | return 0; |
861 | } | 865 | } |
862 | 866 | ||
867 | static int tegra_pcie_phy_disable(struct tegra_pcie *pcie) | ||
868 | { | ||
869 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | ||
870 | u32 value; | ||
871 | |||
872 | /* disable TX/RX data */ | ||
873 | value = pads_readl(pcie, PADS_CTL); | ||
874 | value &= ~(PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L); | ||
875 | pads_writel(pcie, value, PADS_CTL); | ||
876 | |||
877 | /* override IDDQ */ | ||
878 | value = pads_readl(pcie, PADS_CTL); | ||
879 | value |= PADS_CTL_IDDQ_1L; | ||
880 | pads_writel(pcie, PADS_CTL, value); | ||
881 | |||
882 | /* reset PLL */ | ||
883 | value = pads_readl(pcie, soc->pads_pll_ctl); | ||
884 | value &= ~PADS_PLL_CTL_RST_B4SM; | ||
885 | pads_writel(pcie, value, soc->pads_pll_ctl); | ||
886 | |||
887 | usleep_range(20, 100); | ||
888 | |||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | static int tegra_pcie_port_phy_power_on(struct tegra_pcie_port *port) | ||
893 | { | ||
894 | struct device *dev = port->pcie->dev; | ||
895 | unsigned int i; | ||
896 | int err; | ||
897 | |||
898 | for (i = 0; i < port->lanes; i++) { | ||
899 | err = phy_power_on(port->phys[i]); | ||
900 | if (err < 0) { | ||
901 | dev_err(dev, "failed to power on PHY#%u: %d\n", i, | ||
902 | err); | ||
903 | return err; | ||
904 | } | ||
905 | } | ||
906 | |||
907 | return 0; | ||
908 | } | ||
909 | |||
910 | static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port) | ||
911 | { | ||
912 | struct device *dev = port->pcie->dev; | ||
913 | unsigned int i; | ||
914 | int err; | ||
915 | |||
916 | for (i = 0; i < port->lanes; i++) { | ||
917 | err = phy_power_off(port->phys[i]); | ||
918 | if (err < 0) { | ||
919 | dev_err(dev, "failed to power off PHY#%u: %d\n", i, | ||
920 | err); | ||
921 | return err; | ||
922 | } | ||
923 | } | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) | ||
929 | { | ||
930 | struct tegra_pcie_port *port; | ||
931 | int err; | ||
932 | |||
933 | if (pcie->legacy_phy) { | ||
934 | if (pcie->phy) | ||
935 | err = phy_power_on(pcie->phy); | ||
936 | else | ||
937 | err = tegra_pcie_phy_enable(pcie); | ||
938 | |||
939 | if (err < 0) | ||
940 | dev_err(pcie->dev, "failed to power on PHY: %d\n", err); | ||
941 | |||
942 | return err; | ||
943 | } | ||
944 | |||
945 | list_for_each_entry(port, &pcie->ports, list) { | ||
946 | err = tegra_pcie_port_phy_power_on(port); | ||
947 | if (err < 0) { | ||
948 | dev_err(pcie->dev, | ||
949 | "failed to power on PCIe port %u PHY: %d\n", | ||
950 | port->index, err); | ||
951 | return err; | ||
952 | } | ||
953 | } | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static int tegra_pcie_phy_power_off(struct tegra_pcie *pcie) | ||
959 | { | ||
960 | struct tegra_pcie_port *port; | ||
961 | int err; | ||
962 | |||
963 | if (pcie->legacy_phy) { | ||
964 | if (pcie->phy) | ||
965 | err = phy_power_off(pcie->phy); | ||
966 | else | ||
967 | err = tegra_pcie_phy_disable(pcie); | ||
968 | |||
969 | if (err < 0) | ||
970 | dev_err(pcie->dev, "failed to power off PHY: %d\n", | ||
971 | err); | ||
972 | |||
973 | return err; | ||
974 | } | ||
975 | |||
976 | list_for_each_entry(port, &pcie->ports, list) { | ||
977 | err = tegra_pcie_port_phy_power_off(port); | ||
978 | if (err < 0) { | ||
979 | dev_err(pcie->dev, | ||
980 | "failed to power off PCIe port %u PHY: %d\n", | ||
981 | port->index, err); | ||
982 | return err; | ||
983 | } | ||
984 | } | ||
985 | |||
986 | return 0; | ||
987 | } | ||
988 | |||
863 | static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | 989 | static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) |
864 | { | 990 | { |
865 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | 991 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; |
@@ -899,13 +1025,9 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
899 | afi_writel(pcie, value, AFI_FUSE); | 1025 | afi_writel(pcie, value, AFI_FUSE); |
900 | } | 1026 | } |
901 | 1027 | ||
902 | if (!pcie->phy) | 1028 | err = tegra_pcie_phy_power_on(pcie); |
903 | err = tegra_pcie_phy_enable(pcie); | ||
904 | else | ||
905 | err = phy_power_on(pcie->phy); | ||
906 | |||
907 | if (err < 0) { | 1029 | if (err < 0) { |
908 | dev_err(pcie->dev, "failed to power on PHY: %d\n", err); | 1030 | dev_err(pcie->dev, "failed to power on PHY(s): %d\n", err); |
909 | return err; | 1031 | return err; |
910 | } | 1032 | } |
911 | 1033 | ||
@@ -942,9 +1064,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) | |||
942 | 1064 | ||
943 | /* TODO: disable and unprepare clocks? */ | 1065 | /* TODO: disable and unprepare clocks? */ |
944 | 1066 | ||
945 | err = phy_power_off(pcie->phy); | 1067 | err = tegra_pcie_phy_power_off(pcie); |
946 | if (err < 0) | 1068 | if (err < 0) |
947 | dev_warn(pcie->dev, "failed to power off PHY: %d\n", err); | 1069 | dev_err(pcie->dev, "failed to power off PHY(s): %d\n", err); |
948 | 1070 | ||
949 | reset_control_assert(pcie->pcie_xrst); | 1071 | reset_control_assert(pcie->pcie_xrst); |
950 | reset_control_assert(pcie->afi_rst); | 1072 | reset_control_assert(pcie->afi_rst); |
@@ -1049,6 +1171,100 @@ static int tegra_pcie_resets_get(struct tegra_pcie *pcie) | |||
1049 | return 0; | 1171 | return 0; |
1050 | } | 1172 | } |
1051 | 1173 | ||
1174 | static int tegra_pcie_phys_get_legacy(struct tegra_pcie *pcie) | ||
1175 | { | ||
1176 | int err; | ||
1177 | |||
1178 | pcie->phy = devm_phy_optional_get(pcie->dev, "pcie"); | ||
1179 | if (IS_ERR(pcie->phy)) { | ||
1180 | err = PTR_ERR(pcie->phy); | ||
1181 | dev_err(pcie->dev, "failed to get PHY: %d\n", err); | ||
1182 | return err; | ||
1183 | } | ||
1184 | |||
1185 | err = phy_init(pcie->phy); | ||
1186 | if (err < 0) { | ||
1187 | dev_err(pcie->dev, "failed to initialize PHY: %d\n", err); | ||
1188 | return err; | ||
1189 | } | ||
1190 | |||
1191 | pcie->legacy_phy = true; | ||
1192 | |||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1196 | static struct phy *devm_of_phy_optional_get_index(struct device *dev, | ||
1197 | struct device_node *np, | ||
1198 | const char *consumer, | ||
1199 | unsigned int index) | ||
1200 | { | ||
1201 | struct phy *phy; | ||
1202 | char *name; | ||
1203 | |||
1204 | name = kasprintf(GFP_KERNEL, "%s-%u", consumer, index); | ||
1205 | if (!name) | ||
1206 | return ERR_PTR(-ENOMEM); | ||
1207 | |||
1208 | phy = devm_of_phy_get(dev, np, name); | ||
1209 | kfree(name); | ||
1210 | |||
1211 | if (IS_ERR(phy) && PTR_ERR(phy) == -ENODEV) | ||
1212 | phy = NULL; | ||
1213 | |||
1214 | return phy; | ||
1215 | } | ||
1216 | |||
1217 | static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port) | ||
1218 | { | ||
1219 | struct device *dev = port->pcie->dev; | ||
1220 | struct phy *phy; | ||
1221 | unsigned int i; | ||
1222 | int err; | ||
1223 | |||
1224 | port->phys = devm_kcalloc(dev, sizeof(phy), port->lanes, GFP_KERNEL); | ||
1225 | if (!port->phys) | ||
1226 | return -ENOMEM; | ||
1227 | |||
1228 | for (i = 0; i < port->lanes; i++) { | ||
1229 | phy = devm_of_phy_optional_get_index(dev, port->np, "pcie", i); | ||
1230 | if (IS_ERR(phy)) { | ||
1231 | dev_err(dev, "failed to get PHY#%u: %ld\n", i, | ||
1232 | PTR_ERR(phy)); | ||
1233 | return PTR_ERR(phy); | ||
1234 | } | ||
1235 | |||
1236 | err = phy_init(phy); | ||
1237 | if (err < 0) { | ||
1238 | dev_err(dev, "failed to initialize PHY#%u: %d\n", i, | ||
1239 | err); | ||
1240 | return err; | ||
1241 | } | ||
1242 | |||
1243 | port->phys[i] = phy; | ||
1244 | } | ||
1245 | |||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | static int tegra_pcie_phys_get(struct tegra_pcie *pcie) | ||
1250 | { | ||
1251 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | ||
1252 | struct device_node *np = pcie->dev->of_node; | ||
1253 | struct tegra_pcie_port *port; | ||
1254 | int err; | ||
1255 | |||
1256 | if (!soc->has_gen2 || of_find_property(np, "phys", NULL) != NULL) | ||
1257 | return tegra_pcie_phys_get_legacy(pcie); | ||
1258 | |||
1259 | list_for_each_entry(port, &pcie->ports, list) { | ||
1260 | err = tegra_pcie_port_get_phys(port); | ||
1261 | if (err < 0) | ||
1262 | return err; | ||
1263 | } | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1052 | static int tegra_pcie_get_resources(struct tegra_pcie *pcie) | 1268 | static int tegra_pcie_get_resources(struct tegra_pcie *pcie) |
1053 | { | 1269 | { |
1054 | struct platform_device *pdev = to_platform_device(pcie->dev); | 1270 | struct platform_device *pdev = to_platform_device(pcie->dev); |
@@ -1067,16 +1283,9 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) | |||
1067 | return err; | 1283 | return err; |
1068 | } | 1284 | } |
1069 | 1285 | ||
1070 | pcie->phy = devm_phy_optional_get(pcie->dev, "pcie"); | 1286 | err = tegra_pcie_phys_get(pcie); |
1071 | if (IS_ERR(pcie->phy)) { | ||
1072 | err = PTR_ERR(pcie->phy); | ||
1073 | dev_err(&pdev->dev, "failed to get PHY: %d\n", err); | ||
1074 | return err; | ||
1075 | } | ||
1076 | |||
1077 | err = phy_init(pcie->phy); | ||
1078 | if (err < 0) { | 1287 | if (err < 0) { |
1079 | dev_err(&pdev->dev, "failed to initialize PHY: %d\n", err); | 1288 | dev_err(&pdev->dev, "failed to get PHYs: %d\n", err); |
1080 | return err; | 1289 | return err; |
1081 | } | 1290 | } |
1082 | 1291 | ||
@@ -1752,6 +1961,7 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1752 | rp->index = index; | 1961 | rp->index = index; |
1753 | rp->lanes = value; | 1962 | rp->lanes = value; |
1754 | rp->pcie = pcie; | 1963 | rp->pcie = pcie; |
1964 | rp->np = port; | ||
1755 | 1965 | ||
1756 | rp->base = devm_ioremap_resource(pcie->dev, &rp->regs); | 1966 | rp->base = devm_ioremap_resource(pcie->dev, &rp->regs); |
1757 | if (IS_ERR(rp->base)) | 1967 | if (IS_ERR(rp->base)) |