Skip to contentSkip to conversation

sunxi: fix eMMC stability issues on A64

PATCH Superseded Vasily Khoruzhick 2 participants 8 messages May 31, 2018 – Jun 4, 2018

Subsystems (4)

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover sunxi: fix eMMC stability issues on A64

eMMC seems to require new clocking mode and calibration on A64, otherwise it is pretty unstable on some boards (e.g. Pinebook) with some eMMCs.

v2: - improve comment about calibration for eMMC on A64
- simplify ifdef-s around configuring delays
v3: - fix fallout due to ifdef simplification in v2

Vasily Khoruzhick (2):
sunxi-mmc: use new mode on A64
mmc: sunxi: run calibration on A64

 arch/arm/include/asm/arch-sunxi/mmc.h |  6 +++++-
 arch/arm/mach-sunxi/Kconfig           |  1 +
 drivers/mmc/sunxi_mmc.c               | 15 +++++++++++++--
 3 files changed, 19 insertions(+), 3 deletions(-)
Signature · 1 line
2.17.0
#1 lore raw

PATCH v3 1/2 sunxi-mmc: use new mode on A64

That is necessary for using automatic calibration on A64 eMMC.

---
 arch/arm/mach-sunxi/Kconfig | 1 +
 drivers/mmc/sunxi_mmc.c     | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-sunxi/Kconfig +1 -0
index 66fb094ac5..8a35033d1f 100644
@@ -257,6 +257,7 @@ config MACH_SUN50I
 	select SUNXI_GEN_SUN6I
 	select SUN6I_PRCM
 	select SUNXI_HIGH_SRAM
+	select MMC_SUNXI_HAS_NEW_MODE
 	select SUPPORT_SPL
 	select SUNXI_DRAM_DW
 	select SUNXI_DRAM_DW_32BIT
drivers/mmc/sunxi_mmc.c +2 -2
index fe6d82c7b4..3bffb1b02e 100644
@@ -165,10 +165,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
 	}
 
 	if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#if defined(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && !defined(CONFIG_MACH_SUN50I)
 		val = CCM_MMC_CTRL_MODE_SEL_NEW;
-		setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
+		setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 	} else {
 		val = CCM_MMC_CTRL_OCLK_DLY(oclk_dly) |
 			CCM_MMC_CTRL_SCLK_DLY(sclk_dly);
Signature · 1 line
2.17.0
#2 lore raw

PATCH v3 1/2 sunxi-mmc: use new mode on A64

Quoted 25 lines · Vasily Khoruzhick

That is necessary for using automatic calibration on A64 eMMC.

---
 arch/arm/mach-sunxi/Kconfig | 1 +
 drivers/mmc/sunxi_mmc.c     | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-sunxi/Kconfig +1 -0
index 66fb094ac5..8a35033d1f 100644
@@ -257,6 +257,7 @@ config MACH_SUN50I
 	select SUNXI_GEN_SUN6I
 	select SUN6I_PRCM
 	select SUNXI_HIGH_SRAM
+	select MMC_SUNXI_HAS_NEW_MODE
 	select SUPPORT_SPL
 	select SUNXI_DRAM_DW
 	select SUNXI_DRAM_DW_32BIT
drivers/mmc/sunxi_mmc.c +0 -0
index fe6d82c7b4..3bffb1b02e 100644

drivers/mmc/sunxi_mmc.c static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) · line 171

Quoted 9 lines
drivers/mmc/sunxi_mmc.c +2 -2
@@ -165,10 +165,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
 	}
 
 	if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#if defined(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && !defined(CONFIG_MACH_SUN50I)
 		val = CCM_MMC_CTRL_MODE_SEL_NEW;
-		setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
+		setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);

This is slightly more complicated than that, we have three cases we need to support:
- Devices without the new mode (A31 and before)
- Devices with support for the new mode that can be toggled (A23/A33 to H3/H5 iirc)
- Devices with support for the new mode only

The latter was introduced by the A64, but is also found on other SoCs now (such as the H6).

So I guess here we need an extra config option to handle it, or even better, base the decision on the compatible like we're doing in Linux.

Maxime

Signature · 3 lines
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
#3 lore raw

PATCH v3 1/2 sunxi-mmc: use new mode on A64

Quoted 28 lines · Maxime Ripard
Quoted 27 lines · Vasily Khoruzhick

That is necessary for using automatic calibration on A64 eMMC.

---
 arch/arm/mach-sunxi/Kconfig | 1 +
 drivers/mmc/sunxi_mmc.c     | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-sunxi/Kconfig +1 -0
index 66fb094ac5..8a35033d1f 100644
@@ -257,6 +257,7 @@ config MACH_SUN50I
      select SUNXI_GEN_SUN6I
      select SUN6I_PRCM
      select SUNXI_HIGH_SRAM
+     select MMC_SUNXI_HAS_NEW_MODE
      select SUPPORT_SPL
      select SUNXI_DRAM_DW
      select SUNXI_DRAM_DW_32BIT
drivers/mmc/sunxi_mmc.c +0 -0
index fe6d82c7b4..3bffb1b02e 100644
@@ -165,10 +165,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
      }
 
Quoted 13 lines

drivers/mmc/sunxi_mmc.c static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) · line 171

Quoted 7 lines
drivers/mmc/sunxi_mmc.c +2 -2
      if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#if defined(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && !defined(CONFIG_MACH_SUN50I)
              val = CCM_MMC_CTRL_MODE_SEL_NEW;
-             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
+             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);

This is slightly more complicated than that, we have three cases we need to support:
- Devices without the new mode (A31 and before)
- Devices with support for the new mode that can be toggled (A23/A33 to H3/H5 iirc)
- Devices with support for the new mode only

Right.

Quoted 5 lines

The latter was introduced by the A64, but is also found on other SoCs now (such as the H6).

So I guess here we need an extra config option to handle it, or even better, base the decision on the compatible like we're doing in Linux.

OK, sounds reasonable. However using compatibles (and thus switching to DM_MMC) would be more invasive chance and I won't be able to test it on all platforms that use sunxi_mmc driver.

Quoted 7 lines

Maxime

--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

#4 lore raw

PATCH v3 1/2 sunxi-mmc: use new mode on A64

Quoted 49 lines · Vasily Khoruzhick
Quoted 28 lines · Maxime Ripard
Quoted 27 lines · Vasily Khoruzhick

That is necessary for using automatic calibration on A64 eMMC.

---
 arch/arm/mach-sunxi/Kconfig | 1 +
 drivers/mmc/sunxi_mmc.c     | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-sunxi/Kconfig +1 -0
index 66fb094ac5..8a35033d1f 100644
@@ -257,6 +257,7 @@ config MACH_SUN50I
      select SUNXI_GEN_SUN6I
      select SUN6I_PRCM
      select SUNXI_HIGH_SRAM
+     select MMC_SUNXI_HAS_NEW_MODE
      select SUPPORT_SPL
      select SUNXI_DRAM_DW
      select SUNXI_DRAM_DW_32BIT
drivers/mmc/sunxi_mmc.c +0 -0
index fe6d82c7b4..3bffb1b02e 100644
@@ -165,10 +165,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
      }
 
Quoted 13 lines

drivers/mmc/sunxi_mmc.c static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) · line 171

Quoted 7 lines
drivers/mmc/sunxi_mmc.c +2 -2
      if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#if defined(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && !defined(CONFIG_MACH_SUN50I)
              val = CCM_MMC_CTRL_MODE_SEL_NEW;
-             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
+             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);

This is slightly more complicated than that, we have three cases we need to support:
- Devices without the new mode (A31 and before)
- Devices with support for the new mode that can be toggled (A23/A33 to H3/H5 iirc)
- Devices with support for the new mode only

Right.

Quoted 3 lines

The latter was introduced by the A64, but is also found on other SoCs now (such as the H6).

Quoted 6 lines
Quoted 2 lines

So I guess here we need an extra config option to handle it, or even better, base the decision on the compatible like we're doing in Linux.

OK, sounds reasonable. However using compatibles (and thus switching to DM_MMC) would be more invasive chance and I won't be able to test it on all platforms that use sunxi_mmc driver.

We already have DM_MMC support in the driver. The only thing that seems to be missing are the A64 compatibles, and to test. But most of the driver is shared, so I don't expect a lot of trouble there.

Maxime

Signature · 10 lines
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180601/d9d18848/attachment.sig>
#5 lore raw

PATCH v3 1/2 sunxi-mmc: use new mode on A64

Quoted 54 lines · Maxime Ripard
Quoted 52 lines · Vasily Khoruzhick
Quoted 28 lines · Maxime Ripard
Quoted 27 lines · Vasily Khoruzhick

That is necessary for using automatic calibration on A64 eMMC.

---
 arch/arm/mach-sunxi/Kconfig | 1 +
 drivers/mmc/sunxi_mmc.c     | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-sunxi/Kconfig +1 -0
index 66fb094ac5..8a35033d1f 100644
@@ -257,6 +257,7 @@ config MACH_SUN50I
      select SUNXI_GEN_SUN6I
      select SUN6I_PRCM
      select SUNXI_HIGH_SRAM
+     select MMC_SUNXI_HAS_NEW_MODE
      select SUPPORT_SPL
      select SUNXI_DRAM_DW
      select SUNXI_DRAM_DW_32BIT
drivers/mmc/sunxi_mmc.c +0 -0
index fe6d82c7b4..3bffb1b02e 100644
@@ -165,10 +165,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
      }
 
Quoted 13 lines

drivers/mmc/sunxi_mmc.c static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) · line 171

Quoted 7 lines
drivers/mmc/sunxi_mmc.c +2 -2
      if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#if defined(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && !defined(CONFIG_MACH_SUN50I)
              val = CCM_MMC_CTRL_MODE_SEL_NEW;
-             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
+             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);

This is slightly more complicated than that, we have three cases we need to support:
- Devices without the new mode (A31 and before)
- Devices with support for the new mode that can be toggled (A23/A33 to H3/H5 iirc)
- Devices with support for the new mode only

Right.

Quoted 5 lines

The latter was introduced by the A64, but is also found on other SoCs now (such as the H6).

So I guess here we need an extra config option to handle it, or even better, base the decision on the compatible like we're doing in Linux.

Quoted 7 lines
Quoted 3 lines

OK, sounds reasonable. However using compatibles (and thus switching to DM_MMC) would be more invasive chance and I won't be able to test it on all platforms that use sunxi_mmc driver.

We already have DM_MMC support in the driver. The only thing that seems to be missing are the A64 compatibles, and to test. But most of the driver is shared, so I don't expect a lot of trouble there.

With DM_MMC enabled SPL doesn't fit into 32k on A64:

aarch64-linux-gnu-ld.bfd: region `.sram' overflowed by 10584 bytes

Quoted 7 lines

Maxime

--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

#6 lore raw

PATCH v3 1/2 sunxi-mmc: use new mode on A64

Quoted 59 lines · Vasily Khoruzhick
Quoted 58 lines · Maxime Ripard
Quoted 55 lines · Vasily Khoruzhick
Quoted 28 lines · Maxime Ripard
Quoted 27 lines · Vasily Khoruzhick

That is necessary for using automatic calibration on A64 eMMC.

---
 arch/arm/mach-sunxi/Kconfig | 1 +
 drivers/mmc/sunxi_mmc.c     | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-sunxi/Kconfig +1 -0
index 66fb094ac5..8a35033d1f 100644
@@ -257,6 +257,7 @@ config MACH_SUN50I
      select SUNXI_GEN_SUN6I
      select SUN6I_PRCM
      select SUNXI_HIGH_SRAM
+     select MMC_SUNXI_HAS_NEW_MODE
      select SUPPORT_SPL
      select SUNXI_DRAM_DW
      select SUNXI_DRAM_DW_32BIT
drivers/mmc/sunxi_mmc.c +0 -0
index fe6d82c7b4..3bffb1b02e 100644
@@ -165,10 +165,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
      }
 
Quoted 13 lines

drivers/mmc/sunxi_mmc.c static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) · line 171

Quoted 7 lines
drivers/mmc/sunxi_mmc.c +2 -2
      if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#if defined(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && !defined(CONFIG_MACH_SUN50I)
              val = CCM_MMC_CTRL_MODE_SEL_NEW;
-             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
+             setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);

This is slightly more complicated than that, we have three cases we need to support:
- Devices without the new mode (A31 and before)
- Devices with support for the new mode that can be toggled (A23/A33 to H3/H5 iirc)
- Devices with support for the new mode only

Right.

Quoted 5 lines

The latter was introduced by the A64, but is also found on other SoCs now (such as the H6).

So I guess here we need an extra config option to handle it, or even better, base the decision on the compatible like we're doing in Linux.

OK, sounds reasonable. However using compatibles (and thus switching to DM_MMC) would be more invasive chance and I won't be able to test it on all platforms that use sunxi_mmc driver.

Quoted 7 lines
Quoted 3 lines

We already have DM_MMC support in the driver. The only thing that seems to be missing are the A64 compatibles, and to test. But most of the driver is shared, so I don't expect a lot of trouble there.

With DM_MMC enabled SPL doesn't fit into 32k on A64:

aarch64-linux-gnu-ld.bfd: region `.sram' overflowed by 10584 bytes

Hm, too bad... do we have TINY_MMC enabled?

Maxime

Signature · 10 lines
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180604/d7f6ad8d/attachment.sig>
#7 lore raw

PATCH v3 2/2 mmc: sunxi: run calibration on A64

In reply to Vasily Khoruzhick

Along with using new mode it fixes eMMC instability on Pinebook

---
 arch/arm/include/asm/arch-sunxi/mmc.h |  6 +++++-
 drivers/mmc/sunxi_mmc.c               | 11 +++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
arch/arm/include/asm/arch-sunxi/mmc.h +5 -1
index 1574b8e8fe..d6664a01f2 100644
@@ -46,7 +46,9 @@ struct sunxi_mmc {
 	u32 cbda;		/* 0x94 */
 	u32 res2[26];
 #ifdef CONFIG_SUNXI_GEN_SUN6I
-	u32 res3[64];
+	u32 res3[17];
+	u32 samp_dl;
+	u32 res4[46];
 #endif
 	u32 fifo;		/* 0x100 / 0x200 FIFO access address */
 };
@@ -130,5 +132,7 @@ struct sunxi_mmc {
 #define SUNXI_MMC_COMMON_CLK_GATE		(1 << 16)
 #define SUNXI_MMC_COMMON_RESET			(1 << 18)
 
+#define SUNXI_MMC_CAL_DL_SW_EN		(0x1 << 7)
+
 struct mmc *sunxi_mmc_init(int sdc_no);
 #endif /* _SUNXI_MMC_H */
drivers/mmc/sunxi_mmc.c +11 -0
index 3bffb1b02e..bbfcf37b6c 100644
@@ -223,6 +223,17 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
 	rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
 	writel(rval, &priv->reg->clkcr);
 
+#ifdef CONFIG_MACH_SUN50I
+	/* A64 needs to run calibration on eMMC controller and we
+	 * have to set delay of zero before starting calibration.
+	 * Allwinner BSP driver sets a delay only in the case of
+	 * using HS400 which is not supported by mainline U-Boot or
+	 * Linux at the moment
+	 */
+	if (priv->mmc_no == 2)
+		writel(SUNXI_MMC_CAL_DL_SW_EN, &priv->reg->samp_dl);
+#endif
+
 	/* Re-enable Clock */
 	rval |= SUNXI_MMC_CLK_ENABLE;
 	writel(rval, &priv->reg->clkcr);
Signature · 1 line
2.17.0