mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-21 04:00:25 +09:00
mmc: fsl_esdhc: add workaround for erratum A-011334
LS1028A SoCs are restricted in what divider values are allowed for HS400 mode. This is basically a port from the corresponding linux driver. Signed-off-by: Michael Walle <michael@walle.cc>
This commit is contained in:
parent
e9978b17cd
commit
bd7b8505f2
@ -47,6 +47,7 @@ config ARCH_LS1028A
|
|||||||
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
|
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
|
||||||
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
||||||
select SYS_FSL_ERRATUM_A050382
|
select SYS_FSL_ERRATUM_A050382
|
||||||
|
select SYS_FSL_ERRATUM_A011334
|
||||||
select RESV_RAM if GIC_V3_ITS
|
select RESV_RAM if GIC_V3_ITS
|
||||||
imply PANIC_HANG
|
imply PANIC_HANG
|
||||||
|
|
||||||
|
@ -813,3 +813,6 @@ config SYS_FSL_ERRATUM_ESDHC135
|
|||||||
|
|
||||||
config SYS_FSL_ERRATUM_ESDHC_A001
|
config SYS_FSL_ERRATUM_ESDHC_A001
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config SYS_FSL_ERRATUM_A011334
|
||||||
|
bool
|
||||||
|
@ -518,6 +518,24 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
|
|||||||
while (sdhc_clk / (div * pre_div) > clock && div < 16)
|
while (sdhc_clk / (div * pre_div) > clock && div < 16)
|
||||||
div++;
|
div++;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_A011334) &&
|
||||||
|
clock == 200000000 && mmc->selected_mode == MMC_HS_400) {
|
||||||
|
u32 div_ratio = pre_div * div;
|
||||||
|
|
||||||
|
if (div_ratio <= 4) {
|
||||||
|
pre_div = 4;
|
||||||
|
div = 1;
|
||||||
|
} else if (div_ratio <= 8) {
|
||||||
|
pre_div = 4;
|
||||||
|
div = 2;
|
||||||
|
} else if (div_ratio <= 12) {
|
||||||
|
pre_div = 4;
|
||||||
|
div = 3;
|
||||||
|
} else {
|
||||||
|
printf("unsupported clock division.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mmc->clock = sdhc_clk / pre_div / div;
|
mmc->clock = sdhc_clk / pre_div / div;
|
||||||
priv->clock = mmc->clock;
|
priv->clock = mmc->clock;
|
||||||
|
|
||||||
@ -1063,9 +1081,14 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
|
|||||||
struct fsl_esdhc_plat *plat = dev_get_plat(dev);
|
struct fsl_esdhc_plat *plat = dev_get_plat(dev);
|
||||||
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
|
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
|
||||||
struct fsl_esdhc *regs = priv->esdhc_regs;
|
struct fsl_esdhc *regs = priv->esdhc_regs;
|
||||||
|
struct mmc *mmc = &plat->mmc;
|
||||||
u32 val, irqstaten;
|
u32 val, irqstaten;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_A011334) &&
|
||||||
|
plat->mmc.hs400_tuning)
|
||||||
|
set_sysctl(priv, mmc, mmc->clock);
|
||||||
|
|
||||||
esdhc_tuning_block_enable(priv, true);
|
esdhc_tuning_block_enable(priv, true);
|
||||||
esdhc_setbits32(®s->autoc12err, EXECUTE_TUNING);
|
esdhc_setbits32(®s->autoc12err, EXECUTE_TUNING);
|
||||||
|
|
||||||
@ -1073,7 +1096,7 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
|
|||||||
esdhc_write32(®s->irqstaten, IRQSTATEN_BRR);
|
esdhc_write32(®s->irqstaten, IRQSTATEN_BRR);
|
||||||
|
|
||||||
for (i = 0; i < MAX_TUNING_LOOP; i++) {
|
for (i = 0; i < MAX_TUNING_LOOP; i++) {
|
||||||
mmc_send_tuning(&plat->mmc, opcode, NULL);
|
mmc_send_tuning(mmc, opcode, NULL);
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
|
|
||||||
val = esdhc_read32(®s->autoc12err);
|
val = esdhc_read32(®s->autoc12err);
|
||||||
|
Loading…
Reference in New Issue
Block a user