Skip to main content
Graduate
January 10, 2024
Question

Major issue with eMMC 8 bit

  • January 10, 2024
  • 2 replies
  • 4757 views

We are currently experiencing a major issue with eMMC on our custom boards using STM32MP153CAC. Our boards are booting normally with 1 wire mode, but as soon as 8 wire/bit mode is enabled, it starts to bug out.

Here is the description of the problem from our linux developer:


- Starts up on 8 bit bus width, but
- Does not stay at 8 bit bus width
- And after it falls back to 4 bit, it tries to switch back to 8 bit, but fails
- The clock seems to "only" be 27 MHz, and not 52 MHz
- The actual read and write speed is lower then it should be, 8 bit DDR52 should be around 50 MByte/s read and 30 MByte/s write
but it looks to be more around 2-3 MBytes/s
- Read and write bigger file seems to prevoke the from 8 bit to 4 bit
- If configured to start at 4 bit DDR52, fallback 4 bit mmc high-speed (not DDR)

Here is information about the PCB:
- 8 layer
- We only use 3.3V for the emmc, on both power domains

- Here is how the emmc is connected
emmc_circuit.PNG
Here is information on clock set up in TF-A:

&etzpc{
	secure-status = "okay";
	st,decprot = <
	/*"NS_R S_W" peripherals*/
	DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK)
	DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK)
	/*"Non Secured" peripherals*/
	DECPROT(STM32MP1_ETZPC_ADC_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_TT_FDCAN_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_ETH_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_FMC_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_SPI1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_SPI2_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_DMA1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_DMAMUX_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_FMC_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_SPI1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_SPI2_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_UART4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_UART5_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_UART7_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_USART2_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_USART3_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_USART6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	DECPROT(STM32MP1_ETZPC_TIM1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
	/*"Secured" peripherals*/
	DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_UNLOCK)
	/*"Mcu Isolation" peripherals*/
	DECPROT(STM32MP1_ETZPC_DMA2_ID, DECPROT_MCU_ISOLATION, DECPROT_UNLOCK)

	/*Restriction: following IDs are not managed - please to use User-Section if needed:
		 STM32MP1_ETZPC_SRAMx_ID STM32MP1_ETZPC_RETRAM_ID STM32MP1_ETZPC_BKPSRAM_ID*/

	/* USER CODE BEGIN etzpc_decprot */
		/*STM32CubeMX generates a basic and standard configuration for ETZPC.
		Additional device configurations can be added here if needed.
		"etzpc" node could be also overloaded in "addons" User-Section.*/
	/* USER CODE END etzpc_decprot */
	>;

	/* USER CODE BEGIN etzpc */
	/* USER CODE END etzpc */
};

&rcc{
	status = "okay";
	secure-status = "disabled";
	st,csi-cal;
	st,hsi-cal;
	st,cal-sec = <60>;
	st,clksrc=<
		CLK_MPU_PLL1P
		CLK_AXI_PLL2P
		CLK_MCU_HSI
		CLK_PLL12_HSE
		CLK_PLL3_HSE
		CLK_PLL4_HSE
		CLK_RTC_LSI
		CLK_MCO1_DISABLED
		CLK_MCO2_DISABLED
	>;
	st,clkdiv = <
		1 		/*MPU*/
		3 		/*AXI*/
		0 		/*MCU*/
		0 		/*APB1*/
		0 		/*APB2*/
		0 		/*APB3*/
		0 		/*APB4*/
		0 		/*APB5*/
		0 		/*RTC*/
		0 		/*MCO1*/
		0 		/*MCO2*/
	>;
	st,pkcs = <
		CLK_CKPER_DISABLED
		CLK_FMC_ACLK
		CLK_ETH_PLL4P
		CLK_SDMMC12_PLL4P
		CLK_STGEN_HSE
		CLK_USBPHY_PLL4R
		CLK_SPI2S1_PLL4P
		CLK_SPI2S23_PLL4P
		CLK_SPI45_DISABLED
		CLK_SPI6_DISABLED
		CLK_I2C46_PCLK5
		CLK_SDMMC3_DISABLED
		CLK_ADC_PLL4R
		CLK_CEC_DISABLED
		CLK_I2C12_DISABLED
		CLK_I2C35_DISABLED
		CLK_UART1_HSE
		CLK_UART24_HSE
		CLK_UART35_HSE
		CLK_UART6_HSE
		CLK_UART78_HSE
		CLK_SPDIF_DISABLED
		CLK_SAI1_DISABLED
		CLK_SAI2_DISABLED
		CLK_SAI3_DISABLED
		CLK_SAI4_DISABLED
		CLK_LPTIM1_DISABLED
		CLK_LPTIM23_DISABLED
		CLK_LPTIM45_DISABLED
		CLK_FDCAN_HSE
	>;
	pll2:st,pll@1 {
		compatible = "st,stm32mp1-pll";
		reg = <1>;
		cfg = < 0 35 1 1 1 PQR(1,0,1) >;
	};
	pll3:st,pll@2 {
		compatible = "st,stm32mp1-pll";
		reg = <2>;
		cfg = < 2 124 1 3 1 PQR(0,1,0) >;
	};
	pll4:st,pll@3 {
		compatible = "st,stm32mp1-pll";
		reg = <3>;
		cfg = < 0 35 3 4 17 PQR(1,1,0) >;
	};

	/* USER CODE BEGIN rcc */
	/* USER CODE END rcc */
};

Here is the initial configuration of the eMMC using u-boot:

enable_emmc_boot_partition=echo "Setting emmc device and boot partitions"; mmc dev "${emmc_device}"; mmc partconf 1 1 1 1;



Here is our device tree configuration of the eMMC with linux:

&sdmmc2{
	pinctrl-names = "default", "opendrain", "sleep";
	pinctrl-0 = <&sdmmc2_pins_mx>;
	pinctrl-1 = <&sdmmc2_opendrain_pins_mx>;
	pinctrl-2 = <&sdmmc2_sleep_pins_mx>;
	bus-width = <8>;
	non-removable;
	no-sd;
	no-sdio;
	no-1-8-v;
	st,neg-edge;
	mmc-ddr-3_3v;
	vmmc-supply = <&reg_3v3>;
	vqmmc-supply = <&reg_3v3>;
	status = "okay";
};


Linux kernel version: 5.10.61 med STM patch stm32mp1-5.10.61-r2

    This topic has been closed for replies.

    2 replies

    Graduate II
    January 10, 2024

    No series resistors? Usually designs have 27R or 33R to stop ringing. Traces also need matched lengths.

    DDR implies data on both clock edges. DDR104 would have 52 MHz clock, not 104 MHz, although clock within peripheral will likely be higher internally.

    Throughput on eMMC dictated by device, different brands have different performance.

    JOhn1Author
    Graduate
    January 10, 2024

    Only series resistor on EMMC_CLK line. (See attached photo below)
    emmc_mpu_circuit.png

    We read this out from our kernel:

    clock:		52000000 Hz
    actual clock:	27000000 Hz
    vdd:		21 (3.3 ~ 3.4 V)
    bus mode:	2 (push-pull)
    chip select:	0 (don't care)
    power mode:	2 (on)
    bus width:	3 (8 bits)
    timing spec:	8 (mmc DDR52)
    signal voltage:	0 (3.30 V)
    driver type:	0 (driver type B)

    And after running multiple threads it falls back to:

    cat /sys/kernel/debug/mmc1/ios 2000-01-01 01:04:39
    
    clock:		52000000 Hz
    actual clock:	27000000 Hz
    vdd:		21 (3.3 ~ 3.4 V)
    bus mode:	2 (push-pull)
    chip select:	0 (don't care)
    power mode:	2 (on)
    bus width:	2 (4 bits)
    timing spec:	8 (mmc DDR52)
    signal voltage:	0 (3.30 V)
    driver type:	0 (driver type B)
    Graduate II
    January 10, 2024

    Failure suggests you have a signal integrity issue, and perhaps skewing of different data lines vs clock.

    Would look critically at path lengths and drive strength settings. On the MCU series SPEEDR can be reduced on short trace, low load pin paths.

    Technical Moderator
    January 10, 2024

    Hi @JOhn1 ,

    27 MHz whereas 52MHz requested might depend on which combination the driver has found be not be above the 52MHz. Could you please share clock summary.

    cat /sys/kernel/debug/clk/clk_summary

    I think the issue of 8-bit to 4-bit is not linked to 27MHz clocking.

     

    Did you have checked signal/power integrity on your board ?

    Is the serie resistor on SDMMC2_CLK close to signal source ?

    Is the eMMC far away from STM32MP15x ?

    Did you enable more log from related Linux driver to see if there is details/explanation of the fallback from 8-bits to 4-bits ?

    Could you share the eMMC reference you are using ? Did you tried another brand ?

    For read and write performances, it depend on the memory itself, the driver efficiency as well as processor load.

     

    Regards.

    JOhn1Author
    Graduate
    January 10, 2024

    @PatrickF wrote:

    Hi @JOhn1 ,

    27 MHz whereas 52MHz requested might depend on which combination the driver has found be not be above the 52MHz. Could you please share clock summary.

     

    cat /sys/kernel/debug/clk/clk_summary

     


    Clock Summary output is attached.


    @PatrickF wrote:

    Did you have checked signal/power integrity on your board ?


    We are measuring D0 and CLK to see if any ringing or distortion is present on the signal. Currently we are running into issues with out probes not being capable to measure at those frequencies. Our latest measurements indicate good signal integrity, I will post a screenshot from the oscilloscope tomorrow.


    @PatrickF wrote:

    Is the serie resistor on SDMMC2_CLK close to signal source ?


    Yes, according to our EDA tool, 3.75 mm from pad to pad. The series resistor is on same layer as IC, so getting it any closer would require us to move it to the opposite side.


    @PatrickF wrote:

    Is the eMMC far away from STM32MP15x ?


    Each trace is matched withing 10 mil (0,254 mm) and each trace is 27,7 mm long (CLK, CMD D0-D7).


    @PatrickF wrote:

    Did you enable more log from related Linux driver to see if there is details/explanation of the fallback from 8-bits to 4-bits ?

    Not sure what options are available.


    @PatrickF wrote:

    Could you share the eMMC reference you are using ? Did you tried another brand ?

    The layout is according to the the reference design in AN5031 rev4.
    It is our first design using eMMC, as we have many tens of thousands products using raw NAND flash, which also since transitioning to STM32mp153 have worked well. The particular emmc used is ASFC4G31M-51BIN from Alliance.









    Technical Moderator
    January 10, 2024

    Hi,

    I see HSE at 12MHz whereas it should be 24MHz. did you really use 12MHz and define it like that in DT ?

    I see also your AXI is running at 54MHz (instead of up to 266MHz) and the DDR (PLL2) at 216MHz (instead of up to 533MHz). This would explain some issues (performance and stability).

    You likely need to check and revise your overall clocking definitions of your platform.

    Please have a look to

    https://wiki.st.com/stm32mpu/wiki/STM32MP15_clock_tree

    (or https://wiki.st.com/stm32mpu-ecosystem-v4/wiki/STM32MP15_clock_tree if you are still on ecosystem V4.x)

    Regards.