mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-04-01 03:51:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-mmc
This commit is contained in:
commit
ff7e9cfc33
16 changed files with 77 additions and 75 deletions
|
@ -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
|
* (Which is just as well - otherwise we'd have to nobble the DMA engine
|
||||||
* too)
|
* 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);
|
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)
|
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 bcm2835_sdhci_host *bcm_host;
|
||||||
struct sdhci_host *host;
|
struct sdhci_host *host;
|
||||||
|
|
||||||
bcm_host = malloc(sizeof(*bcm_host));
|
bcm_host = calloc(1, sizeof(*bcm_host));
|
||||||
if (!bcm_host) {
|
if (!bcm_host) {
|
||||||
printf("sdhci_host malloc fail!\n");
|
printf("sdhci_host calloc fail!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_4BIT;
|
||||||
host->cfg.host_caps &= ~MMC_MODE_8BIT;
|
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;
|
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||||
|
|
||||||
|
|
|
@ -387,9 +387,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
|
|
||||||
/* Workaround for ESDHC errata ENGcm03648 */
|
/* Workaround for ESDHC errata ENGcm03648 */
|
||||||
if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
|
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(®s->prsstat) &
|
while (timeout > 0 && !(esdhc_read32(®s->prsstat) &
|
||||||
PRSSTAT_DAT0)) {
|
PRSSTAT_DAT0)) {
|
||||||
udelay(100);
|
udelay(100);
|
||||||
|
@ -652,7 +652,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
|
||||||
return -1;
|
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
|
#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
|
||||||
cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
|
cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,7 +121,6 @@ int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
|
||||||
host->name = "kona-sdhci";
|
host->name = "kona-sdhci";
|
||||||
host->ioaddr = reg_base;
|
host->ioaddr = reg_base;
|
||||||
host->quirks = quirks;
|
host->quirks = quirks;
|
||||||
host->host_caps = MMC_MODE_HC;
|
|
||||||
|
|
||||||
if (init_kona_mmc_core(host)) {
|
if (init_kona_mmc_core(host)) {
|
||||||
free(host);
|
free(host);
|
||||||
|
|
|
@ -118,7 +118,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
|
||||||
if (!mmc_host_is_spi(mmc))
|
if (!mmc_host_is_spi(mmc))
|
||||||
cmd.cmdarg = mmc->rca << 16;
|
cmd.cmdarg = mmc->rca << 16;
|
||||||
|
|
||||||
do {
|
while (1) {
|
||||||
err = mmc_send_cmd(mmc, &cmd, NULL);
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
|
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)
|
} else if (--retries < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
udelay(1000);
|
if (timeout-- <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
} while (timeout--);
|
udelay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MMC_TRACE
|
#ifdef CONFIG_MMC_TRACE
|
||||||
status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
|
status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
|
||||||
|
@ -291,7 +293,7 @@ static int sd_send_op_cond(struct mmc *mmc)
|
||||||
int err;
|
int err;
|
||||||
struct mmc_cmd cmd;
|
struct mmc_cmd cmd;
|
||||||
|
|
||||||
do {
|
while (1) {
|
||||||
cmd.cmdidx = MMC_CMD_APP_CMD;
|
cmd.cmdidx = MMC_CMD_APP_CMD;
|
||||||
cmd.resp_type = MMC_RSP_R1;
|
cmd.resp_type = MMC_RSP_R1;
|
||||||
cmd.cmdarg = 0;
|
cmd.cmdarg = 0;
|
||||||
|
@ -322,11 +324,14 @@ static int sd_send_op_cond(struct mmc *mmc)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
udelay(1000);
|
if (cmd.response[0] & OCR_BUSY)
|
||||||
} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
|
break;
|
||||||
|
|
||||||
if (timeout <= 0)
|
if (timeout-- <= 0)
|
||||||
return UNUSABLE_ERR;
|
return UNUSABLE_ERR;
|
||||||
|
|
||||||
|
udelay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
if (mmc->version != SD_VERSION_2)
|
if (mmc->version != SD_VERSION_2)
|
||||||
mmc->version = SD_VERSION_1_0;
|
mmc->version = SD_VERSION_1_0;
|
||||||
|
@ -350,51 +355,46 @@ static int sd_send_op_cond(struct mmc *mmc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We pass in the cmd since otherwise the init seems to fail */
|
static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
|
||||||
static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
|
|
||||||
int use_arg)
|
|
||||||
{
|
{
|
||||||
|
struct mmc_cmd cmd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
cmd->cmdidx = MMC_CMD_SEND_OP_COND;
|
cmd.cmdidx = MMC_CMD_SEND_OP_COND;
|
||||||
cmd->resp_type = MMC_RSP_R3;
|
cmd.resp_type = MMC_RSP_R3;
|
||||||
cmd->cmdarg = 0;
|
cmd.cmdarg = 0;
|
||||||
if (use_arg && !mmc_host_is_spi(mmc)) {
|
if (use_arg && !mmc_host_is_spi(mmc))
|
||||||
cmd->cmdarg =
|
cmd.cmdarg = OCR_HCS |
|
||||||
(mmc->cfg->voltages &
|
(mmc->cfg->voltages &
|
||||||
(mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
|
(mmc->ocr & OCR_VOLTAGE_MASK)) |
|
||||||
(mmc->op_cond_response & OCR_ACCESS_MODE);
|
(mmc->ocr & OCR_ACCESS_MODE);
|
||||||
|
|
||||||
if (mmc->cfg->host_caps & MMC_MODE_HC)
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
||||||
cmd->cmdarg |= OCR_HCS;
|
|
||||||
}
|
|
||||||
err = mmc_send_cmd(mmc, cmd, NULL);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
mmc->op_cond_response = cmd->response[0];
|
mmc->ocr = cmd.response[0];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mmc_send_op_cond(struct mmc *mmc)
|
static int mmc_send_op_cond(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct mmc_cmd cmd;
|
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
/* Some cards seem to need this */
|
/* Some cards seem to need this */
|
||||||
mmc_go_idle(mmc);
|
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++) {
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* exit if not busy (flag seems to be inverted) */
|
/* exit if not busy (flag seems to be inverted) */
|
||||||
if (mmc->op_cond_response & OCR_BUSY)
|
if (mmc->ocr & OCR_BUSY)
|
||||||
return 0;
|
break;
|
||||||
}
|
}
|
||||||
return IN_PROGRESS;
|
mmc->op_cond_pending = 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mmc_complete_op_cond(struct mmc *mmc)
|
static int mmc_complete_op_cond(struct mmc *mmc)
|
||||||
|
@ -405,15 +405,19 @@ static int mmc_complete_op_cond(struct mmc *mmc)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mmc->op_cond_pending = 0;
|
mmc->op_cond_pending = 0;
|
||||||
start = get_timer(0);
|
if (!(mmc->ocr & OCR_BUSY)) {
|
||||||
do {
|
start = get_timer(0);
|
||||||
err = mmc_send_op_cond_iter(mmc, &cmd, 1);
|
while (1) {
|
||||||
if (err)
|
err = mmc_send_op_cond_iter(mmc, 1);
|
||||||
return err;
|
if (err)
|
||||||
if (get_timer(start) > timeout)
|
return err;
|
||||||
return UNUSABLE_ERR;
|
if (mmc->ocr & OCR_BUSY)
|
||||||
udelay(100);
|
break;
|
||||||
} while (!(mmc->op_cond_response & OCR_BUSY));
|
if (get_timer(start) > timeout)
|
||||||
|
return UNUSABLE_ERR;
|
||||||
|
udelay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
|
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
|
||||||
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
|
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
|
||||||
|
@ -424,10 +428,11 @@ static int mmc_complete_op_cond(struct mmc *mmc)
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
mmc->ocr = cmd.response[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
mmc->version = MMC_VERSION_UNKNOWN;
|
mmc->version = MMC_VERSION_UNKNOWN;
|
||||||
mmc->ocr = cmd.response[0];
|
|
||||||
|
|
||||||
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
|
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
|
||||||
mmc->rca = 1;
|
mmc->rca = 1;
|
||||||
|
@ -1619,7 +1624,7 @@ int mmc_start_init(struct mmc *mmc)
|
||||||
if (err == TIMEOUT) {
|
if (err == TIMEOUT) {
|
||||||
err = mmc_send_op_cond(mmc);
|
err = mmc_send_op_cond(mmc);
|
||||||
|
|
||||||
if (err && err != IN_PROGRESS) {
|
if (err) {
|
||||||
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
|
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
|
||||||
printf("Card did not respond to voltage select!\n");
|
printf("Card did not respond to voltage select!\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -1627,7 +1632,7 @@ int mmc_start_init(struct mmc *mmc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == IN_PROGRESS)
|
if (!err)
|
||||||
mmc->init_in_progress = 1;
|
mmc->init_in_progress = 1;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -1637,6 +1642,7 @@ static int mmc_complete_init(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
mmc->init_in_progress = 0;
|
||||||
if (mmc->op_cond_pending)
|
if (mmc->op_cond_pending)
|
||||||
err = mmc_complete_op_cond(mmc);
|
err = mmc_complete_op_cond(mmc);
|
||||||
|
|
||||||
|
@ -1646,13 +1652,12 @@ static int mmc_complete_init(struct mmc *mmc)
|
||||||
mmc->has_init = 0;
|
mmc->has_init = 0;
|
||||||
else
|
else
|
||||||
mmc->has_init = 1;
|
mmc->has_init = 1;
|
||||||
mmc->init_in_progress = 0;
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mmc_init(struct mmc *mmc)
|
int mmc_init(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
int err = IN_PROGRESS;
|
int err = 0;
|
||||||
unsigned start;
|
unsigned start;
|
||||||
|
|
||||||
if (mmc->has_init)
|
if (mmc->has_init)
|
||||||
|
@ -1663,7 +1668,7 @@ int mmc_init(struct mmc *mmc)
|
||||||
if (!mmc->init_in_progress)
|
if (!mmc->init_in_progress)
|
||||||
err = mmc_start_init(mmc);
|
err = mmc_start_init(mmc);
|
||||||
|
|
||||||
if (!err || err == IN_PROGRESS)
|
if (!err)
|
||||||
err = mmc_complete_init(mmc);
|
err = mmc_complete_init(mmc);
|
||||||
debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
|
debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -418,7 +418,7 @@ static struct mmc_config mvebu_mmc_cfg = {
|
||||||
.f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
|
.f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
|
||||||
.f_max = MVEBU_MMC_CLOCKRATE_MAX,
|
.f_max = MVEBU_MMC_CLOCKRATE_MAX,
|
||||||
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
|
.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,
|
MMC_MODE_HS_52MHz,
|
||||||
.part_type = PART_TYPE_DOS,
|
.part_type = PART_TYPE_DOS,
|
||||||
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
|
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
|
||||||
|
|
|
@ -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.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
|
|
||||||
priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
|
priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
|
||||||
MMC_MODE_HS_52MHz | MMC_MODE_HS |
|
MMC_MODE_HS_52MHz | MMC_MODE_HS;
|
||||||
MMC_MODE_HC;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
|
* SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
|
||||||
|
|
|
@ -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)
|
if (priv_data == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
|
host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
|
||||||
MMC_MODE_HC;
|
|
||||||
|
|
||||||
switch (dev_index) {
|
switch (dev_index) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -298,7 +298,7 @@ int s3cmmc_initialize(bd_t *bis, int (*getcd)(struct mmc *),
|
||||||
cfg->name = "S3C MMC";
|
cfg->name = "S3C MMC";
|
||||||
cfg->ops = &s3cmmc_ops;
|
cfg->ops = &s3cmmc_ops;
|
||||||
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
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_min = 400000;
|
||||||
cfg->f_max = get_PCLK() / 2;
|
cfg->f_max = get_PCLK() / 2;
|
||||||
cfg->b_max = 0x80;
|
cfg->b_max = 0x80;
|
||||||
|
|
|
@ -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_control_reg = &s5p_sdhci_set_control_reg;
|
||||||
host->set_clock = set_mmc_clk;
|
host->set_clock = set_mmc_clk;
|
||||||
|
|
||||||
host->host_caps = MMC_MODE_HC;
|
|
||||||
if (host->bus_width == 8)
|
if (host->bus_width == 8)
|
||||||
host->host_caps |= MMC_MODE_8BIT;
|
host->host_caps |= MMC_MODE_8BIT;
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
SDHCI_BLOCK_SIZE);
|
SDHCI_BLOCK_SIZE);
|
||||||
sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
|
sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
|
||||||
sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
|
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);
|
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
|
||||||
|
|
|
@ -577,7 +577,7 @@ static struct mmc_config sh_mmcif_cfg = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.ops = &sh_mmcif_ops,
|
.ops = &sh_mmcif_ops,
|
||||||
.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
|
.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,
|
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
|
||||||
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
|
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
|
||||||
};
|
};
|
||||||
|
|
|
@ -449,7 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
|
||||||
|
|
||||||
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
cfg->host_caps = MMC_MODE_4BIT;
|
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->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||||
|
|
||||||
cfg->f_min = 400000;
|
cfg->f_min = 400000;
|
||||||
|
|
|
@ -528,7 +528,7 @@ static const struct mmc_ops tegra_mmc_ops = {
|
||||||
.getcd = tegra_mmc_getcd,
|
.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_host *host;
|
||||||
struct mmc *mmc;
|
struct mmc *mmc;
|
||||||
|
@ -559,7 +559,7 @@ static int do_mmc_init(int dev_index)
|
||||||
host->cfg.host_caps |= MMC_MODE_8BIT;
|
host->cfg.host_caps |= MMC_MODE_8BIT;
|
||||||
if (host->width >= 4)
|
if (host->width >= 4)
|
||||||
host->cfg.host_caps |= MMC_MODE_4BIT;
|
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
|
* 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;
|
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||||
|
|
||||||
mmc = mmc_create(&host->cfg, host);
|
mmc = mmc_create(&host->cfg, host);
|
||||||
|
mmc->block_dev.removable = removable;
|
||||||
if (mmc == NULL)
|
if (mmc == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -586,7 +587,8 @@ static int do_mmc_init(int dev_index)
|
||||||
* @param node Device index (0-3)
|
* @param node Device index (0-3)
|
||||||
* @param host Structure to fill in (reg, width, mmc_id)
|
* @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);
|
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);
|
GPIOD_IS_IN);
|
||||||
gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
|
gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
|
||||||
&host->pwr_gpio, GPIOD_IS_OUT);
|
&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",
|
debug("%s: found controller at %p, width = %d, periph_id = %d\n",
|
||||||
__func__, host->reg, host->width, host->mmc_id);
|
__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)
|
static int process_nodes(const void *blob, int node_list[], int count)
|
||||||
{
|
{
|
||||||
struct mmc_host *host;
|
struct mmc_host *host;
|
||||||
|
bool removable;
|
||||||
int i, node;
|
int i, node;
|
||||||
|
|
||||||
debug("%s: count = %d\n", __func__, count);
|
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 = &mmc_host[i];
|
||||||
host->id = 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);
|
printf("%s: failed to decode dev %d\n", __func__, i);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
do_mmc_init(i);
|
do_mmc_init(i, removable);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,6 @@ int zynq_sdhci_init(phys_addr_t regbase)
|
||||||
SDHCI_QUIRK_BROKEN_R1B;
|
SDHCI_QUIRK_BROKEN_R1B;
|
||||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||||
|
|
||||||
host->host_caps = MMC_MODE_HC;
|
|
||||||
|
|
||||||
add_sdhci(host, 52000000, 52000000 >> 9);
|
add_sdhci(host, 52000000, 52000000 >> 9);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,13 +55,12 @@
|
||||||
#define MMC_MODE_4BIT (1 << 2)
|
#define MMC_MODE_4BIT (1 << 2)
|
||||||
#define MMC_MODE_8BIT (1 << 3)
|
#define MMC_MODE_8BIT (1 << 3)
|
||||||
#define MMC_MODE_SPI (1 << 4)
|
#define MMC_MODE_SPI (1 << 4)
|
||||||
#define MMC_MODE_HC (1 << 5)
|
#define MMC_MODE_DDR_52MHz (1 << 5)
|
||||||
#define MMC_MODE_DDR_52MHz (1 << 6)
|
|
||||||
|
|
||||||
#define SD_DATA_4BIT 0x00040000
|
#define SD_DATA_4BIT 0x00040000
|
||||||
|
|
||||||
#define IS_SD(x) ((x)->version & SD_VERSION_SD)
|
#define IS_SD(x) ((x)->version & SD_VERSION_SD)
|
||||||
#define IS_MMC(x) ((x)->version & SD_VERSION_MMC)
|
#define IS_MMC(x) ((x)->version & MMC_VERSION_MMC)
|
||||||
|
|
||||||
#define MMC_DATA_READ 1
|
#define MMC_DATA_READ 1
|
||||||
#define MMC_DATA_WRITE 2
|
#define MMC_DATA_WRITE 2
|
||||||
|
@ -70,8 +69,7 @@
|
||||||
#define UNUSABLE_ERR -17 /* Unusable Card */
|
#define UNUSABLE_ERR -17 /* Unusable Card */
|
||||||
#define COMM_ERR -18 /* Communications Error */
|
#define COMM_ERR -18 /* Communications Error */
|
||||||
#define TIMEOUT -19
|
#define TIMEOUT -19
|
||||||
#define IN_PROGRESS -20 /* operation is in progress */
|
#define SWITCH_ERR -20 /* Card reports failure to switch mode */
|
||||||
#define SWITCH_ERR -21 /* Card reports failure to switch mode */
|
|
||||||
|
|
||||||
#define MMC_CMD_GO_IDLE_STATE 0
|
#define MMC_CMD_GO_IDLE_STATE 0
|
||||||
#define MMC_CMD_SEND_OP_COND 1
|
#define MMC_CMD_SEND_OP_COND 1
|
||||||
|
@ -356,7 +354,6 @@ struct mmc {
|
||||||
char op_cond_pending; /* 1 if we are waiting on an op_cond command */
|
char op_cond_pending; /* 1 if we are waiting on an op_cond command */
|
||||||
char init_in_progress; /* 1 if we have done mmc_start_init() */
|
char init_in_progress; /* 1 if we have done mmc_start_init() */
|
||||||
char preinit; /* start init as early as possible */
|
char preinit; /* start init as early as possible */
|
||||||
uint op_cond_response; /* the response byte from the last op_cond */
|
|
||||||
int ddr_mode;
|
int ddr_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue