]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mmc: sdhci-of-dwcmshc: Update DLL and pre-change delay for rockchip platform
authorShawn Lin <shawn.lin@rock-chips.com>
Wed, 28 Jan 2026 18:26:14 +0000 (13:26 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Feb 2026 15:44:20 +0000 (16:44 +0100)
[ Upstream commit b75a52b0dda353aeefb4830a320589a363f49579 ]

For Rockchip platform, DLL bypass bit and start bit need to be set if
DLL is not locked. And adjust pre-change delay to 0x3 for better signal
test result.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Link: https://lore.kernel.org/r/1675298118-64243-2-git-send-email-shawn.lin@rock-chips.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Stable-dep-of: 3009738a855c ("mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/mmc/host/sdhci-of-dwcmshc.c

index b07c7375935551cc3aab8fd7a47074b7e4da5391..19376bee9ec1345a3419bc7374e4bd80cd6aab55 100644 (file)
@@ -48,6 +48,7 @@
 #define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL  29
 #define DWCMSHC_EMMC_DLL_START_POINT   16
 #define DWCMSHC_EMMC_DLL_INC           8
+#define DWCMSHC_EMMC_DLL_BYPASS                BIT(24)
 #define DWCMSHC_EMMC_DLL_DLYENA                BIT(27)
 #define DLL_TXCLK_TAPNUM_DEFAULT       0x10
 #define DLL_TXCLK_TAPNUM_90_DEGREES    0xA
@@ -60,6 +61,7 @@
 #define DLL_RXCLK_NO_INVERTER          1
 #define DLL_RXCLK_INVERTER             0
 #define DLL_CMDOUT_TAPNUM_90_DEGREES   0x8
+#define DLL_RXCLK_ORI_GATE             BIT(31)
 #define DLL_CMDOUT_TAPNUM_FROM_SW      BIT(24)
 #define DLL_CMDOUT_SRC_CLK_NEG         BIT(28)
 #define DLL_CMDOUT_EN_SRC_CLK_NEG      BIT(29)
@@ -234,9 +236,12 @@ static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock
        sdhci_writel(host, extra, reg);
 
        if (clock <= 52000000) {
-               /* Disable DLL and reset both of sample and drive clock */
-               sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
-               sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_RXCLK);
+               /*
+                * Disable DLL and reset both of sample and drive clock.
+                * The bypass bit and start bit need to be set if DLL is not locked.
+                */
+               sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
+               sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
                sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
                sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
                /*
@@ -279,7 +284,7 @@ static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock
        }
 
        extra = 0x1 << 16 | /* tune clock stop en */
-               0x2 << 17 | /* pre-change delay */
+               0x3 << 17 | /* pre-change delay */
                0x3 << 19;  /* post-change delay */
        sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);