sdhci-brcmstb.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * sdhci-brcmstb.c Support for SDHCI on Broadcom BRCMSTB SoC's
  4. *
  5. * Copyright (C) 2015 Broadcom Corporation
  6. */
  7. #include <linux/io.h>
  8. #include <linux/mmc/host.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/bitops.h>
  12. #include <linux/delay.h>
  13. #include "sdhci-cqhci.h"
  14. #include "sdhci-pltfm.h"
  15. #include "cqhci.h"
  16. #define SDHCI_VENDOR 0x78
  17. #define SDHCI_VENDOR_ENHANCED_STRB 0x1
  18. #define SDHCI_VENDOR_GATE_SDCLK_EN 0x2
  19. #define BRCMSTB_MATCH_FLAGS_NO_64BIT BIT(0)
  20. #define BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT BIT(1)
  21. #define BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE BIT(2)
  22. #define BRCMSTB_PRIV_FLAGS_HAS_CQE BIT(0)
  23. #define BRCMSTB_PRIV_FLAGS_GATE_CLOCK BIT(1)
  24. #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200
  25. struct sdhci_brcmstb_priv {
  26. void __iomem *cfg_regs;
  27. unsigned int flags;
  28. struct clk *base_clk;
  29. u32 base_freq_hz;
  30. };
  31. struct brcmstb_match_priv {
  32. void (*hs400es)(struct mmc_host *mmc, struct mmc_ios *ios);
  33. struct sdhci_ops *ops;
  34. const unsigned int flags;
  35. };
  36. static inline void enable_clock_gating(struct sdhci_host *host)
  37. {
  38. u32 reg;
  39. reg = sdhci_readl(host, SDHCI_VENDOR);
  40. reg |= SDHCI_VENDOR_GATE_SDCLK_EN;
  41. sdhci_writel(host, reg, SDHCI_VENDOR);
  42. }
  43. static void brcmstb_reset(struct sdhci_host *host, u8 mask)
  44. {
  45. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  46. struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
  47. sdhci_and_cqhci_reset(host, mask);
  48. /* Reset will clear this, so re-enable it */
  49. if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK)
  50. enable_clock_gating(host);
  51. }
  52. static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios)
  53. {
  54. struct sdhci_host *host = mmc_priv(mmc);
  55. u32 reg;
  56. dev_dbg(mmc_dev(mmc), "%s(): Setting HS400-Enhanced-Strobe mode\n",
  57. __func__);
  58. reg = readl(host->ioaddr + SDHCI_VENDOR);
  59. if (ios->enhanced_strobe)
  60. reg |= SDHCI_VENDOR_ENHANCED_STRB;
  61. else
  62. reg &= ~SDHCI_VENDOR_ENHANCED_STRB;
  63. writel(reg, host->ioaddr + SDHCI_VENDOR);
  64. }
  65. static void sdhci_brcmstb_set_clock(struct sdhci_host *host, unsigned int clock)
  66. {
  67. u16 clk;
  68. host->mmc->actual_clock = 0;
  69. clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
  70. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  71. if (clock == 0)
  72. return;
  73. sdhci_enable_clk(host, clk);
  74. }
  75. static void sdhci_brcmstb_set_uhs_signaling(struct sdhci_host *host,
  76. unsigned int timing)
  77. {
  78. u16 ctrl_2;
  79. dev_dbg(mmc_dev(host->mmc), "%s: Setting UHS signaling for %d timing\n",
  80. __func__, timing);
  81. ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  82. /* Select Bus Speed Mode for host */
  83. ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  84. if ((timing == MMC_TIMING_MMC_HS200) ||
  85. (timing == MMC_TIMING_UHS_SDR104))
  86. ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  87. else if (timing == MMC_TIMING_UHS_SDR12)
  88. ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  89. else if (timing == MMC_TIMING_SD_HS ||
  90. timing == MMC_TIMING_MMC_HS ||
  91. timing == MMC_TIMING_UHS_SDR25)
  92. ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  93. else if (timing == MMC_TIMING_UHS_SDR50)
  94. ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  95. else if ((timing == MMC_TIMING_UHS_DDR50) ||
  96. (timing == MMC_TIMING_MMC_DDR52))
  97. ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  98. else if (timing == MMC_TIMING_MMC_HS400)
  99. ctrl_2 |= SDHCI_CTRL_HS400; /* Non-standard */
  100. sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  101. }
  102. static void sdhci_brcmstb_dumpregs(struct mmc_host *mmc)
  103. {
  104. sdhci_dumpregs(mmc_priv(mmc));
  105. }
  106. static void sdhci_brcmstb_cqe_enable(struct mmc_host *mmc)
  107. {
  108. struct sdhci_host *host = mmc_priv(mmc);
  109. u32 reg;
  110. reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
  111. while (reg & SDHCI_DATA_AVAILABLE) {
  112. sdhci_readl(host, SDHCI_BUFFER);
  113. reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
  114. }
  115. sdhci_cqe_enable(mmc);
  116. }
  117. static const struct cqhci_host_ops sdhci_brcmstb_cqhci_ops = {
  118. .enable = sdhci_brcmstb_cqe_enable,
  119. .disable = sdhci_cqe_disable,
  120. .dumpregs = sdhci_brcmstb_dumpregs,
  121. };
  122. static struct sdhci_ops sdhci_brcmstb_ops = {
  123. .set_clock = sdhci_set_clock,
  124. .set_bus_width = sdhci_set_bus_width,
  125. .reset = sdhci_reset,
  126. .set_uhs_signaling = sdhci_set_uhs_signaling,
  127. };
  128. static struct sdhci_ops sdhci_brcmstb_ops_7216 = {
  129. .set_clock = sdhci_brcmstb_set_clock,
  130. .set_bus_width = sdhci_set_bus_width,
  131. .reset = brcmstb_reset,
  132. .set_uhs_signaling = sdhci_brcmstb_set_uhs_signaling,
  133. };
  134. static struct brcmstb_match_priv match_priv_7425 = {
  135. .flags = BRCMSTB_MATCH_FLAGS_NO_64BIT |
  136. BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT,
  137. .ops = &sdhci_brcmstb_ops,
  138. };
  139. static struct brcmstb_match_priv match_priv_7445 = {
  140. .flags = BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT,
  141. .ops = &sdhci_brcmstb_ops,
  142. };
  143. static const struct brcmstb_match_priv match_priv_7216 = {
  144. .flags = BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE,
  145. .hs400es = sdhci_brcmstb_hs400es,
  146. .ops = &sdhci_brcmstb_ops_7216,
  147. };
  148. static const struct of_device_id sdhci_brcm_of_match[] = {
  149. { .compatible = "brcm,bcm7425-sdhci", .data = &match_priv_7425 },
  150. { .compatible = "brcm,bcm7445-sdhci", .data = &match_priv_7445 },
  151. { .compatible = "brcm,bcm7216-sdhci", .data = &match_priv_7216 },
  152. {},
  153. };
  154. static u32 sdhci_brcmstb_cqhci_irq(struct sdhci_host *host, u32 intmask)
  155. {
  156. int cmd_error = 0;
  157. int data_error = 0;
  158. if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
  159. return intmask;
  160. cqhci_irq(host->mmc, intmask, cmd_error, data_error);
  161. return 0;
  162. }
  163. static int sdhci_brcmstb_add_host(struct sdhci_host *host,
  164. struct sdhci_brcmstb_priv *priv)
  165. {
  166. struct cqhci_host *cq_host;
  167. bool dma64;
  168. int ret;
  169. if ((priv->flags & BRCMSTB_PRIV_FLAGS_HAS_CQE) == 0)
  170. return sdhci_add_host(host);
  171. dev_dbg(mmc_dev(host->mmc), "CQE is enabled\n");
  172. host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
  173. ret = sdhci_setup_host(host);
  174. if (ret)
  175. return ret;
  176. cq_host = devm_kzalloc(mmc_dev(host->mmc),
  177. sizeof(*cq_host), GFP_KERNEL);
  178. if (!cq_host) {
  179. ret = -ENOMEM;
  180. goto cleanup;
  181. }
  182. cq_host->mmio = host->ioaddr + SDHCI_ARASAN_CQE_BASE_ADDR;
  183. cq_host->ops = &sdhci_brcmstb_cqhci_ops;
  184. dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
  185. if (dma64) {
  186. dev_dbg(mmc_dev(host->mmc), "Using 64 bit DMA\n");
  187. cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
  188. }
  189. ret = cqhci_init(cq_host, host->mmc, dma64);
  190. if (ret)
  191. goto cleanup;
  192. ret = __sdhci_add_host(host);
  193. if (ret)
  194. goto cleanup;
  195. return 0;
  196. cleanup:
  197. sdhci_cleanup_host(host);
  198. return ret;
  199. }
  200. static int sdhci_brcmstb_probe(struct platform_device *pdev)
  201. {
  202. const struct brcmstb_match_priv *match_priv;
  203. struct sdhci_pltfm_data brcmstb_pdata;
  204. struct sdhci_pltfm_host *pltfm_host;
  205. const struct of_device_id *match;
  206. struct sdhci_brcmstb_priv *priv;
  207. u32 actual_clock_mhz;
  208. struct sdhci_host *host;
  209. struct resource *iomem;
  210. struct clk *clk;
  211. struct clk *base_clk = NULL;
  212. int res;
  213. match = of_match_node(sdhci_brcm_of_match, pdev->dev.of_node);
  214. match_priv = match->data;
  215. dev_dbg(&pdev->dev, "Probe found match for %s\n", match->compatible);
  216. clk = devm_clk_get_optional(&pdev->dev, NULL);
  217. if (IS_ERR(clk))
  218. return dev_err_probe(&pdev->dev, PTR_ERR(clk),
  219. "Failed to get clock from Device Tree\n");
  220. res = clk_prepare_enable(clk);
  221. if (res)
  222. return res;
  223. memset(&brcmstb_pdata, 0, sizeof(brcmstb_pdata));
  224. brcmstb_pdata.ops = match_priv->ops;
  225. host = sdhci_pltfm_init(pdev, &brcmstb_pdata,
  226. sizeof(struct sdhci_brcmstb_priv));
  227. if (IS_ERR(host)) {
  228. res = PTR_ERR(host);
  229. goto err_clk;
  230. }
  231. pltfm_host = sdhci_priv(host);
  232. priv = sdhci_pltfm_priv(pltfm_host);
  233. if (device_property_read_bool(&pdev->dev, "supports-cqe")) {
  234. priv->flags |= BRCMSTB_PRIV_FLAGS_HAS_CQE;
  235. match_priv->ops->irq = sdhci_brcmstb_cqhci_irq;
  236. }
  237. /* Map in the non-standard CFG registers */
  238. iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  239. priv->cfg_regs = devm_ioremap_resource(&pdev->dev, iomem);
  240. if (IS_ERR(priv->cfg_regs)) {
  241. res = PTR_ERR(priv->cfg_regs);
  242. goto err;
  243. }
  244. sdhci_get_of_property(pdev);
  245. res = mmc_of_parse(host->mmc);
  246. if (res)
  247. goto err;
  248. /*
  249. * Automatic clock gating does not work for SD cards that may
  250. * voltage switch so only enable it for non-removable devices.
  251. */
  252. if ((match_priv->flags & BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE) &&
  253. (host->mmc->caps & MMC_CAP_NONREMOVABLE))
  254. priv->flags |= BRCMSTB_PRIV_FLAGS_GATE_CLOCK;
  255. /*
  256. * If the chip has enhanced strobe and it's enabled, add
  257. * callback
  258. */
  259. if (match_priv->hs400es &&
  260. (host->mmc->caps2 & MMC_CAP2_HS400_ES))
  261. host->mmc_host_ops.hs400_enhanced_strobe = match_priv->hs400es;
  262. /*
  263. * Supply the existing CAPS, but clear the UHS modes. This
  264. * will allow these modes to be specified by device tree
  265. * properties through mmc_of_parse().
  266. */
  267. host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
  268. if (match_priv->flags & BRCMSTB_MATCH_FLAGS_NO_64BIT)
  269. host->caps &= ~SDHCI_CAN_64BIT;
  270. host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
  271. host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
  272. SDHCI_SUPPORT_DDR50);
  273. host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
  274. if (match_priv->flags & BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT)
  275. host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
  276. /* Change the base clock frequency if the DT property exists */
  277. if (device_property_read_u32(&pdev->dev, "clock-frequency",
  278. &priv->base_freq_hz) != 0)
  279. goto add_host;
  280. base_clk = devm_clk_get_optional(&pdev->dev, "sdio_freq");
  281. if (IS_ERR(base_clk)) {
  282. dev_warn(&pdev->dev, "Clock for \"sdio_freq\" not found\n");
  283. goto add_host;
  284. }
  285. res = clk_prepare_enable(base_clk);
  286. if (res)
  287. goto err;
  288. /* set improved clock rate */
  289. clk_set_rate(base_clk, priv->base_freq_hz);
  290. actual_clock_mhz = clk_get_rate(base_clk) / 1000000;
  291. host->caps &= ~SDHCI_CLOCK_V3_BASE_MASK;
  292. host->caps |= (actual_clock_mhz << SDHCI_CLOCK_BASE_SHIFT);
  293. /* Disable presets because they are now incorrect */
  294. host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
  295. dev_dbg(&pdev->dev, "Base Clock Frequency changed to %dMHz\n",
  296. actual_clock_mhz);
  297. priv->base_clk = base_clk;
  298. add_host:
  299. res = sdhci_brcmstb_add_host(host, priv);
  300. if (res)
  301. goto err;
  302. pltfm_host->clk = clk;
  303. return res;
  304. err:
  305. sdhci_pltfm_free(pdev);
  306. err_clk:
  307. clk_disable_unprepare(base_clk);
  308. clk_disable_unprepare(clk);
  309. return res;
  310. }
  311. static void sdhci_brcmstb_shutdown(struct platform_device *pdev)
  312. {
  313. sdhci_pltfm_suspend(&pdev->dev);
  314. }
  315. MODULE_DEVICE_TABLE(of, sdhci_brcm_of_match);
  316. #ifdef CONFIG_PM_SLEEP
  317. static int sdhci_brcmstb_suspend(struct device *dev)
  318. {
  319. struct sdhci_host *host = dev_get_drvdata(dev);
  320. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  321. struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
  322. clk_disable_unprepare(priv->base_clk);
  323. return sdhci_pltfm_suspend(dev);
  324. }
  325. static int sdhci_brcmstb_resume(struct device *dev)
  326. {
  327. struct sdhci_host *host = dev_get_drvdata(dev);
  328. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  329. struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
  330. int ret;
  331. ret = sdhci_pltfm_resume(dev);
  332. if (!ret && priv->base_freq_hz) {
  333. ret = clk_prepare_enable(priv->base_clk);
  334. /*
  335. * Note: using clk_get_rate() below as clk_get_rate()
  336. * honors CLK_GET_RATE_NOCACHE attribute, but clk_set_rate()
  337. * may do implicit get_rate() calls that do not honor
  338. * CLK_GET_RATE_NOCACHE.
  339. */
  340. if (!ret &&
  341. (clk_get_rate(priv->base_clk) != priv->base_freq_hz))
  342. ret = clk_set_rate(priv->base_clk, priv->base_freq_hz);
  343. }
  344. return ret;
  345. }
  346. #endif
  347. static const struct dev_pm_ops sdhci_brcmstb_pmops = {
  348. SET_SYSTEM_SLEEP_PM_OPS(sdhci_brcmstb_suspend, sdhci_brcmstb_resume)
  349. };
  350. static struct platform_driver sdhci_brcmstb_driver = {
  351. .driver = {
  352. .name = "sdhci-brcmstb",
  353. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  354. .pm = &sdhci_brcmstb_pmops,
  355. .of_match_table = of_match_ptr(sdhci_brcm_of_match),
  356. },
  357. .probe = sdhci_brcmstb_probe,
  358. .remove = sdhci_pltfm_unregister,
  359. .shutdown = sdhci_brcmstb_shutdown,
  360. };
  361. module_platform_driver(sdhci_brcmstb_driver);
  362. MODULE_DESCRIPTION("SDHCI driver for Broadcom BRCMSTB SoCs");
  363. MODULE_AUTHOR("Broadcom");
  364. MODULE_LICENSE("GPL v2");