sh_sdhi.c 23 KB

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