bfin_sdh.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*
  2. * Driver for Blackfin on-chip SDH controller
  3. *
  4. * Copyright (c) 2008 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <malloc.h>
  10. #include <part.h>
  11. #include <mmc.h>
  12. #include <asm/io.h>
  13. #include <asm/errno.h>
  14. #include <asm/byteorder.h>
  15. #include <asm/blackfin.h>
  16. #include <asm/mach-common/bits/sdh.h>
  17. #include <asm/mach-common/bits/dma.h>
  18. #include "bfin_sdh.h"
  19. /* SD_CLK frequency must be less than 400k in identification mode */
  20. #ifndef CONFIG_SYS_MMC_CLK_ID
  21. #define CONFIG_SYS_MMC_CLK_ID 200000
  22. #endif
  23. /* SD_CLK for normal working */
  24. #ifndef CONFIG_SYS_MMC_CLK_OP
  25. #define CONFIG_SYS_MMC_CLK_OP 25000000
  26. #endif
  27. /* support 3.2-3.3V and 3.3-3.4V */
  28. #define CONFIG_SYS_MMC_OP_COND 0x00300000
  29. #define MMC_DEFAULT_RCA 1
  30. #if defined(__ADSPBF51x__)
  31. # define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CONTROL
  32. # define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CONTROL
  33. # define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CONTROL
  34. # define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CONTROL
  35. # define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT
  36. # define bfin_write_SDH_COMMAND bfin_write_RSI_COMMAND
  37. # define bfin_read_SDH_RESPONSE0 bfin_read_RSI_RESPONSE0
  38. # define bfin_read_SDH_RESPONSE1 bfin_read_RSI_RESPONSE1
  39. # define bfin_read_SDH_RESPONSE2 bfin_read_RSI_RESPONSE2
  40. # define bfin_read_SDH_RESPONSE3 bfin_read_RSI_RESPONSE3
  41. # define bfin_write_SDH_DATA_TIMER bfin_write_RSI_DATA_TIMER
  42. # define bfin_write_SDH_DATA_LGTH bfin_write_RSI_DATA_LGTH
  43. # define bfin_read_SDH_DATA_CTL bfin_read_RSI_DATA_CONTROL
  44. # define bfin_write_SDH_DATA_CTL bfin_write_RSI_DATA_CONTROL
  45. # define bfin_read_SDH_STATUS bfin_read_RSI_STATUS
  46. # define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUSCL
  47. # define bfin_read_SDH_CFG bfin_read_RSI_CONFIG
  48. # define bfin_write_SDH_CFG bfin_write_RSI_CONFIG
  49. # define bfin_write_DMA_START_ADDR bfin_write_DMA4_START_ADDR
  50. # define bfin_write_DMA_X_COUNT bfin_write_DMA4_X_COUNT
  51. # define bfin_write_DMA_X_MODIFY bfin_write_DMA4_X_MODIFY
  52. # define bfin_write_DMA_CONFIG bfin_write_DMA4_CONFIG
  53. #elif defined(__ADSPBF54x__)
  54. # define bfin_write_DMA_START_ADDR bfin_write_DMA22_START_ADDR
  55. # define bfin_write_DMA_X_COUNT bfin_write_DMA22_X_COUNT
  56. # define bfin_write_DMA_X_MODIFY bfin_write_DMA22_X_MODIFY
  57. # define bfin_write_DMA_CONFIG bfin_write_DMA22_CONFIG
  58. #else
  59. # error no support for this proc yet
  60. #endif
  61. static unsigned int mmc_rca;
  62. static int mmc_card_is_sd;
  63. static block_dev_desc_t mmc_blkdev;
  64. struct mmc_cid cid;
  65. static __u32 csd[4];
  66. #define get_bits(resp, start, size) \
  67. ({ \
  68. const int __size = size; \
  69. const uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1; \
  70. const int32_t __off = 3 - ((start) / 32); \
  71. const int32_t __shft = (start) & 31; \
  72. uint32_t __res; \
  73. \
  74. __res = resp[__off] >> __shft; \
  75. if (__size + __shft > 32) \
  76. __res |= resp[__off-1] << ((32 - __shft) % 32); \
  77. __res & __mask; \
  78. })
  79. block_dev_desc_t *mmc_get_dev(int dev)
  80. {
  81. return &mmc_blkdev;
  82. }
  83. static void mci_set_clk(unsigned long clk)
  84. {
  85. unsigned long sys_clk;
  86. unsigned long clk_div;
  87. __u16 clk_ctl = 0;
  88. /* setting SD_CLK */
  89. sys_clk = get_sclk();
  90. bfin_write_SDH_CLK_CTL(0);
  91. if (sys_clk % (2 * clk) == 0)
  92. clk_div = sys_clk / (2 * clk) - 1;
  93. else
  94. clk_div = sys_clk / (2 * clk);
  95. if (clk_div > 0xff)
  96. clk_div = 0xff;
  97. clk_ctl |= (clk_div & 0xff);
  98. clk_ctl |= CLK_E;
  99. bfin_write_SDH_CLK_CTL(clk_ctl);
  100. }
  101. static int
  102. mmc_cmd(unsigned long cmd, unsigned long arg, void *resp, unsigned long flags)
  103. {
  104. unsigned int sdh_cmd;
  105. unsigned int status;
  106. int ret = 0;
  107. sdh_cmd = 0;
  108. unsigned long *response = resp;
  109. sdh_cmd |= cmd;
  110. if (flags & MMC_RSP_PRESENT)
  111. sdh_cmd |= CMD_RSP;
  112. if (flags & MMC_RSP_136)
  113. sdh_cmd |= CMD_L_RSP;
  114. bfin_write_SDH_ARGUMENT(arg);
  115. bfin_write_SDH_COMMAND(sdh_cmd | CMD_E);
  116. /* wait for a while */
  117. do {
  118. udelay(1);
  119. status = bfin_read_SDH_STATUS();
  120. } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT |
  121. CMD_CRC_FAIL)));
  122. if (flags & MMC_RSP_PRESENT) {
  123. response[0] = bfin_read_SDH_RESPONSE0();
  124. if (flags & MMC_RSP_136) {
  125. response[1] = bfin_read_SDH_RESPONSE1();
  126. response[2] = bfin_read_SDH_RESPONSE2();
  127. response[3] = bfin_read_SDH_RESPONSE3();
  128. }
  129. }
  130. if (status & CMD_TIME_OUT) {
  131. printf("CMD%d timeout\n", (int)cmd);
  132. ret |= -ETIMEDOUT;
  133. } else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) {
  134. printf("CMD%d CRC failure\n", (int)cmd);
  135. ret |= -EILSEQ;
  136. }
  137. bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT |
  138. CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT);
  139. return ret;
  140. }
  141. static int
  142. mmc_acmd(unsigned long cmd, unsigned long arg, void *resp, unsigned long flags)
  143. {
  144. unsigned long aresp[4];
  145. int ret = 0;
  146. ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp,
  147. MMC_RSP_PRESENT);
  148. if (ret)
  149. return ret;
  150. if ((aresp[0] & (ILLEGAL_COMMAND | APP_CMD)) != APP_CMD)
  151. return -ENODEV;
  152. ret = mmc_cmd(cmd, arg, resp, flags);
  153. return ret;
  154. }
  155. static unsigned long
  156. mmc_bread(int dev, unsigned long start, lbaint_t blkcnt, void *buffer)
  157. {
  158. int ret, i;
  159. unsigned long resp[4];
  160. unsigned long card_status;
  161. __u8 *buf = buffer;
  162. __u32 status;
  163. __u16 data_ctl = 0;
  164. __u16 dma_cfg = 0;
  165. if (blkcnt == 0)
  166. return 0;
  167. debug("mmc_bread: dev %d, start %d, blkcnt %d\n", dev, start, blkcnt);
  168. /* Force to use 512-byte block,because a lot of code depends on this */
  169. data_ctl |= 9 << 4;
  170. data_ctl |= DTX_DIR;
  171. bfin_write_SDH_DATA_CTL(data_ctl);
  172. dma_cfg |= WDSIZE_32 | RESTART | WNR | DMAEN;
  173. /* FIXME later */
  174. bfin_write_SDH_DATA_TIMER(0xFFFFFFFF);
  175. for (i = 0; i < blkcnt; ++i, ++start) {
  176. blackfin_dcache_flush_invalidate_range(buf + i * mmc_blkdev.blksz,
  177. buf + (i + 1) * mmc_blkdev.blksz);
  178. bfin_write_DMA_START_ADDR(buf + i * mmc_blkdev.blksz);
  179. bfin_write_DMA_X_COUNT(mmc_blkdev.blksz / 4);
  180. bfin_write_DMA_X_MODIFY(4);
  181. bfin_write_DMA_CONFIG(dma_cfg);
  182. bfin_write_SDH_DATA_LGTH(mmc_blkdev.blksz);
  183. /* Put the device into Transfer state */
  184. ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, MMC_RSP_R1);
  185. if (ret) {
  186. printf("MMC_CMD_SELECT_CARD failed\n");
  187. goto out;
  188. }
  189. /* Set block length */
  190. ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, MMC_RSP_R1);
  191. if (ret) {
  192. printf("MMC_CMD_SET_BLOCKLEN failed\n");
  193. goto out;
  194. }
  195. ret = mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK,
  196. start * mmc_blkdev.blksz, resp,
  197. MMC_RSP_R1);
  198. if (ret) {
  199. printf("MMC_CMD_READ_SINGLE_BLOCK failed\n");
  200. goto out;
  201. }
  202. bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
  203. do {
  204. udelay(1);
  205. status = bfin_read_SDH_STATUS();
  206. } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN)));
  207. if (status & (DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN)) {
  208. bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT | \
  209. DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT);
  210. goto read_error;
  211. } else {
  212. bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT);
  213. mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, 0);
  214. }
  215. }
  216. out:
  217. return i;
  218. read_error:
  219. mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, MMC_RSP_R1);
  220. printf("mmc: bread failed, status = %08x, card status = %08lx\n",
  221. status, card_status);
  222. goto out;
  223. }
  224. static unsigned long
  225. mmc_bwrite(int dev, unsigned long start, lbaint_t blkcnt, const void *buffer)
  226. {
  227. int ret, i = 0;
  228. unsigned long resp[4];
  229. unsigned long card_status;
  230. const __u8 *buf = buffer;
  231. __u32 status;
  232. __u16 data_ctl = 0;
  233. __u16 dma_cfg = 0;
  234. if (blkcnt == 0)
  235. return 0;
  236. debug("mmc_bwrite: dev %d, start %lx, blkcnt %lx\n",
  237. dev, start, blkcnt);
  238. /* Force to use 512-byte block,because a lot of code depends on this */
  239. data_ctl |= 9 << 4;
  240. data_ctl &= ~DTX_DIR;
  241. bfin_write_SDH_DATA_CTL(data_ctl);
  242. dma_cfg |= WDSIZE_32 | RESTART | DMAEN;
  243. /* FIXME later */
  244. bfin_write_SDH_DATA_TIMER(0xFFFFFFFF);
  245. for (i = 0; i < blkcnt; ++i, ++start) {
  246. bfin_write_DMA_START_ADDR(buf + i * mmc_blkdev.blksz);
  247. bfin_write_DMA_X_COUNT(mmc_blkdev.blksz / 4);
  248. bfin_write_DMA_X_MODIFY(4);
  249. bfin_write_DMA_CONFIG(dma_cfg);
  250. bfin_write_SDH_DATA_LGTH(mmc_blkdev.blksz);
  251. /* Put the device into Transfer state */
  252. ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, MMC_RSP_R1);
  253. if (ret) {
  254. printf("MMC_CMD_SELECT_CARD failed\n");
  255. goto out;
  256. }
  257. /* Set block length */
  258. ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, MMC_RSP_R1);
  259. if (ret) {
  260. printf("MMC_CMD_SET_BLOCKLEN failed\n");
  261. goto out;
  262. }
  263. ret = mmc_cmd(MMC_CMD_WRITE_SINGLE_BLOCK,
  264. start * mmc_blkdev.blksz, resp,
  265. MMC_RSP_R1);
  266. if (ret) {
  267. printf("MMC_CMD_WRITE_SINGLE_BLOCK failed\n");
  268. goto out;
  269. }
  270. bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
  271. do {
  272. udelay(1);
  273. status = bfin_read_SDH_STATUS();
  274. } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | TX_UNDERRUN)));
  275. if (status & (DAT_TIME_OUT | DAT_CRC_FAIL | TX_UNDERRUN)) {
  276. bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT |
  277. DAT_CRC_FAIL_STAT | TX_UNDERRUN_STAT);
  278. goto write_error;
  279. } else {
  280. bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT);
  281. mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, 0);
  282. }
  283. }
  284. out:
  285. return i;
  286. write_error:
  287. mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, MMC_RSP_R1);
  288. printf("mmc: bwrite failed, status = %08x, card status = %08lx\n",
  289. status, card_status);
  290. goto out;
  291. }
  292. static void mmc_parse_cid(struct mmc_cid *cid, unsigned long *resp)
  293. {
  294. cid->mid = resp[0] >> 24;
  295. cid->oid = (resp[0] >> 8) & 0xffff;
  296. cid->pnm[0] = resp[0];
  297. cid->pnm[1] = resp[1] >> 24;
  298. cid->pnm[2] = resp[1] >> 16;
  299. cid->pnm[3] = resp[1] >> 8;
  300. cid->pnm[4] = resp[1];
  301. cid->pnm[5] = resp[2] >> 24;
  302. cid->pnm[6] = 0;
  303. cid->prv = resp[2] >> 16;
  304. cid->psn = (resp[2] << 16) | (resp[3] >> 16);
  305. cid->mdt = resp[3] >> 8;
  306. }
  307. static void sd_parse_cid(struct mmc_cid *cid, unsigned long *resp)
  308. {
  309. cid->mid = resp[0] >> 24;
  310. cid->oid = (resp[0] >> 8) & 0xffff;
  311. cid->pnm[0] = resp[0];
  312. cid->pnm[1] = resp[1] >> 24;
  313. cid->pnm[2] = resp[1] >> 16;
  314. cid->pnm[3] = resp[1] >> 8;
  315. cid->pnm[4] = resp[1];
  316. cid->pnm[5] = 0;
  317. cid->pnm[6] = 0;
  318. cid->prv = resp[2] >> 24;
  319. cid->psn = (resp[2] << 8) | (resp[3] >> 24);
  320. cid->mdt = (resp[3] >> 8) & 0x0fff;
  321. }
  322. static void mmc_dump_cid(const struct mmc_cid *cid)
  323. {
  324. printf("CID information:\n");
  325. printf("Manufacturer ID: %02X\n", cid->mid);
  326. printf("OEM/Application ID: %04X\n", cid->oid);
  327. printf("Product name: %s\n", cid->pnm);
  328. printf("Product Revision: %u.%u\n",
  329. cid->prv >> 4, cid->prv & 0x0f);
  330. printf("Product Serial Number: %lu\n", cid->psn);
  331. printf("Manufacturing Date: %02u/%02u\n",
  332. cid->mdt >> 4, cid->mdt & 0x0f);
  333. }
  334. static void mmc_dump_csd(__u32 *csd)
  335. {
  336. printf("CSD information:\n");
  337. printf("CSD structure version: 1.%u\n", get_bits(csd, 126, 2));
  338. printf("Card command classes: %03x\n", get_bits(csd, 84, 12));
  339. printf("Max trans speed: %s\n", (get_bits(csd, 96, 8) == 0x32) ? "25MHz" : "50MHz");
  340. printf("Read block length: %d\n", 1 << get_bits(csd, 80, 4));
  341. printf("Write block length: %u\n", 1 << get_bits(csd, 22, 4));
  342. printf("Card capacity: %u bytes\n",
  343. (get_bits(csd, 62, 12) + 1) * (1 << (get_bits(csd, 47, 3) + 2)) *
  344. (1 << get_bits(csd, 80, 4)));
  345. putc('\n');
  346. }
  347. static int mmc_idle_cards(void)
  348. {
  349. int ret = 0;
  350. /* Reset all cards */
  351. ret = mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, NULL, 0);
  352. if (ret)
  353. return ret;
  354. udelay(500);
  355. return mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, NULL, 0);
  356. }
  357. static int sd_init_card(struct mmc_cid *cid, int verbose)
  358. {
  359. unsigned long resp[4];
  360. int i, ret = 0;
  361. mmc_idle_cards();
  362. for (i = 0; i < 1000; ++i) {
  363. ret = mmc_acmd(SD_CMD_APP_SEND_OP_COND, CONFIG_SYS_MMC_OP_COND,
  364. resp, MMC_RSP_R3);
  365. if (ret || (resp[0] & 0x80000000))
  366. break;
  367. ret = -ETIMEDOUT;
  368. }
  369. if (ret)
  370. return ret;
  371. ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, MMC_RSP_R2);
  372. if (ret)
  373. return ret;
  374. sd_parse_cid(cid, resp);
  375. if (verbose)
  376. mmc_dump_cid(cid);
  377. /* Get RCA of the card that responded */
  378. ret = mmc_cmd(SD_CMD_SEND_RELATIVE_ADDR, 0, resp, MMC_RSP_R6);
  379. if (ret)
  380. return ret;
  381. mmc_rca = (resp[0] >> 16) & 0xffff;
  382. if (verbose)
  383. printf("SD Card detected (RCA %u)\n", mmc_rca);
  384. mmc_card_is_sd = 1;
  385. return 0;
  386. }
  387. static int mmc_init_card(struct mmc_cid *cid, int verbose)
  388. {
  389. unsigned long resp[4];
  390. int i, ret = 0;
  391. mmc_idle_cards();
  392. for (i = 0; i < 1000; ++i) {
  393. ret = mmc_cmd(MMC_CMD_SEND_OP_COND, CONFIG_SYS_MMC_OP_COND, resp,
  394. MMC_RSP_R3);
  395. if (ret || (resp[0] & 0x80000000))
  396. break;
  397. ret = -ETIMEDOUT;
  398. }
  399. if (ret)
  400. return ret;
  401. /* Get CID of all cards. FIXME: Support more than one card */
  402. ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, MMC_RSP_R2);
  403. if (ret)
  404. return ret;
  405. mmc_parse_cid(cid, resp);
  406. if (verbose)
  407. mmc_dump_cid(cid);
  408. /* Set Relative Address of the card that responded */
  409. ret = mmc_cmd(MMC_CMD_SET_RELATIVE_ADDR, mmc_rca << 16, resp,
  410. MMC_RSP_R1);
  411. return ret;
  412. }
  413. int mmc_legacy_init(int verbose)
  414. {
  415. __u16 pwr_ctl = 0;
  416. int ret;
  417. unsigned int max_blksz;
  418. /* Initialize sdh controller */
  419. #if defined(__ADSPBF54x__)
  420. bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
  421. bfin_write_PORTC_FER(bfin_read_PORTC_FER() | 0x3F00);
  422. bfin_write_PORTC_MUX(bfin_read_PORTC_MUX() & ~0xFFF0000);
  423. #elif defined(__ADSPBF51x__)
  424. bfin_write_PORTG_FER(bfin_read_PORTG_FER() | 0x01F8);
  425. bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() & ~0x3FC) | 0x154);
  426. #else
  427. # error no portmux for this proc yet
  428. #endif
  429. bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
  430. /* Disable card detect pin */
  431. bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60);
  432. mci_set_clk(CONFIG_SYS_MMC_CLK_ID);
  433. /* setting power control */
  434. pwr_ctl |= ROD_CTL;
  435. pwr_ctl |= PWR_ON;
  436. bfin_write_SDH_PWR_CTL(pwr_ctl);
  437. mmc_card_is_sd = 0;
  438. ret = sd_init_card(&cid, verbose);
  439. if (ret) {
  440. mmc_rca = MMC_DEFAULT_RCA;
  441. ret = mmc_init_card(&cid, verbose);
  442. }
  443. if (ret)
  444. return ret;
  445. /* Get CSD from the card */
  446. ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, csd, MMC_RSP_R2);
  447. if (ret)
  448. return ret;
  449. if (verbose)
  450. mmc_dump_csd(csd);
  451. /* Initialize the blockdev structure */
  452. mmc_blkdev.if_type = IF_TYPE_MMC;
  453. mmc_blkdev.part_type = PART_TYPE_DOS;
  454. mmc_blkdev.block_read = mmc_bread;
  455. mmc_blkdev.block_write = mmc_bwrite;
  456. sprintf(mmc_blkdev.vendor,
  457. "Man %02x%04x Snr %08lx",
  458. cid.mid, cid.oid, cid.psn);
  459. strncpy(mmc_blkdev.product, cid.pnm,
  460. sizeof(mmc_blkdev.product));
  461. sprintf(mmc_blkdev.revision, "%x %x",
  462. cid.prv >> 4, cid.prv & 0x0f);
  463. max_blksz = 1 << get_bits(csd, 80, 4);
  464. /*
  465. * If we can't use 512 byte blocks, refuse to deal with the
  466. * card. Tons of code elsewhere seems to depend on this.
  467. */
  468. if (max_blksz < 512 || (max_blksz > 512 && !get_bits(csd, 79, 1))) {
  469. printf("Card does not support 512 byte reads, aborting.\n");
  470. return -ENODEV;
  471. }
  472. mmc_blkdev.blksz = 512;
  473. mmc_blkdev.lba = (get_bits(csd, 62, 12) + 1) * (1 << (get_bits(csd, 47, 3) + 2));
  474. mci_set_clk(CONFIG_SYS_MMC_CLK_OP);
  475. init_part(&mmc_blkdev);
  476. return 0;
  477. }
  478. int mmc2info(ulong addr)
  479. {
  480. return 0;
  481. }