sh_sdhi.c 23 KB

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