[PATCH] board: gateworks: venice: poll I2C lines to wait for GSC firmware

Peng Fan peng.fan at oss.nxp.com
Fri Aug 12 02:38:58 CEST 2022



On 8/12/2022 2:59 AM, Tim Harvey wrote:
> In some situations the GSC firmware where the EEPROM containing the
> model and DRAM configuration may not be ready by the time the SoC
> is ready to talk to it over I2C.
> 
> Instead of a hard delay, poll the I2C lines to wait until they are
> released to avoid the I2C drivers 'Arbitation lost' error message.
> 
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>
> ---
>   arch/arm/dts/imx8mm-venice.dts | 13 +++++++++++-
>   arch/arm/dts/imx8mn-venice.dts | 13 +++++++++++-
>   arch/arm/dts/imx8mp-venice.dts | 13 +++++++++++-
>   board/gateworks/venice/spl.c   | 39 ++++++++++++++++++++++------------
>   4 files changed, 61 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/dts/imx8mm-venice.dts b/arch/arm/dts/imx8mm-venice.dts
> index 39b030691e53..a1f292fbd9d3 100644
> --- a/arch/arm/dts/imx8mm-venice.dts
> +++ b/arch/arm/dts/imx8mm-venice.dts
> @@ -23,8 +23,11 @@
>   
>   &i2c1 {
>   	clock-frequency = <100000>;
> -	pinctrl-names = "default";
> +	pinctrl-names = "default", "gpio";
>   	pinctrl-0 = <&pinctrl_i2c1>;
> +	pinctrl-1 = <&pinctrl_i2c1_gpio>;
> +	scl-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
> +	sda-gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
>   	status = "okay";
>   
>   	gsc: gsc at 20 {
> @@ -89,6 +92,14 @@
>   		>;
>   	};
>   
> +	pinctrl_i2c1_gpio: i2c1grp-gpio-grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14	0x400001c3
> +			MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15	0x400001c3
> +		>;
> +		u-boot,dm-spl;
u-boot,dm-spl should be in xx-u-boot.dtsi

> +	};
> +
>   	pinctrl_i2c2: i2c2grp {
>   		fsl,pins = <
>   			MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL		0x400001c3
> diff --git a/arch/arm/dts/imx8mn-venice.dts b/arch/arm/dts/imx8mn-venice.dts
> index eeae225632d7..8480a2e368aa 100644
> --- a/arch/arm/dts/imx8mn-venice.dts
> +++ b/arch/arm/dts/imx8mn-venice.dts
> @@ -23,8 +23,11 @@
>   
>   &i2c1 {
>   	clock-frequency = <100000>;
> -	pinctrl-names = "default";
> +	pinctrl-names = "default", "gpio";
>   	pinctrl-0 = <&pinctrl_i2c1>;
> +	pinctrl-1 = <&pinctrl_i2c1_gpio>;
> +	scl-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
> +	sda-gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
>   	status = "okay";
>   
>   	gsc: gsc at 20 {
> @@ -89,6 +92,14 @@
>   		>;
>   	};
>   
> +	pinctrl_i2c1_gpio: i2c1grp-gpio-grp {
> +		fsl,pins = <
> +			MX8MN_IOMUXC_I2C1_SCL_GPIO5_IO14	0x400001c3
> +			MX8MN_IOMUXC_I2C1_SDA_GPIO5_IO15	0x400001c3
> +		>;
> +		u-boot,dm-spl;
Ditto.

> +	};
> +
>   	pinctrl_i2c2: i2c2grp {
>   		fsl,pins = <
>   			MX8MN_IOMUXC_I2C2_SCL_I2C2_SCL		0x400001c3
> diff --git a/arch/arm/dts/imx8mp-venice.dts b/arch/arm/dts/imx8mp-venice.dts
> index 6b1a7f1a89d4..93145b37049b 100644
> --- a/arch/arm/dts/imx8mp-venice.dts
> +++ b/arch/arm/dts/imx8mp-venice.dts
> @@ -23,8 +23,11 @@
>   
>   &i2c1 {
>   	clock-frequency = <100000>;
> -	pinctrl-names = "default";
> +	pinctrl-names = "default", "gpio";
>   	pinctrl-0 = <&pinctrl_i2c1>;
> +	pinctrl-1 = <&pinctrl_i2c1_gpio>;
> +	scl-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
> +	sda-gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
>   	status = "okay";
>   
>   	gsc: gsc at 20 {
> @@ -89,6 +92,14 @@
>   		>;
>   	};
>   
> +	pinctrl_i2c1_gpio: i2c1grp-gpio-grp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14	0x400001c3
> +			MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15	0x400001c3
> +		>;
> +		u-boot,dm-spl;

Ditto.

Regards,
Peng.

> +	};
> +
>   	pinctrl_i2c2: i2c2grp {
>   		fsl,pins = <
>   			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c3
> diff --git a/board/gateworks/venice/spl.c b/board/gateworks/venice/spl.c
> index 914a56a96f52..ae460296cb99 100644
> --- a/board/gateworks/venice/spl.c
> +++ b/board/gateworks/venice/spl.c
> @@ -16,10 +16,12 @@
>   #include <asm/arch/imx8mp_pins.h>
>   #include <asm/arch/sys_proto.h>
>   #include <asm/mach-imx/boot_mode.h>
> +#include <asm/mach-imx/mxc_i2c.h>
>   #include <asm/arch/ddr.h>
>   #include <asm-generic/gpio.h>
>   #include <dm/uclass.h>
>   #include <dm/device.h>
> +#include <dm/pinctrl.h>
>   #include <linux/delay.h>
>   #include <power/bd71837.h>
>   #include <power/mp5416.h>
> @@ -219,8 +221,8 @@ static int power_init_board(void)
>   
>   void board_init_f(ulong dummy)
>   {
> -	struct udevice *dev;
> -	int ret;
> +	struct udevice *bus, *dev;
> +	int i, ret;
>   	int dram_sz;
>   
>   	arch_cpu_init();
> @@ -251,19 +253,28 @@ void board_init_f(ulong dummy)
>   	 *
>   	 * On a board with a missing/depleted backup battery for GSC, the
>   	 * board may be ready to probe the GSC before its firmware is
> -	 * running. We will wait here indefinately for the GSC EEPROM.
> -	 */
> -#ifdef CONFIG_IMX8MN
> -	/*
> -	 * IMX8MN boots quicker than IMX8MM and exposes issue
> -	 * where because GSC I2C state machine isn't running and its
> -	 * SCL/SDA are driven low the I2C driver spams 'Arbitration lost'
> -	 * I2C errors.
> -	 *
> -	 * TODO: Put a loop here that somehow waits for I2C CLK/DAT to be high
> +	 * running. Wait here for 50ms for the GSC firmware to let go of
> +	 * the SCL/SDA lines to avoid the i2c driver spamming
> +	 * 'Arbitration lost' I2C errors
>   	 */
> -	mdelay(50);
> -#endif
> +	if (!uclass_get_device_by_seq(UCLASS_I2C, 0, &bus)) {
> +		if (!pinctrl_select_state(bus, "gpio")) {
> +			struct mxc_i2c_bus *i2c_bus = dev_get_priv(bus);
> +			struct gpio_desc *scl_gpio = &i2c_bus->scl_gpio;
> +			struct gpio_desc *sda_gpio = &i2c_bus->sda_gpio;
> +
> +			dm_gpio_set_dir_flags(scl_gpio, GPIOD_IS_IN);
> +			dm_gpio_set_dir_flags(sda_gpio, GPIOD_IS_IN);
> +			for (i = 0; i < 5; i++) {
> +				if (dm_gpio_get_value(scl_gpio) &&
> +				    dm_gpio_get_value(sda_gpio))
> +					break;
> +				mdelay(10);
> +			}
> +			pinctrl_select_state(bus, "default");
> +		}
> +	}
> +	/* Wait indefiniately until the GSC probes */
>   	while (1) {
>   		if (!uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev))
>   			break;


More information about the U-Boot mailing list