arm_pl180_mmci.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*
  2. * ARM PrimeCell MultiMedia Card Interface - PL180
  3. *
  4. * Copyright (C) ST-Ericsson SA 2010
  5. *
  6. * Author: Ulf Hansson <ulf.hansson@stericsson.com>
  7. * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
  8. * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org>
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. /* #define DEBUG */
  13. #include "common.h"
  14. #include <clk.h>
  15. #include <errno.h>
  16. #include <malloc.h>
  17. #include <mmc.h>
  18. #include <asm/io.h>
  19. #include <asm-generic/gpio.h>
  20. #include "arm_pl180_mmci.h"
  21. #ifdef CONFIG_DM_MMC
  22. #include <dm.h>
  23. DECLARE_GLOBAL_DATA_PTR;
  24. #define MMC_CLOCK_MAX 48000000
  25. #define MMC_CLOCK_MIN 400000
  26. struct arm_pl180_mmc_plat {
  27. struct mmc_config cfg;
  28. struct mmc mmc;
  29. };
  30. #endif
  31. static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
  32. {
  33. u32 hoststatus, statusmask;
  34. struct pl180_mmc_host *host = dev->priv;
  35. statusmask = SDI_STA_CTIMEOUT | SDI_STA_CCRCFAIL;
  36. if ((cmd->resp_type & MMC_RSP_PRESENT))
  37. statusmask |= SDI_STA_CMDREND;
  38. else
  39. statusmask |= SDI_STA_CMDSENT;
  40. do
  41. hoststatus = readl(&host->base->status) & statusmask;
  42. while (!hoststatus);
  43. writel(statusmask, &host->base->status_clear);
  44. if (hoststatus & SDI_STA_CTIMEOUT) {
  45. debug("CMD%d time out\n", cmd->cmdidx);
  46. return -ETIMEDOUT;
  47. } else if ((hoststatus & SDI_STA_CCRCFAIL) &&
  48. (cmd->resp_type & MMC_RSP_CRC)) {
  49. printf("CMD%d CRC error\n", cmd->cmdidx);
  50. return -EILSEQ;
  51. }
  52. if (cmd->resp_type & MMC_RSP_PRESENT) {
  53. cmd->response[0] = readl(&host->base->response0);
  54. cmd->response[1] = readl(&host->base->response1);
  55. cmd->response[2] = readl(&host->base->response2);
  56. cmd->response[3] = readl(&host->base->response3);
  57. debug("CMD%d response[0]:0x%08X, response[1]:0x%08X, "
  58. "response[2]:0x%08X, response[3]:0x%08X\n",
  59. cmd->cmdidx, cmd->response[0], cmd->response[1],
  60. cmd->response[2], cmd->response[3]);
  61. }
  62. return 0;
  63. }
  64. /* send command to the mmc card and wait for results */
  65. static int do_command(struct mmc *dev, struct mmc_cmd *cmd)
  66. {
  67. int result;
  68. u32 sdi_cmd = 0;
  69. struct pl180_mmc_host *host = dev->priv;
  70. sdi_cmd = ((cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN);
  71. if (cmd->resp_type) {
  72. sdi_cmd |= SDI_CMD_WAITRESP;
  73. if (cmd->resp_type & MMC_RSP_136)
  74. sdi_cmd |= SDI_CMD_LONGRESP;
  75. }
  76. writel((u32)cmd->cmdarg, &host->base->argument);
  77. udelay(COMMAND_REG_DELAY);
  78. writel(sdi_cmd, &host->base->command);
  79. result = wait_for_command_end(dev, cmd);
  80. /* After CMD2 set RCA to a none zero value. */
  81. if ((result == 0) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID))
  82. dev->rca = 10;
  83. /* After CMD3 open drain is switched off and push pull is used. */
  84. if ((result == 0) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) {
  85. u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD;
  86. writel(sdi_pwr, &host->base->power);
  87. }
  88. return result;
  89. }
  90. static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize)
  91. {
  92. u32 *tempbuff = dest;
  93. u64 xfercount = blkcount * blksize;
  94. struct pl180_mmc_host *host = dev->priv;
  95. u32 status, status_err;
  96. debug("read_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
  97. status = readl(&host->base->status);
  98. status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT |
  99. SDI_STA_RXOVERR);
  100. while ((!status_err) && (xfercount >= sizeof(u32))) {
  101. if (status & SDI_STA_RXDAVL) {
  102. *(tempbuff) = readl(&host->base->fifo);
  103. tempbuff++;
  104. xfercount -= sizeof(u32);
  105. }
  106. status = readl(&host->base->status);
  107. status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT |
  108. SDI_STA_RXOVERR);
  109. }
  110. status_err = status &
  111. (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND |
  112. SDI_STA_RXOVERR);
  113. while (!status_err) {
  114. status = readl(&host->base->status);
  115. status_err = status &
  116. (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND |
  117. SDI_STA_RXOVERR);
  118. }
  119. if (status & SDI_STA_DTIMEOUT) {
  120. printf("Read data timed out, xfercount: %llu, status: 0x%08X\n",
  121. xfercount, status);
  122. return -ETIMEDOUT;
  123. } else if (status & SDI_STA_DCRCFAIL) {
  124. printf("Read data bytes CRC error: 0x%x\n", status);
  125. return -EILSEQ;
  126. } else if (status & SDI_STA_RXOVERR) {
  127. printf("Read data RX overflow error\n");
  128. return -EIO;
  129. }
  130. writel(SDI_ICR_MASK, &host->base->status_clear);
  131. if (xfercount) {
  132. printf("Read data error, xfercount: %llu\n", xfercount);
  133. return -ENOBUFS;
  134. }
  135. return 0;
  136. }
  137. static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize)
  138. {
  139. u32 *tempbuff = src;
  140. int i;
  141. u64 xfercount = blkcount * blksize;
  142. struct pl180_mmc_host *host = dev->priv;
  143. u32 status, status_err;
  144. debug("write_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
  145. status = readl(&host->base->status);
  146. status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
  147. while (!status_err && xfercount) {
  148. if (status & SDI_STA_TXFIFOBW) {
  149. if (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32)) {
  150. for (i = 0; i < SDI_FIFO_BURST_SIZE; i++)
  151. writel(*(tempbuff + i),
  152. &host->base->fifo);
  153. tempbuff += SDI_FIFO_BURST_SIZE;
  154. xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32);
  155. } else {
  156. while (xfercount >= sizeof(u32)) {
  157. writel(*(tempbuff), &host->base->fifo);
  158. tempbuff++;
  159. xfercount -= sizeof(u32);
  160. }
  161. }
  162. }
  163. status = readl(&host->base->status);
  164. status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
  165. }
  166. status_err = status &
  167. (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
  168. while (!status_err) {
  169. status = readl(&host->base->status);
  170. status_err = status &
  171. (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
  172. }
  173. if (status & SDI_STA_DTIMEOUT) {
  174. printf("Write data timed out, xfercount:%llu,status:0x%08X\n",
  175. xfercount, status);
  176. return -ETIMEDOUT;
  177. } else if (status & SDI_STA_DCRCFAIL) {
  178. printf("Write data CRC error\n");
  179. return -EILSEQ;
  180. }
  181. writel(SDI_ICR_MASK, &host->base->status_clear);
  182. if (xfercount) {
  183. printf("Write data error, xfercount:%llu", xfercount);
  184. return -ENOBUFS;
  185. }
  186. return 0;
  187. }
  188. static int do_data_transfer(struct mmc *dev,
  189. struct mmc_cmd *cmd,
  190. struct mmc_data *data)
  191. {
  192. int error = -ETIMEDOUT;
  193. struct pl180_mmc_host *host = dev->priv;
  194. u32 blksz = 0;
  195. u32 data_ctrl = 0;
  196. u32 data_len = (u32) (data->blocks * data->blocksize);
  197. if (!host->version2) {
  198. blksz = (ffs(data->blocksize) - 1);
  199. data_ctrl |= ((blksz << 4) & SDI_DCTRL_DBLKSIZE_MASK);
  200. } else {
  201. blksz = data->blocksize;
  202. data_ctrl |= (blksz << SDI_DCTRL_DBLOCKSIZE_V2_SHIFT);
  203. }
  204. data_ctrl |= SDI_DCTRL_DTEN | SDI_DCTRL_BUSYMODE;
  205. writel(SDI_DTIMER_DEFAULT, &host->base->datatimer);
  206. writel(data_len, &host->base->datalength);
  207. udelay(DATA_REG_DELAY);
  208. if (data->flags & MMC_DATA_READ) {
  209. data_ctrl |= SDI_DCTRL_DTDIR_IN;
  210. writel(data_ctrl, &host->base->datactrl);
  211. error = do_command(dev, cmd);
  212. if (error)
  213. return error;
  214. error = read_bytes(dev, (u32 *)data->dest, (u32)data->blocks,
  215. (u32)data->blocksize);
  216. } else if (data->flags & MMC_DATA_WRITE) {
  217. error = do_command(dev, cmd);
  218. if (error)
  219. return error;
  220. writel(data_ctrl, &host->base->datactrl);
  221. error = write_bytes(dev, (u32 *)data->src, (u32)data->blocks,
  222. (u32)data->blocksize);
  223. }
  224. return error;
  225. }
  226. static int host_request(struct mmc *dev,
  227. struct mmc_cmd *cmd,
  228. struct mmc_data *data)
  229. {
  230. int result;
  231. if (data)
  232. result = do_data_transfer(dev, cmd, data);
  233. else
  234. result = do_command(dev, cmd);
  235. return result;
  236. }
  237. static int host_set_ios(struct mmc *dev)
  238. {
  239. struct pl180_mmc_host *host = dev->priv;
  240. u32 sdi_clkcr;
  241. sdi_clkcr = readl(&host->base->clock);
  242. /* Ramp up the clock rate */
  243. if (dev->clock) {
  244. u32 clkdiv = 0;
  245. u32 tmp_clock;
  246. if (dev->clock >= dev->cfg->f_max) {
  247. clkdiv = 0;
  248. dev->clock = dev->cfg->f_max;
  249. } else {
  250. clkdiv = (host->clock_in / dev->clock) - 2;
  251. }
  252. tmp_clock = host->clock_in / (clkdiv + 2);
  253. while (tmp_clock > dev->clock) {
  254. clkdiv++;
  255. tmp_clock = host->clock_in / (clkdiv + 2);
  256. }
  257. if (clkdiv > SDI_CLKCR_CLKDIV_MASK)
  258. clkdiv = SDI_CLKCR_CLKDIV_MASK;
  259. tmp_clock = host->clock_in / (clkdiv + 2);
  260. dev->clock = tmp_clock;
  261. sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK);
  262. sdi_clkcr |= clkdiv;
  263. }
  264. /* Set the bus width */
  265. if (dev->bus_width) {
  266. u32 buswidth = 0;
  267. switch (dev->bus_width) {
  268. case 1:
  269. buswidth |= SDI_CLKCR_WIDBUS_1;
  270. break;
  271. case 4:
  272. buswidth |= SDI_CLKCR_WIDBUS_4;
  273. break;
  274. case 8:
  275. buswidth |= SDI_CLKCR_WIDBUS_8;
  276. break;
  277. default:
  278. printf("Invalid bus width: %d\n", dev->bus_width);
  279. break;
  280. }
  281. sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK);
  282. sdi_clkcr |= buswidth;
  283. }
  284. writel(sdi_clkcr, &host->base->clock);
  285. udelay(CLK_CHANGE_DELAY);
  286. return 0;
  287. }
  288. #ifndef CONFIG_DM_MMC
  289. /* MMC uses open drain drivers in the enumeration phase */
  290. static int mmc_host_reset(struct mmc *dev)
  291. {
  292. struct pl180_mmc_host *host = dev->priv;
  293. writel(host->pwr_init, &host->base->power);
  294. return 0;
  295. }
  296. static const struct mmc_ops arm_pl180_mmci_ops = {
  297. .send_cmd = host_request,
  298. .set_ios = host_set_ios,
  299. .init = mmc_host_reset,
  300. };
  301. #endif
  302. /*
  303. * mmc_host_init - initialize the mmc controller.
  304. * Set initial clock and power for mmc slot.
  305. * Initialize mmc struct and register with mmc framework.
  306. */
  307. int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
  308. {
  309. u32 sdi_u32;
  310. writel(host->pwr_init, &host->base->power);
  311. writel(host->clkdiv_init, &host->base->clock);
  312. udelay(CLK_CHANGE_DELAY);
  313. /* Disable mmc interrupts */
  314. sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
  315. writel(sdi_u32, &host->base->mask0);
  316. host->cfg.name = host->name;
  317. #ifndef CONFIG_DM_MMC
  318. host->cfg.ops = &arm_pl180_mmci_ops;
  319. #endif
  320. /* TODO remove the duplicates */
  321. host->cfg.host_caps = host->caps;
  322. host->cfg.voltages = host->voltages;
  323. host->cfg.f_min = host->clock_min;
  324. host->cfg.f_max = host->clock_max;
  325. if (host->b_max != 0)
  326. host->cfg.b_max = host->b_max;
  327. else
  328. host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  329. *mmc = mmc_create(&host->cfg, host);
  330. if (!*mmc)
  331. return -1;
  332. debug("registered mmc interface number is:%d\n",
  333. (*mmc)->block_dev.devnum);
  334. return 0;
  335. }
  336. #ifdef CONFIG_DM_MMC
  337. static int arm_pl180_mmc_probe(struct udevice *dev)
  338. {
  339. struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
  340. struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  341. struct mmc *mmc = &pdata->mmc;
  342. struct pl180_mmc_host *host = mmc->priv;
  343. struct clk clk;
  344. u32 bus_width;
  345. int ret;
  346. ret = clk_get_by_index(dev, 0, &clk);
  347. if (ret < 0)
  348. return ret;
  349. ret = clk_enable(&clk);
  350. if (ret) {
  351. dev_err(dev, "failed to enable clock\n");
  352. return ret;
  353. }
  354. strcpy(host->name, "MMC");
  355. host->pwr_init = INIT_PWR;
  356. host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN |
  357. SDI_CLKCR_HWFC_EN;
  358. host->voltages = VOLTAGE_WINDOW_SD;
  359. host->caps = 0;
  360. host->clock_in = clk_get_rate(&clk);
  361. host->clock_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
  362. host->clock_max = dev_read_u32_default(dev, "max-frequency",
  363. MMC_CLOCK_MAX);
  364. host->version2 = dev_get_driver_data(dev);
  365. gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
  366. bus_width = dev_read_u32_default(dev, "bus-width", 1);
  367. switch (bus_width) {
  368. case 8:
  369. host->caps |= MMC_MODE_8BIT;
  370. /* Hosts capable of 8-bit transfers can also do 4 bits */
  371. case 4:
  372. host->caps |= MMC_MODE_4BIT;
  373. break;
  374. case 1:
  375. break;
  376. default:
  377. dev_err(dev, "Invalid bus-width value %u\n", bus_width);
  378. }
  379. ret = arm_pl180_mmci_init(host, &mmc);
  380. if (ret) {
  381. dev_err(dev, "arm_pl180_mmci init failed\n");
  382. return ret;
  383. }
  384. mmc->dev = dev;
  385. dev->priv = host;
  386. upriv->mmc = mmc;
  387. return 0;
  388. }
  389. static int dm_host_request(struct udevice *dev, struct mmc_cmd *cmd,
  390. struct mmc_data *data)
  391. {
  392. struct mmc *mmc = mmc_get_mmc_dev(dev);
  393. return host_request(mmc, cmd, data);
  394. }
  395. static int dm_host_set_ios(struct udevice *dev)
  396. {
  397. struct mmc *mmc = mmc_get_mmc_dev(dev);
  398. return host_set_ios(mmc);
  399. }
  400. static int dm_mmc_getcd(struct udevice *dev)
  401. {
  402. struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
  403. struct mmc *mmc = &pdata->mmc;
  404. struct pl180_mmc_host *host = mmc->priv;
  405. int value = 1;
  406. if (dm_gpio_is_valid(&host->cd_gpio)) {
  407. value = dm_gpio_get_value(&host->cd_gpio);
  408. if (host->cd_inverted)
  409. return !value;
  410. }
  411. return value;
  412. }
  413. static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = {
  414. .send_cmd = dm_host_request,
  415. .set_ios = dm_host_set_ios,
  416. .get_cd = dm_mmc_getcd,
  417. };
  418. static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev)
  419. {
  420. struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
  421. struct mmc *mmc = &pdata->mmc;
  422. struct pl180_mmc_host *host = mmc->priv;
  423. fdt_addr_t addr;
  424. addr = devfdt_get_addr(dev);
  425. if (addr == FDT_ADDR_T_NONE)
  426. return -EINVAL;
  427. host->base = (void *)addr;
  428. return 0;
  429. }
  430. static const struct udevice_id arm_pl180_mmc_match[] = {
  431. { .compatible = "st,stm32f4xx-sdio", .data = VERSION1 },
  432. { /* sentinel */ }
  433. };
  434. U_BOOT_DRIVER(arm_pl180_mmc) = {
  435. .name = "arm_pl180_mmc",
  436. .id = UCLASS_MMC,
  437. .of_match = arm_pl180_mmc_match,
  438. .ops = &arm_pl180_dm_mmc_ops,
  439. .probe = arm_pl180_mmc_probe,
  440. .ofdata_to_platdata = arm_pl180_mmc_ofdata_to_platdata,
  441. .priv_auto_alloc_size = sizeof(struct pl180_mmc_host),
  442. .platdata_auto_alloc_size = sizeof(struct arm_pl180_mmc_plat),
  443. };
  444. #endif