fix apalis-tk1 pcie gigabit ethernet operation
Subsystems (3)
v3 cover 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 v3:
- Stick to struct tegra_pcie_port as suggested by Stephen.
- Introduce proper CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT Kconfig option as suggested by Stephen.
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.
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/Kconfig | 8 + board/toradex/apalis-tk1/apalis-tk1.c | 249 ++++++++++++++++++----------- drivers/pci/pci_tegra.c | 25 ++- drivers/power/regulator/as3722_regulator.c | 16 +- include/configs/apalis-tk1.h | 4 +- include/pci_tegra.h | 11 ++ include/power/as3722.h | 4 +- 8 files changed, 214 insertions(+), 109 deletions(-) create mode 100644 include/pci_tegra.h
Signature · 1 line
2.9.4
PATCH v3 1/6 configs: apalis-tk1: fix boot failure using ext4 rootfs
From: Sanchayan Maity <[email protected]>
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.
---
Changes in v3: None
Changes in v2: None
include/configs/apalis-tk1.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/configs/apalis-tk1.h +2 -2
@@ -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} " \
Signature · 1 line
2.9.4
PATCH v3 2/6 apalis-tk1: add missing as3722 gpio0 configuration
In reply to Marcel ZiswilerFrom: Marcel Ziswiler <[email protected]>
As the AS3722 GPIO0 is also a not connected on our Apalis TK1 module explicitly configure it to high-impedance as well.
---
Changes in v3: None
Changes in v2:
- Add Simon's reviewed-by.
arch/arm/dts/tegra124-apalis.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/dts/tegra124-apalis.dts +3 -3
@@ -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; }; };
Signature · 1 line
2.9.4
PATCH v3 3/6 power: as3722: fix ldo_get/set_enable for ldo index bigger than 7
In reply to Marcel ZiswilerFrom: Marcel Ziswiler <[email protected]>
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.
---
Changes in v3: None
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(-)
drivers/power/regulator/as3722_regulator.c +14 -2
@@ -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);
include/power/as3722.h +2 -1
@@ -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
Signature · 1 line
2.9.4
PATCH v3 4/6 pci: tegra: introduce weak tegra_pcie_board_port_reset() function
In reply to Marcel ZiswilerFrom: Marcel Ziswiler <[email protected]>
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.
---
Changes in v3:
- Stick to struct tegra_pcie_port as suggested by Stephen.
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 | 25 ++++++++++++++++++------- include/pci_tegra.h | 11 +++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 include/pci_tegra.h
drivers/pci/pci_tegra.c +18 -7
@@ -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,31 @@ 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;/* 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 (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)
@@ -928,7 +939,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 +990,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;
include/pci_tegra.h new file +11 -0
@@ -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);
Signature · 1 line
2.9.4
PATCH v3 4/6 pci: tegra: introduce weak tegra_pcie_board_port_reset() function
Quoted 10 lines · Marcel Ziswiler
From: Marcel Ziswiler <[email protected]>
Introduce a weak
tegra_pcie_board_port_reset()function by default calling the existingtegra_pcie_port_reset()function. Additionally add ategra_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.
drivers/pci/pci_tegra.c static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) · line 903
Quoted 10 lines
drivers/pci/pci_tegra.c +2
-2-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;/* pulse reset signel */ - value =afi_readl (port->pcie, ctrl); + value =afi_readl (((struct tegra_pcie_port *)port)->pcie, ctrl);
You don't need to add these casts any more.
PATCH v3 4/6 pci: tegra: introduce weak tegra_pcie_board_port_reset() function
Quoted 17 lines · Stephen Warren
Quoted 16 lines · Marcel Ziswiler
From: Marcel Ziswiler <[email protected]>
Introduce a weak
tegra_pcie_board_port_reset()function by default calling the existingtegra_pcie_port_reset()function. Additionally add
ategra_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.drivers/pci/pci_tegra.c +1
-1-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);
Quoted 8 lines
Quoted 6 lines
unsigned long value;
/* pulse reset signel */drivers/pci/pci_tegra.c +1
-1- value =afi_readl (port->pcie, ctrl); + value = afi_readl(((struct tegra_pcie_port *)port)->pcie,ctrl);
You don't need to add these casts any more.
Argh, yeah you are right. I could have sworn I double/triple checked it all. Just sent out a v4 with this now.
PATCH v3 5/6 power: as3722: add as3722_ldo_set_voltage signature to header file
In reply to Marcel ZiswilerFrom: Marcel Ziswiler <[email protected]>
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.
---
Changes in v3: None
Changes in v2:
- Add Simon's reviewed-by.
include/power/as3722.h | 1 + 1 file changed, 1 insertion(+)
include/power/as3722.h +1 -0
@@ -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__ */
Signature · 1 line
2.9.4
PATCH v3 6/6 apalis-tk1: fix pcie reset for reliable gigabit ethernet operation
In reply to Marcel ZiswilerFrom: Marcel Ziswiler <[email protected]>
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.
---
Changes in v3:
- Stick to struct tegra_pcie_port as suggested by Stephen.
- Introduce proper CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT Kconfig option as suggested by Stephen.
Changes in v2: None
board/toradex/apalis-tk1/Kconfig | 8 ++ board/toradex/apalis-tk1/apalis-tk1.c | 249 +++++++++++++++++++++------------- 2 files changed, 163 insertions(+), 94 deletions(-)
board/toradex/apalis-tk1/Kconfig +8 -0
@@ -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
board/toradex/apalis-tk1/apalis-tk1.c +155 -94
295 lines not on this page · raw message
Signature · 1 line
2.9.4