ftsdc010_mci.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Faraday MMC/SD Host Controller
  4. *
  5. * (C) Copyright 2010 Faraday Technology
  6. * Dante Su <dantesu@faraday-tech.com>
  7. *
  8. * Copyright 2018 Andes Technology, Inc.
  9. * Author: Rick Chen (rick@andestech.com)
  10. */
  11. #include <common.h>
  12. #include <clk.h>
  13. #include <malloc.h>
  14. #include <part.h>
  15. #include <mmc.h>
  16. #include <linux/io.h>
  17. #include <linux/errno.h>
  18. #include <asm/byteorder.h>
  19. #include <faraday/ftsdc010.h>
  20. #include "ftsdc010_mci.h"
  21. #include <dm.h>
  22. #include <dt-structs.h>
  23. #include <errno.h>
  24. #include <mapmem.h>
  25. #include <pwrseq.h>
  26. #include <syscon.h>
  27. #include <linux/err.h>
  28. DECLARE_GLOBAL_DATA_PTR;
  29. #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
  30. #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
  31. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  32. struct ftsdc010 {
  33. fdt32_t bus_width;
  34. bool cap_mmc_highspeed;
  35. bool cap_sd_highspeed;
  36. fdt32_t clock_freq_min_max[2];
  37. struct phandle_2_cell clocks[4];
  38. fdt32_t fifo_depth;
  39. fdt32_t reg[2];
  40. };
  41. #endif
  42. struct ftsdc010_plat {
  43. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  44. struct ftsdc010 dtplat;
  45. #endif
  46. struct mmc_config cfg;
  47. struct mmc mmc;
  48. };
  49. struct ftsdc_priv {
  50. struct clk clk;
  51. struct ftsdc010_chip chip;
  52. int fifo_depth;
  53. bool fifo_mode;
  54. u32 minmax[2];
  55. };
  56. static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
  57. {
  58. struct ftsdc010_chip *chip = mmc->priv;
  59. struct ftsdc010_mmc __iomem *regs = chip->regs;
  60. int ret = -ETIMEDOUT;
  61. uint32_t ts, st;
  62. uint32_t cmd = FTSDC010_CMD_IDX(mmc_cmd->cmdidx);
  63. uint32_t arg = mmc_cmd->cmdarg;
  64. uint32_t flags = mmc_cmd->resp_type;
  65. cmd |= FTSDC010_CMD_CMD_EN;
  66. if (chip->acmd) {
  67. cmd |= FTSDC010_CMD_APP_CMD;
  68. chip->acmd = 0;
  69. }
  70. if (flags & MMC_RSP_PRESENT)
  71. cmd |= FTSDC010_CMD_NEED_RSP;
  72. if (flags & MMC_RSP_136)
  73. cmd |= FTSDC010_CMD_LONG_RSP;
  74. writel(FTSDC010_STATUS_RSP_MASK | FTSDC010_STATUS_CMD_SEND,
  75. &regs->clr);
  76. writel(arg, &regs->argu);
  77. writel(cmd, &regs->cmd);
  78. if (!(flags & (MMC_RSP_PRESENT | MMC_RSP_136))) {
  79. for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
  80. if (readl(&regs->status) & FTSDC010_STATUS_CMD_SEND) {
  81. writel(FTSDC010_STATUS_CMD_SEND, &regs->clr);
  82. ret = 0;
  83. break;
  84. }
  85. }
  86. } else {
  87. st = 0;
  88. for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
  89. st = readl(&regs->status);
  90. writel(st & FTSDC010_STATUS_RSP_MASK, &regs->clr);
  91. if (st & FTSDC010_STATUS_RSP_MASK)
  92. break;
  93. }
  94. if (st & FTSDC010_STATUS_RSP_CRC_OK) {
  95. if (flags & MMC_RSP_136) {
  96. mmc_cmd->response[0] = readl(&regs->rsp3);
  97. mmc_cmd->response[1] = readl(&regs->rsp2);
  98. mmc_cmd->response[2] = readl(&regs->rsp1);
  99. mmc_cmd->response[3] = readl(&regs->rsp0);
  100. } else {
  101. mmc_cmd->response[0] = readl(&regs->rsp0);
  102. }
  103. ret = 0;
  104. } else {
  105. debug("ftsdc010: rsp err (cmd=%d, st=0x%x)\n",
  106. mmc_cmd->cmdidx, st);
  107. }
  108. }
  109. if (ret) {
  110. debug("ftsdc010: cmd timeout (op code=%d)\n",
  111. mmc_cmd->cmdidx);
  112. } else if (mmc_cmd->cmdidx == MMC_CMD_APP_CMD) {
  113. chip->acmd = 1;
  114. }
  115. return ret;
  116. }
  117. static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
  118. {
  119. struct ftsdc010_chip *chip = mmc->priv;
  120. struct ftsdc010_mmc __iomem *regs = chip->regs;
  121. uint32_t div;
  122. for (div = 0; div < 0x7f; ++div) {
  123. if (rate >= chip->sclk / (2 * (div + 1)))
  124. break;
  125. }
  126. chip->rate = chip->sclk / (2 * (div + 1));
  127. writel(FTSDC010_CCR_CLK_DIV(div), &regs->ccr);
  128. if (IS_SD(mmc)) {
  129. setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_SD);
  130. if (chip->rate > 25000000)
  131. setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
  132. else
  133. clrbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
  134. }
  135. }
  136. static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
  137. {
  138. int ret = -ETIMEDOUT;
  139. uint32_t st, timeout = 10000000;
  140. while (timeout--) {
  141. st = readl(&regs->status);
  142. if (!(st & mask))
  143. continue;
  144. writel(st & mask, &regs->clr);
  145. ret = 0;
  146. break;
  147. }
  148. if (ret){
  149. debug("ftsdc010: wait st(0x%x) timeout\n", mask);
  150. }
  151. return ret;
  152. }
  153. /*
  154. * u-boot mmc api
  155. */
  156. static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
  157. struct mmc_data *data)
  158. {
  159. struct mmc *mmc = mmc_get_mmc_dev(dev);
  160. int ret = -EOPNOTSUPP;
  161. uint32_t len = 0;
  162. struct ftsdc010_chip *chip = mmc->priv;
  163. struct ftsdc010_mmc __iomem *regs = chip->regs;
  164. if (data && (data->flags & MMC_DATA_WRITE) && chip->wprot) {
  165. printf("ftsdc010: the card is write protected!\n");
  166. return ret;
  167. }
  168. if (data) {
  169. uint32_t dcr;
  170. len = data->blocksize * data->blocks;
  171. /* 1. data disable + fifo reset */
  172. dcr = 0;
  173. #ifdef CONFIG_FTSDC010_SDIO
  174. dcr |= FTSDC010_DCR_FIFO_RST;
  175. #endif
  176. writel(dcr, &regs->dcr);
  177. /* 2. clear status register */
  178. writel(FTSDC010_STATUS_DATA_MASK | FTSDC010_STATUS_FIFO_URUN
  179. | FTSDC010_STATUS_FIFO_ORUN, &regs->clr);
  180. /* 3. data timeout (1 sec) */
  181. writel(chip->rate, &regs->dtr);
  182. /* 4. data length (bytes) */
  183. writel(len, &regs->dlr);
  184. /* 5. data enable */
  185. dcr = (ffs(data->blocksize) - 1) | FTSDC010_DCR_DATA_EN;
  186. if (data->flags & MMC_DATA_WRITE)
  187. dcr |= FTSDC010_DCR_DATA_WRITE;
  188. writel(dcr, &regs->dcr);
  189. }
  190. ret = ftsdc010_send_cmd(mmc, cmd);
  191. if (ret) {
  192. printf("ftsdc010: CMD%d failed\n", cmd->cmdidx);
  193. return ret;
  194. }
  195. if (!data)
  196. return ret;
  197. if (data->flags & MMC_DATA_WRITE) {
  198. const uint8_t *buf = (const uint8_t *)data->src;
  199. while (len > 0) {
  200. int wlen;
  201. /* wait for tx ready */
  202. ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_URUN);
  203. if (ret)
  204. break;
  205. /* write bytes to ftsdc010 */
  206. for (wlen = 0; wlen < len && wlen < chip->fifo; ) {
  207. writel(*(uint32_t *)buf, &regs->dwr);
  208. buf += 4;
  209. wlen += 4;
  210. }
  211. len -= wlen;
  212. }
  213. } else {
  214. uint8_t *buf = (uint8_t *)data->dest;
  215. while (len > 0) {
  216. int rlen;
  217. /* wait for rx ready */
  218. ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_ORUN);
  219. if (ret)
  220. break;
  221. /* fetch bytes from ftsdc010 */
  222. for (rlen = 0; rlen < len && rlen < chip->fifo; ) {
  223. *(uint32_t *)buf = readl(&regs->dwr);
  224. buf += 4;
  225. rlen += 4;
  226. }
  227. len -= rlen;
  228. }
  229. }
  230. if (!ret) {
  231. ret = ftsdc010_wait(regs,
  232. FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_CRC_OK);
  233. }
  234. return ret;
  235. }
  236. static int ftsdc010_set_ios(struct udevice *dev)
  237. {
  238. struct mmc *mmc = mmc_get_mmc_dev(dev);
  239. struct ftsdc010_chip *chip = mmc->priv;
  240. struct ftsdc010_mmc __iomem *regs = chip->regs;
  241. ftsdc010_clkset(mmc, mmc->clock);
  242. clrbits_le32(&regs->bwr, FTSDC010_BWR_MODE_MASK);
  243. switch (mmc->bus_width) {
  244. case 4:
  245. setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_4BIT);
  246. break;
  247. case 8:
  248. setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_8BIT);
  249. break;
  250. default:
  251. setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_1BIT);
  252. break;
  253. }
  254. return 0;
  255. }
  256. static int ftsdc010_get_cd(struct udevice *dev)
  257. {
  258. struct mmc *mmc = mmc_get_mmc_dev(dev);
  259. struct ftsdc010_chip *chip = mmc->priv;
  260. struct ftsdc010_mmc __iomem *regs = chip->regs;
  261. return !(readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT);
  262. }
  263. static int ftsdc010_get_wp(struct udevice *dev)
  264. {
  265. struct mmc *mmc = mmc_get_mmc_dev(dev);
  266. struct ftsdc010_chip *chip = mmc->priv;
  267. struct ftsdc010_mmc __iomem *regs = chip->regs;
  268. if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
  269. printf("ftsdc010: write protected\n");
  270. chip->wprot = 1;
  271. }
  272. return 0;
  273. }
  274. static int ftsdc010_init(struct mmc *mmc)
  275. {
  276. struct ftsdc010_chip *chip = mmc->priv;
  277. struct ftsdc010_mmc __iomem *regs = chip->regs;
  278. uint32_t ts;
  279. chip->fifo = (readl(&regs->feature) & 0xff) << 2;
  280. /* 1. chip reset */
  281. writel(FTSDC010_CMD_SDC_RST, &regs->cmd);
  282. for (ts = get_timer(0); get_timer(ts) < CFG_RST_TIMEOUT; ) {
  283. if (readl(&regs->cmd) & FTSDC010_CMD_SDC_RST)
  284. continue;
  285. break;
  286. }
  287. if (readl(&regs->cmd) & FTSDC010_CMD_SDC_RST) {
  288. printf("ftsdc010: reset failed\n");
  289. return -EOPNOTSUPP;
  290. }
  291. /* 2. enter low speed mode (400k card detection) */
  292. ftsdc010_clkset(mmc, 400000);
  293. /* 3. interrupt disabled */
  294. writel(0, &regs->int_mask);
  295. return 0;
  296. }
  297. static int ftsdc010_probe(struct udevice *dev)
  298. {
  299. struct mmc *mmc = mmc_get_mmc_dev(dev);
  300. return ftsdc010_init(mmc);
  301. }
  302. const struct dm_mmc_ops dm_ftsdc010_mmc_ops = {
  303. .send_cmd = ftsdc010_request,
  304. .set_ios = ftsdc010_set_ios,
  305. .get_cd = ftsdc010_get_cd,
  306. .get_wp = ftsdc010_get_wp,
  307. };
  308. static void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
  309. uint caps, u32 max_clk, u32 min_clk)
  310. {
  311. cfg->name = name;
  312. cfg->f_min = min_clk;
  313. cfg->f_max = max_clk;
  314. cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
  315. cfg->host_caps = caps;
  316. if (buswidth == 8) {
  317. cfg->host_caps |= MMC_MODE_8BIT;
  318. cfg->host_caps &= ~MMC_MODE_4BIT;
  319. } else {
  320. cfg->host_caps |= MMC_MODE_4BIT;
  321. cfg->host_caps &= ~MMC_MODE_8BIT;
  322. }
  323. cfg->part_type = PART_TYPE_DOS;
  324. cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  325. }
  326. static int ftsdc010_mmc_ofdata_to_platdata(struct udevice *dev)
  327. {
  328. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  329. struct ftsdc_priv *priv = dev_get_priv(dev);
  330. struct ftsdc010_chip *chip = &priv->chip;
  331. chip->name = dev->name;
  332. chip->ioaddr = (void *)devfdt_get_addr(dev);
  333. chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  334. "bus-width", 4);
  335. chip->priv = dev;
  336. priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  337. "fifo-depth", 0);
  338. priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
  339. "fifo-mode");
  340. if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
  341. "clock-freq-min-max", priv->minmax, 2)) {
  342. int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  343. "max-frequency", -EINVAL);
  344. if (val < 0)
  345. return val;
  346. priv->minmax[0] = 400000; /* 400 kHz */
  347. priv->minmax[1] = val;
  348. } else {
  349. debug("%s: 'clock-freq-min-max' property was deprecated.\n",
  350. __func__);
  351. }
  352. #endif
  353. chip->sclk = priv->minmax[1];
  354. chip->regs = chip->ioaddr;
  355. return 0;
  356. }
  357. static int ftsdc010_mmc_probe(struct udevice *dev)
  358. {
  359. struct ftsdc010_plat *plat = dev_get_platdata(dev);
  360. struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  361. struct ftsdc_priv *priv = dev_get_priv(dev);
  362. struct ftsdc010_chip *chip = &priv->chip;
  363. struct udevice *pwr_dev __maybe_unused;
  364. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  365. int ret;
  366. struct ftsdc010 *dtplat = &plat->dtplat;
  367. chip->name = dev->name;
  368. chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
  369. chip->buswidth = dtplat->bus_width;
  370. chip->priv = dev;
  371. chip->dev_index = 1;
  372. memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
  373. ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
  374. if (ret < 0)
  375. return ret;
  376. #endif
  377. if (dev_read_bool(dev, "cap-mmc-highspeed") || \
  378. dev_read_bool(dev, "cap-sd-highspeed"))
  379. chip->caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
  380. ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
  381. priv->minmax[1] , priv->minmax[0]);
  382. chip->mmc = &plat->mmc;
  383. chip->mmc->priv = &priv->chip;
  384. chip->mmc->dev = dev;
  385. upriv->mmc = chip->mmc;
  386. return ftsdc010_probe(dev);
  387. }
  388. int ftsdc010_mmc_bind(struct udevice *dev)
  389. {
  390. struct ftsdc010_plat *plat = dev_get_platdata(dev);
  391. return mmc_bind(dev, &plat->mmc, &plat->cfg);
  392. }
  393. static const struct udevice_id ftsdc010_mmc_ids[] = {
  394. { .compatible = "andestech,atfsdc010" },
  395. { }
  396. };
  397. U_BOOT_DRIVER(ftsdc010_mmc) = {
  398. .name = "ftsdc010_mmc",
  399. .id = UCLASS_MMC,
  400. .of_match = ftsdc010_mmc_ids,
  401. .ofdata_to_platdata = ftsdc010_mmc_ofdata_to_platdata,
  402. .ops = &dm_ftsdc010_mmc_ops,
  403. .bind = ftsdc010_mmc_bind,
  404. .probe = ftsdc010_mmc_probe,
  405. .priv_auto_alloc_size = sizeof(struct ftsdc_priv),
  406. .platdata_auto_alloc_size = sizeof(struct ftsdc010_plat),
  407. };