summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/imx_esdhc.c72
-rw-r--r--drivers/mmc/mmc.c15
2 files changed, 56 insertions, 31 deletions
diff --git a/drivers/mmc/imx_esdhc.c b/drivers/mmc/imx_esdhc.c
index f9b35ea..78e0607 100644
--- a/drivers/mmc/imx_esdhc.c
+++ b/drivers/mmc/imx_esdhc.c
@@ -31,10 +31,13 @@
#include <config.h>
#include <common.h>
#include <command.h>
+#include <hwconfig.h>
#include <mmc.h>
+#include <part.h>
#include <malloc.h>
#include <mmc.h>
#include <fsl_esdhc.h>
+#include <fdt_support.h>
#include <asm/io.h>
@@ -108,7 +111,8 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
uint wml_value;
int timeout;
u32 tmp;
- struct fsl_esdhc *regs = mmc->priv;
+ struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+ struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
wml_value = data->blocksize / 4;
@@ -157,7 +161,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
uint xfertyp;
uint irqstat;
u32 tmp;
- volatile struct fsl_esdhc *regs = mmc->priv;
+ struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+ volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
writel(-1, &regs->irqstat);
@@ -278,7 +283,8 @@ void set_sysctl(struct mmc *mmc, uint clock)
{
int sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
int div, pre_div;
- volatile struct fsl_esdhc *regs = mmc->priv;
+ struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+ volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
uint clk;
u32 tmp;
@@ -321,7 +327,8 @@ void set_sysctl(struct mmc *mmc, uint clock)
static void esdhc_set_ios(struct mmc *mmc)
{
- struct fsl_esdhc *regs = mmc->priv;
+ struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+ struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
u32 tmp;
/* Set the clock speed */
@@ -342,10 +349,8 @@ static void esdhc_set_ios(struct mmc *mmc)
static int esdhc_init(struct mmc *mmc)
{
- struct fsl_esdhc *regs = mmc->priv;
- /*
- int timeout = 1000;
- */
+ struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+ struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
u32 tmp;
/* Reset the eSDHC by writing 1 to RSTA bit of SYSCTRL Register */
@@ -388,41 +393,31 @@ static int esdhc_init(struct mmc *mmc)
return 0;
}
-#ifndef CONFIG_SYS_FSL_ESDHC_ADDR
-extern u32 *imx_esdhc_base_addr;
-#endif
-
-static int esdhc_initialize(bd_t *bis)
+int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
{
-#ifdef CONFIG_SYS_FSL_ESDHC_ADDR
- struct fsl_esdhc *regs = (struct fsl_esdhc *)CONFIG_SYS_IMX_ESDHC_ADDR;
-#else
- struct fsl_esdhc *regs = (struct fsl_esdhc *)imx_esdhc_base_addr;
-#endif
+ struct fsl_esdhc *regs;
struct mmc *mmc;
u32 caps;
+ if (!cfg)
+ return -1;
+
mmc = malloc(sizeof(struct mmc));
sprintf(mmc->name, "FSL_ESDHC");
- mmc->priv = regs;
+ regs = (struct fsl_esdhc *)cfg->esdhc_base;
+ mmc->priv = cfg;
mmc->send_cmd = esdhc_send_cmd;
mmc->set_ios = esdhc_set_ios;
mmc->init = esdhc_init;
caps = regs->hostcapblt;
- /*
if (caps & ESDHC_HOSTCAPBLT_VS18)
mmc->voltages |= MMC_VDD_165_195;
if (caps & ESDHC_HOSTCAPBLT_VS30)
mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
- if (caps & ESDHC_HOSTCAPBLT_VS33) {
+ if (caps & ESDHC_HOSTCAPBLT_VS33)
mmc->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
- }
- */
- mmc->voltages = MMC_VDD_35_36 | MMC_VDD_34_35 | MMC_VDD_33_34 |
- MMC_VDD_32_33 | MMC_VDD_31_32 | MMC_VDD_30_31 |
- MMC_VDD_29_30 | MMC_VDD_28_29 | MMC_VDD_27_28;
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
@@ -439,6 +434,29 @@ static int esdhc_initialize(bd_t *bis)
int fsl_esdhc_mmc_init(bd_t *bis)
{
- return esdhc_initialize(bis);
+ struct fsl_esdhc_cfg *cfg;
+
+ cfg = malloc(sizeof(struct fsl_esdhc_cfg));
+ memset(cfg, 0, sizeof(struct fsl_esdhc_cfg));
+ cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
+ return fsl_esdhc_initialize(bis, cfg);
}
+#ifdef CONFIG_OF_LIBFDT
+void fdt_fixup_esdhc(void *blob, bd_t *bd)
+{
+ const char *compat = "fsl,esdhc";
+ const char *status = "okay";
+
+ if (!hwconfig("esdhc")) {
+ status = "disabled";
+ goto out;
+ }
+
+ 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);
+}
+#endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 01d3210..2f774ee 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -176,7 +176,7 @@ int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size)
buffer = malloc(blklen);
if (!buffer) {
- puts("Could not allocate buffer for MMC read!\n");
+ printf("Could not allocate buffer for MMC read!\n");
return -1;
}
@@ -184,7 +184,7 @@ int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size)
err = mmc_set_blocklen(mmc, mmc->read_bl_len);
if (err)
- return err;
+ goto free_buffer;
for (i = startblock; i <= endblock; i++) {
int segment_size;
@@ -321,7 +321,15 @@ sd_send_op_cond(struct mmc *mmc)
cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
cmd.resp_type = MMC_RSP_R3;
- cmd.cmdarg = mmc->voltages;
+
+ /*
+ * Most cards do not answer if some reserved bits
+ * in the ocr are set. However, Some controller
+ * can set bit 7 (reserved for low voltages), but
+ * how to manage low voltages SD card is not yet
+ * specified.
+ */
+ cmd.cmdarg = mmc->voltages & 0xff8000;
if (mmc->version == SD_VERSION_2)
cmd.cmdarg |= OCR_HCS;
@@ -978,7 +986,6 @@ int mmc_startup(struct mmc *mmc)
mmc_set_clock(mmc, 50000000);
else
mmc_set_clock(mmc, 25000000);
-
} else {
if (mmc->card_caps & MMC_MODE_4BIT) {
/* Set the card to use 4 bit*/