From fb3d3ed80e27884dde042261e007c80764f6ddf3 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Fri, 18 Apr 2025 22:47:48 +0800 Subject: [PATCH] rockchip: fix mmc sdhci of dwcmshc pd workaround on rk3576 in kernel 6.12 --- ...-dwcmshc-add-pd-workaround-on-rk3576.patch | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 target/linux/rockchip/patches-6.12/342-mmc-sdhci-of-dwcmshc-add-pd-workaround-on-rk3576.patch diff --git a/target/linux/rockchip/patches-6.12/342-mmc-sdhci-of-dwcmshc-add-pd-workaround-on-rk3576.patch b/target/linux/rockchip/patches-6.12/342-mmc-sdhci-of-dwcmshc-add-pd-workaround-on-rk3576.patch new file mode 100644 index 000000000..e9af302ef --- /dev/null +++ b/target/linux/rockchip/patches-6.12/342-mmc-sdhci-of-dwcmshc-add-pd-workaround-on-rk3576.patch @@ -0,0 +1,83 @@ +Signed-off-by: Nicolas Frattaroli +--- +Changes in v2: +- Rewrite patch to use dev_pm_genpd_rpm_always_on in sdhci driver + instead, after Ulf Hansson made me aware of its existence +- Link to v1: https://lore.kernel.org/r/20250408-rk3576-emmc-fix-v1-1-3009828b1b31@collabora.com +--- + drivers/mmc/host/sdhci-of-dwcmshc.c | 39 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c +index 09b9ab15e4995f0bddf57dd309c010c849be40d9..a00aec05eff2da8197cc64690ba9665be756e54a 100644 +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -745,6 +746,28 @@ static void dwcmshc_rk35xx_postinit(struct sdhci_host *host, struct dwcmshc_priv + } + } + ++static void dwcmshc_rk3576_postinit(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) ++{ ++ struct device *dev = mmc_dev(host->mmc); ++ int ret; ++ ++ /* ++ * This works around what appears to be a silicon bug, which makes the ++ * PD_NVM power domain, which the sdhci controller on the RK3576 is in, ++ * never come back the same way once it's turned off once. This can ++ * happen during early kernel boot if no driver is using either PD_NVM ++ * or its child power domain PD_SDGMAC for a short moment, leading to it ++ * being turned off to save power. By keeping it on, sdhci suspending ++ * won't lead to PD_NVM becoming a candidate for getting turned off. ++ */ ++ ret = dev_pm_genpd_rpm_always_on(dev, true); ++ if (ret && ret != -EOPNOTSUPP) ++ dev_warn(dev, "failed to set PD rpm always on, SoC may hang later: %pe\n", ++ ERR_PTR(ret)); ++ ++ dwcmshc_rk35xx_postinit(host, dwc_priv); ++} ++ + static int th1520_execute_tuning(struct sdhci_host *host, u32 opcode) + { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); +@@ -1176,6 +1199,18 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = { + .postinit = dwcmshc_rk35xx_postinit, + }; + ++static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk3576_pdata = { ++ .pdata = { ++ .ops = &sdhci_dwcmshc_rk35xx_ops, ++ .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | ++ SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, ++ }, ++ .init = dwcmshc_rk35xx_init, ++ .postinit = dwcmshc_rk3576_postinit, ++}; ++ + static const struct dwcmshc_pltfm_data sdhci_dwcmshc_th1520_pdata = { + .pdata = { + .ops = &sdhci_dwcmshc_th1520_ops, +@@ -1274,6 +1309,10 @@ static const struct of_device_id sdhci_dwcmshc_dt_ids[] = { + .compatible = "rockchip,rk3588-dwcmshc", + .data = &sdhci_dwcmshc_rk35xx_pdata, + }, ++ { ++ .compatible = "rockchip,rk3576-dwcmshc", ++ .data = &sdhci_dwcmshc_rk3576_pdata, ++ }, + { + .compatible = "rockchip,rk3568-dwcmshc", + .data = &sdhci_dwcmshc_rk35xx_pdata, + +---