aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch147
1 files changed, 147 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch b/target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch
new file mode 100644
index 0000000000..986db4c221
--- /dev/null
+++ b/target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch
@@ -0,0 +1,147 @@
+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;
+ };
+
+ /**
+@@ -498,6 +543,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;
+@@ -511,27 +557,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 |
+@@ -789,6 +822,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;
+@@ -808,6 +842,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)) {
+@@ -907,14 +944,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",