diff mbox series

[3/4] mmc: fsl_esdhc: add pulse width detection workaround

Message ID 20210317140138.11147-4-michael@walle.cc
State Accepted
Commit d3b745f7d00d07767a0ed85a6b139feeb8df9aaf
Delegated to: Peng Fan
Headers show
Series mmc: fsl_esdhc: ls1028a workarounds | expand

Commit Message

Michael Walle March 17, 2021, 2:01 p.m. UTC
HS400 mode on the LS1028A SoC isn't reliable. The linux driver has a
workaroung for the pulse width detection. Apply this workaround in
u-boot, too.

This will make HS400 mode work reliably on the LS1028A SoC.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 1 +
 drivers/mmc/Kconfig                       | 3 +++
 drivers/mmc/fsl_esdhc.c                   | 6 +++++-
 include/fsl_esdhc.h                       | 3 +++
 4 files changed, 12 insertions(+), 1 deletion(-)

Comments

Jaehoon Chung March 17, 2021, 10:47 p.m. UTC | #1
On 3/17/21 11:01 PM, Michael Walle wrote:
> HS400 mode on the LS1028A SoC isn't reliable. The linux driver has a
> workaroung for the pulse width detection. Apply this workaround in
> u-boot, too.
> 
> This will make HS400 mode work reliably on the LS1028A SoC.
> 
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 1 +
>  drivers/mmc/Kconfig                       | 3 +++
>  drivers/mmc/fsl_esdhc.c                   | 6 +++++-
>  include/fsl_esdhc.h                       | 3 +++
>  4 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
> index c0190a233e..9d1ba4c771 100644
> --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
> +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
> @@ -48,6 +48,7 @@ config ARCH_LS1028A
>  	select SYS_FSL_ERRATUM_A009942 if !TFABOOT
>  	select SYS_FSL_ERRATUM_A050382
>  	select SYS_FSL_ERRATUM_A011334
> +	select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
>  	select RESV_RAM if GIC_V3_ITS
>  	imply PANIC_HANG
>  
> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
> index 0b6755fd90..f7620c9cd1 100644
> --- a/drivers/mmc/Kconfig
> +++ b/drivers/mmc/Kconfig
> @@ -815,3 +815,6 @@ config SYS_FSL_ERRATUM_ESDHC_A001
>  
>  config SYS_FSL_ERRATUM_A011334
>  	bool
> +
> +config SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND

How about using QUIRK instead of WORKAROUD

Best Regards,
Jaehoon Chung

> +	bool
> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
> index 09ea1a9de9..7501fdb71e 100644
> --- a/drivers/mmc/fsl_esdhc.c
> +++ b/drivers/mmc/fsl_esdhc.c
> @@ -71,7 +71,8 @@ struct fsl_esdhc {
>  	uint	sdtimingctl;	/* SD timing control register */
>  	char    reserved8[20];	/* reserved */
>  	uint	dllcfg0;	/* DLL config 0 register */
> -	char	reserved9[12];	/* reserved */
> +	uint	dllcfg1;	/* DLL config 1 register */
> +	char	reserved9[8];	/* reserved */
>  	uint	dllstat0;	/* DLL status 0 register */
>  	char    reserved10[664];/* reserved */
>  	uint    esdhcctl;	/* eSDHC control register */
> @@ -767,6 +768,9 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
>  	/* Set timout to the maximum value */
>  	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
>  
> +	if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND))
> +		esdhc_clrbits32(&regs->dllcfg1, DLL_PD_PULSE_STRETCH_SEL);
> +
>  	return 0;
>  }
>  
> diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
> index 850a304bd7..f86afe5dad 100644
> --- a/include/fsl_esdhc.h
> +++ b/include/fsl_esdhc.h
> @@ -190,6 +190,9 @@
>  #define DLL_RESET		0x40000000
>  #define DLL_FREQ_SEL		0x08000000
>  
> +/* DLL config 1 register */
> +#define DLL_PD_PULSE_STRETCH_SEL 0x80000000
> +
>  /* DLL status 0 register */
>  #define DLL_STS_SLV_LOCK	0x08000000
>  
>
Michael Walle March 17, 2021, 11:01 p.m. UTC | #2
Am 2021-03-17 23:47, schrieb Jaehoon Chung:
> On 3/17/21 11:01 PM, Michael Walle wrote:
>>  config SYS_FSL_ERRATUM_A011334
>>  	bool
>> +
>> +config SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
> 
> How about using QUIRK instead of WORKAROUD

There is already a CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND,
so I chose that for consistency reasons.

-michael
Jaehoon Chung March 18, 2021, 12:06 a.m. UTC | #3
On 3/18/21 8:01 AM, Michael Walle wrote:
> Am 2021-03-17 23:47, schrieb Jaehoon Chung:
>> On 3/17/21 11:01 PM, Michael Walle wrote:
>>>  config SYS_FSL_ERRATUM_A011334
>>>      bool
>>> +
>>> +config SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
>>
>> How about using QUIRK instead of WORKAROUD
> 
> There is already a CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND,
> so I chose that for consistency reasons.

Then i don't have any objection. Thanks!

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> 
> -michael
>
diff mbox series

Patch

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index c0190a233e..9d1ba4c771 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -48,6 +48,7 @@  config ARCH_LS1028A
 	select SYS_FSL_ERRATUM_A009942 if !TFABOOT
 	select SYS_FSL_ERRATUM_A050382
 	select SYS_FSL_ERRATUM_A011334
+	select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
 	select RESV_RAM if GIC_V3_ITS
 	imply PANIC_HANG
 
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0b6755fd90..f7620c9cd1 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -815,3 +815,6 @@  config SYS_FSL_ERRATUM_ESDHC_A001
 
 config SYS_FSL_ERRATUM_A011334
 	bool
+
+config SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
+	bool
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 09ea1a9de9..7501fdb71e 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -71,7 +71,8 @@  struct fsl_esdhc {
 	uint	sdtimingctl;	/* SD timing control register */
 	char    reserved8[20];	/* reserved */
 	uint	dllcfg0;	/* DLL config 0 register */
-	char	reserved9[12];	/* reserved */
+	uint	dllcfg1;	/* DLL config 1 register */
+	char	reserved9[8];	/* reserved */
 	uint	dllstat0;	/* DLL status 0 register */
 	char    reserved10[664];/* reserved */
 	uint    esdhcctl;	/* eSDHC control register */
@@ -767,6 +768,9 @@  static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
 	/* Set timout to the maximum value */
 	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
 
+	if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND))
+		esdhc_clrbits32(&regs->dllcfg1, DLL_PD_PULSE_STRETCH_SEL);
+
 	return 0;
 }
 
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 850a304bd7..f86afe5dad 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -190,6 +190,9 @@ 
 #define DLL_RESET		0x40000000
 #define DLL_FREQ_SEL		0x08000000
 
+/* DLL config 1 register */
+#define DLL_PD_PULSE_STRETCH_SEL 0x80000000
+
 /* DLL status 0 register */
 #define DLL_STS_SLV_LOCK	0x08000000