sunxi_mmc.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2007-2011
  4. * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  5. * Aaron <leafy.myeh@allwinnertech.com>
  6. *
  7. * MMC driver for allwinner sunxi platform.
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <mmc.h>
  15. #include <clk.h>
  16. #include <reset.h>
  17. #include <asm/io.h>
  18. #include <asm/arch/clock.h>
  19. #include <asm/arch/cpu.h>
  20. #include <asm/arch/gpio.h>
  21. #include <asm/arch/mmc.h>
  22. #include <asm-generic/gpio.h>
  23. #include <linux/delay.h>
  24. #ifdef CONFIG_DM_MMC
  25. struct sunxi_mmc_variant {
  26. u16 mclk_offset;
  27. };
  28. #endif
  29. struct sunxi_mmc_plat {
  30. struct mmc_config cfg;
  31. struct mmc mmc;
  32. };
  33. struct sunxi_mmc_priv {
  34. unsigned mmc_no;
  35. uint32_t *mclkreg;
  36. unsigned fatal_err;
  37. struct gpio_desc cd_gpio; /* Change Detect GPIO */
  38. int cd_inverted; /* Inverted Card Detect */
  39. struct sunxi_mmc *reg;
  40. struct mmc_config cfg;
  41. #ifdef CONFIG_DM_MMC
  42. const struct sunxi_mmc_variant *variant;
  43. #endif
  44. };
  45. #if !CONFIG_IS_ENABLED(DM_MMC)
  46. /* support 4 mmc hosts */
  47. struct sunxi_mmc_priv mmc_host[4];
  48. static int sunxi_mmc_getcd_gpio(int sdc_no)
  49. {
  50. switch (sdc_no) {
  51. case 0: return sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN);
  52. case 1: return sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN);
  53. case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN);
  54. case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN);
  55. }
  56. return -EINVAL;
  57. }
  58. static int mmc_resource_init(int sdc_no)
  59. {
  60. struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
  61. struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  62. int cd_pin, ret = 0;
  63. debug("init mmc %d resource\n", sdc_no);
  64. switch (sdc_no) {
  65. case 0:
  66. priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
  67. priv->mclkreg = &ccm->sd0_clk_cfg;
  68. break;
  69. case 1:
  70. priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
  71. priv->mclkreg = &ccm->sd1_clk_cfg;
  72. break;
  73. case 2:
  74. priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
  75. priv->mclkreg = &ccm->sd2_clk_cfg;
  76. break;
  77. #ifdef SUNXI_MMC3_BASE
  78. case 3:
  79. priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
  80. priv->mclkreg = &ccm->sd3_clk_cfg;
  81. break;
  82. #endif
  83. default:
  84. printf("Wrong mmc number %d\n", sdc_no);
  85. return -1;
  86. }
  87. priv->mmc_no = sdc_no;
  88. cd_pin = sunxi_mmc_getcd_gpio(sdc_no);
  89. if (cd_pin >= 0) {
  90. ret = gpio_request(cd_pin, "mmc_cd");
  91. if (!ret) {
  92. sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
  93. ret = gpio_direction_input(cd_pin);
  94. }
  95. }
  96. return ret;
  97. }
  98. #endif
  99. static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
  100. {
  101. unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
  102. bool new_mode = true;
  103. bool calibrate = false;
  104. u32 val = 0;
  105. if (!IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE))
  106. new_mode = false;
  107. /* A83T support new mode only on eMMC */
  108. if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2)
  109. new_mode = false;
  110. #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6)
  111. calibrate = true;
  112. #endif
  113. if (hz <= 24000000) {
  114. pll = CCM_MMC_CTRL_OSCM24;
  115. pll_hz = 24000000;
  116. } else {
  117. #ifdef CONFIG_MACH_SUN9I
  118. pll = CCM_MMC_CTRL_PLL_PERIPH0;
  119. pll_hz = clock_get_pll4_periph0();
  120. #elif defined(CONFIG_MACH_SUN50I_H6)
  121. pll = CCM_MMC_CTRL_PLL6X2;
  122. pll_hz = clock_get_pll6() * 2;
  123. #else
  124. pll = CCM_MMC_CTRL_PLL6;
  125. pll_hz = clock_get_pll6();
  126. #endif
  127. }
  128. div = pll_hz / hz;
  129. if (pll_hz % hz)
  130. div++;
  131. n = 0;
  132. while (div > 16) {
  133. n++;
  134. div = (div + 1) / 2;
  135. }
  136. if (n > 3) {
  137. printf("mmc %u error cannot set clock to %u\n", priv->mmc_no,
  138. hz);
  139. return -1;
  140. }
  141. /* determine delays */
  142. if (hz <= 400000) {
  143. oclk_dly = 0;
  144. sclk_dly = 0;
  145. } else if (hz <= 25000000) {
  146. oclk_dly = 0;
  147. sclk_dly = 5;
  148. #ifdef CONFIG_MACH_SUN9I
  149. } else if (hz <= 52000000) {
  150. oclk_dly = 5;
  151. sclk_dly = 4;
  152. } else {
  153. /* hz > 52000000 */
  154. oclk_dly = 2;
  155. sclk_dly = 4;
  156. #else
  157. } else if (hz <= 52000000) {
  158. oclk_dly = 3;
  159. sclk_dly = 4;
  160. } else {
  161. /* hz > 52000000 */
  162. oclk_dly = 1;
  163. sclk_dly = 4;
  164. #endif
  165. }
  166. if (new_mode) {
  167. #ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
  168. #ifdef CONFIG_MMC_SUNXI_HAS_MODE_SWITCH
  169. val = CCM_MMC_CTRL_MODE_SEL_NEW;
  170. #endif
  171. setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
  172. #endif
  173. } else if (!calibrate) {
  174. /*
  175. * Use hardcoded delay values if controller doesn't support
  176. * calibration
  177. */
  178. val = CCM_MMC_CTRL_OCLK_DLY(oclk_dly) |
  179. CCM_MMC_CTRL_SCLK_DLY(sclk_dly);
  180. }
  181. writel(CCM_MMC_CTRL_ENABLE| pll | CCM_MMC_CTRL_N(n) |
  182. CCM_MMC_CTRL_M(div) | val, priv->mclkreg);
  183. debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n",
  184. priv->mmc_no, hz, pll_hz, 1u << n, div, pll_hz / (1u << n) / div);
  185. return 0;
  186. }
  187. static int mmc_update_clk(struct sunxi_mmc_priv *priv)
  188. {
  189. unsigned int cmd;
  190. unsigned timeout_msecs = 2000;
  191. unsigned long start = get_timer(0);
  192. cmd = SUNXI_MMC_CMD_START |
  193. SUNXI_MMC_CMD_UPCLK_ONLY |
  194. SUNXI_MMC_CMD_WAIT_PRE_OVER;
  195. writel(cmd, &priv->reg->cmd);
  196. while (readl(&priv->reg->cmd) & SUNXI_MMC_CMD_START) {
  197. if (get_timer(start) > timeout_msecs)
  198. return -1;
  199. }
  200. /* clock update sets various irq status bits, clear these */
  201. writel(readl(&priv->reg->rint), &priv->reg->rint);
  202. return 0;
  203. }
  204. static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
  205. {
  206. unsigned rval = readl(&priv->reg->clkcr);
  207. /* Disable Clock */
  208. rval &= ~SUNXI_MMC_CLK_ENABLE;
  209. writel(rval, &priv->reg->clkcr);
  210. if (mmc_update_clk(priv))
  211. return -1;
  212. /* Set mod_clk to new rate */
  213. if (mmc_set_mod_clk(priv, mmc->clock))
  214. return -1;
  215. /* Clear internal divider */
  216. rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
  217. writel(rval, &priv->reg->clkcr);
  218. #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6)
  219. /* A64 supports calibration of delays on MMC controller and we
  220. * have to set delay of zero before starting calibration.
  221. * Allwinner BSP driver sets a delay only in the case of
  222. * using HS400 which is not supported by mainline U-Boot or
  223. * Linux at the moment
  224. */
  225. writel(SUNXI_MMC_CAL_DL_SW_EN, &priv->reg->samp_dl);
  226. #endif
  227. /* Re-enable Clock */
  228. rval |= SUNXI_MMC_CLK_ENABLE;
  229. writel(rval, &priv->reg->clkcr);
  230. if (mmc_update_clk(priv))
  231. return -1;
  232. return 0;
  233. }
  234. static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv,
  235. struct mmc *mmc)
  236. {
  237. debug("set ios: bus_width: %x, clock: %d\n",
  238. mmc->bus_width, mmc->clock);
  239. /* Change clock first */
  240. if (mmc->clock && mmc_config_clock(priv, mmc) != 0) {
  241. priv->fatal_err = 1;
  242. return -EINVAL;
  243. }
  244. /* Change bus width */
  245. if (mmc->bus_width == 8)
  246. writel(0x2, &priv->reg->width);
  247. else if (mmc->bus_width == 4)
  248. writel(0x1, &priv->reg->width);
  249. else
  250. writel(0x0, &priv->reg->width);
  251. return 0;
  252. }
  253. #if !CONFIG_IS_ENABLED(DM_MMC)
  254. static int sunxi_mmc_core_init(struct mmc *mmc)
  255. {
  256. struct sunxi_mmc_priv *priv = mmc->priv;
  257. /* Reset controller */
  258. writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
  259. udelay(1000);
  260. return 0;
  261. }
  262. #endif
  263. static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
  264. struct mmc_data *data)
  265. {
  266. const int reading = !!(data->flags & MMC_DATA_READ);
  267. const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
  268. SUNXI_MMC_STATUS_FIFO_FULL;
  269. unsigned i;
  270. unsigned *buff = (unsigned int *)(reading ? data->dest : data->src);
  271. unsigned byte_cnt = data->blocksize * data->blocks;
  272. unsigned timeout_msecs = byte_cnt >> 8;
  273. unsigned long start;
  274. if (timeout_msecs < 2000)
  275. timeout_msecs = 2000;
  276. /* Always read / write data through the CPU */
  277. setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
  278. start = get_timer(0);
  279. for (i = 0; i < (byte_cnt >> 2); i++) {
  280. while (readl(&priv->reg->status) & status_bit) {
  281. if (get_timer(start) > timeout_msecs)
  282. return -1;
  283. }
  284. if (reading)
  285. buff[i] = readl(&priv->reg->fifo);
  286. else
  287. writel(buff[i], &priv->reg->fifo);
  288. }
  289. return 0;
  290. }
  291. static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc,
  292. uint timeout_msecs, uint done_bit, const char *what)
  293. {
  294. unsigned int status;
  295. unsigned long start = get_timer(0);
  296. do {
  297. status = readl(&priv->reg->rint);
  298. if ((get_timer(start) > timeout_msecs) ||
  299. (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) {
  300. debug("%s timeout %x\n", what,
  301. status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT);
  302. return -ETIMEDOUT;
  303. }
  304. } while (!(status & done_bit));
  305. return 0;
  306. }
  307. static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
  308. struct mmc *mmc, struct mmc_cmd *cmd,
  309. struct mmc_data *data)
  310. {
  311. unsigned int cmdval = SUNXI_MMC_CMD_START;
  312. unsigned int timeout_msecs;
  313. int error = 0;
  314. unsigned int status = 0;
  315. unsigned int bytecnt = 0;
  316. if (priv->fatal_err)
  317. return -1;
  318. if (cmd->resp_type & MMC_RSP_BUSY)
  319. debug("mmc cmd %d check rsp busy\n", cmd->cmdidx);
  320. if (cmd->cmdidx == 12)
  321. return 0;
  322. if (!cmd->cmdidx)
  323. cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ;
  324. if (cmd->resp_type & MMC_RSP_PRESENT)
  325. cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE;
  326. if (cmd->resp_type & MMC_RSP_136)
  327. cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE;
  328. if (cmd->resp_type & MMC_RSP_CRC)
  329. cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC;
  330. if (data) {
  331. if ((u32)(long)data->dest & 0x3) {
  332. error = -1;
  333. goto out;
  334. }
  335. cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER;
  336. if (data->flags & MMC_DATA_WRITE)
  337. cmdval |= SUNXI_MMC_CMD_WRITE;
  338. if (data->blocks > 1)
  339. cmdval |= SUNXI_MMC_CMD_AUTO_STOP;
  340. writel(data->blocksize, &priv->reg->blksz);
  341. writel(data->blocks * data->blocksize, &priv->reg->bytecnt);
  342. }
  343. debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", priv->mmc_no,
  344. cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
  345. writel(cmd->cmdarg, &priv->reg->arg);
  346. if (!data)
  347. writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
  348. /*
  349. * transfer data and check status
  350. * STATREG[2] : FIFO empty
  351. * STATREG[3] : FIFO full
  352. */
  353. if (data) {
  354. int ret = 0;
  355. bytecnt = data->blocksize * data->blocks;
  356. debug("trans data %d bytes\n", bytecnt);
  357. writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
  358. ret = mmc_trans_data_by_cpu(priv, mmc, data);
  359. if (ret) {
  360. error = readl(&priv->reg->rint) &
  361. SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT;
  362. error = -ETIMEDOUT;
  363. goto out;
  364. }
  365. }
  366. error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE,
  367. "cmd");
  368. if (error)
  369. goto out;
  370. if (data) {
  371. timeout_msecs = 120;
  372. debug("cacl timeout %x msec\n", timeout_msecs);
  373. error = mmc_rint_wait(priv, mmc, timeout_msecs,
  374. data->blocks > 1 ?
  375. SUNXI_MMC_RINT_AUTO_COMMAND_DONE :
  376. SUNXI_MMC_RINT_DATA_OVER,
  377. "data");
  378. if (error)
  379. goto out;
  380. }
  381. if (cmd->resp_type & MMC_RSP_BUSY) {
  382. unsigned long start = get_timer(0);
  383. timeout_msecs = 2000;
  384. do {
  385. status = readl(&priv->reg->status);
  386. if (get_timer(start) > timeout_msecs) {
  387. debug("busy timeout\n");
  388. error = -ETIMEDOUT;
  389. goto out;
  390. }
  391. } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY);
  392. }
  393. if (cmd->resp_type & MMC_RSP_136) {
  394. cmd->response[0] = readl(&priv->reg->resp3);
  395. cmd->response[1] = readl(&priv->reg->resp2);
  396. cmd->response[2] = readl(&priv->reg->resp1);
  397. cmd->response[3] = readl(&priv->reg->resp0);
  398. debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n",
  399. cmd->response[3], cmd->response[2],
  400. cmd->response[1], cmd->response[0]);
  401. } else {
  402. cmd->response[0] = readl(&priv->reg->resp0);
  403. debug("mmc resp 0x%08x\n", cmd->response[0]);
  404. }
  405. out:
  406. if (error < 0) {
  407. writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
  408. mmc_update_clk(priv);
  409. }
  410. writel(0xffffffff, &priv->reg->rint);
  411. writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
  412. &priv->reg->gctrl);
  413. return error;
  414. }
  415. #if !CONFIG_IS_ENABLED(DM_MMC)
  416. static int sunxi_mmc_set_ios_legacy(struct mmc *mmc)
  417. {
  418. struct sunxi_mmc_priv *priv = mmc->priv;
  419. return sunxi_mmc_set_ios_common(priv, mmc);
  420. }
  421. static int sunxi_mmc_send_cmd_legacy(struct mmc *mmc, struct mmc_cmd *cmd,
  422. struct mmc_data *data)
  423. {
  424. struct sunxi_mmc_priv *priv = mmc->priv;
  425. return sunxi_mmc_send_cmd_common(priv, mmc, cmd, data);
  426. }
  427. static int sunxi_mmc_getcd_legacy(struct mmc *mmc)
  428. {
  429. struct sunxi_mmc_priv *priv = mmc->priv;
  430. int cd_pin;
  431. cd_pin = sunxi_mmc_getcd_gpio(priv->mmc_no);
  432. if (cd_pin < 0)
  433. return 1;
  434. return !gpio_get_value(cd_pin);
  435. }
  436. static const struct mmc_ops sunxi_mmc_ops = {
  437. .send_cmd = sunxi_mmc_send_cmd_legacy,
  438. .set_ios = sunxi_mmc_set_ios_legacy,
  439. .init = sunxi_mmc_core_init,
  440. .getcd = sunxi_mmc_getcd_legacy,
  441. };
  442. struct mmc *sunxi_mmc_init(int sdc_no)
  443. {
  444. struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  445. struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
  446. struct mmc_config *cfg = &priv->cfg;
  447. int ret;
  448. memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
  449. cfg->name = "SUNXI SD/MMC";
  450. cfg->ops = &sunxi_mmc_ops;
  451. cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
  452. cfg->host_caps = MMC_MODE_4BIT;
  453. #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I_H6)
  454. if (sdc_no == 2)
  455. cfg->host_caps = MMC_MODE_8BIT;
  456. #endif
  457. cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
  458. cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  459. cfg->f_min = 400000;
  460. cfg->f_max = 52000000;
  461. if (mmc_resource_init(sdc_no) != 0)
  462. return NULL;
  463. /* config ahb clock */
  464. debug("init mmc %d clock and io\n", sdc_no);
  465. #if !defined(CONFIG_MACH_SUN50I_H6)
  466. setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
  467. #ifdef CONFIG_SUNXI_GEN_SUN6I
  468. /* unassert reset */
  469. setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
  470. #endif
  471. #if defined(CONFIG_MACH_SUN9I)
  472. /* sun9i has a mmc-common module, also set the gate and reset there */
  473. writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
  474. SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
  475. #endif
  476. #else /* CONFIG_MACH_SUN50I_H6 */
  477. setbits_le32(&ccm->sd_gate_reset, 1 << sdc_no);
  478. /* unassert reset */
  479. setbits_le32(&ccm->sd_gate_reset, 1 << (RESET_SHIFT + sdc_no));
  480. #endif
  481. ret = mmc_set_mod_clk(priv, 24000000);
  482. if (ret)
  483. return NULL;
  484. return mmc_create(cfg, priv);
  485. }
  486. #else
  487. static int sunxi_mmc_set_ios(struct udevice *dev)
  488. {
  489. struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
  490. struct sunxi_mmc_priv *priv = dev_get_priv(dev);
  491. return sunxi_mmc_set_ios_common(priv, &plat->mmc);
  492. }
  493. static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
  494. struct mmc_data *data)
  495. {
  496. struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
  497. struct sunxi_mmc_priv *priv = dev_get_priv(dev);
  498. return sunxi_mmc_send_cmd_common(priv, &plat->mmc, cmd, data);
  499. }
  500. static int sunxi_mmc_getcd(struct udevice *dev)
  501. {
  502. struct sunxi_mmc_priv *priv = dev_get_priv(dev);
  503. if (dm_gpio_is_valid(&priv->cd_gpio)) {
  504. int cd_state = dm_gpio_get_value(&priv->cd_gpio);
  505. return cd_state ^ priv->cd_inverted;
  506. }
  507. return 1;
  508. }
  509. static const struct dm_mmc_ops sunxi_mmc_ops = {
  510. .send_cmd = sunxi_mmc_send_cmd,
  511. .set_ios = sunxi_mmc_set_ios,
  512. .get_cd = sunxi_mmc_getcd,
  513. };
  514. static int sunxi_mmc_probe(struct udevice *dev)
  515. {
  516. struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  517. struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
  518. struct sunxi_mmc_priv *priv = dev_get_priv(dev);
  519. struct reset_ctl_bulk reset_bulk;
  520. struct clk gate_clk;
  521. struct mmc_config *cfg = &plat->cfg;
  522. struct ofnode_phandle_args args;
  523. u32 *ccu_reg;
  524. int bus_width, ret;
  525. cfg->name = dev->name;
  526. bus_width = dev_read_u32_default(dev, "bus-width", 1);
  527. cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
  528. cfg->host_caps = 0;
  529. if (bus_width == 8)
  530. cfg->host_caps |= MMC_MODE_8BIT;
  531. if (bus_width >= 4)
  532. cfg->host_caps |= MMC_MODE_4BIT;
  533. cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
  534. cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  535. cfg->f_min = 400000;
  536. cfg->f_max = 52000000;
  537. priv->reg = (void *)dev_read_addr(dev);
  538. priv->variant =
  539. (const struct sunxi_mmc_variant *)dev_get_driver_data(dev);
  540. /* We don't have a sunxi clock driver so find the clock address here */
  541. ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
  542. 1, &args);
  543. if (ret)
  544. return ret;
  545. ccu_reg = (u32 *)ofnode_get_addr(args.node);
  546. priv->mmc_no = ((uintptr_t)priv->reg - SUNXI_MMC0_BASE) / 0x1000;
  547. priv->mclkreg = (void *)ccu_reg +
  548. (priv->variant->mclk_offset + (priv->mmc_no * 4));
  549. ret = clk_get_by_name(dev, "ahb", &gate_clk);
  550. if (!ret)
  551. clk_enable(&gate_clk);
  552. ret = reset_get_bulk(dev, &reset_bulk);
  553. if (!ret)
  554. reset_deassert_bulk(&reset_bulk);
  555. ret = mmc_set_mod_clk(priv, 24000000);
  556. if (ret)
  557. return ret;
  558. /* This GPIO is optional */
  559. if (!dev_read_bool(dev, "non-removable") &&
  560. !gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
  561. GPIOD_IS_IN)) {
  562. int cd_pin = gpio_get_number(&priv->cd_gpio);
  563. sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
  564. }
  565. /* Check if card detect is inverted */
  566. priv->cd_inverted = dev_read_bool(dev, "cd-inverted");
  567. upriv->mmc = &plat->mmc;
  568. /* Reset controller */
  569. writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
  570. udelay(1000);
  571. return 0;
  572. }
  573. static int sunxi_mmc_bind(struct udevice *dev)
  574. {
  575. struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
  576. return mmc_bind(dev, &plat->mmc, &plat->cfg);
  577. }
  578. static const struct sunxi_mmc_variant sun4i_a10_variant = {
  579. .mclk_offset = 0x88,
  580. };
  581. static const struct sunxi_mmc_variant sun9i_a80_variant = {
  582. .mclk_offset = 0x410,
  583. };
  584. static const struct sunxi_mmc_variant sun50i_h6_variant = {
  585. .mclk_offset = 0x830,
  586. };
  587. static const struct udevice_id sunxi_mmc_ids[] = {
  588. {
  589. .compatible = "allwinner,sun4i-a10-mmc",
  590. .data = (ulong)&sun4i_a10_variant,
  591. },
  592. {
  593. .compatible = "allwinner,sun5i-a13-mmc",
  594. .data = (ulong)&sun4i_a10_variant,
  595. },
  596. {
  597. .compatible = "allwinner,sun7i-a20-mmc",
  598. .data = (ulong)&sun4i_a10_variant,
  599. },
  600. {
  601. .compatible = "allwinner,sun8i-a83t-emmc",
  602. .data = (ulong)&sun4i_a10_variant,
  603. },
  604. {
  605. .compatible = "allwinner,sun9i-a80-mmc",
  606. .data = (ulong)&sun9i_a80_variant,
  607. },
  608. {
  609. .compatible = "allwinner,sun50i-a64-mmc",
  610. .data = (ulong)&sun4i_a10_variant,
  611. },
  612. {
  613. .compatible = "allwinner,sun50i-a64-emmc",
  614. .data = (ulong)&sun4i_a10_variant,
  615. },
  616. {
  617. .compatible = "allwinner,sun50i-h6-mmc",
  618. .data = (ulong)&sun50i_h6_variant,
  619. },
  620. {
  621. .compatible = "allwinner,sun50i-h6-emmc",
  622. .data = (ulong)&sun50i_h6_variant,
  623. },
  624. { /* sentinel */ }
  625. };
  626. U_BOOT_DRIVER(sunxi_mmc_drv) = {
  627. .name = "sunxi_mmc",
  628. .id = UCLASS_MMC,
  629. .of_match = sunxi_mmc_ids,
  630. .bind = sunxi_mmc_bind,
  631. .probe = sunxi_mmc_probe,
  632. .ops = &sunxi_mmc_ops,
  633. .platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat),
  634. .priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv),
  635. };
  636. #endif