diff mbox

[U-Boot,4/5] mmc: tegra: allow disabling external clock loopback

Message ID 20161130164702.27372-5-marcel@ziswiler.com
State Superseded
Delegated to: Tom Warren
Headers show

Commit Message

Marcel Ziswiler Nov. 30, 2016, 4:47 p.m. UTC
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>
---

 arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 ++
 drivers/mmc/Kconfig                         |  8 ++++++++
 drivers/mmc/tegra_mmc.c                     | 13 +++++++++++++
 3 files changed, 23 insertions(+)

Comments

Simon Glass Dec. 1, 2016, 2:20 a.m. UTC | #1
Hi Marcel,

On 30 November 2016 at 09:47, Marcel Ziswiler <marcel@ziswiler.com> 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>
> ---
>
>  arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 ++
>  drivers/mmc/Kconfig                         |  8 ++++++++
>  drivers/mmc/tegra_mmc.c                     | 13 +++++++++++++
>  3 files changed, 23 insertions(+)

This should be controlled by the device tree, shouldn't it?

Regards,
Simon
Marcel Ziswiler Dec. 1, 2016, 7:40 a.m. UTC | #2
On December 1, 2016 3:20:55 AM GMT+01:00, Simon Glass <sjg@chromium.org> wrote:
>Hi Marcel,
>
>On 30 November 2016 at 09:47, Marcel Ziswiler <marcel@ziswiler.com>
>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>
>> ---
>>
>>  arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 ++
>>  drivers/mmc/Kconfig                         |  8 ++++++++
>>  drivers/mmc/tegra_mmc.c                     | 13 +++++++++++++
>>  3 files changed, 23 insertions(+)
>
>This should be controlled by the device tree, shouldn't it?

Glad you brought it up. So far NVIDIA hasn't even acknowledged that they completely seriously screwed this one up big time. Unlike their PCIe bug I reported which eventually did make it to the errata... Anyway, my hopes were kind of to sneak this one into U-Boot first, then work on a proper kernel integration probably involving device tree integration and only in a later third step maybe updating this in U-Boot again.

>Regards,
>Simon

Cheers

Marcel
Simon Glass Dec. 5, 2016, 6:23 a.m. UTC | #3
On 1 December 2016 at 00:40, Marcel Ziswiler <marcel@ziswiler.com> wrote:
>
>
> On December 1, 2016 3:20:55 AM GMT+01:00, Simon Glass <sjg@chromium.org> wrote:
>>Hi Marcel,
>>
>>On 30 November 2016 at 09:47, Marcel Ziswiler <marcel@ziswiler.com>
>>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>
>>> ---
>>>
>>>  arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 ++
>>>  drivers/mmc/Kconfig                         |  8 ++++++++
>>>  drivers/mmc/tegra_mmc.c                     | 13 +++++++++++++
>>>  3 files changed, 23 insertions(+)
>>
>>This should be controlled by the device tree, shouldn't it?
>
> Glad you brought it up. So far NVIDIA hasn't even acknowledged that they completely seriously screwed this one up big time. Unlike their PCIe bug I reported which eventually did make it to the errata... Anyway, my hopes were kind of to sneak this one into U-Boot first, then work on a proper kernel integration probably involving device tree integration and only in a later third step maybe updating this in U-Boot again.

OK, please can you add a TODO(email) in there so it is clear this is temporary?

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox

Patch

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 19e89ab..2c71420 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -101,4 +101,12 @@  config TEGRA_MMC
 	help
 	  This selects support for SDHCI on Tegra SoCs.
 
+config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
+	bool "Disable external clock loopback"
+	depends on TEGRA_MMC && 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.
+
 endmenu
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 97b1154..ed02708 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -511,6 +511,19 @@  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.
+	 */
+	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);