OpenWrt – Rev 1

Subversion Repositories:
Rev:
From f901f791d07deaeba6310ac070769575a0bb790a Mon Sep 17 00:00:00 2001
From: Biwen Li <biwen.li@nxp.com>
Date: Tue, 30 Oct 2018 18:27:54 +0800
Subject: [PATCH 36/40] sdhc: support layerscape
This is an integrated patch of sdhc for layerscape

Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
 drivers/mmc/host/sdhci-of-esdhc.c | 85 +++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 28 deletions(-)

--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -30,11 +30,56 @@
 #define VENDOR_V_22    0x12
 #define VENDOR_V_23    0x13
 
+#define MMC_TIMING_NUM (MMC_TIMING_MMC_HS400 + 1)
+
+struct esdhc_clk_fixup {
+       const unsigned int sd_dflt_max_clk;
+       const unsigned int max_clk[MMC_TIMING_NUM];
+};
+
+static const struct esdhc_clk_fixup ls1021a_esdhc_clk = {
+       .sd_dflt_max_clk = 25000000,
+       .max_clk[MMC_TIMING_MMC_HS] = 46500000,
+       .max_clk[MMC_TIMING_SD_HS] = 46500000,
+};
+
+static const struct esdhc_clk_fixup ls1046a_esdhc_clk = {
+       .sd_dflt_max_clk = 25000000,
+       .max_clk[MMC_TIMING_UHS_SDR104] = 167000000,
+       .max_clk[MMC_TIMING_MMC_HS200] = 167000000,
+};
+
+static const struct esdhc_clk_fixup ls1012a_esdhc_clk = {
+       .sd_dflt_max_clk = 25000000,
+       .max_clk[MMC_TIMING_UHS_SDR104] = 125000000,
+       .max_clk[MMC_TIMING_MMC_HS200] = 125000000,
+};
+
+static const struct esdhc_clk_fixup p1010_esdhc_clk = {
+       .sd_dflt_max_clk = 20000000,
+       .max_clk[MMC_TIMING_LEGACY] = 20000000,
+       .max_clk[MMC_TIMING_MMC_HS] = 42000000,
+       .max_clk[MMC_TIMING_SD_HS] = 40000000,
+};
+
+static const struct of_device_id sdhci_esdhc_of_match[] = {
+       { .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk},
+       { .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk},
+       { .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk},
+       { .compatible = "fsl,p1010-esdhc",   .data = &p1010_esdhc_clk},
+       { .compatible = "fsl,mpc8379-esdhc" },
+       { .compatible = "fsl,mpc8536-esdhc" },
+       { .compatible = "fsl,esdhc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
+
 struct sdhci_esdhc {
        u8 vendor_ver;
        u8 spec_ver;
        bool quirk_incorrect_hostver;
        unsigned int peripheral_clock;
+       const struct esdhc_clk_fixup *clk_fixup;
 };
 
 /**
@@ -502,6 +547,7 @@ static void esdhc_of_set_clock(struct sd
        int pre_div = 1;
        int div = 1;
        ktime_t timeout;
+       long fixup = 0;
        u32 temp;
 
        host->mmc->actual_clock = 0;
@@ -515,27 +561,14 @@ static void esdhc_of_set_clock(struct sd
        if (esdhc->vendor_ver < VENDOR_V_23)
                pre_div = 2;
 
-       /*
-        * Limit SD clock to 167MHz for ls1046a according to its datasheet
-        */
-       if (clock > 167000000 &&
-           of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
-               clock = 167000000;
+       if (host->mmc->card && mmc_card_sd(host->mmc->card) &&
+               esdhc->clk_fixup && host->mmc->ios.timing == MMC_TIMING_LEGACY)
+               fixup = esdhc->clk_fixup->sd_dflt_max_clk;
+       else if (esdhc->clk_fixup)
+               fixup = esdhc->clk_fixup->max_clk[host->mmc->ios.timing];
 
-       /*
-        * Limit SD clock to 125MHz for ls1012a according to its datasheet
-        */
-       if (clock > 125000000 &&
-           of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
-               clock = 125000000;
-
-       /* Workaround to reduce the clock frequency for p1010 esdhc */
-       if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
-               if (clock > 20000000)
-                       clock -= 5000000;
-               if (clock > 40000000)
-                       clock -= 5000000;
-       }
+       if (fixup && clock > fixup)
+               clock = fixup;
 
        temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
        temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
@@ -797,6 +830,7 @@ static struct soc_device_attribute soc_i
 
 static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
 {
+       const struct of_device_id *match;
        struct sdhci_pltfm_host *pltfm_host;
        struct sdhci_esdhc *esdhc;
        struct device_node *np;
@@ -816,6 +850,9 @@ static void esdhc_init(struct platform_d
        else
                esdhc->quirk_incorrect_hostver = false;
 
+       match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node);
+       if (match)
+               esdhc->clk_fixup = match->data;
        np = pdev->dev.of_node;
        clk = of_clk_get(np, 0);
        if (!IS_ERR(clk)) {
@@ -915,14 +952,6 @@ static int sdhci_esdhc_probe(struct plat
        return ret;
 }
 
-static const struct of_device_id sdhci_esdhc_of_match[] = {
-       { .compatible = "fsl,mpc8379-esdhc" },
-       { .compatible = "fsl,mpc8536-esdhc" },
-       { .compatible = "fsl,esdhc" },
-       { }
-};
-MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
-
 static struct platform_driver sdhci_esdhc_driver = {
        .driver = {
                .name = "sdhci-esdhc",