diff options
author | Sukumar Ghorai | 2009-12-17 14:20:49 -0600 |
---|---|---|
committer | Vikram Pandita | 2009-12-18 08:30:38 -0600 |
commit | cfff3fc44b70ba6d40ef9627db939239e3566377 (patch) | |
tree | ec9d4ba48e30000affe4feca397d1f068f4951c9 | |
parent | 2c5c4b4c5b44e697147be0d54fe49a12d5680dc1 (diff) | |
download | psdkla-u-boot-cfff3fc44b70ba6d40ef9627db939239e3566377.tar.gz psdkla-u-boot-cfff3fc44b70ba6d40ef9627db939239e3566377.tar.xz psdkla-u-boot-cfff3fc44b70ba6d40ef9627db939239e3566377.zip |
Add MMC2 support for OMAP3
MMC files have been modified to add support for MMC2.
Write functionality has been added.
Signed-off-by: Sukumar Ghorai<s-ghorai@ti.com>
Signed-off-by: Christina Warren <cawarren@ti.com>
-rw-r--r-- | cpu/omap3/mmc.c | 701 | ||||
-rw-r--r-- | cpu/omap3/mmc_host_def.h | 50 | ||||
-rw-r--r-- | cpu/omap3/mmc_protocol.h | 1 | ||||
-rw-r--r-- | include/mmc.h | 13 | ||||
-rw-r--r-- | include/part.h | 1 |
5 files changed, 572 insertions, 194 deletions
diff --git a/cpu/omap3/mmc.c b/cpu/omap3/mmc.c index 8c185bc26f..9bd78c8296 100644 --- a/cpu/omap3/mmc.c +++ b/cpu/omap3/mmc.c | |||
@@ -25,71 +25,113 @@ | |||
25 | #include <common.h> | 25 | #include <common.h> |
26 | #include <mmc.h> | 26 | #include <mmc.h> |
27 | #include <part.h> | 27 | #include <part.h> |
28 | |||
29 | #if CONFIG_DRIVER_OMAP34XX_I2C /* don't compile for x-loader */ | ||
28 | #include <i2c.h> | 30 | #include <i2c.h> |
31 | #endif | ||
32 | |||
33 | #ifdef DEBUG | ||
34 | #define MMC_DPRINT(args...) printf(args) | ||
35 | #else | ||
36 | #define MMC_DPRINT(args...) | ||
37 | #endif | ||
29 | 38 | ||
30 | #ifdef CONFIG_MMC | 39 | #ifdef CONFIG_MMC |
31 | #include "mmc_host_def.h" | 40 | #include "mmc_host_def.h" |
32 | #include "mmc_protocol.h" | 41 | #include "mmc_protocol.h" |
33 | 42 | ||
34 | #define OMAP_MMC_MASTER_CLOCK 96000000 | 43 | #define OMAP_MMC_MASTER_CLOCK 96000000 |
35 | extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no); | ||
36 | 44 | ||
37 | mmc_card_data cur_card_data; | 45 | mmc_card_data cur_card_data[2]; |
38 | static block_dev_desc_t mmc_blk_dev; | 46 | static block_dev_desc_t mmc_blk_dev[2]; |
39 | 47 | ||
40 | block_dev_desc_t *mmc_get_dev(int dev) | 48 | block_dev_desc_t *mmc_get_dev(int dev) |
41 | { | 49 | { |
42 | return ((block_dev_desc_t *) &mmc_blk_dev); | 50 | |
51 | if ((dev == 0) || (dev == 1)) { | ||
52 | if (cur_card_data[dev].size == 0) | ||
53 | printf("Card is not Initalized (e.g. mmc init 0)\n"); | ||
54 | else | ||
55 | return &mmc_blk_dev[dev]; | ||
56 | } | ||
57 | return NULL; | ||
43 | } | 58 | } |
44 | 59 | ||
45 | void twl4030_mmc_config(void) | 60 | #if CONFIG_DRIVER_OMAP34XX_I2C /* don't compile for x-loader */ |
61 | static void twl4030_mmc_config(unsigned int slot) | ||
46 | { | 62 | { |
47 | unsigned char data; | 63 | unsigned char data; |
48 | 64 | ||
49 | data = 0x20; | 65 | /* configure the LDO */ |
50 | i2c_write(0x4B, 0x82, 1, &data, 1); | 66 | if (slot == 0) { |
51 | data = 0x2; | 67 | data = 0x20; |
52 | i2c_write(0x4B, 0x85, 1, &data, 1); | 68 | i2c_write(0x4B, 0x82, 1, &data, 1); |
69 | data = 0x2; | ||
70 | i2c_write(0x4B, 0x85, 1, &data, 1); | ||
71 | } else { | ||
72 | data = 0x20; | ||
73 | i2c_write(0x4B, 0x86, 1, &data, 1); | ||
74 | data = 0xB; | ||
75 | i2c_write(0x4B, 0x89, 1, &data, 1); | ||
76 | } | ||
53 | return; | 77 | return; |
54 | } | 78 | } |
79 | #endif | ||
55 | 80 | ||
56 | unsigned char mmc_board_init(void) | 81 | static int mmc_board_init(unsigned int slot) |
57 | { | 82 | { |
58 | unsigned int value = 0; | 83 | unsigned int value = 0; |
59 | 84 | ||
60 | twl4030_mmc_config(); | 85 | MMC_DPRINT("+mmc_board_init : slot=%d\n", slot); |
86 | |||
87 | #if CONFIG_DRIVER_OMAP34XX_I2C /* don't compile for x-loader */ | ||
88 | twl4030_mmc_config(slot); | ||
89 | #endif | ||
61 | 90 | ||
62 | value = CONTROL_PBIAS_LITE; | 91 | if (slot == 0) { |
63 | CONTROL_PBIAS_LITE = value | (1 << 2) | (1 << 1) | (1 << 9); | 92 | value = CONTROL_PBIAS_LITE; |
93 | CONTROL_PBIAS_LITE = value | (1 << 2) | (1 << 1) | (1 << 9); | ||
64 | 94 | ||
65 | value = CONTROL_DEV_CONF0; | 95 | value = CONTROL_DEV_CONF0; |
66 | CONTROL_DEV_CONF0 = value | (1 << 24); | 96 | CONTROL_DEV_CONF0 = value | (1 << 24); |
67 | 97 | ||
68 | return 1; | 98 | } else if (slot == 1) { |
99 | value = CONTROL_DEV_CONF1; | ||
100 | CONTROL_DEV_CONF1 = value | (1 << 6); | ||
101 | value = (*(volatile unsigned int *)CM_FCLKEN1_CORE); | ||
102 | (*(volatile unsigned int *)CM_FCLKEN1_CORE) = value | (1 << 25); | ||
103 | value = (*(volatile unsigned int *)CM_ICLKEN1_CORE); | ||
104 | (*(volatile unsigned int *)CM_ICLKEN1_CORE) = value | (1 << 25); | ||
105 | } | ||
106 | return 0; | ||
69 | } | 107 | } |
70 | 108 | ||
71 | void mmc_init_stream(void) | 109 | static void mmc_init_stream(unsigned int base) |
72 | { | 110 | { |
73 | OMAP_HSMMC_CON |= INIT_INITSTREAM; | 111 | MMC_DPRINT("+mmc_init_stream\n"); |
112 | OMAP_HSMMC_CON(base) |= INIT_INITSTREAM; | ||
74 | 113 | ||
75 | OMAP_HSMMC_CMD = MMC_CMD0; | 114 | OMAP_HSMMC_CMD(base) = MMC_CMD0; |
76 | while (!(OMAP_HSMMC_STAT & CC_MASK)); | 115 | while (!(OMAP_HSMMC_STAT(base) & CC_MASK)) |
116 | ; | ||
77 | 117 | ||
78 | OMAP_HSMMC_STAT = CC_MASK; | 118 | OMAP_HSMMC_STAT(base) = CC_MASK; |
79 | 119 | ||
80 | OMAP_HSMMC_CMD = MMC_CMD0; | 120 | OMAP_HSMMC_CMD(base) = MMC_CMD0; |
81 | while (!(OMAP_HSMMC_STAT & CC_MASK)); | 121 | while (!(OMAP_HSMMC_STAT(base) & CC_MASK)) |
122 | ; | ||
82 | 123 | ||
83 | 124 | OMAP_HSMMC_STAT(base) = OMAP_HSMMC_STAT(base); | |
84 | OMAP_HSMMC_STAT = OMAP_HSMMC_STAT; | 125 | OMAP_HSMMC_CON(base) &= ~INIT_INITSTREAM; |
85 | OMAP_HSMMC_CON &= ~INIT_INITSTREAM; | ||
86 | } | 126 | } |
87 | 127 | ||
88 | unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div) | 128 | static int mmc_clock_config(unsigned int base, unsigned int iclk, |
129 | unsigned short clk_div) | ||
89 | { | 130 | { |
90 | unsigned int val; | 131 | unsigned int val; |
91 | 132 | ||
92 | mmc_reg_out(OMAP_HSMMC_SYSCTL, (ICE_MASK | DTO_MASK | CEN_MASK), | 133 | MMC_DPRINT("+mmc_clock_config : base=0x%x\n", base); |
134 | mmc_reg_out(OMAP_HSMMC_SYSCTL(base), (ICE_MASK | DTO_MASK | CEN_MASK), | ||
93 | (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); | 135 | (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); |
94 | 136 | ||
95 | switch (iclk) { | 137 | switch (iclk) { |
@@ -103,87 +145,94 @@ unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div) | |||
103 | val = clk_div; | 145 | val = clk_div; |
104 | break; | 146 | break; |
105 | default: | 147 | default: |
106 | return 0; | 148 | return 1; |
107 | } | 149 | } |
108 | mmc_reg_out(OMAP_HSMMC_SYSCTL, | 150 | mmc_reg_out(OMAP_HSMMC_SYSCTL(base), |
109 | ICE_MASK | CLKD_MASK, (val << CLKD_OFFSET) | ICE_OSCILLATE); | 151 | ICE_MASK | CLKD_MASK, (val << CLKD_OFFSET) | ICE_OSCILLATE); |
110 | 152 | ||
111 | while ((OMAP_HSMMC_SYSCTL & ICS_MASK) == ICS_NOTREADY); | 153 | while ((OMAP_HSMMC_SYSCTL(base) & ICS_MASK) == ICS_NOTREADY) |
154 | ; | ||
112 | 155 | ||
113 | 156 | ||
114 | OMAP_HSMMC_SYSCTL |= CEN_ENABLE; | 157 | OMAP_HSMMC_SYSCTL(base) |= CEN_ENABLE; |
115 | return 1; | 158 | return 0; |
116 | } | 159 | } |
117 | 160 | ||
118 | unsigned char mmc_init_setup(void) | 161 | static int mmc_init_setup(mmc_card_data *mmc_c) |
119 | { | 162 | { |
120 | unsigned int reg_val; | 163 | unsigned int reg_val; |
164 | unsigned int base = mmc_c->base; | ||
121 | 165 | ||
122 | mmc_board_init(); | 166 | MMC_DPRINT("+mmc_init_setup\n"); |
167 | mmc_board_init(mmc_c->slot); | ||
123 | 168 | ||
124 | OMAP_HSMMC_SYSCONFIG |= MMC_SOFTRESET; | 169 | OMAP_HSMMC_SYSCONFIG(base) |= MMC_SOFTRESET; |
125 | while ((OMAP_HSMMC_SYSSTATUS & RESETDONE) == 0) ; | 170 | while ((OMAP_HSMMC_SYSSTATUS(base) & RESETDONE) == 0) |
171 | ; | ||
126 | 172 | ||
127 | OMAP_HSMMC_SYSCTL |= SOFTRESETALL; | 173 | OMAP_HSMMC_SYSCTL(base) |= SOFTRESETALL; |
128 | while ((OMAP_HSMMC_SYSCTL & SOFTRESETALL) != 0x0) ; | 174 | while ((OMAP_HSMMC_SYSCTL(base) & SOFTRESETALL) != 0x0) |
175 | ; | ||
129 | 176 | ||
130 | OMAP_HSMMC_HCTL = DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0; | 177 | OMAP_HSMMC_HCTL(base) = DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0; |
131 | OMAP_HSMMC_CAPA |= VS30_3V0SUP | VS18_1V8SUP; | 178 | OMAP_HSMMC_CAPA(base) |= VS30_3V0SUP | VS18_1V8SUP; |
132 | 179 | ||
133 | reg_val = OMAP_HSMMC_CON & RESERVED_MASK; | 180 | reg_val = OMAP_HSMMC_CON(base) & RESERVED_MASK; |
134 | 181 | ||
135 | OMAP_HSMMC_CON = CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | | 182 | OMAP_HSMMC_CON(base) = CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | |
136 | CDP_ACTIVEHIGH | MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | | 183 | CDP_ACTIVEHIGH | MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | |
137 | STR_BLOCK | HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN; | 184 | STR_BLOCK | HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN; |
138 | 185 | ||
139 | mmc_clock_config(CLK_INITSEQ, 0); | 186 | mmc_clock_config(base, CLK_INITSEQ, 0); |
140 | OMAP_HSMMC_HCTL |= SDBP_PWRON; | 187 | OMAP_HSMMC_HCTL(base) |= SDBP_PWRON; |
141 | 188 | ||
142 | OMAP_HSMMC_IE = 0x307f0033; | 189 | OMAP_HSMMC_IE(base) = OMAP_HSMMC_STATUS_REQ; |
143 | 190 | ||
144 | mmc_init_stream(); | 191 | mmc_init_stream(base); |
145 | return 1; | 192 | return 0; |
146 | } | 193 | } |
147 | 194 | ||
148 | unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg, | 195 | static int mmc_send_cmd(unsigned int base, unsigned int cmd, |
149 | unsigned int *response) | 196 | unsigned int arg, unsigned int *response) |
150 | { | 197 | { |
151 | unsigned int mmc_stat; | 198 | unsigned int mmc_stat; |
152 | 199 | ||
153 | while ((OMAP_HSMMC_PSTATE & DATI_MASK) == DATI_CMDDIS); | 200 | MMC_DPRINT("+mmc_send_cmd cmd=0x%x arg=0x%x\n", cmd, arg); |
201 | while ((OMAP_HSMMC_PSTATE(base) & DATI_MASK) == DATI_CMDDIS) | ||
202 | ; | ||
154 | 203 | ||
155 | 204 | OMAP_HSMMC_BLK(base) = BLEN_512BYTESLEN | NBLK_STPCNT; | |
156 | OMAP_HSMMC_BLK = BLEN_512BYTESLEN | NBLK_STPCNT; | 205 | OMAP_HSMMC_STAT(base) = 0xFFFFFFFF; |
157 | OMAP_HSMMC_STAT = 0xFFFFFFFF; | 206 | OMAP_HSMMC_ARG(base) = arg; |
158 | OMAP_HSMMC_ARG = arg; | 207 | OMAP_HSMMC_CMD(base) = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK | |
159 | OMAP_HSMMC_CMD = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK | | ||
160 | CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | | 208 | CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | |
161 | DE_DISABLE; | 209 | DE_DISABLE; |
162 | 210 | ||
163 | while (1) { | 211 | while (1) { |
164 | do { | 212 | do { |
165 | mmc_stat = OMAP_HSMMC_STAT; | 213 | mmc_stat = OMAP_HSMMC_STAT(base); |
166 | } while (mmc_stat == 0); | 214 | } while (mmc_stat == 0); |
167 | 215 | ||
168 | if ((mmc_stat & ERRI_MASK) != 0) | 216 | if ((mmc_stat & ERRI_MASK) != 0) { |
169 | return (unsigned char)mmc_stat; | 217 | MMC_DPRINT("+mmc_send_cmd err=0x%x\n", mmc_stat); |
170 | 218 | return (unsigned int)mmc_stat; | |
219 | } | ||
171 | 220 | ||
172 | if (mmc_stat & CC_MASK) { | 221 | if (mmc_stat & CC_MASK) { |
173 | OMAP_HSMMC_STAT = CC_MASK; | 222 | OMAP_HSMMC_STAT(base) = CC_MASK; |
174 | response[0] = OMAP_HSMMC_RSP10; | 223 | response[0] = OMAP_HSMMC_RSP10(base); |
175 | if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) { | 224 | if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) { |
176 | response[1] = OMAP_HSMMC_RSP32; | 225 | response[1] = OMAP_HSMMC_RSP32(base); |
177 | response[2] = OMAP_HSMMC_RSP54; | 226 | response[2] = OMAP_HSMMC_RSP54(base); |
178 | response[3] = OMAP_HSMMC_RSP76; | 227 | response[3] = OMAP_HSMMC_RSP76(base); |
179 | } | 228 | } |
180 | break; | 229 | break; |
181 | } | 230 | } |
182 | } | 231 | } |
183 | return 1; | 232 | return 0; |
184 | } | 233 | } |
185 | 234 | ||
186 | unsigned char mmc_read_data(unsigned int *output_buf) | 235 | static int mmc_read_data(unsigned int base, unsigned int *output_buf) |
187 | { | 236 | { |
188 | unsigned int mmc_stat; | 237 | unsigned int mmc_stat; |
189 | unsigned int read_count = 0; | 238 | unsigned int read_count = 0; |
@@ -193,78 +242,125 @@ unsigned char mmc_read_data(unsigned int *output_buf) | |||
193 | */ | 242 | */ |
194 | while (1) { | 243 | while (1) { |
195 | do { | 244 | do { |
196 | mmc_stat = OMAP_HSMMC_STAT; | 245 | mmc_stat = OMAP_HSMMC_STAT(base); |
197 | } while (mmc_stat == 0); | 246 | } while (mmc_stat == 0); |
198 | 247 | ||
199 | if ((mmc_stat & ERRI_MASK) != 0) | 248 | if ((mmc_stat & ERRI_MASK) != 0) |
200 | return (unsigned char)mmc_stat; | 249 | return mmc_stat; |
201 | 250 | ||
202 | if (mmc_stat & BRR_MASK) { | 251 | if (mmc_stat & BRR_MASK) { |
203 | unsigned int k; | 252 | unsigned int k; |
204 | 253 | ||
205 | OMAP_HSMMC_STAT |= BRR_MASK; | 254 | OMAP_HSMMC_STAT(base) |= BRR_MASK; |
206 | for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) { | 255 | for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) { |
207 | *output_buf = OMAP_HSMMC_DATA; | 256 | *output_buf = OMAP_HSMMC_DATA(base); |
208 | output_buf++; | 257 | output_buf++; |
209 | read_count += 4; | 258 | read_count += 4; |
210 | } | 259 | } |
211 | } | 260 | } |
212 | 261 | ||
213 | if (mmc_stat & BWR_MASK) | 262 | if (mmc_stat & BWR_MASK) |
214 | OMAP_HSMMC_STAT |= BWR_MASK; | 263 | OMAP_HSMMC_STAT(base) |= BWR_MASK; |
264 | |||
265 | if (mmc_stat & TC_MASK) { | ||
266 | OMAP_HSMMC_STAT(base) |= TC_MASK; | ||
267 | break; | ||
268 | } | ||
269 | } | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | #if CONFIG_DRIVER_OMAP34XX_I2C /* don't compile for x-loader */ | ||
274 | unsigned int mmc_write_data(unsigned int base, unsigned int *output_buf) | ||
275 | { | ||
276 | unsigned int mmc_stat; | ||
277 | unsigned int write_count = 0; | ||
278 | |||
279 | /* Start Polled write */ | ||
280 | while (1) { | ||
281 | MMC_DPRINT("+mmc_write_data\n"); | ||
282 | do { | ||
283 | mmc_stat = OMAP_HSMMC_STAT(base); | ||
284 | } while (mmc_stat == 0); | ||
285 | |||
286 | if ((mmc_stat & ERRI_MASK) != 0) | ||
287 | return mmc_stat; | ||
288 | |||
289 | if (mmc_stat & BWR_MASK) { | ||
290 | unsigned int k; | ||
291 | |||
292 | OMAP_HSMMC_STAT(base) |= BRR_MASK; | ||
293 | for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) { | ||
294 | OMAP_HSMMC_DATA(base) = *output_buf; | ||
295 | output_buf++; | ||
296 | write_count += 4; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | if (mmc_stat & BWR_MASK) | ||
301 | OMAP_HSMMC_STAT(base) |= BWR_MASK; | ||
215 | 302 | ||
216 | if (mmc_stat & TC_MASK) { | 303 | if (mmc_stat & TC_MASK) { |
217 | OMAP_HSMMC_STAT |= TC_MASK; | 304 | OMAP_HSMMC_STAT(base) |= TC_MASK; |
218 | break; | 305 | break; |
219 | } | 306 | } |
220 | } | 307 | } |
221 | return 1; | 308 | MMC_DPRINT("-mmc_write_data(%d)\n", write_count); |
309 | return 0; | ||
222 | } | 310 | } |
311 | #endif /* CFG_CMD_MMC - not to used x-loader build */ | ||
223 | 312 | ||
224 | unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur) | 313 | static int mmc_detect_card(mmc_card_data *mmc_card_cur) |
225 | { | 314 | { |
226 | unsigned char err; | 315 | unsigned int err; |
227 | unsigned int argument = 0; | 316 | unsigned int argument = 0; |
228 | unsigned int ocr_value, ocr_recvd, ret_cmd41, hcs_val; | 317 | unsigned int ocr_value, ocr_recvd, ret_cmd41, hcs_val; |
229 | unsigned int resp[4]; | 318 | unsigned int resp[4]; |
230 | unsigned short retry_cnt = 2000; | 319 | unsigned short retry_cnt = 2000; |
231 | 320 | ||
321 | MMC_DPRINT("+mmc_detect_card : slot=%d\n", mmc_card_cur->slot); | ||
232 | /* Set to Initialization Clock */ | 322 | /* Set to Initialization Clock */ |
233 | err = mmc_clock_config(CLK_400KHZ, 0); | 323 | err = mmc_clock_config(mmc_card_cur->base, CLK_400KHZ, 0); |
234 | if (err != 1) | 324 | if (err) |
235 | return err; | 325 | return err; |
236 | 326 | ||
237 | mmc_card_cur->RCA = MMC_RELATIVE_CARD_ADDRESS; | 327 | mmc_card_cur->RCA = MMC_RELATIVE_CARD_ADDRESS; |
238 | argument = 0x00000000; | 328 | argument = 0x00000000; |
239 | 329 | ||
240 | ocr_value = (0x1FF << 15); | 330 | if (mmc_card_cur->slot == 0) |
241 | err = mmc_send_cmd(MMC_CMD0, argument, resp); | 331 | ocr_value = (0x1FF << 15); |
242 | if (err != 1) | 332 | else |
333 | ocr_value = (0x80); | ||
334 | |||
335 | err = mmc_send_cmd(mmc_card_cur->base, MMC_CMD0, argument, resp); | ||
336 | if (err) | ||
243 | return err; | 337 | return err; |
244 | 338 | ||
245 | argument = SD_CMD8_CHECK_PATTERN | SD_CMD8_2_7_3_6_V_RANGE; | 339 | argument = SD_CMD8_CHECK_PATTERN | SD_CMD8_2_7_3_6_V_RANGE; |
246 | err = mmc_send_cmd(MMC_SDCMD8, argument, resp); | 340 | err = mmc_send_cmd(mmc_card_cur->base, MMC_SDCMD8, argument, resp); |
247 | hcs_val = (err == 1) ? | 341 | hcs_val = (err == 0) ? |
248 | MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR : | 342 | MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR : |
249 | MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE; | 343 | MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE; |
250 | 344 | ||
251 | argument = 0x0000 << 16; | 345 | argument = 0x0000 << 16; |
252 | err = mmc_send_cmd(MMC_CMD55, argument, resp); | 346 | err = mmc_send_cmd(mmc_card_cur->base, MMC_CMD55, argument, resp); |
253 | if (err == 1) { | 347 | if (err == 0) { |
254 | mmc_card_cur->card_type = SD_CARD; | 348 | mmc_card_cur->card_type = SD_CARD; |
255 | ocr_value |= hcs_val; | 349 | ocr_value |= hcs_val; |
256 | ret_cmd41 = MMC_ACMD41; | 350 | ret_cmd41 = MMC_ACMD41; |
351 | MMC_DPRINT("Card found : SD_CARD\n"); | ||
257 | } else { | 352 | } else { |
258 | mmc_card_cur->card_type = MMC_CARD; | 353 | mmc_card_cur->card_type = MMC_CARD; |
259 | ocr_value |= MMC_OCR_REG_ACCESS_MODE_SECTOR; | 354 | ocr_value |= MMC_OCR_REG_ACCESS_MODE_SECTOR; |
260 | ret_cmd41 = MMC_CMD1; | 355 | ret_cmd41 = MMC_CMD1; |
261 | OMAP_HSMMC_CON &= ~OD; | 356 | OMAP_HSMMC_CON(mmc_card_cur->base) &= ~OD; |
262 | OMAP_HSMMC_CON |= OPENDRAIN; | 357 | OMAP_HSMMC_CON(mmc_card_cur->base) |= OPENDRAIN; |
358 | MMC_DPRINT("Card found : MMC_CARD\n"); | ||
263 | } | 359 | } |
264 | 360 | ||
265 | argument = ocr_value; | 361 | argument = ocr_value; |
266 | err = mmc_send_cmd(ret_cmd41, argument, resp); | 362 | err = mmc_send_cmd(mmc_card_cur->base, ret_cmd41, argument, resp); |
267 | if (err != 1) | 363 | if (err) |
268 | return err; | 364 | return err; |
269 | 365 | ||
270 | ocr_recvd = ((mmc_resp_r3 *) resp)->ocr; | 366 | ocr_recvd = ((mmc_resp_r3 *) resp)->ocr; |
@@ -273,18 +369,21 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur) | |||
273 | retry_cnt--; | 369 | retry_cnt--; |
274 | if (mmc_card_cur->card_type == SD_CARD) { | 370 | if (mmc_card_cur->card_type == SD_CARD) { |
275 | argument = 0x0000 << 16; | 371 | argument = 0x0000 << 16; |
276 | err = mmc_send_cmd(MMC_CMD55, argument, resp); | 372 | err = mmc_send_cmd(mmc_card_cur->base, |
373 | MMC_CMD55, argument, resp); | ||
277 | } | 374 | } |
278 | 375 | ||
279 | argument = ocr_value; | 376 | argument = ocr_value; |
280 | err = mmc_send_cmd(ret_cmd41, argument, resp); | 377 | err = mmc_send_cmd(mmc_card_cur->base, |
281 | if (err != 1) | 378 | ret_cmd41, argument, resp); |
379 | if (err) | ||
282 | return err; | 380 | return err; |
283 | ocr_recvd = ((mmc_resp_r3 *) resp)->ocr; | 381 | ocr_recvd = ((mmc_resp_r3 *) resp)->ocr; |
284 | } | 382 | } |
285 | 383 | ||
384 | /* check if busy */ | ||
286 | if (!(ocr_recvd & (0x1 << 31))) | 385 | if (!(ocr_recvd & (0x1 << 31))) |
287 | return 0; | 386 | return 1; |
288 | 387 | ||
289 | if (mmc_card_cur->card_type == MMC_CARD) { | 388 | if (mmc_card_cur->card_type == MMC_CARD) { |
290 | if ((ocr_recvd & MMC_OCR_REG_ACCESS_MODE_MASK) == | 389 | if ((ocr_recvd & MMC_OCR_REG_ACCESS_MODE_MASK) == |
@@ -307,39 +406,44 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur) | |||
307 | 406 | ||
308 | ocr_recvd &= ~(0x1 << 31); | 407 | ocr_recvd &= ~(0x1 << 31); |
309 | if (!(ocr_recvd & ocr_value)) | 408 | if (!(ocr_recvd & ocr_value)) |
310 | return 0; | 409 | return 1; |
311 | 410 | ||
312 | err = mmc_send_cmd(MMC_CMD2, argument, resp); | 411 | err = mmc_send_cmd(mmc_card_cur->base, MMC_CMD2, argument, resp); |
313 | if (err != 1) | 412 | if (err) |
314 | return err; | 413 | return err; |
315 | 414 | ||
316 | if (mmc_card_cur->card_type == MMC_CARD) { | 415 | if (mmc_card_cur->card_type == MMC_CARD) { |
317 | argument = mmc_card_cur->RCA << 16; | 416 | argument = mmc_card_cur->RCA << 16; |
318 | err = mmc_send_cmd(MMC_CMD3, argument, resp); | 417 | err = mmc_send_cmd(mmc_card_cur->base, |
319 | if (err != 1) | 418 | MMC_CMD3, argument, resp); |
419 | if (err) | ||
320 | return err; | 420 | return err; |
321 | } else { | 421 | } else { |
322 | argument = 0x00000000; | 422 | argument = 0x00000000; |
323 | err = mmc_send_cmd(MMC_SDCMD3, argument, resp); | 423 | err = mmc_send_cmd(mmc_card_cur->base, |
324 | if (err != 1) | 424 | MMC_SDCMD3, argument, resp); |
425 | if (err) | ||
325 | return err; | 426 | return err; |
326 | 427 | ||
327 | mmc_card_cur->RCA = ((mmc_resp_r6 *) resp)->newpublishedrca; | 428 | mmc_card_cur->RCA = ((mmc_resp_r6 *) resp)->newpublishedrca; |
328 | } | 429 | } |
329 | 430 | ||
330 | OMAP_HSMMC_CON &= ~OD; | 431 | OMAP_HSMMC_CON(mmc_card_cur->base) &= ~OD; |
331 | OMAP_HSMMC_CON |= NOOPENDRAIN; | 432 | OMAP_HSMMC_CON(mmc_card_cur->base) |= NOOPENDRAIN; |
332 | return 1; | 433 | MMC_DPRINT("-mmc_detect_card\n"); |
434 | return 0; | ||
333 | } | 435 | } |
334 | 436 | ||
335 | unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data, | 437 | static int mmc_read_cardsize(mmc_card_data *mmc_dev_data, |
336 | mmc_csd_reg_t *cur_csd) | 438 | mmc_csd_reg_t *cur_csd) |
337 | { | 439 | { |
338 | mmc_extended_csd_reg_t ext_csd; | 440 | mmc_extended_csd_reg_t ext_csd; |
339 | unsigned int size, count, blk_len, blk_no, card_size, argument; | 441 | unsigned int size, count, blk_len, blk_no, card_size, argument; |
340 | unsigned char err; | 442 | int err; |
341 | unsigned int resp[4]; | 443 | unsigned int resp[4]; |
444 | unsigned int base = mmc_dev_data->base; | ||
342 | 445 | ||
446 | mmc_dev_data->size = 0; | ||
343 | if (mmc_dev_data->mode == SECTOR_MODE) { | 447 | if (mmc_dev_data->mode == SECTOR_MODE) { |
344 | if (mmc_dev_data->card_type == SD_CARD) { | 448 | if (mmc_dev_data->card_type == SD_CARD) { |
345 | card_size = | 449 | card_size = |
@@ -350,26 +454,27 @@ unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data, | |||
350 | << MMC_SD2_CSD_C_SIZE_MSB_OFFSET); | 454 | << MMC_SD2_CSD_C_SIZE_MSB_OFFSET); |
351 | mmc_dev_data->size = card_size * 1024; | 455 | mmc_dev_data->size = card_size * 1024; |
352 | if (mmc_dev_data->size == 0) | 456 | if (mmc_dev_data->size == 0) |
353 | return 0; | 457 | return 1; |
354 | } else { | 458 | } else { |
355 | argument = 0x00000000; | 459 | argument = 0x00000000; |
356 | err = mmc_send_cmd(MMC_CMD8, argument, resp); | 460 | err = mmc_send_cmd(base, MMC_CMD8, argument, resp); |
357 | if (err != 1) | 461 | if (err) |
358 | return err; | 462 | return err; |
359 | err = mmc_read_data((unsigned int *)&ext_csd); | 463 | err = mmc_read_data(base, (unsigned int *)&ext_csd); |
360 | if (err != 1) | 464 | if (err) |
361 | return err; | 465 | return err; |
362 | mmc_dev_data->size = ext_csd.sectorcount; | 466 | mmc_dev_data->size = ext_csd.sectorcount; |
363 | 467 | ||
364 | if (mmc_dev_data->size == 0) | 468 | if (mmc_dev_data->size == 0) |
365 | mmc_dev_data->size = 8388608; | 469 | mmc_dev_data->size = 8388608; |
366 | } | 470 | } |
471 | MMC_DPRINT("Card Size=%d Sectors\n", mmc_dev_data->size); | ||
367 | } else { | 472 | } else { |
368 | if (cur_csd->c_size_mult >= 8) | 473 | if (cur_csd->c_size_mult >= 8) |
369 | return 0; | 474 | return 1; |
370 | 475 | ||
371 | if (cur_csd->read_bl_len >= 12) | 476 | if (cur_csd->read_bl_len >= 12) |
372 | return 0; | 477 | return 1; |
373 | 478 | ||
374 | /* Compute size */ | 479 | /* Compute size */ |
375 | count = 1 << (cur_csd->c_size_mult + 2); | 480 | count = 1 << (cur_csd->c_size_mult + 2); |
@@ -381,53 +486,66 @@ unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data, | |||
381 | size = blk_no * blk_len; | 486 | size = blk_no * blk_len; |
382 | mmc_dev_data->size = size / MMCSD_SECTOR_SIZE; | 487 | mmc_dev_data->size = size / MMCSD_SECTOR_SIZE; |
383 | if (mmc_dev_data->size == 0) | 488 | if (mmc_dev_data->size == 0) |
384 | return 0; | 489 | return 1; |
490 | |||
491 | MMC_DPRINT("Card Size=%d Bytes\n", mmc_dev_data->size); | ||
385 | } | 492 | } |
386 | return 1; | 493 | return 0; |
387 | } | 494 | } |
388 | 495 | ||
389 | unsigned char omap_mmc_read_sect(unsigned int start_sec, unsigned int num_bytes, | 496 | int mmc_read_block(int dev_num, unsigned int blknr, |
390 | mmc_card_data *mmc_c, | 497 | unsigned int blkcnt, unsigned char *dst) |
391 | unsigned int *output_buf) | ||
392 | { | 498 | { |
393 | unsigned char err; | 499 | unsigned int start_sec = blknr; |
500 | unsigned int num_bytes = (blkcnt * MMCSD_SECTOR_SIZE); | ||
501 | mmc_card_data *mmc_c = &cur_card_data[dev_num]; | ||
502 | unsigned int *output_buf = (unsigned int *)dst; | ||
503 | |||
504 | int err; | ||
394 | unsigned int argument; | 505 | unsigned int argument; |
395 | unsigned int resp[4]; | 506 | unsigned int resp[4]; |
396 | unsigned int num_sec_val = | 507 | unsigned int num_sec_val = |
397 | (num_bytes + (MMCSD_SECTOR_SIZE - 1)) / MMCSD_SECTOR_SIZE; | 508 | (num_bytes + (MMCSD_SECTOR_SIZE - 1)) / MMCSD_SECTOR_SIZE; |
398 | unsigned int sec_inc_val; | 509 | unsigned int sec_inc_val; |
399 | 510 | ||
511 | MMC_DPRINT("mmc_read_block Pos=0x%x 0x%x-bytes Add=0x%x\n", | ||
512 | start_sec, num_bytes, output_buf); | ||
400 | if (num_sec_val == 0) | 513 | if (num_sec_val == 0) |
401 | return 1; | 514 | return 1; |
402 | 515 | ||
403 | if (mmc_c->mode == SECTOR_MODE) { | 516 | if (mmc_c->mode == SECTOR_MODE) { |
404 | argument = start_sec; | 517 | argument = start_sec; |
405 | sec_inc_val = 1; | 518 | sec_inc_val = 1; |
519 | MMC_DPRINT("SECTOR_MODE\n"); | ||
406 | } else { | 520 | } else { |
407 | argument = start_sec * MMCSD_SECTOR_SIZE; | 521 | argument = start_sec * MMCSD_SECTOR_SIZE; |
408 | sec_inc_val = MMCSD_SECTOR_SIZE; | 522 | sec_inc_val = MMCSD_SECTOR_SIZE; |
523 | MMC_DPRINT("BYTE_MODE\n"); | ||
409 | } | 524 | } |
410 | 525 | ||
411 | while (num_sec_val) { | 526 | while (num_sec_val) { |
412 | err = mmc_send_cmd(MMC_CMD17, argument, resp); | 527 | err = mmc_send_cmd(mmc_c->base, MMC_CMD17, argument, resp); |
413 | if (err != 1) | 528 | if (err) |
414 | return err; | 529 | break; |
415 | |||
416 | 530 | ||
417 | err = mmc_read_data(output_buf); | 531 | err = mmc_read_data(mmc_c->base, output_buf); |
418 | if (err != 1) | 532 | if (err) |
419 | return err; | 533 | break; |
420 | 534 | ||
421 | output_buf += (MMCSD_SECTOR_SIZE / 4); | 535 | output_buf += (MMCSD_SECTOR_SIZE / 4); |
422 | argument += sec_inc_val; | 536 | argument += sec_inc_val; |
423 | num_sec_val--; | 537 | num_sec_val--; |
424 | } | 538 | } |
425 | return 1; | 539 | /* FAT file system expects 1 as success */ |
540 | if (err == 1) | ||
541 | return 0; | ||
542 | else | ||
543 | return 1; | ||
426 | } | 544 | } |
427 | 545 | ||
428 | unsigned char configure_mmc(mmc_card_data *mmc_card_cur) | 546 | unsigned char configure_mmc(mmc_card_data *mmc_card_cur) |
429 | { | 547 | { |
430 | unsigned char ret_val; | 548 | int ret_val; |
431 | unsigned int argument; | 549 | unsigned int argument; |
432 | unsigned int resp[4]; | 550 | unsigned int resp[4]; |
433 | unsigned int trans_fact, trans_unit, retries = 2; | 551 | unsigned int trans_fact, trans_unit, retries = 2; |
@@ -436,19 +554,20 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur) | |||
436 | mmc_csd_reg_t Card_CSD; | 554 | mmc_csd_reg_t Card_CSD; |
437 | unsigned char trans_speed; | 555 | unsigned char trans_speed; |
438 | 556 | ||
439 | ret_val = mmc_init_setup(); | 557 | MMC_DPRINT("+configure_mmc\n"); |
440 | if (ret_val != 1) | 558 | ret_val = mmc_init_setup(mmc_card_cur); |
559 | if (ret_val) | ||
441 | return ret_val; | 560 | return ret_val; |
442 | 561 | ||
443 | 562 | ||
444 | do { | 563 | do { |
445 | ret_val = mmc_detect_card(mmc_card_cur); | 564 | ret_val = mmc_detect_card(mmc_card_cur); |
446 | retries--; | 565 | retries--; |
447 | } while ((retries > 0) && (ret_val != 1)); | 566 | } while ((retries > 0) && (ret_val)); |
448 | 567 | ||
449 | argument = mmc_card_cur->RCA << 16; | 568 | argument = mmc_card_cur->RCA << 16; |
450 | ret_val = mmc_send_cmd(MMC_CMD9, argument, resp); | 569 | ret_val = mmc_send_cmd(mmc_card_cur->base, MMC_CMD9, argument, resp); |
451 | if (ret_val != 1) | 570 | if (ret_val) |
452 | return ret_val; | 571 | return ret_val; |
453 | 572 | ||
454 | ((unsigned int *)&Card_CSD)[3] = resp[3]; | 573 | ((unsigned int *)&Card_CSD)[3] = resp[3]; |
@@ -460,8 +579,9 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur) | |||
460 | mmc_card_cur->version = Card_CSD.spec_vers; | 579 | mmc_card_cur->version = Card_CSD.spec_vers; |
461 | 580 | ||
462 | trans_speed = Card_CSD.tran_speed; | 581 | trans_speed = Card_CSD.tran_speed; |
463 | ret_val = mmc_send_cmd(MMC_CMD4, MMC_DSR_DEFAULT << 16, resp); | 582 | ret_val = mmc_send_cmd(mmc_card_cur->base, |
464 | if (ret_val != 1) | 583 | MMC_CMD4, MMC_DSR_DEFAULT << 16, resp); |
584 | if (ret_val) | ||
465 | return ret_val; | 585 | return ret_val; |
466 | 586 | ||
467 | trans_unit = trans_speed & MMC_CSD_TRAN_SPEED_UNIT_MASK; | 587 | trans_unit = trans_speed & MMC_CSD_TRAN_SPEED_UNIT_MASK; |
@@ -480,83 +600,314 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur) | |||
480 | max_dtr = tran_exp[trans_unit] * tran_mant[trans_fact]; | 600 | max_dtr = tran_exp[trans_unit] * tran_mant[trans_fact]; |
481 | dsor = OMAP_MMC_MASTER_CLOCK / max_dtr; | 601 | dsor = OMAP_MMC_MASTER_CLOCK / max_dtr; |
482 | 602 | ||
603 | /* Following lines commented to build in x-loader; otherwise its including | ||
604 | * division library and creating a linking error. | ||
483 | if (OMAP_MMC_MASTER_CLOCK / dsor > max_dtr) | 605 | if (OMAP_MMC_MASTER_CLOCK / dsor > max_dtr) |
484 | dsor++; | 606 | dsor++; |
607 | */ | ||
608 | if (dsor == 4) | ||
609 | dsor = 5; | ||
610 | else if (dsor == 3) | ||
611 | dsor = 4; | ||
612 | else | ||
613 | return 1; | ||
485 | 614 | ||
486 | ret_val = mmc_clock_config(CLK_MISC, dsor); | 615 | ret_val = mmc_clock_config(mmc_card_cur->base, CLK_MISC, dsor); |
487 | if (ret_val != 1) | 616 | if (ret_val) |
488 | return ret_val; | 617 | return ret_val; |
489 | 618 | ||
490 | argument = mmc_card_cur->RCA << 16; | 619 | argument = mmc_card_cur->RCA << 16; |
491 | ret_val = mmc_send_cmd(MMC_CMD7_SELECT, argument, resp); | 620 | ret_val = mmc_send_cmd(mmc_card_cur->base, |
492 | if (ret_val != 1) | 621 | MMC_CMD7_SELECT, argument, resp); |
622 | if (ret_val) | ||
493 | return ret_val; | 623 | return ret_val; |
494 | 624 | ||
495 | /* Configure the block length to 512 bytes */ | 625 | /* Configure the block length to 512 bytes */ |
496 | argument = MMCSD_SECTOR_SIZE; | 626 | argument = MMCSD_SECTOR_SIZE; |
497 | ret_val = mmc_send_cmd(MMC_CMD16, argument, resp); | 627 | ret_val = mmc_send_cmd(mmc_card_cur->base, MMC_CMD16, argument, resp); |
498 | if (ret_val != 1) | 628 | if (ret_val) |
499 | return ret_val; | 629 | return ret_val; |
500 | 630 | ||
501 | /* get the card size in sectors */ | 631 | /* get the card size in sectors */ |
502 | ret_val = mmc_read_cardsize(mmc_card_cur, &Card_CSD); | 632 | ret_val = mmc_read_cardsize(mmc_card_cur, &Card_CSD); |
503 | if (ret_val != 1) | 633 | |
634 | MMC_DPRINT("-configure_mmc(%d)\n", ret_val); | ||
504 | return ret_val; | 635 | return ret_val; |
636 | } | ||
637 | |||
638 | #if CONFIG_DRIVER_OMAP34XX_I2C /* don't compile for x-loader */ | ||
639 | int mmc_write_block(int dev_num, unsigned int blknr, unsigned int blkcnt, | ||
640 | unsigned char *src, unsigned int *total) | ||
641 | { | ||
642 | unsigned int start_sec = blknr; | ||
643 | unsigned int num_bytes = (blkcnt * MMCSD_SECTOR_SIZE); | ||
644 | mmc_card_data *mmc_c = &cur_card_data[dev_num]; | ||
645 | unsigned int *output_buf = (unsigned int *)src; | ||
646 | |||
647 | int err; | ||
648 | unsigned int argument; | ||
649 | unsigned int resp[4]; | ||
650 | unsigned int sec_inc_val; | ||
651 | unsigned int num_sec_val = (num_bytes + (MMCSD_SECTOR_SIZE - 1)) / | ||
652 | MMCSD_SECTOR_SIZE; | ||
505 | 653 | ||
506 | return 1; | 654 | MMC_DPRINT("+mmc_write_block(0x%x sector)\n", num_sec_val); |
655 | if (blkcnt == 0) | ||
656 | return 1; | ||
657 | |||
658 | if (mmc_c->mode == SECTOR_MODE) { | ||
659 | argument = start_sec; | ||
660 | sec_inc_val = 1; | ||
661 | } else { | ||
662 | argument = start_sec * MMCSD_SECTOR_SIZE; | ||
663 | sec_inc_val = MMCSD_SECTOR_SIZE; | ||
664 | } | ||
665 | |||
666 | while (num_sec_val) { | ||
667 | err = mmc_send_cmd(mmc_c->base, MMC_CMD24, argument, resp); | ||
668 | if (err) | ||
669 | break; | ||
670 | |||
671 | err = mmc_write_data(mmc_c->base, output_buf); | ||
672 | if (err) | ||
673 | break; | ||
674 | |||
675 | output_buf += (MMCSD_SECTOR_SIZE / 4); | ||
676 | argument += sec_inc_val; | ||
677 | num_sec_val--; | ||
678 | } | ||
679 | *total = blkcnt - num_sec_val; | ||
680 | |||
681 | MMC_DPRINT("-mmc_write_block\n"); | ||
682 | /* return 1 as success */ | ||
683 | if (err == 0) | ||
684 | return 1; | ||
685 | else | ||
686 | return err; | ||
507 | } | 687 | } |
688 | #endif /*CFG_CMD_MMC - not to used x-loader build */ | ||
508 | 689 | ||
509 | unsigned long mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst) | 690 | int mmc_init(int slot) |
510 | { | 691 | { |
511 | unsigned long ret; | 692 | int ret = 0; |
693 | |||
694 | MMC_DPRINT("mmc_init - %d\n", slot); | ||
695 | switch (slot) { | ||
696 | case 0: | ||
697 | cur_card_data[0].slot = 0; | ||
698 | cur_card_data[0].base = OMAP_HSMMC1_BASE; | ||
699 | break; | ||
700 | case 1: | ||
701 | cur_card_data[1].slot = 1; | ||
702 | cur_card_data[1].base = OMAP_HSMMC2_BASE; | ||
703 | break; | ||
704 | default: | ||
705 | ret = -1; | ||
706 | } | ||
707 | |||
708 | if (ret == 0) | ||
709 | ret = configure_mmc(&cur_card_data[slot]); | ||
710 | |||
711 | if (ret == 0) { | ||
712 | /* update mmc_blk_dev info */ | ||
713 | mmc_blk_dev[slot].if_type = | ||
714 | (slot == 0) ? IF_TYPE_MMC : IF_TYPE_MMC2; | ||
715 | |||
716 | mmc_blk_dev[slot].part_type = PART_TYPE_DOS; | ||
717 | mmc_blk_dev[slot].dev = 0; | ||
718 | mmc_blk_dev[slot].lun = 0; | ||
719 | mmc_blk_dev[slot].type = 0; | ||
512 | 720 | ||
513 | ret = (unsigned long)omap_mmc_read_sect(blknr, | 721 | /* FIXME fill in the correct size (is set to 32MByte) */ |
514 | (blkcnt * MMCSD_SECTOR_SIZE), | 722 | mmc_blk_dev[slot].blksz = MMCSD_SECTOR_SIZE; |
515 | &cur_card_data, | 723 | mmc_blk_dev[slot].lba = 0x10000; |
516 | (unsigned int *)dst); | 724 | mmc_blk_dev[slot].removable = 0; |
725 | mmc_blk_dev[slot].block_read = (void *)mmc_read_block; | ||
726 | |||
727 | } else | ||
728 | MMC_DPRINT("MMC#%d Initalization FAILED\n", slot); | ||
729 | |||
730 | /* return */ | ||
517 | return ret; | 731 | return ret; |
518 | } | 732 | } |
519 | 733 | ||
520 | int mmc_init(int verbose) | 734 | #if CONFIG_DRIVER_OMAP34XX_I2C /* don't compile for x-loader */ |
735 | /* for partial read or used to read in byte mode */ | ||
736 | int mmc_read_opts(int dev_num, unsigned int bytepos, | ||
737 | unsigned int bytecnt, unsigned char *dst) | ||
738 | { | ||
739 | int err = 1; | ||
740 | unsigned int i, startsec, pos, cursize = 0, blkcnt; | ||
741 | unsigned char buf[MMCSD_SECTOR_SIZE]; | ||
742 | |||
743 | MMC_DPRINT("+mmc_read_opts dev=%d\n", dev_num); | ||
744 | |||
745 | /* check, if length is not larger than device */ | ||
746 | MMC_DPRINT("mmc_read_opts Pos=0x%x 0x%x-bytes Add=0x%x\n", | ||
747 | bytepos, bytecnt, dst); | ||
748 | if (bytecnt == 0) | ||
749 | return 1; | ||
750 | |||
751 | /* check if bytepos is Sector bounday */ | ||
752 | startsec = bytepos/MMCSD_SECTOR_SIZE; | ||
753 | if (startsec * MMCSD_SECTOR_SIZE < bytepos) { | ||
754 | pos = bytepos - (startsec*MMCSD_SECTOR_SIZE); | ||
755 | err = mmc_read_block(dev_num, startsec, 1, buf); | ||
756 | /* 1 is success */ | ||
757 | if (err == 0x01) { | ||
758 | /* check how much to read from this sector */ | ||
759 | if ((MMCSD_SECTOR_SIZE-pos) > bytecnt) | ||
760 | cursize = bytecnt; | ||
761 | else | ||
762 | cursize = (MMCSD_SECTOR_SIZE-pos); | ||
763 | |||
764 | for (i = pos; i < (cursize+pos); i++) | ||
765 | *dst++ = buf[i]; | ||
766 | bytecnt = bytecnt - cursize; | ||
767 | startsec++; | ||
768 | } | ||
769 | } | ||
770 | |||
771 | if (bytecnt >= MMCSD_SECTOR_SIZE) { | ||
772 | err = mmc_read_block(dev_num, | ||
773 | startsec, bytecnt/MMCSD_SECTOR_SIZE, dst); | ||
774 | |||
775 | /* 1 is success */ | ||
776 | if (err == 0x01) { | ||
777 | blkcnt = bytecnt/MMCSD_SECTOR_SIZE; | ||
778 | startsec = startsec + blkcnt; | ||
779 | dst = dst + (blkcnt * MMCSD_SECTOR_SIZE); | ||
780 | bytecnt = bytecnt - (blkcnt * MMCSD_SECTOR_SIZE); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | /* check if any fraction to read */ | ||
785 | if ((err == 0x01) && (bytecnt > 0)) { | ||
786 | err = mmc_read_block(dev_num, startsec, 1, buf); | ||
787 | if (err == 0x01) { | ||
788 | for (i = 0; i < bytecnt; i++) | ||
789 | *dst++ = buf[i]; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | /* return 1 as success */ | ||
794 | return err; | ||
795 | } | ||
796 | |||
797 | /* for partial Write or used to write in byte mode */ | ||
798 | int mmc_write_opts(int dev_num, unsigned int bytepos, unsigned int bytecnt, | ||
799 | unsigned char *src, unsigned int *total) | ||
521 | { | 800 | { |
522 | configure_mmc(&cur_card_data); | 801 | int err = 1; |
523 | 802 | unsigned int i, startsec, pos, cursize = 0, blkcnt, tmptotal; | |
524 | mmc_blk_dev.if_type = IF_TYPE_MMC; | 803 | unsigned char buf[MMCSD_SECTOR_SIZE]; |
525 | mmc_blk_dev.part_type = PART_TYPE_DOS; | 804 | |
526 | mmc_blk_dev.dev = 0; | 805 | MMC_DPRINT("+mmc_read_opts dev=%d\n", dev_num); |
527 | mmc_blk_dev.lun = 0; | 806 | |
528 | mmc_blk_dev.type = 0; | 807 | /* check, if length is not larger than device */ |
529 | 808 | MMC_DPRINT("mmc_read_opts Pos=0x%x 0x%x-bytes Add=0x%x\n", | |
530 | /* FIXME fill in the correct size (is set to 32MByte) */ | 809 | bytepos, bytecnt, src); |
531 | mmc_blk_dev.blksz = MMCSD_SECTOR_SIZE; | 810 | if (bytecnt == 0) |
532 | mmc_blk_dev.lba = 0x10000; | 811 | return 1; |
533 | mmc_blk_dev.removable = 0; | 812 | |
534 | mmc_blk_dev.block_read = mmc_bread; | 813 | /* check if bytepos is Sector bounday */ |
535 | 814 | *total = bytecnt; | |
536 | fat_register_device(&mmc_blk_dev, 1); | 815 | startsec = bytepos/MMCSD_SECTOR_SIZE; |
537 | return 0; | 816 | if (startsec*MMCSD_SECTOR_SIZE < bytepos) { |
817 | pos = bytepos - (startsec*MMCSD_SECTOR_SIZE); | ||
818 | err = mmc_read_block(dev_num, startsec, 1, buf); | ||
819 | /* 1 is success */ | ||
820 | if (err == 0x01) { | ||
821 | /* check how much to read from this sector */ | ||
822 | if ((MMCSD_SECTOR_SIZE-pos) > bytecnt) | ||
823 | cursize = bytecnt; | ||
824 | else | ||
825 | cursize = (MMCSD_SECTOR_SIZE-pos); | ||
826 | |||
827 | /* make the buffer */ | ||
828 | for (i = pos; i < (cursize+pos); i++) | ||
829 | buf[i] = *src++; | ||
830 | /* write the buffer */ | ||
831 | err = mmc_write_block(dev_num, | ||
832 | startsec, 1, buf, &tmptotal); | ||
833 | |||
834 | bytecnt = bytecnt - cursize; | ||
835 | startsec++; | ||
836 | } | ||
837 | } | ||
838 | |||
839 | if (bytecnt >= MMCSD_SECTOR_SIZE) { | ||
840 | err = mmc_write_block(dev_num, | ||
841 | startsec, bytecnt/MMCSD_SECTOR_SIZE, src, &tmptotal); | ||
842 | |||
843 | /* 1 is success */ | ||
844 | if (err == 0x01) { | ||
845 | blkcnt = bytecnt/MMCSD_SECTOR_SIZE; | ||
846 | startsec = startsec + blkcnt; | ||
847 | src = src + (blkcnt * MMCSD_SECTOR_SIZE); | ||
848 | bytecnt = bytecnt - (blkcnt * MMCSD_SECTOR_SIZE); | ||
849 | } | ||
850 | } | ||
851 | |||
852 | /* check if any fraction to read */ | ||
853 | if ((err == 0x01) && (bytecnt > 0)) { | ||
854 | err = mmc_read_block(dev_num, startsec, 1, src); | ||
855 | if (err == 0x01) { | ||
856 | /* make the buffer */ | ||
857 | for (i = 0; i < bytecnt; i++) | ||
858 | buf[i] = *src++; | ||
859 | /* write the buffer */ | ||
860 | err = mmc_write_block(dev_num, | ||
861 | startsec, 1, buf, &tmptotal); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | /* return 1 as success */ | ||
866 | if (err != 1) | ||
867 | *total = 0; | ||
868 | |||
869 | return err; | ||
870 | } | ||
871 | #endif /* CFG_CMD_MMC - not to used x-loader build */ | ||
872 | |||
873 | int mmc_support_rawboot_check(int dev) | ||
874 | { | ||
875 | unsigned char buff[MMCSD_SECTOR_SIZE]; | ||
876 | |||
877 | /* read the 1st sector */ | ||
878 | if (mmc_read_block(dev, 0x00, 0x01, buff) != 1) | ||
879 | return 1; | ||
880 | |||
881 | /* search for "CHSETTINGS" @ 0x14*/ | ||
882 | if ((buff[TOC_NAME_OFFSET] != 'C') || | ||
883 | (buff[TOC_NAME_OFFSET+1] != 'H') || | ||
884 | (buff[TOC_NAME_OFFSET+2] != 'S') || | ||
885 | (buff[TOC_NAME_OFFSET+3] != 'E') || | ||
886 | (buff[TOC_NAME_OFFSET+4] != 'T') || | ||
887 | (buff[TOC_NAME_OFFSET+5] != 'T') || | ||
888 | (buff[TOC_NAME_OFFSET+6] != 'I') || | ||
889 | (buff[TOC_NAME_OFFSET+7] != 'N') || | ||
890 | (buff[TOC_NAME_OFFSET+8] != 'G') || | ||
891 | (buff[TOC_NAME_OFFSET+9] != 'S')) | ||
892 | return 1; /* raw boot not supported */ | ||
893 | else | ||
894 | return 0; | ||
538 | } | 895 | } |
539 | 896 | ||
540 | int mmc_read(unsigned int src, unsigned char *dst, int size) | 897 | int mmc_read(unsigned int src, unsigned char *dst, int size) |
541 | { | 898 | { |
542 | /* | 899 | printf("mmc_read: NOT Implemented\n"); |
543 | * NOT Implemented | ||
544 | */ | ||
545 | return 0; | 900 | return 0; |
546 | } | 901 | } |
547 | int mmc_write(unsigned char *src, unsigned long dst, int size) | 902 | int mmc_write(unsigned char *src, unsigned long dst, int size) |
548 | { | 903 | { |
549 | /* | 904 | printf("mmc_write: NOT Implemented\n"); |
550 | * NOT Implemented | ||
551 | */ | ||
552 | return 0; | 905 | return 0; |
553 | } | 906 | } |
554 | 907 | ||
555 | int mmc2info(unsigned int addr) | 908 | int mmc2info(unsigned int addr) |
556 | { | 909 | { |
557 | /* | 910 | printf("mmc2info: NOT Implemented\n"); |
558 | * NOT Implemented | ||
559 | */ | ||
560 | return 0; | 911 | return 0; |
561 | } | 912 | } |
562 | #endif | 913 | #endif |
diff --git a/cpu/omap3/mmc_host_def.h b/cpu/omap3/mmc_host_def.h index 9569bc54c4..f4739fed88 100644 --- a/cpu/omap3/mmc_host_def.h +++ b/cpu/omap3/mmc_host_def.h | |||
@@ -28,27 +28,35 @@ | |||
28 | /* | 28 | /* |
29 | * OMAP HSMMC register definitions | 29 | * OMAP HSMMC register definitions |
30 | */ | 30 | */ |
31 | #define OMAP_HSMMC_SYSCONFIG (*(volatile unsigned int *) 0x4809C010) | 31 | #define OMAP_HSMMC1_BASE 0x4809C000 |
32 | #define OMAP_HSMMC_SYSSTATUS (*(volatile unsigned int *) 0x4809C014) | 32 | #define OMAP_HSMMC2_BASE 0x480B4000 |
33 | #define OMAP_HSMMC_CON (*(volatile unsigned int *) 0x4809C02C) | 33 | |
34 | #define OMAP_HSMMC_BLK (*(volatile unsigned int *) 0x4809C104) | 34 | #define OMAP_HSMMC_SYSCONFIG(base) (*(volatile unsigned int *)(base+0x010)) |
35 | #define OMAP_HSMMC_ARG (*(volatile unsigned int *) 0x4809C108) | 35 | #define OMAP_HSMMC_SYSSTATUS(base) (*(volatile unsigned int *)(base+0x014)) |
36 | #define OMAP_HSMMC_CMD (*(volatile unsigned int *) 0x4809C10C) | 36 | #define OMAP_HSMMC_CON(base) (*(volatile unsigned int *)(base+0x02C)) |
37 | #define OMAP_HSMMC_RSP10 (*(volatile unsigned int *) 0x4809C110) | 37 | #define OMAP_HSMMC_BLK(base) (*(volatile unsigned int *)(base+0x104)) |
38 | #define OMAP_HSMMC_RSP32 (*(volatile unsigned int *) 0x4809C114) | 38 | #define OMAP_HSMMC_ARG(base) (*(volatile unsigned int *)(base+0x108)) |
39 | #define OMAP_HSMMC_RSP54 (*(volatile unsigned int *) 0x4809C118) | 39 | #define OMAP_HSMMC_CMD(base) (*(volatile unsigned int *)(base+0x10C)) |
40 | #define OMAP_HSMMC_RSP76 (*(volatile unsigned int *) 0x4809C11C) | 40 | #define OMAP_HSMMC_RSP10(base) (*(volatile unsigned int *)(base+0x110)) |
41 | #define OMAP_HSMMC_DATA (*(volatile unsigned int *) 0x4809C120) | 41 | #define OMAP_HSMMC_RSP32(base) (*(volatile unsigned int *)(base+0x114)) |
42 | #define OMAP_HSMMC_PSTATE (*(volatile unsigned int *) 0x4809C124) | 42 | #define OMAP_HSMMC_RSP54(base) (*(volatile unsigned int *)(base+0x118)) |
43 | #define OMAP_HSMMC_HCTL (*(volatile unsigned int *) 0x4809C128) | 43 | #define OMAP_HSMMC_RSP76(base) (*(volatile unsigned int *)(base+0x11C)) |
44 | #define OMAP_HSMMC_SYSCTL (*(volatile unsigned int *) 0x4809C12C) | 44 | #define OMAP_HSMMC_DATA(base) (*(volatile unsigned int *)(base+0x120)) |
45 | #define OMAP_HSMMC_STAT (*(volatile unsigned int *) 0x4809C130) | 45 | #define OMAP_HSMMC_PSTATE(base) (*(volatile unsigned int *)(base+0x124)) |
46 | #define OMAP_HSMMC_IE (*(volatile unsigned int *) 0x4809C134) | 46 | #define OMAP_HSMMC_HCTL(base) (*(volatile unsigned int *)(base+0x128)) |
47 | #define OMAP_HSMMC_CAPA (*(volatile unsigned int *) 0x4809C140) | 47 | #define OMAP_HSMMC_SYSCTL(base) (*(volatile unsigned int *)(base+0x12C)) |
48 | #define OMAP_HSMMC_STAT(base) (*(volatile unsigned int *)(base+0x130)) | ||
49 | #define OMAP_HSMMC_IE(base) (*(volatile unsigned int *)(base+0x134)) | ||
50 | #define OMAP_HSMMC_CAPA(base) (*(volatile unsigned int *)(base+0x140)) | ||
48 | 51 | ||
49 | /* T2 Register definitions */ | 52 | /* T2 Register definitions */ |
50 | #define CONTROL_DEV_CONF0 (*(volatile unsigned int *) 0x48002274) | 53 | #define CONTROL_DEV_CONF0 (*(volatile unsigned int *) 0x48002274) |
54 | #define CONTROL_DEV_CONF1 (*(volatile unsigned int *) 0x480022D8) | ||
51 | #define CONTROL_PBIAS_LITE (*(volatile unsigned int *) 0x48002520) | 55 | #define CONTROL_PBIAS_LITE (*(volatile unsigned int *) 0x48002520) |
56 | /* Configuration Header: (TOC filename offset; e.g. "CHSETTINGS") | ||
57 | * 12 character long name of sub image, including the zero (.\0.) terminator | ||
58 | */ | ||
59 | #define TOC_NAME_OFFSET 0x14 | ||
52 | 60 | ||
53 | /* | 61 | /* |
54 | * OMAP HS MMC Bit definitions | 62 | * OMAP HS MMC Bit definitions |
@@ -140,6 +148,11 @@ | |||
140 | #define VS30_3V0SUP (1 << 25) | 148 | #define VS30_3V0SUP (1 << 25) |
141 | #define VS18_1V8SUP (1 << 26) | 149 | #define VS18_1V8SUP (1 << 26) |
142 | 150 | ||
151 | /* Interrupt MMC/SD enable register; Set the value to the register that allows | ||
152 | to get the status bits, on an event-by-event basis | ||
153 | */ | ||
154 | #define OMAP_HSMMC_STATUS_REQ 0x307f0033 | ||
155 | |||
143 | /* Driver definitions */ | 156 | /* Driver definitions */ |
144 | #define MMCSD_SECTOR_SIZE (512) | 157 | #define MMCSD_SECTOR_SIZE (512) |
145 | #define MMC_CARD 0 | 158 | #define MMC_CARD 0 |
@@ -151,6 +164,8 @@ | |||
151 | #define CLK_MISC 2 | 164 | #define CLK_MISC 2 |
152 | 165 | ||
153 | typedef struct { | 166 | typedef struct { |
167 | unsigned int slot; /* hsmmc# */ | ||
168 | unsigned int base; /* hsmmc base address */ | ||
154 | unsigned int card_type; | 169 | unsigned int card_type; |
155 | unsigned int version; | 170 | unsigned int version; |
156 | unsigned int mode; | 171 | unsigned int mode; |
@@ -162,3 +177,4 @@ typedef struct { | |||
162 | (addr) = (((addr)) & (~(mask)) ) | ( (val) & (mask)); | 177 | (addr) = (((addr)) & (~(mask)) ) | ( (val) & (mask)); |
163 | 178 | ||
164 | #endif /* MMC_HOST_DEFINITIONS_H */ | 179 | #endif /* MMC_HOST_DEFINITIONS_H */ |
180 | |||
diff --git a/cpu/omap3/mmc_protocol.h b/cpu/omap3/mmc_protocol.h index 51d6a17b74..867b27c348 100644 --- a/cpu/omap3/mmc_protocol.h +++ b/cpu/omap3/mmc_protocol.h | |||
@@ -241,6 +241,5 @@ unsigned char mmc_send_command(unsigned int cmd, unsigned int arg, | |||
241 | unsigned int *response); | 241 | unsigned int *response); |
242 | unsigned char mmc_setup_clock(unsigned int iclk, unsigned short clkd); | 242 | unsigned char mmc_setup_clock(unsigned int iclk, unsigned short clkd); |
243 | unsigned char mmc_set_opendrain(unsigned char state); | 243 | unsigned char mmc_set_opendrain(unsigned char state); |
244 | unsigned char mmc_read_data(unsigned int *output_buf); | ||
245 | 244 | ||
246 | #endif /*MMC_PROTOCOL_H */ | 245 | #endif /*MMC_PROTOCOL_H */ |
diff --git a/include/mmc.h b/include/mmc.h index ee74261b3a..d74902e853 100644 --- a/include/mmc.h +++ b/include/mmc.h | |||
@@ -24,10 +24,21 @@ | |||
24 | #ifndef _MMC_H_ | 24 | #ifndef _MMC_H_ |
25 | #define _MMC_H_ | 25 | #define _MMC_H_ |
26 | #include <asm/arch/mmc.h> | 26 | #include <asm/arch/mmc.h> |
27 | #include <part.h> | ||
27 | 28 | ||
28 | int mmc_init(int verbose); | 29 | int mmc_init(int slot); |
29 | int mmc_read(unsigned int src, unsigned char *dst, int size); | 30 | int mmc_read(unsigned int src, unsigned char *dst, int size); |
30 | int mmc_write(unsigned char *src, unsigned long dst, int size); | 31 | int mmc_write(unsigned char *src, unsigned long dst, int size); |
32 | int mmc_read_block(int slot, unsigned int blknr, | ||
33 | unsigned int blkcnt, unsigned char *buf); | ||
34 | int mmc_write_block(int slot, unsigned int blknr, unsigned int blkcnt, | ||
35 | unsigned char *buf, unsigned int *total); | ||
36 | int mmc_read_opts(int dev_num, unsigned int bytepos, | ||
37 | unsigned int bytecnt, unsigned char *dst); | ||
38 | int mmc_write_opts(int dev_num, unsigned int bytepos, unsigned int bytecnt, | ||
39 | unsigned char *src, unsigned int *total); | ||
40 | int mmc_support_rawboot_check(int dev); | ||
31 | int mmc2info(unsigned int addr); | 41 | int mmc2info(unsigned int addr); |
42 | block_dev_desc_t *mmc_get_dev(int dev); | ||
32 | 43 | ||
33 | #endif /* _MMC_H_ */ | 44 | #endif /* _MMC_H_ */ |
diff --git a/include/part.h b/include/part.h index 318aa3cb3f..25d05dac8f 100644 --- a/include/part.h +++ b/include/part.h | |||
@@ -54,6 +54,7 @@ typedef struct block_dev_desc { | |||
54 | #define IF_TYPE_USB 4 | 54 | #define IF_TYPE_USB 4 |
55 | #define IF_TYPE_DOC 5 | 55 | #define IF_TYPE_DOC 5 |
56 | #define IF_TYPE_MMC 6 | 56 | #define IF_TYPE_MMC 6 |
57 | #define IF_TYPE_MMC2 7 | ||
57 | 58 | ||
58 | /* Part types */ | 59 | /* Part types */ |
59 | #define PART_TYPE_UNKNOWN 0x00 | 60 | #define PART_TYPE_UNKNOWN 0x00 |