On Mon, 01 Jun 2026, Kunal Zodape <[email protected]> wrote:
> The EEPROM write path currently waits a fixed 10 ms after each page
> write to cover the maximum write-cycle time.
>
> Replace the fixed delay with ACK polling so the driver can continue as
> soon as the EEPROM finishes its internal write cycle. Since the SMU I2C
> adapter used for these EEPROM accesses does not support zero-length
> transfers, poll readiness with an offset-only dummy write.
>
> Keep the existing 10 ms timeout as the upper bound for the polling loop.
>
> Tested on MI200 (ALDEBARAN) with ras_eeprom_reset confirming clean
> write/read-back with no I2C errors.
>
> Signed-off-by: Kunal Zodape <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c | 28 +++++++++++++++-------
>  1 file changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c
> index 8cd69836dd99..53be5a31c40c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c
> @@ -153,15 +153,27 @@ static int __amdgpu_eeprom_xfer(struct i2c_adapter 
> *i2c_adap, u32 eeprom_addr,
>                       break;
>  
>               if (!read) {
> -                     /* According to EEPROM specs the length of the
> -                      * self-writing cycle, tWR (tW), is 10 ms.
> -                      *
> -                      * TODO: Use polling on ACK, aka Acknowledge
> -                      * Polling, to minimize waiting for the
> -                      * internal write cycle to complete, as it is
> -                      * usually smaller than tWR (tW).
> +                     ktime_t timeout = ktime_add_ms(ktime_get(), 10);
> +
> +                     /* Poll for ACK to detect when the self-timed
> +                      * internal write cycle has completed, as per
> +                      * Acknowledge Polling described in the AT24CM02
> +                      * datasheet, Section 7.4. The SMU I2C adapter
> +                      * used by these EEPROM paths does not support
> +                      * zero-length messages, so use an offset-only
> +                      * dummy write to probe for the ACK. The address
> +                      * pointer update is harmless because each real
> +                      * transfer reprograms it before use.
>                        */
> -                     msleep(10);
> +                     do {
> +                             r = i2c_transfer(i2c_adap, &msgs[0], 1);
> +                             if (r == 1)
> +                                     break;
> +                             usleep_range(100, 200);
> +                     } while (ktime_before(ktime_get(), timeout));
> +
> +                     if (r != 1)
> +                             break;

See poll_timeout_us().


BR,
Jani.


>               }
>       }

-- 
Jani Nikula, Intel

Reply via email to