Hi Wolfram, On Wed, Apr 23, 2025 at 9:26 AM Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> wrote: > > > > Well, frankly, this is the only test I tried and, yes, it did work for > > me. Will check 'incomplete_write_byte' later today. I will also check if > > I need to run the tests more often. I did not do an endless loop. > > Both tests work for me, even in an endless loop. I also get the desired > signal outputs checking with the logic analyzer. > > Here is the branch I used: > > git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/g3s/riic-recovery-experimental > I prepared a setup on SMARC2 RZ/G3S and I can confirm it is working (but this is failing on SMARC RZ/G2L I'll look further into this) For the SMARC2 RZ/G3S to make sure the I2C GPIO pins behave as opendrain I have the below patch for pinctrl drivers/pinctrl/renesas/pinctrl-rzg2l.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 78fa08ff0faa..04bbc7499ce9 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -167,6 +167,7 @@ #define NOD_MASK 0x01 #define SMT_MASK 0x01 +#define PM_HI_Z 0x0 #define PM_INPUT 0x1 #define PM_OUTPUT 0x2 @@ -176,6 +177,9 @@ #define RZG2L_TINT_MAX_INTERRUPT 32 #define RZG2L_PACK_HWIRQ(t, i) (((t) << 16) | (i)) +#define GPIO8_P8_2 66 +#define GPIO8_P8_3 67 + /* Custom pinconf parameters */ #define RENESAS_RZV2H_PIN_CONFIG_OUTPUT_IMPEDANCE (PIN_CONFIG_END + 1) @@ -1703,6 +1707,10 @@ static int rzg2l_gpio_request(struct gpio_chip *chip, unsigned int offset) pctrl->data->pmc_writeb(pctrl, reg8, PMC(off)); spin_unlock_irqrestore(&pctrl->lock, flags); + if (offset == GPIO8_P8_2 || offset == GPIO8_P8_3) { + rzg2l_rmw_pin_config(pctrl, PUPD(off), bit, PUPD_MASK, 1); + rzg2l_rmw_pin_config(pctrl, IOLH(off), bit, IOLH_MASK, 0x3); + } return 0; } @@ -1722,7 +1730,10 @@ static void rzg2l_gpio_set_direction(struct rzg2l_pinctrl *pctrl, u32 offset, reg16 = readw(pctrl->base + PM(off)); reg16 &= ~(PM_MASK << (bit * 2)); - reg16 |= (output ? PM_OUTPUT : PM_INPUT) << (bit * 2); + if (offset == GPIO8_P8_2 || offset == GPIO8_P8_3) + reg16 |= (output ? PM_OUTPUT : PM_HI_Z) << (bit * 2); + else + reg16 |= (output ? PM_OUTPUT : PM_INPUT) << (bit * 2); writew(reg16, pctrl->base + PM(off)); spin_unlock_irqrestore(&pctrl->lock, flags); @@ -1769,6 +1780,11 @@ static void rzg2l_gpio_set(struct gpio_chip *chip, unsigned int offset, unsigned long flags; u8 reg8; + if (offset == GPIO8_P8_2 || offset == GPIO8_P8_3) { + rzg2l_gpio_set_direction(pctrl, offset, value ? 0 : 1); + return; + } + spin_lock_irqsave(&pctrl->lock, flags); reg8 = readb(pctrl->base + P(off)); @@ -1804,6 +1820,12 @@ static int rzg2l_gpio_get(struct gpio_chip *chip, unsigned int offset) reg16 = readw(pctrl->base + PM(off)); reg16 = (reg16 >> (bit * 2)) & PM_MASK; + if (offset == GPIO8_P8_2 || offset == GPIO8_P8_3) { + if (reg16 == PM_HI_Z) + return 1; + return 0; + } + if (reg16 == PM_INPUT) return !!(readb(pctrl->base + PIN(off)) & BIT(bit)); else if (reg16 == PM_OUTPUT) -- 2.49.0 Below is my loop tests for SMARC2 RZ/G3S which worked without any issues: root@smarc-rzg3s:~/i2c# cat ./i2c-inject-error.sh DEFAULT_LOOP_COUNT=500 incomplete_address_phase() { cd /sys/kernel/debug/i2c/i2c-2/ for i in {1..1}; do echo 0x1a > incomplete_address_phase; val=$(i2cget -y -f 0 0x1a 3) if [ "$?" != "0" ] || [ "${val}" != "0x0c" ]; then echo "I2C Read error (ret:$?) ${val}!!" exit 1 fi echo "Read val:${val}" i2cget -y -f 0 0x1a 3; if [ "$?" != "0" ]; then echo "I2C Read error when no error injection!!" exit 1 fi done } incomplete_write_byte() { cd /sys/kernel/debug/i2c/i2c-2/ for i in {1..1}; do val1=$(printf "0x%02x" $((RANDOM & 0xff))) val2=$(printf "0x%02x" $((RANDOM & 0xff))) i2cset -y -f 0 0x57 0 ${val1} i2cset -y -f 0 0x57 8 ${val2} r1=$(i2cget -y -f 0 0x57 0x0) if [ "$?" != "0" ] || [ "${r1}" != "${val1}" ]; then echo "1: I2C Read error (ret:$?) ${r1}!!" exit 1 fi echo 0x57 > incomplete_write_byte r1=$(i2cget -y -f 0 0x57 0x8) if [ "$?" != "0" ] || [ "${r1}" != "${val2}" ]; then echo "2: I2C Read error (ret:$?) ${r1}!!" exit 1 fi r1=$(i2cget -y -f 0 0x57 0x0) if [ "$?" != "0" ] || [ "${r1}" != "${val1}" ]; then echo "3: I2C Read error (ret:$?) ${r1}!!" exit 1 fi done } if [ ! -z "${1}" ];then DEFAULT_LOOP_COUNT=$1 fi for i in $(seq 0 $DEFAULT_LOOP_COUNT);do echo "Loop count: "$i; incomplete_address_phase incomplete_write_byte done root@smarc-rzg3s:~/i2c# Ive attached the analyzer for SMARC RZ/G2L where it is failing for `incomplete_address_phase`. Cheers, Prabhakar
Attachment:
trigger-incomplete-address.png
Description: PNG image
Attachment:
recovery-trigger.png
Description: PNG image