mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-09-10 12:39:22 -04:00
Merge branch 'master' of /home/wd/git/u-boot/custodians
* 'master' of /home/wd/git/u-boot/custodians: fsl_esdhc: fix PIO mode transfers mmc: tegra2: Implement card-detect hook. mmc: fsl_esdhc: Implement card-detect hook. mmc: Implement card detection. mmc: Change board_mmc_getcd() function prototype. drivers/mmc/mv_sdhci.c: Fix build warning ftsdc010: improve performance and capability mmc: add host_caps checking avoid switch card improperly i.mx: fsl_esdhc: add the i.mx6q support
This commit is contained in:
commit
6d7ba2cef5
@ -314,17 +314,18 @@ static inline uint32_t efika_mmc_cd(void)
|
|||||||
return MX51_PIN_EIM_CS2;
|
return MX51_PIN_EIM_CS2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_getcd(u8 *absent, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
uint32_t cd = efika_mmc_cd();
|
uint32_t cd = efika_mmc_cd();
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
||||||
*absent = gpio_get_value(IOMUX_TO_GPIO(cd));
|
ret = !gpio_get_value(IOMUX_TO_GPIO(cd));
|
||||||
else
|
else
|
||||||
*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
|
ret = !gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_init(bd_t *bis)
|
int board_mmc_init(bd_t *bis)
|
||||||
|
@ -108,17 +108,9 @@ int board_mmc_init(bd_t *bd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* this is a weak define that we are overriding */
|
/* this is a weak define that we are overriding */
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
/*
|
return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
|
||||||
* the only currently existing use of this function
|
|
||||||
* (fsl_esdhc.c) suggests this function must return
|
|
||||||
* *cs = TRUE if a card is NOT detected -> in most
|
|
||||||
* cases the value of the pin when the detect switch
|
|
||||||
* closes to GND
|
|
||||||
*/
|
|
||||||
*cd = at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -321,19 +321,20 @@ static void power_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_ESDHC
|
#ifdef CONFIG_FSL_ESDHC
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mxc_request_iomux(MX51_PIN_GPIO1_0, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX51_PIN_GPIO1_0, IOMUX_CONFIG_ALT1);
|
||||||
mxc_request_iomux(MX51_PIN_GPIO1_6, IOMUX_CONFIG_ALT0);
|
mxc_request_iomux(MX51_PIN_GPIO1_6, IOMUX_CONFIG_ALT0);
|
||||||
|
|
||||||
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
||||||
*cd = gpio_get_value(0);
|
ret = !gpio_get_value(0);
|
||||||
else
|
else
|
||||||
*cd = gpio_get_value(6);
|
ret = !gpio_get_value(6);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_init(bd_t *bis)
|
int board_mmc_init(bd_t *bis)
|
||||||
|
@ -83,19 +83,20 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = {
|
|||||||
{MMC_SDHC2_BASE_ADDR, 1 },
|
{MMC_SDHC2_BASE_ADDR, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
|
||||||
mxc_request_iomux(MX53_PIN_GPIO_4, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_GPIO_4, IOMUX_CONFIG_ALT1);
|
||||||
|
|
||||||
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
||||||
*cd = gpio_get_value(1); /*GPIO1_1*/
|
ret = !gpio_get_value(1); /* GPIO1_1 */
|
||||||
else
|
else
|
||||||
*cd = gpio_get_value(4); /*GPIO1_4*/
|
ret = !gpio_get_value(4); /* GPIO1_4 */
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_init(bd_t *bis)
|
int board_mmc_init(bd_t *bis)
|
||||||
|
@ -208,19 +208,20 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = {
|
|||||||
{MMC_SDHC3_BASE_ADDR, 1},
|
{MMC_SDHC3_BASE_ADDR, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
|
||||||
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
|
||||||
|
|
||||||
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
||||||
*cd = gpio_get_value(77); /*GPIO3_13*/
|
ret = !gpio_get_value(77); /* GPIO3_13 */
|
||||||
else
|
else
|
||||||
*cd = gpio_get_value(75); /*GPIO3_11*/
|
ret = !gpio_get_value(75); /* GPIO3_11 */
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_init(bd_t *bis)
|
int board_mmc_init(bd_t *bis)
|
||||||
|
@ -147,19 +147,20 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = {
|
|||||||
{MMC_SDHC3_BASE_ADDR, 1},
|
{MMC_SDHC3_BASE_ADDR, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
|
||||||
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
|
||||||
|
|
||||||
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
|
||||||
*cd = gpio_get_value(77); /*GPIO3_13*/
|
ret = !gpio_get_value(77); /* GPIO3_13 */
|
||||||
else
|
else
|
||||||
*cd = gpio_get_value(75); /*GPIO3_11*/
|
ret = !gpio_get_value(75); /* GPIO3_11 */
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_init(bd_t *bis)
|
int board_mmc_init(bd_t *bis)
|
||||||
|
@ -132,12 +132,10 @@ struct fsl_esdhc_cfg esdhc_cfg[1] = {
|
|||||||
{MMC_SDHC1_BASE_ADDR, 1},
|
{MMC_SDHC1_BASE_ADDR, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
|
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
|
||||||
*cd = gpio_get_value(77); /*GPIO3_13*/
|
return !gpio_get_value(77); /* GPIO3_13 */
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_init(bd_t *bis)
|
int board_mmc_init(bd_t *bis)
|
||||||
|
@ -59,17 +59,9 @@ int board_mmc_init(bd_t *bd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* this is a weak define that we are overriding */
|
/* this is a weak define that we are overriding */
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
int board_mmc_getcd(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
/*
|
return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
|
||||||
* the only currently existing use of this function
|
|
||||||
* (fsl_esdhc.c) suggests this function must return
|
|
||||||
* *cs = TRUE if a card is NOT detected -> in most
|
|
||||||
* cases the value of the pin when the detect switch
|
|
||||||
* closes to GND
|
|
||||||
*/
|
|
||||||
*cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -385,6 +385,7 @@ static int arm_pl180_mmci_host_init(struct mmc *dev)
|
|||||||
dev->send_cmd = host_request;
|
dev->send_cmd = host_request;
|
||||||
dev->set_ios = host_set_ios;
|
dev->set_ios = host_set_ios;
|
||||||
dev->init = mmc_host_reset;
|
dev->init = mmc_host_reset;
|
||||||
|
dev->getcd = NULL;
|
||||||
dev->host_caps = 0;
|
dev->host_caps = 0;
|
||||||
dev->voltages = VOLTAGE_WINDOW_MMC;
|
dev->voltages = VOLTAGE_WINDOW_MMC;
|
||||||
dev->f_min = dev->clock;
|
dev->f_min = dev->clock;
|
||||||
|
@ -250,6 +250,7 @@ int bfin_mmc_init(bd_t *bis)
|
|||||||
mmc->send_cmd = bfin_sdh_request;
|
mmc->send_cmd = bfin_sdh_request;
|
||||||
mmc->set_ios = bfin_sdh_set_ios;
|
mmc->set_ios = bfin_sdh_set_ios;
|
||||||
mmc->init = bfin_sdh_init;
|
mmc->init = bfin_sdh_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
mmc->host_caps = MMC_MODE_4BIT;
|
mmc->host_caps = MMC_MODE_4BIT;
|
||||||
|
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
|
@ -387,6 +387,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
|
|||||||
mmc->send_cmd = dmmc_send_cmd;
|
mmc->send_cmd = dmmc_send_cmd;
|
||||||
mmc->set_ios = dmmc_set_ios;
|
mmc->set_ios = dmmc_set_ios;
|
||||||
mmc->init = dmmc_init;
|
mmc->init = dmmc_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
mmc->f_min = 200000;
|
mmc->f_min = 200000;
|
||||||
mmc->f_max = 25000000;
|
mmc->f_max = 25000000;
|
||||||
|
@ -58,7 +58,8 @@ struct fsl_esdhc {
|
|||||||
uint autoc12err;
|
uint autoc12err;
|
||||||
uint hostcapblt;
|
uint hostcapblt;
|
||||||
uint wml;
|
uint wml;
|
||||||
char reserved1[8];
|
uint mixctrl;
|
||||||
|
char reserved1[4];
|
||||||
uint fevt;
|
uint fevt;
|
||||||
char reserved2[168];
|
char reserved2[168];
|
||||||
uint hostver;
|
uint hostver;
|
||||||
@ -113,7 +114,8 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
|
|||||||
static void
|
static void
|
||||||
esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
|
esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
|
||||||
{
|
{
|
||||||
struct fsl_esdhc *regs = mmc->priv;
|
struct fsl_esdhc_cfg *cfg = mmc->priv;
|
||||||
|
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
||||||
uint blocks;
|
uint blocks;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
uint databuf;
|
uint databuf;
|
||||||
@ -298,8 +300,13 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
|||||||
|
|
||||||
/* Send the command */
|
/* Send the command */
|
||||||
esdhc_write32(®s->cmdarg, cmd->cmdarg);
|
esdhc_write32(®s->cmdarg, cmd->cmdarg);
|
||||||
|
#if defined(CONFIG_FSL_USDHC)
|
||||||
|
esdhc_write32(®s->mixctrl,
|
||||||
|
(esdhc_read32(®s->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
|
||||||
|
esdhc_write32(®s->xfertyp, xfertyp & 0xFFFF0000);
|
||||||
|
#else
|
||||||
esdhc_write32(®s->xfertyp, xfertyp);
|
esdhc_write32(®s->xfertyp, xfertyp);
|
||||||
|
#endif
|
||||||
/* Wait for the command to complete */
|
/* Wait for the command to complete */
|
||||||
while (!(esdhc_read32(®s->irqstat) & IRQSTAT_CC))
|
while (!(esdhc_read32(®s->irqstat) & IRQSTAT_CC))
|
||||||
;
|
;
|
||||||
@ -412,8 +419,6 @@ static int esdhc_init(struct mmc *mmc)
|
|||||||
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
||||||
int timeout = 1000;
|
int timeout = 1000;
|
||||||
int ret = 0;
|
|
||||||
u8 card_absent;
|
|
||||||
|
|
||||||
/* Reset the entire host controller */
|
/* Reset the entire host controller */
|
||||||
esdhc_write32(®s->sysctl, SYSCTL_RSTA);
|
esdhc_write32(®s->sysctl, SYSCTL_RSTA);
|
||||||
@ -440,21 +445,19 @@ static int esdhc_init(struct mmc *mmc)
|
|||||||
/* Set timout to the maximum value */
|
/* Set timout to the maximum value */
|
||||||
esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
|
esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
|
||||||
|
|
||||||
/* Check if there is a callback for detecting the card */
|
return 0;
|
||||||
if (board_mmc_getcd(&card_absent, mmc)) {
|
|
||||||
timeout = 1000;
|
|
||||||
while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) &&
|
|
||||||
--timeout)
|
|
||||||
udelay(1000);
|
|
||||||
|
|
||||||
if (timeout <= 0)
|
|
||||||
ret = NO_CARD_ERR;
|
|
||||||
} else {
|
|
||||||
if (card_absent)
|
|
||||||
ret = NO_CARD_ERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
static int esdhc_getcd(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
||||||
|
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
||||||
|
int timeout = 1000;
|
||||||
|
|
||||||
|
while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout)
|
||||||
|
udelay(1000);
|
||||||
|
|
||||||
|
return timeout > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void esdhc_reset(struct fsl_esdhc *regs)
|
static void esdhc_reset(struct fsl_esdhc *regs)
|
||||||
@ -482,7 +485,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
|
|||||||
|
|
||||||
mmc = malloc(sizeof(struct mmc));
|
mmc = malloc(sizeof(struct mmc));
|
||||||
|
|
||||||
sprintf(mmc->name, "FSL_ESDHC");
|
sprintf(mmc->name, "FSL_SDHC");
|
||||||
regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
||||||
|
|
||||||
/* First reset the eSDHC controller */
|
/* First reset the eSDHC controller */
|
||||||
@ -492,6 +495,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
|
|||||||
mmc->send_cmd = esdhc_send_cmd;
|
mmc->send_cmd = esdhc_send_cmd;
|
||||||
mmc->set_ios = esdhc_set_ios;
|
mmc->set_ios = esdhc_set_ios;
|
||||||
mmc->init = esdhc_init;
|
mmc->init = esdhc_init;
|
||||||
|
mmc->getcd = esdhc_getcd;
|
||||||
|
|
||||||
voltage_caps = 0;
|
voltage_caps = 0;
|
||||||
caps = regs->hostcapblt;
|
caps = regs->hostcapblt;
|
||||||
|
@ -90,8 +90,13 @@ static void ftsdc010_pio_read(struct mmc_host *host, char *buf, unsigned int siz
|
|||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
status = readl(&host->reg->status);
|
status = readl(&host->reg->status);
|
||||||
|
debug("%s: size: %08x\n", __func__, size);
|
||||||
|
|
||||||
if (status & FTSDC010_STATUS_FIFO_ORUN) {
|
if (status & FTSDC010_STATUS_FIFO_ORUN) {
|
||||||
|
|
||||||
|
debug("%s: FIFO OVERRUN: sta: %08x\n",
|
||||||
|
__func__, status);
|
||||||
|
|
||||||
fifo = host->fifo_len > size ?
|
fifo = host->fifo_len > size ?
|
||||||
size : host->fifo_len;
|
size : host->fifo_len;
|
||||||
|
|
||||||
@ -146,7 +151,7 @@ static void ftsdc010_pio_write(struct mmc_host *host, const char *buf,
|
|||||||
while (size) {
|
while (size) {
|
||||||
status = readl(&host->reg->status);
|
status = readl(&host->reg->status);
|
||||||
|
|
||||||
if (status & FTSDC010_STATUS_FIFO_ORUN) {
|
if (status & FTSDC010_STATUS_FIFO_URUN) {
|
||||||
fifo = host->fifo_len > size ?
|
fifo = host->fifo_len > size ?
|
||||||
size : host->fifo_len;
|
size : host->fifo_len;
|
||||||
|
|
||||||
@ -158,7 +163,6 @@ static void ftsdc010_pio_write(struct mmc_host *host, const char *buf,
|
|||||||
writel(*ptr, &host->reg->dwr);
|
writel(*ptr, &host->reg->dwr);
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
udelay(1);
|
udelay(1);
|
||||||
if (++retry >= FTSDC010_PIO_RETRY) {
|
if (++retry >= FTSDC010_PIO_RETRY) {
|
||||||
@ -169,56 +173,19 @@ static void ftsdc010_pio_write(struct mmc_host *host, const char *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftsdc010_pio_check_status(struct mmc *mmc, struct mmc_cmd *cmd,
|
static int ftsdc010_check_rsp(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
struct mmc_data *data)
|
struct mmc_data *data)
|
||||||
{
|
{
|
||||||
struct mmc_host *host = mmc->priv;
|
struct mmc_host *host = mmc->priv;
|
||||||
|
|
||||||
unsigned int sta, clear;
|
unsigned int sta, clear;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* check response and hardware status */
|
|
||||||
clear = 0;
|
|
||||||
|
|
||||||
/* chech CMD_SEND */
|
|
||||||
for (i = 0; i < FTSDC010_CMD_RETRY; i++) {
|
|
||||||
sta = readl(&host->reg->status);
|
sta = readl(&host->reg->status);
|
||||||
/* Command Complete */
|
debug("%s: sta: %08x cmd %d\n", __func__, sta, cmd->cmdidx);
|
||||||
if (sta & FTSDC010_STATUS_CMD_SEND) {
|
|
||||||
if (!data)
|
|
||||||
clear |= FTSDC010_CLR_CMD_SEND;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i > FTSDC010_CMD_RETRY) {
|
|
||||||
printf("%s: send command timeout\n", __func__);
|
|
||||||
return TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* debug: print status register and command index*/
|
|
||||||
debug("sta: %08x cmd %d\n", sta, cmd->cmdidx);
|
|
||||||
|
|
||||||
/* handle data FIFO */
|
|
||||||
if ((sta & FTSDC010_STATUS_FIFO_ORUN) ||
|
|
||||||
(sta & FTSDC010_STATUS_FIFO_URUN)) {
|
|
||||||
|
|
||||||
/* Wrong DATA FIFO Flag */
|
|
||||||
if (data == NULL)
|
|
||||||
printf("%s, data fifo wrong: sta: %08x cmd %d\n",
|
|
||||||
__func__, sta, cmd->cmdidx);
|
|
||||||
|
|
||||||
if (sta & FTSDC010_STATUS_FIFO_ORUN)
|
|
||||||
clear |= FTSDC010_STATUS_FIFO_ORUN;
|
|
||||||
if (sta & FTSDC010_STATUS_FIFO_URUN)
|
|
||||||
clear |= FTSDC010_STATUS_FIFO_URUN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check RSP TIMEOUT or FAIL */
|
/* check RSP TIMEOUT or FAIL */
|
||||||
if (sta & FTSDC010_STATUS_RSP_TIMEOUT) {
|
if (sta & FTSDC010_STATUS_RSP_TIMEOUT) {
|
||||||
/* RSP TIMEOUT */
|
/* RSP TIMEOUT */
|
||||||
debug("%s: RSP timeout: sta: %08x cmd %d\n",
|
debug("%s: RSP timeout: sta: %08x\n", __func__, sta);
|
||||||
__func__, sta, cmd->cmdidx);
|
|
||||||
|
|
||||||
clear |= FTSDC010_CLR_RSP_TIMEOUT;
|
clear |= FTSDC010_CLR_RSP_TIMEOUT;
|
||||||
writel(clear, &host->reg->clr);
|
writel(clear, &host->reg->clr);
|
||||||
@ -226,47 +193,62 @@ static int ftsdc010_pio_check_status(struct mmc *mmc, struct mmc_cmd *cmd,
|
|||||||
return TIMEOUT;
|
return TIMEOUT;
|
||||||
} else if (sta & FTSDC010_STATUS_RSP_CRC_FAIL) {
|
} else if (sta & FTSDC010_STATUS_RSP_CRC_FAIL) {
|
||||||
/* clear response fail bit */
|
/* clear response fail bit */
|
||||||
debug("%s: RSP CRC FAIL: sta: %08x cmd %d\n",
|
debug("%s: RSP CRC FAIL: sta: %08x\n", __func__, sta);
|
||||||
__func__, sta, cmd->cmdidx);
|
|
||||||
|
|
||||||
clear |= FTSDC010_CLR_RSP_CRC_FAIL;
|
clear |= FTSDC010_CLR_RSP_CRC_FAIL;
|
||||||
writel(clear, &host->reg->clr);
|
writel(clear, &host->reg->clr);
|
||||||
|
|
||||||
return 0;
|
return COMM_ERR;
|
||||||
} else if (sta & FTSDC010_STATUS_RSP_CRC_OK) {
|
} else if (sta & FTSDC010_STATUS_RSP_CRC_OK) {
|
||||||
|
|
||||||
/* clear response CRC OK bit */
|
/* clear response CRC OK bit */
|
||||||
clear |= FTSDC010_CLR_RSP_CRC_OK;
|
clear |= FTSDC010_CLR_RSP_CRC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writel(clear, &host->reg->clr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ftsdc010_check_data(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data)
|
||||||
|
{
|
||||||
|
struct mmc_host *host = mmc->priv;
|
||||||
|
unsigned int sta, clear;
|
||||||
|
|
||||||
|
sta = readl(&host->reg->status);
|
||||||
|
debug("%s: sta: %08x cmd %d\n", __func__, sta, cmd->cmdidx);
|
||||||
|
|
||||||
/* check DATA TIMEOUT or FAIL */
|
/* check DATA TIMEOUT or FAIL */
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
||||||
|
/* Transfer Complete */
|
||||||
|
if (sta & FTSDC010_STATUS_DATA_END)
|
||||||
|
clear |= FTSDC010_STATUS_DATA_END;
|
||||||
|
|
||||||
|
/* Data CRC_OK */
|
||||||
|
if (sta & FTSDC010_STATUS_DATA_CRC_OK)
|
||||||
|
clear |= FTSDC010_STATUS_DATA_CRC_OK;
|
||||||
|
|
||||||
|
/* DATA TIMEOUT or DATA CRC FAIL */
|
||||||
if (sta & FTSDC010_STATUS_DATA_TIMEOUT) {
|
if (sta & FTSDC010_STATUS_DATA_TIMEOUT) {
|
||||||
/* DATA TIMEOUT */
|
/* DATA TIMEOUT */
|
||||||
debug("%s: DATA TIMEOUT: sta: %08x\n",
|
debug("%s: DATA TIMEOUT: sta: %08x\n", __func__, sta);
|
||||||
__func__, sta);
|
|
||||||
|
|
||||||
clear |= FTSDC010_STATUS_DATA_TIMEOUT;
|
clear |= FTSDC010_STATUS_DATA_TIMEOUT;
|
||||||
writel(sta, &host->reg->clr);
|
writel(clear, &host->reg->clr);
|
||||||
|
|
||||||
return TIMEOUT;
|
return TIMEOUT;
|
||||||
} else if (sta & FTSDC010_STATUS_DATA_CRC_FAIL) {
|
} else if (sta & FTSDC010_STATUS_DATA_CRC_FAIL) {
|
||||||
/* Error Interrupt */
|
/* DATA CRC FAIL */
|
||||||
debug("%s: DATA CRC FAIL: sta: %08x\n",
|
debug("%s: DATA CRC FAIL: sta: %08x\n", __func__, sta);
|
||||||
__func__, sta);
|
|
||||||
|
|
||||||
clear |= FTSDC010_STATUS_DATA_CRC_FAIL;
|
clear |= FTSDC010_STATUS_DATA_CRC_FAIL;
|
||||||
writel(clear, &host->reg->clr);
|
writel(clear, &host->reg->clr);
|
||||||
|
|
||||||
return 0;
|
return COMM_ERR;
|
||||||
} else if (sta & FTSDC010_STATUS_DATA_END) {
|
|
||||||
/* Transfer Complete */
|
|
||||||
clear |= FTSDC010_STATUS_DATA_END;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* transaction is success and clear status register */
|
|
||||||
writel(clear, &host->reg->clr);
|
writel(clear, &host->reg->clr);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +263,9 @@ static int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
|||||||
unsigned int ccon;
|
unsigned int ccon;
|
||||||
unsigned int mask, tmpmask;
|
unsigned int mask, tmpmask;
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
unsigned int sta, i;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
mask = FTSDC010_INT_MASK_RSP_TIMEOUT;
|
mask = FTSDC010_INT_MASK_RSP_TIMEOUT;
|
||||||
@ -290,13 +275,9 @@ static int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
|||||||
mask = FTSDC010_INT_MASK_CMD_SEND;
|
mask = FTSDC010_INT_MASK_CMD_SEND;
|
||||||
|
|
||||||
/* write argu reg */
|
/* write argu reg */
|
||||||
debug("%s: cmd->arg: %08x\n", __func__, cmd->cmdarg);
|
debug("%s: argu: %08x\n", __func__, host->reg->argu);
|
||||||
writel(cmd->cmdarg, &host->reg->argu);
|
writel(cmd->cmdarg, &host->reg->argu);
|
||||||
|
|
||||||
/* setup cmd reg */
|
|
||||||
debug("cmd: %d\n", cmd->cmdidx);
|
|
||||||
debug("resp: %08x\n", cmd->resp_type);
|
|
||||||
|
|
||||||
/* setup commnad */
|
/* setup commnad */
|
||||||
ccon = FTSDC010_CMD_IDX(cmd->cmdidx);
|
ccon = FTSDC010_CMD_IDX(cmd->cmdidx);
|
||||||
|
|
||||||
@ -340,7 +321,51 @@ static int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
|||||||
/* write cmd reg */
|
/* write cmd reg */
|
||||||
debug("%s: ccon: %08x\n", __func__, ccon);
|
debug("%s: ccon: %08x\n", __func__, ccon);
|
||||||
writel(ccon, &host->reg->cmd);
|
writel(ccon, &host->reg->cmd);
|
||||||
udelay(4*FTSDC010_DELAY_UNIT);
|
|
||||||
|
/* check CMD_SEND */
|
||||||
|
for (i = 0; i < FTSDC010_CMD_RETRY; i++) {
|
||||||
|
/*
|
||||||
|
* If we read status register too fast
|
||||||
|
* will lead hardware error and the RSP_TIMEOUT
|
||||||
|
* flag will be raised incorrectly.
|
||||||
|
*/
|
||||||
|
udelay(16*FTSDC010_DELAY_UNIT);
|
||||||
|
sta = readl(&host->reg->status);
|
||||||
|
|
||||||
|
/* Command Complete */
|
||||||
|
/*
|
||||||
|
* Note:
|
||||||
|
* Do not clear FTSDC010_CLR_CMD_SEND flag.
|
||||||
|
* (by writing FTSDC010_CLR_CMD_SEND bit to clear register)
|
||||||
|
* It will make the driver becomes very slow.
|
||||||
|
* If the operation hasn't been finished, hardware will
|
||||||
|
* clear this bit automatically.
|
||||||
|
* In origin, the driver will clear this flag if there is
|
||||||
|
* no data need to be read.
|
||||||
|
*/
|
||||||
|
if (sta & FTSDC010_STATUS_CMD_SEND)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > FTSDC010_CMD_RETRY) {
|
||||||
|
printf("%s: send command timeout\n", __func__);
|
||||||
|
return TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check rsp status */
|
||||||
|
ret = ftsdc010_check_rsp(mmc, cmd, data);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* read response if we have RSP_OK */
|
||||||
|
if (ccon & FTSDC010_CMD_LONG_RSP) {
|
||||||
|
cmd->response[0] = readl(&host->reg->rsp3);
|
||||||
|
cmd->response[1] = readl(&host->reg->rsp2);
|
||||||
|
cmd->response[2] = readl(&host->reg->rsp1);
|
||||||
|
cmd->response[3] = readl(&host->reg->rsp0);
|
||||||
|
} else {
|
||||||
|
cmd->response[0] = readl(&host->reg->rsp0);
|
||||||
|
}
|
||||||
|
|
||||||
/* read/write data */
|
/* read/write data */
|
||||||
if (data && (data->flags & MMC_DATA_READ)) {
|
if (data && (data->flags & MMC_DATA_READ)) {
|
||||||
@ -351,19 +376,11 @@ static int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
|||||||
data->blocksize * data->blocks);
|
data->blocksize * data->blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pio check response status */
|
/* check data status */
|
||||||
ret = ftsdc010_pio_check_status(mmc, cmd, data);
|
if (data) {
|
||||||
if (!ret) {
|
ret = ftsdc010_check_data(mmc, cmd, data);
|
||||||
/* if it is long response */
|
if (ret)
|
||||||
if (ccon & FTSDC010_CMD_LONG_RSP) {
|
return ret;
|
||||||
cmd->response[0] = readl(&host->reg->rsp3);
|
|
||||||
cmd->response[1] = readl(&host->reg->rsp2);
|
|
||||||
cmd->response[2] = readl(&host->reg->rsp1);
|
|
||||||
cmd->response[3] = readl(&host->reg->rsp0);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cmd->response[0] = readl(&host->reg->rsp0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
udelay(FTSDC010_DELAY_UNIT);
|
udelay(FTSDC010_DELAY_UNIT);
|
||||||
@ -431,8 +448,6 @@ static int ftsdc010_setup_data(struct mmc *mmc, struct mmc_data *data)
|
|||||||
/* always reset fifo since last transfer may fail */
|
/* always reset fifo since last transfer may fail */
|
||||||
dcon |= FTSDC010_DCR_FIFO_RST;
|
dcon |= FTSDC010_DCR_FIFO_RST;
|
||||||
|
|
||||||
/* handle sdio */
|
|
||||||
dcon = data->blocksize | data->blocks << 15;
|
|
||||||
if (data->blocks > 1)
|
if (data->blocks > 1)
|
||||||
dcon |= FTSDC010_SDIO_CTRL1_SDIO_BLK_MODE;
|
dcon |= FTSDC010_SDIO_CTRL1_SDIO_BLK_MODE;
|
||||||
#endif
|
#endif
|
||||||
@ -497,7 +512,7 @@ static void ftsdc010_set_clk(struct mmc *mmc)
|
|||||||
{
|
{
|
||||||
struct mmc_host *host = mmc->priv;
|
struct mmc_host *host = mmc->priv;
|
||||||
unsigned char clk_div;
|
unsigned char clk_div;
|
||||||
unsigned char real_rate;
|
unsigned int real_rate;
|
||||||
unsigned int clock;
|
unsigned int clock;
|
||||||
|
|
||||||
debug("%s: mmc_set_clock: %x\n", __func__, mmc->clock);
|
debug("%s: mmc_set_clock: %x\n", __func__, mmc->clock);
|
||||||
@ -518,7 +533,7 @@ static void ftsdc010_set_clk(struct mmc *mmc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("%s: computed real_rete: %x, clk_div: %x\n",
|
debug("%s: computed real_rate: %x, clk_div: %x\n",
|
||||||
__func__, real_rate, clk_div);
|
__func__, real_rate, clk_div);
|
||||||
|
|
||||||
if (clk_div > 127)
|
if (clk_div > 127)
|
||||||
@ -579,6 +594,7 @@ static void ftsdc010_set_ios(struct mmc *mmc)
|
|||||||
static void ftsdc010_reset(struct mmc_host *host)
|
static void ftsdc010_reset(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
unsigned int timeout;
|
unsigned int timeout;
|
||||||
|
unsigned int sta;
|
||||||
|
|
||||||
/* Do SDC_RST: Software reset for all register */
|
/* Do SDC_RST: Software reset for all register */
|
||||||
writel(FTSDC010_CMD_SDC_RST, &host->reg->cmd);
|
writel(FTSDC010_CMD_SDC_RST, &host->reg->cmd);
|
||||||
@ -598,6 +614,10 @@ static void ftsdc010_reset(struct mmc_host *host)
|
|||||||
timeout--;
|
timeout--;
|
||||||
udelay(10*FTSDC010_DELAY_UNIT);
|
udelay(10*FTSDC010_DELAY_UNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sta = readl(&host->reg->status);
|
||||||
|
if (sta & FTSDC010_STATUS_CARD_CHANGE)
|
||||||
|
writel(FTSDC010_CLR_CARD_CHANGE, &host->reg->clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftsdc010_core_init(struct mmc *mmc)
|
static int ftsdc010_core_init(struct mmc *mmc)
|
||||||
@ -645,13 +665,12 @@ int ftsdc010_mmc_init(int dev_index)
|
|||||||
mmc->send_cmd = ftsdc010_request;
|
mmc->send_cmd = ftsdc010_request;
|
||||||
mmc->set_ios = ftsdc010_set_ios;
|
mmc->set_ios = ftsdc010_set_ios;
|
||||||
mmc->init = ftsdc010_core_init;
|
mmc->init = ftsdc010_core_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
|
|
||||||
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
|
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
|
||||||
|
|
||||||
mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
|
|
||||||
|
|
||||||
mmc->f_min = CONFIG_SYS_CLK_FREQ / 2 / (2*128);
|
mmc->f_min = CONFIG_SYS_CLK_FREQ / 2 / (2*128);
|
||||||
mmc->f_max = CONFIG_SYS_CLK_FREQ / 2 / 2;
|
mmc->f_max = CONFIG_SYS_CLK_FREQ / 2 / 2;
|
||||||
|
|
||||||
|
@ -337,6 +337,7 @@ int atmel_mci_init(void *regs)
|
|||||||
mmc->send_cmd = mci_send_cmd;
|
mmc->send_cmd = mci_send_cmd;
|
||||||
mmc->set_ios = mci_set_ios;
|
mmc->set_ios = mci_set_ios;
|
||||||
mmc->init = mci_init;
|
mmc->init = mci_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
/* need to be able to pass these in on a board by board basis */
|
/* need to be able to pass these in on a board by board basis */
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
|
@ -40,11 +40,11 @@
|
|||||||
static struct list_head mmc_devices;
|
static struct list_head mmc_devices;
|
||||||
static int cur_dev_num = -1;
|
static int cur_dev_num = -1;
|
||||||
|
|
||||||
int __board_mmc_getcd(u8 *cd, struct mmc *mmc) {
|
int __board_mmc_getcd(struct mmc *mmc) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak,
|
int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
|
||||||
alias("__board_mmc_getcd")));
|
alias("__board_mmc_getcd")));
|
||||||
|
|
||||||
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
@ -674,6 +674,18 @@ int mmc_switch_part(int dev_num, unsigned int part_num)
|
|||||||
| (part_num & PART_ACCESS_MASK));
|
| (part_num & PART_ACCESS_MASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mmc_getcd(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
int cd;
|
||||||
|
|
||||||
|
cd = board_mmc_getcd(mmc);
|
||||||
|
|
||||||
|
if ((cd < 0) && mmc->getcd)
|
||||||
|
cd = mmc->getcd(mmc);
|
||||||
|
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
|
int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
|
||||||
{
|
{
|
||||||
struct mmc_cmd cmd;
|
struct mmc_cmd cmd;
|
||||||
@ -785,6 +797,16 @@ retry_scr:
|
|||||||
if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
|
if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the host doesn't support SD_HIGHSPEED, do not switch card to
|
||||||
|
* HIGHSPEED mode even if the card support SD_HIGHSPPED.
|
||||||
|
* This can avoid furthur problem when the card runs in different
|
||||||
|
* mode between the host.
|
||||||
|
*/
|
||||||
|
if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
|
||||||
|
(mmc->host_caps & MMC_MODE_HS)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
|
err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -1192,6 +1214,12 @@ int mmc_init(struct mmc *mmc)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (mmc_getcd(mmc) == 0) {
|
||||||
|
mmc->has_init = 0;
|
||||||
|
printf("MMC: no card present\n");
|
||||||
|
return NO_CARD_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
if (mmc->has_init)
|
if (mmc->has_init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -272,6 +272,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
|
|||||||
mmc->send_cmd = mmc_spi_request;
|
mmc->send_cmd = mmc_spi_request;
|
||||||
mmc->set_ios = mmc_spi_set_ios;
|
mmc->set_ios = mmc_spi_set_ios;
|
||||||
mmc->init = mmc_spi_init_p;
|
mmc->init = mmc_spi_init_p;
|
||||||
|
mmc->getcd = NULL;
|
||||||
mmc->host_caps = MMC_MODE_SPI;
|
mmc->host_caps = MMC_MODE_SPI;
|
||||||
|
|
||||||
mmc->voltages = MMC_SPI_VOLTAGE;
|
mmc->voltages = MMC_SPI_VOLTAGE;
|
||||||
|
@ -44,7 +44,6 @@ int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
|
|||||||
host->quirks = quirks;
|
host->quirks = quirks;
|
||||||
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
|
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
|
||||||
memset(&mv_ops, 0, sizeof(struct sdhci_ops));
|
memset(&mv_ops, 0, sizeof(struct sdhci_ops));
|
||||||
if (mv_sdhci_writeb != NULL)
|
|
||||||
mv_ops.write_b = mv_sdhci_writeb;
|
mv_ops.write_b = mv_sdhci_writeb;
|
||||||
host->ops = &mv_ops;
|
host->ops = &mv_ops;
|
||||||
#endif
|
#endif
|
||||||
|
@ -500,6 +500,7 @@ static int mxcmci_initialize(bd_t *bis)
|
|||||||
mmc->send_cmd = mxcmci_request;
|
mmc->send_cmd = mxcmci_request;
|
||||||
mmc->set_ios = mxcmci_set_ios;
|
mmc->set_ios = mxcmci_set_ios;
|
||||||
mmc->init = mxcmci_init;
|
mmc->init = mxcmci_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
mmc->host_caps = MMC_MODE_4BIT;
|
mmc->host_caps = MMC_MODE_4BIT;
|
||||||
|
|
||||||
host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
|
host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
|
||||||
|
@ -329,6 +329,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))
|
|||||||
mmc->send_cmd = mxsmmc_send_cmd;
|
mmc->send_cmd = mxsmmc_send_cmd;
|
||||||
mmc->set_ios = mxsmmc_set_ios;
|
mmc->set_ios = mxsmmc_set_ios;
|
||||||
mmc->init = mxsmmc_init;
|
mmc->init = mxsmmc_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
mmc->priv = priv;
|
mmc->priv = priv;
|
||||||
|
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
|
@ -472,6 +472,7 @@ int omap_mmc_init(int dev_index)
|
|||||||
mmc->send_cmd = mmc_send_cmd;
|
mmc->send_cmd = mmc_send_cmd;
|
||||||
mmc->set_ios = mmc_set_ios;
|
mmc->set_ios = mmc_set_ios;
|
||||||
mmc->init = mmc_init_setup;
|
mmc->init = mmc_init_setup;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
switch (dev_index) {
|
switch (dev_index) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -411,6 +411,7 @@ int pxa_mmc_register(int card_index)
|
|||||||
mmc->send_cmd = pxa_mmc_request;
|
mmc->send_cmd = pxa_mmc_request;
|
||||||
mmc->set_ios = pxa_mmc_set_ios;
|
mmc->set_ios = pxa_mmc_set_ios;
|
||||||
mmc->init = pxa_mmc_init;
|
mmc->init = pxa_mmc_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
mmc->f_max = PXAMMC_MAX_SPEED;
|
mmc->f_max = PXAMMC_MAX_SPEED;
|
||||||
|
@ -463,6 +463,7 @@ static int s5p_mmc_initialize(int dev_index, int bus_width)
|
|||||||
mmc->send_cmd = mmc_send_cmd;
|
mmc->send_cmd = mmc_send_cmd;
|
||||||
mmc->set_ios = mmc_set_ios;
|
mmc->set_ios = mmc_set_ios;
|
||||||
mmc->init = mmc_core_init;
|
mmc->init = mmc_core_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||||
if (bus_width == 8)
|
if (bus_width == 8)
|
||||||
|
@ -390,6 +390,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
|
|||||||
mmc->send_cmd = sdhci_send_command;
|
mmc->send_cmd = sdhci_send_command;
|
||||||
mmc->set_ios = sdhci_set_ios;
|
mmc->set_ios = sdhci_set_ios;
|
||||||
mmc->init = sdhci_init;
|
mmc->init = sdhci_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
|
|
||||||
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
|
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||||
#ifdef CONFIG_MMC_SDMA
|
#ifdef CONFIG_MMC_SDMA
|
||||||
|
@ -598,6 +598,7 @@ int mmcif_mmc_init(void)
|
|||||||
mmc->send_cmd = sh_mmcif_request;
|
mmc->send_cmd = sh_mmcif_request;
|
||||||
mmc->set_ios = sh_mmcif_set_ios;
|
mmc->set_ios = sh_mmcif_set_ios;
|
||||||
mmc->init = sh_mmcif_init;
|
mmc->init = sh_mmcif_init;
|
||||||
|
mmc->getcd = NULL;
|
||||||
host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
|
host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
|
||||||
host->clk = CONFIG_SH_MMCIF_CLK;
|
host->clk = CONFIG_SH_MMCIF_CLK;
|
||||||
mmc->priv = host;
|
mmc->priv = host;
|
||||||
|
@ -474,6 +474,18 @@ static int mmc_core_init(struct mmc *mmc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tegra2_mmc_getcd(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
struct mmc_host *host = (struct mmc_host *)mmc->priv;
|
||||||
|
|
||||||
|
debug("tegra2_mmc_getcd called\n");
|
||||||
|
|
||||||
|
if (host->cd_gpio >= 0)
|
||||||
|
return !gpio_get_value(host->cd_gpio);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
|
int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
|
||||||
{
|
{
|
||||||
struct mmc_host *host;
|
struct mmc_host *host;
|
||||||
@ -512,6 +524,7 @@ int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
|
|||||||
mmc->send_cmd = mmc_send_cmd;
|
mmc->send_cmd = mmc_send_cmd;
|
||||||
mmc->set_ios = mmc_set_ios;
|
mmc->set_ios = mmc_set_ios;
|
||||||
mmc->init = mmc_core_init;
|
mmc->init = mmc_core_init;
|
||||||
|
mmc->getcd = tegra2_mmc_getcd;
|
||||||
|
|
||||||
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||||
if (bus_width == 8)
|
if (bus_width == 8)
|
||||||
@ -535,22 +548,3 @@ int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is a weak define that we are overriding */
|
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc)
|
|
||||||
{
|
|
||||||
struct mmc_host *host = (struct mmc_host *)mmc->priv;
|
|
||||||
|
|
||||||
debug("board_mmc_getcd called\n");
|
|
||||||
|
|
||||||
*cd = 1; /* Assume card is inserted, or eMMC */
|
|
||||||
|
|
||||||
if (IS_SD(mmc)) {
|
|
||||||
if (host->cd_gpio >= 0) {
|
|
||||||
if (gpio_get_value(host->cd_gpio))
|
|
||||||
*cd = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -302,6 +302,7 @@ struct mmc {
|
|||||||
struct mmc_cmd *cmd, struct mmc_data *data);
|
struct mmc_cmd *cmd, struct mmc_data *data);
|
||||||
void (*set_ios)(struct mmc *mmc);
|
void (*set_ios)(struct mmc *mmc);
|
||||||
int (*init)(struct mmc *mmc);
|
int (*init)(struct mmc *mmc);
|
||||||
|
int (*getcd)(struct mmc *mmc);
|
||||||
uint b_max;
|
uint b_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -314,8 +315,9 @@ struct mmc *find_mmc_device(int dev_num);
|
|||||||
int mmc_set_dev(int dev_num);
|
int mmc_set_dev(int dev_num);
|
||||||
void print_mmc_devices(char separator);
|
void print_mmc_devices(char separator);
|
||||||
int get_mmc_num(void);
|
int get_mmc_num(void);
|
||||||
int board_mmc_getcd(u8 *cd, struct mmc *mmc);
|
int board_mmc_getcd(struct mmc *mmc);
|
||||||
int mmc_switch_part(int dev_num, unsigned int part_num);
|
int mmc_switch_part(int dev_num, unsigned int part_num);
|
||||||
|
int mmc_getcd(struct mmc *mmc);
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_MMC
|
#ifdef CONFIG_GENERIC_MMC
|
||||||
int atmel_mci_init(void *regs);
|
int atmel_mci_init(void *regs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user