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.s...@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. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot