Message ID | 1406788772-23377-2-git-send-email-voice.shen@atmel.com |
---|---|
State | Accepted |
Delegated to: | Pantelis Antoniou |
Headers | show |
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.
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
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(-)