emmc_csl_sdcmd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. /*
  2. * Copyright (c) 2016 - 2020, Broadcom
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <stdlib.h>
  7. #include <stddef.h>
  8. #include "bcm_emmc.h"
  9. #include "emmc_chal_types.h"
  10. #include "emmc_chal_sd.h"
  11. #include "emmc_csl_sdprot.h"
  12. #include "emmc_csl_sdcmd.h"
  13. #include "emmc_csl_sd.h"
  14. #include "emmc_chal_sd.h"
  15. #include "emmc_pboot_hal_memory_drv.h"
  16. int sd_cmd0(struct sd_handle *handle)
  17. {
  18. int res;
  19. uint32_t argument = 0x0; /* Go to IDLE state. */
  20. /* send cmd and parse result */
  21. res = send_cmd(handle, SD_CMD_GO_IDLE_STATE, argument, 0, NULL);
  22. if (res == SD_OK) {
  23. /* Clear all other interrupts */
  24. chal_sd_clear_irq((void *)handle->device, 0xffffffff);
  25. }
  26. return res;
  27. }
  28. int sd_cmd1(struct sd_handle *handle, uint32_t ocr, uint32_t *ocr_output)
  29. {
  30. int res;
  31. uint32_t options;
  32. struct sd_resp resp;
  33. options = SD_CMDR_RSP_TYPE_R3_4 << SD_CMDR_RSP_TYPE_S;
  34. if (ocr_output == NULL) {
  35. EMMC_TRACE("Invalid args\n");
  36. return SD_FAIL;
  37. }
  38. /* send cmd and parse result */
  39. res = send_cmd(handle, SD_CMD_SEND_OPCOND, ocr, options, &resp);
  40. if (res == SD_OK)
  41. *ocr_output = resp.data.r3.ocr;
  42. return res;
  43. }
  44. int sd_cmd2(struct sd_handle *handle)
  45. {
  46. uint32_t options;
  47. struct sd_resp resp;
  48. /* send cmd and parse result */
  49. options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S;
  50. return send_cmd(handle, SD_CMD_ALL_SEND_CID, 0, options, &resp);
  51. }
  52. int sd_cmd3(struct sd_handle *handle)
  53. {
  54. int res;
  55. uint32_t options = 0;
  56. uint32_t argument;
  57. struct sd_resp resp;
  58. /* use non zero and non 0x1 value for rca */
  59. handle->device->ctrl.rca = 0x5;
  60. argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
  61. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  62. SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
  63. SD4_EMMC_TOP_CMD_CRC_EN_MASK;
  64. /* send cmd and parse result */
  65. res = send_cmd(handle, SD_CMD_MMC_SET_RCA, argument, options, &resp);
  66. if (res != SD_OK)
  67. handle->device->ctrl.rca = 0;
  68. return res;
  69. }
  70. int sd_cmd7(struct sd_handle *handle, uint32_t rca)
  71. {
  72. int res;
  73. uint32_t argument, options;
  74. struct sd_resp resp;
  75. argument = (rca << SD_CMD7_ARG_RCA_SHIFT);
  76. /*
  77. * Response to CMD7 is:
  78. * R1 while selectiing from Stand-By State to Transfer State
  79. * R1b while selecting from Disconnected State to Programming State.
  80. *
  81. * In this driver, we only issue a CMD7 once, to go to transfer mode
  82. * during init_mmc_card().
  83. */
  84. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  85. SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
  86. SD4_EMMC_TOP_CMD_CRC_EN_MASK;
  87. /* send cmd and parse result */
  88. res = send_cmd(handle, SD_CMD_SELECT_DESELECT_CARD, argument, options,
  89. &resp);
  90. if (res == SD_OK)
  91. /* Clear all other interrupts */
  92. chal_sd_clear_irq((void *)handle->device, 0xffffffff);
  93. return res;
  94. }
  95. /*
  96. * CMD8 Get CSD_EXT
  97. */
  98. int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg)
  99. {
  100. uint32_t res, options;
  101. struct sd_resp resp;
  102. data_xfer_setup(handle, extCsdReg, CEATA_EXT_CSDBLOCK_SIZE,
  103. SD_XFER_CARD_TO_HOST);
  104. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  105. SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
  106. SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK;
  107. /* send cmd and parse result */
  108. res = send_cmd(handle, SD_CMD_READ_EXT_CSD, 0, options, &resp);
  109. if (res == SD_OK)
  110. res = process_data_xfer(handle, extCsdReg, 0,
  111. CEATA_EXT_CSDBLOCK_SIZE,
  112. SD_XFER_CARD_TO_HOST);
  113. return res;
  114. }
  115. int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card)
  116. {
  117. int res;
  118. uint32_t argument, options, iBlkNum, multiFactor = 1;
  119. uint32_t maxReadBlockLen = 1, maxWriteBlockLen = 1;
  120. struct sd_resp resp;
  121. argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
  122. options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S |
  123. SD4_EMMC_TOP_CMD_CRC_EN_MASK;
  124. /* send cmd and parse result */
  125. res = send_cmd(handle, SD_CMD_SEND_CSD, argument, options, &resp);
  126. if (res != SD_OK)
  127. return res;
  128. if (handle->card->type == SD_CARD_MMC) {
  129. card->csd.mmc.structure = (resp.data.r2.rsp4 >> 22) & 0x3;
  130. card->csd.mmc.csdSpecVer = (resp.data.r2.rsp4 >> 18) & 0x0f;
  131. card->csd.mmc.taac = (resp.data.r2.rsp4 >> 8) & 0xff;
  132. card->csd.mmc.nsac = resp.data.r2.rsp4 & 0xff;
  133. card->csd.mmc.speed = resp.data.r2.rsp3 >> 24;
  134. card->csd.mmc.classes = (resp.data.r2.rsp3 >> 12) & 0xfff;
  135. card->csd.mmc.rdBlkLen = (resp.data.r2.rsp3 >> 8) & 0xf;
  136. card->csd.mmc.rdBlkPartial = (resp.data.r2.rsp3 >> 7) & 0x01;
  137. card->csd.mmc.wrBlkMisalign = (resp.data.r2.rsp3 >> 6) & 0x1;
  138. card->csd.mmc.rdBlkMisalign = (resp.data.r2.rsp3 >> 5) & 0x1;
  139. card->csd.mmc.dsr = (resp.data.r2.rsp2 >> 4) & 0x01;
  140. card->csd.mmc.size =
  141. ((resp.data.r2.rsp3 & 0x3) << 10) +
  142. ((resp.data.r2.rsp2 >> 22) & 0x3ff);
  143. card->csd.mmc.vddRdCurrMin = (resp.data.r2.rsp2 >> 19) & 0x7;
  144. card->csd.mmc.vddRdCurrMax = (resp.data.r2.rsp2 >> 16) & 0x7;
  145. card->csd.mmc.vddWrCurrMin = (resp.data.r2.rsp2 >> 13) & 0x7;
  146. card->csd.mmc.vddWrCurrMax = (resp.data.r2.rsp2 >> 10) & 0x7;
  147. card->csd.mmc.devSizeMulti = (resp.data.r2.rsp2 >> 7) & 0x7;
  148. card->csd.mmc.eraseGrpSize = (resp.data.r2.rsp2 >> 2) & 0x1f;
  149. card->csd.mmc.eraseGrpSizeMulti =
  150. ((resp.data.r2.rsp2 & 0x3) << 3) +
  151. ((resp.data.r2.rsp1 >> 29) & 0x7);
  152. card->csd.mmc.wrProtGroupSize =
  153. ((resp.data.r2.rsp1 >> 24) & 0x1f);
  154. card->csd.mmc.wrProtGroupEnable =
  155. (resp.data.r2.rsp1 >> 23) & 0x1;
  156. card->csd.mmc.manuDefEcc = (resp.data.r2.rsp1 >> 21) & 0x3;
  157. card->csd.mmc.wrSpeedFactor = (resp.data.r2.rsp1 >> 18) & 0x7;
  158. card->csd.mmc.wrBlkLen = (resp.data.r2.rsp1 >> 14) & 0xf;
  159. card->csd.mmc.wrBlkPartial = (resp.data.r2.rsp1 >> 13) & 0x1;
  160. card->csd.mmc.protAppl = (resp.data.r2.rsp1 >> 8) & 0x1;
  161. card->csd.mmc.copyFlag = (resp.data.r2.rsp1 >> 7) & 0x1;
  162. card->csd.mmc.permWrProt = (resp.data.r2.rsp1 >> 6) & 0x1;
  163. card->csd.mmc.tmpWrProt = (resp.data.r2.rsp1 >> 5) & 0x1;
  164. card->csd.mmc.fileFormat = (resp.data.r2.rsp1 >> 4) & 0x03;
  165. card->csd.mmc.eccCode = resp.data.r2.rsp1 & 0x03;
  166. maxReadBlockLen <<= card->csd.mmc.rdBlkLen;
  167. maxWriteBlockLen <<= card->csd.mmc.wrBlkLen;
  168. iBlkNum = card->csd.mmc.size + 1;
  169. multiFactor = (1 << (card->csd.mmc.devSizeMulti + 2));
  170. handle->card->size =
  171. iBlkNum * multiFactor * (1 << card->csd.mmc.rdBlkLen);
  172. }
  173. handle->card->maxRdBlkLen = maxReadBlockLen;
  174. handle->card->maxWtBlkLen = maxWriteBlockLen;
  175. if (handle->card->size < 0xA00000) {
  176. /*
  177. * 10MB Too small size mean, cmd9 response is wrong,
  178. * Use default value 1G
  179. */
  180. handle->card->size = 0x40000000;
  181. handle->card->maxRdBlkLen = 512;
  182. handle->card->maxWtBlkLen = 512;
  183. }
  184. if ((handle->card->maxRdBlkLen > 512) ||
  185. (handle->card->maxWtBlkLen > 512)) {
  186. handle->card->maxRdBlkLen = 512;
  187. handle->card->maxWtBlkLen = 512;
  188. } else if ((handle->card->maxRdBlkLen == 0) ||
  189. (handle->card->maxWtBlkLen == 0)) {
  190. handle->card->maxRdBlkLen = 512;
  191. handle->card->maxWtBlkLen = 512;
  192. }
  193. handle->device->cfg.blockSize = handle->card->maxRdBlkLen;
  194. return res;
  195. }
  196. int sd_cmd13(struct sd_handle *handle, uint32_t *status)
  197. {
  198. int res;
  199. uint32_t argument, options;
  200. struct sd_resp resp;
  201. argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
  202. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  203. SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
  204. SD4_EMMC_TOP_CMD_CRC_EN_MASK;
  205. /* send cmd and parse result */
  206. res = send_cmd(handle, SD_CMD_SEND_STATUS, argument, options, &resp);
  207. if (res == SD_OK) {
  208. *status = resp.cardStatus;
  209. }
  210. return res;
  211. }
  212. int sd_cmd16(struct sd_handle *handle, uint32_t length)
  213. {
  214. int res;
  215. uint32_t argument, options, ntry;
  216. struct sd_resp resp;
  217. argument = length;
  218. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  219. SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  220. SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
  221. ntry = 0;
  222. do {
  223. res = sd_cmd13(handle, &resp.cardStatus);
  224. if (res != SD_OK) {
  225. EMMC_TRACE(
  226. "cmd13 failed before cmd16: rca 0x%0x, return %d, response 0x%0x\n",
  227. handle->device->ctrl.rca, res, resp.cardStatus);
  228. return res;
  229. }
  230. if (resp.cardStatus & 0x100)
  231. break;
  232. EMMC_TRACE("cmd13 rsp:0x%08x before cmd16\n", resp.cardStatus);
  233. if (ntry > handle->device->cfg.retryLimit) {
  234. EMMC_TRACE("cmd13 retry reach limit %d\n",
  235. handle->device->cfg.retryLimit);
  236. return SD_CMD_TIMEOUT;
  237. }
  238. ntry++;
  239. EMMC_TRACE("cmd13 retry %d\n", ntry);
  240. SD_US_DELAY(1000);
  241. } while (1);
  242. /* send cmd and parse result */
  243. res = send_cmd(handle, SD_CMD_SET_BLOCKLEN, argument, options, &resp);
  244. return res;
  245. }
  246. int sd_cmd17(struct sd_handle *handle,
  247. uint32_t addr, uint32_t len, uint8_t *buffer)
  248. {
  249. int res;
  250. uint32_t argument, options, ntry;
  251. struct sd_resp resp;
  252. ntry = 0;
  253. do {
  254. res = sd_cmd13(handle, &resp.cardStatus);
  255. if (res != SD_OK) {
  256. EMMC_TRACE(
  257. "cmd 13 failed before cmd17: rca 0x%0x, return %d, response 0x%0x\n",
  258. handle->device->ctrl.rca, res, resp.cardStatus);
  259. return res;
  260. }
  261. if (resp.cardStatus & 0x100)
  262. break;
  263. EMMC_TRACE("cmd13 rsp:0x%08x before cmd17\n", resp.cardStatus);
  264. if (ntry > handle->device->cfg.retryLimit) {
  265. EMMC_TRACE("cmd13 retry reach limit %d\n",
  266. handle->device->cfg.retryLimit);
  267. return SD_CMD_TIMEOUT;
  268. }
  269. ntry++;
  270. EMMC_TRACE("cmd13 retry %d\n", ntry);
  271. SD_US_DELAY(1000);
  272. } while (1);
  273. data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST);
  274. /* send cmd and parse result */
  275. argument = addr;
  276. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  277. SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
  278. SD4_EMMC_TOP_CMD_CRC_EN_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
  279. res = send_cmd(handle, SD_CMD_READ_SINGLE_BLOCK, argument, options,
  280. &resp);
  281. if (res != SD_OK)
  282. return res;
  283. res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST);
  284. return res;
  285. }
  286. int sd_cmd18(struct sd_handle *handle,
  287. uint32_t addr, uint32_t len, uint8_t *buffer)
  288. {
  289. int res;
  290. uint32_t argument, options, ntry;
  291. struct sd_resp resp;
  292. ntry = 0;
  293. do {
  294. res = sd_cmd13(handle, &resp.cardStatus);
  295. if (res != SD_OK) {
  296. EMMC_TRACE(
  297. "cmd 13 failed before cmd18: rca 0x%0x, return %d, response 0x%0x\n",
  298. handle->device->ctrl.rca, res, resp.cardStatus);
  299. return res;
  300. }
  301. if (resp.cardStatus & 0x100)
  302. break;
  303. EMMC_TRACE("cmd13 rsp:0x%08x before cmd18\n", resp.cardStatus);
  304. if (ntry > handle->device->cfg.retryLimit) {
  305. EMMC_TRACE("cmd13 retry reach limit %d\n",
  306. handle->device->cfg.retryLimit);
  307. return SD_CMD_TIMEOUT;
  308. }
  309. ntry++;
  310. EMMC_TRACE("cmd13 retry %d\n", ntry);
  311. SD_US_DELAY(1000);
  312. } while (1);
  313. data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST);
  314. argument = addr;
  315. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  316. SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
  317. SD4_EMMC_TOP_CMD_MSBS_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
  318. SD4_EMMC_TOP_CMD_BCEN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  319. BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT);
  320. /* send cmd and parse result */
  321. res = send_cmd(handle, SD_CMD_READ_MULTIPLE_BLOCK, argument, options,
  322. &resp);
  323. if (res != SD_OK)
  324. return res;
  325. res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST);
  326. return res;
  327. }
  328. #ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
  329. static int card_sts_resp(struct sd_handle *handle, uint32_t *status)
  330. {
  331. int res;
  332. uint32_t ntry = 0;
  333. do {
  334. res = sd_cmd13(handle, status);
  335. if (res != SD_OK) {
  336. EMMC_TRACE(
  337. "cmd 13 failed before cmd35: rca 0x%0x, return %d\n",
  338. handle->device->ctrl.rca, res);
  339. return res;
  340. }
  341. if (*status & 0x100)
  342. break;
  343. EMMC_TRACE("cmd13 rsp:0x%08x before cmd35\n", resp.cardStatus);
  344. if (ntry > handle->device->cfg.retryLimit) {
  345. EMMC_TRACE("cmd13 retry reach limit %d\n",
  346. handle->device->cfg.retryLimit);
  347. return SD_CMD_TIMEOUT;
  348. }
  349. ntry++;
  350. EMMC_TRACE("cmd13 retry %d\n", ntry);
  351. SD_US_DELAY(1000);
  352. } while (1);
  353. return SD_OK;
  354. }
  355. int sd_cmd35(struct sd_handle *handle, uint32_t start)
  356. {
  357. int res;
  358. uint32_t argument, options;
  359. struct sd_resp resp;
  360. res = card_sts_resp(handle, &resp.cardStatus);
  361. if (res != SD_OK)
  362. return res;
  363. argument = start;
  364. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  365. SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  366. SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
  367. /* send cmd and parse result */
  368. res = send_cmd(handle, SD_CMD_ERASE_GROUP_START,
  369. argument, options, &resp);
  370. if (res != SD_OK)
  371. return res;
  372. return res;
  373. }
  374. int sd_cmd36(struct sd_handle *handle, uint32_t end)
  375. {
  376. int res;
  377. uint32_t argument, options;
  378. struct sd_resp resp;
  379. res = card_sts_resp(handle, &resp.cardStatus);
  380. if (res != SD_OK)
  381. return res;
  382. argument = end;
  383. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  384. SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  385. SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
  386. /* send cmd and parse result */
  387. res = send_cmd(handle, SD_CMD_ERASE_GROUP_END,
  388. argument, options, &resp);
  389. if (res != SD_OK)
  390. return res;
  391. return res;
  392. }
  393. int sd_cmd38(struct sd_handle *handle)
  394. {
  395. int res;
  396. uint32_t argument, options;
  397. struct sd_resp resp;
  398. res = card_sts_resp(handle, &resp.cardStatus);
  399. if (res != SD_OK)
  400. return res;
  401. argument = 0;
  402. options = (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) |
  403. SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  404. SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
  405. /* send cmd and parse result */
  406. res = send_cmd(handle, SD_CMD_ERASE, argument, options, &resp);
  407. if (res != SD_OK)
  408. return res;
  409. return res;
  410. }
  411. #endif
  412. #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
  413. int sd_cmd24(struct sd_handle *handle,
  414. uint32_t addr, uint32_t len, uint8_t *buffer)
  415. {
  416. int res;
  417. uint32_t argument, options, ntry;
  418. struct sd_resp resp;
  419. ntry = 0;
  420. do {
  421. res = sd_cmd13(handle, &resp.cardStatus);
  422. if (res != SD_OK) {
  423. EMMC_TRACE(
  424. "cmd 13 failed before cmd24: rca 0x%0x, return %d, response 0x%0x\n",
  425. handle->device->ctrl.rca, res, &resp.cardStatus);
  426. return res;
  427. }
  428. if (resp.cardStatus & 0x100)
  429. break;
  430. EMMC_TRACE("cmd13 rsp:0x%08x before cmd24\n", resp.cardStatus);
  431. if (ntry > handle->device->cfg.retryLimit) {
  432. EMMC_TRACE("cmd13 retry reach limit %d\n",
  433. handle->device->cfg.retryLimit);
  434. return SD_CMD_TIMEOUT;
  435. }
  436. ntry++;
  437. EMMC_TRACE("cmd13 retry %d\n", ntry);
  438. SD_US_DELAY(1000);
  439. } while (1);
  440. data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD);
  441. argument = addr;
  442. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  443. SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  444. SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
  445. /* send cmd and parse result */
  446. res = send_cmd(handle, SD_CMD_WRITE_BLOCK, argument, options, &resp);
  447. if (res != SD_OK)
  448. return res;
  449. res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD);
  450. return res;
  451. }
  452. int sd_cmd25(struct sd_handle *handle,
  453. uint32_t addr, uint32_t len, uint8_t *buffer)
  454. {
  455. int res = SD_OK;
  456. uint32_t argument, options, ntry;
  457. struct sd_resp resp;
  458. ntry = 0;
  459. do {
  460. res = sd_cmd13(handle, &resp.cardStatus);
  461. if (res != SD_OK) {
  462. EMMC_TRACE(
  463. "cmd 13 failed before cmd25: rca 0x%0x, return %d, response 0x%0x\n",
  464. handle->device->ctrl.rca, res, &resp.cardStatus);
  465. return res;
  466. }
  467. if (resp.cardStatus & 0x100)
  468. break;
  469. EMMC_TRACE("cmd13 rsp:0x%08x before cmd25\n", resp.cardStatus);
  470. if (ntry > handle->device->cfg.retryLimit) {
  471. EMMC_TRACE("cmd13 retry reach limit %d\n",
  472. handle->device->cfg.retryLimit);
  473. return SD_CMD_TIMEOUT;
  474. }
  475. ntry++;
  476. EMMC_TRACE("cmd13 retry %d\n", ntry);
  477. SD_US_DELAY(1000);
  478. } while (1);
  479. data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD);
  480. argument = addr;
  481. options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
  482. SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_MSBS_MASK |
  483. SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_BCEN_MASK |
  484. SD4_EMMC_TOP_CMD_CRC_EN_MASK |
  485. BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT);
  486. /* send cmd and parse result */
  487. res = send_cmd(handle, SD_CMD_WRITE_MULTIPLE_BLOCK,
  488. argument, options, &resp);
  489. if (res != SD_OK)
  490. return res;
  491. res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD);
  492. return res;
  493. }
  494. #endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */
  495. int mmc_cmd6(struct sd_handle *handle, uint32_t argument)
  496. {
  497. int res;
  498. uint32_t options;
  499. struct sd_resp resp;
  500. options = SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S |
  501. SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK;
  502. EMMC_TRACE("Sending CMD6 with argument 0x%X\n", argument);
  503. /* send cmd and parse result */
  504. res = send_cmd(handle, SD_ACMD_SET_BUS_WIDTH, argument, options, &resp);
  505. /*
  506. * For R1b type response:
  507. * controller issues a COMMAND COMPLETE interrupt when the R1
  508. * response is received,
  509. * then controller monitors DAT0 for busy status,
  510. * controller issues a TRANSFER COMPLETE interrupt when busy signal
  511. * clears.
  512. */
  513. wait_for_event(handle,
  514. SD4_EMMC_TOP_INTR_TXDONE_MASK | SD_ERR_INTERRUPTS,
  515. handle->device->cfg.wfe_retry);
  516. if (res == SD_OK) {
  517. /* Check result of Cmd6 using Cmd13 to check card status */
  518. /* Check status using Cmd13 */
  519. res = sd_cmd13(handle, &resp.cardStatus);
  520. if (res == SD_OK) {
  521. /* Check bit 7 (SWITCH_ERROR) in card status */
  522. if ((resp.cardStatus & 0x80) != 0) {
  523. EMMC_TRACE("cmd6 failed: SWITCH_ERROR\n");
  524. res = SD_FAIL;
  525. }
  526. } else {
  527. EMMC_TRACE("cmd13 failed after cmd6: ");
  528. EMMC_TRACE("rca 0x%0x, return %d, response 0x%0x\n",
  529. handle->device->ctrl.rca, res, resp.cardStatus);
  530. }
  531. }
  532. return res;
  533. }
  534. #define SD_BUSY_CHECK 0x00203000
  535. #define DAT0_LEVEL_MASK 0x100000 /* bit20 in PSTATE */
  536. #define DEV_BUSY_TIMEOUT 600000 /* 60 Sec : 600000 * 100us */
  537. int send_cmd(struct sd_handle *handle, uint32_t cmdIndex, uint32_t argument,
  538. uint32_t options, struct sd_resp *resp)
  539. {
  540. int status = SD_OK;
  541. uint32_t event = 0, present, timeout = 0, retry = 0, mask = 3;
  542. uint32_t temp_resp[4];
  543. if (handle == NULL) {
  544. EMMC_TRACE("Invalid handle for cmd%d\n", cmdIndex);
  545. return SD_INVALID_HANDLE;
  546. }
  547. mask = (SD_BUSY_CHECK & options) ? 3 : 1;
  548. RETRY_WRITE_CMD:
  549. do {
  550. /* Make sure it is ok to send command */
  551. present =
  552. chal_sd_get_present_status((CHAL_HANDLE *) handle->device);
  553. timeout++;
  554. if (present & mask)
  555. SD_US_DELAY(1000);
  556. else
  557. break;
  558. } while (timeout < EMMC_BUSY_CMD_TIMEOUT_MS);
  559. if (timeout >= EMMC_BUSY_CMD_TIMEOUT_MS) {
  560. status = SD_CMD_MISSING;
  561. EMMC_TRACE("cmd%d timedout %dms\n", cmdIndex, timeout);
  562. }
  563. /* Reset both DAT and CMD line if only of them are stuck */
  564. if (present & mask)
  565. check_error(handle, SD4_EMMC_TOP_INTR_CMDERROR_MASK);
  566. handle->device->ctrl.argReg = argument;
  567. chal_sd_send_cmd((CHAL_HANDLE *) handle->device, cmdIndex,
  568. handle->device->ctrl.argReg, options);
  569. handle->device->ctrl.cmdIndex = cmdIndex;
  570. event = wait_for_event(handle,
  571. (SD4_EMMC_TOP_INTR_CMDDONE_MASK |
  572. SD_ERR_INTERRUPTS),
  573. handle->device->cfg.wfe_retry);
  574. if (handle->device->ctrl.cmdStatus == SD_CMD_MISSING) {
  575. retry++;
  576. if (retry >= handle->device->cfg.retryLimit) {
  577. status = SD_CMD_MISSING;
  578. EMMC_TRACE("cmd%d retry reaches the limit %d\n",
  579. cmdIndex, retry);
  580. } else {
  581. /* reset both DAT & CMD line if one of them is stuck */
  582. present = chal_sd_get_present_status((CHAL_HANDLE *)
  583. handle->device);
  584. if (present & mask)
  585. check_error(handle,
  586. SD4_EMMC_TOP_INTR_CMDERROR_MASK);
  587. EMMC_TRACE("cmd%d retry %d PSTATE[0x%08x]\n",
  588. cmdIndex, retry,
  589. chal_sd_get_present_status((CHAL_HANDLE *)
  590. handle->device));
  591. goto RETRY_WRITE_CMD;
  592. }
  593. }
  594. if (handle->device->ctrl.cmdStatus == SD_OK) {
  595. if (resp != NULL) {
  596. status =
  597. chal_sd_get_response((CHAL_HANDLE *) handle->device,
  598. temp_resp);
  599. process_cmd_response(handle,
  600. handle->device->ctrl.cmdIndex,
  601. temp_resp[0], temp_resp[1],
  602. temp_resp[2], temp_resp[3], resp);
  603. }
  604. /* Check Device busy after CMD */
  605. if ((cmdIndex == 5) || (cmdIndex == 6) || (cmdIndex == 7) ||
  606. (cmdIndex == 28) || (cmdIndex == 29) || (cmdIndex == 38)) {
  607. timeout = 0;
  608. do {
  609. present =
  610. chal_sd_get_present_status((CHAL_HANDLE *)
  611. handle->device);
  612. timeout++;
  613. /* Dat[0]:bit20 low means device busy */
  614. if ((present & DAT0_LEVEL_MASK) == 0) {
  615. EMMC_TRACE("Device busy: ");
  616. EMMC_TRACE(
  617. "cmd%d arg:0x%08x: PSTATE[0x%08x]\n",
  618. cmdIndex, argument, present);
  619. SD_US_DELAY(100);
  620. } else {
  621. break;
  622. }
  623. } while (timeout < DEV_BUSY_TIMEOUT);
  624. }
  625. } else if (handle->device->ctrl.cmdStatus &&
  626. handle->device->ctrl.cmdStatus != SD_CMD_MISSING) {
  627. retry++;
  628. status = check_error(handle, handle->device->ctrl.cmdStatus);
  629. EMMC_TRACE(
  630. "cmd%d error: cmdStatus:0x%08x error_status:0x%08x\n",
  631. cmdIndex, handle->device->ctrl.cmdStatus, status);
  632. if ((handle->device->ctrl.cmdIndex == 1) ||
  633. (handle->device->ctrl.cmdIndex == 5)) {
  634. status = event;
  635. } else if ((handle->device->ctrl.cmdIndex == 7) ||
  636. (handle->device->ctrl.cmdIndex == 41)) {
  637. status = event;
  638. } else if ((status == SD_ERROR_RECOVERABLE) &&
  639. (retry < handle->device->cfg.retryLimit)) {
  640. EMMC_TRACE("cmd%d recoverable error ", cmdIndex);
  641. EMMC_TRACE("retry %d PSTATE[0x%08x].\n", retry,
  642. chal_sd_get_present_status((CHAL_HANDLE *)
  643. handle->device));
  644. goto RETRY_WRITE_CMD;
  645. } else {
  646. EMMC_TRACE("cmd%d retry reaches the limit %d\n",
  647. cmdIndex, retry);
  648. status = event;
  649. }
  650. }
  651. handle->device->ctrl.blkReg = 0;
  652. /* clear error status for next command */
  653. handle->device->ctrl.cmdStatus = 0;
  654. return status;
  655. }