static struct list_head mmc_devices;
static int cur_dev_num = -1;
+static int mmc_dev_count;
__weak int board_mmc_getwp(struct mmc *mmc)
{
udelay(1000);
} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
-
- if (timeout <= 0)
+ if (!(cmd.response[0] & OCR_BUSY))
return UNUSABLE_ERR;
if (mmc->version != SD_VERSION_2)
/* Some cards seem to need this */
mmc_go_idle(mmc);
- /* Asking to the card its capabilities */
+ /* 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);
if (err)
return err;
if (get_timer(start) > timeout)
- return UNUSABLE_ERR;
+ break;
udelay(100);
} while (!(mmc->op_cond_response & OCR_BUSY));
+ if (!(mmc->op_cond_response & OCR_BUSY)) {
+ debug("%s: timeout\n", __func__);
+ return UNUSABLE_ERR;
+ }
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
char cardtype;
int err;
- mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
+ mmc->card_caps = 0;
if (mmc_host_is_spi(mmc))
return 0;
if (mmc->version < MMC_VERSION_4)
return 0;
+ mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
+
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
mmc->tran_speed = 50000000;
else
mmc->tran_speed = 25000000;
- } else {
+ } else if (mmc->version >= MMC_VERSION_4) {
+ /* Only version 4 of MMC supports wider bus widths */
int idx;
/* An array of possible bus widths in order of preference */
unsigned int extw = ext_csd_bits[idx];
unsigned int caps = ext_to_hostcaps[extw];
+ /*
+ * If the bus width is still not changed,
+ * don't try to set the default again.
+ * Otherwise, recover from switch attempts
+ * by switching to 1-bit bus width.
+ */
+ if (extw == EXT_CSD_BUS_WIDTH_1 &&
+ mmc->bus_width == 1) {
+ err = 0;
+ break;
+ }
+
/*
* Check to make sure the card and controller support
* these capabilities
INIT_LIST_HEAD(&mmc->link);
list_add_tail(&mmc->link, &mmc_devices);
+ mmc_dev_count++;
return mmc;
}
return cur_dev_num;
}
+int get_mmc_dev_count(void)
+{
+ return mmc_dev_count;
+}
+
void mmc_set_preinit(struct mmc *mmc, int preinit)
{
mmc->preinit = preinit;
*/
int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
{
+ int ret;
+ ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+
+ ret = mmc_send_ext_csd(mmc, ext_csd);
+ if (ret)
+ return ret;
+
+ if (ext_csd[EXT_CSD_RST_N_FUNCTION] != 0 &&
+ ext_csd[EXT_CSD_RST_N_FUNCTION] != enable) {
+ printf("RST_N_FUNCTION is already set to %u; cannot change to %u\n",
+ ext_csd[EXT_CSD_RST_N_FUNCTION], enable);
+ return -EINVAL;
+ }
return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
enable);
}