dw_mmc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include <arch.h>
  10. #include <arch_helpers.h>
  11. #include <common/debug.h>
  12. #include <drivers/delay_timer.h>
  13. #include <drivers/mmc.h>
  14. #include <drivers/synopsys/dw_mmc.h>
  15. #include <lib/utils_def.h>
  16. #include <lib/mmio.h>
  17. #define DWMMC_CTRL (0x00)
  18. #define CTRL_IDMAC_EN (1 << 25)
  19. #define CTRL_DMA_EN (1 << 5)
  20. #define CTRL_INT_EN (1 << 4)
  21. #define CTRL_DMA_RESET (1 << 2)
  22. #define CTRL_FIFO_RESET (1 << 1)
  23. #define CTRL_RESET (1 << 0)
  24. #define CTRL_RESET_ALL (CTRL_DMA_RESET | CTRL_FIFO_RESET | \
  25. CTRL_RESET)
  26. #define DWMMC_PWREN (0x04)
  27. #define DWMMC_CLKDIV (0x08)
  28. #define DWMMC_CLKSRC (0x0c)
  29. #define DWMMC_CLKENA (0x10)
  30. #define DWMMC_TMOUT (0x14)
  31. #define DWMMC_CTYPE (0x18)
  32. #define CTYPE_8BIT (1 << 16)
  33. #define CTYPE_4BIT (1)
  34. #define CTYPE_1BIT (0)
  35. #define DWMMC_BLKSIZ (0x1c)
  36. #define DWMMC_BYTCNT (0x20)
  37. #define DWMMC_INTMASK (0x24)
  38. #define INT_EBE (1 << 15)
  39. #define INT_SBE (1 << 13)
  40. #define INT_HLE (1 << 12)
  41. #define INT_FRUN (1 << 11)
  42. #define INT_DRT (1 << 9)
  43. #define INT_RTO (1 << 8)
  44. #define INT_DCRC (1 << 7)
  45. #define INT_RCRC (1 << 6)
  46. #define INT_RXDR (1 << 5)
  47. #define INT_TXDR (1 << 4)
  48. #define INT_DTO (1 << 3)
  49. #define INT_CMD_DONE (1 << 2)
  50. #define INT_RE (1 << 1)
  51. #define DWMMC_CMDARG (0x28)
  52. #define DWMMC_CMD (0x2c)
  53. #define CMD_START (U(1) << 31)
  54. #define CMD_USE_HOLD_REG (1 << 29) /* 0 if SDR50/100 */
  55. #define CMD_UPDATE_CLK_ONLY (1 << 21)
  56. #define CMD_SEND_INIT (1 << 15)
  57. #define CMD_STOP_ABORT_CMD (1 << 14)
  58. #define CMD_WAIT_PRVDATA_COMPLETE (1 << 13)
  59. #define CMD_WRITE (1 << 10)
  60. #define CMD_DATA_TRANS_EXPECT (1 << 9)
  61. #define CMD_CHECK_RESP_CRC (1 << 8)
  62. #define CMD_RESP_LEN (1 << 7)
  63. #define CMD_RESP_EXPECT (1 << 6)
  64. #define CMD(x) (x & 0x3f)
  65. #define DWMMC_RESP0 (0x30)
  66. #define DWMMC_RESP1 (0x34)
  67. #define DWMMC_RESP2 (0x38)
  68. #define DWMMC_RESP3 (0x3c)
  69. #define DWMMC_RINTSTS (0x44)
  70. #define DWMMC_STATUS (0x48)
  71. #define STATUS_DATA_BUSY (1 << 9)
  72. #define DWMMC_FIFOTH (0x4c)
  73. #define FIFOTH_TWMARK(x) (x & 0xfff)
  74. #define FIFOTH_RWMARK(x) ((x & 0x1ff) << 16)
  75. #define FIFOTH_DMA_BURST_SIZE(x) ((x & 0x7) << 28)
  76. #define DWMMC_DEBNCE (0x64)
  77. #define DWMMC_BMOD (0x80)
  78. #define BMOD_ENABLE (1 << 7)
  79. #define BMOD_FB (1 << 1)
  80. #define BMOD_SWRESET (1 << 0)
  81. #define DWMMC_DBADDR (0x88)
  82. #define DWMMC_IDSTS (0x8c)
  83. #define DWMMC_IDINTEN (0x90)
  84. #define DWMMC_CARDTHRCTL (0x100)
  85. #define CARDTHRCTL_RD_THR(x) ((x & 0xfff) << 16)
  86. #define CARDTHRCTL_RD_THR_EN (1 << 0)
  87. #define IDMAC_DES0_DIC (1 << 1)
  88. #define IDMAC_DES0_LD (1 << 2)
  89. #define IDMAC_DES0_FS (1 << 3)
  90. #define IDMAC_DES0_CH (1 << 4)
  91. #define IDMAC_DES0_ER (1 << 5)
  92. #define IDMAC_DES0_CES (1 << 30)
  93. #define IDMAC_DES0_OWN (U(1) << 31)
  94. #define IDMAC_DES1_BS1(x) ((x) & 0x1fff)
  95. #define IDMAC_DES2_BS2(x) (((x) & 0x1fff) << 13)
  96. #define DWMMC_DMA_MAX_BUFFER_SIZE (512 * 8)
  97. #define DWMMC_8BIT_MODE (1 << 6)
  98. #define DWMMC_ADDRESS_MASK U(0x0f)
  99. #define TIMEOUT 100000
  100. struct dw_idmac_desc {
  101. unsigned int des0;
  102. unsigned int des1;
  103. unsigned int des2;
  104. unsigned int des3;
  105. };
  106. static void dw_init(void);
  107. static int dw_send_cmd(struct mmc_cmd *cmd);
  108. static int dw_set_ios(unsigned int clk, unsigned int width);
  109. static int dw_prepare(int lba, uintptr_t buf, size_t size);
  110. static int dw_read(int lba, uintptr_t buf, size_t size);
  111. static int dw_write(int lba, uintptr_t buf, size_t size);
  112. static const struct mmc_ops dw_mmc_ops = {
  113. .init = dw_init,
  114. .send_cmd = dw_send_cmd,
  115. .set_ios = dw_set_ios,
  116. .prepare = dw_prepare,
  117. .read = dw_read,
  118. .write = dw_write,
  119. };
  120. static dw_mmc_params_t dw_params;
  121. static void dw_update_clk(void)
  122. {
  123. unsigned int data;
  124. mmio_write_32(dw_params.reg_base + DWMMC_CMD,
  125. CMD_WAIT_PRVDATA_COMPLETE | CMD_UPDATE_CLK_ONLY |
  126. CMD_START);
  127. while (1) {
  128. data = mmio_read_32(dw_params.reg_base + DWMMC_CMD);
  129. if ((data & CMD_START) == 0)
  130. break;
  131. data = mmio_read_32(dw_params.reg_base + DWMMC_RINTSTS);
  132. assert((data & INT_HLE) == 0);
  133. }
  134. }
  135. static void dw_set_clk(int clk)
  136. {
  137. unsigned int data;
  138. int div;
  139. assert(clk > 0);
  140. for (div = 1; div < 256; div++) {
  141. if ((dw_params.clk_rate / (2 * div)) <= clk) {
  142. break;
  143. }
  144. }
  145. assert(div < 256);
  146. /* wait until controller is idle */
  147. do {
  148. data = mmio_read_32(dw_params.reg_base + DWMMC_STATUS);
  149. } while (data & STATUS_DATA_BUSY);
  150. /* disable clock before change clock rate */
  151. mmio_write_32(dw_params.reg_base + DWMMC_CLKENA, 0);
  152. dw_update_clk();
  153. mmio_write_32(dw_params.reg_base + DWMMC_CLKDIV, div);
  154. dw_update_clk();
  155. /* enable clock */
  156. mmio_write_32(dw_params.reg_base + DWMMC_CLKENA, 1);
  157. mmio_write_32(dw_params.reg_base + DWMMC_CLKSRC, 0);
  158. dw_update_clk();
  159. }
  160. static void dw_init(void)
  161. {
  162. unsigned int data;
  163. uintptr_t base;
  164. assert((dw_params.reg_base & MMC_BLOCK_MASK) == 0);
  165. base = dw_params.reg_base;
  166. mmio_write_32(base + DWMMC_PWREN, 1);
  167. mmio_write_32(base + DWMMC_CTRL, CTRL_RESET_ALL);
  168. do {
  169. data = mmio_read_32(base + DWMMC_CTRL);
  170. } while (data);
  171. /* enable DMA in CTRL */
  172. data = CTRL_INT_EN | CTRL_DMA_EN | CTRL_IDMAC_EN;
  173. mmio_write_32(base + DWMMC_CTRL, data);
  174. mmio_write_32(base + DWMMC_RINTSTS, ~0);
  175. mmio_write_32(base + DWMMC_INTMASK, 0);
  176. mmio_write_32(base + DWMMC_TMOUT, ~0);
  177. mmio_write_32(base + DWMMC_IDINTEN, ~0);
  178. mmio_write_32(base + DWMMC_BLKSIZ, MMC_BLOCK_SIZE);
  179. mmio_write_32(base + DWMMC_BYTCNT, 256 * 1024);
  180. mmio_write_32(base + DWMMC_DEBNCE, 0x00ffffff);
  181. mmio_write_32(base + DWMMC_BMOD, BMOD_SWRESET);
  182. do {
  183. data = mmio_read_32(base + DWMMC_BMOD);
  184. } while (data & BMOD_SWRESET);
  185. /* enable DMA in BMOD */
  186. data |= BMOD_ENABLE | BMOD_FB;
  187. mmio_write_32(base + DWMMC_BMOD, data);
  188. udelay(100);
  189. dw_set_clk(MMC_BOOT_CLK_RATE);
  190. udelay(100);
  191. }
  192. static int dw_send_cmd(struct mmc_cmd *cmd)
  193. {
  194. unsigned int op, data, err_mask;
  195. uintptr_t base;
  196. int timeout;
  197. assert(cmd);
  198. base = dw_params.reg_base;
  199. switch (cmd->cmd_idx) {
  200. case 0:
  201. op = CMD_SEND_INIT;
  202. break;
  203. case 12:
  204. op = CMD_STOP_ABORT_CMD;
  205. break;
  206. case 13:
  207. op = CMD_WAIT_PRVDATA_COMPLETE;
  208. break;
  209. case 8:
  210. if (dw_params.mmc_dev_type == MMC_IS_EMMC)
  211. op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE;
  212. else
  213. op = CMD_WAIT_PRVDATA_COMPLETE;
  214. break;
  215. case 17:
  216. case 18:
  217. op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE;
  218. break;
  219. case 24:
  220. case 25:
  221. op = CMD_WRITE | CMD_DATA_TRANS_EXPECT |
  222. CMD_WAIT_PRVDATA_COMPLETE;
  223. break;
  224. case 51:
  225. op = CMD_DATA_TRANS_EXPECT;
  226. break;
  227. default:
  228. op = 0;
  229. break;
  230. }
  231. op |= CMD_USE_HOLD_REG | CMD_START;
  232. switch (cmd->resp_type) {
  233. case 0:
  234. break;
  235. case MMC_RESPONSE_R2:
  236. op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC |
  237. CMD_RESP_LEN;
  238. break;
  239. case MMC_RESPONSE_R3:
  240. op |= CMD_RESP_EXPECT;
  241. break;
  242. default:
  243. op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC;
  244. break;
  245. }
  246. timeout = TIMEOUT;
  247. do {
  248. data = mmio_read_32(base + DWMMC_STATUS);
  249. if (--timeout <= 0)
  250. panic();
  251. } while (data & STATUS_DATA_BUSY);
  252. mmio_write_32(base + DWMMC_RINTSTS, ~0);
  253. mmio_write_32(base + DWMMC_CMDARG, cmd->cmd_arg);
  254. mmio_write_32(base + DWMMC_CMD, op | cmd->cmd_idx);
  255. err_mask = INT_EBE | INT_HLE | INT_RTO | INT_RCRC | INT_RE |
  256. INT_DCRC | INT_DRT | INT_SBE;
  257. timeout = TIMEOUT;
  258. do {
  259. udelay(500);
  260. data = mmio_read_32(base + DWMMC_RINTSTS);
  261. if (data & err_mask)
  262. return -EIO;
  263. if (data & INT_DTO)
  264. break;
  265. if (--timeout == 0) {
  266. ERROR("%s, RINTSTS:0x%x\n", __func__, data);
  267. panic();
  268. }
  269. } while (!(data & INT_CMD_DONE));
  270. if (op & CMD_RESP_EXPECT) {
  271. cmd->resp_data[0] = mmio_read_32(base + DWMMC_RESP0);
  272. if (op & CMD_RESP_LEN) {
  273. cmd->resp_data[1] = mmio_read_32(base + DWMMC_RESP1);
  274. cmd->resp_data[2] = mmio_read_32(base + DWMMC_RESP2);
  275. cmd->resp_data[3] = mmio_read_32(base + DWMMC_RESP3);
  276. }
  277. }
  278. return 0;
  279. }
  280. static int dw_set_ios(unsigned int clk, unsigned int width)
  281. {
  282. switch (width) {
  283. case MMC_BUS_WIDTH_1:
  284. mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_1BIT);
  285. break;
  286. case MMC_BUS_WIDTH_4:
  287. mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_4BIT);
  288. break;
  289. case MMC_BUS_WIDTH_8:
  290. mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_8BIT);
  291. break;
  292. default:
  293. assert(0);
  294. break;
  295. }
  296. dw_set_clk(clk);
  297. return 0;
  298. }
  299. static int dw_prepare(int lba, uintptr_t buf, size_t size)
  300. {
  301. struct dw_idmac_desc *desc;
  302. int desc_cnt, i, last;
  303. uintptr_t base;
  304. assert(((buf & DWMMC_ADDRESS_MASK) == 0) &&
  305. (dw_params.desc_size > 0) &&
  306. ((dw_params.reg_base & MMC_BLOCK_MASK) == 0) &&
  307. ((dw_params.desc_base & MMC_BLOCK_MASK) == 0) &&
  308. ((dw_params.desc_size & MMC_BLOCK_MASK) == 0));
  309. flush_dcache_range(buf, size);
  310. desc_cnt = (size + DWMMC_DMA_MAX_BUFFER_SIZE - 1) /
  311. DWMMC_DMA_MAX_BUFFER_SIZE;
  312. assert(desc_cnt * sizeof(struct dw_idmac_desc) < dw_params.desc_size);
  313. base = dw_params.reg_base;
  314. desc = (struct dw_idmac_desc *)dw_params.desc_base;
  315. mmio_write_32(base + DWMMC_BYTCNT, size);
  316. if (size < MMC_BLOCK_SIZE)
  317. mmio_write_32(base + DWMMC_BLKSIZ, size);
  318. else
  319. mmio_write_32(base + DWMMC_BLKSIZ, MMC_BLOCK_SIZE);
  320. mmio_write_32(base + DWMMC_RINTSTS, ~0);
  321. for (i = 0; i < desc_cnt; i++) {
  322. desc[i].des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH | IDMAC_DES0_DIC;
  323. desc[i].des1 = IDMAC_DES1_BS1(DWMMC_DMA_MAX_BUFFER_SIZE);
  324. desc[i].des2 = buf + DWMMC_DMA_MAX_BUFFER_SIZE * i;
  325. desc[i].des3 = dw_params.desc_base +
  326. (sizeof(struct dw_idmac_desc)) * (i + 1);
  327. }
  328. /* first descriptor */
  329. desc->des0 |= IDMAC_DES0_FS;
  330. /* last descriptor */
  331. last = desc_cnt - 1;
  332. (desc + last)->des0 |= IDMAC_DES0_LD;
  333. (desc + last)->des0 &= ~(IDMAC_DES0_DIC | IDMAC_DES0_CH);
  334. (desc + last)->des1 = IDMAC_DES1_BS1(size - (last *
  335. DWMMC_DMA_MAX_BUFFER_SIZE));
  336. /* set next descriptor address as 0 */
  337. (desc + last)->des3 = 0;
  338. mmio_write_32(base + DWMMC_DBADDR, dw_params.desc_base);
  339. flush_dcache_range(dw_params.desc_base,
  340. desc_cnt * DWMMC_DMA_MAX_BUFFER_SIZE);
  341. return 0;
  342. }
  343. static int dw_read(int lba, uintptr_t buf, size_t size)
  344. {
  345. uint32_t data = 0;
  346. int timeout = TIMEOUT;
  347. do {
  348. data = mmio_read_32(dw_params.reg_base + DWMMC_RINTSTS);
  349. udelay(50);
  350. } while (!(data & INT_DTO) && timeout-- > 0);
  351. inv_dcache_range(buf, size);
  352. return 0;
  353. }
  354. static int dw_write(int lba, uintptr_t buf, size_t size)
  355. {
  356. return 0;
  357. }
  358. void dw_mmc_init(dw_mmc_params_t *params, struct mmc_device_info *info)
  359. {
  360. assert((params != 0) &&
  361. ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
  362. ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
  363. ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
  364. (params->desc_size > 0) &&
  365. (params->clk_rate > 0) &&
  366. ((params->bus_width == MMC_BUS_WIDTH_1) ||
  367. (params->bus_width == MMC_BUS_WIDTH_4) ||
  368. (params->bus_width == MMC_BUS_WIDTH_8)));
  369. memcpy(&dw_params, params, sizeof(dw_mmc_params_t));
  370. dw_params.mmc_dev_type = info->mmc_dev_type;
  371. mmc_init(&dw_mmc_ops, params->clk_rate, params->bus_width,
  372. params->flags, info);
  373. }