summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/fsl_esdhc.c20
-rw-r--r--drivers/mmc/mmc.c23
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(&regs->wml, WML_RD_WML_MASK, wml_value);
esdhc_write32(&regs->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(&regs->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(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
;
+ if (data && (data->flags & MMC_DATA_READ))
+ check_and_invalidate_dcache_range(cmd, data);
+
irqstat = esdhc_read32(&regs->irqstat);
esdhc_write32(&regs->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(&regs->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