mmc: uniphier-sd: Add control to switch UHS speed
authorKunihiko Hayashi <hayashi.kunihiko@socionext.com>
Wed, 25 Jan 2023 01:01:59 +0000 (10:01 +0900)
committerUlf Hansson <ulf.hansson@linaro.org>
Fri, 27 Jan 2023 10:55:50 +0000 (11:55 +0100)
SD interface logic has the register to switch UHS speed.
The default is up to SDR25 and to support SDR50 or faster,
add uniphier_sd_speed_switch() function to switch the speed mode.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Link: https://lore.kernel.org/r/20230125010201.28246-4-hayashi.kunihiko@socionext.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/uniphier-sd.c

index c9766d6..61acd69 100644 (file)
@@ -54,6 +54,7 @@
 #define UNIPHIER_SDCTRL_CHOFFSET       0x200
 #define UNIPHIER_SDCTRL_MODE           0x30
 #define   UNIPHIER_SDCTRL_MODE_UHS1MOD         BIT(15)
+#define   UNIPHIER_SDCTRL_MODE_SDRSEL          BIT(14)
 
 /*
  * IP is extended to support various features: built-in DMA engine,
@@ -429,6 +430,25 @@ static void uniphier_sd_hw_reset(struct mmc_host *mmc)
        usleep_range(300, 1000);
 }
 
+static void uniphier_sd_speed_switch(struct tmio_mmc_host *host)
+{
+       struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
+       unsigned int offset;
+       u32 val = 0;
+
+       if (!(host->mmc->caps & MMC_CAP_UHS))
+               return;
+
+       if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR50 ||
+           host->mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+               val = UNIPHIER_SDCTRL_MODE_SDRSEL;
+
+       offset = UNIPHIER_SDCTRL_CHOFFSET * priv->sdctrl_ch
+               + UNIPHIER_SDCTRL_MODE;
+       regmap_write_bits(priv->sdctrl_regmap, offset,
+                         UNIPHIER_SDCTRL_MODE_SDRSEL, val);
+}
+
 static void uniphier_sd_uhs_enable(struct tmio_mmc_host *host, bool uhs_en)
 {
        struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
@@ -459,6 +479,8 @@ static void uniphier_sd_set_clock(struct tmio_mmc_host *host,
        tmp &= ~CLK_CTL_SCLKEN;
        writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1));
 
+       uniphier_sd_speed_switch(host);
+
        if (clock == 0)
                return;