sdhci-xenon.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /*
  2. * Driver for Marvell Xenon SDHC as a platform device
  3. *
  4. * Copyright (C) 2016 Marvell, All Rights Reserved.
  5. *
  6. * Author: Hu Ziji <huziji@marvell.com>
  7. * Date: 2016-8-24
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation version 2.
  12. *
  13. * Inspired by Jisheng Zhang <jszhang@marvell.com>
  14. * Special thanks to Video BG4 project team.
  15. */
  16. #include <linux/delay.h>
  17. #include <linux/ktime.h>
  18. #include <linux/module.h>
  19. #include <linux/of.h>
  20. #include <linux/pm.h>
  21. #include <linux/pm_runtime.h>
  22. #include "sdhci-pltfm.h"
  23. #include "sdhci-xenon.h"
  24. static int xenon_enable_internal_clk(struct sdhci_host *host)
  25. {
  26. u32 reg;
  27. ktime_t timeout;
  28. reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL);
  29. reg |= SDHCI_CLOCK_INT_EN;
  30. sdhci_writel(host, reg, SDHCI_CLOCK_CONTROL);
  31. /* Wait max 20 ms */
  32. timeout = ktime_add_ms(ktime_get(), 20);
  33. while (1) {
  34. bool timedout = ktime_after(ktime_get(), timeout);
  35. reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  36. if (reg & SDHCI_CLOCK_INT_STABLE)
  37. break;
  38. if (timedout) {
  39. dev_err(mmc_dev(host->mmc), "Internal clock never stabilised.\n");
  40. return -ETIMEDOUT;
  41. }
  42. usleep_range(900, 1100);
  43. }
  44. return 0;
  45. }
  46. /* Set SDCLK-off-while-idle */
  47. static void xenon_set_sdclk_off_idle(struct sdhci_host *host,
  48. unsigned char sdhc_id, bool enable)
  49. {
  50. u32 reg;
  51. u32 mask;
  52. reg = sdhci_readl(host, XENON_SYS_OP_CTRL);
  53. /* Get the bit shift basing on the SDHC index */
  54. mask = (0x1 << (XENON_SDCLK_IDLEOFF_ENABLE_SHIFT + sdhc_id));
  55. if (enable)
  56. reg |= mask;
  57. else
  58. reg &= ~mask;
  59. sdhci_writel(host, reg, XENON_SYS_OP_CTRL);
  60. }
  61. /* Enable/Disable the Auto Clock Gating function */
  62. static void xenon_set_acg(struct sdhci_host *host, bool enable)
  63. {
  64. u32 reg;
  65. reg = sdhci_readl(host, XENON_SYS_OP_CTRL);
  66. if (enable)
  67. reg &= ~XENON_AUTO_CLKGATE_DISABLE_MASK;
  68. else
  69. reg |= XENON_AUTO_CLKGATE_DISABLE_MASK;
  70. sdhci_writel(host, reg, XENON_SYS_OP_CTRL);
  71. }
  72. /* Enable this SDHC */
  73. static void xenon_enable_sdhc(struct sdhci_host *host,
  74. unsigned char sdhc_id)
  75. {
  76. u32 reg;
  77. reg = sdhci_readl(host, XENON_SYS_OP_CTRL);
  78. reg |= (BIT(sdhc_id) << XENON_SLOT_ENABLE_SHIFT);
  79. sdhci_writel(host, reg, XENON_SYS_OP_CTRL);
  80. host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
  81. /*
  82. * Force to clear BUS_TEST to
  83. * skip bus_test_pre and bus_test_post
  84. */
  85. host->mmc->caps &= ~MMC_CAP_BUS_WIDTH_TEST;
  86. }
  87. /* Disable this SDHC */
  88. static void xenon_disable_sdhc(struct sdhci_host *host,
  89. unsigned char sdhc_id)
  90. {
  91. u32 reg;
  92. reg = sdhci_readl(host, XENON_SYS_OP_CTRL);
  93. reg &= ~(BIT(sdhc_id) << XENON_SLOT_ENABLE_SHIFT);
  94. sdhci_writel(host, reg, XENON_SYS_OP_CTRL);
  95. }
  96. /* Enable Parallel Transfer Mode */
  97. static void xenon_enable_sdhc_parallel_tran(struct sdhci_host *host,
  98. unsigned char sdhc_id)
  99. {
  100. u32 reg;
  101. reg = sdhci_readl(host, XENON_SYS_EXT_OP_CTRL);
  102. reg |= BIT(sdhc_id);
  103. sdhci_writel(host, reg, XENON_SYS_EXT_OP_CTRL);
  104. }
  105. /* Mask command conflict error */
  106. static void xenon_mask_cmd_conflict_err(struct sdhci_host *host)
  107. {
  108. u32 reg;
  109. reg = sdhci_readl(host, XENON_SYS_EXT_OP_CTRL);
  110. reg |= XENON_MASK_CMD_CONFLICT_ERR;
  111. sdhci_writel(host, reg, XENON_SYS_EXT_OP_CTRL);
  112. }
  113. static void xenon_retune_setup(struct sdhci_host *host)
  114. {
  115. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  116. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  117. u32 reg;
  118. /* Disable the Re-Tuning Request functionality */
  119. reg = sdhci_readl(host, XENON_SLOT_RETUNING_REQ_CTRL);
  120. reg &= ~XENON_RETUNING_COMPATIBLE;
  121. sdhci_writel(host, reg, XENON_SLOT_RETUNING_REQ_CTRL);
  122. /* Disable the Re-tuning Interrupt */
  123. reg = sdhci_readl(host, SDHCI_SIGNAL_ENABLE);
  124. reg &= ~SDHCI_INT_RETUNE;
  125. sdhci_writel(host, reg, SDHCI_SIGNAL_ENABLE);
  126. reg = sdhci_readl(host, SDHCI_INT_ENABLE);
  127. reg &= ~SDHCI_INT_RETUNE;
  128. sdhci_writel(host, reg, SDHCI_INT_ENABLE);
  129. /* Force to use Tuning Mode 1 */
  130. host->tuning_mode = SDHCI_TUNING_MODE_1;
  131. /* Set re-tuning period */
  132. host->tuning_count = 1 << (priv->tuning_count - 1);
  133. }
  134. /*
  135. * Operations inside struct sdhci_ops
  136. */
  137. /* Recover the Register Setting cleared during SOFTWARE_RESET_ALL */
  138. static void xenon_reset_exit(struct sdhci_host *host,
  139. unsigned char sdhc_id, u8 mask)
  140. {
  141. /* Only SOFTWARE RESET ALL will clear the register setting */
  142. if (!(mask & SDHCI_RESET_ALL))
  143. return;
  144. /* Disable tuning request and auto-retuning again */
  145. xenon_retune_setup(host);
  146. /*
  147. * The ACG should be turned off at the early init time, in order
  148. * to solve a possible issues with the 1.8V regulator stabilization.
  149. * The feature is enabled in later stage.
  150. */
  151. xenon_set_acg(host, false);
  152. xenon_set_sdclk_off_idle(host, sdhc_id, false);
  153. xenon_mask_cmd_conflict_err(host);
  154. }
  155. static void xenon_reset(struct sdhci_host *host, u8 mask)
  156. {
  157. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  158. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  159. sdhci_reset(host, mask);
  160. xenon_reset_exit(host, priv->sdhc_id, mask);
  161. }
  162. /*
  163. * Xenon defines different values for HS200 and HS400
  164. * in Host_Control_2
  165. */
  166. static void xenon_set_uhs_signaling(struct sdhci_host *host,
  167. unsigned int timing)
  168. {
  169. u16 ctrl_2;
  170. ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  171. /* Select Bus Speed Mode for host */
  172. ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  173. if (timing == MMC_TIMING_MMC_HS200)
  174. ctrl_2 |= XENON_CTRL_HS200;
  175. else if (timing == MMC_TIMING_UHS_SDR104)
  176. ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  177. else if (timing == MMC_TIMING_UHS_SDR12)
  178. ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  179. else if (timing == MMC_TIMING_UHS_SDR25)
  180. ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  181. else if (timing == MMC_TIMING_UHS_SDR50)
  182. ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  183. else if ((timing == MMC_TIMING_UHS_DDR50) ||
  184. (timing == MMC_TIMING_MMC_DDR52))
  185. ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  186. else if (timing == MMC_TIMING_MMC_HS400)
  187. ctrl_2 |= XENON_CTRL_HS400;
  188. sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  189. }
  190. static void xenon_set_power(struct sdhci_host *host, unsigned char mode,
  191. unsigned short vdd)
  192. {
  193. struct mmc_host *mmc = host->mmc;
  194. u8 pwr = host->pwr;
  195. sdhci_set_power_noreg(host, mode, vdd);
  196. if (host->pwr == pwr)
  197. return;
  198. if (host->pwr == 0)
  199. vdd = 0;
  200. if (!IS_ERR(mmc->supply.vmmc))
  201. mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
  202. }
  203. static void xenon_voltage_switch(struct sdhci_host *host)
  204. {
  205. /* Wait for 5ms after set 1.8V signal enable bit */
  206. usleep_range(5000, 5500);
  207. /*
  208. * For some reason the controller's Host Control2 register reports
  209. * the bit representing 1.8V signaling as 0 when read after it was
  210. * written as 1. Subsequent read reports 1.
  211. *
  212. * Since this may cause some issues, do an empty read of the Host
  213. * Control2 register here to circumvent this.
  214. */
  215. sdhci_readw(host, SDHCI_HOST_CONTROL2);
  216. }
  217. static const struct sdhci_ops sdhci_xenon_ops = {
  218. .voltage_switch = xenon_voltage_switch,
  219. .set_clock = sdhci_set_clock,
  220. .set_power = xenon_set_power,
  221. .set_bus_width = sdhci_set_bus_width,
  222. .reset = xenon_reset,
  223. .set_uhs_signaling = xenon_set_uhs_signaling,
  224. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  225. };
  226. static const struct sdhci_pltfm_data sdhci_xenon_pdata = {
  227. .ops = &sdhci_xenon_ops,
  228. .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
  229. SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
  230. SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
  231. };
  232. /*
  233. * Xenon Specific Operations in mmc_host_ops
  234. */
  235. static void xenon_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
  236. {
  237. struct sdhci_host *host = mmc_priv(mmc);
  238. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  239. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  240. u32 reg;
  241. /*
  242. * HS400/HS200/eMMC HS doesn't have Preset Value register.
  243. * However, sdhci_set_ios will read HS400/HS200 Preset register.
  244. * Disable Preset Value register for HS400/HS200.
  245. * eMMC HS with preset_enabled set will trigger a bug in
  246. * get_preset_value().
  247. */
  248. if ((ios->timing == MMC_TIMING_MMC_HS400) ||
  249. (ios->timing == MMC_TIMING_MMC_HS200) ||
  250. (ios->timing == MMC_TIMING_MMC_HS)) {
  251. host->preset_enabled = false;
  252. host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
  253. host->flags &= ~SDHCI_PV_ENABLED;
  254. reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  255. reg &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  256. sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
  257. } else {
  258. host->quirks2 &= ~SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
  259. }
  260. sdhci_set_ios(mmc, ios);
  261. xenon_phy_adj(host, ios);
  262. if (host->clock > XENON_DEFAULT_SDCLK_FREQ)
  263. xenon_set_sdclk_off_idle(host, priv->sdhc_id, true);
  264. }
  265. static int xenon_start_signal_voltage_switch(struct mmc_host *mmc,
  266. struct mmc_ios *ios)
  267. {
  268. struct sdhci_host *host = mmc_priv(mmc);
  269. /*
  270. * Before SD/SDIO set signal voltage, SD bus clock should be
  271. * disabled. However, sdhci_set_clock will also disable the Internal
  272. * clock in mmc_set_signal_voltage().
  273. * If Internal clock is disabled, the 3.3V/1.8V bit can not be updated.
  274. * Thus here manually enable internal clock.
  275. *
  276. * After switch completes, it is unnecessary to disable internal clock,
  277. * since keeping internal clock active obeys SD spec.
  278. */
  279. xenon_enable_internal_clk(host);
  280. xenon_soc_pad_ctrl(host, ios->signal_voltage);
  281. /*
  282. * If Vqmmc is fixed on platform, vqmmc regulator should be unavailable.
  283. * Thus SDHCI_CTRL_VDD_180 bit might not work then.
  284. * Skip the standard voltage switch to avoid any issue.
  285. */
  286. if (PTR_ERR(mmc->supply.vqmmc) == -ENODEV)
  287. return 0;
  288. return sdhci_start_signal_voltage_switch(mmc, ios);
  289. }
  290. /*
  291. * Update card type.
  292. * priv->init_card_type will be used in PHY timing adjustment.
  293. */
  294. static void xenon_init_card(struct mmc_host *mmc, struct mmc_card *card)
  295. {
  296. struct sdhci_host *host = mmc_priv(mmc);
  297. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  298. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  299. /* Update card type*/
  300. priv->init_card_type = card->type;
  301. }
  302. static int xenon_execute_tuning(struct mmc_host *mmc, u32 opcode)
  303. {
  304. struct sdhci_host *host = mmc_priv(mmc);
  305. if (host->timing == MMC_TIMING_UHS_DDR50 ||
  306. host->timing == MMC_TIMING_MMC_DDR52)
  307. return 0;
  308. /*
  309. * Currently force Xenon driver back to support mode 1 only,
  310. * even though Xenon might claim to support mode 2 or mode 3.
  311. * It requires more time to test mode 2/mode 3 on more platforms.
  312. */
  313. if (host->tuning_mode != SDHCI_TUNING_MODE_1)
  314. xenon_retune_setup(host);
  315. return sdhci_execute_tuning(mmc, opcode);
  316. }
  317. static void xenon_enable_sdio_irq(struct mmc_host *mmc, int enable)
  318. {
  319. struct sdhci_host *host = mmc_priv(mmc);
  320. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  321. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  322. u32 reg;
  323. u8 sdhc_id = priv->sdhc_id;
  324. sdhci_enable_sdio_irq(mmc, enable);
  325. if (enable) {
  326. /*
  327. * Set SDIO Card Inserted indication
  328. * to enable detecting SDIO async irq.
  329. */
  330. reg = sdhci_readl(host, XENON_SYS_CFG_INFO);
  331. reg |= (1 << (sdhc_id + XENON_SLOT_TYPE_SDIO_SHIFT));
  332. sdhci_writel(host, reg, XENON_SYS_CFG_INFO);
  333. } else {
  334. /* Clear SDIO Card Inserted indication */
  335. reg = sdhci_readl(host, XENON_SYS_CFG_INFO);
  336. reg &= ~(1 << (sdhc_id + XENON_SLOT_TYPE_SDIO_SHIFT));
  337. sdhci_writel(host, reg, XENON_SYS_CFG_INFO);
  338. }
  339. }
  340. static void xenon_replace_mmc_host_ops(struct sdhci_host *host)
  341. {
  342. host->mmc_host_ops.set_ios = xenon_set_ios;
  343. host->mmc_host_ops.start_signal_voltage_switch =
  344. xenon_start_signal_voltage_switch;
  345. host->mmc_host_ops.init_card = xenon_init_card;
  346. host->mmc_host_ops.execute_tuning = xenon_execute_tuning;
  347. host->mmc_host_ops.enable_sdio_irq = xenon_enable_sdio_irq;
  348. }
  349. /*
  350. * Parse Xenon specific DT properties:
  351. * sdhc-id: the index of current SDHC.
  352. * Refer to XENON_SYS_CFG_INFO register
  353. * tun-count: the interval between re-tuning
  354. */
  355. static int xenon_probe_dt(struct platform_device *pdev)
  356. {
  357. struct device_node *np = pdev->dev.of_node;
  358. struct sdhci_host *host = platform_get_drvdata(pdev);
  359. struct mmc_host *mmc = host->mmc;
  360. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  361. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  362. u32 sdhc_id, nr_sdhc;
  363. u32 tuning_count;
  364. /* Disable HS200 on Armada AP806 */
  365. if (of_device_is_compatible(np, "marvell,armada-ap806-sdhci"))
  366. host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
  367. sdhc_id = 0x0;
  368. if (!of_property_read_u32(np, "marvell,xenon-sdhc-id", &sdhc_id)) {
  369. nr_sdhc = sdhci_readl(host, XENON_SYS_CFG_INFO);
  370. nr_sdhc &= XENON_NR_SUPPORTED_SLOT_MASK;
  371. if (unlikely(sdhc_id > nr_sdhc)) {
  372. dev_err(mmc_dev(mmc), "SDHC Index %d exceeds Number of SDHCs %d\n",
  373. sdhc_id, nr_sdhc);
  374. return -EINVAL;
  375. }
  376. }
  377. priv->sdhc_id = sdhc_id;
  378. tuning_count = XENON_DEF_TUNING_COUNT;
  379. if (!of_property_read_u32(np, "marvell,xenon-tun-count",
  380. &tuning_count)) {
  381. if (unlikely(tuning_count >= XENON_TMR_RETUN_NO_PRESENT)) {
  382. dev_err(mmc_dev(mmc), "Wrong Re-tuning Count. Set default value %d\n",
  383. XENON_DEF_TUNING_COUNT);
  384. tuning_count = XENON_DEF_TUNING_COUNT;
  385. }
  386. }
  387. priv->tuning_count = tuning_count;
  388. return xenon_phy_parse_dt(np, host);
  389. }
  390. static int xenon_sdhc_prepare(struct sdhci_host *host)
  391. {
  392. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  393. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  394. u8 sdhc_id = priv->sdhc_id;
  395. /* Enable SDHC */
  396. xenon_enable_sdhc(host, sdhc_id);
  397. /* Enable ACG */
  398. xenon_set_acg(host, true);
  399. /* Enable Parallel Transfer Mode */
  400. xenon_enable_sdhc_parallel_tran(host, sdhc_id);
  401. /* Disable SDCLK-Off-While-Idle before card init */
  402. xenon_set_sdclk_off_idle(host, sdhc_id, false);
  403. xenon_mask_cmd_conflict_err(host);
  404. return 0;
  405. }
  406. static void xenon_sdhc_unprepare(struct sdhci_host *host)
  407. {
  408. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  409. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  410. u8 sdhc_id = priv->sdhc_id;
  411. /* disable SDHC */
  412. xenon_disable_sdhc(host, sdhc_id);
  413. }
  414. static int xenon_probe(struct platform_device *pdev)
  415. {
  416. struct sdhci_pltfm_host *pltfm_host;
  417. struct sdhci_host *host;
  418. struct xenon_priv *priv;
  419. int err;
  420. host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata,
  421. sizeof(struct xenon_priv));
  422. if (IS_ERR(host))
  423. return PTR_ERR(host);
  424. pltfm_host = sdhci_priv(host);
  425. priv = sdhci_pltfm_priv(pltfm_host);
  426. /*
  427. * Link Xenon specific mmc_host_ops function,
  428. * to replace standard ones in sdhci_ops.
  429. */
  430. xenon_replace_mmc_host_ops(host);
  431. pltfm_host->clk = devm_clk_get(&pdev->dev, "core");
  432. if (IS_ERR(pltfm_host->clk)) {
  433. err = PTR_ERR(pltfm_host->clk);
  434. dev_err(&pdev->dev, "Failed to setup input clk: %d\n", err);
  435. goto free_pltfm;
  436. }
  437. err = clk_prepare_enable(pltfm_host->clk);
  438. if (err)
  439. goto free_pltfm;
  440. priv->axi_clk = devm_clk_get(&pdev->dev, "axi");
  441. if (IS_ERR(priv->axi_clk)) {
  442. err = PTR_ERR(priv->axi_clk);
  443. if (err == -EPROBE_DEFER)
  444. goto err_clk;
  445. } else {
  446. err = clk_prepare_enable(priv->axi_clk);
  447. if (err)
  448. goto err_clk;
  449. }
  450. err = mmc_of_parse(host->mmc);
  451. if (err)
  452. goto err_clk_axi;
  453. sdhci_get_of_property(pdev);
  454. xenon_set_acg(host, false);
  455. /* Xenon specific dt parse */
  456. err = xenon_probe_dt(pdev);
  457. if (err)
  458. goto err_clk_axi;
  459. err = xenon_sdhc_prepare(host);
  460. if (err)
  461. goto err_clk_axi;
  462. pm_runtime_get_noresume(&pdev->dev);
  463. pm_runtime_set_active(&pdev->dev);
  464. pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
  465. pm_runtime_use_autosuspend(&pdev->dev);
  466. pm_runtime_enable(&pdev->dev);
  467. pm_suspend_ignore_children(&pdev->dev, 1);
  468. err = sdhci_add_host(host);
  469. if (err)
  470. goto remove_sdhc;
  471. pm_runtime_put_autosuspend(&pdev->dev);
  472. return 0;
  473. remove_sdhc:
  474. pm_runtime_disable(&pdev->dev);
  475. pm_runtime_put_noidle(&pdev->dev);
  476. xenon_sdhc_unprepare(host);
  477. err_clk_axi:
  478. clk_disable_unprepare(priv->axi_clk);
  479. err_clk:
  480. clk_disable_unprepare(pltfm_host->clk);
  481. free_pltfm:
  482. sdhci_pltfm_free(pdev);
  483. return err;
  484. }
  485. static int xenon_remove(struct platform_device *pdev)
  486. {
  487. struct sdhci_host *host = platform_get_drvdata(pdev);
  488. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  489. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  490. pm_runtime_get_sync(&pdev->dev);
  491. pm_runtime_disable(&pdev->dev);
  492. pm_runtime_put_noidle(&pdev->dev);
  493. sdhci_remove_host(host, 0);
  494. xenon_sdhc_unprepare(host);
  495. clk_disable_unprepare(priv->axi_clk);
  496. clk_disable_unprepare(pltfm_host->clk);
  497. sdhci_pltfm_free(pdev);
  498. return 0;
  499. }
  500. #ifdef CONFIG_PM_SLEEP
  501. static int xenon_suspend(struct device *dev)
  502. {
  503. struct sdhci_host *host = dev_get_drvdata(dev);
  504. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  505. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  506. int ret;
  507. ret = pm_runtime_force_suspend(dev);
  508. priv->restore_needed = true;
  509. return ret;
  510. }
  511. #endif
  512. #ifdef CONFIG_PM
  513. static int xenon_runtime_suspend(struct device *dev)
  514. {
  515. struct sdhci_host *host = dev_get_drvdata(dev);
  516. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  517. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  518. int ret;
  519. ret = sdhci_runtime_suspend_host(host);
  520. if (ret)
  521. return ret;
  522. if (host->tuning_mode != SDHCI_TUNING_MODE_3)
  523. mmc_retune_needed(host->mmc);
  524. clk_disable_unprepare(pltfm_host->clk);
  525. /*
  526. * Need to update the priv->clock here, or when runtime resume
  527. * back, phy don't aware the clock change and won't adjust phy
  528. * which will cause cmd err
  529. */
  530. priv->clock = 0;
  531. return 0;
  532. }
  533. static int xenon_runtime_resume(struct device *dev)
  534. {
  535. struct sdhci_host *host = dev_get_drvdata(dev);
  536. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  537. struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
  538. int ret;
  539. ret = clk_prepare_enable(pltfm_host->clk);
  540. if (ret) {
  541. dev_err(dev, "can't enable mainck\n");
  542. return ret;
  543. }
  544. if (priv->restore_needed) {
  545. ret = xenon_sdhc_prepare(host);
  546. if (ret)
  547. goto out;
  548. priv->restore_needed = false;
  549. }
  550. ret = sdhci_runtime_resume_host(host);
  551. if (ret)
  552. goto out;
  553. return 0;
  554. out:
  555. clk_disable_unprepare(pltfm_host->clk);
  556. return ret;
  557. }
  558. #endif /* CONFIG_PM */
  559. static const struct dev_pm_ops sdhci_xenon_dev_pm_ops = {
  560. SET_SYSTEM_SLEEP_PM_OPS(xenon_suspend,
  561. pm_runtime_force_resume)
  562. SET_RUNTIME_PM_OPS(xenon_runtime_suspend,
  563. xenon_runtime_resume,
  564. NULL)
  565. };
  566. static const struct of_device_id sdhci_xenon_dt_ids[] = {
  567. { .compatible = "marvell,armada-ap806-sdhci",},
  568. { .compatible = "marvell,armada-cp110-sdhci",},
  569. { .compatible = "marvell,armada-3700-sdhci",},
  570. {}
  571. };
  572. MODULE_DEVICE_TABLE(of, sdhci_xenon_dt_ids);
  573. static struct platform_driver sdhci_xenon_driver = {
  574. .driver = {
  575. .name = "xenon-sdhci",
  576. .of_match_table = sdhci_xenon_dt_ids,
  577. .pm = &sdhci_xenon_dev_pm_ops,
  578. },
  579. .probe = xenon_probe,
  580. .remove = xenon_remove,
  581. };
  582. module_platform_driver(sdhci_xenon_driver);
  583. MODULE_DESCRIPTION("SDHCI platform driver for Marvell Xenon SDHC");
  584. MODULE_AUTHOR("Hu Ziji <huziji@marvell.com>");
  585. MODULE_LICENSE("GPL v2");