Message ID | 20170321092958.4440-3-marcel@ziswiler.com |
---|---|
State | Accepted |
Commit | 4119b7098c8ef83105946502bc7098dec67bd15d |
Delegated to: | Tom Warren |
Headers | show |
On 03/21/2017 06:29 PM, Marcel Ziswiler wrote: > From: Marcel Ziswiler <marcel.ziswiler@toradex.com> > > Introduce CONFIG_TEGRA124_MMC_DISABLE_EXT_LOOPBACK to disable the external clock > loopback and use the internal one on SDMMC3 as per the SDMMC_VENDOR_MISC_CNTRL_0 > register's SDMMC_SPARE1 bits being set to 0xfffd according to the TRM. > > Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> > Reviewed-by: Simon Glass <sjg@chromium.org> > > Signed-off-by: Marcel Ziswiler <marcel@ziswiler.com> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Best Regards, Jaehoon Chung > --- > > Changes in v4: > - Re-based. > > Changes in v3: None > Changes in v2: > - Added Simon's reviewed-by. > - Added TODO(email) as suggested by Simon so it is clear this is > temporary and will be moved to device tree controlled approach once > proper kernel integration made it mainline. > > arch/arm/include/asm/arch-tegra/tegra_mmc.h | 2 ++ > drivers/mmc/Kconfig | 11 +++++++++++ > drivers/mmc/tegra_mmc.c | 16 ++++++++++++++++ > 3 files changed, 29 insertions(+) > > diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h > index 64c848a..c40599a 100644 > --- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h > +++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h > @@ -108,6 +108,8 @@ struct tegra_mmc { > #define TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT 8 > #define TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_MASK (0xff << 8) > > +#define TEGRA_MMC_MISCON_ENABLE_EXT_LOOPBACK (1 << 17) > + > #define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL (1 << 0) > #define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE (1 << 1) > #define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE (1 << 2) > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig > index ddef59a..3a6dcec 100644 > --- a/drivers/mmc/Kconfig > +++ b/drivers/mmc/Kconfig > @@ -345,6 +345,17 @@ config MMC_SUNXI > > endif > > +config TEGRA124_MMC_DISABLE_EXT_LOOPBACK > + bool "Disable external clock loopback" > + depends on MMC_SDHCI_TEGRA && TEGRA124 > + help > + Disable the external clock loopback and use the internal one on SDMMC3 > + as per the SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 bits > + being set to 0xfffd according to the TRM. > + > + TODO(marcel.ziswiler@toradex.com): Move to device tree controlled > + approach once proper kernel integration made it mainline. > + > endmenu > > config SYS_FSL_ERRATUM_ESDHC111 > diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c > index 0df74ef..6c6affb 100644 > --- a/drivers/mmc/tegra_mmc.c > +++ b/drivers/mmc/tegra_mmc.c > @@ -513,6 +513,22 @@ static int tegra_mmc_init(struct mmc *mmc) > > tegra_mmc_reset(priv, mmc); > > +#if defined(CONFIG_TEGRA124_MMC_DISABLE_EXT_LOOPBACK) > + /* > + * Disable the external clock loopback and use the internal one on > + * SDMMC3 as per the SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 > + * bits being set to 0xfffd according to the TRM. > + * > + * TODO(marcel.ziswiler@toradex.com): Move to device tree controlled > + * approach once proper kernel integration made it mainline. > + */ > + if (priv->reg == (void *)0x700b0400) { > + mask = readl(&priv->reg->venmiscctl); > + mask &= ~TEGRA_MMC_MISCON_ENABLE_EXT_LOOPBACK; > + writel(mask, &priv->reg->venmiscctl); > + } > +#endif > + > priv->version = readw(&priv->reg->hcver); > debug("host version = %x\n", priv->version); > >
diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h index 64c848a..c40599a 100644 --- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h +++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h @@ -108,6 +108,8 @@ struct tegra_mmc { #define TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT 8 #define TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_MASK (0xff << 8) +#define TEGRA_MMC_MISCON_ENABLE_EXT_LOOPBACK (1 << 17) + #define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL (1 << 0) #define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE (1 << 1) #define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE (1 << 2) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index ddef59a..3a6dcec 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -345,6 +345,17 @@ config MMC_SUNXI endif +config TEGRA124_MMC_DISABLE_EXT_LOOPBACK + bool "Disable external clock loopback" + depends on MMC_SDHCI_TEGRA && TEGRA124 + help + Disable the external clock loopback and use the internal one on SDMMC3 + as per the SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 bits + being set to 0xfffd according to the TRM. + + TODO(marcel.ziswiler@toradex.com): Move to device tree controlled + approach once proper kernel integration made it mainline. + endmenu config SYS_FSL_ERRATUM_ESDHC111 diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 0df74ef..6c6affb 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -513,6 +513,22 @@ static int tegra_mmc_init(struct mmc *mmc) tegra_mmc_reset(priv, mmc); +#if defined(CONFIG_TEGRA124_MMC_DISABLE_EXT_LOOPBACK) + /* + * Disable the external clock loopback and use the internal one on + * SDMMC3 as per the SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 + * bits being set to 0xfffd according to the TRM. + * + * TODO(marcel.ziswiler@toradex.com): Move to device tree controlled + * approach once proper kernel integration made it mainline. + */ + if (priv->reg == (void *)0x700b0400) { + mask = readl(&priv->reg->venmiscctl); + mask &= ~TEGRA_MMC_MISCON_ENABLE_EXT_LOOPBACK; + writel(mask, &priv->reg->venmiscctl); + } +#endif + priv->version = readw(&priv->reg->hcver); debug("host version = %x\n", priv->version);