
Hi Bo,
On Jul 31, 2014, at 9:39 AM, Bo Shen wrote:
The mode register is different between MCI IP version. So, according to MCI IP version to set the mode register.
Signed-off-by: Bo Shen voice.shen@atmel.com
drivers/mmc/gen_atmel_mci.c | 56 +++++++++++++++++++++++++++++++++------------ include/atmel_mci.h | 4 ++++ 2 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index a57a9b1..8778a4d 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -58,30 +58,58 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) atmel_mci_t *mci = mmc->priv; u32 bus_hz = get_mci_clk_rate(); u32 clkdiv = 255;
unsigned int version = atmel_mci_get_version(mci);
u32 clkodd = 0;
u32 mr;
debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n", bus_hz, hz, blklen); if (hz > 0) {
/* find lowest clkdiv yielding a rate <= than requested */
for (clkdiv=0; clkdiv<255; clkdiv++) {
if ((bus_hz / (clkdiv+1) / 2) <= hz)
break;
if (version >= 0x500) {
clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
if (clkdiv > 511)
clkdiv = 511;
clkodd = clkdiv & 1;
clkdiv >>= 1;
printf("mci: setting clock %u Hz, block size %u\n",
bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
} else {
/* find clkdiv yielding a rate <= than requested */
for (clkdiv = 0; clkdiv < 255; clkdiv++) {
if ((bus_hz / (clkdiv + 1) / 2) <= hz)
break;
}
printf("mci: setting clock %u Hz, block size %u\n",
(bus_hz / (clkdiv + 1)) / 2, blklen);
- } }
printf("mci: setting clock %u Hz, block size %u\n",
(bus_hz / (clkdiv+1)) / 2, blklen);
blklen &= 0xfffc;
/* On some platforms RDPROOF and WRPROOF are ignored */
writel((MMCI_BF(CLKDIV, clkdiv)
| MMCI_BF(BLKLEN, blklen)
| MMCI_BIT(RDPROOF)
| MMCI_BIT(WRPROOF)), &mci->mr);
- mr = MMCI_BF(CLKDIV, clkdiv);
- /* MCI IP version >= 0x200 has R/WPROOF */
- if (version >= 0x200)
mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF);
- /*
* On some new platforms BLKLEN in mci->mr is ignored.
* Should use the BLKLEN in the block register.
* MCI IP version >= 0x500 use bit 16 as clkodd.
*/* MCI IP version < 0x500 use upper 16 bits for blklen.
- writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
- if (version >= 0x500)
mr |= MMCI_BF(CLKODD, clkodd);
- else
mr |= MMCI_BF(BLKLEN, blklen);
- writel(mr, &mci->mr);
- /* MCI IP version >= 0x200 has blkr */
- if (version >= 0x200)
writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
- initialized = 1;
}
diff --git a/include/atmel_mci.h b/include/atmel_mci.h index 090574d..3d2870f 100644 --- a/include/atmel_mci.h +++ b/include/atmel_mci.h @@ -67,6 +67,10 @@ typedef struct atmel_mci { #define MMCI_PDCPADV_SIZE 1 #define MMCI_PDCMODE_OFFSET 15 #define MMCI_PDCMODE_SIZE 1 +/* MCI IP version >= 0x500, MR bit 16 used for CLKODD */ +#define MMCI_CLKODD_OFFSET 16 +#define MMCI_CLKODD_SIZE 1 +/* MCI IP version < 0x200, MR higher 16bits for BLKLEN */ #define MMCI_BLKLEN_OFFSET 16 #define MMCI_BLKLEN_SIZE 16
-- 1.8.5.2
Looks good.
Applied, thanks.