kona_sdhci.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2013 Broadcom Corporation.
  4. */
  5. #include <common.h>
  6. #include <malloc.h>
  7. #include <sdhci.h>
  8. #include <linux/errno.h>
  9. #include <asm/kona-common/clk.h>
  10. #define SDHCI_CORECTRL_OFFSET 0x00008000
  11. #define SDHCI_CORECTRL_EN 0x01
  12. #define SDHCI_CORECTRL_RESET 0x02
  13. #define SDHCI_CORESTAT_OFFSET 0x00008004
  14. #define SDHCI_CORESTAT_CD_SW 0x01
  15. #define SDHCI_COREIMR_OFFSET 0x00008008
  16. #define SDHCI_COREIMR_IP 0x01
  17. static int init_kona_mmc_core(struct sdhci_host *host)
  18. {
  19. unsigned int mask;
  20. unsigned int timeout;
  21. if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) {
  22. printf("%s: sd host controller reset error\n", __func__);
  23. return -EBUSY;
  24. }
  25. /* For kona a hardware reset before anything else. */
  26. mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET) | SDHCI_CORECTRL_RESET;
  27. sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
  28. /* Wait max 100 ms */
  29. timeout = 1000;
  30. do {
  31. if (timeout == 0) {
  32. printf("%s: reset timeout error\n", __func__);
  33. return -ETIMEDOUT;
  34. }
  35. timeout--;
  36. udelay(100);
  37. } while (0 ==
  38. (sdhci_readl(host, SDHCI_CORECTRL_OFFSET) &
  39. SDHCI_CORECTRL_RESET));
  40. /* Clear the reset bit. */
  41. mask = mask & ~SDHCI_CORECTRL_RESET;
  42. sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
  43. /* Enable AHB clock */
  44. mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET);
  45. sdhci_writel(host, mask | SDHCI_CORECTRL_EN, SDHCI_CORECTRL_OFFSET);
  46. /* Enable interrupts */
  47. sdhci_writel(host, SDHCI_COREIMR_IP, SDHCI_COREIMR_OFFSET);
  48. /* Make sure Card is detected in controller */
  49. mask = sdhci_readl(host, SDHCI_CORESTAT_OFFSET);
  50. sdhci_writel(host, mask | SDHCI_CORESTAT_CD_SW, SDHCI_CORESTAT_OFFSET);
  51. /* Wait max 100 ms */
  52. timeout = 1000;
  53. while (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
  54. if (timeout == 0) {
  55. printf("%s: CARD DETECT timeout error\n", __func__);
  56. return -ETIMEDOUT;
  57. }
  58. timeout--;
  59. udelay(100);
  60. }
  61. return 0;
  62. }
  63. int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
  64. {
  65. int ret = 0;
  66. u32 max_clk;
  67. void *reg_base;
  68. struct sdhci_host *host = NULL;
  69. host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
  70. if (!host) {
  71. printf("%s: sdhci host malloc fail!\n", __func__);
  72. return -ENOMEM;
  73. }
  74. switch (dev_index) {
  75. case 0:
  76. reg_base = (void *)CONFIG_SYS_SDIO_BASE0;
  77. ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO0_MAX_CLK,
  78. &max_clk);
  79. break;
  80. case 1:
  81. reg_base = (void *)CONFIG_SYS_SDIO_BASE1;
  82. ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO1_MAX_CLK,
  83. &max_clk);
  84. break;
  85. case 2:
  86. reg_base = (void *)CONFIG_SYS_SDIO_BASE2;
  87. ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO2_MAX_CLK,
  88. &max_clk);
  89. break;
  90. case 3:
  91. reg_base = (void *)CONFIG_SYS_SDIO_BASE3;
  92. ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO3_MAX_CLK,
  93. &max_clk);
  94. break;
  95. default:
  96. printf("%s: sdio dev index %d not supported\n",
  97. __func__, dev_index);
  98. ret = -EINVAL;
  99. }
  100. if (ret) {
  101. free(host);
  102. return ret;
  103. }
  104. host->name = "kona-sdhci";
  105. host->ioaddr = reg_base;
  106. host->quirks = quirks;
  107. host->max_clk = max_clk;
  108. if (init_kona_mmc_core(host)) {
  109. free(host);
  110. return -EINVAL;
  111. }
  112. add_sdhci(host, 0, min_clk);
  113. return ret;
  114. }