[U-Boot] [PATCH v2 0/6] fix apalis-tk1 pcie gigabit ethernet operation

This series addresses a gigabit Ethernet reliability issue as observed on Apalis TK1 related to a PCIe reset timing violation.
This series depends on Simon's work available at u-boot-dm/master plus my previous series "move apalis t30/tk1, colibri t20/t30 to livetree".
This series is available at http://git.toradex.com/cgit/u-boot-toradex.git/log/?h=for-next
Changes in v2: - Add Simon's reviewed-by. - New bug fix. - Incorporate Stephen's review feedback by introducing a tegra_pcie_port_index_of_port() function as well as a board-specific reset override function. - Add Simon's reviewed-by.
Marcel Ziswiler (5): apalis-tk1: add missing as3722 gpio0 configuration power: as3722: fix ldo_get/set_enable for ldo index bigger than 7 pci: tegra: introduce weak tegra_pcie_board_port_reset() function power: as3722: add as3722_ldo_set_voltage signature to header file apalis-tk1: fix pcie reset for reliable gigabit ethernet operation
Sanchayan Maity (1): configs: apalis-tk1: fix boot failure using ext4 rootfs
arch/arm/dts/tegra124-apalis.dts | 6 +- board/toradex/apalis-tk1/apalis-tk1.c | 247 ++++++++++++++++++----------- drivers/pci/pci_tegra.c | 28 +++- drivers/power/regulator/as3722_regulator.c | 16 +- include/configs/apalis-tk1.h | 5 +- include/pci_tegra.h | 9 ++ include/power/as3722.h | 4 +- 7 files changed, 206 insertions(+), 109 deletions(-) create mode 100644 include/pci_tegra.h

From: Sanchayan Maity maitysanchayan@gmail.com
Trying to boot from an ext4 rootfs fails due to us defaulting to ext3. While the downstream T20/T30 L4T kernel has issues with ext4 later TK1 L4T should work just fine with it. Hence enable ext4 for sdboot and usbboot on TK1.
Signed-off-by: Sanchayan Maity maitysanchayan@gmail.com Acked-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
Changes in v2: None
include/configs/apalis-tk1.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/configs/apalis-tk1.h b/include/configs/apalis-tk1.h index d6b226c..bb46768 100644 --- a/include/configs/apalis-tk1.h +++ b/include/configs/apalis-tk1.h @@ -87,7 +87,7 @@ "&& setenv dtbparam ${fdt_addr_r}\0"
#define SD_BOOTCMD \ - "sdargs=ip=off root=/dev/mmcblk1p2 rw rootfstype=ext3 rootwait\0" \ + "sdargs=ip=off root=/dev/mmcblk1p2 rw rootfstype=ext4 rootwait\0" \ "sdboot=run setup; setenv bootargs ${defargs} ${sdargs} ${setupargs} " \ "${vidargs}; echo Booting from SD card in 8bit slot...; " \ "run sddtbload; load mmc 1:1 ${kernel_addr_r} " \ @@ -98,7 +98,7 @@ "&& setenv dtbparam ${fdt_addr_r}\0"
#define USB_BOOTCMD \ - "usbargs=ip=off root=/dev/sda2 rw rootfstype=ext3 rootwait\0" \ + "usbargs=ip=off root=/dev/sda2 rw rootfstype=ext4 rootwait\0" \ "usbboot=run setup; setenv bootargs ${defargs} ${setupargs} " \ "${usbargs} ${vidargs}; echo Booting from USB stick...; " \ "usb start && run usbdtbload; load usb 0:1 ${kernel_addr_r} " \

From: Marcel Ziswiler marcel.ziswiler@toradex.com
As the AS3722 GPIO0 is also a not connected on our Apalis TK1 module explicitly configure it to high-impedance as well.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Reviewed-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add Simon's reviewed-by.
arch/arm/dts/tegra124-apalis.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/tegra124-apalis.dts b/arch/arm/dts/tegra124-apalis.dts index 2fc0384..fe08d3e 100644 --- a/arch/arm/dts/tegra124-apalis.dts +++ b/arch/arm/dts/tegra124-apalis.dts @@ -1683,9 +1683,9 @@ bias-pull-up; };
- gpio1_3_4_5_6 { - pins = "gpio1", "gpio3", "gpio4", - "gpio5", "gpio6"; + gpio0_1_3_4_5_6 { + pins = "gpio0", "gpio1", "gpio3", + "gpio4", "gpio5", "gpio6"; bias-high-impedance; }; };

From: Marcel Ziswiler marcel.ziswiler@toradex.com
Fix ldo_get_enable() and ldo_set_enable() functions for LDOs with an index > 7. Turns out there are actually two separate AS3722_LDO_CONTROL registers AS3722_LDO_CONTROL0 and AS3722_LDO_CONTROL1. Actually make use of both. While at it also actually use the enable parameter of the ldo_set_enable() function which now truly allows disabling as opposed to only enabling LDOs.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
Changes in v2: - New bug fix.
drivers/power/regulator/as3722_regulator.c | 16 ++++++++++++++-- include/power/as3722.h | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/power/regulator/as3722_regulator.c b/drivers/power/regulator/as3722_regulator.c index 3e1e6f1..eb4c465 100644 --- a/drivers/power/regulator/as3722_regulator.c +++ b/drivers/power/regulator/as3722_regulator.c @@ -69,10 +69,16 @@ static int ldo_set_value(struct udevice *dev, int uvolt) static int ldo_set_enable(struct udevice *dev, bool enable) { struct udevice *pmic = dev_get_parent(dev); + u8 ctrl_reg = AS3722_LDO_CONTROL0; int ldo = dev->driver_data; int ret;
- ret = pmic_clrsetbits(pmic, AS3722_LDO_CONTROL, 0, 1 << ldo); + if (ldo > 7) { + ctrl_reg = AS3722_LDO_CONTROL1; + ldo -= 8; + } + + ret = pmic_clrsetbits(pmic, ctrl_reg, !enable << ldo, enable << ldo); if (ret < 0) { debug("%s: failed to write LDO control register: %d", __func__, ret); @@ -85,10 +91,16 @@ static int ldo_set_enable(struct udevice *dev, bool enable) static int ldo_get_enable(struct udevice *dev) { struct udevice *pmic = dev_get_parent(dev); + u8 ctrl_reg = AS3722_LDO_CONTROL0; int ldo = dev->driver_data; int ret;
- ret = pmic_reg_read(pmic, AS3722_LDO_CONTROL); + if (ldo > 7) { + ctrl_reg = AS3722_LDO_CONTROL1; + ldo -= 8; + } + + ret = pmic_reg_read(pmic, ctrl_reg); if (ret < 0) { debug("%s: failed to read SD control register: %d", __func__, ret); diff --git a/include/power/as3722.h b/include/power/as3722.h index cb4b188..b3dc7b6 100644 --- a/include/power/as3722.h +++ b/include/power/as3722.h @@ -14,7 +14,8 @@ #define AS3722_SD_VOLTAGE(n) (0x00 + (n)) #define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) #define AS3722_SD_CONTROL 0x4d -#define AS3722_LDO_CONTROL 0x4e +#define AS3722_LDO_CONTROL0 0x4e +#define AS3722_LDO_CONTROL1 0x4f #define AS3722_ASIC_ID1 0x90 #define AS3722_ASIC_ID2 0x91

On 8 August 2017 at 06:42, Marcel Ziswiler marcel@ziswiler.com wrote:
From: Marcel Ziswiler marcel.ziswiler@toradex.com
Fix ldo_get_enable() and ldo_set_enable() functions for LDOs with an index > 7. Turns out there are actually two separate AS3722_LDO_CONTROL registers AS3722_LDO_CONTROL0 and AS3722_LDO_CONTROL1. Actually make use of both. While at it also actually use the enable parameter of the ldo_set_enable() function which now truly allows disabling as opposed to only enabling LDOs.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
Changes in v2:
- New bug fix.
drivers/power/regulator/as3722_regulator.c | 16 ++++++++++++++-- include/power/as3722.h | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Marcel Ziswiler marcel.ziswiler@toradex.com
Introduce a weak tegra_pcie_board_port_reset() function by default calling the existing tegra_pcie_port_reset() function. Additionally add a tegra_pcie_port_index_of_port() function to retrieve the specific PCIe port index if required. This allows overriding the PCIe port reset functionality from board specific code as e.g. required for Apalis T30 and Apalis TK1.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
Changes in v2: - Incorporate Stephen's review feedback by introducing a tegra_pcie_port_index_of_port() function as well as a board-specific reset override function.
drivers/pci/pci_tegra.c | 28 ++++++++++++++++++++-------- include/pci_tegra.h | 9 +++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 include/pci_tegra.h
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index cb5cf8b..cb0a30c 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -18,6 +18,7 @@ #include <errno.h> #include <malloc.h> #include <pci.h> +#include <pci_tegra.h> #include <power-domain.h> #include <reset.h>
@@ -893,21 +894,32 @@ 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(void *port) { - unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); + unsigned long ctrl = tegra_pcie_port_get_pex_ctrl( + (struct tegra_pcie_port *)port); unsigned long value;
/* pulse reset signel */ - value = afi_readl(port->pcie, ctrl); + value = afi_readl(((struct tegra_pcie_port *)port)->pcie, ctrl); value &= ~AFI_PEX_CTRL_RST; - afi_writel(port->pcie, value, ctrl); + afi_writel(((struct tegra_pcie_port *)port)->pcie, value, ctrl);
udelay(2000);
- value = afi_readl(port->pcie, ctrl); + value = afi_readl(((struct tegra_pcie_port *)port)->pcie, ctrl); value |= AFI_PEX_CTRL_RST; - afi_writel(port->pcie, value, ctrl); + afi_writel(((struct tegra_pcie_port *)port)->pcie, value, ctrl); +} + +int tegra_pcie_port_index_of_port(void *port) +{ + return ((struct tegra_pcie_port *)port)->index; +} + +void __weak tegra_pcie_board_port_reset(void *port) +{ + tegra_pcie_port_reset(port); }
static void tegra_pcie_port_enable(struct tegra_pcie_port *port) @@ -928,7 +940,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); @@ -979,7 +991,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 0000000..13ee908 --- /dev/null +++ b/include/pci_tegra.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2017 Toradex, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +int tegra_pcie_port_index_of_port(void *port); + +void tegra_pcie_port_reset(void *port);

On 08/08/2017 06:42 AM, Marcel Ziswiler wrote:
From: Marcel Ziswiler marcel.ziswiler@toradex.com
Introduce a weak tegra_pcie_board_port_reset() function by default calling the existing tegra_pcie_port_reset() function. Additionally add a tegra_pcie_port_index_of_port() function to retrieve the specific PCIe port index if required. This allows overriding the PCIe port reset functionality from board specific code as e.g. required for Apalis T30 and Apalis TK1.
diff --git a/include/pci_tegra.h b/include/pci_tegra.h
+int tegra_pcie_port_index_of_port(void *port);
+void tegra_pcie_port_reset(void *port);
The parameter to these functions should be "struct tegra_pcie_port *port" for type-safety and to avoid all the casts in the implementation. Since this is a pointer, it doesn't matter that the board-level callers don't have the full type defined since they don't dereference the pointer, just pass it around. All you need to do is add the following to the header before the function prototypes:
struct tegra_pcie_port;

On Tue, 2017-08-08 at 10:09 -0600, Stephen Warren wrote:
On 08/08/2017 06:42 AM, Marcel Ziswiler wrote:
From: Marcel Ziswiler marcel.ziswiler@toradex.com
Introduce a weak tegra_pcie_board_port_reset() function by default calling the existing tegra_pcie_port_reset() function. Additionally add a tegra_pcie_port_index_of_port() function to retrieve the specific PCIe port index if required. This allows overriding the PCIe port reset functionality from board specific code as e.g. required for Apalis T30 and Apalis TK1. diff --git a/include/pci_tegra.h b/include/pci_tegra.h +int tegra_pcie_port_index_of_port(void *port);
+void tegra_pcie_port_reset(void *port);
The parameter to these functions should be "struct tegra_pcie_port *port" for type-safety and to avoid all the casts in the implementation. Since this is a pointer, it doesn't matter that the board-level callers don't have the full type defined since they don't dereference the pointer, just pass it around. All you need to do is add the following to the header before the function prototypes:
struct tegra_pcie_port;
Yes, thanks. Of course that makes more sense. I will do that in a v3.

From: Marcel Ziswiler marcel.ziswiler@toradex.com
Just like the already present as3722_sd_set_voltage() add the currently missing signature of the as3722_ldo_set_voltage() function to its header file.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Reviewed-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add Simon's reviewed-by.
include/power/as3722.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/power/as3722.h b/include/power/as3722.h index b3dc7b6..128df49 100644 --- a/include/power/as3722.h +++ b/include/power/as3722.h @@ -26,5 +26,6 @@ #define AS3722_GPIO_CONTROL_INVERT (1 << 7)
int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 value); +int as3722_ldo_set_voltage(struct udevice *dev, unsigned int ldo, u8 value);
#endif /* __POWER_AS3722_H__ */

From: Marcel Ziswiler marcel.ziswiler@toradex.com
It turns out that the current PCIe reset implementation in the PCIe board init function is not quite working reliably due to PCIe reset timing violations. Fix this by overriding the tegra_pcie_board_port_reset() function.
Also allow optionally bringing up the PCIe switch as found on the Apalis Evaluation board. Note however that the Apalis PCIe port is also left disabled in the device tree by default.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
Changes in v2: None
board/toradex/apalis-tk1/apalis-tk1.c | 247 +++++++++++++++++++++------------- include/configs/apalis-tk1.h | 1 + 2 files changed, 155 insertions(+), 93 deletions(-)
diff --git a/board/toradex/apalis-tk1/apalis-tk1.c b/board/toradex/apalis-tk1/apalis-tk1.c index 5de61e7..ad3f5ec 100644 --- a/board/toradex/apalis-tk1/apalis-tk1.c +++ b/board/toradex/apalis-tk1/apalis-tk1.c @@ -5,17 +5,26 @@ */
#include <common.h> +#include <dm.h> #include <asm/arch-tegra/ap.h> #include <asm/gpio.h> #include <asm/io.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> +#include <pci_tegra.h> #include <power/as3722.h> +#include <power/pmic.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 APALIS_TK1_PCIE_EVALBOARD_INIT +#define PEX_PERST_N TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */ +#define RESET_MOCI_CTRL TEGRA_GPIO(U, 4) +#endif /* APALIS_TK1_PCIE_EVALBOARD_INIT */
int arch_misc_init(void) { @@ -59,123 +68,175 @@ void pinmux_init(void) }
#ifdef CONFIG_PCI_TEGRA -int tegra_pcie_board_init(void) +/* TODO: Convert to driver model */ +static int as3722_sd_enable(struct udevice *pmic, unsigned int sd) { - /* TODO: Convert to driver model - struct udevice *pmic; int err;
- err = as3722_init(&pmic); + if (sd > 6) + return -EINVAL; + + err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd); if (err) { - error("failed to initialize AS3722 PMIC: %d\n", err); + error("failed to update SD control register: %d", err); return err; }
- err = as3722_sd_enable(pmic, 4); - if (err < 0) { - error("failed to enable SD4: %d\n", err); - return err; - } + return 0; +}
- err = as3722_sd_set_voltage(pmic, 4, 0x24); - if (err < 0) { - error("failed to set SD4 voltage: %d\n", err); - return err; - } +/* TODO: Convert to driver model */ +static int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) +{ + int err; + u8 ctrl_reg = AS3722_LDO_CONTROL0;
- err = as3722_gpio_configure(pmic, 1, AS3722_GPIO_OUTPUT_VDDH | - AS3722_GPIO_INVERT); - if (err < 0) { - error("failed to configure GPIO#1 as output: %d\n", err); - return err; - } + if (ldo > 11) + return -EINVAL;
- err = as3722_gpio_direction_output(pmic, 2, 1); - if (err < 0) { - error("failed to set GPIO#2 high: %d\n", err); - return err; + if (ldo > 7) { + ctrl_reg = AS3722_LDO_CONTROL1; + ldo -= 8; } - */
- /* Reset I210 Gigabit Ethernet Controller */ - 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 */ - /* TODO: Convert to driver model - 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); + err = pmic_clrsetbits(pmic, ctrl_reg, 0, 1 << ldo); + if (err) { + error("failed to update LDO control register: %d", err); return err; } - */
- mdelay(100); + return 0; +}
- /* Make sure controller gets enabled by disabling DEV_OFF_N */ - gpio_set_value(TEGRA_GPIO(O, 6), 1); +int tegra_pcie_board_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_as3722), &dev); + if (ret) { + debug("%s: Failed to find PMIC\n", __func__); + return ret; + }
- /* Enable LDO9 and LDO10 for +V3.3_ETH on patched prototypes */ - /* TODO: Convert to driver model - err = as3722_ldo_set_voltage(pmic, 9, 0xff); - if (err < 0) { - error("failed to set LDO9 voltage: %d\n", err); - return err; + ret = as3722_sd_enable(dev, 4); + if (ret < 0) { + error("failed to enable SD4: %d\n", ret); + return ret; } - err = as3722_ldo_set_voltage(pmic, 10, 0xff); - if (err < 0) { - error("failed to set LDO10 voltage: %d\n", err); - return err; + + ret = as3722_sd_set_voltage(dev, 4, 0x24); + if (ret < 0) { + error("failed to set SD4 voltage: %d\n", ret); + return ret; } - */
- mdelay(100); - gpio_set_value(LAN_RESET_N, 1); + gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N"); + gpio_request(LAN_RESET_N, "LAN_RESET_N"); + gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
#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 */ 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 /* APALIS_TK1_PCIE_EVALBOARD_INIT */
return 0; } + +void tegra_pcie_board_port_reset(void *port) +{ + int index = tegra_pcie_port_index_of_port(port); + if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_as3722), + &dev); + if (ret) { + debug("%s: Failed to find PMIC\n", __func__); + 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 */ + ret = as3722_ldo_enable(dev, 9); + if (ret < 0) { + error("failed to enable LDO9: %d\n", ret); + return; + } + ret = as3722_ldo_enable(dev, 10); + if (ret < 0) { + error("failed to enable LDO10: %d\n", ret); + return; + } + ret = as3722_ldo_set_voltage(dev, 9, 0x80); + if (ret < 0) { + error("failed to set LDO9 voltage: %d\n", ret); + return; + } + ret = as3722_ldo_set_voltage(dev, 10, 0x80); + if (ret < 0) { + error("failed to set LDO10 voltage: %d\n", ret); + 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 + */ + ret = as3722_ldo_set_voltage(dev, 9, 0xff); + if (ret < 0) { + error("failed to set LDO9 voltage: %d\n", ret); + return; + } + ret = as3722_ldo_set_voltage(dev, 10, 0xff); + if (ret < 0) { + error("failed to set LDO10 voltage: %d\n", ret); + 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 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 /* APALIS_TK1_PCIE_EVALBOARD_INIT */ + } +} #endif /* CONFIG_PCI_TEGRA */ diff --git a/include/configs/apalis-tk1.h b/include/configs/apalis-tk1.h index bb46768..20d0c4d 100644 --- a/include/configs/apalis-tk1.h +++ b/include/configs/apalis-tk1.h @@ -40,6 +40,7 @@ /* PCI host support */ #undef CONFIG_PCI_SCAN_SHOW #define CONFIG_CMD_PCI +#undef APALIS_TK1_PCIE_EVALBOARD_INIT
/* PCI networking support */ #define CONFIG_E1000_NO_NVM
participants (4)
-
Marcel Ziswiler
-
Marcel Ziswiler
-
Simon Glass
-
Stephen Warren