diff options
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.patch | 572 |
1 files changed, 0 insertions, 572 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 deleted file mode 100644 index 02688c74cd..0000000000 --- a/target/linux/layerscape/patches-4.14/819-sdhc-support-layerscape.patch +++ /dev/null @@ -1,572 +0,0 @@ -From 6ca94d2e7dc72b21703e6d9be4e8ec3ad4a26f41 Mon Sep 17 00:00:00 2001 -From: Biwen Li <biwen.li@nxp.com> -Date: Wed, 17 Apr 2019 18:59:02 +0800 -Subject: [PATCH] sdhc: support layerscape - -This is an integrated patch of sdhc for layerscape - -Signed-off-by: Biwen Li <biwen.li@nxp.com> -Signed-off-by: Mathew McBride <matt@traverse.com.au> -Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> -Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> -Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com> ---- - drivers/mmc/core/mmc.c | 3 + - drivers/mmc/host/sdhci-esdhc.h | 25 +++ - drivers/mmc/host/sdhci-of-esdhc.c | 270 ++++++++++++++++++++++++++---- - drivers/mmc/host/sdhci.c | 9 +- - drivers/mmc/host/sdhci.h | 1 + - include/linux/mmc/card.h | 1 + - include/linux/mmc/host.h | 2 + - 7 files changed, 272 insertions(+), 39 deletions(-) - ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1174,6 +1174,9 @@ static int mmc_select_hs400(struct mmc_c - goto out_err; - - /* Switch card to DDR */ -+ if (host->ops->prepare_ddr_to_hs400) -+ host->ops->prepare_ddr_to_hs400(host); -+ - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, - EXT_CSD_DDR_BUS_WIDTH_8, ---- a/drivers/mmc/host/sdhci-esdhc.h -+++ b/drivers/mmc/host/sdhci-esdhc.h -@@ -59,7 +59,32 @@ - - /* Tuning Block Control Register */ - #define ESDHC_TBCTL 0x120 -+#define ESDHC_HS400_WNDW_ADJUST 0x00000040 -+#define ESDHC_HS400_MODE 0x00000010 - #define ESDHC_TB_EN 0x00000004 -+#define ESDHC_TBPTR 0x128 -+ -+/* SD Clock Control Register */ -+#define ESDHC_SDCLKCTL 0x144 -+#define ESDHC_LPBK_CLK_SEL 0x80000000 -+#define ESDHC_CMD_CLK_CTL 0x00008000 -+ -+/* SD Timing Control Register */ -+#define ESDHC_SDTIMNGCTL 0x148 -+#define ESDHC_FLW_CTL_BG 0x00008000 -+ -+/* DLL Config 0 Register */ -+#define ESDHC_DLLCFG0 0x160 -+#define ESDHC_DLL_ENABLE 0x80000000 -+#define ESDHC_DLL_FREQ_SEL 0x08000000 -+ -+/* DLL Config 1 Register */ -+#define ESDHC_DLLCFG1 0x164 -+#define ESDHC_DLL_PD_PULSE_STRETCH_SEL 0x80000000 -+ -+/* DLL Status 0 Register */ -+#define ESDHC_DLLSTAT0 0x170 -+#define ESDHC_DLL_STS_SLV_LOCK 0x08000000 - - /* Control Register for DMA transfer */ - #define ESDHC_DMA_SYSCTL 0x40c ---- a/drivers/mmc/host/sdhci-of-esdhc.c -+++ b/drivers/mmc/host/sdhci-of-esdhc.c -@@ -30,11 +30,61 @@ - #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; -+ bool quirk_limited_clk_division; -+ bool quirk_unreliable_pulse_detection; -+ bool quirk_fixup_tuning; -+ bool quirk_incorrect_delay_chain; - unsigned int peripheral_clock; -+ const struct esdhc_clk_fixup *clk_fixup; -+ u32 div_ratio; - }; - - /** -@@ -500,13 +550,20 @@ static void esdhc_clock_enable(struct sd - } - } - -+static struct soc_device_attribute soc_incorrect_delay_chain[] = { -+ { .family = "QorIQ LX2160A", .revision = "1.0", }, -+ { }, -+}; -+ - static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) - { - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); - int pre_div = 1; - int div = 1; -+ int division; - ktime_t timeout; -+ long fixup = 0; - u32 temp; - - host->mmc->actual_clock = 0; -@@ -520,27 +577,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 | -@@ -553,9 +597,30 @@ static void esdhc_of_set_clock(struct sd - while (host->max_clk / pre_div / div > clock && div < 16) - div++; - -+ if (esdhc->quirk_limited_clk_division && -+ clock == MMC_HS200_MAX_DTR && -+ (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 || -+ host->flags & SDHCI_HS400_TUNING)) { -+ division = pre_div * div; -+ if (division <= 4) { -+ pre_div = 4; -+ div = 1; -+ } else if (division <= 8) { -+ pre_div = 4; -+ div = 2; -+ } else if (division <= 12) { -+ pre_div = 4; -+ div = 3; -+ } else { -+ pr_warn("%s: using upsupported clock division.\n", -+ mmc_hostname(host->mmc)); -+ } -+ } -+ - dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", - clock, host->max_clk / pre_div / div); - host->mmc->actual_clock = host->max_clk / pre_div / div; -+ esdhc->div_ratio = pre_div * div; - pre_div >>= 1; - div--; - -@@ -565,6 +630,29 @@ static void esdhc_of_set_clock(struct sd - | (pre_div << ESDHC_PREDIV_SHIFT)); - sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); - -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 && -+ clock == MMC_HS200_MAX_DTR) { -+ temp = sdhci_readl(host, ESDHC_TBCTL); -+ sdhci_writel(host, temp | ESDHC_HS400_MODE, ESDHC_TBCTL); -+ temp = sdhci_readl(host, ESDHC_SDCLKCTL); -+ sdhci_writel(host, temp | ESDHC_CMD_CLK_CTL, ESDHC_SDCLKCTL); -+ esdhc_clock_enable(host, true); -+ -+ temp = sdhci_readl(host, ESDHC_DLLCFG0); -+ temp |= ESDHC_DLL_ENABLE; -+ if (host->mmc->actual_clock == MMC_HS200_MAX_DTR || -+ esdhc->quirk_incorrect_delay_chain == false) -+ temp |= ESDHC_DLL_FREQ_SEL; -+ sdhci_writel(host, temp, ESDHC_DLLCFG0); -+ temp = sdhci_readl(host, ESDHC_TBCTL); -+ sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL); -+ -+ esdhc_clock_enable(host, false); -+ temp = sdhci_readl(host, ESDHC_DMA_SYSCTL); -+ temp |= ESDHC_FLUSH_ASYNC_FIFO; -+ sdhci_writel(host, temp, ESDHC_DMA_SYSCTL); -+ } -+ - /* Wait max 20 ms */ - timeout = ktime_add_ms(ktime_get(), 20); - while (1) { -@@ -580,6 +668,7 @@ static void esdhc_of_set_clock(struct sd - udelay(10); - } - -+ temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); - temp |= ESDHC_CLOCK_SDCLKEN; - sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); - } -@@ -608,6 +697,8 @@ static void esdhc_pltfm_set_bus_width(st - - static void esdhc_reset(struct sdhci_host *host, u8 mask) - { -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); - u32 val; - - sdhci_reset(host, mask); -@@ -619,6 +710,12 @@ static void esdhc_reset(struct sdhci_hos - val = sdhci_readl(host, ESDHC_TBCTL); - val &= ~ESDHC_TB_EN; - sdhci_writel(host, val, ESDHC_TBCTL); -+ -+ if (esdhc->quirk_unreliable_pulse_detection) { -+ val = sdhci_readl(host, ESDHC_DLLCFG1); -+ val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL; -+ sdhci_writel(host, val, ESDHC_DLLCFG1); -+ } - } - } - -@@ -630,6 +727,7 @@ static void esdhc_reset(struct sdhci_hos - static const struct of_device_id scfg_device_ids[] = { - { .compatible = "fsl,t1040-scfg", }, - { .compatible = "fsl,ls1012a-scfg", }, -+ { .compatible = "fsl,ls1043a-scfg", }, - { .compatible = "fsl,ls1046a-scfg", }, - {} - }; -@@ -692,23 +790,91 @@ static int esdhc_signal_voltage_switch(s - } - } - --static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) -+static struct soc_device_attribute soc_fixup_tuning[] = { -+ { .family = "QorIQ T1040", .revision = "1.0", }, -+ { .family = "QorIQ T2080", .revision = "1.0", }, -+ { .family = "QorIQ T1023", .revision = "1.0", }, -+ { .family = "QorIQ LS1021A", .revision = "1.0", }, -+ { .family = "QorIQ LS1080A", .revision = "1.0", }, -+ { .family = "QorIQ LS2080A", .revision = "1.0", }, -+ { .family = "QorIQ LS1012A", .revision = "1.0", }, -+ { .family = "QorIQ LS1043A", .revision = "1.*", }, -+ { .family = "QorIQ LS1046A", .revision = "1.0", }, -+ { }, -+}; -+ -+static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable) - { -- struct sdhci_host *host = mmc_priv(mmc); - u32 val; - -- /* Use tuning block for tuning procedure */ - esdhc_clock_enable(host, false); -+ - val = sdhci_readl(host, ESDHC_DMA_SYSCTL); - val |= ESDHC_FLUSH_ASYNC_FIFO; - sdhci_writel(host, val, ESDHC_DMA_SYSCTL); - - val = sdhci_readl(host, ESDHC_TBCTL); -- val |= ESDHC_TB_EN; -+ if (enable) -+ val |= ESDHC_TB_EN; -+ else -+ val &= ~ESDHC_TB_EN; - sdhci_writel(host, val, ESDHC_TBCTL); -+ - esdhc_clock_enable(host, true); -+} -+ -+static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); -+ bool hs400_tuning; -+ u32 val; -+ int ret; -+ -+ if (esdhc->quirk_limited_clk_division && -+ host->flags & SDHCI_HS400_TUNING) -+ esdhc_of_set_clock(host, host->clock); -+ -+ esdhc_tuning_block_enable(host, true); -+ -+ hs400_tuning = host->flags & SDHCI_HS400_TUNING; -+ ret = sdhci_execute_tuning(mmc, opcode); -+ -+ if (hs400_tuning) { -+ val = sdhci_readl(host, ESDHC_SDTIMNGCTL); -+ val |= ESDHC_FLW_CTL_BG; -+ sdhci_writel(host, val, ESDHC_SDTIMNGCTL); -+ } - -- return sdhci_execute_tuning(mmc, opcode); -+ if (host->tuning_err == -EAGAIN && esdhc->quirk_fixup_tuning) { -+ -+ /* program TBPTR[TB_WNDW_END_PTR] = 3*DIV_RATIO and -+ * program TBPTR[TB_WNDW_START_PTR] = 5*DIV_RATIO -+ */ -+ val = sdhci_readl(host, ESDHC_TBPTR); -+ val = (val & ~((0x7f << 8) | 0x7f)) | -+ (3 * esdhc->div_ratio) | ((5 * esdhc->div_ratio) << 8); -+ sdhci_writel(host, val, ESDHC_TBPTR); -+ -+ /* program the software tuning mode by setting -+ * TBCTL[TB_MODE]=2'h3 -+ */ -+ val = sdhci_readl(host, ESDHC_TBCTL); -+ val |= 0x3; -+ sdhci_writel(host, val, ESDHC_TBCTL); -+ sdhci_execute_tuning(mmc, opcode); -+ } -+ return ret; -+} -+ -+static void esdhc_set_uhs_signaling(struct sdhci_host *host, -+ unsigned int timing) -+{ -+ if (timing == MMC_TIMING_MMC_HS400) -+ esdhc_tuning_block_enable(host, true); -+ else -+ sdhci_set_uhs_signaling(host, timing); - } - - #ifdef CONFIG_PM_SLEEP -@@ -757,7 +923,7 @@ static const struct sdhci_ops sdhci_esdh - .adma_workaround = esdhc_of_adma_workaround, - .set_bus_width = esdhc_pltfm_set_bus_width, - .reset = esdhc_reset, -- .set_uhs_signaling = sdhci_set_uhs_signaling, -+ .set_uhs_signaling = esdhc_set_uhs_signaling, - }; - - static const struct sdhci_ops sdhci_esdhc_le_ops = { -@@ -774,7 +940,7 @@ static const struct sdhci_ops sdhci_esdh - .adma_workaround = esdhc_of_adma_workaround, - .set_bus_width = esdhc_pltfm_set_bus_width, - .reset = esdhc_reset, -- .set_uhs_signaling = sdhci_set_uhs_signaling, -+ .set_uhs_signaling = esdhc_set_uhs_signaling, - }; - - static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { -@@ -800,8 +966,20 @@ static struct soc_device_attribute soc_i - { }, - }; - -+static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = { -+ { .family = "QorIQ LX2160A", .revision = "1.0", }, -+ { .family = "QorIQ LX2160A", .revision = "2.0", }, -+ { }, -+}; -+ -+static struct soc_device_attribute soc_unreliable_pulse_detection[] = { -+ { .family = "QorIQ LX2160A", .revision = "1.0", }, -+ { }, -+}; -+ - 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; -@@ -821,6 +999,24 @@ static void esdhc_init(struct platform_d - else - esdhc->quirk_incorrect_hostver = false; - -+ if (soc_device_match(soc_fixup_sdhc_clkdivs)) -+ esdhc->quirk_limited_clk_division = true; -+ else -+ esdhc->quirk_limited_clk_division = false; -+ -+ if (soc_device_match(soc_unreliable_pulse_detection)) -+ esdhc->quirk_unreliable_pulse_detection = true; -+ else -+ esdhc->quirk_unreliable_pulse_detection = false; -+ -+ if (soc_device_match(soc_incorrect_delay_chain)) -+ esdhc->quirk_incorrect_delay_chain = true; -+ else -+ esdhc->quirk_incorrect_delay_chain = 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)) { -@@ -848,6 +1044,12 @@ static void esdhc_init(struct platform_d - } - } - -+static int esdhc_prepare_ddr_to_hs400(struct mmc_host *mmc) -+{ -+ esdhc_tuning_block_enable(mmc_priv(mmc), false); -+ return 0; -+} -+ - static int sdhci_esdhc_probe(struct platform_device *pdev) - { - struct sdhci_host *host; -@@ -871,6 +1073,7 @@ static int sdhci_esdhc_probe(struct plat - host->mmc_host_ops.start_signal_voltage_switch = - esdhc_signal_voltage_switch; - host->mmc_host_ops.execute_tuning = esdhc_execute_tuning; -+ host->mmc_host_ops.prepare_ddr_to_hs400 = esdhc_prepare_ddr_to_hs400; - host->tuning_delay = 1; - - esdhc_init(pdev, host); -@@ -879,6 +1082,11 @@ static int sdhci_esdhc_probe(struct plat - - pltfm_host = sdhci_priv(host); - esdhc = sdhci_pltfm_priv(pltfm_host); -+ if (soc_device_match(soc_fixup_tuning)) -+ esdhc->quirk_fixup_tuning = true; -+ else -+ esdhc->quirk_fixup_tuning = false; -+ - if (esdhc->vendor_ver == VENDOR_V_22) - host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; - -@@ -925,14 +1133,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", ---- a/drivers/mmc/host/sdhci.c -+++ b/drivers/mmc/host/sdhci.c -@@ -2148,7 +2148,7 @@ static void sdhci_send_tuning(struct sdh - - } - --static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) -+static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) - { - int i; - -@@ -2165,13 +2165,13 @@ static void __sdhci_execute_tuning(struc - pr_debug("%s: Tuning timeout, falling back to fixed sampling clock\n", - mmc_hostname(host->mmc)); - sdhci_abort_tuning(host, opcode); -- return; -+ return -ETIMEDOUT; - } - - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); - if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) { - if (ctrl & SDHCI_CTRL_TUNED_CLK) -- return; /* Success! */ -+ return 0; /* Success! */ - break; - } - -@@ -2183,6 +2183,7 @@ static void __sdhci_execute_tuning(struc - pr_info("%s: Tuning failed, falling back to fixed sampling clock\n", - mmc_hostname(host->mmc)); - sdhci_reset_tuning(host); -+ return -EAGAIN; - } - - int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) -@@ -2244,7 +2245,7 @@ int sdhci_execute_tuning(struct mmc_host - - sdhci_start_tuning(host); - -- __sdhci_execute_tuning(host, opcode); -+ host->tuning_err = __sdhci_execute_tuning(host, opcode); - - sdhci_end_tuning(host); - out: ---- a/drivers/mmc/host/sdhci.h -+++ b/drivers/mmc/host/sdhci.h -@@ -545,6 +545,7 @@ struct sdhci_host { - - unsigned int tuning_count; /* Timer count for re-tuning */ - unsigned int tuning_mode; /* Re-tuning mode supported by host */ -+ unsigned int tuning_err; /* Error code for re-tuning */ - #define SDHCI_TUNING_MODE_1 0 - #define SDHCI_TUNING_MODE_2 1 - #define SDHCI_TUNING_MODE_3 2 ---- a/include/linux/mmc/card.h -+++ b/include/linux/mmc/card.h -@@ -156,6 +156,7 @@ struct sd_switch_caps { - #define UHS_DDR50_MAX_DTR 50000000 - #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR - #define UHS_SDR12_MAX_DTR 25000000 -+#define DEFAULT_SPEED_MAX_DTR UHS_SDR12_MAX_DTR - unsigned int sd3_bus_mode; - #define UHS_SDR12_BUS_SPEED 0 - #define HIGH_SPEED_BUS_SPEED 1 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -145,6 +145,8 @@ struct mmc_host_ops { - - /* Prepare HS400 target operating frequency depending host driver */ - int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); -+ int (*prepare_ddr_to_hs400)(struct mmc_host *host); -+ - /* Prepare enhanced strobe depending host driver */ - void (*hs400_enhanced_strobe)(struct mmc_host *host, - struct mmc_ios *ios); |