MMC: atmel_mci: refactor setting the mode register

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>
Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>
master
Bo Shen 10 years ago committed by Pantelis Antoniou
parent 6ace153d13
commit cd60ebd430
  1. 56
      drivers/mmc/gen_atmel_mci.c
  2. 4
      include/atmel_mci.h

@ -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;
}

@ -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

Loading…
Cancel
Save