Re: [PATCH 2/2] mmc: t210: Fix 'bad' SD-card clock when doing 400KHz card detect

2020-04-01 Thread Jaehoon Chung
On 3/27/20 7:30 AM, tomcwarren3...@gmail.com wrote:
> From: Tom Warren 
> 
> According to the HW team, for some reason the normal clock select code
> picks what appears to be a perfectly valid 375KHz SD card clock, based
> on the CAR clock source and SDMMC1 controller register settings (CAR =
> 408MHz PLLP0 divided by 68 for 6MHz, then a SD Clock Control register
> divisor of 16 = 375KHz). But the resulting SD card clock, as measured by
> the HW team, is 700KHz, which is out-of-spec. So the WAR is to use the
> values given in the TRM PLLP table to generate a 400KHz SD-clock (CAR
> clock of 24.7MHz, SD Clock Control divisor of 62) only for SDMMC1 on
> T210 when the requested clock is <= 400KHz. Note that as far as I can
> tell, the other requests for clocks in the Tegra MMC driver result in
> valid SD clocks.
> 
> Signed-off-by: Tom Warren 


Reviewed-by: Jaehoon Chung 

Best Regards,
Jaehoon Chung

> ---
> Changes for v2:
>  - None
> 
>  arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 +-
>  drivers/mmc/tegra_mmc.c | 18 ++
>  2 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h 
> b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
> index a8bfa46..70dcf4a 100644
> --- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h
> +++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
> @@ -130,9 +130,9 @@ struct tegra_mmc {
>  /* SDMMC1/3 settings from SDMMCx Initialization Sequence of TRM */
>  #define MEMCOMP_PADCTRL_VREF 7
>  #define AUTO_CAL_ENABLE  (1 << 29)
> -#if defined(CONFIG_TEGRA210)
>  #define AUTO_CAL_ACTIVE  (1 << 31)
>  #define AUTO_CAL_START   (1 << 31)
> +#if defined(CONFIG_TEGRA210)
>  #define AUTO_CAL_PD_OFFSET   (0x7D << 8)
>  #define AUTO_CAL_PU_OFFSET   (0 << 0)
>  #define IO_TRIM_BYPASS_MASK  (1 << 2)
> diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
> index 73ac58c..03110ba 100644
> --- a/drivers/mmc/tegra_mmc.c
> +++ b/drivers/mmc/tegra_mmc.c
> @@ -376,6 +376,24 @@ static void tegra_mmc_change_clock(struct tegra_mmc_priv 
> *priv, uint clock)
>  
>   rate = clk_set_rate(>clk, clock);
>   div = (rate + clock - 1) / clock;
> +
> +#if defined(CONFIG_TEGRA210)
> + if (priv->mmc_id == PERIPH_ID_SDMMC1 && clock <= 40) {
> + /* clock_adjust_periph_pll_div() chooses a 'bad' clock
> +  * on SDMMC1 T210, so skip it here and force a clock
> +  * that's been spec'd in the table in the TRM for
> +  * card-detect (400KHz).
> +  */
> + uint effective_rate = clock_adjust_periph_pll_div(priv->mmc_id,
> + CLOCK_ID_PERIPH, 24727273, NULL);
> + div = 62;
> +
> + debug("%s: WAR: Using SDMMC1 clock of %u, div %d to achieve 
> %dHz card clock ...\n",
> + __func__, effective_rate, div, clock);
> + } else
> + clock_adjust_periph_pll_div(priv->mmc_id, CLOCK_ID_PERIPH, 
> clock,
> + );
> +#endif
>   debug("div = %d\n", div);
>  
>   writew(0, >reg->clkcon);
> 



[PATCH 2/2] mmc: t210: Fix 'bad' SD-card clock when doing 400KHz card detect

2020-03-26 Thread tomcwarren3959
From: Tom Warren 

According to the HW team, for some reason the normal clock select code
picks what appears to be a perfectly valid 375KHz SD card clock, based
on the CAR clock source and SDMMC1 controller register settings (CAR =
408MHz PLLP0 divided by 68 for 6MHz, then a SD Clock Control register
divisor of 16 = 375KHz). But the resulting SD card clock, as measured by
the HW team, is 700KHz, which is out-of-spec. So the WAR is to use the
values given in the TRM PLLP table to generate a 400KHz SD-clock (CAR
clock of 24.7MHz, SD Clock Control divisor of 62) only for SDMMC1 on
T210 when the requested clock is <= 400KHz. Note that as far as I can
tell, the other requests for clocks in the Tegra MMC driver result in
valid SD clocks.

Signed-off-by: Tom Warren 
---
Changes for v2:
 - None

 arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 +-
 drivers/mmc/tegra_mmc.c | 18 ++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h 
b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
index a8bfa46..70dcf4a 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
@@ -130,9 +130,9 @@ struct tegra_mmc {
 /* SDMMC1/3 settings from SDMMCx Initialization Sequence of TRM */
 #define MEMCOMP_PADCTRL_VREF   7
 #define AUTO_CAL_ENABLE(1 << 29)
-#if defined(CONFIG_TEGRA210)
 #define AUTO_CAL_ACTIVE(1 << 31)
 #define AUTO_CAL_START (1 << 31)
+#if defined(CONFIG_TEGRA210)
 #define AUTO_CAL_PD_OFFSET (0x7D << 8)
 #define AUTO_CAL_PU_OFFSET (0 << 0)
 #define IO_TRIM_BYPASS_MASK(1 << 2)
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 73ac58c..03110ba 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -376,6 +376,24 @@ static void tegra_mmc_change_clock(struct tegra_mmc_priv 
*priv, uint clock)
 
rate = clk_set_rate(>clk, clock);
div = (rate + clock - 1) / clock;
+
+#if defined(CONFIG_TEGRA210)
+   if (priv->mmc_id == PERIPH_ID_SDMMC1 && clock <= 40) {
+   /* clock_adjust_periph_pll_div() chooses a 'bad' clock
+* on SDMMC1 T210, so skip it here and force a clock
+* that's been spec'd in the table in the TRM for
+* card-detect (400KHz).
+*/
+   uint effective_rate = clock_adjust_periph_pll_div(priv->mmc_id,
+   CLOCK_ID_PERIPH, 24727273, NULL);
+   div = 62;
+
+   debug("%s: WAR: Using SDMMC1 clock of %u, div %d to achieve 
%dHz card clock ...\n",
+   __func__, effective_rate, div, clock);
+   } else
+   clock_adjust_periph_pll_div(priv->mmc_id, CLOCK_ID_PERIPH, 
clock,
+   );
+#endif
debug("div = %d\n", div);
 
writew(0, >reg->clkcon);
-- 
1.8.2.1.610.g562af5b


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---


[PATCH 2/2] mmc: t210: Fix 'bad' SD-card clock when doing 400KHz card detect

2020-03-16 Thread twarren
From: Tom Warren 

According to the HW team, for some reason the normal clock select code
picks what appears to be a perfectly valid 375KHz SD card clock, based
on the CAR clock source and SDMMC1 controller register settings (CAR =
408MHz PLLP0 divided by 68 for 6MHz, then a SD Clock Control register
divisor of 16 = 375KHz). But the resulting SD card clock, as measured by
the HW team, is 700KHz, which is out-of-spec. So the WAR is to use the
values given in the TRM PLLP table to generate a 400KHz SD-clock (CAR
clock of 24.7MHz, SD Clock Control divisor of 62) only for SDMMC1 on
T210 when the requested clock is <= 400KHz. Note that as far as I can
tell, the other requests for clocks in the Tegra MMC driver result in
valid SD clocks.

Signed-off-by: Tom Warren 
---
 arch/arm/include/asm/arch-tegra/tegra_mmc.h |  2 +-
 drivers/mmc/tegra_mmc.c | 18 ++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h 
b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
index a8bfa46..70dcf4a 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
@@ -130,9 +130,9 @@ struct tegra_mmc {
 /* SDMMC1/3 settings from SDMMCx Initialization Sequence of TRM */
 #define MEMCOMP_PADCTRL_VREF   7
 #define AUTO_CAL_ENABLE(1 << 29)
-#if defined(CONFIG_TEGRA210)
 #define AUTO_CAL_ACTIVE(1 << 31)
 #define AUTO_CAL_START (1 << 31)
+#if defined(CONFIG_TEGRA210)
 #define AUTO_CAL_PD_OFFSET (0x7D << 8)
 #define AUTO_CAL_PU_OFFSET (0 << 0)
 #define IO_TRIM_BYPASS_MASK(1 << 2)
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index a4bd679..3ca947c 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -376,6 +376,24 @@ static void tegra_mmc_change_clock(struct tegra_mmc_priv 
*priv, uint clock)
 
rate = clk_set_rate(>clk, clock);
div = (rate + clock - 1) / clock;
+
+#if defined(CONFIG_TEGRA210)
+   if (priv->mmc_id == PERIPH_ID_SDMMC1 && clock <= 40) {
+   /* clock_adjust_periph_pll_div() chooses a 'bad' clock
+* on SDMMC1 T210, so skip it here and force a clock
+* that's been spec'd in the table in the TRM for
+* card-detect (400KHz).
+*/
+   uint effective_rate = clock_adjust_periph_pll_div(priv->mmc_id,
+   CLOCK_ID_PERIPH, 24727273, NULL);
+   div = 62;
+
+   debug("%s: WAR: Using SDMMC1 clock of %u, div %d to achieve 
%dHz card clock ...\n",
+   __func__, effective_rate, div, clock);
+   } else
+   clock_adjust_periph_pll_div(priv->mmc_id, CLOCK_ID_PERIPH, 
clock,
+   );
+#endif
debug("div = %d\n", div);
 
writew(0, >reg->clkcon);
-- 
1.8.2.1.610.g562af5b


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---