summaryrefslogtreecommitdiff
path: root/recipes-kernel/linux/linux-toradex-mainline-4.9/0001-apalis_t30-tk1-fix-pcie-clock-and-reset-not-conformi.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-toradex-mainline-4.9/0001-apalis_t30-tk1-fix-pcie-clock-and-reset-not-conformi.patch')
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-4.9/0001-apalis_t30-tk1-fix-pcie-clock-and-reset-not-conformi.patch147
1 files changed, 147 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-toradex-mainline-4.9/0001-apalis_t30-tk1-fix-pcie-clock-and-reset-not-conformi.patch b/recipes-kernel/linux/linux-toradex-mainline-4.9/0001-apalis_t30-tk1-fix-pcie-clock-and-reset-not-conformi.patch
new file mode 100644
index 0000000..c958ff6
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-4.9/0001-apalis_t30-tk1-fix-pcie-clock-and-reset-not-conformi.patch
@@ -0,0 +1,147 @@
+From a2286569bb02b2ef881302eedbd944f8482beabe Mon Sep 17 00:00:00 2001
+From: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Date: Thu, 15 Dec 2016 10:24:58 +0100
+Subject: [PATCH 1/4] apalis_t30/tk1: fix pcie clock and reset not conforming
+ to specification
+
+Fix PCIe clock and reset not conforming to specification by moving PCIe
+reset handling including the PLX PEX 8605 errata 5 workaround from the
+board platform data into the right places timing wise in the PCIe driver
+itself.
+
+Also add a kernel command line argument to allow using the Apalis GPIO7
+as a regular GPIO rather than for above mentioned PLX PEX 8605
+workaround:
+
+pex_perst=0
+
+Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Acked-by: Dominik Sliwa <dominik.sliwa@toradex.com>
+(cherry picked from toradex_tk1_l4t_r21.5 commit
+3e2259b04c2e2c029f742e9dda06a3a2739977d4)
+(cherry picked from tegra commit
+a2f63805703b43d55d91ae17f10d0049bf0f625e)
+
+---
+
+ drivers/pci/host/pci-tegra.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 83 insertions(+)
+
+diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
+index 8dfccf7..1452fe4 100644
+--- a/drivers/pci/host/pci-tegra.c
++++ b/drivers/pci/host/pci-tegra.c
+@@ -55,6 +55,34 @@
+ #include <asm/mach/map.h>
+ #include <asm/mach/pci.h>
+
++//#define CONFIG_MACH_APALIS_T30
++#define CONFIG_MACH_APALIS_TK1
++#if defined(CONFIG_MACH_APALIS_T30) || defined(CONFIG_MACH_APALIS_TK1)
++#include <linux/gpio.h>
++
++#include "../../../arch/arm/boot/dts/include/dt-bindings/gpio/tegra-gpio.h"
++
++#ifdef CONFIG_MACH_APALIS_T30
++#define APALIS_GPIO7 TEGRA_GPIO(S, 7)
++
++#define LAN_RESET_N -1
++
++#define PEX_PERST_N APALIS_GPIO7
++
++#define RESET_MOCI_N TEGRA_GPIO(I, 4)
++#endif
++
++#ifdef CONFIG_MACH_APALIS_TK1
++#define APALIS_GPIO7 TEGRA_GPIO(DD, 1)
++
++#define LAN_RESET_N TEGRA_GPIO(S, 2)
++
++#define PEX_PERST_N APALIS_GPIO7
++
++#define RESET_MOCI_N TEGRA_GPIO(U, 4)
++#endif
++#endif
++
+ #define INT_PCI_MSI_NR (8 * 32)
+
+ /* register definitions */
+@@ -322,6 +350,21 @@ struct tegra_pcie_bus {
+ unsigned int nr;
+ };
+
++#if defined(CONFIG_MACH_APALIS_T30) || defined(CONFIG_MACH_APALIS_TK1)
++/* To disable the PCIe switch reset errata workaround */
++int g_pex_perst = 1;
++
++/* To disable the PCIe switch reset errata workaround */
++static int __init disable_pex_perst(char *s)
++{
++ if (!(*s) || !strcmp(s, "0"))
++ g_pex_perst = 0;
++
++ return 0;
++}
++__setup("pex_perst=", disable_pex_perst);
++#endif /* CONFIG_MACH_APALIS_T30 || CONFIG_MACH_APALIS_TK1 */
++
+ static inline struct tegra_pcie *sys_to_pcie(struct pci_sys_data *sys)
+ {
+ return sys->private_data;
+@@ -528,6 +571,27 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+ unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+ unsigned long value;
+
++#if defined(CONFIG_MACH_APALIS_T30) || defined(CONFIG_MACH_APALIS_TK1)
++ /*
++ * 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_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);
++ }
++#endif /* CONFIG_MACH_APALIS_TK1 */
++#endif /* CONFIG_MACH_APALIS_T30 || CONFIG_MACH_APALIS_TK1 */
++
+ /* pulse reset signal */
+ value = afi_readl(port->pcie, ctrl);
+ value &= ~AFI_PEX_CTRL_RST;
+@@ -538,6 +602,25 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+ value = afi_readl(port->pcie, ctrl);
+ value |= AFI_PEX_CTRL_RST;
+ afi_writel(port->pcie, value, ctrl);
++
++#if defined(CONFIG_MACH_APALIS_T30) || defined(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);
++
++#ifdef CONFIG_MACH_APALIS_TK1
++ /* Release I210 Gigabit Ethernet Controller Reset */
++ if (LAN_RESET_N)
++ gpio_set_value(LAN_RESET_N, 1);
++#endif /* CONFIG_MACH_APALIS_TK1 */
++#endif /* CONFIG_MACH_APALIS_T30 || CONFIG_MACH_APALIS_TK1 */
+ }
+
+ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
+--
+2.9.3
+