819-sdhc-support-layerscape.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. From f901f791d07deaeba6310ac070769575a0bb790a Mon Sep 17 00:00:00 2001
  2. From: Biwen Li <[email protected]>
  3. Date: Tue, 30 Oct 2018 18:27:54 +0800
  4. Subject: [PATCH 36/40] sdhc: support layerscape
  5. This is an integrated patch of sdhc for layerscape
  6. Signed-off-by: Yinbo Zhu <[email protected]>
  7. Signed-off-by: Biwen Li <[email protected]>
  8. ---
  9. drivers/mmc/host/sdhci-of-esdhc.c | 85 +++++++++++++++++++++----------
  10. 1 file changed, 57 insertions(+), 28 deletions(-)
  11. --- a/drivers/mmc/host/sdhci-of-esdhc.c
  12. +++ b/drivers/mmc/host/sdhci-of-esdhc.c
  13. @@ -30,11 +30,56 @@
  14. #define VENDOR_V_22 0x12
  15. #define VENDOR_V_23 0x13
  16. +#define MMC_TIMING_NUM (MMC_TIMING_MMC_HS400 + 1)
  17. +
  18. +struct esdhc_clk_fixup {
  19. + const unsigned int sd_dflt_max_clk;
  20. + const unsigned int max_clk[MMC_TIMING_NUM];
  21. +};
  22. +
  23. +static const struct esdhc_clk_fixup ls1021a_esdhc_clk = {
  24. + .sd_dflt_max_clk = 25000000,
  25. + .max_clk[MMC_TIMING_MMC_HS] = 46500000,
  26. + .max_clk[MMC_TIMING_SD_HS] = 46500000,
  27. +};
  28. +
  29. +static const struct esdhc_clk_fixup ls1046a_esdhc_clk = {
  30. + .sd_dflt_max_clk = 25000000,
  31. + .max_clk[MMC_TIMING_UHS_SDR104] = 167000000,
  32. + .max_clk[MMC_TIMING_MMC_HS200] = 167000000,
  33. +};
  34. +
  35. +static const struct esdhc_clk_fixup ls1012a_esdhc_clk = {
  36. + .sd_dflt_max_clk = 25000000,
  37. + .max_clk[MMC_TIMING_UHS_SDR104] = 125000000,
  38. + .max_clk[MMC_TIMING_MMC_HS200] = 125000000,
  39. +};
  40. +
  41. +static const struct esdhc_clk_fixup p1010_esdhc_clk = {
  42. + .sd_dflt_max_clk = 20000000,
  43. + .max_clk[MMC_TIMING_LEGACY] = 20000000,
  44. + .max_clk[MMC_TIMING_MMC_HS] = 42000000,
  45. + .max_clk[MMC_TIMING_SD_HS] = 40000000,
  46. +};
  47. +
  48. +static const struct of_device_id sdhci_esdhc_of_match[] = {
  49. + { .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk},
  50. + { .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk},
  51. + { .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk},
  52. + { .compatible = "fsl,p1010-esdhc", .data = &p1010_esdhc_clk},
  53. + { .compatible = "fsl,mpc8379-esdhc" },
  54. + { .compatible = "fsl,mpc8536-esdhc" },
  55. + { .compatible = "fsl,esdhc" },
  56. + { }
  57. +};
  58. +MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
  59. +
  60. struct sdhci_esdhc {
  61. u8 vendor_ver;
  62. u8 spec_ver;
  63. bool quirk_incorrect_hostver;
  64. unsigned int peripheral_clock;
  65. + const struct esdhc_clk_fixup *clk_fixup;
  66. };
  67. /**
  68. @@ -502,6 +547,7 @@ static void esdhc_of_set_clock(struct sd
  69. int pre_div = 1;
  70. int div = 1;
  71. ktime_t timeout;
  72. + long fixup = 0;
  73. u32 temp;
  74. host->mmc->actual_clock = 0;
  75. @@ -515,27 +561,14 @@ static void esdhc_of_set_clock(struct sd
  76. if (esdhc->vendor_ver < VENDOR_V_23)
  77. pre_div = 2;
  78. - /*
  79. - * Limit SD clock to 167MHz for ls1046a according to its datasheet
  80. - */
  81. - if (clock > 167000000 &&
  82. - of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
  83. - clock = 167000000;
  84. + if (host->mmc->card && mmc_card_sd(host->mmc->card) &&
  85. + esdhc->clk_fixup && host->mmc->ios.timing == MMC_TIMING_LEGACY)
  86. + fixup = esdhc->clk_fixup->sd_dflt_max_clk;
  87. + else if (esdhc->clk_fixup)
  88. + fixup = esdhc->clk_fixup->max_clk[host->mmc->ios.timing];
  89. - /*
  90. - * Limit SD clock to 125MHz for ls1012a according to its datasheet
  91. - */
  92. - if (clock > 125000000 &&
  93. - of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
  94. - clock = 125000000;
  95. -
  96. - /* Workaround to reduce the clock frequency for p1010 esdhc */
  97. - if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
  98. - if (clock > 20000000)
  99. - clock -= 5000000;
  100. - if (clock > 40000000)
  101. - clock -= 5000000;
  102. - }
  103. + if (fixup && clock > fixup)
  104. + clock = fixup;
  105. temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
  106. temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
  107. @@ -797,6 +830,7 @@ static struct soc_device_attribute soc_i
  108. static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
  109. {
  110. + const struct of_device_id *match;
  111. struct sdhci_pltfm_host *pltfm_host;
  112. struct sdhci_esdhc *esdhc;
  113. struct device_node *np;
  114. @@ -816,6 +850,9 @@ static void esdhc_init(struct platform_d
  115. else
  116. esdhc->quirk_incorrect_hostver = false;
  117. + match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node);
  118. + if (match)
  119. + esdhc->clk_fixup = match->data;
  120. np = pdev->dev.of_node;
  121. clk = of_clk_get(np, 0);
  122. if (!IS_ERR(clk)) {
  123. @@ -915,14 +952,6 @@ static int sdhci_esdhc_probe(struct plat
  124. return ret;
  125. }
  126. -static const struct of_device_id sdhci_esdhc_of_match[] = {
  127. - { .compatible = "fsl,mpc8379-esdhc" },
  128. - { .compatible = "fsl,mpc8536-esdhc" },
  129. - { .compatible = "fsl,esdhc" },
  130. - { }
  131. -};
  132. -MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
  133. -
  134. static struct platform_driver sdhci_esdhc_driver = {
  135. .driver = {
  136. .name = "sdhci-esdhc",