From: Shawn Lin Date: Mon, 9 Mar 2026 03:29:03 +0000 (+0800) Subject: mmc: dw_mmc-rockchip: Add phase map support X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc1060a18e0464a7b03c06fb64889935d27acee0;p=thirdparty%2Fkernel%2Fstable.git mmc: dw_mmc-rockchip: Add phase map support Multiple boards require different phase settings, rendering the default phase policy unscalable. Therefore, we introduce phase map to address this limitation. To preserve backward compatibility, the default_sample_phase and original drv phase for different modes are retained, with phase map values taking precedence when available. Signed-off-by: Shawn Lin Signed-off-by: Ulf Hansson --- diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 76995415bc4c..c6eece4ec3fd 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -179,7 +179,8 @@ static int rockchip_mmc_set_phase(struct dw_mci *host, bool sample, int degrees) static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) { struct dw_mci_rockchip_priv_data *priv = host->priv; - int ret; + struct mmc_clk_phase phase = host->phase_map.phase[ios->timing]; + int ret, sample_phase, drv_phase; unsigned int cclkin; u32 bus_hz; @@ -213,8 +214,15 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) } /* Make sure we use phases which we can enumerate with */ - if (!IS_ERR(priv->sample_clk) && ios->timing <= MMC_TIMING_SD_HS) - rockchip_mmc_set_phase(host, true, priv->default_sample_phase); + if (!IS_ERR(priv->sample_clk)) { + /* Keep backward compatibility */ + if (ios->timing <= MMC_TIMING_SD_HS) { + sample_phase = phase.valid ? phase.in_deg : priv->default_sample_phase; + rockchip_mmc_set_phase(host, true, sample_phase); + } else if (phase.valid) { + rockchip_mmc_set_phase(host, true, phase.in_deg); + } + } /* * Set the drive phase offset based on speed mode to achieve hold times. @@ -243,15 +251,13 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) * same results, for instance). */ if (!IS_ERR(priv->drv_clk)) { - int phase; - /* * In almost all cases a 90 degree phase offset will provide * sufficient hold times across all valid input clock rates * assuming delay_o is not absurd for a given SoC. We'll use * that as a default. */ - phase = 90; + drv_phase = 90; switch (ios->timing) { case MMC_TIMING_MMC_DDR52: @@ -261,7 +267,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) * to get the same timings. */ if (ios->bus_width == MMC_BUS_WIDTH_8) - phase = 180; + drv_phase = 180; break; case MMC_TIMING_UHS_SDR104: case MMC_TIMING_MMC_HS200: @@ -273,11 +279,14 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) * SoCs measured this seems to be OK, but it doesn't * hurt to give margin here, so we use 180. */ - phase = 180; + drv_phase = 180; break; } - rockchip_mmc_set_phase(host, false, phase); + /* Use out phase from phase map first */ + if (phase.valid) + drv_phase = phase.out_deg; + rockchip_mmc_set_phase(host, false, drv_phase); } }