From a7c1d4dfb4404c892823aa809993f00426d039bc Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <6654e1bd342708a683daf47e7558455f709a3e7e.1531317141.git.marcel.ziswiler@toradex.com> References: <6654e1bd342708a683daf47e7558455f709a3e7e.1531317141.git.marcel.ziswiler@toradex.com> From: Marcel Ziswiler Date: Thu, 15 Dec 2016 10:24:58 +0100 Subject: [PATCH 02/33] 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 Acked-by: Dominik Sliwa (cherry picked from toradex_tk1_l4t_r21.5 commit 3e2259b04c2e2c029f742e9dda06a3a2739977d4) (cherry picked from tegra commit a2f63805703b43d55d91ae17f10d0049bf0f625e) --- drivers/pci/host/pci-tegra.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 1987fec1f126..5c7916b5de73 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -51,6 +51,34 @@ #include #include +//#define CONFIG_MACH_APALIS_T30 +#define CONFIG_MACH_APALIS_TK1 +#if defined(CONFIG_MACH_APALIS_T30) || defined(CONFIG_MACH_APALIS_TK1) +#include + +#include "../../../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 */ @@ -323,6 +351,26 @@ 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; +} + static inline void afi_writel(struct tegra_pcie *pcie, u32 value, unsigned long offset) { @@ -526,6 +574,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; @@ -536,6 +605,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.14.4