sh_sdhi.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * drivers/mmc/sh_sdhi.c
  4. *
  5. * SD/MMC driver for Renesas rmobile ARM SoCs.
  6. *
  7. * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation
  8. * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
  9. * Copyright (C) 2008-2009 Renesas Solutions Corp.
  10. */
  11. #include <common.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <mmc.h>
  15. #include <dm.h>
  16. #include <part.h>
  17. #include <dm/device_compat.h>
  18. #include <linux/bitops.h>
  19. #include <linux/delay.h>
  20. #include <linux/errno.h>
  21. #include <linux/compat.h>
  22. #include <linux/io.h>
  23. #include <linux/sizes.h>
  24. #include <asm/arch/rmobile.h>
  25. #include <asm/arch/sh_sdhi.h>
  26. #include <asm/global_data.h>
  27. #include <clk.h>
  28. #define DRIVER_NAME "sh-sdhi"
  29. struct sh_sdhi_host {
  30. void __iomem *addr;
  31. int ch;
  32. int bus_shift;
  33. unsigned long quirks;
  34. unsigned char wait_int;
  35. unsigned char sd_error;
  36. unsigned char detect_waiting;
  37. unsigned char app_cmd;
  38. };
  39. static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val)
  40. {
  41. writeq(val, host->addr + (reg << host->bus_shift));
  42. }
  43. static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
  44. {
  45. return readq(host->addr + (reg << host->bus_shift));
  46. }
  47. static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
  48. {
  49. writew(val, host->addr + (reg << host->bus_shift));
  50. }
  51. static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg)
  52. {
  53. return readw(host->addr + (reg << host->bus_shift));
  54. }
  55. static void sh_sdhi_detect(struct sh_sdhi_host *host)
  56. {
  57. sh_sdhi_writew(host, SDHI_OPTION,
  58. OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION));
  59. host->detect_waiting = 0;
  60. }
  61. static int sh_sdhi_intr(void *dev_id)
  62. {
  63. struct sh_sdhi_host *host = dev_id;
  64. int state1 = 0, state2 = 0;
  65. state1 = sh_sdhi_readw(host, SDHI_INFO1);
  66. state2 = sh_sdhi_readw(host, SDHI_INFO2);
  67. debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2);
  68. /* CARD Insert */
  69. if (state1 & INFO1_CARD_IN) {
  70. sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_IN);
  71. if (!host->detect_waiting) {
  72. host->detect_waiting = 1;
  73. sh_sdhi_detect(host);
  74. }
  75. sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
  76. INFO1M_ACCESS_END | INFO1M_CARD_IN |
  77. INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
  78. return -EAGAIN;
  79. }
  80. /* CARD Removal */
  81. if (state1 & INFO1_CARD_RE) {
  82. sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_RE);
  83. if (!host->detect_waiting) {
  84. host->detect_waiting = 1;
  85. sh_sdhi_detect(host);
  86. }
  87. sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
  88. INFO1M_ACCESS_END | INFO1M_CARD_RE |
  89. INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
  90. sh_sdhi_writew(host, SDHI_SDIO_INFO1_MASK, SDIO_INFO1M_ON);
  91. sh_sdhi_writew(host, SDHI_SDIO_MODE, SDIO_MODE_OFF);
  92. return -EAGAIN;
  93. }
  94. if (state2 & INFO2_ALL_ERR) {
  95. sh_sdhi_writew(host, SDHI_INFO2,
  96. (unsigned short)~(INFO2_ALL_ERR));
  97. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  98. INFO2M_ALL_ERR |
  99. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  100. host->sd_error = 1;
  101. host->wait_int = 1;
  102. return 0;
  103. }
  104. /* Respons End */
  105. if (state1 & INFO1_RESP_END) {
  106. sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
  107. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  108. INFO1M_RESP_END |
  109. sh_sdhi_readw(host, SDHI_INFO1_MASK));
  110. host->wait_int = 1;
  111. return 0;
  112. }
  113. /* SD_BUF Read Enable */
  114. if (state2 & INFO2_BRE_ENABLE) {
  115. sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BRE_ENABLE);
  116. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  117. INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ |
  118. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  119. host->wait_int = 1;
  120. return 0;
  121. }
  122. /* SD_BUF Write Enable */
  123. if (state2 & INFO2_BWE_ENABLE) {
  124. sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BWE_ENABLE);
  125. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  126. INFO2_BWE_ENABLE | INFO2M_BUF_ILL_WRITE |
  127. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  128. host->wait_int = 1;
  129. return 0;
  130. }
  131. /* Access End */
  132. if (state1 & INFO1_ACCESS_END) {
  133. sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END);
  134. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  135. INFO1_ACCESS_END |
  136. sh_sdhi_readw(host, SDHI_INFO1_MASK));
  137. host->wait_int = 1;
  138. return 0;
  139. }
  140. return -EAGAIN;
  141. }
  142. static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host)
  143. {
  144. int timeout = 10000000;
  145. while (1) {
  146. timeout--;
  147. if (timeout < 0) {
  148. debug(DRIVER_NAME": %s timeout\n", __func__);
  149. return 0;
  150. }
  151. if (!sh_sdhi_intr(host))
  152. break;
  153. udelay(1); /* 1 usec */
  154. }
  155. return 1; /* Return value: NOT 0 = complete waiting */
  156. }
  157. static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk)
  158. {
  159. u32 clkdiv, i, timeout;
  160. if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) {
  161. printf(DRIVER_NAME": Busy state ! Cannot change the clock\n");
  162. return -EBUSY;
  163. }
  164. sh_sdhi_writew(host, SDHI_CLK_CTRL,
  165. ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL));
  166. if (clk == 0)
  167. return -EIO;
  168. clkdiv = 0x80;
  169. i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1);
  170. for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1))
  171. i <<= 1;
  172. sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv);
  173. timeout = 100000;
  174. /* Waiting for SD Bus busy to be cleared */
  175. while (timeout--) {
  176. if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
  177. break;
  178. }
  179. if (timeout)
  180. sh_sdhi_writew(host, SDHI_CLK_CTRL,
  181. CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
  182. else
  183. return -EBUSY;
  184. return 0;
  185. }
  186. static int sh_sdhi_sync_reset(struct sh_sdhi_host *host)
  187. {
  188. u32 timeout;
  189. sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_ON);
  190. sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_OFF);
  191. sh_sdhi_writew(host, SDHI_CLK_CTRL,
  192. CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL));
  193. timeout = 100000;
  194. while (timeout--) {
  195. if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY))
  196. break;
  197. udelay(100);
  198. }
  199. if (!timeout)
  200. return -EBUSY;
  201. if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
  202. sh_sdhi_writew(host, SDHI_HOST_MODE, 1);
  203. return 0;
  204. }
  205. static int sh_sdhi_error_manage(struct sh_sdhi_host *host)
  206. {
  207. unsigned short e_state1, e_state2;
  208. int ret;
  209. host->sd_error = 0;
  210. host->wait_int = 0;
  211. e_state1 = sh_sdhi_readw(host, SDHI_ERR_STS1);
  212. e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2);
  213. if (e_state2 & ERR_STS2_SYS_ERROR) {
  214. if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT)
  215. ret = -ETIMEDOUT;
  216. else
  217. ret = -EILSEQ;
  218. debug("%s: ERR_STS2 = %04x\n",
  219. DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2));
  220. sh_sdhi_sync_reset(host);
  221. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  222. INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
  223. return ret;
  224. }
  225. if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR)
  226. ret = -EILSEQ;
  227. else
  228. ret = -ETIMEDOUT;
  229. debug("%s: ERR_STS1 = %04x\n",
  230. DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1));
  231. sh_sdhi_sync_reset(host);
  232. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  233. INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
  234. return ret;
  235. }
  236. static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
  237. {
  238. long time;
  239. unsigned short blocksize, i;
  240. unsigned short *p = (unsigned short *)data->dest;
  241. u64 *q = (u64 *)data->dest;
  242. if ((unsigned long)p & 0x00000001) {
  243. debug(DRIVER_NAME": %s: The data pointer is unaligned.",
  244. __func__);
  245. return -EIO;
  246. }
  247. host->wait_int = 0;
  248. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  249. ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
  250. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  251. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  252. ~INFO1M_ACCESS_END &
  253. sh_sdhi_readw(host, SDHI_INFO1_MASK));
  254. time = sh_sdhi_wait_interrupt_flag(host);
  255. if (time == 0 || host->sd_error != 0)
  256. return sh_sdhi_error_manage(host);
  257. host->wait_int = 0;
  258. blocksize = sh_sdhi_readw(host, SDHI_SIZE);
  259. if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
  260. for (i = 0; i < blocksize / 8; i++)
  261. *q++ = sh_sdhi_readq(host, SDHI_BUF0);
  262. else
  263. for (i = 0; i < blocksize / 2; i++)
  264. *p++ = sh_sdhi_readw(host, SDHI_BUF0);
  265. time = sh_sdhi_wait_interrupt_flag(host);
  266. if (time == 0 || host->sd_error != 0)
  267. return sh_sdhi_error_manage(host);
  268. host->wait_int = 0;
  269. return 0;
  270. }
  271. static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
  272. {
  273. long time;
  274. unsigned short blocksize, i, sec;
  275. unsigned short *p = (unsigned short *)data->dest;
  276. u64 *q = (u64 *)data->dest;
  277. if ((unsigned long)p & 0x00000001) {
  278. debug(DRIVER_NAME": %s: The data pointer is unaligned.",
  279. __func__);
  280. return -EIO;
  281. }
  282. debug("%s: blocks = %d, blocksize = %d\n",
  283. __func__, data->blocks, data->blocksize);
  284. host->wait_int = 0;
  285. for (sec = 0; sec < data->blocks; sec++) {
  286. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  287. ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) &
  288. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  289. time = sh_sdhi_wait_interrupt_flag(host);
  290. if (time == 0 || host->sd_error != 0)
  291. return sh_sdhi_error_manage(host);
  292. host->wait_int = 0;
  293. blocksize = sh_sdhi_readw(host, SDHI_SIZE);
  294. if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
  295. for (i = 0; i < blocksize / 8; i++)
  296. *q++ = sh_sdhi_readq(host, SDHI_BUF0);
  297. else
  298. for (i = 0; i < blocksize / 2; i++)
  299. *p++ = sh_sdhi_readw(host, SDHI_BUF0);
  300. }
  301. return 0;
  302. }
  303. static int sh_sdhi_single_write(struct sh_sdhi_host *host,
  304. struct mmc_data *data)
  305. {
  306. long time;
  307. unsigned short blocksize, i;
  308. const unsigned short *p = (const unsigned short *)data->src;
  309. const u64 *q = (const u64 *)data->src;
  310. if ((unsigned long)p & 0x00000001) {
  311. debug(DRIVER_NAME": %s: The data pointer is unaligned.",
  312. __func__);
  313. return -EIO;
  314. }
  315. debug("%s: blocks = %d, blocksize = %d\n",
  316. __func__, data->blocks, data->blocksize);
  317. host->wait_int = 0;
  318. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  319. ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
  320. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  321. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  322. ~INFO1M_ACCESS_END &
  323. sh_sdhi_readw(host, SDHI_INFO1_MASK));
  324. time = sh_sdhi_wait_interrupt_flag(host);
  325. if (time == 0 || host->sd_error != 0)
  326. return sh_sdhi_error_manage(host);
  327. host->wait_int = 0;
  328. blocksize = sh_sdhi_readw(host, SDHI_SIZE);
  329. if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
  330. for (i = 0; i < blocksize / 8; i++)
  331. sh_sdhi_writeq(host, SDHI_BUF0, *q++);
  332. else
  333. for (i = 0; i < blocksize / 2; i++)
  334. sh_sdhi_writew(host, SDHI_BUF0, *p++);
  335. time = sh_sdhi_wait_interrupt_flag(host);
  336. if (time == 0 || host->sd_error != 0)
  337. return sh_sdhi_error_manage(host);
  338. host->wait_int = 0;
  339. return 0;
  340. }
  341. static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
  342. {
  343. long time;
  344. unsigned short i, sec, blocksize;
  345. const unsigned short *p = (const unsigned short *)data->src;
  346. const u64 *q = (const u64 *)data->src;
  347. debug("%s: blocks = %d, blocksize = %d\n",
  348. __func__, data->blocks, data->blocksize);
  349. host->wait_int = 0;
  350. for (sec = 0; sec < data->blocks; sec++) {
  351. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  352. ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) &
  353. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  354. time = sh_sdhi_wait_interrupt_flag(host);
  355. if (time == 0 || host->sd_error != 0)
  356. return sh_sdhi_error_manage(host);
  357. host->wait_int = 0;
  358. blocksize = sh_sdhi_readw(host, SDHI_SIZE);
  359. if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
  360. for (i = 0; i < blocksize / 8; i++)
  361. sh_sdhi_writeq(host, SDHI_BUF0, *q++);
  362. else
  363. for (i = 0; i < blocksize / 2; i++)
  364. sh_sdhi_writew(host, SDHI_BUF0, *p++);
  365. }
  366. return 0;
  367. }
  368. static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd)
  369. {
  370. unsigned short i, j, cnt = 1;
  371. unsigned short resp[8];
  372. if (cmd->resp_type & MMC_RSP_136) {
  373. cnt = 4;
  374. resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
  375. resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
  376. resp[2] = sh_sdhi_readw(host, SDHI_RSP02);
  377. resp[3] = sh_sdhi_readw(host, SDHI_RSP03);
  378. resp[4] = sh_sdhi_readw(host, SDHI_RSP04);
  379. resp[5] = sh_sdhi_readw(host, SDHI_RSP05);
  380. resp[6] = sh_sdhi_readw(host, SDHI_RSP06);
  381. resp[7] = sh_sdhi_readw(host, SDHI_RSP07);
  382. /* SDHI REGISTER SPECIFICATION */
  383. for (i = 7, j = 6; i > 0; i--) {
  384. resp[i] = (resp[i] << 8) & 0xff00;
  385. resp[i] |= (resp[j--] >> 8) & 0x00ff;
  386. }
  387. resp[0] = (resp[0] << 8) & 0xff00;
  388. } else {
  389. resp[0] = sh_sdhi_readw(host, SDHI_RSP00);
  390. resp[1] = sh_sdhi_readw(host, SDHI_RSP01);
  391. }
  392. #if defined(__BIG_ENDIAN_BITFIELD)
  393. if (cnt == 4) {
  394. cmd->response[0] = (resp[6] << 16) | resp[7];
  395. cmd->response[1] = (resp[4] << 16) | resp[5];
  396. cmd->response[2] = (resp[2] << 16) | resp[3];
  397. cmd->response[3] = (resp[0] << 16) | resp[1];
  398. } else {
  399. cmd->response[0] = (resp[0] << 16) | resp[1];
  400. }
  401. #else
  402. if (cnt == 4) {
  403. cmd->response[0] = (resp[7] << 16) | resp[6];
  404. cmd->response[1] = (resp[5] << 16) | resp[4];
  405. cmd->response[2] = (resp[3] << 16) | resp[2];
  406. cmd->response[3] = (resp[1] << 16) | resp[0];
  407. } else {
  408. cmd->response[0] = (resp[1] << 16) | resp[0];
  409. }
  410. #endif /* __BIG_ENDIAN_BITFIELD */
  411. }
  412. static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host,
  413. struct mmc_data *data, unsigned short opc)
  414. {
  415. if (host->app_cmd) {
  416. if (!data)
  417. host->app_cmd = 0;
  418. return opc | BIT(6);
  419. }
  420. switch (opc) {
  421. case MMC_CMD_SWITCH:
  422. return opc | (data ? 0x1c00 : 0x40);
  423. case MMC_CMD_SEND_EXT_CSD:
  424. return opc | (data ? 0x1c00 : 0);
  425. case MMC_CMD_SEND_OP_COND:
  426. return opc | 0x0700;
  427. case MMC_CMD_APP_CMD:
  428. host->app_cmd = 1;
  429. default:
  430. return opc;
  431. }
  432. }
  433. static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host,
  434. struct mmc_data *data, unsigned short opc)
  435. {
  436. if (host->app_cmd) {
  437. host->app_cmd = 0;
  438. switch (opc) {
  439. case SD_CMD_APP_SEND_SCR:
  440. case SD_CMD_APP_SD_STATUS:
  441. return sh_sdhi_single_read(host, data);
  442. default:
  443. printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n",
  444. opc);
  445. return -EINVAL;
  446. }
  447. } else {
  448. switch (opc) {
  449. case MMC_CMD_WRITE_MULTIPLE_BLOCK:
  450. return sh_sdhi_multi_write(host, data);
  451. case MMC_CMD_READ_MULTIPLE_BLOCK:
  452. return sh_sdhi_multi_read(host, data);
  453. case MMC_CMD_WRITE_SINGLE_BLOCK:
  454. return sh_sdhi_single_write(host, data);
  455. case MMC_CMD_READ_SINGLE_BLOCK:
  456. case MMC_CMD_SWITCH:
  457. case MMC_CMD_SEND_EXT_CSD:;
  458. return sh_sdhi_single_read(host, data);
  459. default:
  460. printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc);
  461. return -EINVAL;
  462. }
  463. }
  464. }
  465. static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
  466. struct mmc_data *data, struct mmc_cmd *cmd)
  467. {
  468. long time;
  469. unsigned short shcmd, opc = cmd->cmdidx;
  470. int ret = 0;
  471. unsigned long timeout;
  472. debug("opc = %d, arg = %x, resp_type = %x\n",
  473. opc, cmd->cmdarg, cmd->resp_type);
  474. if (opc == MMC_CMD_STOP_TRANSMISSION) {
  475. /* SDHI sends the STOP command automatically by STOP reg */
  476. sh_sdhi_writew(host, SDHI_INFO1_MASK, ~INFO1M_ACCESS_END &
  477. sh_sdhi_readw(host, SDHI_INFO1_MASK));
  478. time = sh_sdhi_wait_interrupt_flag(host);
  479. if (time == 0 || host->sd_error != 0)
  480. return sh_sdhi_error_manage(host);
  481. sh_sdhi_get_response(host, cmd);
  482. return 0;
  483. }
  484. if (data) {
  485. if ((opc == MMC_CMD_READ_MULTIPLE_BLOCK) ||
  486. opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) {
  487. sh_sdhi_writew(host, SDHI_STOP, STOP_SEC_ENABLE);
  488. sh_sdhi_writew(host, SDHI_SECCNT, data->blocks);
  489. }
  490. sh_sdhi_writew(host, SDHI_SIZE, data->blocksize);
  491. }
  492. shcmd = sh_sdhi_set_cmd(host, data, opc);
  493. /*
  494. * U-Boot cannot use interrupt.
  495. * So this flag may not be clear by timing
  496. */
  497. sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END);
  498. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  499. INFO1M_RESP_END | sh_sdhi_readw(host, SDHI_INFO1_MASK));
  500. sh_sdhi_writew(host, SDHI_ARG0,
  501. (unsigned short)(cmd->cmdarg & ARG0_MASK));
  502. sh_sdhi_writew(host, SDHI_ARG1,
  503. (unsigned short)((cmd->cmdarg >> 16) & ARG1_MASK));
  504. timeout = 100000;
  505. /* Waiting for SD Bus busy to be cleared */
  506. while (timeout--) {
  507. if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000))
  508. break;
  509. }
  510. host->wait_int = 0;
  511. sh_sdhi_writew(host, SDHI_INFO1_MASK,
  512. ~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK));
  513. sh_sdhi_writew(host, SDHI_INFO2_MASK,
  514. ~(INFO2M_CMD_ERROR | INFO2M_CRC_ERROR |
  515. INFO2M_END_ERROR | INFO2M_TIMEOUT |
  516. INFO2M_RESP_TIMEOUT | INFO2M_ILA) &
  517. sh_sdhi_readw(host, SDHI_INFO2_MASK));
  518. sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(shcmd & CMD_MASK));
  519. time = sh_sdhi_wait_interrupt_flag(host);
  520. if (!time) {
  521. host->app_cmd = 0;
  522. return sh_sdhi_error_manage(host);
  523. }
  524. if (host->sd_error) {
  525. switch (cmd->cmdidx) {
  526. case MMC_CMD_ALL_SEND_CID:
  527. case MMC_CMD_SELECT_CARD:
  528. case SD_CMD_SEND_IF_COND:
  529. case MMC_CMD_APP_CMD:
  530. ret = -ETIMEDOUT;
  531. break;
  532. default:
  533. debug(DRIVER_NAME": Cmd(d'%d) err\n", opc);
  534. debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx);
  535. ret = sh_sdhi_error_manage(host);
  536. break;
  537. }
  538. host->sd_error = 0;
  539. host->wait_int = 0;
  540. host->app_cmd = 0;
  541. return ret;
  542. }
  543. if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) {
  544. host->app_cmd = 0;
  545. return -EINVAL;
  546. }
  547. if (host->wait_int) {
  548. sh_sdhi_get_response(host, cmd);
  549. host->wait_int = 0;
  550. }
  551. if (data)
  552. ret = sh_sdhi_data_trans(host, data, opc);
  553. debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
  554. ret, cmd->response[0], cmd->response[1],
  555. cmd->response[2], cmd->response[3]);
  556. return ret;
  557. }
  558. static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host,
  559. struct mmc_cmd *cmd, struct mmc_data *data)
  560. {
  561. host->sd_error = 0;
  562. return sh_sdhi_start_cmd(host, data, cmd);
  563. }
  564. static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc)
  565. {
  566. int ret;
  567. ret = sh_sdhi_clock_control(host, mmc->clock);
  568. if (ret)
  569. return -EINVAL;
  570. if (mmc->bus_width == 8)
  571. sh_sdhi_writew(host, SDHI_OPTION,
  572. OPT_BUS_WIDTH_8 | (~OPT_BUS_WIDTH_M &
  573. sh_sdhi_readw(host, SDHI_OPTION)));
  574. else if (mmc->bus_width == 4)
  575. sh_sdhi_writew(host, SDHI_OPTION,
  576. OPT_BUS_WIDTH_4 | (~OPT_BUS_WIDTH_M &
  577. sh_sdhi_readw(host, SDHI_OPTION)));
  578. else
  579. sh_sdhi_writew(host, SDHI_OPTION,
  580. OPT_BUS_WIDTH_1 | (~OPT_BUS_WIDTH_M &
  581. sh_sdhi_readw(host, SDHI_OPTION)));
  582. debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
  583. return 0;
  584. }
  585. static int sh_sdhi_initialize_common(struct sh_sdhi_host *host)
  586. {
  587. int ret = sh_sdhi_sync_reset(host);
  588. sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT);
  589. #if defined(__BIG_ENDIAN_BITFIELD)
  590. sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP);
  591. #endif
  592. sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END |
  593. INFO1M_ACCESS_END | INFO1M_CARD_RE |
  594. INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN);
  595. return ret;
  596. }
  597. #ifndef CONFIG_DM_MMC
  598. static void *mmc_priv(struct mmc *mmc)
  599. {
  600. return (void *)mmc->priv;
  601. }
  602. static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
  603. struct mmc_data *data)
  604. {
  605. struct sh_sdhi_host *host = mmc_priv(mmc);
  606. return sh_sdhi_send_cmd_common(host, cmd, data);
  607. }
  608. static int sh_sdhi_set_ios(struct mmc *mmc)
  609. {
  610. struct sh_sdhi_host *host = mmc_priv(mmc);
  611. return sh_sdhi_set_ios_common(host, mmc);
  612. }
  613. static int sh_sdhi_initialize(struct mmc *mmc)
  614. {
  615. struct sh_sdhi_host *host = mmc_priv(mmc);
  616. return sh_sdhi_initialize_common(host);
  617. }
  618. static const struct mmc_ops sh_sdhi_ops = {
  619. .send_cmd = sh_sdhi_send_cmd,
  620. .set_ios = sh_sdhi_set_ios,
  621. .init = sh_sdhi_initialize,
  622. };
  623. #ifdef CONFIG_RCAR_GEN3
  624. static struct mmc_config sh_sdhi_cfg = {
  625. .name = DRIVER_NAME,
  626. .ops = &sh_sdhi_ops,
  627. .f_min = CLKDEV_INIT,
  628. .f_max = CLKDEV_HS_DATA,
  629. .voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
  630. .host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
  631. MMC_MODE_HS_52MHz,
  632. .part_type = PART_TYPE_DOS,
  633. .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
  634. };
  635. #else
  636. static struct mmc_config sh_sdhi_cfg = {
  637. .name = DRIVER_NAME,
  638. .ops = &sh_sdhi_ops,
  639. .f_min = CLKDEV_INIT,
  640. .f_max = CLKDEV_HS_DATA,
  641. .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
  642. .host_caps = MMC_MODE_4BIT | MMC_MODE_HS,
  643. .part_type = PART_TYPE_DOS,
  644. .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
  645. };
  646. #endif
  647. int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
  648. {
  649. int ret = 0;
  650. struct mmc *mmc;
  651. struct sh_sdhi_host *host = NULL;
  652. if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL)
  653. return -ENODEV;
  654. host = malloc(sizeof(struct sh_sdhi_host));
  655. if (!host)
  656. return -ENOMEM;
  657. mmc = mmc_create(&sh_sdhi_cfg, host);
  658. if (!mmc) {
  659. ret = -1;
  660. goto error;
  661. }
  662. host->ch = ch;
  663. host->addr = (void __iomem *)addr;
  664. host->quirks = quirks;
  665. if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
  666. host->bus_shift = 2;
  667. else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
  668. host->bus_shift = 1;
  669. return ret;
  670. error:
  671. free(host);
  672. return ret;
  673. }
  674. #else
  675. struct sh_sdhi_plat {
  676. struct mmc_config cfg;
  677. struct mmc mmc;
  678. };
  679. int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
  680. struct mmc_data *data)
  681. {
  682. struct sh_sdhi_host *host = dev_get_priv(dev);
  683. return sh_sdhi_send_cmd_common(host, cmd, data);
  684. }
  685. int sh_sdhi_dm_set_ios(struct udevice *dev)
  686. {
  687. struct sh_sdhi_host *host = dev_get_priv(dev);
  688. struct mmc *mmc = mmc_get_mmc_dev(dev);
  689. return sh_sdhi_set_ios_common(host, mmc);
  690. }
  691. static const struct dm_mmc_ops sh_sdhi_dm_ops = {
  692. .send_cmd = sh_sdhi_dm_send_cmd,
  693. .set_ios = sh_sdhi_dm_set_ios,
  694. };
  695. static int sh_sdhi_dm_bind(struct udevice *dev)
  696. {
  697. struct sh_sdhi_plat *plat = dev_get_plat(dev);
  698. return mmc_bind(dev, &plat->mmc, &plat->cfg);
  699. }
  700. static int sh_sdhi_dm_probe(struct udevice *dev)
  701. {
  702. struct sh_sdhi_plat *plat = dev_get_plat(dev);
  703. struct sh_sdhi_host *host = dev_get_priv(dev);
  704. struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  705. struct clk sh_sdhi_clk;
  706. const u32 quirks = dev_get_driver_data(dev);
  707. fdt_addr_t base;
  708. int ret;
  709. base = dev_read_addr(dev);
  710. if (base == FDT_ADDR_T_NONE)
  711. return -EINVAL;
  712. host->addr = devm_ioremap(dev, base, SZ_2K);
  713. if (!host->addr)
  714. return -ENOMEM;
  715. ret = clk_get_by_index(dev, 0, &sh_sdhi_clk);
  716. if (ret) {
  717. debug("failed to get clock, ret=%d\n", ret);
  718. return ret;
  719. }
  720. ret = clk_enable(&sh_sdhi_clk);
  721. if (ret) {
  722. debug("failed to enable clock, ret=%d\n", ret);
  723. return ret;
  724. }
  725. host->quirks = quirks;
  726. if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
  727. host->bus_shift = 2;
  728. else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
  729. host->bus_shift = 1;
  730. plat->cfg.name = dev->name;
  731. plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
  732. switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
  733. 1)) {
  734. case 8:
  735. plat->cfg.host_caps |= MMC_MODE_8BIT;
  736. break;
  737. case 4:
  738. plat->cfg.host_caps |= MMC_MODE_4BIT;
  739. break;
  740. case 1:
  741. break;
  742. default:
  743. dev_err(dev, "Invalid \"bus-width\" value\n");
  744. return -EINVAL;
  745. }
  746. sh_sdhi_initialize_common(host);
  747. plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
  748. plat->cfg.f_min = CLKDEV_INIT;
  749. plat->cfg.f_max = CLKDEV_HS_DATA;
  750. plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  751. upriv->mmc = &plat->mmc;
  752. return 0;
  753. }
  754. static const struct udevice_id sh_sdhi_sd_match[] = {
  755. { .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF },
  756. { .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF },
  757. { /* sentinel */ }
  758. };
  759. U_BOOT_DRIVER(sh_sdhi_mmc) = {
  760. .name = "sh-sdhi-mmc",
  761. .id = UCLASS_MMC,
  762. .of_match = sh_sdhi_sd_match,
  763. .bind = sh_sdhi_dm_bind,
  764. .probe = sh_sdhi_dm_probe,
  765. .priv_auto = sizeof(struct sh_sdhi_host),
  766. .plat_auto = sizeof(struct sh_sdhi_plat),
  767. .ops = &sh_sdhi_dm_ops,
  768. };
  769. #endif