rpi3_sdhost.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. * Copyright (c) 2019, Linaro Limited
  3. * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include <arch.h>
  8. #include <arch_helpers.h>
  9. #include <assert.h>
  10. #include <common/debug.h>
  11. #include <lib/mmio.h>
  12. #include <drivers/delay_timer.h>
  13. #include <drivers/rpi3/sdhost/rpi3_sdhost.h>
  14. #include <drivers/mmc.h>
  15. #include <drivers/rpi3/gpio/rpi3_gpio.h>
  16. #include <errno.h>
  17. #include <string.h>
  18. static void rpi3_sdhost_initialize(void);
  19. static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd);
  20. static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width);
  21. static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size);
  22. static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size);
  23. static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size);
  24. static const struct mmc_ops rpi3_sdhost_ops = {
  25. .init = rpi3_sdhost_initialize,
  26. .send_cmd = rpi3_sdhost_send_cmd,
  27. .set_ios = rpi3_sdhost_set_ios,
  28. .prepare = rpi3_sdhost_prepare,
  29. .read = rpi3_sdhost_read,
  30. .write = rpi3_sdhost_write,
  31. };
  32. static struct rpi3_sdhost_params rpi3_sdhost_params;
  33. /**
  34. * Wait for command being processed.
  35. *
  36. * This function waits the command being processed. It compares
  37. * the ENABLE flag of the HC_COMMAND register. When ENABLE flag disappeared
  38. * it means the command is processed by the SDHOST.
  39. * The timeout is currently 1000*100 us = 100 ms.
  40. *
  41. * @return 0: command finished. 1: command timed out.
  42. */
  43. static int rpi3_sdhost_waitcommand(void)
  44. {
  45. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  46. volatile int timeout = 1000;
  47. while ((mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_ENABLE)
  48. && (--timeout > 0)) {
  49. udelay(100);
  50. }
  51. return ((timeout > 0) ? 0 : (-(ETIMEDOUT)));
  52. }
  53. /**
  54. * Send the command and argument to the SDHOST
  55. *
  56. * This function will wait for the previous command finished. And then
  57. * clear any error status of previous command. And then
  58. * send out the command and args. The command will be turned on the ENABLE
  59. * flag before sending out.
  60. */
  61. static void send_command_raw(unsigned int cmd, unsigned int arg)
  62. {
  63. unsigned int status;
  64. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  65. /* wait for previous command finish */
  66. rpi3_sdhost_waitcommand();
  67. /* clean error status */
  68. status = mmio_read_32(reg_base + HC_HOSTSTATUS);
  69. if (status & HC_HSTST_MASK_ERROR_ALL)
  70. mmio_write_32(reg_base + HC_HOSTSTATUS, status);
  71. /* recording the command */
  72. rpi3_sdhost_params.current_cmd = cmd & HC_CMD_COMMAND_MASK;
  73. /* send the argument and command */
  74. mmio_write_32(reg_base + HC_ARGUMENT, arg);
  75. mmio_write_32(reg_base + HC_COMMAND, cmd | HC_CMD_ENABLE);
  76. }
  77. /**
  78. * Send the command and argument to the SDHOST, decorated with control
  79. * flags.
  80. *
  81. * This function will use send_command_raw to send the commands to SDHOST.
  82. * But before sending it will decorate the command with control flags specific
  83. * to SDHOST.
  84. */
  85. static void send_command_decorated(unsigned int cmd, unsigned int arg)
  86. {
  87. unsigned int cmd_flags = 0;
  88. switch (cmd & HC_CMD_COMMAND_MASK) {
  89. case MMC_CMD(0):
  90. cmd_flags |= HC_CMD_RESPONSE_NONE;
  91. break;
  92. case MMC_ACMD(51):
  93. cmd_flags |= HC_CMD_READ;
  94. break;
  95. case MMC_CMD(8):
  96. case MMC_CMD(11):
  97. case MMC_CMD(17):
  98. case MMC_CMD(18):
  99. cmd_flags |= HC_CMD_READ;
  100. break;
  101. case MMC_CMD(20):
  102. case MMC_CMD(24):
  103. case MMC_CMD(25):
  104. cmd_flags |= HC_CMD_WRITE;
  105. break;
  106. case MMC_CMD(12):
  107. cmd_flags |= HC_CMD_BUSY;
  108. break;
  109. default:
  110. break;
  111. }
  112. send_command_raw(cmd | cmd_flags, arg);
  113. }
  114. /**
  115. * drains the FIFO on DATA port
  116. *
  117. * This function drains any data left in the DATA port.
  118. */
  119. static void rpi3_drain_fifo(void)
  120. {
  121. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  122. volatile int timeout = 100000;
  123. rpi3_sdhost_waitcommand();
  124. while (mmio_read_32(reg_base + HC_HOSTSTATUS) & HC_HSTST_HAVEDATA) {
  125. mmio_read_32(reg_base + HC_DATAPORT);
  126. udelay(100);
  127. }
  128. while (1) {
  129. uint32_t edm, fsm;
  130. edm = mmio_read_32(reg_base + HC_DEBUG);
  131. fsm = edm & HC_DBG_FSM_MASK;
  132. if ((fsm == HC_DBG_FSM_IDENTMODE) ||
  133. (fsm == HC_DBG_FSM_DATAMODE))
  134. break;
  135. if ((fsm == HC_DBG_FSM_READWAIT) ||
  136. (fsm == HC_DBG_FSM_WRITESTART1) ||
  137. (fsm == HC_DBG_FSM_READDATA)) {
  138. mmio_write_32(reg_base + HC_DEBUG,
  139. edm | HC_DBG_FORCE_DATA_MODE);
  140. break;
  141. }
  142. if (--timeout <= 0) {
  143. ERROR("rpi3_sdhost: %s cannot recover stat\n",
  144. __func__);
  145. return;
  146. }
  147. }
  148. }
  149. /**
  150. * Dump SDHOST registers
  151. */
  152. static void rpi3_sdhost_print_regs(void)
  153. {
  154. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  155. INFO("rpi3_sdhost: HC_COMMAND: 0x%08x\n",
  156. mmio_read_32(reg_base + HC_COMMAND));
  157. INFO("rpi3_sdhost: HC_ARGUMENT: 0x%08x\n",
  158. mmio_read_32(reg_base + HC_ARGUMENT));
  159. INFO("rpi3_sdhost: HC_TIMEOUTCOUNTER: 0x%08x\n",
  160. mmio_read_32(reg_base + HC_TIMEOUTCOUNTER));
  161. INFO("rpi3_sdhost: HC_CLOCKDIVISOR: 0x%08x\n",
  162. mmio_read_32(reg_base + HC_CLOCKDIVISOR));
  163. INFO("rpi3_sdhost: HC_RESPONSE_0: 0x%08x\n",
  164. mmio_read_32(reg_base + HC_RESPONSE_0));
  165. INFO("rpi3_sdhost: HC_RESPONSE_1: 0x%08x\n",
  166. mmio_read_32(reg_base + HC_RESPONSE_1));
  167. INFO("rpi3_sdhost: HC_RESPONSE_2: 0x%08x\n",
  168. mmio_read_32(reg_base + HC_RESPONSE_2));
  169. INFO("rpi3_sdhost: HC_RESPONSE_3: 0x%08x\n",
  170. mmio_read_32(reg_base + HC_RESPONSE_3));
  171. INFO("rpi3_sdhost: HC_HOSTSTATUS: 0x%08x\n",
  172. mmio_read_32(reg_base + HC_HOSTSTATUS));
  173. INFO("rpi3_sdhost: HC_POWER: 0x%08x\n",
  174. mmio_read_32(reg_base + HC_POWER));
  175. INFO("rpi3_sdhost: HC_DEBUG: 0x%08x\n",
  176. mmio_read_32(reg_base + HC_DEBUG));
  177. INFO("rpi3_sdhost: HC_HOSTCONFIG: 0x%08x\n",
  178. mmio_read_32(reg_base + HC_HOSTCONFIG));
  179. INFO("rpi3_sdhost: HC_BLOCKSIZE: 0x%08x\n",
  180. mmio_read_32(reg_base + HC_BLOCKSIZE));
  181. INFO("rpi3_sdhost: HC_BLOCKCOUNT: 0x%08x\n",
  182. mmio_read_32(reg_base + HC_BLOCKCOUNT));
  183. }
  184. /**
  185. * Reset SDHOST
  186. */
  187. static void rpi3_sdhost_reset(void)
  188. {
  189. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  190. unsigned int dbg;
  191. uint32_t tmp1;
  192. mmio_write_32(reg_base + HC_POWER, 0);
  193. mmio_write_32(reg_base + HC_COMMAND, 0);
  194. mmio_write_32(reg_base + HC_ARGUMENT, 0);
  195. mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_DEFAULT);
  196. mmio_write_32(reg_base + HC_CLOCKDIVISOR, 0);
  197. mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_RESET);
  198. mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
  199. mmio_write_32(reg_base + HC_BLOCKSIZE, 0);
  200. mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
  201. dbg = mmio_read_32(reg_base + HC_DEBUG);
  202. dbg &= ~((HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_READ_SHIFT) |
  203. (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_WRITE_SHIFT));
  204. dbg |= (HC_FIFO_THRESH_READ << HC_DBG_FIFO_THRESH_READ_SHIFT) |
  205. (HC_FIFO_THRESH_WRITE << HC_DBG_FIFO_THRESH_WRITE_SHIFT);
  206. mmio_write_32(reg_base + HC_DEBUG, dbg);
  207. mdelay(250);
  208. mmio_write_32(reg_base + HC_POWER, 1);
  209. mdelay(250);
  210. rpi3_sdhost_params.clk_rate = 0;
  211. mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_MAXVAL);
  212. tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
  213. mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 | HC_HSTCF_INT_BUSY);
  214. }
  215. static void rpi3_sdhost_initialize(void)
  216. {
  217. assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);
  218. rpi3_sdhost_reset();
  219. rpi3_sdhost_set_ios(rpi3_sdhost_params.clk_rate_initial,
  220. rpi3_sdhost_params.bus_width);
  221. udelay(300);
  222. }
  223. static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
  224. {
  225. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  226. int err = 0;
  227. uint32_t cmd_idx;
  228. uint32_t cmd_arg;
  229. uint32_t cmd_flags = 0;
  230. uint32_t intmask;
  231. /* Wait for the command done */
  232. err = rpi3_sdhost_waitcommand();
  233. if (err != 0) {
  234. WARN("previous command not done yet\n");
  235. return err;
  236. }
  237. cmd_idx = cmd->cmd_idx & HC_CMD_COMMAND_MASK;
  238. cmd_arg = cmd->cmd_arg;
  239. if (cmd_idx == MMC_ACMD(51)) {
  240. /* if previous cmd send to SDHOST is not MMC_CMD(55).
  241. * It means this MMC_ACMD(51) is a resend.
  242. * And we must also resend MMC_CMD(55) in this case
  243. */
  244. if (rpi3_sdhost_params.current_cmd != MMC_CMD(55)) {
  245. send_command_decorated(
  246. MMC_CMD(55),
  247. rpi3_sdhost_params.sdcard_rca <<
  248. RCA_SHIFT_OFFSET);
  249. rpi3_sdhost_params.mmc_app_cmd = 1;
  250. rpi3_sdhost_waitcommand();
  251. /* Also we need to call prepare to clean the buffer */
  252. rpi3_sdhost_prepare(0, (uintptr_t)NULL, 8);
  253. }
  254. }
  255. /* We ignore MMC_CMD(12) sending from the TF-A's MMC driver
  256. * because we send MMC_CMD(12) by ourselves.
  257. */
  258. if (cmd_idx == MMC_CMD(12))
  259. return 0;
  260. if ((cmd->resp_type & MMC_RSP_136) &&
  261. (cmd->resp_type & MMC_RSP_BUSY)) {
  262. ERROR("rpi3_sdhost: unsupported response type!\n");
  263. return -(EOPNOTSUPP);
  264. }
  265. if (cmd->resp_type & MMC_RSP_48 && cmd->resp_type != MMC_RESPONSE_R2) {
  266. /* 48-bit command
  267. * We don't need to set any flags here because it is default.
  268. */
  269. } else if (cmd->resp_type & MMC_RSP_136) {
  270. /* 136-bit command */
  271. cmd_flags |= HC_CMD_RESPONSE_LONG;
  272. } else {
  273. /* no respond command */
  274. cmd_flags |= HC_CMD_RESPONSE_NONE;
  275. }
  276. rpi3_sdhost_params.cmdbusy = 0;
  277. if (cmd->resp_type & MMC_RSP_BUSY) {
  278. cmd_flags |= HC_CMD_BUSY;
  279. rpi3_sdhost_params.cmdbusy = 1;
  280. }
  281. if (rpi3_sdhost_params.mmc_app_cmd) {
  282. switch (cmd_idx) {
  283. case MMC_ACMD(41):
  284. if (cmd_arg == OCR_HCS)
  285. cmd_arg |= OCR_3_3_3_4;
  286. break;
  287. default:
  288. break;
  289. }
  290. rpi3_sdhost_params.mmc_app_cmd = 0;
  291. }
  292. if (cmd_idx == MMC_CMD(55))
  293. rpi3_sdhost_params.mmc_app_cmd = 1;
  294. send_command_decorated(cmd_idx | cmd_flags, cmd_arg);
  295. intmask = mmio_read_32(reg_base + HC_HOSTSTATUS);
  296. if (rpi3_sdhost_params.cmdbusy && (intmask & HC_HSTST_INT_BUSY)) {
  297. mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_INT_BUSY);
  298. rpi3_sdhost_params.cmdbusy = 0;
  299. }
  300. if (!(cmd_flags & HC_CMD_RESPONSE_NONE)) {
  301. err = rpi3_sdhost_waitcommand();
  302. if (err != 0)
  303. ERROR("rpi3_sdhost: cmd cannot be finished\n");
  304. }
  305. cmd->resp_data[0] = mmio_read_32(reg_base + HC_RESPONSE_0);
  306. cmd->resp_data[1] = mmio_read_32(reg_base + HC_RESPONSE_1);
  307. cmd->resp_data[2] = mmio_read_32(reg_base + HC_RESPONSE_2);
  308. cmd->resp_data[3] = mmio_read_32(reg_base + HC_RESPONSE_3);
  309. if (mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_FAILED) {
  310. uint32_t sdhsts = mmio_read_32(reg_base + HC_HOSTSTATUS);
  311. mmio_write_32(reg_base + HC_HOSTSTATUS,
  312. HC_HSTST_MASK_ERROR_ALL);
  313. /*
  314. * If the command SEND_OP_COND returns with CRC7 error,
  315. * it can be considered as having completed successfully.
  316. */
  317. if (!(sdhsts & HC_HSTST_ERROR_CRC7)
  318. || (cmd_idx != MMC_CMD(1))) {
  319. if (sdhsts & HC_HSTST_TIMEOUT_CMD) {
  320. ERROR("rpi3_sdhost: timeout status 0x%x\n",
  321. sdhsts);
  322. err = -(ETIMEDOUT);
  323. } else {
  324. ERROR("rpi3_sdhost: unknown err, cmd = 0x%x\n",
  325. mmio_read_32(reg_base + HC_COMMAND));
  326. ERROR("rpi3_sdhost status: 0x%x\n", sdhsts);
  327. err = -(EILSEQ);
  328. }
  329. }
  330. }
  331. if ((!err) && (cmd_idx == MMC_CMD(3))) {
  332. /* we keep the RCA in case to send MMC_CMD(55) ourselves */
  333. rpi3_sdhost_params.sdcard_rca = (cmd->resp_data[0]
  334. & 0xFFFF0000U) >> 16;
  335. }
  336. return err;
  337. }
  338. static int rpi3_sdhost_set_clock(unsigned int clk)
  339. {
  340. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  341. uint32_t max_clk = 250000000;
  342. uint32_t div;
  343. if (clk < 100000) {
  344. mmio_write_32(reg_base + HC_CLOCKDIVISOR,
  345. HC_CLOCKDIVISOR_MAXVAL);
  346. return 0;
  347. }
  348. div = max_clk / clk;
  349. if (div < 2)
  350. div = 2;
  351. if ((max_clk / div) > clk)
  352. div++;
  353. div -= 2;
  354. if (div > HC_CLOCKDIVISOR_MAXVAL)
  355. div = HC_CLOCKDIVISOR_MAXVAL;
  356. rpi3_sdhost_params.clk_rate = max_clk / (div + 2);
  357. rpi3_sdhost_params.ns_per_fifo_word = (1000000000 /
  358. rpi3_sdhost_params.clk_rate)
  359. * 8;
  360. mmio_write_32(reg_base + HC_CLOCKDIVISOR, div);
  361. return 0;
  362. }
  363. static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width)
  364. {
  365. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  366. uint32_t tmp1;
  367. rpi3_sdhost_set_clock(clk);
  368. VERBOSE("rpi3_sdhost: Changing clock to %dHz for data mode\n", clk);
  369. if (width != MMC_BUS_WIDTH_4 && width != MMC_BUS_WIDTH_1) {
  370. ERROR("rpi3_sdhost: width %d not supported\n", width);
  371. return -(EOPNOTSUPP);
  372. }
  373. rpi3_sdhost_params.bus_width = width;
  374. tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
  375. tmp1 &= ~(HC_HSTCF_EXTBUS_4BIT);
  376. if (rpi3_sdhost_params.bus_width == MMC_BUS_WIDTH_4)
  377. tmp1 |= HC_HSTCF_EXTBUS_4BIT;
  378. mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1);
  379. tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
  380. mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 |
  381. HC_HSTCF_SLOW_CARD | HC_HSTCF_INTBUS_WIDE);
  382. return 0;
  383. }
  384. static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size)
  385. {
  386. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  387. size_t blocks;
  388. size_t blocksize;
  389. if (size < 512) {
  390. blocksize = size;
  391. blocks = 1;
  392. } else {
  393. blocksize = 512;
  394. blocks = size / blocksize;
  395. if (size % blocksize != 0)
  396. blocks++;
  397. }
  398. rpi3_drain_fifo();
  399. mmio_write_32(reg_base + HC_BLOCKSIZE, blocksize);
  400. mmio_write_32(reg_base + HC_BLOCKCOUNT, blocks);
  401. udelay(100);
  402. return 0;
  403. }
  404. static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size)
  405. {
  406. int err = 0;
  407. uint32_t *buf1 = ((uint32_t *) buf);
  408. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  409. int timeout = 100000;
  410. int remaining_words = 0;
  411. for (int i = 0; i < size / 4; i++) {
  412. volatile int t = timeout;
  413. uint32_t hsts_err;
  414. while ((mmio_read_32(reg_base + HC_HOSTSTATUS)
  415. & HC_HSTST_HAVEDATA) == 0) {
  416. if (t == 0) {
  417. ERROR("rpi3_sdhost: fifo timeout after %dus\n",
  418. timeout);
  419. err = -(ETIMEDOUT);
  420. break;
  421. }
  422. t--;
  423. udelay(10);
  424. }
  425. if (t == 0)
  426. break;
  427. uint32_t data = mmio_read_32(reg_base + HC_DATAPORT);
  428. hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
  429. & HC_HSTST_MASK_ERROR_ALL;
  430. if (hsts_err) {
  431. ERROR("rpi3_sdhost: transfer FIFO word %d: 0x%x\n",
  432. i,
  433. mmio_read_32(reg_base + HC_HOSTSTATUS));
  434. rpi3_sdhost_print_regs();
  435. err = -(EILSEQ);
  436. /* clean the error status */
  437. mmio_write_32(reg_base + HC_HOSTSTATUS, hsts_err);
  438. }
  439. if (buf1)
  440. buf1[i] = data;
  441. /* speeding up if the remaining words are still a lot */
  442. remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
  443. & HC_DBG_FIFO_THRESH_MASK;
  444. if (remaining_words >= 7)
  445. continue;
  446. /* delay. slowing down the read process */
  447. udelay(100);
  448. }
  449. /* We decide to stop by ourselves.
  450. * It is because MMC_CMD(18) -> MMC_CMD(13) -> MMC_CMD(12)
  451. * doesn't work for RPi3 SDHost.
  452. */
  453. if (rpi3_sdhost_params.current_cmd == MMC_CMD(18))
  454. send_command_decorated(MMC_CMD(12), 0);
  455. return err;
  456. }
  457. static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size)
  458. {
  459. uint32_t *buf1 = ((uint32_t *) buf);
  460. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  461. int err = 0;
  462. int remaining_words = 0;
  463. for (int i = 0; i < size / 4; i++) {
  464. uint32_t hsts_err;
  465. uint32_t data = buf1[i];
  466. uint32_t dbg;
  467. uint32_t fsm_state;
  468. mmio_write_32(reg_base + HC_DATAPORT, data);
  469. dbg = mmio_read_32(reg_base + HC_DEBUG);
  470. fsm_state = dbg & HC_DBG_FSM_MASK;
  471. if (fsm_state != HC_DBG_FSM_WRITEDATA
  472. && fsm_state != HC_DBG_FSM_WRITESTART1
  473. && fsm_state != HC_DBG_FSM_WRITESTART2
  474. && fsm_state != HC_DBG_FSM_WRITECRC
  475. && fsm_state != HC_DBG_FSM_WRITEWAIT1
  476. && fsm_state != HC_DBG_FSM_WRITEWAIT2) {
  477. hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
  478. & HC_HSTST_MASK_ERROR_ALL;
  479. if (hsts_err)
  480. err = -(EILSEQ);
  481. }
  482. /* speeding up if the remaining words are not many */
  483. remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
  484. & HC_DBG_FIFO_THRESH_MASK;
  485. if (remaining_words <= 4)
  486. continue;
  487. udelay(100);
  488. }
  489. /* We decide to stop by ourselves.
  490. * It is because MMC_CMD(25) -> MMC_CMD(13) -> MMC_CMD(12)
  491. * doesn't work for RPi3 SDHost.
  492. */
  493. if (rpi3_sdhost_params.current_cmd == MMC_CMD(25))
  494. send_command_decorated(MMC_CMD(12), 0);
  495. return err;
  496. }
  497. void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
  498. struct mmc_device_info *mmc_dev_info)
  499. {
  500. assert((params != 0) &&
  501. ((params->reg_base & MMC_BLOCK_MASK) == 0));
  502. memcpy(&rpi3_sdhost_params, params, sizeof(struct rpi3_sdhost_params));
  503. /* backup GPIO 48 to 53 configurations */
  504. for (int i = 48; i <= 53; i++) {
  505. rpi3_sdhost_params.gpio48_pinselect[i - 48]
  506. = rpi3_gpio_get_select(i);
  507. VERBOSE("rpi3_sdhost: Original GPIO state %d: %d\n",
  508. i,
  509. rpi3_sdhost_params.gpio48_pinselect[i - 48]);
  510. }
  511. /* setting pull resistors for 48 to 53.
  512. * It is debatable to set SD_CLK to UP or NONE. We massively
  513. * tested different brands of SD Cards and found NONE works
  514. * most stable.
  515. *
  516. * GPIO 48 (SD_CLK) to GPIO_PULL_NONE
  517. * GPIO 49 (SD_CMD) to GPIO_PULL_UP
  518. * GPIO 50 (SD_D0) to GPIO_PULL_UP
  519. * GPIO 51 (SD_D1) to GPIO_PULL_UP
  520. * GPIO 52 (SD_D2) to GPIO_PULL_UP
  521. * GPIO 53 (SD_D3) to GPIO_PULL_UP
  522. */
  523. gpio_set_pull(48, GPIO_PULL_NONE);
  524. for (int i = 49; i <= 53; i++)
  525. gpio_set_pull(i, GPIO_PULL_UP);
  526. /* Set pin 48-53 to alt-0. It means route SDHOST to card slot */
  527. for (int i = 48; i <= 53; i++)
  528. rpi3_gpio_set_select(i, RPI3_GPIO_FUNC_ALT0);
  529. mmc_init(&rpi3_sdhost_ops, params->clk_rate, params->bus_width,
  530. params->flags, mmc_dev_info);
  531. }
  532. void rpi3_sdhost_stop(void)
  533. {
  534. uintptr_t reg_base = rpi3_sdhost_params.reg_base;
  535. VERBOSE("rpi3_sdhost: Shutting down: drain FIFO out\n");
  536. rpi3_drain_fifo();
  537. VERBOSE("rpi3_sdhost: Shutting down: slowing down the clock\n");
  538. mmio_write_32(reg_base+HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_SLOWVAL);
  539. udelay(500);
  540. VERBOSE("rpi3_sdhost: Shutting down: put SDHost into idle state\n");
  541. send_command_decorated(MMC_CMD(0), 0);
  542. udelay(500);
  543. mmio_write_32(reg_base + HC_COMMAND, 0);
  544. mmio_write_32(reg_base + HC_ARGUMENT, 0);
  545. mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_IDLE);
  546. mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_STOPVAL);
  547. udelay(100);
  548. mmio_write_32(reg_base + HC_POWER, 0);
  549. mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
  550. mmio_write_32(reg_base + HC_BLOCKSIZE, 0x400);
  551. mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
  552. mmio_write_32(reg_base + HC_HOSTSTATUS, 0x7f8);
  553. mmio_write_32(reg_base + HC_COMMAND, 0);
  554. mmio_write_32(reg_base + HC_ARGUMENT, 0);
  555. udelay(100);
  556. /* Restore the pinmux to original state */
  557. for (int i = 48; i <= 53; i++) {
  558. rpi3_gpio_set_select(i,
  559. rpi3_sdhost_params.gpio48_pinselect[i-48]);
  560. }
  561. /* Reset the pull resistors before entering BL33.
  562. * GPIO 48 (SD_CLK) to GPIO_PULL_UP
  563. * GPIO 49 (SD_CMD) to GPIO_PULL_UP
  564. * GPIO 50 (SD_D0) to GPIO_PULL_UP
  565. * GPIO 51 (SD_D1) to GPIO_PULL_UP
  566. * GPIO 52 (SD_D2) to GPIO_PULL_UP
  567. * GPIO 53 (SD_D3) to GPIO_PULL_UP
  568. */
  569. for (int i = 48; i <= 53; i++)
  570. gpio_set_pull(i, GPIO_PULL_UP);
  571. }