sh_sdhi.c 23 KB

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