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