diff options
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 20 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 23 |
2 files changed, 35 insertions, 8 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 07370b5..b6c969d 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -190,6 +190,10 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); esdhc_write32(®s->dsaddr, (u32)data->dest); } else { + flush_dcache_range((ulong)data->src, + (ulong)data->src+data->blocks + *data->blocksize); + if (wml_value > WML_WR_WML_MAX) wml_value = WML_WR_WML_MAX_VAL; if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { @@ -249,7 +253,15 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) return 0; } - +static void check_and_invalidate_dcache_range + (struct mmc_cmd *cmd, + struct mmc_data *data) { + unsigned start = (unsigned)data->dest ; + unsigned size = roundup(ARCH_DMA_MINALIGN, + data->blocks*data->blocksize); + unsigned end = start+size ; + invalidate_dcache_range(start, end); +} /* * Sends a command out on the bus. Takes the mmc pointer, * a command pointer, and an optional data pointer. @@ -315,6 +327,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) while (!(esdhc_read32(®s->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE))) ; + if (data && (data->flags & MMC_DATA_READ)) + check_and_invalidate_dcache_range(cmd, data); + irqstat = esdhc_read32(®s->irqstat); esdhc_write32(®s->irqstat, irqstat); @@ -528,6 +543,9 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) /* First reset the eSDHC controller */ esdhc_reset(regs); + esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN + | SYSCTL_IPGEN | SYSCTL_CKEN); + mmc->priv = cfg; mmc->send_cmd = esdhc_send_cmd; mmc->set_ios = esdhc_set_ios; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index aebe578..c1c2862 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -333,6 +333,7 @@ mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt) int err = 0; struct mmc *mmc = find_mmc_device(dev_num); lbaint_t blk = 0, blk_r = 0; + int timeout = 1000; if (!mmc) return -1; @@ -352,6 +353,10 @@ mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt) break; blk += blk_r; + + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) + return 0; } return blk; @@ -1195,9 +1200,9 @@ int mmc_startup(struct mmc *mmc) } if (mmc->card_caps & MMC_MODE_HS) - mmc_set_clock(mmc, 50000000); + mmc->tran_speed = 50000000; else - mmc_set_clock(mmc, 25000000); + mmc->tran_speed = 25000000; } else { width = ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) >> MMC_MODE_WIDTH_BITS_SHIFT); @@ -1234,13 +1239,14 @@ int mmc_startup(struct mmc *mmc) if (mmc->card_caps & MMC_MODE_HS) { if (mmc->card_caps & MMC_MODE_HS_52MHz) - mmc_set_clock(mmc, 52000000); + mmc->tran_speed = 52000000; else - mmc_set_clock(mmc, 26000000); - } else - mmc_set_clock(mmc, 20000000); + mmc->tran_speed = 26000000; + } } + mmc_set_clock(mmc, mmc->tran_speed); + /* fill in device description */ mmc->block_dev.lun = 0; mmc->block_dev.type = 0; @@ -1305,8 +1311,11 @@ int mmc_register(struct mmc *mmc) block_dev_desc_t *mmc_get_dev(int dev) { struct mmc *mmc = find_mmc_device(dev); + if (!mmc) + return NULL; - return mmc ? &mmc->block_dev : NULL; + mmc_init(mmc); + return &mmc->block_dev; } #endif |