Advertisement
Guest User

Untitled

a guest
Aug 13th, 2013
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.28 KB | None | 0 0
  1. commit 99d13f86eea7beecd38116632d704b65b5897a88
  2. Author: Marcin Bukat <marcin.bukat@gmail.com>
  3. Date: Tue Jul 16 21:02:52 2013 +0200
  4.  
  5. sd rework WIP
  6.  
  7. Change-Id: I9e8db66338d9bd6bebe7abf309ef37f9ba06edc5
  8.  
  9. diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
  10. index cb870c9..29f6f35 100644
  11. --- a/firmware/target/arm/rk27xx/sd-rk27xx.c
  12. +++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
  13. @@ -47,11 +47,6 @@
  14. #include <stdarg.h>
  15. #include "sysfont.h"
  16.  
  17. -#define RES_NO (-1)
  18. -
  19. -/* debug stuff */
  20. -unsigned long sd_debug_time_rd = 0;
  21. -unsigned long sd_debug_time_wr = 0;
  22.  
  23. static tCardInfo card_info;
  24.  
  25. @@ -66,11 +61,79 @@ static struct event_queue sd_queue;
  26. bool sd_enabled = false;
  27. #endif
  28.  
  29. +struct sdmmc_command {
  30. + uint32_t opcode; /* sd command opcode */
  31. + uint32_t arg; /* sd command argument */
  32. + uint32_t flags; /* flags coding response type */
  33. + uint32_t rsp[4]; /* command response buffer */
  34. + uint32_t retries; /* no of retries */
  35. + bool error; /* command error indicator */
  36. +};
  37. +
  38. +struct sdmmc_data {
  39. + void *buf; /* data transfer buffer */
  40. + uint32_t blksz; /* transfer block size */
  41. + uint32_t blkcnt; /* transfer block count */
  42. + uint32_t flags; /* flags coding transfer direction */
  43. + uint32_t error; /* data transfer error indicator */
  44. +};
  45. +
  46. +struct sdmmc_request {
  47. + struct sdmmc_command *cmd;
  48. + struct sdmmc_data *data;
  49. + struct sdmmc_command *stop;
  50. +};
  51. +
  52. +#define SDMMC_CMD_PREPARE(o,a,f) cmd.opcode = (o); \
  53. + cmd.arg = (a); \
  54. + cmd.flags = (f)
  55. +
  56. +#define SDMMC_STP_PREPARE(o,a,f) stp.opcode = (o); \
  57. + stp.arg = (a); \
  58. + stp.flags = (f)
  59. +
  60. +#define SDMMC_DAT_PREPARE(b,s,c,f) dat.buf = (void *)(b); \
  61. + dat.blksz = (s); \
  62. + dat.blkcnt = (c); \
  63. + dat.flags = (f)
  64. +
  65. +#define SDMMC_REQ_PREPARE(c,d,s) req.cmd = (c); \
  66. + req.data = (d); \
  67. + req.stop = (s)
  68. +
  69. +static struct sdmmc_request req;
  70. +static struct sdmmc_command cmd, stp;
  71. +static struct sdmmc_data dat;
  72. +
  73. +#define SDMMC_RSP_NONE (0)
  74. +#define SDMMC_RSP_R1 (1<<0)
  75. +#define SDMMC_RSP_R1B (1<<1)
  76. +#define SDMMC_RSP_R2 (1<<2)
  77. +#define SDMMC_RSP_R3 (1<<3)
  78. +#define SDMMC_RSP_R4 (1<<4)
  79. +#define SDMMC_RSP_R5 (1<<5)
  80. +#define SDMMC_RSP_R6 (1<<6)
  81. +#define SDMMC_RSP_R7 (1<<7)
  82. +
  83. +
  84. +#define SDMMC_DIR_WRITE (0)
  85. +#define SDMMC_DIR_READ (1)
  86. +
  87. +/* in Hz */
  88. +#define SDMMC_FREQ_INIT (400000)
  89. +#define SDMMC_FREQ_NORMAL (25000000)
  90. +
  91. +
  92. +/********** hw specific part ************/
  93. static struct semaphore transfer_completion_signal;
  94. static struct semaphore command_completion_signal;
  95. static volatile bool retry;
  96. static volatile int cmd_error;
  97.  
  98. +/* debug stuff */
  99. +unsigned long sd_debug_time_rd = 0;
  100. +unsigned long sd_debug_time_wr = 0;
  101. +
  102. /* interrupt handler for SD */
  103. void INT_SD(void)
  104. {
  105. @@ -105,9 +168,9 @@ void INT_SD(void)
  106. */
  107. static void mmu_switch_buff(void)
  108. {
  109. - static unsigned int i = 0;
  110. + static unsigned int i = 1;
  111.  
  112. - if (i++ & 0x01)
  113. + if (i ^= 1)
  114. {
  115. MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET |
  116. MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD;
  117. @@ -139,125 +202,286 @@ static inline bool card_detect_target(void)
  118. #endif
  119. }
  120.  
  121. -/* Send command to the SD card. Command finish is signaled in ISR */
  122. -static bool send_cmd(const int cmd, const int arg, const int res,
  123. - unsigned long *response)
  124. +
  125. +static inline void controller_read_data(void *dst, uint32_t blksz)
  126. {
  127. - SD_CMD = arg;
  128. + commit_discard_dcache_range((const void *)dst, blksz);
  129.  
  130. - if (res > 0)
  131. - SD_CMDREST = CMD_XFER_START | RES_XFER_START | res | cmd;
  132. - else
  133. - SD_CMDREST = CMD_XFER_START | RES_XFER_END | RES_R1 | cmd;
  134. + A2A_IDST0 = (unsigned long)dst;
  135. + A2A_ICNT0 = blksz;
  136. + A2A_CON0 = (3<<9) | /* burst 16 */
  137. + (1<<6) | /* fixed src */
  138. + (1<<3) | /* DMA start */
  139. + (2<<1) | /* word transfer size */
  140. + (1<<0); /* software mode */
  141.  
  142. - semaphore_wait(&command_completion_signal, TIMEOUT_BLOCK);
  143. + /* wait for DMA engine to finish transfer */
  144. + while (A2A_DMA_STS & 1);
  145. +}
  146.  
  147. - /* Handle command responses & errors */
  148. - if(res != RES_NO)
  149. - {
  150. - if(cmd_error & STAT_CMD_RES_ERR)
  151. - return false;
  152. +static inline void controller_write_data(void *src, uint32_t blksz)
  153. +{
  154. + commit_discard_dcache_range((const void *)src, blksz);
  155.  
  156. - if(res == RES_R2)
  157. - {
  158. - response[0] = SD_RES3;
  159. - response[1] = SD_RES2;
  160. - response[2] = SD_RES1;
  161. - response[3] = SD_RES0;
  162. - }
  163. - else
  164. - response[0] = SD_RES3;
  165. - }
  166. - return true;
  167. + A2A_ISRC1 = (unsigned long)src;
  168. + A2A_ICNT1 = blksz;
  169. + A2A_CON1 = (3<<9) | /* burst 16 */
  170. + (1<<5) | /* fixed dst */
  171. + (1<<3) | /* DMA start */
  172. + (2<<1) | /* word transfer size */
  173. + (1<<0); /* software mode */
  174. +
  175. + /* wait for DMA engine to finish transfer */
  176. + while (A2A_DMA_STS & 2);
  177. }
  178.  
  179. -#if 0
  180. -/* for some misterious reason the card does not report itself as being in TRAN
  181. - * but transfers are successful. Rockchip OF does not check the card state
  182. - * after SELECT. I checked two different cards.
  183. - */
  184. -static void print_card_status(void)
  185. +static int sd_wait_card_busy(void)
  186. {
  187. - unsigned long response;
  188. - send_cmd(SD_SEND_STATUS, card_info.rca, RES_R1,
  189. - &response);
  190. + unsigned int timeout = current_tick + 5*HZ;
  191. +
  192. + while (!(SD_CARD & SD_CARD_BSY))
  193. + {
  194. + if(TIME_AFTER(current_tick, timeout))
  195. + return -1;
  196. + }
  197.  
  198. - printf("card status: 0x%0x, state: 0x%0x", response, (response>>9)&0xf);
  199. + return 0;
  200. }
  201.  
  202. -static int sd_wait_for_tran_state(void)
  203. +static void rk27xx_sd_cmd(struct sdmmc_command *cmd)
  204. {
  205. - unsigned long response;
  206. - unsigned int timeout = current_tick + 5*HZ;
  207. - int cmd_retry = 10;
  208. + SD_CMD = cmd->arg;
  209.  
  210. - while (1)
  211. + switch (cmd->flags)
  212. {
  213. - while (!send_cmd(SD_SEND_STATUS, card_info.rca, RES_R1,
  214. - &response) && cmd_retry > 0)
  215. + case SDMMC_RSP_NONE:
  216. + case SDMMC_RSP_R4:
  217. + case SDMMC_RSP_R7:
  218. + SD_CMDREST = CMD_XFER_START | RES_XFER_END | cmd->opcode;
  219. + break;
  220. +
  221. + case SDMMC_RSP_R1:
  222. + SD_CMDREST = CMD_XFER_START | RES_XFER_START | RES_R1 | cmd->opcode;
  223. + break;
  224. +
  225. + case SDMMC_RSP_R1B:
  226. + SD_CMDREST = CMD_XFER_START | RES_XFER_START | RES_R1b | cmd->opcode;
  227. + break;
  228. +
  229. + case SDMMC_RSP_R2:
  230. + SD_CMDREST = CMD_XFER_START | RES_XFER_START | RES_R2 | cmd->opcode;
  231. + break;
  232. +
  233. + case SDMMC_RSP_R3:
  234. + SD_CMDREST = CMD_XFER_START | RES_XFER_START | RES_R3 | cmd->opcode;
  235. + break;
  236. +
  237. + case SDMMC_RSP_R6:
  238. + SD_CMDREST = CMD_XFER_START | RES_XFER_START | RES_R6 | cmd->opcode;
  239. + }
  240. +
  241. + semaphore_wait(&command_completion_signal, HZ);
  242. +
  243. + if (cmd->flags != SDMMC_RSP_NONE)
  244. + {
  245. + cmd->error = (cmd_error & STAT_CMD_RES_ERR) ? true : false;
  246. +
  247. + cmd->rsp[0] = SD_RES3;
  248. + if (cmd->flags == SDMMC_RSP_R2)
  249. {
  250. - cmd_retry--;
  251. + cmd->rsp[1] = SD_RES2;
  252. + cmd->rsp[2] = SD_RES1;
  253. + cmd->rsp[3] = SD_RES0;
  254. }
  255. -
  256. - if (cmd_retry <= 0)
  257. + else if (cmd->flags == SDMMC_RSP_R1B)
  258. {
  259. - return -1;
  260. + sd_wait_card_busy();
  261. }
  262. + }
  263. +}
  264. +
  265. +/* considers only reads for now */
  266. +static void rk27xx_sd_data(struct sdmmc_data *data)
  267. +{
  268. + uint32_t xfercnt = data->blkcnt;
  269. + void *xferbuf = data->buf;
  270. +
  271. + mmu_buff_reset();
  272.  
  273. - if (((response >> 9) & 0xf) == SD_TRAN)
  274. + if (data->flags & SDMMC_DIR_READ)
  275. + {
  276. + /* first block */
  277. + SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  278. + DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  279. + ((xfercnt == 1) ? DATA_XFER_SINGLE : DATA_XFER_MULTI);
  280. +
  281. + semaphore_wait(&transfer_completion_signal, HZ);
  282. +
  283. + while(--xfercnt)
  284. {
  285. - return 0;
  286. + mmu_switch_buff();
  287. +
  288. + SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  289. + DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  290. + ((xfercnt == 1) ? DATA_XFER_SINGLE : DATA_XFER_MULTI);
  291. +
  292. + controller_read_data(xferbuf, data->blksz);
  293. + xferbuf = (void *)((unsigned char *)xferbuf + data->blksz);
  294. +
  295. + semaphore_wait(&transfer_completion_signal, HZ);
  296. }
  297. -
  298. - if(TIME_AFTER(current_tick, timeout))
  299. +
  300. + /* last block */
  301. + mmu_switch_buff();
  302. + controller_read_data(xferbuf, data->blksz);
  303. + }
  304. + else
  305. + {
  306. + controller_write_data(xferbuf, data->blksz);
  307. + mmu_switch_buff();
  308. +
  309. + /* first block */
  310. + SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  311. + DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  312. + ((xfercnt == 1) ? DATA_XFER_SINGLE : DATA_XFER_MULTI);
  313. +
  314. + while(--xfercnt)
  315. {
  316. - return -10 * ((response >> 9) & 0xf);
  317. + xferbuf = (void *)((unsigned char *)xferbuf + data->blksz);
  318. + controller_write_data(xferbuf, data->blksz);
  319. +
  320. + semaphore_wait(&transfer_completion_signal, HZ);
  321. +
  322. + mmu_switch_buff();
  323. +
  324. + SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  325. + DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  326. + ((xfercnt == 1) ? DATA_XFER_SINGLE : DATA_XFER_MULTI);
  327. }
  328.  
  329. - last_disk_activity = current_tick;
  330. + /* wait for last block to finish */
  331. + semaphore_wait(&transfer_completion_signal, HZ);
  332. }
  333. }
  334. -#endif
  335.  
  336. -static bool sd_wait_card_busy(void)
  337. +/* all in one prototype */
  338. +static void sdmmc_command(struct sdmmc_request *req)
  339. {
  340. - unsigned int timeout = current_tick + 5*HZ;
  341. + if (req->cmd != NULL)
  342. + rk27xx_sd_cmd(req->cmd);
  343.  
  344. - while (!(SD_CARD & SD_CARD_BSY))
  345. + if (req->data != NULL)
  346. + rk27xx_sd_data(req->data);
  347. +
  348. + if (req->stop != NULL)
  349. + rk27xx_sd_cmd(req->stop);
  350. +}
  351. +
  352. +static void controller_set_freq(int freq)
  353. +{
  354. + if (freq == SDMMC_FREQ_INIT)
  355. + /* assume 50 MHz APB freq / 125 = 400 kHz */
  356. + SD_CTRL = (SD_CTRL & ~(0x7FF)) | 0x7D;
  357. + else
  358. + /* Card back to full speed 25MHz*/
  359. + SD_CTRL = (SD_CTRL & ~0x7FF);
  360. +}
  361. +
  362. +static void init_controller(void)
  363. +{
  364. + /* reset SD module */
  365. + SCU_RSTCFG |= RSTCFG_SD;
  366. + sleep(1);
  367. + SCU_RSTCFG &= ~RSTCFG_SD;
  368. +
  369. + /* set pins functions as SD signals */
  370. + SCU_IOMUXA_CON |= IOMUX_SD;
  371. +
  372. + /* enable and unmask SD interrupts in interrupt controller */
  373. + SCU_CLKCFG &= ~CLKCFG_SD;
  374. + INTC_IMR |= IRQ_ARM_SD;
  375. + INTC_IECR |= IRQ_ARM_SD;
  376. +
  377. + SD_CTRL = SD_PWR_CPU | SD_DETECT_MECH | SD_CLOCK_EN | 0x7D;
  378. + SD_INT = CMD_RES_INT_EN | DATA_XFER_INT_EN;
  379. + SD_CARD = SD_CARD_SELECT | SD_CARD_PWR_EN;
  380. +
  381. + /* setup mmu buffers */
  382. + MMU_PNRI = 0x1ff;
  383. + MMU_PNRII = 0x1ff;
  384. + MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET |
  385. + MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD;
  386. +
  387. + /* setup A2A DMA CH0 for SD reads */
  388. + A2A_ISRC0 = (unsigned long)(&MMU_DATA);
  389. + A2A_ICNT0 = 512;
  390. + A2A_LCNT0 = 1;
  391. +
  392. + /* setup A2A DMA CH1 for SD writes */
  393. + A2A_IDST1 = (unsigned long)(&MMU_DATA);
  394. + A2A_ICNT1 = 512;
  395. + A2A_LCNT1 = 1;
  396. +
  397. + /* src and dst for CH0 and CH1 is AHB0 */
  398. + A2A_DOMAIN = 0;
  399. +
  400. +#ifdef RK27XX_SD_DEBUG
  401. + /* setup Timer1 for profiling purposes */
  402. + TMR1CON = (1<<8)|(1<<3);
  403. +#endif
  404. +
  405. + semaphore_init(&transfer_completion_signal, 1, 0);
  406. + semaphore_init(&command_completion_signal, 1, 0);
  407. +}
  408. +
  409. +void sd_enable(bool on)
  410. +{
  411. + /* enable or disable clock signal for SD module */
  412. + if (on)
  413. {
  414. - if(TIME_AFTER(current_tick, timeout))
  415. - return false;
  416. + SCU_CLKCFG &= ~CLKCFG_SD;
  417. + led(true);
  418. + }
  419. + else
  420. + {
  421. + SCU_CLKCFG |= CLKCFG_SD;
  422. + led(false);
  423. }
  424. -
  425. - return true;
  426. }
  427.  
  428. +/************ SDMMC core **************/
  429. static int sd_init_card(void)
  430. {
  431. - unsigned long response;
  432. long init_timeout;
  433. bool sd_v2 = false;
  434. + uint32_t buf[16];
  435.  
  436. card_info.rca = 0;
  437.  
  438. - /* assume 50 MHz APB freq / 125 = 400 kHz */
  439. - SD_CTRL = (SD_CTRL & ~(0x7FF)) | 0x7D;
  440. -
  441. /* 100 - 400kHz clock required for Identification Mode */
  442. + controller_set_freq(SDMMC_FREQ_INIT);
  443. +
  444. /* Start of Card Identification Mode ************************************/
  445. + SDMMC_CMD_PREPARE(SD_GO_IDLE_STATE, 0, SDMMC_RSP_NONE);
  446. + SDMMC_REQ_PREPARE(&cmd, NULL, NULL);
  447.  
  448. /* CMD0 Go Idle */
  449. - if(!send_cmd(SD_GO_IDLE_STATE, 0, RES_NO, NULL))
  450. + sdmmc_command(&req);
  451. +
  452. + if (req.cmd->error)
  453. return -1;
  454.  
  455. sleep(1);
  456.  
  457. + SDMMC_CMD_PREPARE(SD_SEND_IF_COND, 0x1aa, SDMMC_RSP_R6);
  458. /* CMD8 Check for v2 sd card. Must be sent before using ACMD41
  459. Non v2 cards will not respond to this command*/
  460. - if(send_cmd(SD_SEND_IF_COND, 0x1AA, RES_R6, &response))
  461. - if((response & 0xFFF) == 0x1AA)
  462. - sd_v2 = true;
  463. + sdmmc_command(&req);
  464.  
  465. + if (!req.cmd->error)
  466. + if ((req.cmd->rsp[0] & 0xFFF) == 0x1AA)
  467. + sd_v2 = true;
  468. +
  469. /* Timeout for inintialization is 2 sec.
  470. According to SD Specification 2.00 it should be >= 1,
  471. but it's not enough in some rare cases. */
  472. @@ -268,47 +492,72 @@ static int sd_init_card(void)
  473. if(TIME_AFTER(current_tick, init_timeout))
  474. return -2;
  475.  
  476. - if(!send_cmd(SD_APP_CMD, card_info.rca, RES_R1, &response))
  477. + SDMMC_CMD_PREPARE(SD_APP_CMD, card_info.rca, SDMMC_RSP_R1);
  478. + sdmmc_command(&req);
  479. +
  480. + if (req.cmd->error)
  481. return -3;
  482.  
  483. sleep(1); /* bus conflict otherwise */
  484.  
  485. - /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
  486. - if(!send_cmd(SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)),
  487. - RES_R3, &card_info.ocr))
  488. + /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
  489. + SDMMC_CMD_PREPARE(SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), SDMMC_RSP_R3);
  490. + sdmmc_command(&req);
  491. + if (req.cmd->error)
  492. return -4;
  493. +
  494. + card_info.ocr = req.cmd->rsp[0];
  495. } while(!(card_info.ocr & (1<<31)) );
  496.  
  497. /* CMD2 send CID */
  498. - if(!send_cmd(SD_ALL_SEND_CID, 0, RES_R2, card_info.cid))
  499. + SDMMC_CMD_PREPARE(SD_ALL_SEND_CID, 0, SDMMC_RSP_R2);
  500. + sdmmc_command(&req);
  501. +
  502. + if (req.cmd->error)
  503. return -5;
  504.  
  505. + memcpy(card_info.cid, req.cmd->rsp, sizeof(card_info.cid));
  506. +
  507. /* CMD3 send RCA */
  508. - if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, RES_R6, &card_info.rca))
  509. + SDMMC_CMD_PREPARE(SD_SEND_RELATIVE_ADDR, 0, SDMMC_RSP_R6);
  510. + sdmmc_command(&req);
  511. +
  512. + if (req.cmd->error)
  513. return -6;
  514.  
  515. + card_info.rca = req.cmd->rsp[0];
  516. /* End of Card Identification Mode ************************************/
  517.  
  518. -
  519. /* CMD9 send CSD */
  520. - if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd))
  521. + SDMMC_CMD_PREPARE(SD_SEND_CSD, card_info.rca, SDMMC_RSP_R2);
  522. + sdmmc_command(&req);
  523. +
  524. + if (req.cmd->error)
  525. return -11;
  526.  
  527. + memcpy(card_info.csd, req.cmd->rsp, sizeof(card_info.csd));
  528. +
  529. sd_parse_csd(&card_info);
  530.  
  531. - if(!send_cmd(SD_SELECT_CARD, card_info.rca, RES_R1b, &response))
  532. - return -20;
  533. + SDMMC_CMD_PREPARE(SD_SELECT_CARD, card_info.rca, SDMMC_RSP_R1B);
  534. + sdmmc_command(&req);
  535.  
  536. - if (!sd_wait_card_busy())
  537. - return -21;
  538. + if (req.cmd->error)
  539. + return -20;
  540.  
  541. /* CMD6 */
  542. - if(!send_cmd(SD_SWITCH_FUNC, 0x80fffff1, RES_R1, &response))
  543. + SDMMC_CMD_PREPARE(SD_SWITCH_FUNC, 0x80fffff1, SDMMC_RSP_R1);
  544. + SDMMC_DAT_PREPARE(buf, 64, 1, SDMMC_DIR_READ);
  545. + SDMMC_REQ_PREPARE(&cmd, &dat, NULL);
  546. + sdmmc_command(&req);
  547. +
  548. + if (req.cmd->error)
  549. return -8;
  550. - sleep(HZ/10);
  551.  
  552. - /* Card back to full speed 25MHz*/
  553. - SD_CTRL = (SD_CTRL & ~0x7FF);
  554. + //sleep(HZ/10);
  555. +
  556. + controller_set_freq(SDMMC_FREQ_NORMAL);
  557. +
  558. card_info.initialized = 1;
  559.  
  560. return 0;
  561. @@ -394,57 +643,10 @@ static void sd_thread(void)
  562. }
  563. }
  564.  
  565. -static void init_controller(void)
  566. -{
  567. - /* reset SD module */
  568. - SCU_RSTCFG |= RSTCFG_SD;
  569. - sleep(1);
  570. - SCU_RSTCFG &= ~RSTCFG_SD;
  571. -
  572. - /* set pins functions as SD signals */
  573. - SCU_IOMUXA_CON |= IOMUX_SD;
  574. -
  575. - /* enable and unmask SD interrupts in interrupt controller */
  576. - SCU_CLKCFG &= ~CLKCFG_SD;
  577. - INTC_IMR |= IRQ_ARM_SD;
  578. - INTC_IECR |= IRQ_ARM_SD;
  579. -
  580. - SD_CTRL = SD_PWR_CPU | SD_DETECT_MECH | SD_CLOCK_EN | 0x7D;
  581. - SD_INT = CMD_RES_INT_EN | DATA_XFER_INT_EN;
  582. - SD_CARD = SD_CARD_SELECT | SD_CARD_PWR_EN;
  583. -
  584. - /* setup mmu buffers */
  585. - MMU_PNRI = 0x1ff;
  586. - MMU_PNRII = 0x1ff;
  587. - MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET |
  588. - MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD;
  589. -
  590. - /* setup A2A DMA CH0 for SD reads */
  591. - A2A_ISRC0 = (unsigned long)(&MMU_DATA);
  592. - A2A_ICNT0 = 512;
  593. - A2A_LCNT0 = 1;
  594. -
  595. - /* setup A2A DMA CH1 for SD writes */
  596. - A2A_IDST1 = (unsigned long)(&MMU_DATA);
  597. - A2A_ICNT1 = 512;
  598. - A2A_LCNT1 = 1;
  599. -
  600. - /* src and dst for CH0 and CH1 is AHB0 */
  601. - A2A_DOMAIN = 0;
  602. -
  603. -#ifdef RK27XX_SD_DEBUG
  604. - /* setup Timer1 for profiling purposes */
  605. - TMR1CON = (1<<8)|(1<<3);
  606. -#endif
  607. -}
  608. -
  609. int sd_init(void)
  610. {
  611. int ret;
  612.  
  613. - semaphore_init(&transfer_completion_signal, 1, 0);
  614. - semaphore_init(&command_completion_signal, 1, 0);
  615. -
  616. init_controller();
  617.  
  618. ret = sd_init_card();
  619. @@ -461,39 +663,7 @@ int sd_init(void)
  620. return 0;
  621. }
  622.  
  623. -static inline void read_sd_data(unsigned char **dst)
  624. -{
  625. - commit_discard_dcache_range((const void *)*dst, 512);
  626. -
  627. - A2A_IDST0 = (unsigned long)*dst;
  628. - A2A_CON0 = (3<<9) | /* burst 16 */
  629. - (1<<6) | /* fixed src */
  630. - (1<<3) | /* DMA start */
  631. - (2<<1) | /* word transfer size */
  632. - (1<<0); /* software mode */
  633.  
  634. - /* wait for DMA engine to finish transfer */
  635. - while (A2A_DMA_STS & 1);
  636. -
  637. - *dst += 512;
  638. -}
  639. -
  640. -static inline void write_sd_data(unsigned char **src)
  641. -{
  642. - commit_discard_dcache_range((const void *)*src, 512);
  643. -
  644. - A2A_ISRC1 = (unsigned long)*src;
  645. - A2A_CON1 = (3<<9) | /* burst 16 */
  646. - (1<<5) | /* fixed dst */
  647. - (1<<3) | /* DMA start */
  648. - (2<<1) | /* word transfer size */
  649. - (1<<0); /* software mode */
  650. -
  651. - /* wait for DMA engine to finish transfer */
  652. - while (A2A_DMA_STS & 2);
  653. -
  654. - *src += 512;
  655. -}
  656.  
  657. int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
  658. void* buf)
  659. @@ -501,11 +671,6 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
  660. #ifdef HAVE_MULTIDRIVE
  661. (void)drive;
  662. #endif
  663. - unsigned long response;
  664. - unsigned int retry_cnt = 0;
  665. - int cnt, ret = 0;
  666. - unsigned char *dst;
  667. -
  668. mutex_lock(&sd_mtx);
  669. sd_enable(true);
  670.  
  671. @@ -515,106 +680,17 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
  672. if(!(card_info.ocr & (1<<30)))
  673. start <<= 9; /* not SDHC */
  674.  
  675. - while (retry_cnt++ < 20)
  676. - {
  677. - cnt = count;
  678. - dst = (unsigned char *)buf;
  679. + SDMMC_CMD_PREPARE(SD_READ_MULTIPLE_BLOCK, start, SDMMC_RSP_R1);
  680. + SDMMC_STP_PREPARE(SD_STOP_TRANSMISSION, 0, SDMMC_RSP_R1B);
  681. + SDMMC_DAT_PREPARE(buf, 512, (count + 0x1ff) >> 9, SDMMC_DIR_READ);
  682. + SDMMC_REQ_PREPARE(&cmd, &dat, &stp);
  683.  
  684. - ret = 0;
  685. - retry = false; /* reset retry flag */
  686. -
  687. - mmu_buff_reset();
  688. -
  689. - if (cnt == 1)
  690. - {
  691. - /* last block to transfer */
  692. - SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  693. - DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  694. - DATA_XFER_SINGLE;
  695. - }
  696. - else
  697. - {
  698. - /* more than one block to transfer */
  699. - SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  700. - DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  701. - DATA_XFER_MULTI;
  702. - }
  703. -
  704. - /* issue read command to the card */
  705. - if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response))
  706. - {
  707. - ret = -2;
  708. - continue;
  709. - }
  710. -
  711. - while (cnt > 0)
  712. - {
  713. -#ifdef RK27XX_SD_DEBUG
  714. - /* debug stuff */
  715. - TMR1LR = 0xffffffff;
  716. -#endif
  717. - /* wait for transfer completion */
  718. - semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
  719. -
  720. -#ifdef RK27XX_SD_DEBUG
  721. - /* debug stuff */
  722. - sd_debug_time_rd = 0xffffffff - TMR1CVR;
  723. -#endif
  724. - if (retry)
  725. - {
  726. - /* data transfer error */
  727. - ret = -3;
  728. - break;
  729. - }
  730. -
  731. - /* exchange buffers */
  732. - mmu_switch_buff();
  733. -
  734. - cnt--;
  735. -
  736. - if (cnt == 0)
  737. - {
  738. - if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response))
  739. - ret = -4;
  740. -
  741. - read_sd_data(&dst);
  742. -
  743. - break;
  744. - }
  745. - else if (cnt == 1)
  746. - {
  747. - /* last block to transfer */
  748. - SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  749. - DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  750. - DATA_XFER_SINGLE;
  751. -
  752. - read_sd_data(&dst);
  753. -
  754. - }
  755. - else
  756. - {
  757. - /* more than one block to transfer */
  758. - SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
  759. - DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  760. - DATA_XFER_MULTI;
  761. -
  762. - read_sd_data(&dst);
  763. - }
  764. -
  765. - last_disk_activity = current_tick;
  766. -
  767. - } /* while (cnt > 0) */
  768. -
  769. - /* transfer successfull - leave retry loop */
  770. - if (ret == 0)
  771. - break;
  772. -
  773. - } /* while (retry_cnt++ < 20) */
  774. + sdmmc_command(&req);
  775.  
  776. sd_enable(false);
  777. mutex_unlock(&sd_mtx);
  778.  
  779. - return ret;
  780. + return (req.cmd->error || req.stop->error) ? -1 : 0;
  781. }
  782.  
  783. /* Not tested */
  784. @@ -631,118 +707,30 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
  785. return -1;
  786. #else
  787.  
  788. -#ifdef RK27XX_SD_DEBUG
  789. - /* debug stuff */
  790. - TMR1LR = 0xffffffff;
  791. -#endif
  792. -
  793. - unsigned long response;
  794. - unsigned int retry_cnt = 0;
  795. - int cnt, ret = 0;
  796. - unsigned char *src;
  797. - /* bool card_selected = false; */
  798. -
  799. - mutex_lock(&sd_mtx);
  800. - sd_enable(true);
  801. -
  802. if (count <= 0 || start + count > card_info.numblocks)
  803. return -1;
  804.  
  805. if(!(card_info.ocr & (1<<30)))
  806. start <<= 9; /* not SDHC */
  807.  
  808. - while (retry_cnt++ < 20)
  809. - {
  810. - cnt = count;
  811. - src = (unsigned char *)buf;
  812. -
  813. - ret = 0;
  814. - retry = false; /* reset retry flag */
  815. - mmu_buff_reset(); /* reset recive buff state */
  816. -
  817. - write_sd_data(&src); /* put data into transfer buffer */
  818. -
  819. - if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
  820. - {
  821. - ret = -3;
  822. - continue;
  823. - }
  824. -
  825. - while (cnt > 0)
  826. - {
  827. - /* exchange buffers */
  828. - mmu_switch_buff();
  829. -
  830. - if (cnt == 1)
  831. - {
  832. - /* last block to transfer */
  833. - SD_DATAT = DATA_XFER_START | DATA_XFER_WRITE |
  834. - DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  835. - DATA_XFER_SINGLE;
  836. -
  837. - }
  838. - else
  839. - {
  840. - /* more than one block to transfer */
  841. - SD_DATAT = DATA_XFER_START | DATA_XFER_WRITE |
  842. - DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
  843. - DATA_XFER_MULTI;
  844. -
  845. - /* put more data */
  846. - write_sd_data(&src);
  847. - }
  848. - /* wait for transfer completion */
  849. - semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
  850. -
  851. - if (retry)
  852. - {
  853. - /* data transfer error */
  854. - ret = -3;
  855. - break;
  856. - }
  857. -
  858. - cnt--;
  859. - } /* while (cnt > 0) */
  860. -
  861. - if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response))
  862. - ret = -4;
  863. + mutex_lock(&sd_mtx);
  864. + sd_enable(true);
  865.  
  866. - if (!sd_wait_card_busy())
  867. - ret = -5;
  868. + SDMMC_CMD_PREPARE(SD_WRITE_MULTIPLE_BLOCK, start, SDMMC_RSP_R1);
  869. + SDMMC_STP_PREPARE(SD_STOP_TRANSMISSION, 0, SDMMC_RSP_R1B);
  870. + SDMMC_DAT_PREPARE(buf, 512, (count + 0x1ff) >> 9, SDMMC_DIR_READ);
  871. + SDMMC_REQ_PREPARE(&cmd, &dat, &stp);
  872.  
  873. - /* transfer successfull - leave retry loop */
  874. - if (ret == 0)
  875. - break;
  876. - }
  877. + sdmmc_command(&req);
  878.  
  879. sd_enable(false);
  880. mutex_unlock(&sd_mtx);
  881.  
  882. -#ifdef RK27XX_SD_DEBUG
  883. - /* debug stuff */
  884. - sd_debug_time_wr = 0xffffffff - TMR1CVR;
  885. -#endif
  886. -
  887. - return ret;
  888. + return (req.cmd->error || req.stop->error) ? -1 : 0;;
  889.  
  890. #endif /* defined(BOOTLOADER) */
  891. }
  892.  
  893. -void sd_enable(bool on)
  894. -{
  895. - /* enable or disable clock signal for SD module */
  896. - if (on)
  897. - {
  898. - SCU_CLKCFG &= ~CLKCFG_SD;
  899. - led(true);
  900. - }
  901. - else
  902. - {
  903. - SCU_CLKCFG |= CLKCFG_SD;
  904. - led(false);
  905. - }
  906. -}
  907. -
  908. #ifndef BOOTLOADER
  909. long sd_last_disk_activity(void)
  910. {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement