Commit c9abb4260c30fbfd51bb2cd551e7426e2ae15b66
Committed by
Andreas Bießmann
1 parent
72fa467988
Exists in
master
and in
54 other branches
ATMEL: remove old atmel_mci driver
All boards are using the gen_atmel_mci driver now, so no need to carry the old driver around. Signed-off-by: Sven Schnelle <svens@stackframe.org> Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
Showing 5 changed files with 3 additions and 537 deletions Side-by-side Diff
arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
arch/avr32/lib/board.c
doc/README.atmel_mci
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | |
21 | 21 | example: this is added to at91sam9260_devices.c: |
22 | 22 | |
23 | -#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI) | |
23 | +#if defined(CONFIG_GENERIC_ATMEL_MCI) | |
24 | 24 | void at91_mci_hw_init(void) |
25 | 25 | { |
26 | 26 | at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCCK */ |
drivers/mmc/Makefile
drivers/mmc/atmel_mci.c
1 | -/* | |
2 | - * Copyright (C) 2004-2006 Atmel Corporation | |
3 | - * | |
4 | - * See file CREDITS for list of people who contributed to this | |
5 | - * project. | |
6 | - * | |
7 | - * This program is free software; you can redistribute it and/or | |
8 | - * modify it under the terms of the GNU General Public License as | |
9 | - * published by the Free Software Foundation; either version 2 of | |
10 | - * the License, or (at your option) any later version. | |
11 | - * | |
12 | - * This program is distributed in the hope that it will be useful, | |
13 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | - * GNU General Public License for more details. | |
16 | - * | |
17 | - * You should have received a copy of the GNU General Public License | |
18 | - * along with this program; if not, write to the Free Software | |
19 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
20 | - * MA 02111-1307 USA | |
21 | - */ | |
22 | -#include <common.h> | |
23 | - | |
24 | -#include <part.h> | |
25 | -#include <mmc.h> | |
26 | - | |
27 | -#include <asm/io.h> | |
28 | -#include <asm/errno.h> | |
29 | -#include <asm/byteorder.h> | |
30 | -#include <asm/arch/clk.h> | |
31 | -#include <asm/arch/hardware.h> | |
32 | - | |
33 | -#include "atmel_mci.h" | |
34 | - | |
35 | -#ifdef DEBUG | |
36 | -#define pr_debug(fmt, args...) printf(fmt, ##args) | |
37 | -#else | |
38 | -#define pr_debug(...) do { } while(0) | |
39 | -#endif | |
40 | - | |
41 | -#ifndef CONFIG_SYS_MMC_CLK_OD | |
42 | -#define CONFIG_SYS_MMC_CLK_OD 150000 | |
43 | -#endif | |
44 | - | |
45 | -#ifndef CONFIG_SYS_MMC_CLK_PP | |
46 | -#define CONFIG_SYS_MMC_CLK_PP 5000000 | |
47 | -#endif | |
48 | - | |
49 | -#ifndef CONFIG_SYS_MMC_OP_COND | |
50 | -#define CONFIG_SYS_MMC_OP_COND 0x00100000 | |
51 | -#endif | |
52 | - | |
53 | -#define MMC_DEFAULT_BLKLEN 512 | |
54 | -#define MMC_DEFAULT_RCA 1 | |
55 | - | |
56 | -static unsigned int mmc_rca; | |
57 | -static int mmc_card_is_sd; | |
58 | -static block_dev_desc_t mmc_blkdev; | |
59 | - | |
60 | -block_dev_desc_t *mmc_get_dev(int dev) | |
61 | -{ | |
62 | - return &mmc_blkdev; | |
63 | -} | |
64 | - | |
65 | -static void mci_set_mode(unsigned long hz, unsigned long blklen) | |
66 | -{ | |
67 | - unsigned long bus_hz; | |
68 | - unsigned long clkdiv; | |
69 | - | |
70 | - bus_hz = get_mci_clk_rate(); | |
71 | - clkdiv = (bus_hz / hz) / 2 - 1; | |
72 | - | |
73 | - pr_debug("mmc: setting clock %lu Hz, block size %lu\n", | |
74 | - hz, blklen); | |
75 | - | |
76 | - if (clkdiv & ~255UL) { | |
77 | - clkdiv = 255; | |
78 | - printf("mmc: clock %lu too low; setting CLKDIV to 255\n", | |
79 | - hz); | |
80 | - } | |
81 | - | |
82 | - blklen &= 0xfffc; | |
83 | - mmci_writel(MR, (MMCI_BF(CLKDIV, clkdiv) | |
84 | - | MMCI_BF(BLKLEN, blklen) | |
85 | - | MMCI_BIT(RDPROOF) | |
86 | - | MMCI_BIT(WRPROOF))); | |
87 | -} | |
88 | - | |
89 | -#define RESP_NO_CRC 1 | |
90 | -#define R1 MMCI_BF(RSPTYP, 1) | |
91 | -#define R2 MMCI_BF(RSPTYP, 2) | |
92 | -#define R3 (R1 | RESP_NO_CRC) | |
93 | -#define R6 R1 | |
94 | -#define NID MMCI_BF(MAXLAT, 0) | |
95 | -#define NCR MMCI_BF(MAXLAT, 1) | |
96 | -#define TRCMD_START MMCI_BF(TRCMD, 1) | |
97 | -#define TRDIR_READ MMCI_BF(TRDIR, 1) | |
98 | -#define TRTYP_BLOCK MMCI_BF(TRTYP, 0) | |
99 | -#define INIT_CMD MMCI_BF(SPCMD, 1) | |
100 | -#define OPEN_DRAIN MMCI_BF(OPDCMD, 1) | |
101 | - | |
102 | -#define ERROR_FLAGS (MMCI_BIT(DTOE) \ | |
103 | - | MMCI_BIT(RDIRE) \ | |
104 | - | MMCI_BIT(RENDE) \ | |
105 | - | MMCI_BIT(RINDE) \ | |
106 | - | MMCI_BIT(RTOE)) | |
107 | - | |
108 | -static int | |
109 | -mmc_cmd(unsigned long cmd, unsigned long arg, | |
110 | - void *resp, unsigned long flags) | |
111 | -{ | |
112 | - unsigned long *response = resp; | |
113 | - int i, response_words = 0; | |
114 | - unsigned long error_flags; | |
115 | - u32 status; | |
116 | - | |
117 | - pr_debug("mmc: CMD%lu 0x%lx (flags 0x%lx)\n", | |
118 | - cmd, arg, flags); | |
119 | - | |
120 | - error_flags = ERROR_FLAGS; | |
121 | - if (!(flags & RESP_NO_CRC)) | |
122 | - error_flags |= MMCI_BIT(RCRCE); | |
123 | - | |
124 | - flags &= ~MMCI_BF(CMDNB, ~0UL); | |
125 | - | |
126 | - if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_48_BIT_RESP) | |
127 | - response_words = 1; | |
128 | - else if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_136_BIT_RESP) | |
129 | - response_words = 4; | |
130 | - | |
131 | - mmci_writel(ARGR, arg); | |
132 | - mmci_writel(CMDR, cmd | flags); | |
133 | - do { | |
134 | - udelay(40); | |
135 | - status = mmci_readl(SR); | |
136 | - } while (!(status & MMCI_BIT(CMDRDY))); | |
137 | - | |
138 | - pr_debug("mmc: status 0x%08x\n", status); | |
139 | - | |
140 | - if (status & error_flags) { | |
141 | - printf("mmc: command %lu failed (status: 0x%08x)\n", | |
142 | - cmd, status); | |
143 | - return -EIO; | |
144 | - } | |
145 | - | |
146 | - if (response_words) | |
147 | - pr_debug("mmc: response:"); | |
148 | - | |
149 | - for (i = 0; i < response_words; i++) { | |
150 | - response[i] = mmci_readl(RSPR); | |
151 | - pr_debug(" %08lx", response[i]); | |
152 | - } | |
153 | - pr_debug("\n"); | |
154 | - | |
155 | - return 0; | |
156 | -} | |
157 | - | |
158 | -static int mmc_acmd(unsigned long cmd, unsigned long arg, | |
159 | - void *resp, unsigned long flags) | |
160 | -{ | |
161 | - unsigned long aresp[4]; | |
162 | - int ret; | |
163 | - | |
164 | - /* | |
165 | - * Seems like the APP_CMD part of an ACMD has 64 cycles max | |
166 | - * latency even though the ACMD part doesn't. This isn't | |
167 | - * entirely clear in the SD Card spec, but some cards refuse | |
168 | - * to work if we attempt to use 5 cycles max latency here... | |
169 | - */ | |
170 | - ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp, | |
171 | - R1 | NCR | (flags & OPEN_DRAIN)); | |
172 | - if (ret) | |
173 | - return ret; | |
174 | - if ((aresp[0] & (R1_ILLEGAL_COMMAND | R1_APP_CMD)) != R1_APP_CMD) | |
175 | - return -ENODEV; | |
176 | - | |
177 | - ret = mmc_cmd(cmd, arg, resp, flags); | |
178 | - return ret; | |
179 | -} | |
180 | - | |
181 | -static unsigned long | |
182 | -mmc_bread(int dev, unsigned long start, lbaint_t blkcnt, | |
183 | - void *buffer) | |
184 | -{ | |
185 | - int ret, i = 0; | |
186 | - unsigned long resp[4]; | |
187 | - unsigned long card_status, data; | |
188 | - unsigned long wordcount; | |
189 | - u32 *p = buffer; | |
190 | - u32 status; | |
191 | - | |
192 | - if (blkcnt == 0) | |
193 | - return 0; | |
194 | - | |
195 | - pr_debug("mmc_bread: dev %d, start %lx, blkcnt %lx\n", | |
196 | - dev, start, blkcnt); | |
197 | - | |
198 | - /* Put the device into Transfer state */ | |
199 | - ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, R1 | NCR); | |
200 | - if (ret) goto out; | |
201 | - | |
202 | - /* Set block length */ | |
203 | - ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, R1 | NCR); | |
204 | - if (ret) goto out; | |
205 | - | |
206 | - pr_debug("MCI_DTOR = %08lx\n", mmci_readl(DTOR)); | |
207 | - | |
208 | - for (i = 0; i < blkcnt; i++, start++) { | |
209 | - ret = mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK, | |
210 | - start * mmc_blkdev.blksz, resp, | |
211 | - (R1 | NCR | TRCMD_START | TRDIR_READ | |
212 | - | TRTYP_BLOCK)); | |
213 | - if (ret) goto out; | |
214 | - | |
215 | - ret = -EIO; | |
216 | - wordcount = 0; | |
217 | - do { | |
218 | - do { | |
219 | - status = mmci_readl(SR); | |
220 | - if (status & (ERROR_FLAGS | MMCI_BIT(OVRE))) | |
221 | - goto read_error; | |
222 | - } while (!(status & MMCI_BIT(RXRDY))); | |
223 | - | |
224 | - if (status & MMCI_BIT(RXRDY)) { | |
225 | - data = mmci_readl(RDR); | |
226 | - /* pr_debug("%x\n", data); */ | |
227 | - *p++ = data; | |
228 | - wordcount++; | |
229 | - } | |
230 | - } while(wordcount < (mmc_blkdev.blksz / 4)); | |
231 | - | |
232 | - pr_debug("mmc: read %u words, waiting for BLKE\n", wordcount); | |
233 | - | |
234 | - do { | |
235 | - status = mmci_readl(SR); | |
236 | - } while (!(status & MMCI_BIT(BLKE))); | |
237 | - | |
238 | - putc('.'); | |
239 | - } | |
240 | - | |
241 | -out: | |
242 | - /* Put the device back into Standby state */ | |
243 | - mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, NCR); | |
244 | - return i; | |
245 | - | |
246 | -read_error: | |
247 | - mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, R1 | NCR); | |
248 | - printf("mmc: bread failed, status = %08x, card status = %08lx\n", | |
249 | - status, card_status); | |
250 | - goto out; | |
251 | -} | |
252 | - | |
253 | -static void mmc_parse_cid(struct mmc_cid *cid, unsigned long *resp) | |
254 | -{ | |
255 | - cid->mid = resp[0] >> 24; | |
256 | - cid->oid = (resp[0] >> 8) & 0xffff; | |
257 | - cid->pnm[0] = resp[0]; | |
258 | - cid->pnm[1] = resp[1] >> 24; | |
259 | - cid->pnm[2] = resp[1] >> 16; | |
260 | - cid->pnm[3] = resp[1] >> 8; | |
261 | - cid->pnm[4] = resp[1]; | |
262 | - cid->pnm[5] = resp[2] >> 24; | |
263 | - cid->pnm[6] = 0; | |
264 | - cid->prv = resp[2] >> 16; | |
265 | - cid->psn = (resp[2] << 16) | (resp[3] >> 16); | |
266 | - cid->mdt = resp[3] >> 8; | |
267 | -} | |
268 | - | |
269 | -static void sd_parse_cid(struct mmc_cid *cid, unsigned long *resp) | |
270 | -{ | |
271 | - cid->mid = resp[0] >> 24; | |
272 | - cid->oid = (resp[0] >> 8) & 0xffff; | |
273 | - cid->pnm[0] = resp[0]; | |
274 | - cid->pnm[1] = resp[1] >> 24; | |
275 | - cid->pnm[2] = resp[1] >> 16; | |
276 | - cid->pnm[3] = resp[1] >> 8; | |
277 | - cid->pnm[4] = resp[1]; | |
278 | - cid->pnm[5] = 0; | |
279 | - cid->pnm[6] = 0; | |
280 | - cid->prv = resp[2] >> 24; | |
281 | - cid->psn = (resp[2] << 8) | (resp[3] >> 24); | |
282 | - cid->mdt = (resp[3] >> 8) & 0x0fff; | |
283 | -} | |
284 | - | |
285 | -static void mmc_dump_cid(const struct mmc_cid *cid) | |
286 | -{ | |
287 | - printf("Manufacturer ID: %02X\n", cid->mid); | |
288 | - printf("OEM/Application ID: %04X\n", cid->oid); | |
289 | - printf("Product name: %s\n", cid->pnm); | |
290 | - printf("Product Revision: %u.%u\n", | |
291 | - cid->prv >> 4, cid->prv & 0x0f); | |
292 | - printf("Product Serial Number: %lu\n", cid->psn); | |
293 | - printf("Manufacturing Date: %02u/%02u\n", | |
294 | - cid->mdt >> 4, cid->mdt & 0x0f); | |
295 | -} | |
296 | - | |
297 | -static void mmc_dump_csd(const struct mmc_csd *csd) | |
298 | -{ | |
299 | - unsigned long *csd_raw = (unsigned long *)csd; | |
300 | - printf("CSD data: %08lx %08lx %08lx %08lx\n", | |
301 | - csd_raw[0], csd_raw[1], csd_raw[2], csd_raw[3]); | |
302 | - printf("CSD structure version: 1.%u\n", csd->csd_structure); | |
303 | - printf("MMC System Spec version: %u\n", csd->spec_vers); | |
304 | - printf("Card command classes: %03x\n", csd->ccc); | |
305 | - printf("Read block length: %u\n", 1 << csd->read_bl_len); | |
306 | - if (csd->read_bl_partial) | |
307 | - puts("Supports partial reads\n"); | |
308 | - else | |
309 | - puts("Does not support partial reads\n"); | |
310 | - printf("Write block length: %u\n", 1 << csd->write_bl_len); | |
311 | - if (csd->write_bl_partial) | |
312 | - puts("Supports partial writes\n"); | |
313 | - else | |
314 | - puts("Does not support partial writes\n"); | |
315 | - if (csd->wp_grp_enable) | |
316 | - printf("Supports group WP: %u\n", csd->wp_grp_size + 1); | |
317 | - else | |
318 | - puts("Does not support group WP\n"); | |
319 | - printf("Card capacity: %u bytes\n", | |
320 | - (csd->c_size + 1) * (1 << (csd->c_size_mult + 2)) * | |
321 | - (1 << csd->read_bl_len)); | |
322 | - printf("File format: %u/%u\n", | |
323 | - csd->file_format_grp, csd->file_format); | |
324 | - puts("Write protection: "); | |
325 | - if (csd->perm_write_protect) | |
326 | - puts(" permanent"); | |
327 | - if (csd->tmp_write_protect) | |
328 | - puts(" temporary"); | |
329 | - putc('\n'); | |
330 | -} | |
331 | - | |
332 | -static int mmc_idle_cards(void) | |
333 | -{ | |
334 | - int ret; | |
335 | - | |
336 | - /* Reset and initialize all cards */ | |
337 | - ret = mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, NULL, 0); | |
338 | - if (ret) | |
339 | - return ret; | |
340 | - | |
341 | - /* Keep the bus idle for 74 clock cycles */ | |
342 | - return mmc_cmd(0, 0, NULL, INIT_CMD); | |
343 | -} | |
344 | - | |
345 | -static int sd_init_card(struct mmc_cid *cid, int verbose) | |
346 | -{ | |
347 | - unsigned long resp[4]; | |
348 | - int i, ret = 0; | |
349 | - | |
350 | - mmc_idle_cards(); | |
351 | - for (i = 0; i < 1000; i++) { | |
352 | - ret = mmc_acmd(SD_CMD_APP_SEND_OP_COND, CONFIG_SYS_MMC_OP_COND, | |
353 | - resp, R3 | NID); | |
354 | - if (ret || (resp[0] & 0x80000000)) | |
355 | - break; | |
356 | - ret = -ETIMEDOUT; | |
357 | - } | |
358 | - | |
359 | - if (ret) | |
360 | - return ret; | |
361 | - | |
362 | - ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID); | |
363 | - if (ret) | |
364 | - return ret; | |
365 | - sd_parse_cid(cid, resp); | |
366 | - if (verbose) | |
367 | - mmc_dump_cid(cid); | |
368 | - | |
369 | - /* Get RCA of the card that responded */ | |
370 | - ret = mmc_cmd(SD_CMD_SEND_RELATIVE_ADDR, 0, resp, R6 | NCR); | |
371 | - if (ret) | |
372 | - return ret; | |
373 | - | |
374 | - mmc_rca = resp[0] >> 16; | |
375 | - if (verbose) | |
376 | - printf("SD Card detected (RCA %u)\n", mmc_rca); | |
377 | - mmc_card_is_sd = 1; | |
378 | - return 0; | |
379 | -} | |
380 | - | |
381 | -static int mmc_init_card(struct mmc_cid *cid, int verbose) | |
382 | -{ | |
383 | - unsigned long resp[4]; | |
384 | - int i, ret = 0; | |
385 | - | |
386 | - mmc_idle_cards(); | |
387 | - for (i = 0; i < 1000; i++) { | |
388 | - ret = mmc_cmd(MMC_CMD_SEND_OP_COND, CONFIG_SYS_MMC_OP_COND, resp, | |
389 | - R3 | NID | OPEN_DRAIN); | |
390 | - if (ret || (resp[0] & 0x80000000)) | |
391 | - break; | |
392 | - ret = -ETIMEDOUT; | |
393 | - } | |
394 | - | |
395 | - if (ret) | |
396 | - return ret; | |
397 | - | |
398 | - /* Get CID of all cards. FIXME: Support more than one card */ | |
399 | - ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID | OPEN_DRAIN); | |
400 | - if (ret) | |
401 | - return ret; | |
402 | - mmc_parse_cid(cid, resp); | |
403 | - if (verbose) | |
404 | - mmc_dump_cid(cid); | |
405 | - | |
406 | - /* Set Relative Address of the card that responded */ | |
407 | - ret = mmc_cmd(MMC_CMD_SET_RELATIVE_ADDR, mmc_rca << 16, resp, | |
408 | - R1 | NCR | OPEN_DRAIN); | |
409 | - return ret; | |
410 | -} | |
411 | - | |
412 | -static void mci_set_data_timeout(struct mmc_csd *csd) | |
413 | -{ | |
414 | - static const unsigned int dtomul_to_shift[] = { | |
415 | - 0, 4, 7, 8, 10, 12, 16, 20, | |
416 | - }; | |
417 | - static const unsigned int taac_exp[] = { | |
418 | - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | |
419 | - }; | |
420 | - static const unsigned int taac_mant[] = { | |
421 | - 0, 10, 12, 13, 15, 60, 25, 30, | |
422 | - 35, 40, 45, 50, 55, 60, 70, 80, | |
423 | - }; | |
424 | - unsigned int timeout_ns, timeout_clks; | |
425 | - unsigned int e, m; | |
426 | - unsigned int dtocyc, dtomul; | |
427 | - unsigned int shift; | |
428 | - u32 dtor; | |
429 | - | |
430 | - e = csd->taac & 0x07; | |
431 | - m = (csd->taac >> 3) & 0x0f; | |
432 | - | |
433 | - timeout_ns = (taac_exp[e] * taac_mant[m] + 9) / 10; | |
434 | - timeout_clks = csd->nsac * 100; | |
435 | - | |
436 | - timeout_clks += (((timeout_ns + 9) / 10) | |
437 | - * ((CONFIG_SYS_MMC_CLK_PP + 99999) / 100000) + 9999) / 10000; | |
438 | - if (!mmc_card_is_sd) | |
439 | - timeout_clks *= 10; | |
440 | - else | |
441 | - timeout_clks *= 100; | |
442 | - | |
443 | - dtocyc = timeout_clks; | |
444 | - dtomul = 0; | |
445 | - shift = 0; | |
446 | - while (dtocyc > 15 && dtomul < 8) { | |
447 | - dtomul++; | |
448 | - shift = dtomul_to_shift[dtomul]; | |
449 | - dtocyc = (timeout_clks + (1 << shift) - 1) >> shift; | |
450 | - } | |
451 | - | |
452 | - if (dtomul >= 8) { | |
453 | - dtomul = 7; | |
454 | - dtocyc = 15; | |
455 | - puts("Warning: Using maximum data timeout\n"); | |
456 | - } | |
457 | - | |
458 | - dtor = (MMCI_BF(DTOMUL, dtomul) | |
459 | - | MMCI_BF(DTOCYC, dtocyc)); | |
460 | - mmci_writel(DTOR, dtor); | |
461 | - | |
462 | - printf("mmc: Using %u cycles data timeout (DTOR=0x%x)\n", | |
463 | - dtocyc << shift, dtor); | |
464 | -} | |
465 | - | |
466 | -int mmc_legacy_init(int verbose) | |
467 | -{ | |
468 | - struct mmc_cid cid; | |
469 | - struct mmc_csd csd; | |
470 | - unsigned int max_blksz; | |
471 | - int ret; | |
472 | - | |
473 | - /* Initialize controller */ | |
474 | - mmci_writel(CR, MMCI_BIT(SWRST)); | |
475 | - mmci_writel(CR, MMCI_BIT(MCIEN)); | |
476 | - mmci_writel(DTOR, 0x5f); | |
477 | - mmci_writel(IDR, ~0UL); | |
478 | - mci_set_mode(CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); | |
479 | - | |
480 | - mmc_card_is_sd = 0; | |
481 | - | |
482 | - ret = sd_init_card(&cid, verbose); | |
483 | - if (ret) { | |
484 | - mmc_rca = MMC_DEFAULT_RCA; | |
485 | - ret = mmc_init_card(&cid, verbose); | |
486 | - } | |
487 | - if (ret) | |
488 | - return ret; | |
489 | - | |
490 | - /* Get CSD from the card */ | |
491 | - ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, &csd, R2 | NCR); | |
492 | - if (ret) | |
493 | - return ret; | |
494 | - if (verbose) | |
495 | - mmc_dump_csd(&csd); | |
496 | - | |
497 | - mci_set_data_timeout(&csd); | |
498 | - | |
499 | - /* Initialize the blockdev structure */ | |
500 | - mmc_blkdev.if_type = IF_TYPE_MMC; | |
501 | - mmc_blkdev.part_type = PART_TYPE_DOS; | |
502 | - mmc_blkdev.block_read = mmc_bread; | |
503 | - sprintf((char *)mmc_blkdev.vendor, | |
504 | - "Man %02x%04x Snr %08lx", | |
505 | - cid.mid, cid.oid, cid.psn); | |
506 | - strncpy((char *)mmc_blkdev.product, cid.pnm, | |
507 | - sizeof(mmc_blkdev.product)); | |
508 | - sprintf((char *)mmc_blkdev.revision, "%x %x", | |
509 | - cid.prv >> 4, cid.prv & 0x0f); | |
510 | - | |
511 | - /* | |
512 | - * If we can't use 512 byte blocks, refuse to deal with the | |
513 | - * card. Tons of code elsewhere seems to depend on this. | |
514 | - */ | |
515 | - max_blksz = 1 << csd.read_bl_len; | |
516 | - if (max_blksz < 512 || (max_blksz > 512 && !csd.read_bl_partial)) { | |
517 | - printf("Card does not support 512 byte reads, aborting.\n"); | |
518 | - return -ENODEV; | |
519 | - } | |
520 | - mmc_blkdev.blksz = 512; | |
521 | - mmc_blkdev.lba = (csd.c_size + 1) * (1 << (csd.c_size_mult + 2)); | |
522 | - | |
523 | - mci_set_mode(CONFIG_SYS_MMC_CLK_PP, mmc_blkdev.blksz); | |
524 | - | |
525 | -#if 0 | |
526 | - if (fat_register_device(&mmc_blkdev, 1)) | |
527 | - printf("Could not register MMC fat device\n"); | |
528 | -#else | |
529 | - init_part(&mmc_blkdev); | |
530 | -#endif | |
531 | - | |
532 | - return 0; | |
533 | -} |