sdhci-pxa.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /* linux/drivers/mmc/host/sdhci-pxa.c
  2. *
  3. * Copyright (C) 2010 Marvell International Ltd.
  4. * Zhangfei Gao <zhangfei.gao@marvell.com>
  5. * Kevin Wang <dwang4@marvell.com>
  6. * Mingwei Wang <mwwang@marvell.com>
  7. * Philip Rakity <prakity@marvell.com>
  8. * Mark Brown <markb@marvell.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. /* Supports:
  15. * SDHCI support for MMP2/PXA910/PXA168
  16. *
  17. * Refer to sdhci-s3c.c.
  18. */
  19. #include <linux/delay.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/mmc/host.h>
  22. #include <linux/clk.h>
  23. #include <linux/io.h>
  24. #include <linux/err.h>
  25. #include <plat/sdhci.h>
  26. #include "sdhci.h"
  27. #define DRIVER_NAME "sdhci-pxa"
  28. #define SD_FIFO_PARAM 0x104
  29. #define DIS_PAD_SD_CLK_GATE 0x400
  30. struct sdhci_pxa {
  31. struct sdhci_host *host;
  32. struct sdhci_pxa_platdata *pdata;
  33. struct clk *clk;
  34. struct resource *res;
  35. u8 clk_enable;
  36. };
  37. /*****************************************************************************\
  38. * *
  39. * SDHCI core callbacks *
  40. * *
  41. \*****************************************************************************/
  42. static void set_clock(struct sdhci_host *host, unsigned int clock)
  43. {
  44. struct sdhci_pxa *pxa = sdhci_priv(host);
  45. u32 tmp = 0;
  46. if (clock == 0) {
  47. if (pxa->clk_enable) {
  48. clk_disable(pxa->clk);
  49. pxa->clk_enable = 0;
  50. }
  51. } else {
  52. if (0 == pxa->clk_enable) {
  53. if (pxa->pdata->flags & PXA_FLAG_DISABLE_CLOCK_GATING) {
  54. tmp = readl(host->ioaddr + SD_FIFO_PARAM);
  55. tmp |= DIS_PAD_SD_CLK_GATE;
  56. writel(tmp, host->ioaddr + SD_FIFO_PARAM);
  57. }
  58. clk_enable(pxa->clk);
  59. pxa->clk_enable = 1;
  60. }
  61. }
  62. }
  63. static int set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  64. {
  65. u16 ctrl_2;
  66. /*
  67. * Set V18_EN -- UHS modes do not work without this.
  68. * does not change signaling voltage
  69. */
  70. ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  71. /* Select Bus Speed Mode for host */
  72. ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  73. switch (uhs) {
  74. case MMC_TIMING_UHS_SDR12:
  75. ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  76. break;
  77. case MMC_TIMING_UHS_SDR25:
  78. ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  79. break;
  80. case MMC_TIMING_UHS_SDR50:
  81. ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
  82. break;
  83. case MMC_TIMING_UHS_SDR104:
  84. ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
  85. break;
  86. case MMC_TIMING_UHS_DDR50:
  87. ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
  88. break;
  89. }
  90. sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  91. pr_debug("%s:%s uhs = %d, ctrl_2 = %04X\n",
  92. __func__, mmc_hostname(host->mmc), uhs, ctrl_2);
  93. return 0;
  94. }
  95. static struct sdhci_ops sdhci_pxa_ops = {
  96. .set_uhs_signaling = set_uhs_signaling,
  97. .set_clock = set_clock,
  98. };
  99. /*****************************************************************************\
  100. * *
  101. * Device probing/removal *
  102. * *
  103. \*****************************************************************************/
  104. static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
  105. {
  106. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  107. struct device *dev = &pdev->dev;
  108. struct sdhci_host *host = NULL;
  109. struct resource *iomem = NULL;
  110. struct sdhci_pxa *pxa = NULL;
  111. int ret, irq;
  112. irq = platform_get_irq(pdev, 0);
  113. if (irq < 0) {
  114. dev_err(dev, "no irq specified\n");
  115. return irq;
  116. }
  117. iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  118. if (!iomem) {
  119. dev_err(dev, "no memory specified\n");
  120. return -ENOENT;
  121. }
  122. host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
  123. if (IS_ERR(host)) {
  124. dev_err(dev, "failed to alloc host\n");
  125. return PTR_ERR(host);
  126. }
  127. pxa = sdhci_priv(host);
  128. pxa->host = host;
  129. pxa->pdata = pdata;
  130. pxa->clk_enable = 0;
  131. pxa->clk = clk_get(dev, "PXA-SDHCLK");
  132. if (IS_ERR(pxa->clk)) {
  133. dev_err(dev, "failed to get io clock\n");
  134. ret = PTR_ERR(pxa->clk);
  135. goto out;
  136. }
  137. pxa->res = request_mem_region(iomem->start, resource_size(iomem),
  138. mmc_hostname(host->mmc));
  139. if (!pxa->res) {
  140. dev_err(&pdev->dev, "cannot request region\n");
  141. ret = -EBUSY;
  142. goto out;
  143. }
  144. host->ioaddr = ioremap(iomem->start, resource_size(iomem));
  145. if (!host->ioaddr) {
  146. dev_err(&pdev->dev, "failed to remap registers\n");
  147. ret = -ENOMEM;
  148. goto out;
  149. }
  150. host->hw_name = "MMC";
  151. host->ops = &sdhci_pxa_ops;
  152. host->irq = irq;
  153. host->quirks = SDHCI_QUIRK_BROKEN_ADMA
  154. | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
  155. | SDHCI_QUIRK_32BIT_DMA_ADDR
  156. | SDHCI_QUIRK_32BIT_DMA_SIZE
  157. | SDHCI_QUIRK_32BIT_ADMA_SIZE
  158. | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
  159. if (pdata->quirks)
  160. host->quirks |= pdata->quirks;
  161. /* enable 1/8V DDR capable */
  162. host->mmc->caps |= MMC_CAP_1_8V_DDR;
  163. /* If slot design supports 8 bit data, indicate this to MMC. */
  164. if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
  165. host->mmc->caps |= MMC_CAP_8_BIT_DATA;
  166. ret = sdhci_add_host(host);
  167. if (ret) {
  168. dev_err(&pdev->dev, "failed to add host\n");
  169. goto out;
  170. }
  171. if (pxa->pdata->max_speed)
  172. host->mmc->f_max = pxa->pdata->max_speed;
  173. platform_set_drvdata(pdev, host);
  174. return 0;
  175. out:
  176. if (host) {
  177. clk_put(pxa->clk);
  178. if (host->ioaddr)
  179. iounmap(host->ioaddr);
  180. if (pxa->res)
  181. release_mem_region(pxa->res->start,
  182. resource_size(pxa->res));
  183. sdhci_free_host(host);
  184. }
  185. return ret;
  186. }
  187. static int __devexit sdhci_pxa_remove(struct platform_device *pdev)
  188. {
  189. struct sdhci_host *host = platform_get_drvdata(pdev);
  190. struct sdhci_pxa *pxa = sdhci_priv(host);
  191. int dead = 0;
  192. u32 scratch;
  193. if (host) {
  194. scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
  195. if (scratch == (u32)-1)
  196. dead = 1;
  197. sdhci_remove_host(host, dead);
  198. if (host->ioaddr)
  199. iounmap(host->ioaddr);
  200. if (pxa->res)
  201. release_mem_region(pxa->res->start,
  202. resource_size(pxa->res));
  203. if (pxa->clk_enable) {
  204. clk_disable(pxa->clk);
  205. pxa->clk_enable = 0;
  206. }
  207. clk_put(pxa->clk);
  208. sdhci_free_host(host);
  209. platform_set_drvdata(pdev, NULL);
  210. }
  211. return 0;
  212. }
  213. #ifdef CONFIG_PM
  214. static int sdhci_pxa_suspend(struct platform_device *dev, pm_message_t state)
  215. {
  216. struct sdhci_host *host = platform_get_drvdata(dev);
  217. return sdhci_suspend_host(host, state);
  218. }
  219. static int sdhci_pxa_resume(struct platform_device *dev)
  220. {
  221. struct sdhci_host *host = platform_get_drvdata(dev);
  222. return sdhci_resume_host(host);
  223. }
  224. #else
  225. #define sdhci_pxa_suspend NULL
  226. #define sdhci_pxa_resume NULL
  227. #endif
  228. static struct platform_driver sdhci_pxa_driver = {
  229. .probe = sdhci_pxa_probe,
  230. .remove = __devexit_p(sdhci_pxa_remove),
  231. .suspend = sdhci_pxa_suspend,
  232. .resume = sdhci_pxa_resume,
  233. .driver = {
  234. .name = DRIVER_NAME,
  235. .owner = THIS_MODULE,
  236. },
  237. };
  238. /*****************************************************************************\
  239. * *
  240. * Driver init/exit *
  241. * *
  242. \*****************************************************************************/
  243. static int __init sdhci_pxa_init(void)
  244. {
  245. return platform_driver_register(&sdhci_pxa_driver);
  246. }
  247. static void __exit sdhci_pxa_exit(void)
  248. {
  249. platform_driver_unregister(&sdhci_pxa_driver);
  250. }
  251. module_init(sdhci_pxa_init);
  252. module_exit(sdhci_pxa_exit);
  253. MODULE_DESCRIPTION("SDH controller driver for PXA168/PXA910/MMP2");
  254. MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");
  255. MODULE_LICENSE("GPL v2");