mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-02 22:57:07 +08:00
80 lines
2.7 KiB
Diff
80 lines
2.7 KiB
Diff
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
|
|
---
|
|
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(+)
|
|
|
|
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
|
|
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
|
|
@@ -17,6 +17,7 @@
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/platform_device.h>
|
|
+#include <linux/pm_domain.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/reset.h>
|
|
#include <linux/sizes.h>
|
|
@@ -787,6 +788,28 @@ static void dwcmshc_rk35xx_postinit(stru
|
|
}
|
|
}
|
|
|
|
+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);
|
|
@@ -1218,6 +1241,18 @@ static const struct dwcmshc_pltfm_data s
|
|
.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,
|
|
@@ -1317,6 +1352,10 @@ static const struct of_device_id sdhci_d
|
|
.data = &sdhci_dwcmshc_rk35xx_pdata,
|
|
},
|
|
{
|
|
+ .compatible = "rockchip,rk3576-dwcmshc",
|
|
+ .data = &sdhci_dwcmshc_rk3576_pdata,
|
|
+ },
|
|
+ {
|
|
.compatible = "rockchip,rk3568-dwcmshc",
|
|
.data = &sdhci_dwcmshc_rk35xx_pdata,
|
|
},
|