How to Properly increase MMC Drive Strength with U-Boot for eMMC on SAMA5D27 WLSOM1

Discussion around products based on ARM Cortex-A5 core.

Moderator: nferre

philbot999
Posts: 1
Joined: Mon Aug 17, 2020 5:10 pm

How to Properly increase MMC Drive Strength with U-Boot for eMMC on SAMA5D27 WLSOM1

Mon Dec 21, 2020 5:58 pm

I am using the SAMA5D27 WLSOM1 module in a new product and am successfully booting Linux from an SD Card. I came across this Linux4SAM wiki page, which mentions several eMMC chips that works with the WLSOM1 --> https://www.linux4sam.org/bin/view/Linu ... MMCSupport

In order to evaluate them with our product, I purchased a "micro-sd to eMMC" adapter from Friendly Elec and their 16 GB Samsung eMMC module ( https://www.friendlyarm.com/index.php?r ... uct_id=240 ). The part number is the same as one of the wiki listed parts.

I flashed the eMMC from my laptop with the same image that worked on the micro sd card. When I first tried to boot, AT91Bootstrap would not recognize the part. I then read on the Linux4SAM wiki that I had to increase the drive strength for the mmc0 pins. I did that with this patch and it worked. The part now always recognizes the eMMC, and loads and launches U-Boot:

Code: Select all

@@ -468,12 +466,12 @@
 {
 #if defined(CONFIG_SDHC0)
 	const struct pio_desc sdmmc_pins[] = {
-		{"SDMMC0_CK",   AT91C_PIN_PA(0), 0, PIO_DEFAULT, PIO_PERIPH_A},
-		{"SDMMC0_CMD",  AT91C_PIN_PA(1), 0, PIO_DEFAULT, PIO_PERIPH_A},
-		{"SDMMC0_DAT0", AT91C_PIN_PA(2), 0, PIO_DEFAULT, PIO_PERIPH_A},
-		{"SDMMC0_DAT1", AT91C_PIN_PA(3), 0, PIO_DEFAULT, PIO_PERIPH_A},
-		{"SDMMC0_DAT2", AT91C_PIN_PA(4), 0, PIO_DEFAULT, PIO_PERIPH_A},
-		{"SDMMC0_DAT3", AT91C_PIN_PA(5), 0, PIO_DEFAULT, PIO_PERIPH_A},
+		{"SDMMC0_CK",   AT91C_PIN_PA(0), 0, PIO_DRVSTR_HI, PIO_PERIPH_A},
+		{"SDMMC0_CMD",  AT91C_PIN_PA(1), 0, PIO_DRVSTR_HI, PIO_PERIPH_A},
+		{"SDMMC0_DAT0", AT91C_PIN_PA(2), 0, PIO_DRVSTR_HI, PIO_PERIPH_A},
+		{"SDMMC0_DAT1", AT91C_PIN_PA(3), 0, PIO_DRVSTR_HI, PIO_PERIPH_A},
+		{"SDMMC0_DAT2", AT91C_PIN_PA(4), 0, PIO_DRVSTR_HI, PIO_PERIPH_A},
+		{"SDMMC0_DAT3", AT91C_PIN_PA(5), 0, PIO_DRVSTR_HI, PIO_PERIPH_A},
 		{"SDMMC0_VDDSEL", AT91C_PIN_PA(11), 0, PIO_DEFAULT, PIO_PERIPH_A},
 		{"SDMMC0_WP",   AT91C_PIN_PA(12), 1, PIO_DEFAULT, PIO_PERIPH_A},
 		{"SDMMC0_CD",   AT91C_PIN_PA(13), 0, PIO_DEFAULT, PIO_PERIPH_A},
After that change, the board would load U-Boot from the eMMC, U-Boot would recognize the eMMC part, and could sometimes list my files on the FAT partition, however it could not load the Kernel ITB file. It would fail with various ( changing ) errors such as "Error reading cluster" and "** No partition table - mmc 0 **". On 1 very rare boot, it loaded the Kernel ITB file, but failed to boot successfully to Linux, it hung shortly loading.

Here is the successful enumeration of the eMMC by AT91Bootstrap:

Code: Select all

AT91Bootstrap 3.10.0-dirty (2020-10-02)

SD/MMC: Image: Read file u-boot.bin to 0x26f00000
MMC: ADMA supported
MMC: Specification Version 4.0 or higher
MMC: v5.1 detected
MMC: highspeed supported
MMC: Dual Data Rate supported
MMC: detecting buswidth...
SDHC: Error detected in status: 0x8020, 0x40
MMC: 4-bit bus width detected
SD/MMC: Done to load image
<debug_uart> 

U-Boot 2020.01-linux4sam-2020.04 (May 22 2020)

CPU: SAMA5D27 2G bits LPDDR2 SDRAM
Crystal frequency:       24 MHz
CPU clock        :      492 MHz
Master clock     :      164 MHz
DRAM:  256 MiB
MMC:   sdio-hosta0000000: 0
Loading Environment from FAT... clock is disabled (0Hz)
clock is enabled (400000Hz)
clock is enabled (25000000Hz)
clock is enabled (52000000Hz)
Error reading cluster
Unable to read "uboot.env" from mmc0:1... In:    serialf8020000
Out:   serialf8020000
Err:   serialf8020000
Model: Microchip SAMA5D27 WLSOM1 EK
SF: Detected sst26vf064b with page size 256 Bytes, erase size 4 KiB, total 8 MiB
Net:   eth0: ethernetf8008000
Hit any key to stop autoboot:  0 
** No partition table - mmc 0 **
** No partition table - mmc 0 **
Here is the rescan of the eMMC with U-Boot, and the failure to load the Kernel ITB file:

Code: Select all

=> mmc rescan
clock is disabled (0Hz)
clock is enabled (400000Hz)
clock is enabled (25000000Hz)
clock is enabled (52000000Hz)
=> mmc dev 0:1
clock is disabled (0Hz)
clock is enabled (400000Hz)
clock is enabled (25000000Hz)
clock is enabled (52000000Hz)
switch to partitions #0, OK
mmc0(part 0) is current device
=> 
=> fatls mmc 0:1 /
    19545   BOOT.BIN
  8663854   sama5d27_wlsom1_ek.itb
   502826   u-boot.bin
    16384   uboot.env
            .fseventsd/

4 file(s), 1 dir(s)

=> fatls mmc 0:1 /
    19545   BOOT.BIN
  8663854   sama5d27_wlsom1_ek.itb
   502826   u-boot.bin
    16384   uboot.env
            .fseventsd/

4 file(s), 1 dir(s)

=> fatls mmc 0:1 /
    19545   BOOT.BIN
  8663854   sama5d27_wlsom1_ek.itb
   502826   u-boot.bin
    16384   uboot.env
            .fseventsd/

4 file(s), 1 dir(s)

=> fatload mmc 0:1 0x24000000 sama5d27_wlsom1_ek.itb
Error reading cluster
** Unable to read file sama5d27_wlsom1_ek.itb **
=> fatls mmc 0:1 /                                  
** No partition table - mmc 0 **
I believe I need to increase the drive strength for U-Boot, however I have tried multiple ways to do it, and none of them allow Linux to be loaded from the eMMC successfully.

Code: Select all

--- git/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
+++ git.new/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
@@ -95,13 +95,16 @@
 #ifdef CONFIG_SD_BOOT
 void spl_mmc_init(void)
 {
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, 0);	/* CMD */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, 0);	/* DAT0 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, 0);	/* DAT1 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, 0);	/* DAT2 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, 0);	/* DAT3 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, 0);	/* CK */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 13, 0);	/* CD */
+
+	// Boost Drive Strength for eMMC boots
+	printf("Changing Drive Strength Now!\n");
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, ATMEL_PIO_DRVSTR_HI);	/* CMD */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, ATMEL_PIO_DRVSTR_HI);	/* DAT0 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, ATMEL_PIO_DRVSTR_HI);	/* DAT1 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, ATMEL_PIO_DRVSTR_HI);	/* DAT2 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, ATMEL_PIO_DRVSTR_HI);	/* DAT3 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, ATMEL_PIO_DRVSTR_HI);	/* CK */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 13, ATMEL_PIO_DRVSTR_HI);	/* CD */
 
 	at91_periph_clk_enable(ATMEL_ID_SDMMC0);
 }

Code: Select all

--- git/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts
+++ git.new/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts
@@ -120,7 +120,10 @@
 							 <PIN_PA3__SDMMC0_DAT1>,
 							 <PIN_PA4__SDMMC0_DAT2>,
 							 <PIN_PA5__SDMMC0_DAT3>;
-						bias-disable;
+						/* Increase drive strength for DDR modes */
+						atmel,drive-strength = <3>;
+						/* eMMC is missing pull-ups */
+						bias-pull-up;
 					};
 
 					pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default {
@@ -128,7 +131,10 @@
 							 <PIN_PA11__SDMMC0_VDDSEL>,
 							 <PIN_PA12__SDMMC0_WP>,
 							 <PIN_PA13__SDMMC0_CD>;
-						bias-disable;
+						/* Increase drive strength for DDR modes */
+						atmel,drive-strength = <3>;
+						/* eMMC is missing pull-ups */
+						bias-pull-up;
 					};
 
 					pinctrl_uart0_default: uart0_default {
I also tried the Linux4SAM wiki patch that adds a drive strength overlay.

I've tried various U-Boot configuration options that I thought would help, however none have:

Code: Select all

--- git/configs/sama5d27_wlsom1_ek_mmc_defconfig
+++ git.new/configs/sama5d27_wlsom1_ek_mmc_defconfig
@@ -65,6 +65,15 @@
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ATMEL=y
+#CONFIG_MMC_IO_VOLTAGE=y
+#CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_AT91_GPIO=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+#CONFIG_MMC_HS200_SUPPORT=y
+#CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_MMC_VERBOSE=y
+#CONFIG_DM_MMC=y
+MMC_SUPPORTS_TUNING=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SF_DEFAULT_BUS=2


How can I increase the drive strength for U-Boot so that the eMMC works consistently like AT91Boostrap? Thank you.
blue_z
Location: USA
Posts: 2154
Joined: Thu Apr 19, 2007 10:15 pm

Re: How to Properly increase MMC Drive Strength with U-Boot for eMMC on SAMA5D27 WLSOM1

Tue Dec 22, 2020 1:59 am

philbot999 wrote: I believe I need to increase the drive strength for U-Boot, however I have tried multiple ways to do it, and none of them allow Linux to be loaded from the eMMC successfully.

Code: Select all

--- git/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
+++ git.new/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
@@ -95,13 +95,16 @@
 #ifdef CONFIG_SD_BOOT
 void spl_mmc_init(void)
 {
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, 0);	/* CMD */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, 0);	/* DAT0 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, 0);	/* DAT1 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, 0);	/* DAT2 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, 0);	/* DAT3 */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, 0);	/* CK */
-	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 13, 0);	/* CD */
+
+	// Boost Drive Strength for eMMC boots
+	printf("Changing Drive Strength Now!\n");
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, ATMEL_PIO_DRVSTR_HI);	/* CMD */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, ATMEL_PIO_DRVSTR_HI);	/* DAT0 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, ATMEL_PIO_DRVSTR_HI);	/* DAT1 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, ATMEL_PIO_DRVSTR_HI);	/* DAT2 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, ATMEL_PIO_DRVSTR_HI);	/* DAT3 */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, ATMEL_PIO_DRVSTR_HI);	/* CK */
+	atmel_pio4_set_a_periph(AT91_PIO_PORTA, 13, ATMEL_PIO_DRVSTR_HI);	/* CD */
 
 	at91_periph_clk_enable(ATMEL_ID_SDMMC0);
 }
That patch would have no effect because you overlooked the more-encompassing conditional-compilation directive surrounding that block of code.
That is

Code: Select all

/* SPL */
#ifdef CONFIG_SPL_BUILD
  ...  
#endif
inhibited the generation of any of that modified code.

If you had checked the console output for the printf() you inserted, then the absence of your message should have been a red flag and an indication that your patch was ineffective and not executed.


philbot999 wrote:

Code: Select all

--- git/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts
+++ git.new/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts
@@ -120,7 +120,10 @@
 							 <PIN_PA3__SDMMC0_DAT1>,
 							 <PIN_PA4__SDMMC0_DAT2>,
 							 <PIN_PA5__SDMMC0_DAT3>;
-						bias-disable;
+						/* Increase drive strength for DDR modes */
+						atmel,drive-strength = <3>;
+						/* eMMC is missing pull-ups */
+						bias-pull-up;
 					};
 
 					pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default {
@@ -128,7 +131,10 @@
 							 <PIN_PA11__SDMMC0_VDDSEL>,
 							 <PIN_PA12__SDMMC0_WP>,
 							 <PIN_PA13__SDMMC0_CD>;
-						bias-disable;
+						/* Increase drive strength for DDR modes */
+						atmel,drive-strength = <3>;
+						/* eMMC is missing pull-ups */
+						bias-pull-up;
 					};
 
 					pinctrl_uart0_default: uart0_default {
Your use of a magic number for the drive-strength parameter is problematic, despite the kernel DT bindings documentation.
Every example and specification of the drive-strength property (that I've seen) uses a mnemonic such as ATMEL_PIO_DRVSTR_ME or ATMEL_PIO_DRVSTR_HI, because it is just a scaler in the Linux kernel but in U-Boot is a shifted scaler.


philbot999 wrote: I also tried the Linux4SAM wiki patch that adds a drive strength overlay.
...
How can I increase the drive strength for U-Boot so that the eMMC works consistently like AT91Boostrap?
Despite the existence of Eugen Hristev's patch, I see no processing in the pinctrl-at91-pio4.c version of atmel_pinctrl_get_pinconf() for drive strength!
There is a printf() to report an unsupported pinctrl property, but whether this message actually appears in the boot log is unknown due to your ambiguous reporting of results.

Your reporting of results is ambiguous. You only provide summations, and the boot logs do not detail which modification(s) is/are being tested.

Learn to use the built-in debugging capabilities of U-Boot.
You can examine the actual PIO registers of the SAMA5D2 SoC to determine if the drive strength has been configured as expected.
You could even manually configure the drive strength of those six pins to test if that actually resolves the access issues.

Regards

Return to “SAMA5D Cortex-A5 MPU”

Who is online

Users browsing this forum: No registered users and 3 guests