0019-mmc-mmc_spi-Re-write-driver-using-DM-framework.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. From 250c07102bfb556093f26fd4b4e1a16c8e5df9db Mon Sep 17 00:00:00 2001
  2. From: Bhargav Shah <bhargavshah1988@gmail.com>
  3. Date: Mon, 24 Jun 2019 09:30:28 +0530
  4. Subject: [PATCH 19/21] mmc: mmc_spi: Re-write driver using DM framework
  5. This patch rewrites MMC SPI driver using U-Boot DM
  6. framework and get it's working on SiFive Unleashed
  7. board.
  8. Signed-off-by: Bhargav Shah <bhargavshah1988@gmail.com>
  9. Signed-off-by: Anup Patel <anup.patel@wdc.com>
  10. Upstream-Status: Submitted
  11. ---
  12. drivers/mmc/Kconfig | 18 ++
  13. drivers/mmc/mmc_spi.c | 469 +++++++++++++++++++++++++++---------------
  14. 2 files changed, 320 insertions(+), 167 deletions(-)
  15. diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
  16. index c23299ea96..f750dad00a 100644
  17. --- a/drivers/mmc/Kconfig
  18. +++ b/drivers/mmc/Kconfig
  19. @@ -46,6 +46,24 @@ config SPL_DM_MMC
  20. if MMC
  21. +config MMC_SPI
  22. + bool "Support for SPI-based MMC controller"
  23. + depends on DM_MMC && DM_SPI
  24. + help
  25. + This selects SPI-based MMC controllers.
  26. + If you have an MMC controller on a SPI bus, say Y here.
  27. +
  28. + If unsure, say N.
  29. +
  30. +config MMC_SPI_CRC_ON
  31. + bool "Support CRC for SPI-based MMC controller"
  32. + depends on MMC_SPI
  33. + default y
  34. + help
  35. + This enables CRC for SPI-based MMC controllers.
  36. +
  37. + If unsure, say N.
  38. +
  39. config ARM_PL180_MMCI
  40. bool "ARM AMBA Multimedia Card Interface and compatible support"
  41. depends on DM_MMC && OF_CONTROL
  42. diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
  43. index 4f57990d9c..f3d687ae80 100644
  44. --- a/drivers/mmc/mmc_spi.c
  45. +++ b/drivers/mmc/mmc_spi.c
  46. @@ -2,6 +2,8 @@
  47. * generic mmc spi driver
  48. *
  49. * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
  50. + * Copyright 2019 Bhargav Shah <bhargavshah1988@gmail.com>
  51. + *
  52. * Licensed under the GPL-2 or later.
  53. */
  54. #include <common.h>
  55. @@ -9,21 +11,23 @@
  56. #include <malloc.h>
  57. #include <part.h>
  58. #include <mmc.h>
  59. -#include <spi.h>
  60. +#include <stdlib.h>
  61. #include <u-boot/crc.h>
  62. #include <linux/crc7.h>
  63. #include <asm/byteorder.h>
  64. +#include <dm.h>
  65. +#include <spi.h>
  66. /* MMC/SD in SPI mode reports R1 status always */
  67. -#define R1_SPI_IDLE (1 << 0)
  68. -#define R1_SPI_ERASE_RESET (1 << 1)
  69. -#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
  70. -#define R1_SPI_COM_CRC (1 << 3)
  71. -#define R1_SPI_ERASE_SEQ (1 << 4)
  72. -#define R1_SPI_ADDRESS (1 << 5)
  73. -#define R1_SPI_PARAMETER (1 << 6)
  74. +#define R1_SPI_IDLE BIT(0)
  75. +#define R1_SPI_ERASE_RESET BIT(1)
  76. +#define R1_SPI_ILLEGAL_COMMAND BIT(2)
  77. +#define R1_SPI_COM_CRC BIT(3)
  78. +#define R1_SPI_ERASE_SEQ BIT(4)
  79. +#define R1_SPI_ADDRESS BIT(5)
  80. +#define R1_SPI_PARAMETER BIT(6)
  81. /* R1 bit 7 is always zero, reuse this bit for error */
  82. -#define R1_SPI_ERROR (1 << 7)
  83. +#define R1_SPI_ERROR BIT(7)
  84. /* Response tokens used to ack each block written: */
  85. #define SPI_MMC_RESPONSE_CODE(x) ((x) & 0x1f)
  86. @@ -34,28 +38,45 @@
  87. /* Read and write blocks start with these tokens and end with crc;
  88. * on error, read tokens act like a subset of R2_SPI_* values.
  89. */
  90. -#define SPI_TOKEN_SINGLE 0xfe /* single block r/w, multiblock read */
  91. -#define SPI_TOKEN_MULTI_WRITE 0xfc /* multiblock write */
  92. -#define SPI_TOKEN_STOP_TRAN 0xfd /* terminate multiblock write */
  93. +/* single block write multiblock read */
  94. +#define SPI_TOKEN_SINGLE 0xfe
  95. +/* multiblock write */
  96. +#define SPI_TOKEN_MULTI_WRITE 0xfc
  97. +/* terminate multiblock write */
  98. +#define SPI_TOKEN_STOP_TRAN 0xfd
  99. /* MMC SPI commands start with a start bit "0" and a transmit bit "1" */
  100. -#define MMC_SPI_CMD(x) (0x40 | (x & 0x3f))
  101. +#define MMC_SPI_CMD(x) (0x40 | (x))
  102. /* bus capability */
  103. -#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34)
  104. -#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */
  105. +#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34)
  106. +#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */
  107. +#define MMC_SPI_MAX_CLOCK 25000000 /* SD/MMC legacy speed */
  108. /* timeout value */
  109. -#define CTOUT 8
  110. -#define RTOUT 3000000 /* 1 sec */
  111. -#define WTOUT 3000000 /* 1 sec */
  112. +#define CMD_TIMEOUT 8
  113. +#define READ_TIMEOUT 3000000 /* 1 sec */
  114. +#define WRITE_TIMEOUT 3000000 /* 1 sec */
  115. -static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
  116. +struct mmc_spi_priv {
  117. + struct spi_slave *spi;
  118. + struct mmc_config cfg;
  119. + struct mmc mmc;
  120. +};
  121. +
  122. +static int mmc_spi_sendcmd(struct udevice *dev,
  123. + ushort cmdidx, u32 cmdarg, u32 resp_type,
  124. + u8 *resp, u32 resp_size,
  125. + bool resp_match, u8 resp_match_value)
  126. {
  127. - struct spi_slave *spi = mmc->priv;
  128. - u8 cmdo[7];
  129. - u8 r1;
  130. - int i;
  131. + int i, rpos = 0, ret = 0;
  132. + u8 cmdo[7], r;
  133. +
  134. + debug("%s: cmd%d cmdarg=0x%x resp_type=0x%x "
  135. + "resp_size=%d resp_match=%d resp_match_value=0x%x\n",
  136. + __func__, cmdidx, cmdarg, resp_type,
  137. + resp_size, resp_match, resp_match_value);
  138. +
  139. cmdo[0] = 0xff;
  140. cmdo[1] = MMC_SPI_CMD(cmdidx);
  141. cmdo[2] = cmdarg >> 24;
  142. @@ -63,37 +84,79 @@ static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
  143. cmdo[4] = cmdarg >> 8;
  144. cmdo[5] = cmdarg;
  145. cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01;
  146. - spi_xfer(spi, sizeof(cmdo) * 8, cmdo, NULL, 0);
  147. - for (i = 0; i < CTOUT; i++) {
  148. - spi_xfer(spi, 1 * 8, NULL, &r1, 0);
  149. - if (i && (r1 & 0x80) == 0) /* r1 response */
  150. - break;
  151. + ret = dm_spi_xfer(dev, sizeof(cmdo) * 8, cmdo, NULL, 0);
  152. + if (ret)
  153. + return ret;
  154. +
  155. + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
  156. + if (ret)
  157. + return ret;
  158. +
  159. + if (!resp || !resp_size)
  160. + return 0;
  161. +
  162. + debug("%s: cmd%d", __func__, cmdidx);
  163. +
  164. + if (resp_match) {
  165. + r = ~resp_match_value;
  166. + i = CMD_TIMEOUT;
  167. + while (i--) {
  168. + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
  169. + if (ret)
  170. + return ret;
  171. + debug(" resp%d=0x%x", rpos, r);
  172. + rpos++;
  173. + if (r == resp_match_value)
  174. + break;
  175. + }
  176. + if (!i && (r != resp_match_value))
  177. + return -ETIMEDOUT;
  178. + }
  179. +
  180. + for (i = 0; i < resp_size; i++) {
  181. + if (i == 0 && resp_match) {
  182. + resp[i] = resp_match_value;
  183. + continue;
  184. + }
  185. + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
  186. + if (ret)
  187. + return ret;
  188. + debug(" resp%d=0x%x", rpos, r);
  189. + rpos++;
  190. + resp[i] = r;
  191. }
  192. - debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1);
  193. - return r1;
  194. +
  195. + debug("\n");
  196. +
  197. + return 0;
  198. }
  199. -static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
  200. - u32 bcnt, u32 bsize)
  201. +static int mmc_spi_readdata(struct udevice *dev,
  202. + void *xbuf, u32 bcnt, u32 bsize)
  203. {
  204. - struct spi_slave *spi = mmc->priv;
  205. - u8 *buf = xbuf;
  206. - u8 r1;
  207. u16 crc;
  208. - int i;
  209. + u8 *buf = xbuf, r1;
  210. + int i, ret = 0;
  211. +
  212. while (bcnt--) {
  213. - for (i = 0; i < RTOUT; i++) {
  214. - spi_xfer(spi, 1 * 8, NULL, &r1, 0);
  215. - if (r1 != 0xff) /* data token */
  216. + for (i = 0; i < READ_TIMEOUT; i++) {
  217. + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
  218. + if (ret)
  219. + return ret;
  220. + if (r1 == SPI_TOKEN_SINGLE)
  221. break;
  222. }
  223. - debug("%s:tok%d %x\n", __func__, i, r1);
  224. + debug("%s: data tok%d 0x%x\n", __func__, i, r1);
  225. if (r1 == SPI_TOKEN_SINGLE) {
  226. - spi_xfer(spi, bsize * 8, NULL, buf, 0);
  227. - spi_xfer(spi, 2 * 8, NULL, &crc, 0);
  228. + ret = dm_spi_xfer(dev, bsize * 8, NULL, buf, 0);
  229. + if (ret)
  230. + return ret;
  231. + ret = dm_spi_xfer(dev, 2 * 8, NULL, &crc, 0);
  232. + if (ret)
  233. + return ret;
  234. #ifdef CONFIG_MMC_SPI_CRC_ON
  235. - if (be_to_cpu16(crc16_ccitt(0, buf, bsize)) != crc) {
  236. - debug("%s: CRC error\n", mmc->cfg->name);
  237. + if (be16_to_cpu(crc16_ccitt(0, buf, bsize)) != crc) {
  238. + debug("%s: data crc error\n", __func__);
  239. r1 = R1_SPI_COM_CRC;
  240. break;
  241. }
  242. @@ -105,48 +168,56 @@ static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
  243. }
  244. buf += bsize;
  245. }
  246. - return r1;
  247. +
  248. + if (r1 & R1_SPI_COM_CRC)
  249. + ret = -ECOMM;
  250. + else if (r1) /* other errors */
  251. + ret = -ETIMEDOUT;
  252. +
  253. + return ret;
  254. }
  255. -static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
  256. - u32 bcnt, u32 bsize, int multi)
  257. +static int mmc_spi_writedata(struct udevice *dev, const void *xbuf,
  258. + u32 bcnt, u32 bsize, int multi)
  259. {
  260. - struct spi_slave *spi = mmc->priv;
  261. const u8 *buf = xbuf;
  262. - u8 r1;
  263. + u8 r1, tok[2];
  264. u16 crc;
  265. - u8 tok[2];
  266. - int i;
  267. + int i, ret = 0;
  268. +
  269. tok[0] = 0xff;
  270. tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
  271. +
  272. while (bcnt--) {
  273. #ifdef CONFIG_MMC_SPI_CRC_ON
  274. crc = cpu_to_be16(crc16_ccitt(0, (u8 *)buf, bsize));
  275. #endif
  276. - spi_xfer(spi, 2 * 8, tok, NULL, 0);
  277. - spi_xfer(spi, bsize * 8, buf, NULL, 0);
  278. - spi_xfer(spi, 2 * 8, &crc, NULL, 0);
  279. - for (i = 0; i < CTOUT; i++) {
  280. - spi_xfer(spi, 1 * 8, NULL, &r1, 0);
  281. + dm_spi_xfer(dev, 2 * 8, tok, NULL, 0);
  282. + dm_spi_xfer(dev, bsize * 8, buf, NULL, 0);
  283. + dm_spi_xfer(dev, 2 * 8, &crc, NULL, 0);
  284. + for (i = 0; i < CMD_TIMEOUT; i++) {
  285. + dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
  286. if ((r1 & 0x10) == 0) /* response token */
  287. break;
  288. }
  289. - debug("%s:tok%d %x\n", __func__, i, r1);
  290. + debug("%s: data tok%d 0x%x\n", __func__, i, r1);
  291. if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
  292. - for (i = 0; i < WTOUT; i++) { /* wait busy */
  293. - spi_xfer(spi, 1 * 8, NULL, &r1, 0);
  294. + debug("%s: data accepted\n", __func__);
  295. + for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */
  296. + dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
  297. if (i && r1 == 0xff) {
  298. r1 = 0;
  299. break;
  300. }
  301. }
  302. - if (i == WTOUT) {
  303. - debug("%s:wtout %x\n", __func__, r1);
  304. + if (i == WRITE_TIMEOUT) {
  305. + debug("%s: data write timeout 0x%x\n",
  306. + __func__, r1);
  307. r1 = R1_SPI_ERROR;
  308. break;
  309. }
  310. } else {
  311. - debug("%s: err %x\n", __func__, r1);
  312. + debug("%s: data error 0x%x\n", __func__, r1);
  313. r1 = R1_SPI_COM_CRC;
  314. break;
  315. }
  316. @@ -154,140 +225,204 @@ static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
  317. }
  318. if (multi && bcnt == -1) { /* stop multi write */
  319. tok[1] = SPI_TOKEN_STOP_TRAN;
  320. - spi_xfer(spi, 2 * 8, tok, NULL, 0);
  321. - for (i = 0; i < WTOUT; i++) { /* wait busy */
  322. - spi_xfer(spi, 1 * 8, NULL, &r1, 0);
  323. + dm_spi_xfer(dev, 2 * 8, tok, NULL, 0);
  324. + for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */
  325. + dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
  326. if (i && r1 == 0xff) {
  327. r1 = 0;
  328. break;
  329. }
  330. }
  331. - if (i == WTOUT) {
  332. - debug("%s:wstop %x\n", __func__, r1);
  333. + if (i == WRITE_TIMEOUT) {
  334. + debug("%s: data write timeout 0x%x\n", __func__, r1);
  335. r1 = R1_SPI_ERROR;
  336. }
  337. }
  338. - return r1;
  339. -}
  340. -static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
  341. - struct mmc_data *data)
  342. -{
  343. - struct spi_slave *spi = mmc->priv;
  344. - u8 r1;
  345. - int i;
  346. - int ret = 0;
  347. - debug("%s:cmd%d %x %x\n", __func__,
  348. - cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
  349. - spi_claim_bus(spi);
  350. - spi_cs_activate(spi);
  351. - r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg);
  352. - if (r1 == 0xff) { /* no response */
  353. - ret = -ENOMEDIUM;
  354. - goto done;
  355. - } else if (r1 & R1_SPI_COM_CRC) {
  356. + if (r1 & R1_SPI_COM_CRC)
  357. ret = -ECOMM;
  358. - goto done;
  359. - } else if (r1 & ~R1_SPI_IDLE) { /* other errors */
  360. + else if (r1) /* other errors */
  361. ret = -ETIMEDOUT;
  362. +
  363. + return ret;
  364. +}
  365. +
  366. +static int dm_mmc_spi_set_ios(struct udevice *dev)
  367. +{
  368. + return 0;
  369. +}
  370. +
  371. +static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
  372. + struct mmc_data *data)
  373. +{
  374. + int i, multi, ret = 0;
  375. + u8 *resp = NULL;
  376. + u32 resp_size = 0;
  377. + bool resp_match = false;
  378. + u8 resp8 = 0, resp40[5] = { 0 }, resp_match_value = 0;
  379. +
  380. + dm_spi_claim_bus(dev);
  381. +
  382. + for (i = 0; i < 4; i++)
  383. + cmd->response[i] = 0;
  384. +
  385. + switch (cmd->cmdidx) {
  386. + case SD_CMD_APP_SEND_OP_COND:
  387. + case MMC_CMD_SEND_OP_COND:
  388. + resp = &resp8;
  389. + resp_size = sizeof(resp8);
  390. + cmd->cmdarg = 0x40000000;
  391. + break;
  392. + case SD_CMD_SEND_IF_COND:
  393. + resp = (u8 *)&resp40[0];
  394. + resp_size = sizeof(resp40);
  395. + resp_match = true;
  396. + resp_match_value = R1_SPI_IDLE;
  397. + break;
  398. + case MMC_CMD_SPI_READ_OCR:
  399. + resp = (u8 *)&resp40[0];
  400. + resp_size = sizeof(resp40);
  401. + break;
  402. + case MMC_CMD_SEND_STATUS:
  403. + case MMC_CMD_SET_BLOCKLEN:
  404. + case MMC_CMD_SPI_CRC_ON_OFF:
  405. + case MMC_CMD_STOP_TRANSMISSION:
  406. + resp = &resp8;
  407. + resp_size = sizeof(resp8);
  408. + resp_match = true;
  409. + resp_match_value = 0x0;
  410. + break;
  411. + case MMC_CMD_SEND_CSD:
  412. + case MMC_CMD_SEND_CID:
  413. + case MMC_CMD_READ_SINGLE_BLOCK:
  414. + case MMC_CMD_READ_MULTIPLE_BLOCK:
  415. + case MMC_CMD_WRITE_SINGLE_BLOCK:
  416. + case MMC_CMD_WRITE_MULTIPLE_BLOCK:
  417. + break;
  418. + default:
  419. + resp = &resp8;
  420. + resp_size = sizeof(resp8);
  421. + resp_match = true;
  422. + resp_match_value = R1_SPI_IDLE;
  423. + break;
  424. + };
  425. +
  426. + ret = mmc_spi_sendcmd(dev, cmd->cmdidx, cmd->cmdarg, cmd->resp_type,
  427. + resp, resp_size, resp_match, resp_match_value);
  428. + if (ret)
  429. goto done;
  430. - } else if (cmd->resp_type == MMC_RSP_R2) {
  431. - r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16);
  432. +
  433. + switch (cmd->cmdidx) {
  434. + case SD_CMD_APP_SEND_OP_COND:
  435. + case MMC_CMD_SEND_OP_COND:
  436. + cmd->response[0] = (resp8 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
  437. + break;
  438. + case SD_CMD_SEND_IF_COND:
  439. + case MMC_CMD_SPI_READ_OCR:
  440. + cmd->response[0] = resp40[4];
  441. + cmd->response[0] |= (uint)resp40[3] << 8;
  442. + cmd->response[0] |= (uint)resp40[2] << 16;
  443. + cmd->response[0] |= (uint)resp40[1] << 24;
  444. + break;
  445. + case MMC_CMD_SEND_STATUS:
  446. + cmd->response[0] = (resp8 & 0xff) ?
  447. + MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
  448. + break;
  449. + case MMC_CMD_SEND_CID:
  450. + case MMC_CMD_SEND_CSD:
  451. + ret = mmc_spi_readdata(dev, cmd->response, 1, 16);
  452. + if (ret)
  453. + return ret;
  454. for (i = 0; i < 4; i++)
  455. - cmd->response[i] = be32_to_cpu(cmd->response[i]);
  456. - debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],
  457. - cmd->response[2], cmd->response[3]);
  458. - } else if (!data) {
  459. - switch (cmd->cmdidx) {
  460. - case SD_CMD_APP_SEND_OP_COND:
  461. - case MMC_CMD_SEND_OP_COND:
  462. - cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
  463. - break;
  464. - case SD_CMD_SEND_IF_COND:
  465. - case MMC_CMD_SPI_READ_OCR:
  466. - spi_xfer(spi, 4 * 8, NULL, cmd->response, 0);
  467. - cmd->response[0] = be32_to_cpu(cmd->response[0]);
  468. - debug("r32 %x\n", cmd->response[0]);
  469. - break;
  470. - case MMC_CMD_SEND_STATUS:
  471. - spi_xfer(spi, 1 * 8, NULL, cmd->response, 0);
  472. - cmd->response[0] = (cmd->response[0] & 0xff) ?
  473. - MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
  474. - break;
  475. - }
  476. - } else {
  477. - debug("%s:data %x %x %x\n", __func__,
  478. - data->flags, data->blocks, data->blocksize);
  479. + cmd->response[i] =
  480. + cpu_to_be32(cmd->response[i]);
  481. + break;
  482. + default:
  483. + cmd->response[0] = resp8;
  484. + break;
  485. + }
  486. +
  487. + debug("%s: cmd%d resp0=0x%x resp1=0x%x resp2=0x%x resp3=0x%x\n",
  488. + __func__, cmd->cmdidx, cmd->response[0], cmd->response[1],
  489. + cmd->response[2], cmd->response[3]);
  490. +
  491. + if (data) {
  492. + debug("%s: data flags=0x%x blocks=%d block_size=%d\n",
  493. + __func__, data->flags, data->blocks, data->blocksize);
  494. + multi = (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK);
  495. if (data->flags == MMC_DATA_READ)
  496. - r1 = mmc_spi_readdata(mmc, data->dest,
  497. - data->blocks, data->blocksize);
  498. + ret = mmc_spi_readdata(dev, data->dest,
  499. + data->blocks, data->blocksize);
  500. else if (data->flags == MMC_DATA_WRITE)
  501. - r1 = mmc_spi_writedata(mmc, data->src,
  502. - data->blocks, data->blocksize,
  503. - (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
  504. - if (r1 & R1_SPI_COM_CRC)
  505. - ret = -ECOMM;
  506. - else if (r1) /* other errors */
  507. - ret = -ETIMEDOUT;
  508. + ret = mmc_spi_writedata(dev, data->src,
  509. + data->blocks, data->blocksize,
  510. + multi);
  511. }
  512. +
  513. done:
  514. - spi_cs_deactivate(spi);
  515. - spi_release_bus(spi);
  516. + dm_spi_release_bus(dev);
  517. +
  518. return ret;
  519. }
  520. -static int mmc_spi_set_ios(struct mmc *mmc)
  521. +static int mmc_spi_probe(struct udevice *dev)
  522. {
  523. - struct spi_slave *spi = mmc->priv;
  524. + struct mmc_spi_priv *priv = dev_get_priv(dev);
  525. + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  526. + char *name;
  527. +
  528. + priv->spi = dev_get_parent_priv(dev);
  529. + if (!priv->spi->max_hz)
  530. + priv->spi->max_hz = MMC_SPI_MAX_CLOCK;
  531. + priv->spi->speed = 0;
  532. + priv->spi->mode = SPI_MODE_0;
  533. + priv->spi->wordlen = 8;
  534. +
  535. + name = malloc(strlen(dev->parent->name) + strlen(dev->name) + 4);
  536. + if (!name)
  537. + return -ENOMEM;
  538. + sprintf(name, "%s:%s", dev->parent->name, dev->name);
  539. +
  540. + priv->cfg.name = name;
  541. + priv->cfg.host_caps = MMC_MODE_SPI;
  542. + priv->cfg.voltages = MMC_SPI_VOLTAGE;
  543. + priv->cfg.f_min = MMC_SPI_MIN_CLOCK;
  544. + priv->cfg.f_max = priv->spi->max_hz;
  545. + priv->cfg.part_type = PART_TYPE_DOS;
  546. + priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  547. +
  548. + priv->mmc.cfg = &priv->cfg;
  549. + priv->mmc.priv = priv;
  550. + priv->mmc.dev = dev;
  551. +
  552. + upriv->mmc = &priv->mmc;
  553. - debug("%s: clock %u\n", __func__, mmc->clock);
  554. - if (mmc->clock)
  555. - spi_set_speed(spi, mmc->clock);
  556. return 0;
  557. }
  558. -static int mmc_spi_init_p(struct mmc *mmc)
  559. +static int mmc_spi_bind(struct udevice *dev)
  560. {
  561. - struct spi_slave *spi = mmc->priv;
  562. - spi_set_speed(spi, MMC_SPI_MIN_CLOCK);
  563. - spi_claim_bus(spi);
  564. - /* cs deactivated for 100+ clock */
  565. - spi_xfer(spi, 18 * 8, NULL, NULL, 0);
  566. - spi_release_bus(spi);
  567. - return 0;
  568. + struct mmc_spi_priv *priv = dev_get_priv(dev);
  569. +
  570. + return mmc_bind(dev, &priv->mmc, &priv->cfg);
  571. }
  572. -static const struct mmc_ops mmc_spi_ops = {
  573. - .send_cmd = mmc_spi_request,
  574. - .set_ios = mmc_spi_set_ios,
  575. - .init = mmc_spi_init_p,
  576. +static const struct dm_mmc_ops mmc_spi_ops = {
  577. + .send_cmd = dm_mmc_spi_request,
  578. + .set_ios = dm_mmc_spi_set_ios,
  579. };
  580. -static struct mmc_config mmc_spi_cfg = {
  581. - .name = "MMC_SPI",
  582. - .ops = &mmc_spi_ops,
  583. - .host_caps = MMC_MODE_SPI,
  584. - .voltages = MMC_SPI_VOLTAGE,
  585. - .f_min = MMC_SPI_MIN_CLOCK,
  586. - .part_type = PART_TYPE_DOS,
  587. - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
  588. +static const struct udevice_id dm_mmc_spi_match[] = {
  589. + { .compatible = "mmc-spi-slot" },
  590. + { /* sentinel */ }
  591. };
  592. -struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
  593. -{
  594. - struct mmc *mmc;
  595. - struct spi_slave *spi;
  596. -
  597. - spi = spi_setup_slave(bus, cs, speed, mode);
  598. - if (spi == NULL)
  599. - return NULL;
  600. -
  601. - mmc_spi_cfg.f_max = speed;
  602. -
  603. - mmc = mmc_create(&mmc_spi_cfg, spi);
  604. - if (mmc == NULL) {
  605. - spi_free_slave(spi);
  606. - return NULL;
  607. - }
  608. - return mmc;
  609. -}
  610. +U_BOOT_DRIVER(mmc_spi) = {
  611. + .name = "mmc_spi",
  612. + .id = UCLASS_MMC,
  613. + .of_match = dm_mmc_spi_match,
  614. + .ops = &mmc_spi_ops,
  615. + .probe = mmc_spi_probe,
  616. + .bind = mmc_spi_bind,
  617. + .priv_auto_alloc_size = sizeof(struct mmc_spi_priv),
  618. +};
  619. --
  620. 2.22.0