This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM572x: SD Card UHS mode not working after reboot

Other Parts Discussed in Thread: AM5728

Hi,

I'm using a custom AM5728 hardware running the Linux SDK 3.0.0.4 Kernel. We use a UHS 1 SD card which is connected to the mmc1 interface. The I/O voltage can be controlled independently changed while the supply voltage is always 3.3V (like the AM572x Industrial EVM).

After power-up, the SD card gets correctly recognized with UHS mode:

[    2.203581] mmc0: new ultra high speed SDR104 SDHC card at address aaaa

But after reboot ("init 6"), the SD card only works in HS mode:

[    2.028148] mmc0: new high speed SDHC card at address aaaa

I think the problem is that the SD Card supply voltage doesn't get turned off during shutdown, because it can't be controlled independently.

Now, I implemented a different reset function which initiates a software reset to the PMIC. The PMIC then automatically performs a cold-reset sequence, powering off all supplies and turning them on again. The SD Card the works in UHS mode after a reboot.

drivers/mfs/palmas.c:

...

#include <linux/reboot.h>
#include <asm/system_misc.h>

static void palmas_pm_reset(enum reboot_mode reboot_mode, const char *cmd)
{
    unsigned int addr;
    int ret, slave;

    if (!palmas_dev)
        return;

    slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE);
    addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL);

    ret = regmap_update_bits(
            palmas_dev->regmap[slave],
            addr,
            PALMAS_DEV_CTRL_SW_RST,
            PALMAS_DEV_CTRL_SW_RST);

    if (ret)
        pr_err("%s: Unable to write to DEV_CTRL_SW_RST: %d\n",
                __func__, ret);
}

...

static int palmas_i2c_probe(struct i2c_client *i2c,
                const struct i2c_device_id *id)
{
...
    /*
     * If we are probing with DT do this the DT way and return here
     * otherwise continue and add devices using mfd helpers.
     */
    if (node) {
        ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
        if (ret < 0) {
            goto err_irq;
        } else if (pdata->pm_off) {
            palmas_dev = palmas;
            if (!pm_power_off)
                pm_power_off = palmas_power_off;
            arm_pm_restart = palmas_pm_reset;
        }
    }

The function pointer arm_pm_restart is normally initialized with omap44xx_restart which executes a warm-reset in omap4_prminst_global_warm_sw_reset(). I overwrite the pointer with my new implementation.

What do the experts think about this?

Thanks,
Ralf

  • Update:

    It turned out that this fix doesn't work for other reset sources which cause a warm-reset, for example watchdog or resetn input.

    Now, I implemented a different solution in U-Boot. I use a PMIC backup register to store a flag which decides if the PMIC should do a cold-reset after the next reboot. I implemented the fix in do_board_detect() - SPL (board.c):

    #ifdef CONFIG_SPL_BUILD
    /* No env to setup for SPL */
    static inline void setup_board_eeprom_env(void) { }

    /* Override function to read eeprom information */
    void do_board_detect(void)
    {
        int rc;
        u8 reg;

        rc = ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
                      CONFIG_EEPROM_CHIP_ADDRESS);
        if (rc)
            printf("ti_i2c_eeprom_init failed %d\n", rc);

        /* Read PMIC backup register 0, bit 0 */
        palmas_i2c_read_u8(TPS65903X_CHIP_P1, 0x18, &reg);
        if (reg & 1)
        {
            /* Cold-reset required, reset the flag first */
            reg &= ~1;
            palmas_i2c_write_u8(TPS65903X_CHIP_P1, 0x18, reg);

            /* Restart device by writing a 1 to the SW_RST bit */
            palmas_i2c_write_u8(TPS65903X_CHIP_P1, 0xA0, 3);
        }
        else
        {
            /* next reboot requires a cold-reset, set the flag to 1 */
            reg |= 1;
            palmas_i2c_write_u8(TPS65903X_CHIP_P1, 0x18, reg);
        }
    }

    #else    /* CONFIG_SPL_BUILD */
    ...

    I also think it's better to have the fix in board-specific code in U-Boot than to have it in generic kernel code.

    Ralf

  • Hi Ralf,

    Thanks for sharing this info.

    Could you please let us know if this issue (SD card not correctly recognized with UHS mode after reboot) is specific for your custom board or is also valid for AM57x TI boards?

    Regards,
    Pavel
  • Hi Pavel,

    I don't have any TI boards to verify the behaviour, maybe someone else can do this. I think the first revision of the GP EVM also doesn't support UHS mode, because the SD card supply is connected to the I/O voltage rail. I'm using a SanDsik 32GB MicroSDHC Class 10 UHS-I card.

    Ralf

  • Hi,

    After changing to a SD card with 16 GB of the same type, I discovered a kernel boot problem during voltage switching to 1.8V:

    ...
    [    2.048429] omap_hsmmc 4809c000.mmc: card busy
    [    2.052891] mmc0: Signal voltage switch failed, power cycling card
    [    2.059143] mmc_power_cycle()
    [    2.083781] Waiting for root device PARTUUID=00000000-02...
    [    2.119794] mmc0: error -110 whilst initialising SD card

    The boot process stops there.

    It turns out that the card seems to have a problem with the configuration of the CLK pin which has the pull-up resistor enabled. The pull-ups are defined in the device tree for each mode, e.g. am572x-idk.dts:

    &dra7_pmx_core {
        mmc1_pins_default: mmc1_pins_default {
            pinctrl-single,pins = <
                0x354 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
                0x358 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
                0x35c (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
                0x360 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
                0x364 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
                0x368 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
            >;
        };

        mmc1_pins_sdr12: pinmux_mmc1_sdr12_pins {
            pinctrl-single,pins = <
                0x354 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc1_clk.clk */
                0x358 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc1_cmd.cmd */
                0x35c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc1_dat0.dat0 */
    ...

    After removing the _PULLUP part, the voltage switching seems to work properly again.

    Ralf

  • Hi,

    Update:
    After using the PMIC Cold-Reset Workaround in U-Boot for some time, I noticed that the RBL sometimes seems to get stuck accessing the SD card after the reset. I'm not sure why, but the PMIC comes out of the Power-Off state very quickly again, maybe too early before all voltages are settled down. I couldn't find any way to adjust the power off state time.

    We are now using a new hardware revision where we can control the SD card power supply by using a gpio pin. After turning SD card power off and on within U-Boot, the UHS mode seems to work properly after a reset.

    Ralf