Commit cd60ebd430ab0aa5e2ed6afeb28c1ed4b2d01388
Committed by
Pantelis Antoniou
1 parent
6ace153d13
Exists in
v2017.01-smarct4x
and in
37 other branches
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>
Showing 2 changed files with 46 additions and 14 deletions Side-by-side Diff
drivers/mmc/gen_atmel_mci.c
... | ... | @@ -58,30 +58,58 @@ |
58 | 58 | atmel_mci_t *mci = mmc->priv; |
59 | 59 | u32 bus_hz = get_mci_clk_rate(); |
60 | 60 | u32 clkdiv = 255; |
61 | + unsigned int version = atmel_mci_get_version(mci); | |
62 | + u32 clkodd = 0; | |
63 | + u32 mr; | |
61 | 64 | |
62 | 65 | debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n", |
63 | 66 | bus_hz, hz, blklen); |
64 | 67 | if (hz > 0) { |
65 | - /* find lowest clkdiv yielding a rate <= than requested */ | |
66 | - for (clkdiv=0; clkdiv<255; clkdiv++) { | |
67 | - if ((bus_hz / (clkdiv+1) / 2) <= hz) | |
68 | - break; | |
68 | + if (version >= 0x500) { | |
69 | + clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2; | |
70 | + if (clkdiv > 511) | |
71 | + clkdiv = 511; | |
72 | + | |
73 | + clkodd = clkdiv & 1; | |
74 | + clkdiv >>= 1; | |
75 | + | |
76 | + printf("mci: setting clock %u Hz, block size %u\n", | |
77 | + bus_hz / (clkdiv * 2 + clkodd + 2), blklen); | |
78 | + } else { | |
79 | + /* find clkdiv yielding a rate <= than requested */ | |
80 | + for (clkdiv = 0; clkdiv < 255; clkdiv++) { | |
81 | + if ((bus_hz / (clkdiv + 1) / 2) <= hz) | |
82 | + break; | |
83 | + } | |
84 | + printf("mci: setting clock %u Hz, block size %u\n", | |
85 | + (bus_hz / (clkdiv + 1)) / 2, blklen); | |
86 | + | |
69 | 87 | } |
70 | 88 | } |
71 | - printf("mci: setting clock %u Hz, block size %u\n", | |
72 | - (bus_hz / (clkdiv+1)) / 2, blklen); | |
73 | 89 | |
74 | 90 | blklen &= 0xfffc; |
75 | - /* On some platforms RDPROOF and WRPROOF are ignored */ | |
76 | - writel((MMCI_BF(CLKDIV, clkdiv) | |
77 | - | MMCI_BF(BLKLEN, blklen) | |
78 | - | MMCI_BIT(RDPROOF) | |
79 | - | MMCI_BIT(WRPROOF)), &mci->mr); | |
91 | + | |
92 | + mr = MMCI_BF(CLKDIV, clkdiv); | |
93 | + | |
94 | + /* MCI IP version >= 0x200 has R/WPROOF */ | |
95 | + if (version >= 0x200) | |
96 | + mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF); | |
97 | + | |
80 | 98 | /* |
81 | - * On some new platforms BLKLEN in mci->mr is ignored. | |
82 | - * Should use the BLKLEN in the block register. | |
99 | + * MCI IP version >= 0x500 use bit 16 as clkodd. | |
100 | + * MCI IP version < 0x500 use upper 16 bits for blklen. | |
83 | 101 | */ |
84 | - writel(MMCI_BF(BLKLEN, blklen), &mci->blkr); | |
102 | + if (version >= 0x500) | |
103 | + mr |= MMCI_BF(CLKODD, clkodd); | |
104 | + else | |
105 | + mr |= MMCI_BF(BLKLEN, blklen); | |
106 | + | |
107 | + writel(mr, &mci->mr); | |
108 | + | |
109 | + /* MCI IP version >= 0x200 has blkr */ | |
110 | + if (version >= 0x200) | |
111 | + writel(MMCI_BF(BLKLEN, blklen), &mci->blkr); | |
112 | + | |
85 | 113 | initialized = 1; |
86 | 114 | } |
87 | 115 |
include/atmel_mci.h
... | ... | @@ -67,6 +67,10 @@ |
67 | 67 | #define MMCI_PDCPADV_SIZE 1 |
68 | 68 | #define MMCI_PDCMODE_OFFSET 15 |
69 | 69 | #define MMCI_PDCMODE_SIZE 1 |
70 | +/* MCI IP version >= 0x500, MR bit 16 used for CLKODD */ | |
71 | +#define MMCI_CLKODD_OFFSET 16 | |
72 | +#define MMCI_CLKODD_SIZE 1 | |
73 | +/* MCI IP version < 0x200, MR higher 16bits for BLKLEN */ | |
70 | 74 | #define MMCI_BLKLEN_OFFSET 16 |
71 | 75 | #define MMCI_BLKLEN_SIZE 16 |
72 | 76 |