summaryrefslogtreecommitdiff
path: root/recipes-kernel/linux/linux-toradex-mainline-4.14/0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-toradex-mainline-4.14/0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch')
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-4.14/0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch329
1 files changed, 329 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-toradex-mainline-4.14/0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch b/recipes-kernel/linux/linux-toradex-mainline-4.14/0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch
new file mode 100644
index 0000000..e0f2483
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-4.14/0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch
@@ -0,0 +1,329 @@
+From 7e4a3d7ee5cf304ce0c5a5be6e1dcb7cafc34a1b Mon Sep 17 00:00:00 2001
+Message-Id: <7e4a3d7ee5cf304ce0c5a5be6e1dcb7cafc34a1b.1531317141.git.marcel.ziswiler@toradex.com>
+In-Reply-To: <6654e1bd342708a683daf47e7558455f709a3e7e.1531317141.git.marcel.ziswiler@toradex.com>
+References: <6654e1bd342708a683daf47e7558455f709a3e7e.1531317141.git.marcel.ziswiler@toradex.com>
+From: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Date: Wed, 11 Jul 2018 15:44:16 +0200
+Subject: [PATCH 32/33] apalis-tk1: fix pcie reset for reliable gigabit
+ ethernet operation
+
+It turns out that the forward port of the current PCIe reset
+implementation was not quite working reliably due to differences in
+regulator naming. Another shortcoming was that it currently resets
+multiple times due to not differentiating which PCIe port needs
+resetting. Improve this by doing specific reset per port only.
+
+Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+---
+ arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts | 10 --
+ arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi | 20 ---
+ arch/arm/boot/dts/tegra124-apalis.dtsi | 2 -
+ drivers/pci/host/pci-tegra.c | 171 ++++++++++++++----------
+ 4 files changed, 103 insertions(+), 100 deletions(-)
+
+diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts
+index 046a415d5db8..4f2e4766379d 100644
+--- a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts
++++ b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts
+@@ -250,13 +250,3 @@
+ vin-supply = <&reg_5v0>;
+ };
+ };
+-
+-&gpio {
+- /* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
+- pex_perst_n {
+- gpio-hog;
+- gpios = <TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "PEX_PERST_N";
+- };
+-};
+diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
+index 08e4b08e26f8..1336e8caf95d 100644
+--- a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
++++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
+@@ -1721,14 +1721,12 @@
+ regulator-name = "+V3.3_ETH(ldo9)";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+ };
+
+ ldo10 {
+ regulator-name = "+V3.3_ETH(ldo10)";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+ };
+
+ ldo11 {
+@@ -2065,21 +2063,3 @@
+ };
+ };
+ };
+-
+-&gpio {
+- /* I210 Gigabit Ethernet Controller Reset */
+- lan_reset_n {
+- gpio-hog;
+- gpios = <TEGRA_GPIO(S, 2) GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "LAN_RESET_N";
+- };
+-
+- /* Control MXM3 pin 26 Reset Module Output Carrier Input */
+- reset_moci_ctrl {
+- gpio-hog;
+- gpios = <TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "RESET_MOCI_CTRL";
+- };
+-};
+diff --git a/arch/arm/boot/dts/tegra124-apalis.dtsi b/arch/arm/boot/dts/tegra124-apalis.dtsi
+index a19844e61adc..00920c26f60a 100644
+--- a/arch/arm/boot/dts/tegra124-apalis.dtsi
++++ b/arch/arm/boot/dts/tegra124-apalis.dtsi
+@@ -1756,14 +1756,12 @@
+ regulator-name = "+V3.3_ETH(ldo9)";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+ };
+
+ ldo10 {
+ regulator-name = "+V3.3_ETH(ldo10)";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+ };
+
+ ldo11 {
+diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
+index 0c6237159243..0e19ff52275e 100644
+--- a/drivers/pci/host/pci-tegra.c
++++ b/drivers/pci/host/pci-tegra.c
+@@ -333,6 +333,9 @@ struct tegra_pcie {
+ struct regulator_bulk_data *supplies;
+ unsigned int num_supplies;
+
++#ifdef CONFIG_MACH_APALIS_T30
++ int pci_reset_status;
++#endif
+ #ifdef CONFIG_MACH_APALIS_TK1
+ struct regulator *regulator_apalis_tk1_ldo9;
+ struct regulator *regulator_apalis_tk1_ldo10;
+@@ -584,58 +587,82 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+ unsigned long value;
+
+ #if defined(CONFIG_MACH_APALIS_T30) || defined(CONFIG_MACH_APALIS_TK1)
++#ifdef CONFIG_MACH_APALIS_T30
+ /*
+- * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis Evaluation
+- * Board
++ * Apalis PCIe aka port 1 and Apalis Type Specific 4 Lane PCIe aka port
++ * 0 share the same RESET_MOCI therefore only assert it once for both
++ * ports to avoid loosing the previously brought up port again.
+ */
+- if (g_pex_perst)
+- gpio_request(PEX_PERST_N, "PEX_PERST_N");
+- gpio_request(RESET_MOCI_N, "RESET_MOCI_N");
+- if (g_pex_perst)
+- gpio_direction_output(PEX_PERST_N, 0);
+- gpio_direction_output(RESET_MOCI_N, 0);
+-
++ if ((port->index == 1) || (port->index == 0)) {
++ /* only do it once per init cycle */
++ if (port->pcie->pci_reset_status % 2 == 0) {
++#endif
+ #ifdef CONFIG_MACH_APALIS_TK1
+- /* Reset I210 Gigabit Ethernet Controller */
+- if (LAN_RESET_N) {
+- gpio_request(LAN_RESET_N, "LAN_RESET_N");
+- gpio_direction_output(LAN_RESET_N, 0);
++ if (port->index == 0) { /* Apalis PCIe */
++#endif
++ /*
++ * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis Evaluation
++ * Board
++ */
++ if (g_pex_perst)
++ gpio_request(PEX_PERST_N, "PEX_PERST_N");
++ gpio_request(RESET_MOCI_N, "RESET_MOCI_N");
++ if (g_pex_perst)
++ gpio_direction_output(PEX_PERST_N, 0);
++ gpio_direction_output(RESET_MOCI_N, 0);
++#ifdef CONFIG_MACH_APALIS_T30
++ }
++#endif
+ }
++#ifdef CONFIG_MACH_APALIS_TK1
++ if (port->index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */
++ /* Reset I210 Gigabit Ethernet Controller */
++ if (LAN_RESET_N >= 0) {
++ gpio_request(LAN_RESET_N, "LAN_RESET_N");
++ gpio_direction_output(LAN_RESET_N, 0);
++ }
+
+- /*
+- * Make sure we don't get any back feeding from LAN_WAKE_N resp.
+- * DEV_OFF_N
+- */
+- gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
+- gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
+- gpio_direction_output(LAN_WAKE_N, 0);
+- gpio_direction_output(LAN_DEV_OFF_N, 0);
+-
+- /* Make sure LDO9 and LDO10 are initially disabled @ 0V */
+- if (regulator_is_enabled(port->pcie->regulator_apalis_tk1_ldo9))
+- regulator_disable(port->pcie->regulator_apalis_tk1_ldo9);
+- if (regulator_is_enabled(port->pcie->regulator_apalis_tk1_ldo10))
+- regulator_disable(port->pcie->regulator_apalis_tk1_ldo10);
++ /*
++ * Make sure we don't get any back feeding from LAN_WAKE_N resp.
++ * DEV_OFF_N
++ */
++ gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
++ gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
++ gpio_direction_output(LAN_WAKE_N, 0);
++ gpio_direction_output(LAN_DEV_OFF_N, 0);
++
++ /* Make sure LDO9 and LDO10 are initially disabled @ 0V */
++ if (regulator_is_enabled(port->pcie->regulator_apalis_tk1_ldo9)) {
++ value = regulator_enable(port->pcie->regulator_apalis_tk1_ldo9);
++ if (regulator_disable(port->pcie->regulator_apalis_tk1_ldo9) < 0)
++ pr_err("failed disabling +V3.3_ETH(ldo9)\n");
++ }
++ if (regulator_is_enabled(port->pcie->regulator_apalis_tk1_ldo10)) {
++ value = regulator_enable(port->pcie->regulator_apalis_tk1_ldo10);
++ if (regulator_disable(port->pcie->regulator_apalis_tk1_ldo10) <0)
++ pr_err("failed disabling +V3.3_ETH(ldo10)\n");
++ }
+
+- mdelay(100);
++ mdelay(100);
+
+- /* Make sure LAN_WAKE_N gets re-configured as a GPIO input */
+- gpio_direction_input(LAN_WAKE_N);
++ /* Make sure LAN_WAKE_N gets re-configured as a GPIO input */
++ gpio_direction_input(LAN_WAKE_N);
+
+- /* Make sure controller gets enabled by disabling DEV_OFF_N */
+- gpio_set_value(LAN_DEV_OFF_N, 1);
++ /* Make sure controller gets enabled by disabling DEV_OFF_N */
++ gpio_set_value(LAN_DEV_OFF_N, 1);
+
+- /*
+- * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
+- * V1.0A and sample V1.0B and newer modules
+- */
+- if (regulator_enable(port->pcie->regulator_apalis_tk1_ldo9) < 0) {
+- pr_err("pcie: couldn't enable regulator i210_vdd3p3_ldo9\n");
+- return;
+- }
+- if (regulator_enable(port->pcie->regulator_apalis_tk1_ldo10) < 0) {
+- pr_err("pcie: couldn't enable regulator i210_vdd3p3_ldo10\n");
+- return;
++ /*
++ * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
++ * V1.0A and sample V1.0B and newer modules
++ */
++ if (regulator_enable(port->pcie->regulator_apalis_tk1_ldo9) < 0) {
++ pr_err("pcie: couldn't enable regulator +V3.3_ETH(ldo9)\n");
++ return;
++ }
++ if (regulator_enable(port->pcie->regulator_apalis_tk1_ldo10) < 0) {
++ pr_err("pcie: couldn't enable regulator +V3.3_ETH(ldo10)\n");
++ return;
++ }
+ }
+ #endif /* CONFIG_MACH_APALIS_TK1 */
+ #endif /* CONFIG_MACH_APALIS_T30 || CONFIG_MACH_APALIS_TK1 */
+@@ -652,25 +679,38 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+ afi_writel(port->pcie, value, ctrl);
+
+ #if defined(CONFIG_MACH_APALIS_T30) || defined(CONFIG_MACH_APALIS_TK1)
++#ifdef CONFIG_MACH_APALIS_T30
++ if ((port->index == 1) || (port->index == 0)) {
++ /* only do it once per init cycle */
++ if (port->pcie->pci_reset_status % 2 == 0) {
++#endif
+ #ifdef CONFIG_MACH_APALIS_TK1
+- gpio_set_value(LAN_RESET_N, 1);
+-#endif /* CONFIG_MACH_APALIS_TK1 */
+-
+- /* Must be asserted for 100 ms after power and clocks are stable */
+- if (g_pex_perst)
+- gpio_set_value(PEX_PERST_N, 1);
+- /*
+- * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed Until
+- * 900 us After PEX_PERST# De-assertion
+- */
+- if (g_pex_perst)
+- mdelay(1);
+- gpio_set_value(RESET_MOCI_N, 1);
++ if (port->index == 0) { /* Apalis PCIe */
++#endif
++ /* Must be asserted for 100 ms after power and clocks are stable */
++ if (g_pex_perst)
++ gpio_set_value(PEX_PERST_N, 1);
++ /*
++ * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed Until
++ * 900 us After PEX_PERST# De-assertion
++ */
++ if (g_pex_perst)
++ mdelay(1);
++ gpio_set_value(RESET_MOCI_N, 1);
++#ifdef CONFIG_MACH_APALIS_T30
++ }
++ port->pcie->pci_reset_status++;
++#endif
++ }
+
+ #ifdef CONFIG_MACH_APALIS_TK1
+- /* Release I210 Gigabit Ethernet Controller Reset */
+- if (LAN_RESET_N)
+- gpio_set_value(LAN_RESET_N, 1);
++ mdelay(5);
++
++ if (port->index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */
++ /* Release I210 Gigabit Ethernet Controller Reset */
++ if (LAN_RESET_N >= 0)
++ gpio_set_value(LAN_RESET_N, 1);
++ }
+ #endif /* CONFIG_MACH_APALIS_TK1 */
+ #endif /* CONFIG_MACH_APALIS_T30 || CONFIG_MACH_APALIS_TK1 */
+ }
+@@ -1232,25 +1272,20 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
+
+ #ifdef CONFIG_MACH_APALIS_TK1
+ if (pcie->regulator_apalis_tk1_ldo9 == NULL) {
+- pcie->regulator_apalis_tk1_ldo9 = regulator_get(pcie->dev, "i210_vdd3p3_ldo9");
++ pcie->regulator_apalis_tk1_ldo9 = regulator_get(pcie->dev, "+V3.3_ETH(ldo9)");
+ if (IS_ERR(pcie->regulator_apalis_tk1_ldo9)) {
+- pr_err("pcie: couldn't get regulator i210_vdd3p3_ldo9\n");
++ pr_err("pcie: couldn't get regulator +V3.3_ETH(ldo9)\n");
+ pcie->regulator_apalis_tk1_ldo9 = 0;
+ }
+ }
+
+ if (pcie->regulator_apalis_tk1_ldo10 == NULL) {
+- pcie->regulator_apalis_tk1_ldo10 = regulator_get(pcie->dev, "i210_vdd3p3_ldo10");
++ pcie->regulator_apalis_tk1_ldo10 = regulator_get(pcie->dev, "+V3.3_ETH(ldo10)");
+ if (IS_ERR(pcie->regulator_apalis_tk1_ldo10)) {
+- pr_err("pcie: couldn't get regulator i210_vdd3p3_ldo10\n");
++ pr_err("pcie: couldn't get regulator +V3.3_ETH(ldo10)\n");
+ pcie->regulator_apalis_tk1_ldo10 = 0;
+ }
+ }
+-
+- if (pcie->regulator_apalis_tk1_ldo9)
+- err = regulator_enable(pcie->regulator_apalis_tk1_ldo9);
+- if (pcie->regulator_apalis_tk1_ldo10)
+- err = regulator_enable(pcie->regulator_apalis_tk1_ldo10);
+ #endif /* CONFIG_MACH_APALIS_TK1 */
+
+ reset_control_deassert(pcie->afi_rst);
+--
+2.14.4
+