summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-05-05 07:00:38 -0400
committerTom Rini <trini@konsulko.com>2015-05-05 07:00:38 -0400
commitff7e9cfc338ecd6db5ed7d6ff8fb7a2889b0131c (patch)
treed127b051d0cb5ad8571fc176056600488576bdb5 /drivers/mmc
parent3f2f1a00394eb7ce7176f9d0930e40e55ba2c79c (diff)
parent33fe2fb8df01647f97a7bce96a1c7781a7f6d253 (diff)
downloadblackbird-obmc-uboot-ff7e9cfc338ecd6db5ed7d6ff8fb7a2889b0131c.tar.gz
blackbird-obmc-uboot-ff7e9cfc338ecd6db5ed7d6ff8fb7a2889b0131c.zip
Merge branch 'master' of git://git.denx.de/u-boot-mmc
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/bcm2835_sdhci.c8
-rw-r--r--drivers/mmc/dw_mmc.c2
-rw-r--r--drivers/mmc/fsl_esdhc.c6
-rw-r--r--drivers/mmc/kona_sdhci.c1
-rw-r--r--drivers/mmc/mmc.c93
-rw-r--r--drivers/mmc/mvebu_mmc.c2
-rw-r--r--drivers/mmc/mxsmmc.c3
-rw-r--r--drivers/mmc/omap_hsmmc.c3
-rw-r--r--drivers/mmc/s3c_sdi.c2
-rw-r--r--drivers/mmc/s5p_sdhci.c1
-rw-r--r--drivers/mmc/sdhci.c2
-rw-r--r--drivers/mmc/sh_mmcif.c2
-rw-r--r--drivers/mmc/sunxi_mmc.c2
-rw-r--r--drivers/mmc/tegra_mmc.c14
-rw-r--r--drivers/mmc/zynq_sdhci.c2
15 files changed, 74 insertions, 69 deletions
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index 4ec2968ece..078ef0523a 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -69,11 +69,11 @@ static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
* (Which is just as well - otherwise we'd have to nobble the DMA engine
* too)
*/
- while (get_timer_us(bcm_host->last_write) < bcm_host->twoticks_delay)
+ while (get_timer(bcm_host->last_write) < bcm_host->twoticks_delay)
;
writel(val, host->ioaddr + reg);
- bcm_host->last_write = get_timer_us(0);
+ bcm_host->last_write = get_timer(0);
}
static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)
@@ -154,9 +154,9 @@ int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
struct bcm2835_sdhci_host *bcm_host;
struct sdhci_host *host;
- bcm_host = malloc(sizeof(*bcm_host));
+ bcm_host = calloc(1, sizeof(*bcm_host));
if (!bcm_host) {
- printf("sdhci_host malloc fail!\n");
+ printf("sdhci_host calloc fail!\n");
return 1;
}
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 76fa0b0534..53a8aca84b 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -388,7 +388,7 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
host->cfg.host_caps |= MMC_MODE_4BIT;
host->cfg.host_caps &= ~MMC_MODE_8BIT;
}
- host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
+ host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 10ec216d2c..b9bc1654d3 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -387,9 +387,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Workaround for ESDHC errata ENGcm03648 */
if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
- int timeout = 2500;
+ int timeout = 6000;
- /* Poll on DATA0 line for cmd with busy signal for 250 ms */
+ /* Poll on DATA0 line for cmd with busy signal for 600 ms */
while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
PRSSTAT_DAT0)) {
udelay(100);
@@ -652,7 +652,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
return -1;
}
- cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+ cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
#endif
diff --git a/drivers/mmc/kona_sdhci.c b/drivers/mmc/kona_sdhci.c
index f804f4c0db..3653d00b1b 100644
--- a/drivers/mmc/kona_sdhci.c
+++ b/drivers/mmc/kona_sdhci.c
@@ -121,7 +121,6 @@ int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
host->name = "kona-sdhci";
host->ioaddr = reg_base;
host->quirks = quirks;
- host->host_caps = MMC_MODE_HC;
if (init_kona_mmc_core(host)) {
free(host);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a13769ea25..3909e14e72 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -118,7 +118,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
if (!mmc_host_is_spi(mmc))
cmd.cmdarg = mmc->rca << 16;
- do {
+ while (1) {
err = mmc_send_cmd(mmc, &cmd, NULL);
if (!err) {
if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
@@ -135,9 +135,11 @@ int mmc_send_status(struct mmc *mmc, int timeout)
} else if (--retries < 0)
return err;
- udelay(1000);
+ if (timeout-- <= 0)
+ break;
- } while (timeout--);
+ udelay(1000);
+ }
#ifdef CONFIG_MMC_TRACE
status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
@@ -291,7 +293,7 @@ static int sd_send_op_cond(struct mmc *mmc)
int err;
struct mmc_cmd cmd;
- do {
+ while (1) {
cmd.cmdidx = MMC_CMD_APP_CMD;
cmd.resp_type = MMC_RSP_R1;
cmd.cmdarg = 0;
@@ -322,11 +324,14 @@ static int sd_send_op_cond(struct mmc *mmc)
if (err)
return err;
- udelay(1000);
- } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+ if (cmd.response[0] & OCR_BUSY)
+ break;
- if (timeout <= 0)
- return UNUSABLE_ERR;
+ if (timeout-- <= 0)
+ return UNUSABLE_ERR;
+
+ udelay(1000);
+ }
if (mmc->version != SD_VERSION_2)
mmc->version = SD_VERSION_1_0;
@@ -350,51 +355,46 @@ static int sd_send_op_cond(struct mmc *mmc)
return 0;
}
-/* We pass in the cmd since otherwise the init seems to fail */
-static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
- int use_arg)
+static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
{
+ struct mmc_cmd cmd;
int err;
- cmd->cmdidx = MMC_CMD_SEND_OP_COND;
- cmd->resp_type = MMC_RSP_R3;
- cmd->cmdarg = 0;
- if (use_arg && !mmc_host_is_spi(mmc)) {
- cmd->cmdarg =
+ cmd.cmdidx = MMC_CMD_SEND_OP_COND;
+ cmd.resp_type = MMC_RSP_R3;
+ cmd.cmdarg = 0;
+ if (use_arg && !mmc_host_is_spi(mmc))
+ cmd.cmdarg = OCR_HCS |
(mmc->cfg->voltages &
- (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
- (mmc->op_cond_response & OCR_ACCESS_MODE);
+ (mmc->ocr & OCR_VOLTAGE_MASK)) |
+ (mmc->ocr & OCR_ACCESS_MODE);
- if (mmc->cfg->host_caps & MMC_MODE_HC)
- cmd->cmdarg |= OCR_HCS;
- }
- err = mmc_send_cmd(mmc, cmd, NULL);
+ err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
return err;
- mmc->op_cond_response = cmd->response[0];
+ mmc->ocr = cmd.response[0];
return 0;
}
static int mmc_send_op_cond(struct mmc *mmc)
{
- struct mmc_cmd cmd;
int err, i;
/* Some cards seem to need this */
mmc_go_idle(mmc);
/* Asking to the card its capabilities */
- mmc->op_cond_pending = 1;
for (i = 0; i < 2; i++) {
- err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
+ err = mmc_send_op_cond_iter(mmc, i != 0);
if (err)
return err;
/* exit if not busy (flag seems to be inverted) */
- if (mmc->op_cond_response & OCR_BUSY)
- return 0;
+ if (mmc->ocr & OCR_BUSY)
+ break;
}
- return IN_PROGRESS;
+ mmc->op_cond_pending = 1;
+ return 0;
}
static int mmc_complete_op_cond(struct mmc *mmc)
@@ -405,15 +405,19 @@ static int mmc_complete_op_cond(struct mmc *mmc)
int err;
mmc->op_cond_pending = 0;
- start = get_timer(0);
- do {
- err = mmc_send_op_cond_iter(mmc, &cmd, 1);
- if (err)
- return err;
- if (get_timer(start) > timeout)
- return UNUSABLE_ERR;
- udelay(100);
- } while (!(mmc->op_cond_response & OCR_BUSY));
+ if (!(mmc->ocr & OCR_BUSY)) {
+ start = get_timer(0);
+ while (1) {
+ err = mmc_send_op_cond_iter(mmc, 1);
+ if (err)
+ return err;
+ if (mmc->ocr & OCR_BUSY)
+ break;
+ if (get_timer(start) > timeout)
+ return UNUSABLE_ERR;
+ udelay(100);
+ }
+ }
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
@@ -424,10 +428,11 @@ static int mmc_complete_op_cond(struct mmc *mmc)
if (err)
return err;
+
+ mmc->ocr = cmd.response[0];
}
mmc->version = MMC_VERSION_UNKNOWN;
- mmc->ocr = cmd.response[0];
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
mmc->rca = 1;
@@ -1619,7 +1624,7 @@ int mmc_start_init(struct mmc *mmc)
if (err == TIMEOUT) {
err = mmc_send_op_cond(mmc);
- if (err && err != IN_PROGRESS) {
+ if (err) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("Card did not respond to voltage select!\n");
#endif
@@ -1627,7 +1632,7 @@ int mmc_start_init(struct mmc *mmc)
}
}
- if (err == IN_PROGRESS)
+ if (!err)
mmc->init_in_progress = 1;
return err;
@@ -1637,6 +1642,7 @@ static int mmc_complete_init(struct mmc *mmc)
{
int err = 0;
+ mmc->init_in_progress = 0;
if (mmc->op_cond_pending)
err = mmc_complete_op_cond(mmc);
@@ -1646,13 +1652,12 @@ static int mmc_complete_init(struct mmc *mmc)
mmc->has_init = 0;
else
mmc->has_init = 1;
- mmc->init_in_progress = 0;
return err;
}
int mmc_init(struct mmc *mmc)
{
- int err = IN_PROGRESS;
+ int err = 0;
unsigned start;
if (mmc->has_init)
@@ -1663,7 +1668,7 @@ int mmc_init(struct mmc *mmc)
if (!mmc->init_in_progress)
err = mmc_start_init(mmc);
- if (!err || err == IN_PROGRESS)
+ if (!err)
err = mmc_complete_init(mmc);
debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
return err;
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 8ca09042d8..056aef5bef 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -418,7 +418,7 @@ static struct mmc_config mvebu_mmc_cfg = {
.f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
.f_max = MVEBU_MMC_CLOCKRATE_MAX,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
- .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |
+ .host_caps = MMC_MODE_4BIT | MMC_MODE_HS |
MMC_MODE_HS_52MHz,
.part_type = PART_TYPE_DOS,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 2fa4eeef44..31fb3abc9c 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -405,8 +405,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
- MMC_MODE_HS_52MHz | MMC_MODE_HS |
- MMC_MODE_HC;
+ MMC_MODE_HS_52MHz | MMC_MODE_HS;
/*
* SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index dc725cb5b0..8238a7e8e0 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -651,8 +651,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
if (priv_data == NULL)
return -1;
- host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
- MMC_MODE_HC;
+ host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
switch (dev_index) {
case 0:
diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c
index 1b5b70512d..02d1138a5f 100644
--- a/drivers/mmc/s3c_sdi.c
+++ b/drivers/mmc/s3c_sdi.c
@@ -298,7 +298,7 @@ int s3cmmc_initialize(bd_t *bis, int (*getcd)(struct mmc *),
cfg->name = "S3C MMC";
cfg->ops = &s3cmmc_ops;
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
- cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HC | MMC_MODE_HS;
+ cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;
cfg->f_min = 400000;
cfg->f_max = get_PCLK() / 2;
cfg->b_max = 0x80;
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 0eec7310e4..8e1968a4ea 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -76,7 +76,6 @@ static int s5p_sdhci_core_init(struct sdhci_host *host)
host->set_control_reg = &s5p_sdhci_set_control_reg;
host->set_clock = set_mmc_clk;
- host->host_caps = MMC_MODE_HC;
if (host->bus_width == 8)
host->host_caps |= MMC_MODE_8BIT;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 5332e61cae..75556a332d 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -213,6 +213,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
SDHCI_BLOCK_SIZE);
sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
+ } else if (cmd->resp_type & MMC_RSP_BUSY) {
+ sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
}
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c
index 76ba93b81d..f92cf00cf4 100644
--- a/drivers/mmc/sh_mmcif.c
+++ b/drivers/mmc/sh_mmcif.c
@@ -577,7 +577,7 @@ static struct mmc_config sh_mmcif_cfg = {
.name = DRIVER_NAME,
.ops = &sh_mmcif_ops,
.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
- MMC_MODE_8BIT | MMC_MODE_HC,
+ MMC_MODE_8BIT,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
};
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index c4300f25fd..bb0814706c 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -449,7 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->host_caps = MMC_MODE_4BIT;
- cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
cfg->f_min = 400000;
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 2cd8cf10ae..d555692f7f 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -528,7 +528,7 @@ static const struct mmc_ops tegra_mmc_ops = {
.getcd = tegra_mmc_getcd,
};
-static int do_mmc_init(int dev_index)
+static int do_mmc_init(int dev_index, bool removable)
{
struct mmc_host *host;
struct mmc *mmc;
@@ -559,7 +559,7 @@ static int do_mmc_init(int dev_index)
host->cfg.host_caps |= MMC_MODE_8BIT;
if (host->width >= 4)
host->cfg.host_caps |= MMC_MODE_4BIT;
- host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+ host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
/*
* min freq is for card identification, and is the highest
@@ -573,6 +573,7 @@ static int do_mmc_init(int dev_index)
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
mmc = mmc_create(&host->cfg, host);
+ mmc->block_dev.removable = removable;
if (mmc == NULL)
return -1;
@@ -586,7 +587,8 @@ static int do_mmc_init(int dev_index)
* @param node Device index (0-3)
* @param host Structure to fill in (reg, width, mmc_id)
*/
-static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
+static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
+ bool *removablep)
{
debug("%s: node = %d\n", __func__, node);
@@ -619,6 +621,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
GPIOD_IS_IN);
gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
&host->pwr_gpio, GPIOD_IS_OUT);
+ *removablep = !fdtdec_get_bool(blob, node, "non-removable");
debug("%s: found controller at %p, width = %d, periph_id = %d\n",
__func__, host->reg, host->width, host->mmc_id);
@@ -636,6 +639,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
static int process_nodes(const void *blob, int node_list[], int count)
{
struct mmc_host *host;
+ bool removable;
int i, node;
debug("%s: count = %d\n", __func__, count);
@@ -649,11 +653,11 @@ static int process_nodes(const void *blob, int node_list[], int count)
host = &mmc_host[i];
host->id = i;
- if (mmc_get_config(blob, node, host)) {
+ if (mmc_get_config(blob, node, host, &removable)) {
printf("%s: failed to decode dev %d\n", __func__, i);
return -1;
}
- do_mmc_init(i);
+ do_mmc_init(i, removable);
}
return 0;
}
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index d4f3882cbd..971acbb6df 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -29,8 +29,6 @@ int zynq_sdhci_init(phys_addr_t regbase)
SDHCI_QUIRK_BROKEN_R1B;
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
- host->host_caps = MMC_MODE_HC;
-
add_sdhci(host, 52000000, 52000000 >> 9);
return 0;
}
OpenPOWER on IntegriCloud