Hi again,

On 5/11/2026 10:30 AM, Jonas Karlman wrote:
> Hi,
> 
> On 5/11/2026 9:49 AM, Ye Li wrote:
>> SD initialization failure happens with some UHS-I SD cards on
>> iMX8MM/iMX93/iMX91 EVK after
>> commit 4fcba5d556b4 ("regulator: implement basic reference counter").
>> When sending operation condition to SD card, the OCR does not return
>> correct status. The root cause is regulator on/off delay is missed
>> in MMC power cycle with above commit, so SD card is not completely
>> power off.
>>
>> When SD startup, the sequence of MMC power cycle is:
>> mmc_power_init(get vmmc_supply dev) -> mmc_power_off -> udelay(2000)
>> -> mmc_power_on
>>
>> Before above commit, as a fixed regulator, the GPIO is set as:
>>   GPIO inactive (in mmc_power_init) ->
>>   GPIO inactive and delay off-on-delay-us (in mmc_power_off) ->
>>   udelay(2000) ->
>>   GPIO active (in mmc_power_on)
>>
>> After the commit:
>>   GPIO inactive (in mmc_power_init) ->
>>   enable_count is 0, regulator_set_enable returns -EALREADY immediately,
>>       so GPIO is inactive but No off-on-delay-us (in mmc_power_off) ->

If the regulator is off at boot-on then this is working as intended.

However, if probing the regulator turns it off and that requires a
off-on-delay-us delay, maybe you are missing a regulator-boot-on
property to indicate that the regulator is on at boot/reset. That should
also align the enable count with boot-on state of the regulator.

Looking at the kernel the off-on-delay-us is applied before a regulator
is enabled, not after it is disabled like in U-Boot. Maybe U-Boot should
do something similar, in simplest form always udelay off-on-delay-us
before the regulator is enabled.

>>   udelay(2000) ->
>>   GPIO active (in mmc_power_on)
>>
>> Add the on/off delay and startup delay after GPIO request in
>> regulator_common_of_to_plat which is called in regulator device probing.
>> So in mmc_power_init, after GPIO is set to default inactive, the
>> off-on-delay-us is applied.
>>
>> Signed-off-by: Ye Li <[email protected]>
>> ---
>>  drivers/power/regulator/regulator_common.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/power/regulator/regulator_common.c 
>> b/drivers/power/regulator/regulator_common.c
>> index 85af8d599ad..158284a3309 100644
>> --- a/drivers/power/regulator/regulator_common.c
>> +++ b/drivers/power/regulator/regulator_common.c
>> @@ -46,6 +46,12 @@ int regulator_common_of_to_plat(struct udevice *dev,
>>                      dev_read_u32_default(dev, "u-boot,off-on-delay-us", 0);
>>      }
>>  
>> +    if ((flags & GPIOD_IS_OUT_ACTIVE) && plat->startup_delay_us)
>> +            udelay(plat->startup_delay_us);
>> +
>> +    if (!(flags & GPIOD_IS_OUT_ACTIVE) && plat->off_on_delay_us)
>> +            udelay(plat->off_on_delay_us);
> 
> regulator_common_of_to_plat() is for parsing the values, no udelay()
> should be applied here.
> 
> regulator_common_set_enable() applies udelay() when the regulator is
> enabled.

Or disabled.

> 
> Does your regulator .get_enable() ops not being called or does it not
> implement its own udelay() based on parsed values?

I meant set_enable() here :-)

Regards,
Jonas

> 
> Regards,
> Jonas
> 
>> +
>>      return 0;
>>  }
>>  
> 

Reply via email to