[v2, 0/2] mmc: fsl_esdhc: fix up for eMMC HS400

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[v2, 0/2] mmc: fsl_esdhc: fix up for eMMC HS400

Yangbo Lu
This patch-set provides fix up for eMMC HS400 for a potential
DLL lock issue during mmc rescan.

Changes for v2:
- Added "Reviewed-by".
- Explained more in patch 2 commit message.

Yangbo Lu (2):
  mmc: fsl_esdhc: set sysctl register for clock initialization
  mmc: fsl_esdhc: make sure delay chain locked for HS400

 drivers/mmc/fsl_esdhc.c | 30 ++++++++++++++++++++++++++----
 include/fsl_esdhc.h     |  4 ++++
 2 files changed, 30 insertions(+), 4 deletions(-)

--
2.7.4

Reply | Threaded
Open this post in threaded view
|

[v2, 1/2] mmc: fsl_esdhc: set sysctl register for clock initialization

Yangbo Lu
The initial clock setting should be through sysctl register only,
while the mmc_set_clock() will call mmc_set_ios() introduce other
configurations like bus width, mode, and so on.

Signed-off-by: Yangbo Lu <[hidden email]>
Reviewed-by: Jaehoon Chung <[hidden email]>
---
Changes for v2:
        - Added "Reviewed-by".
---
 drivers/mmc/fsl_esdhc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 642784e..68130ee 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -715,7 +715,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
  esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
 
  /* Set the initial clock speed */
- mmc_set_clock(mmc, 400000, MMC_CLK_ENABLE);
+ set_sysctl(priv, mmc, 400000);
 
  /* Disable the BRR and BWR bits in IRQSTAT */
  esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
--
2.7.4

Reply | Threaded
Open this post in threaded view
|

[v2, 2/2] mmc: fsl_esdhc: make sure delay chain locked for HS400

Yangbo Lu
In reply to this post by Yangbo Lu
For eMMC HS400 mode, the DLL reset is a required step for mmc rescan.
This step has not been documented in reference manual, but the RM will
be fixed sooner or later.

In previous commit to support eMMC HS400,
  db8f936 mmc: fsl_esdhc: support eMMC HS400 mode

the steps to configure DLL could be found in commit message,
  13. Set DLLCFG0[DLL_ENABLE] and DLLCFG0[DLL_FREQ_SEL].
  14. Wait for delay chain to lock.

these would be fixed as,
  13.   Set DLLCFG0[DLL_ENABLE] and DLLCFG0[DLL_FREQ_SEL].
  13.1  Write DLLCFG0[DLL_RESET] to 1 and wait for 1us,
        then write DLLCFG0[DLL_RESET]
  14.   Wait for delay chain to lock.

This patch is to add the step of DLL reset, and make sure delay chain
locked for HS400.

Fixes: db8f93672b42 ("mmc: fsl_esdhc: support eMMC HS400 mode")
Signed-off-by: Yangbo Lu <[hidden email]>
Reviewed-by: Jaehoon Chung <[hidden email]>
---
Changes for v2:
        - Added "Reviewed-by".
        - Explained more in commit message.
---
 drivers/mmc/fsl_esdhc.c | 28 +++++++++++++++++++++++++---
 include/fsl_esdhc.h     |  4 ++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 68130ee..a18316e 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -70,7 +70,9 @@ struct fsl_esdhc {
  uint sdtimingctl; /* SD timing control register */
  char    reserved8[20]; /* reserved */
  uint dllcfg0; /* DLL config 0 register */
- char    reserved9[680]; /* reserved */
+ char reserved9[12]; /* reserved */
+ uint dllstat0; /* DLL status 0 register */
+ char    reserved10[664];/* reserved */
  uint    esdhcctl; /* eSDHC control register */
 };
 
@@ -617,9 +619,11 @@ static void esdhc_exit_hs400(struct fsl_esdhc_priv *priv)
  esdhc_tuning_block_enable(priv, false);
 }
 
-static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode)
+static int esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode)
 {
  struct fsl_esdhc *regs = priv->esdhc_regs;
+ ulong start;
+ u32 val;
 
  /* Exit HS400 mode before setting any other mode */
  if (esdhc_read32(&regs->tbctl) & HS400_MODE &&
@@ -640,17 +644,33 @@ static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode)
  esdhc_setbits32(&regs->dllcfg0, DLL_FREQ_SEL);
 
  esdhc_setbits32(&regs->dllcfg0, DLL_ENABLE);
+
+ esdhc_setbits32(&regs->dllcfg0, DLL_RESET);
+ udelay(1);
+ esdhc_clrbits32(&regs->dllcfg0, DLL_RESET);
+
+ start = get_timer(0);
+ val = DLL_STS_SLV_LOCK;
+ while (!(esdhc_read32(&regs->dllstat0) & val)) {
+ if (get_timer(start) > 1000) {
+ printf("fsl_esdhc: delay chain lock timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+
  esdhc_setbits32(&regs->tbctl, HS400_WNDW_ADJUST);
 
  esdhc_clock_control(priv, false);
  esdhc_flush_async_fifo(priv);
  }
  esdhc_clock_control(priv, true);
+ return 0;
 }
 
 static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
 {
  struct fsl_esdhc *regs = priv->esdhc_regs;
+ int ret;
 
  if (priv->is_sdhc_per_clk) {
  /* Select to use peripheral clock */
@@ -667,7 +687,9 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
  set_sysctl(priv, mmc, mmc->clock);
 
  /* Set timing */
- esdhc_set_timing(priv, mmc->selected_mode);
+ ret = esdhc_set_timing(priv, mmc->selected_mode);
+ if (ret)
+ return ret;
 
  /* Set the bus width */
  esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index e6f1c75..850a304 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -187,8 +187,12 @@
 
 /* DLL config 0 register */
 #define DLL_ENABLE 0x80000000
+#define DLL_RESET 0x40000000
 #define DLL_FREQ_SEL 0x08000000
 
+/* DLL status 0 register */
+#define DLL_STS_SLV_LOCK 0x08000000
+
 #define MAX_TUNING_LOOP 40
 
 #define HOSTVER_VENDOR(x) (((x) >> 8) & 0xff)
--
2.7.4

Reply | Threaded
Open this post in threaded view
|

RE: [v2, 0/2] mmc: fsl_esdhc: fix up for eMMC HS400

Yangbo Lu
In reply to this post by Yangbo Lu
Hi Peng,

Any comments on the patches.
Thanks.

Best regards,
Yangbo Lu

> -----Original Message-----
> From: Yangbo Lu <[hidden email]>
> Sent: Tuesday, October 20, 2020 11:05 AM
> To: [hidden email]; Peng Fan <[hidden email]>; 'Jaehoon Chung'
> <[hidden email]>
> Cc: Y.b. Lu <[hidden email]>
> Subject: [v2, 0/2] mmc: fsl_esdhc: fix up for eMMC HS400
>
> This patch-set provides fix up for eMMC HS400 for a potential
> DLL lock issue during mmc rescan.
>
> Changes for v2:
> - Added "Reviewed-by".
> - Explained more in patch 2 commit message.
>
> Yangbo Lu (2):
>   mmc: fsl_esdhc: set sysctl register for clock initialization
>   mmc: fsl_esdhc: make sure delay chain locked for HS400
>
>  drivers/mmc/fsl_esdhc.c | 30 ++++++++++++++++++++++++++----
>  include/fsl_esdhc.h     |  4 ++++
>  2 files changed, 30 insertions(+), 4 deletions(-)
>
> --
> 2.7.4