X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmmc%2Ffsl_esdhc.c;h=ec953f07d7156760b2ca81e5ee6418efdc91b14b;hb=4d28db8a1e8b90e1e3ffd95d7f949b849e33fa2f;hp=57cd4ee1f436cced7b367e09e5b43c200ab54ca5;hpb=b5d58d8500bfb918c7fec56f241e6ee1078c2be0;p=u-boot diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 57cd4ee1f4..ec953f07d7 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -1,5 +1,5 @@ /* - * Copyright 2007,2010 Freescale Semiconductor, Inc + * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc * Andy Fleming * * Based vaguely on the pxa mmc code: @@ -79,6 +79,9 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) if (data->blocks > 1) { xfertyp |= XFERTYP_MSBSEL; xfertyp |= XFERTYP_BCEN; +#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 + xfertyp |= XFERTYP_AC12EN; +#endif } if (data->flags & MMC_DATA_READ) @@ -96,6 +99,10 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) else if (cmd->resp_type & MMC_RSP_PRESENT) xfertyp |= XFERTYP_RSPTYP_48; +#ifdef CONFIG_MX53 + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + xfertyp |= XFERTYP_CMDTYP_ABORT; +#endif return XFERTYP_CMD(cmd->cmdidx) | xfertyp; } @@ -175,14 +182,14 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) wml_value = data->blocksize/4; if (data->flags & MMC_DATA_READ) { - if (wml_value > 0x10) - wml_value = 0x10; + if (wml_value > WML_RD_WML_MAX) + wml_value = WML_RD_WML_MAX_VAL; esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); esdhc_write32(®s->dsaddr, (u32)data->dest); } else { - if (wml_value > 0x80) - wml_value = 0x80; + if (wml_value > WML_WR_WML_MAX) + wml_value = WML_WR_WML_MAX_VAL; if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); return TIMEOUT; @@ -207,7 +214,21 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize); /* Calculate the timeout period for data transactions */ - timeout = fls(mmc->tran_speed/10) - 1; + /* + * 1)Timeout period = (2^(timeout+13)) SD Clock cycles + * 2)Timeout period should be minimum 0.250sec as per SD Card spec + * So, Number of SD Clock cycles for 0.25sec should be minimum + * (SD Clock/sec * 0.25 sec) SD Clock cycles + * = (mmc->tran_speed * 1/4) SD Clock cycles + * As 1) >= 2) + * => (2^(timeout+13)) >= mmc->tran_speed * 1/4 + * Taking log2 both the sides + * => timeout + 13 >= log2(mmc->tran_speed/4) + * Rounding up to next power of 2 + * => timeout + 13 = log2(mmc->tran_speed/4) + 1 + * => timeout + 13 = fls(mmc->tran_speed/4) + */ + timeout = fls(mmc->tran_speed/4); timeout -= 13; if (timeout > 14) @@ -216,6 +237,11 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) if (timeout < 0) timeout = 0; +#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001 + if ((timeout == 4) || (timeout == 8) || (timeout == 12)) + timeout++; +#endif + esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16); return 0; @@ -234,6 +260,11 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; +#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + return 0; +#endif + esdhc_write32(®s->irqstat, -1); sync(); @@ -305,11 +336,11 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) do { irqstat = esdhc_read32(®s->irqstat); - if (irqstat & DATA_ERR) - return COMM_ERR; - if (irqstat & IRQSTAT_DTOE) return TIMEOUT; + + if (irqstat & DATA_ERR) + return COMM_ERR; } while (!(irqstat & IRQSTAT_TC) && (esdhc_read32(®s->prsstat) & PRSSTAT_DLA)); #endif @@ -398,7 +429,7 @@ static int esdhc_init(struct mmc *mmc) esdhc_write32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN); /* Set the initial clock speed */ - set_sysctl(mmc, 400000); + mmc_set_clock(mmc, 400000); /* Disable the BRR and BWR bits in IRQSTAT */ esdhc_clrbits32(®s->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR); @@ -444,7 +475,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) { struct fsl_esdhc *regs; struct mmc *mmc; - u32 caps; + u32 caps, voltage_caps; if (!cfg) return -1; @@ -462,14 +493,29 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) mmc->set_ios = esdhc_set_ios; mmc->init = esdhc_init; + voltage_caps = 0; caps = regs->hostcapblt; +#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135 + caps = caps & ~(ESDHC_HOSTCAPBLT_SRS | + ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30); +#endif if (caps & ESDHC_HOSTCAPBLT_VS18) - mmc->voltages |= MMC_VDD_165_195; + voltage_caps |= MMC_VDD_165_195; if (caps & ESDHC_HOSTCAPBLT_VS30) - mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; + voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31; if (caps & ESDHC_HOSTCAPBLT_VS33) - mmc->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; + voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; + +#ifdef CONFIG_SYS_SD_VOLTAGE + mmc->voltages = CONFIG_SYS_SD_VOLTAGE; +#else + mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; +#endif + if ((mmc->voltages & voltage_caps) == 0) { + printf("voltage not supported by controller\n"); + return -1; + } mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; @@ -477,8 +523,9 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; mmc->f_min = 400000; - mmc->f_max = MIN(gd->sdhc_clk, 50000000); + mmc->f_max = MIN(gd->sdhc_clk, 52000000); + mmc->b_max = 0; mmc_register(mmc); return 0; @@ -498,17 +545,19 @@ int fsl_esdhc_mmc_init(bd_t *bis) void fdt_fixup_esdhc(void *blob, bd_t *bd) { const char *compat = "fsl,esdhc"; - const char *status = "okay"; +#ifdef CONFIG_FSL_ESDHC_PIN_MUX if (!hwconfig("esdhc")) { - status = "disabled"; - goto out; + do_fixup_by_compat(blob, compat, "status", "disabled", + 8 + 1, 1); + return; } +#endif do_fixup_by_compat_u32(blob, compat, "clock-frequency", gd->sdhc_clk, 1); -out: - do_fixup_by_compat(blob, compat, "status", status, - strlen(status) + 1, 1); + + do_fixup_by_compat(blob, compat, "status", "okay", + 4 + 1, 1); } #endif