kona_sdhci.c 3.1 KB

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