Skip to content

Commit 6465a8b

Browse files
shawn1221storulf
authored andcommitted
mmc: dw_mmc-rockchip: Fix runtime PM support for internal phase support
RK3576 is the first platform to introduce internal phase support, and subsequent platforms are expected to adopt a similar design. In this architecture, runtime suspend powers off the attached power domain, which resets registers, including vendor-specific ones such as SDMMC_TIMING_CON0, SDMMC_TIMING_CON1, and SDMMC_MISC_CON. These registers must be saved and restored, a requirement that falls outside the scope of the dw_mmc core. Fixes: 5990344 ("mmc: dw_mmc-rockchip: Add internal phase support") Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Tested-by: Marco Schirrmeister <mschirrmeister@gmail.com> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent af12e64 commit 6465a8b

1 file changed

Lines changed: 37 additions & 1 deletion

File tree

drivers/mmc/host/dw_mmc-rockchip.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct dw_mci_rockchip_priv_data {
3636
int default_sample_phase;
3737
int num_phases;
3838
bool internal_phase;
39+
int sample_phase;
40+
int drv_phase;
3941
};
4042

4143
/*
@@ -573,9 +575,43 @@ static void dw_mci_rockchip_remove(struct platform_device *pdev)
573575
dw_mci_pltfm_remove(pdev);
574576
}
575577

578+
static int dw_mci_rockchip_runtime_suspend(struct device *dev)
579+
{
580+
struct platform_device *pdev = to_platform_device(dev);
581+
struct dw_mci *host = platform_get_drvdata(pdev);
582+
struct dw_mci_rockchip_priv_data *priv = host->priv;
583+
584+
if (priv->internal_phase) {
585+
priv->sample_phase = rockchip_mmc_get_phase(host, true);
586+
priv->drv_phase = rockchip_mmc_get_phase(host, false);
587+
}
588+
589+
return dw_mci_runtime_suspend(dev);
590+
}
591+
592+
static int dw_mci_rockchip_runtime_resume(struct device *dev)
593+
{
594+
struct platform_device *pdev = to_platform_device(dev);
595+
struct dw_mci *host = platform_get_drvdata(pdev);
596+
struct dw_mci_rockchip_priv_data *priv = host->priv;
597+
int ret;
598+
599+
ret = dw_mci_runtime_resume(dev);
600+
if (ret)
601+
return ret;
602+
603+
if (priv->internal_phase) {
604+
rockchip_mmc_set_phase(host, true, priv->sample_phase);
605+
rockchip_mmc_set_phase(host, false, priv->drv_phase);
606+
mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE);
607+
}
608+
609+
return ret;
610+
}
611+
576612
static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = {
577613
SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
578-
RUNTIME_PM_OPS(dw_mci_runtime_suspend, dw_mci_runtime_resume, NULL)
614+
RUNTIME_PM_OPS(dw_mci_rockchip_runtime_suspend, dw_mci_rockchip_runtime_resume, NULL)
579615
};
580616

581617
static struct platform_driver dw_mci_rockchip_pltfm_driver = {

0 commit comments

Comments
 (0)