summaryrefslogtreecommitdiff
path: root/recipes-kernel/linux/linux-toradex-mainline-4.14/0008-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/0008-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch')
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-4.14/0008-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-toradex-mainline-4.14/0008-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch b/recipes-kernel/linux/linux-toradex-mainline-4.14/0008-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch
new file mode 100644
index 0000000..50d7407
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-4.14/0008-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch
@@ -0,0 +1,140 @@
+From ea64a271a36553990bb2a6cb40edfd929d8e6e88 Mon Sep 17 00:00:00 2001
+Message-Id: <ea64a271a36553990bb2a6cb40edfd929d8e6e88.1510580437.git.marcel.ziswiler@toradex.com>
+In-Reply-To: <8d39626d07718220b426e9be045df8ed9d1fd707.1510580437.git.marcel.ziswiler@toradex.com>
+References: <8d39626d07718220b426e9be045df8ed9d1fd707.1510580437.git.marcel.ziswiler@toradex.com>
+From: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Date: Mon, 13 Nov 2017 14:37:25 +0100
+Subject: [PATCH 8/8] apalis-tk1: fix pcie reset for reliable gigabit ethernet
+ operation
+
+It turns out that the current PCIe reset implementation is not quite
+working reliably due to some Intel i210 errata. Fix this by making sure
+the i210's +V3.3_ETH rail is properly disabled during its reset
+sequence.
+
+Also further improve on the bringing up the PCIe switch as found on the
+Apalis Evaluation board.
+
+Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Acked-by: Dominik Sliwa <dominik.sliwa@toradex.com>
+(downstream commit 7ad9771527d2b1c884beb22d9df28bae899f8d3d)
+---
+ drivers/pci/host/pci-tegra.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
+index 5c7916b..0c62371 100644
+--- a/drivers/pci/host/pci-tegra.c
++++ b/drivers/pci/host/pci-tegra.c
+@@ -71,8 +71,12 @@
+ #ifdef CONFIG_MACH_APALIS_TK1
+ #define APALIS_GPIO7 TEGRA_GPIO(DD, 1)
+
++#define LAN_DEV_OFF_N TEGRA_GPIO(O, 6)
++
+ #define LAN_RESET_N TEGRA_GPIO(S, 2)
+
++#define LAN_WAKE_N TEGRA_GPIO(O, 5)
++
+ #define PEX_PERST_N APALIS_GPIO7
+
+ #define RESET_MOCI_N TEGRA_GPIO(U, 4)
+@@ -329,6 +333,11 @@ struct tegra_pcie {
+ struct regulator_bulk_data *supplies;
+ unsigned int num_supplies;
+
++#ifdef CONFIG_MACH_APALIS_TK1
++ struct regulator *regulator_apalis_tk1_ldo9;
++ struct regulator *regulator_apalis_tk1_ldo10;
++#endif /* CONFIG_MACH_APALIS_TK1 */
++
+ const struct tegra_pcie_soc *soc;
+ struct dentry *debugfs;
+ };
+@@ -592,6 +601,42 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+ 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);
++
++ mdelay(100);
++
++ /* 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);
++
++ /*
++ * 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;
++ }
+ #endif /* CONFIG_MACH_APALIS_TK1 */
+ #endif /* CONFIG_MACH_APALIS_T30 || CONFIG_MACH_APALIS_TK1 */
+
+@@ -607,6 +652,10 @@ 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_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);
+@@ -1181,6 +1230,29 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
+ return err;
+ }
+
++#ifdef CONFIG_MACH_APALIS_TK1
++ if (pcie->regulator_apalis_tk1_ldo9 == NULL) {
++ pcie->regulator_apalis_tk1_ldo9 = regulator_get(pcie->dev, "i210_vdd3p3_ldo9");
++ if (IS_ERR(pcie->regulator_apalis_tk1_ldo9)) {
++ pr_err("pcie: couldn't get regulator i210_vdd3p3_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");
++ if (IS_ERR(pcie->regulator_apalis_tk1_ldo10)) {
++ pr_err("pcie: couldn't get regulator i210_vdd3p3_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);
+
+ err = clk_prepare_enable(pcie->afi_clk);
+--
+2.9.5
+