diff options
author | Bo Shen <voice.shen@atmel.com> | 2013-04-26 00:27:06 +0000 |
---|---|---|
committer | Andreas Bießmann <andreas.devel@googlemail.com> | 2013-05-12 16:47:05 +0200 |
commit | aac4b69b2c916736911976562bfc0cb4bfd26b2f (patch) | |
tree | a744ebe992695c7df134528db1e08fab71bcbf90 /drivers | |
parent | 248020734b83d4bd6f329095b7186dea16552909 (diff) | |
download | u-boot-imx-aac4b69b2c916736911976562bfc0cb4bfd26b2f.zip u-boot-imx-aac4b69b2c916736911976562bfc0cb4bfd26b2f.tar.gz u-boot-imx-aac4b69b2c916736911976562bfc0cb4bfd26b2f.tar.bz2 |
mmc: atmel_mci: using IP version for different setting
Using IP version for different setting
- Higher version supports 8bit mode
- Higher version bus width setting is different
Signed-off-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 70a9f91..fc0a181 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -50,6 +50,12 @@ static int initialized = 0; +/* Read Atmel MCI IP version */ +static unsigned int atmel_mci_get_version(struct atmel_mci *mci) +{ + return readl(&mci->version) & 0x00000fff; +} + /* * Print command and status: * @@ -297,7 +303,9 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) static void mci_set_ios(struct mmc *mmc) { atmel_mci_t *mci = (atmel_mci_t *)mmc->priv; - int busw = (mmc->bus_width == 4) ? 1 : 0; + int bus_width = mmc->bus_width; + unsigned int version = atmel_mci_get_version(mci); + int busw; /* Set the clock speed */ mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN); @@ -305,9 +313,26 @@ static void mci_set_ios(struct mmc *mmc) /* * set the bus width and select slot for this interface * there is no capability for multiple slots on the same interface yet - * Bitfield SCDBUS needs to be expanded to 2 bits for 8-bit buses */ - writel(MMCI_BF(SCDBUS, busw) | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); + if ((version & 0xf00) >= 0x300) { + switch (bus_width) { + case 8: + busw = 3; + break; + case 4: + busw = 2; + break; + default: + busw = 0; + break; + } + + writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); + } else { + busw = (bus_width == 4) ? 1 : 0; + + writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); + } } /* Entered into mmc structure during driver init */ @@ -340,9 +365,12 @@ static int mci_init(struct mmc *mmc) int atmel_mci_init(void *regs) { struct mmc *mmc = malloc(sizeof(struct mmc)); + struct atmel_mci *mci; + unsigned int version; if (!mmc) return -1; + strcpy(mmc->name, "mci"); mmc->priv = regs; mmc->send_cmd = mci_send_cmd; @@ -353,7 +381,13 @@ int atmel_mci_init(void *regs) /* 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->host_caps = MMC_MODE_4BIT; + mci = (struct atmel_mci *)mmc->priv; + version = atmel_mci_get_version(mci); + if ((version & 0xf00) >= 0x300) + mmc->host_caps = MMC_MODE_8BIT; + + mmc->host_caps |= MMC_MODE_4BIT; + /* * min and max frequencies determined by * max and min of clock divider |