diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index f5d2ccb..c5e270d 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -54,19 +54,21 @@ struct fsl_esdhc { uint fevt; /* Force event register */ uint admaes; /* ADMA error status register */ uint adsaddr; /* ADMA system address register */ - char reserved2[160]; /* reserved */ + char reserved2[100]; /* reserved */ + uint vendorspec; /* Vendor Specific register */ + char reserved3[59]; /* reserved */ uint hostver; /* Host controller version register */ - char reserved3[4]; /* reserved */ - uint dmaerraddr; /* DMA error address register */ char reserved4[4]; /* reserved */ - uint dmaerrattr; /* DMA error attribute register */ + uint dmaerraddr; /* DMA error address register */ char reserved5[4]; /* reserved */ + uint dmaerrattr; /* DMA error attribute register */ + char reserved6[4]; /* reserved */ uint hostcapblt2; /* Host controller capabilities register 2 */ - char reserved6[8]; /* reserved */ + char reserved7[8]; /* reserved */ uint tcr; /* Tuning control register */ - char reserved7[28]; /* reserved */ + char reserved8[28]; /* reserved */ uint sddirctl; /* SD direction control register */ - char reserved8[712]; /* reserved */ + char reserved9[712]; /* reserved */ uint scr; /* eSDHC control register */ }; @@ -342,6 +344,15 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) goto out; } + /* Switch voltage to 1.8V if CMD11 succeeded */ + if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) { + esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); + + printf("Run CMD11 1.8V switch\n"); + /* Sleep for 5 ms - max time for card to switch to 1.8V */ + udelay(5000); + } + /* Workaround for ESDHC errata ENGcm03648 */ if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { int timeout = 2500; @@ -414,6 +425,10 @@ out: while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD)) ; } + + /* If this was CMD11, then notify that power cycle is needed */ + if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) + printf("CMD11 to switch to 1.8V mode failed, card requires power cycle.\n"); } esdhc_write32(®s->irqstat, -1); @@ -509,6 +524,10 @@ static int esdhc_init(struct mmc *mmc) /* Set timout to the maximum value */ esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16); +#ifdef CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT + esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); +#endif + return 0; } |