ftsdc010_mci.c 9.9 KB

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