diff options
Diffstat (limited to 'drivers/mmc/renesas-sdhi.c')
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index f8dc5f57ce..e7f96f8bf2 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -34,6 +34,8 @@ #define RENESAS_SDHI_SCC_RVSREQ_RVSERR BIT(2) #define RENESAS_SDHI_SCC_SMPCMP 0x818 #define RENESAS_SDHI_SCC_TMPPORT2 0x81c +#define RENESAS_SDHI_SCC_TMPPORT2_HS400EN BIT(31) +#define RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL BIT(4) #define RENESAS_SDHI_MAX_TAP 3 @@ -49,12 +51,9 @@ static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv) tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); /* Set sampling clock selection range */ - tmio_sd_writel(priv, 0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT, - RENESAS_SDHI_SCC_DTCNTL); - - reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL); - reg |= RENESAS_SDHI_SCC_DTCNTL_TAPEN; - tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_DTCNTL); + tmio_sd_writel(priv, (0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) | + RENESAS_SDHI_SCC_DTCNTL_TAPEN, + RENESAS_SDHI_SCC_DTCNTL); reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL; @@ -90,6 +89,11 @@ static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) reg &= ~RENESAS_SDHI_SCC_CKSEL_DTSEL; tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_TMPPORT2); + reg &= ~(RENESAS_SDHI_SCC_TMPPORT2_HS400EN | + RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_TMPPORT2); + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); reg |= TMIO_SD_CLKCTL_SCLKEN; tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); @@ -294,19 +298,45 @@ static int renesas_sdhi_set_ios(struct udevice *dev) #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) struct tmio_sd_priv *priv = dev_get_priv(dev); - renesas_sdhi_reset_tuning(priv); + if (priv->caps & TMIO_SD_CAP_RCAR_UHS) + renesas_sdhi_reset_tuning(priv); #endif return ret; } +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) +static int renesas_sdhi_wait_dat0(struct udevice *dev, int state, int timeout) +{ + int ret = -ETIMEDOUT; + bool dat0_high; + bool target_dat0_high = !!state; + struct tmio_sd_priv *priv = dev_get_priv(dev); + + timeout = DIV_ROUND_UP(timeout, 10); /* check every 10 us. */ + while (timeout--) { + dat0_high = !!(tmio_sd_readl(priv, TMIO_SD_INFO2) & TMIO_SD_INFO2_DAT0); + if (dat0_high == target_dat0_high) { + ret = 0; + break; + } + udelay(10); + } + + return ret; +} +#endif + static const struct dm_mmc_ops renesas_sdhi_ops = { .send_cmd = tmio_sd_send_cmd, .set_ios = renesas_sdhi_set_ios, .get_cd = tmio_sd_get_cd, -#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) .execute_tuning = renesas_sdhi_execute_tuning, #endif +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) + .wait_dat0 = renesas_sdhi_wait_dat0, +#endif }; #define RENESAS_GEN2_QUIRKS TMIO_SD_CAP_RCAR_GEN2 @@ -373,7 +403,7 @@ static int renesas_sdhi_probe(struct udevice *dev) ret = tmio_sd_probe(dev, quirks); #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) - if (!ret) + if (!ret && (priv->caps & TMIO_SD_CAP_RCAR_UHS)) renesas_sdhi_reset_tuning(priv); #endif return ret; |