]> Git Repo - linux.git/commitdiff
mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
authorYangbo Lu <[email protected]>
Tue, 20 Oct 2020 08:11:16 +0000 (16:11 +0800)
committerUlf Hansson <[email protected]>
Wed, 28 Oct 2020 10:07:01 +0000 (11:07 +0100)
For eMMC HS400 mode initialization, the DLL reset is a required step
if DLL is enabled to use previously, like in bootloader.
This step has not been documented in reference manual, but the RM will
be fixed sooner or later.

This patch is to add the step of DLL reset, and make sure delay chain
locked for HS400.

Signed-off-by: Yangbo Lu <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Fixes: 54e08d9a95ca ("mmc: sdhci-of-esdhc: add hs400 mode support")
Cc: [email protected]
Signed-off-by: Ulf Hansson <[email protected]>
drivers/mmc/host/sdhci-esdhc.h
drivers/mmc/host/sdhci-of-esdhc.c

index a30796e79b1cbf6d5b13512e24229e6a0af10bcf..6de02f09c3222408a457b871c225b26071cd980d 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (c) 2007 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
  * Copyright (c) 2010 Pengutronix e.K.
+ * Copyright 2020 NXP
  *   Author: Wolfram Sang <[email protected]>
  */
 
@@ -88,6 +89,7 @@
 /* DLL Config 0 Register */
 #define ESDHC_DLLCFG0                  0x160
 #define ESDHC_DLL_ENABLE               0x80000000
+#define ESDHC_DLL_RESET                        0x40000000
 #define ESDHC_DLL_FREQ_SEL             0x08000000
 
 /* DLL Config 1 Register */
index baf7801a180441da14a38cd1565ccbae401577b1..bb094459196a3a1fd2e30e82f70b117409f09150 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
+ * Copyright 2020 NXP
  *
  * Authors: Xiaobo Xie <[email protected]>
  *         Anton Vorontsov <[email protected]>
@@ -19,6 +20,7 @@
 #include <linux/clk.h>
 #include <linux/ktime.h>
 #include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include "sdhci-pltfm.h"
@@ -743,6 +745,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
                if (host->mmc->actual_clock == MMC_HS200_MAX_DTR)
                        temp |= ESDHC_DLL_FREQ_SEL;
                sdhci_writel(host, temp, ESDHC_DLLCFG0);
+
+               temp |= ESDHC_DLL_RESET;
+               sdhci_writel(host, temp, ESDHC_DLLCFG0);
+               udelay(1);
+               temp &= ~ESDHC_DLL_RESET;
+               sdhci_writel(host, temp, ESDHC_DLLCFG0);
+
+               /* Wait max 20 ms */
+               if (read_poll_timeout(sdhci_readl, temp,
+                                     temp & ESDHC_DLL_STS_SLV_LOCK,
+                                     10, 20000, false,
+                                     host, ESDHC_DLLSTAT0))
+                       pr_err("%s: timeout for delay chain lock.\n",
+                              mmc_hostname(host->mmc));
+
                temp = sdhci_readl(host, ESDHC_TBCTL);
                sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
 
This page took 0.06425 seconds and 4 git commands to generate.