diff options
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.patch | 140 |
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 + |