Merge branch 'master' of git://www.denx.de/git/u-boot-mmc
This commit is contained in:
@@ -52,7 +52,7 @@ static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
|
||||
debug("CMD%d time out\n", cmd->cmdidx);
|
||||
return TIMEOUT;
|
||||
} else if ((hoststatus & SDI_STA_CCRCFAIL) &&
|
||||
(cmd->flags & MMC_RSP_CRC)) {
|
||||
(cmd->resp_type & MMC_RSP_CRC)) {
|
||||
printf("CMD%d CRC error\n", cmd->cmdidx);
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
@@ -236,7 +236,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
|
||||
status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
|
||||
printf("CURR STATE:%d\n", status);
|
||||
#endif
|
||||
if (!timeout) {
|
||||
if (timeout <= 0) {
|
||||
printf("Timeout waiting card ready\n");
|
||||
return TIMEOUT;
|
||||
}
|
||||
@@ -658,7 +658,7 @@ int mmc_send_op_cond(struct mmc *mmc)
|
||||
}
|
||||
|
||||
|
||||
int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
|
||||
int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
|
||||
{
|
||||
struct mmc_cmd cmd;
|
||||
struct mmc_data data;
|
||||
@@ -669,7 +669,7 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
|
||||
cmd.resp_type = MMC_RSP_R1;
|
||||
cmd.cmdarg = 0;
|
||||
|
||||
data.dest = ext_csd;
|
||||
data.dest = (char *)ext_csd;
|
||||
data.blocks = 1;
|
||||
data.blocksize = 512;
|
||||
data.flags = MMC_DATA_READ;
|
||||
@@ -704,7 +704,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
|
||||
|
||||
int mmc_change_freq(struct mmc *mmc)
|
||||
{
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512);
|
||||
ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
|
||||
char cardtype;
|
||||
int err;
|
||||
|
||||
@@ -963,8 +963,8 @@ int mmc_startup(struct mmc *mmc)
|
||||
uint mult, freq;
|
||||
u64 cmult, csize, capacity;
|
||||
struct mmc_cmd cmd;
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512);
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, test_csd, 512);
|
||||
ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
|
||||
ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512);
|
||||
int timeout = 1000;
|
||||
|
||||
#ifdef CONFIG_MMC_SPI_CRC_ON
|
||||
@@ -1137,7 +1137,8 @@ int mmc_startup(struct mmc *mmc)
|
||||
}
|
||||
|
||||
/* store the partition info of emmc */
|
||||
if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT)
|
||||
if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
|
||||
ext_csd[EXT_CSD_BOOT_MULT])
|
||||
mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
|
||||
}
|
||||
|
||||
@@ -1232,7 +1233,9 @@ int mmc_startup(struct mmc *mmc)
|
||||
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
|
||||
sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
|
||||
(mmc->cid[2] >> 24) & 0xf);
|
||||
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
|
||||
init_part(&mmc->block_dev);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1283,10 +1286,9 @@ int mmc_register(struct mmc *mmc)
|
||||
block_dev_desc_t *mmc_get_dev(int dev)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(dev);
|
||||
if (!mmc)
|
||||
if (!mmc || mmc_init(mmc))
|
||||
return NULL;
|
||||
|
||||
mmc_init(mmc);
|
||||
return &mmc->block_dev;
|
||||
}
|
||||
#endif
|
||||
|
@@ -118,7 +118,7 @@ static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||
int ret;
|
||||
|
||||
/* The card can send a "busy" response */
|
||||
if (cmd->flags & MMC_RSP_BUSY)
|
||||
if (cmd->resp_type & MMC_RSP_BUSY)
|
||||
cmdat |= MMC_CMDAT_BUSY;
|
||||
|
||||
/* Inform the controller about response type */
|
||||
@@ -181,9 +181,11 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd)
|
||||
/* The command response didn't arrive */
|
||||
if (stat & MMC_STAT_TIME_OUT_RESPONSE)
|
||||
return -ETIMEDOUT;
|
||||
else if (stat & MMC_STAT_RES_CRC_ERROR && cmd->flags & MMC_RSP_CRC) {
|
||||
else if (stat & MMC_STAT_RES_CRC_ERROR
|
||||
&& cmd->resp_type & MMC_RSP_CRC) {
|
||||
#ifdef PXAMMC_CRC_SKIP
|
||||
if (cmd->flags & MMC_RSP_136 && cmd->response[0] & (1 << 31))
|
||||
if (cmd->resp_type & MMC_RSP_136
|
||||
&& cmd->response[0] & (1 << 31))
|
||||
printf("Ignoring CRC, this may be dangerous!\n");
|
||||
else
|
||||
#endif
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <malloc.h>
|
||||
#include <sdhci.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
#include <asm/arch/clk.h>
|
||||
|
||||
static char *S5P_NAME = "SAMSUNG SDHCI";
|
||||
static void s5p_sdhci_set_control_reg(struct sdhci_host *host)
|
||||
@@ -54,7 +55,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host)
|
||||
* 00 = Delay3 (inverter delay)
|
||||
* 10 = Delay4 (inverter delay + 2ns)
|
||||
*/
|
||||
val = SDHCI_CTRL3_FCSEL3 | SDHCI_CTRL3_FCSEL1;
|
||||
val = SDHCI_CTRL3_FCSEL0 | SDHCI_CTRL3_FCSEL1;
|
||||
sdhci_writel(host, val, SDHCI_CONTROL3);
|
||||
|
||||
/*
|
||||
@@ -69,7 +70,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host)
|
||||
sdhci_writel(host, ctrl, SDHCI_CONTROL2);
|
||||
}
|
||||
|
||||
int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
|
||||
int s5p_sdhci_init(u32 regbase, int index, int bus_width)
|
||||
{
|
||||
struct sdhci_host *host = NULL;
|
||||
host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
|
||||
@@ -80,19 +81,18 @@ int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
|
||||
|
||||
host->name = S5P_NAME;
|
||||
host->ioaddr = (void *)regbase;
|
||||
host->quirks = quirks;
|
||||
|
||||
host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE;
|
||||
host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE |
|
||||
SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR;
|
||||
host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||
if (quirks & SDHCI_QUIRK_REG32_RW)
|
||||
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
|
||||
else
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
host->set_control_reg = &s5p_sdhci_set_control_reg;
|
||||
host->set_clock = set_mmc_clk;
|
||||
host->index = index;
|
||||
|
||||
host->host_caps = MMC_MODE_HC;
|
||||
|
||||
add_sdhci(host, max_clk, min_clk);
|
||||
add_sdhci(host, 52000000, 400000);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -260,7 +260,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
|
||||
if (clock == 0)
|
||||
return 0;
|
||||
|
||||
if (host->version >= SDHCI_SPEC_300) {
|
||||
if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) {
|
||||
/* Version 3.00 divisors must be a multiple of 2. */
|
||||
if (mmc->f_max <= clock)
|
||||
div = 1;
|
||||
@@ -279,6 +279,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
|
||||
}
|
||||
div >>= 1;
|
||||
|
||||
if (host->set_clock)
|
||||
host->set_clock(host->index, div);
|
||||
|
||||
clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
|
||||
clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
|
||||
<< SDHCI_DIVIDER_HI_SHIFT;
|
||||
@@ -347,10 +350,10 @@ void sdhci_set_ios(struct mmc *mmc)
|
||||
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
|
||||
if (mmc->bus_width == 8) {
|
||||
ctrl &= ~SDHCI_CTRL_4BITBUS;
|
||||
if (host->version >= SDHCI_SPEC_300)
|
||||
if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
|
||||
ctrl |= SDHCI_CTRL_8BITBUS;
|
||||
} else {
|
||||
if (host->version >= SDHCI_SPEC_300)
|
||||
if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
|
||||
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||
if (mmc->bus_width == 4)
|
||||
ctrl |= SDHCI_CTRL_4BITBUS;
|
||||
@@ -381,12 +384,25 @@ int sdhci_init(struct mmc *mmc)
|
||||
}
|
||||
}
|
||||
|
||||
sdhci_set_power(host, fls(mmc->voltages) - 1);
|
||||
|
||||
if (host->quirks & SDHCI_QUIRK_NO_CD) {
|
||||
unsigned int status;
|
||||
|
||||
sdhci_writel(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST,
|
||||
SDHCI_HOST_CONTROL);
|
||||
|
||||
status = sdhci_readl(host, SDHCI_PRESENT_STATE);
|
||||
while ((!(status & SDHCI_CARD_PRESENT)) ||
|
||||
(!(status & SDHCI_CARD_STATE_STABLE)) ||
|
||||
(!(status & SDHCI_CARD_DETECT_PIN_LEVEL)))
|
||||
status = sdhci_readl(host, SDHCI_PRESENT_STATE);
|
||||
}
|
||||
|
||||
/* Eable all state */
|
||||
sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE);
|
||||
sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE);
|
||||
|
||||
sdhci_set_power(host, fls(mmc->voltages) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -421,7 +437,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
|
||||
if (max_clk)
|
||||
mmc->f_max = max_clk;
|
||||
else {
|
||||
if (host->version >= SDHCI_SPEC_300)
|
||||
if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
|
||||
mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
|
||||
>> SDHCI_CLOCK_BASE_SHIFT;
|
||||
else
|
||||
@@ -436,7 +452,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
|
||||
if (min_clk)
|
||||
mmc->f_min = min_clk;
|
||||
else {
|
||||
if (host->version >= SDHCI_SPEC_300)
|
||||
if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
|
||||
mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300;
|
||||
else
|
||||
mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200;
|
||||
|
@@ -593,7 +593,7 @@ int mmcif_mmc_init(void)
|
||||
mmc->f_max = CLKDEV_EMMC_DATA;
|
||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||
mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
|
||||
MMC_MODE_8BIT;
|
||||
MMC_MODE_8BIT | MMC_MODE_HC;
|
||||
memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME));
|
||||
mmc->send_cmd = sh_mmcif_request;
|
||||
mmc->set_ios = sh_mmcif_set_ios;
|
||||
|
Reference in New Issue
Block a user