diff options
-rw-r--r-- | board/toradex/apalis-tk1/Kconfig | 8 | ||||
-rw-r--r-- | board/toradex/apalis-tk1/apalis-tk1.c | 180 | ||||
-rw-r--r-- | drivers/pci/pci_tegra.c | 17 | ||||
-rw-r--r-- | include/pci_tegra.h | 11 |
4 files changed, 141 insertions, 75 deletions
diff --git a/board/toradex/apalis-tk1/Kconfig b/board/toradex/apalis-tk1/Kconfig index 05407ad2d57..159b8fb19a5 100644 --- a/board/toradex/apalis-tk1/Kconfig +++ b/board/toradex/apalis-tk1/Kconfig @@ -25,6 +25,14 @@ config TDX_CFG_BLOCK_PART config TDX_CFG_BLOCK_OFFSET default "-512" +config APALIS_TK1_PCIE_EVALBOARD_INIT + bool "Apalis Evaluation Board PCIe Initialisation" + help + Bring up the Apalis PCIe port with the PCIe switch as found on the + Apalis Evaluation board. Note that by default the PCIe port is also + left disabled in the device tree which needs changing as well for this + to actually work. + source "board/toradex/common/Kconfig" endif diff --git a/board/toradex/apalis-tk1/apalis-tk1.c b/board/toradex/apalis-tk1/apalis-tk1.c index 4ce9d6909b9..7f554e455f1 100644 --- a/board/toradex/apalis-tk1/apalis-tk1.c +++ b/board/toradex/apalis-tk1/apalis-tk1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Toradex, Inc. + * Copyright (c) 2016-2017 Toradex, Inc. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -10,12 +10,20 @@ #include <asm/io.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> +#include <pci_tegra.h> #include <power/as3722.h> #include "../common/tdx-common.h" #include "pinmux-config-apalis-tk1.h" -#define LAN_RESET_N TEGRA_GPIO(S, 2) +#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) +#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT +#define PEX_PERST_N TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */ +#define RESET_MOCI_CTRL TEGRA_GPIO(U, 4) +#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ + #define IXORA_FAN_GPIO TEGRA_GPIO(DD, 2) int arch_misc_init(void) @@ -98,83 +106,111 @@ int tegra_pcie_board_init(void) return err; } - /* Reset I210 Gigabit Ethernet Controller */ + gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N"); 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(TEGRA_GPIO(O, 5), "LAN_WAKE_N"); - gpio_direction_output(TEGRA_GPIO(O, 5), 0); - - gpio_request(TEGRA_GPIO(O, 6), "LAN_DEV_OFF_N"); - gpio_direction_output(TEGRA_GPIO(O, 6), 0); - - /* Make sure LDO9 and LDO10 are initially enabled @ 0V */ - err = as3722_ldo_enable(pmic, 9); - if (err < 0) { - error("failed to enable LDO9: %d\n", err); - return err; - } - err = as3722_ldo_enable(pmic, 10); - if (err < 0) { - error("failed to enable LDO10: %d\n", err); - return err; - } - err = as3722_ldo_set_voltage(pmic, 9, 0x80); - if (err < 0) { - error("failed to set LDO9 voltage: %d\n", err); - return err; - } - err = as3722_ldo_set_voltage(pmic, 10, 0x80); - if (err < 0) { - error("failed to set LDO10 voltage: %d\n", err); - return err; - } + gpio_request(LAN_WAKE_N, "LAN_WAKE_N"); - mdelay(100); - - /* Make sure controller gets enabled by disabling DEV_OFF_N */ - gpio_set_value(TEGRA_GPIO(O, 6), 1); - - /* Enable LDO9 and LDO10 for +V3.3_ETH on patched prototypes */ - err = as3722_ldo_set_voltage(pmic, 9, 0xff); - if (err < 0) { - error("failed to set LDO9 voltage: %d\n", err); - return err; - } - err = as3722_ldo_set_voltage(pmic, 10, 0xff); - if (err < 0) { - error("failed to set LDO10 voltage: %d\n", err); - return err; - } - - mdelay(100); - gpio_set_value(LAN_RESET_N, 1); - -#ifdef APALIS_TK1_PCIE_EVALBOARD_INIT -#define PEX_PERST_N TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */ -#define RESET_MOCI_CTRL TEGRA_GPIO(U, 4) - - /* Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis Evaluation - Board */ +#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT gpio_request(PEX_PERST_N, "PEX_PERST_N"); gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL"); - gpio_direction_output(PEX_PERST_N, 0); - gpio_direction_output(RESET_MOCI_CTRL, 0); - /* Must be asserted for 100 ms after power and clocks are stable */ - mdelay(100); - 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 */ - mdelay(1); - gpio_set_value(RESET_MOCI_CTRL, 1); -#endif /* APALIS_T30_PCIE_EVALBOARD_INIT */ +#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ return 0; } + +void tegra_pcie_board_port_reset(struct tegra_pcie_port *port) +{ + int index = tegra_pcie_port_index_of_port(port); + if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */ + struct udevice *pmic; + int err; + + err = as3722_init(&pmic); + if (err) { + error("failed to initialize AS3722 PMIC: %d\n", err); + return; + } + + /* Reset I210 Gigabit Ethernet Controller */ + gpio_direction_output(LAN_RESET_N, 0); + + /* + * Make sure we don't get any back feeding from DEV_OFF_N resp. + * LAN_WAKE_N + */ + gpio_direction_output(LAN_DEV_OFF_N, 0); + gpio_direction_output(LAN_WAKE_N, 0); + + /* Make sure LDO9 and LDO10 are initially enabled @ 0V */ + err = as3722_ldo_enable(pmic, 9); + if (err < 0) { + error("failed to enable LDO9: %d\n", err); + return; + } + err = as3722_ldo_enable(pmic, 10); + if (err < 0) { + error("failed to enable LDO10: %d\n", err); + return; + } + err = as3722_ldo_set_voltage(pmic, 9, 0x80); + if (err < 0) { + error("failed to set LDO9 voltage: %d\n", err); + return; + } + err = as3722_ldo_set_voltage(pmic, 10, 0x80); + if (err < 0) { + error("failed to set LDO10 voltage: %d\n", err); + return; + } + + /* 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 + */ + err = as3722_ldo_set_voltage(pmic, 9, 0xff); + if (err < 0) { + error("failed to set LDO9 voltage: %d\n", err); + return; + } + err = as3722_ldo_set_voltage(pmic, 10, 0xff); + if (err < 0) { + error("failed to set LDO10 voltage: %d\n", err); + return; + } + + /* + * Must be asserted for 100 ms after power and clocks are stable + */ + mdelay(100); + + gpio_set_value(LAN_RESET_N, 1); + } else if (index == 0) { /* Apalis PCIe */ +#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT + /* + * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis + * Evaluation Board + */ + gpio_direction_output(PEX_PERST_N, 0); + gpio_direction_output(RESET_MOCI_CTRL, 0); + + /* + * Must be asserted for 100 ms after power and clocks are stable + */ + mdelay(100); + + 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 + */ + mdelay(1); + gpio_set_value(RESET_MOCI_CTRL, 1); +#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ + } +} #endif /* CONFIG_PCI_TEGRA */ void start_cpu_fan(void) diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index 430270ec292..53ba46cd76d 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -19,6 +19,7 @@ #include <fdtdec.h> #include <malloc.h> #include <pci.h> +#include <pci_tegra.h> #include <power-domain.h> #include <reset.h> @@ -898,7 +899,7 @@ static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) return ret; } -static void tegra_pcie_port_reset(struct tegra_pcie_port *port) +void tegra_pcie_port_reset(struct tegra_pcie_port *port) { unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); unsigned long value; @@ -915,6 +916,16 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port) afi_writel(port->pcie, value, ctrl); } +int tegra_pcie_port_index_of_port(struct tegra_pcie_port *port) +{ + return port->index; +} + +void __weak tegra_pcie_board_port_reset(struct tegra_pcie_port *port) +{ + tegra_pcie_port_reset(port); +} + static void tegra_pcie_port_enable(struct tegra_pcie_port *port) { struct tegra_pcie *pcie = port->pcie; @@ -933,7 +944,7 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) afi_writel(pcie, value, ctrl); - tegra_pcie_port_reset(port); + tegra_pcie_board_port_reset(port); if (soc->force_pca_enable) { value = rp_readl(port, RP_VEND_CTL2); @@ -984,7 +995,7 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port) } while (--timeout); retry: - tegra_pcie_port_reset(port); + tegra_pcie_board_port_reset(port); } while (--retries); return false; diff --git a/include/pci_tegra.h b/include/pci_tegra.h new file mode 100644 index 00000000000..2bf1f59061d --- /dev/null +++ b/include/pci_tegra.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2017 Toradex, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +struct tegra_pcie_port; + +int tegra_pcie_port_index_of_port(struct tegra_pcie_port *port); + +void tegra_pcie_port_reset(struct tegra_pcie_port *port); |