This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM625: eMMC tuning algorithm for HS200

Part Number: AM625

Hello TI

I have question about the eMMC tuning algorithm for HS200 mode in file “/drivers/mmc/am654_sdhci.c”. This functionality exists both in Linux and in u-boot.

The function is “static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)”

The algorithm in the function follows the SW Tuning Algorithm chapter 3 in MMC SW Tuning Algorithm (ti.com).

For our HW the tuning algorithm mostly works. We usually have a failing window with length of 1 starting at 16, 17 or 18. Sometimes we can have a failing window of 2. With these values the passing window will be 30 or 31 and the itap is set to 0, 1 or 31 (far away from failing window) depending on the different values. This works.

BUT!!

The problem occurs when all 32 tuning test passes. We then have a failing window of 0. The algorithm than calculates itap of 16, which is in the failing window. When this happens, we have a unit that hangs, eMMC in not working.

We have units that sometimes have a falling window of 1 and next start has failing window 0.

 

I guess the algorithm isn’t written for this scenario. How should we handle this?

 

Best regards

Magnus

  • Hi Magnus,

     Let me discuss this with our software developer and get back to you.

  • Magnus,

    How repeatable are the results for a given device? To make sure I understand correctly, you are saying on some devices you do not have any failures during the tuning sequence and the end result is an ITAP set to the middle of the entire window (~16) which ultimately does fail outside of the tuning operation?

    Thanks,

    Chris

  • Hello,

    That is what happens.

    We have units that sometimes have 1 failure during the tuning sequence about 15, 16 something. The algorithm calculates an ITAP of 0 or 31. The next start up it could have 0 failure and the algorithm calculates ITAP 16, which is in the middle of our failure window, which isn’t good

    This is repeatable and easy to reproduce.

    We have solved it by patching the algorithm. If no failure, we just set ITAP to 0 at the moment.

    I guess the algorithm isn’t written for this scenario. How should we handle this?

  • Magnus, 

    It sounds more like the algorithm is not failing when you think it should, i.e. you are getting a false positive in the middle of the ITAP values.

    Just to confirm you are running in HS200 mode? Can you confirm the other MMC CTRL parameters are appropriately set to match table 7-77 in the datasheet?

    Thanks,

    Chris 

  • Hello,

    Yes, we running HS200 mode and using correct value from the table.

    We using the values in the file k3-am62-main.dtsi

    	sdhci0: mmc@fa10000 {
    		compatible = "ti,am62-sdhci";
    		reg = <0x00 0xfa10000 0x00 0x260>, <0x00 0xfa18000 0x00 0x134>;
    		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
    		clock-names = "clk_ahb", "clk_xin";
    		assigned-clocks = <&k3_clks 57 6>;
    		assigned-clock-parents = <&k3_clks 57 8>;
    		mmc-ddr-1_8v;
    		mmc-hs200-1_8v;
    		ti,trm-icp = <0x2>;
    		bus-width = <8>;
    		ti,clkbuf-sel = <0x7>;
    		ti,otap-del-sel-legacy = <0x0>;
    		ti,otap-del-sel-mmc-hs = <0x0>;
    		ti,otap-del-sel-ddr52 = <0x5>;
    		ti,otap-del-sel-hs200 = <0x5>;
    		ti,itap-del-sel-legacy = <0xa>;
    		ti,itap-del-sel-mmc-hs = <0x1>;
    	}

    But even if we change "ti,otap-del-sel-hs200" to 0x6, it's the same...

    Should it be 0x5 or 0x6? This file is provided by TI and coming for LINUX SDK

    PS.

    Our HW developers has joked about that the HW is so good, so we dont get any fails : )

    /Regards

    Magnus

  • Magnus,

    I do not expect the OTAP being set to 0x5 instead of 0x6 to have any impact. Yes, it would be nice if we could explain this one away with a very robust hardware design Slight smile

    The goal now should be to understand why no failing band is being detected consistently. Do you have an output log of the tuning you can share? I am working to try and identify device registers that we can check in order to confirm that tuning is actually completing successfully.

    Thanks,

    Chris

  • Hello,

    I have added some printout in file am654_sdhci.c in u-boot.

    The algorithm runs 3 times:

    First in R5 SBL, then in A53 SPL and finally in u-boot.

    In this start:

    R5 SBL tuning have 1 fail window at itap 16. Algorithm sets itap to 0 ,

    A53 SBL tuning have 0 fails. Algorithm sets itap to 16, but our patch sets it 0. See "if(pass_len == ITAP_MAX)" in code.

    U-boot tuning have 1 fail window at itap 15. Algorithm sets itap to 31

    Without our patch this units hangs in A53 SBL.

    Console print out:

    U-Boot SPL 2021.01-00031-g46a7712e22-dirty (Mar 09 2023 - 08:53:31 +0100)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.4.7--v08.04.07 (Jolly Jellyfi')
    Trying to boot from MMC1
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find 
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    
    am654_sdhci_execute_tuning
    itap=0, cur_val=1 fail_len=0 pass_window=0
    itap=1, cur_val=1 fail_len=0 pass_window=0
    itap=2, cur_val=1 fail_len=0 pass_window=0
    itap=3, cur_val=1 fail_len=0 pass_window=0
    itap=4, cur_val=1 fail_len=0 pass_window=0
    itap=5, cur_val=1 fail_len=0 pass_window=0
    itap=6, cur_val=1 fail_len=0 pass_window=0
    itap=7, cur_val=1 fail_len=0 pass_window=0
    itap=8, cur_val=1 fail_len=0 pass_window=0
    itap=9, cur_val=1 fail_len=0 pass_window=0
    itap=10, cur_val=1 fail_len=0 pass_window=0
    itap=11, cur_val=1 fail_len=0 pass_window=0
    itap=12, cur_val=1 fail_len=0 pass_window=0
    itap=13, cur_val=1 fail_len=0 pass_window=0
    itap=14, cur_val=1 fail_len=0 pass_window=0
    itap=15, cur_val=1 fail_len=0 pass_window=0
    itap=16, cur_val=0 fail_len=1 pass_window=0
    itap=17, cur_val=1 fail_len=1 pass_window=17
    itap=18, cur_val=1 fail_len=1 pass_window=17
    itap=19, cur_val=1 fail_len=1 pass_window=17
    itap=20, cur_val=1 fail_len=1 pass_window=17
    itap=21, cur_val=1 fail_len=1 pass_window=17
    itap=22, cur_val=1 fail_len=1 pass_window=17
    itap=23, cur_val=1 fail_len=1 pass_window=17
    itap=24, cur_val=1 fail_len=1 pass_window=17
    itap=25, cur_val=1 fail_len=1 pass_window=17
    itap=26, cur_val=1 fail_len=1 pass_window=17
    itap=27, cur_val=1 fail_len=1 pass_window=17
    itap=28, cur_val=1 fail_len=1 pass_window=17
    itap=29, cur_val=1 fail_len=1 pass_window=17
    itap=30, cur_val=1 fail_len=1 pass_window=17
    itap=31, cur_val=1 fail_len=1 pass_window=17
    MMC tuning itap=0, pass_window=17, pass_len=31 fail_len=1 
    Starting ATF on ARM64 core...
    
    NOTICE:  BL31: v2.7(release):v2.7.0-dirty
    NOTICE:  BL31: Built : 16:41:25, Sep 27 2022
    
    U-Boot SPL 2021.01-00031-g46a7712e22-dirty (Mar 09 2023 - 08:53:17 +0100)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.4.7--v08.04.07 (Jolly Jellyfi')
    Trying to boot from MMC1
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find 
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    
    am654_sdhci_execute_tuning
    itap=0, cur_val=1 fail_len=0 pass_window=0
    itap=1, cur_val=1 fail_len=0 pass_window=0
    itap=2, cur_val=1 fail_len=0 pass_window=0
    itap=3, cur_val=1 fail_len=0 pass_window=0
    itap=4, cur_val=1 fail_len=0 pass_window=0
    itap=5, cur_val=1 fail_len=0 pass_window=0
    itap=6, cur_val=1 fail_len=0 pass_window=0
    itap=7, cur_val=1 fail_len=0 pass_window=0
    itap=8, cur_val=1 fail_len=0 pass_window=0
    itap=9, cur_val=1 fail_len=0 pass_window=0
    itap=10, cur_val=1 fail_len=0 pass_window=0
    itap=11, cur_val=1 fail_len=0 pass_window=0
    itap=12, cur_val=1 fail_len=0 pass_window=0
    itap=13, cur_val=1 fail_len=0 pass_window=0
    itap=14, cur_val=1 fail_len=0 pass_window=0
    itap=15, cur_val=1 fail_len=0 pass_window=0
    itap=16, cur_val=1 fail_len=0 pass_window=0
    itap=17, cur_val=1 fail_len=0 pass_window=0
    itap=18, cur_val=1 fail_len=0 pass_window=0
    itap=19, cur_val=1 fail_len=0 pass_window=0
    itap=20, cur_val=1 fail_len=0 pass_window=0
    itap=21, cur_val=1 fail_len=0 pass_window=0
    itap=22, cur_val=1 fail_len=0 pass_window=0
    itap=23, cur_val=1 fail_len=0 pass_window=0
    itap=24, cur_val=1 fail_len=0 pass_window=0
    itap=25, cur_val=1 fail_len=0 pass_window=0
    itap=26, cur_val=1 fail_len=0 pass_window=0
    itap=27, cur_val=1 fail_len=0 pass_window=0
    itap=28, cur_val=1 fail_len=0 pass_window=0
    itap=29, cur_val=1 fail_len=0 pass_window=0
    itap=30, cur_val=1 fail_len=0 pass_window=0
    itap=31, cur_val=1 fail_len=0 pass_window=0
    MMC tuning itap=0, pass_window=0, pass_len=32 fail_len=0 
    
    
    U-Boot 2021.01-00031-g46a7712e22-dirty (Mar 09 2023 - 08:53:17 +0100)
    
    SoC:   AM62X SR1.0 GP
    Model: Parker Hannifin AM625 IQAN-MD5
    DRAM:  512 MiB
    MMC:   am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find <NULL>
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    mmc@fa10000: 0
    Loading Environment from MMC... 
    am654_sdhci_execute_tuning
    itap=0, cur_val=1 fail_len=0 pass_window=0
    itap=1, cur_val=1 fail_len=0 pass_window=0
    itap=2, cur_val=1 fail_len=0 pass_window=0
    itap=3, cur_val=1 fail_len=0 pass_window=0
    itap=4, cur_val=1 fail_len=0 pass_window=0
    itap=5, cur_val=1 fail_len=0 pass_window=0
    itap=6, cur_val=1 fail_len=0 pass_window=0
    itap=7, cur_val=1 fail_len=0 pass_window=0
    itap=8, cur_val=1 fail_len=0 pass_window=0
    itap=9, cur_val=1 fail_len=0 pass_window=0
    itap=10, cur_val=1 fail_len=0 pass_window=0
    itap=11, cur_val=1 fail_len=0 pass_window=0
    itap=12, cur_val=1 fail_len=0 pass_window=0
    itap=13, cur_val=1 fail_len=0 pass_window=0
    itap=14, cur_val=1 fail_len=0 pass_window=0
    itap=15, cur_val=0 fail_len=1 pass_window=0
    itap=16, cur_val=1 fail_len=1 pass_window=16
    itap=17, cur_val=1 fail_len=1 pass_window=16
    itap=18, cur_val=1 fail_len=1 pass_window=16
    itap=19, cur_val=1 fail_len=1 pass_window=16
    itap=20, cur_val=1 fail_len=1 pass_window=16
    itap=21, cur_val=1 fail_len=1 pass_window=16
    itap=22, cur_val=1 fail_len=1 pass_window=16
    itap=23, cur_val=1 fail_len=1 pass_window=16
    itap=24, cur_val=1 fail_len=1 pass_window=16
    itap=25, cur_val=1 fail_len=1 pass_window=16
    itap=26, cur_val=1 fail_len=1 pass_window=16
    itap=27, cur_val=1 fail_len=1 pass_window=16
    itap=28, cur_val=1 fail_len=1 pass_window=16
    itap=29, cur_val=1 fail_len=1 pass_window=16
    itap=30, cur_val=1 fail_len=1 pass_window=16
    itap=31, cur_val=1 fail_len=1 pass_window=16
    MMC tuning itap=31, pass_window=16, pass_len=31 fail_len=1 
    OK
    In:    serial@2800000
    Out:   serial@2800000
    Err:   serial@2800000
    Net:   eth0: ethernet@8000000port@1
    Hit any key to stop autoboot:  0 
    17000960 bytes read in 151 ms (107.4 MiB/s)
    28695 bytes read in 3 ms (9.1 MiB/s)
    ## Flattened Device Tree blob at 88000000
       Booting using the fdt blob at 0x88000000
       Loading Device Tree to 000000008fef5000, end 000000008fffffff ... OK
    
    Starting kernel ...
    
    

    Function am654_sdhci_execute_tuning, file m654_sdhci.c in u-boot

    #ifdef MMC_SUPPORTS_TUNING
    #define ITAP_MAX	32
    static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
    {
    	struct udevice *dev = mmc->dev;
    	struct am654_sdhci_plat *plat = dev_get_platdata(dev);
    	int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len;
    	u32 itap;
    
    	debug("\n%s\n", __func__);
    
    	/* Enable ITAPDLY */
    	regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK,
    			   1 << ITAPDLYENA_SHIFT);
    
    	for (itap = 0; itap < ITAP_MAX; itap++) {
    		am654_sdhci_write_itapdly(plat, itap);
    
    		cur_val = !mmc_send_tuning(mmc, opcode, NULL);
    		if (cur_val && !prev_val)
    			pass_window = itap;
    
    		if (!cur_val)
    			fail_len++;
    
    		debug("itap=%d, cur_val=%d fail_len=%d pass_window=%d\n", itap, cur_val, fail_len, pass_window);
    
    		prev_val = cur_val;
    	}
    	/*
    	 * Having determined the length of the failing window and start of
    	 * the passing window calculate the length of the passing window and
    	 * set the final value halfway through it considering the range as a
    	 * circular buffer
    	 */
    	pass_len = ITAP_MAX - fail_len;
    	if(pass_len == ITAP_MAX)
    	{
    		itap = 0;
    	}
    	else
    	{
    		itap = (pass_window + (pass_len >> 1)) % ITAP_MAX;
    	}
    	am654_sdhci_write_itapdly(plat, itap);
    
    	debug("MMC tuning itap=%d, pass_window=%d, pass_len=%d fail_len=%d \n", itap, pass_window, pass_len, fail_len);
    
    	return 0;
    }
    

    Regards

    Magnus

  • Magnus,

    Is the behavior of seeing no failures on A53 and seeing one failure on U-Boot/R5 SBL consistent between runs?

    I am curious if we can narrow down the lack of failures to only running on A53 SBL.

    Thanks,

    Chris

  • Hello,

    No, this in not consistent to A53 SPL. After reading your post I did one startup where I had 1 fail in each boot. The second start up had no fail in R5 SPL. See log.

    U-Boot SPL 2021.01-00031-g46a7712e22-dirty (Mar 09 2023 - 08:53:31 +0100)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.4.7--v08.04.07 (Jolly Jellyfi')
    Trying to boot from MMC1
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    
    am654_sdhci_execute_tuning
    itap=0, cur_val=1 fail_len=0 pass_window=0
    itap=1, cur_val=1 fail_len=0 pass_window=0
    itap=2, cur_val=1 fail_len=0 pass_window=0
    itap=3, cur_val=1 fail_len=0 pass_window=0
    itap=4, cur_val=1 fail_len=0 pass_window=0
    itap=5, cur_val=1 fail_len=0 pass_window=0
    itap=6, cur_val=1 fail_len=0 pass_window=0
    itap=7, cur_val=1 fail_len=0 pass_window=0
    itap=8, cur_val=1 fail_len=0 pass_window=0
    itap=9, cur_val=1 fail_len=0 pass_window=0
    itap=10, cur_val=1 fail_len=0 pass_window=0
    itap=11, cur_val=1 fail_len=0 pass_window=0
    itap=12, cur_val=1 fail_len=0 pass_window=0
    itap=13, cur_val=1 fail_len=0 pass_window=0
    itap=14, cur_val=1 fail_len=0 pass_window=0
    itap=15, cur_val=1 fail_len=0 pass_window=0
    itap=16, cur_val=1 fail_len=0 pass_window=0
    itap=17, cur_val=1 fail_len=0 pass_window=0
    itap=18, cur_val=1 fail_len=0 pass_window=0
    itap=19, cur_val=1 fail_len=0 pass_window=0
    itap=20, cur_val=1 fail_len=0 pass_window=0
    itap=21, cur_val=1 fail_len=0 pass_window=0
    itap=22, cur_val=1 fail_len=0 pass_window=0
    itap=23, cur_val=1 fail_len=0 pass_window=0
    itap=24, cur_val=1 fail_len=0 pass_window=0
    itap=25, cur_val=1 fail_len=0 pass_window=0
    itap=26, cur_val=1 fail_len=0 pass_window=0
    itap=27, cur_val=1 fail_len=0 pass_window=0
    itap=28, cur_val=1 fail_len=0 pass_window=0
    itap=29, cur_val=1 fail_len=0 pass_window=0
    itap=30, cur_val=1 fail_len=0 pass_window=0
    itap=31, cur_val=1 fail_len=0 pass_window=0
    MMC tuning itap=0, pass_window=0, pass_len=32 fail_len=0
    Starting ATF on ARM64 core...
    
    NOTICE:  BL31: v2.7(release):v2.7.0-dirty
    NOTICE:  BL31: Built : 16:41:25, Sep 27 2022
    
    U-Boot SPL 2021.01-00031-g46a7712e22-dirty (Mar 09 2023 - 08:53:17 +0100)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.4.7--v08.04.07 (Jolly Jellyfi')
    Trying to boot from MMC1
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    
    am654_sdhci_execute_tuning
    itap=0, cur_val=1 fail_len=0 pass_window=0
    itap=1, cur_val=1 fail_len=0 pass_window=0
    itap=2, cur_val=1 fail_len=0 pass_window=0
    itap=3, cur_val=1 fail_len=0 pass_window=0
    itap=4, cur_val=1 fail_len=0 pass_window=0
    itap=5, cur_val=1 fail_len=0 pass_window=0
    itap=6, cur_val=1 fail_len=0 pass_window=0
    itap=7, cur_val=1 fail_len=0 pass_window=0
    itap=8, cur_val=1 fail_len=0 pass_window=0
    itap=9, cur_val=1 fail_len=0 pass_window=0
    itap=10, cur_val=1 fail_len=0 pass_window=0
    itap=11, cur_val=1 fail_len=0 pass_window=0
    itap=12, cur_val=1 fail_len=0 pass_window=0
    itap=13, cur_val=1 fail_len=0 pass_window=0
    itap=14, cur_val=1 fail_len=0 pass_window=0
    itap=15, cur_val=0 fail_len=1 pass_window=0
    itap=16, cur_val=1 fail_len=1 pass_window=16
    itap=17, cur_val=1 fail_len=1 pass_window=16
    itap=18, cur_val=1 fail_len=1 pass_window=16
    itap=19, cur_val=1 fail_len=1 pass_window=16
    itap=20, cur_val=1 fail_len=1 pass_window=16
    itap=21, cur_val=1 fail_len=1 pass_window=16
    itap=22, cur_val=1 fail_len=1 pass_window=16
    itap=23, cur_val=1 fail_len=1 pass_window=16
    itap=24, cur_val=1 fail_len=1 pass_window=16
    itap=25, cur_val=1 fail_len=1 pass_window=16
    itap=26, cur_val=1 fail_len=1 pass_window=16
    itap=27, cur_val=1 fail_len=1 pass_window=16
    itap=28, cur_val=1 fail_len=1 pass_window=16
    itap=29, cur_val=1 fail_len=1 pass_window=16
    itap=30, cur_val=1 fail_len=1 pass_window=16
    itap=31, cur_val=1 fail_len=1 pass_window=16
    MMC tuning itap=31, pass_window=16, pass_len=31 fail_len=1
    
    
    U-Boot 2021.01-00031-g46a7712e22-dirty (Mar 09 2023 - 08:53:17 +0100)
    
    SoC:   AM62X SR1.0 GP
    Model: Parker Hannifin AM625 IQAN-MD5
    DRAM:  512 MiB
    MMC:   am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find <NULL>
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    mmc@fa10000: 0
    Loading Environment from MMC...
    am654_sdhci_execute_tuning
    itap=0, cur_val=1 fail_len=0 pass_window=0
    itap=1, cur_val=1 fail_len=0 pass_window=0
    itap=2, cur_val=1 fail_len=0 pass_window=0
    itap=3, cur_val=1 fail_len=0 pass_window=0
    itap=4, cur_val=1 fail_len=0 pass_window=0
    itap=5, cur_val=1 fail_len=0 pass_window=0
    itap=6, cur_val=1 fail_len=0 pass_window=0
    itap=7, cur_val=1 fail_len=0 pass_window=0
    itap=8, cur_val=1 fail_len=0 pass_window=0
    itap=9, cur_val=1 fail_len=0 pass_window=0
    itap=10, cur_val=1 fail_len=0 pass_window=0
    itap=11, cur_val=1 fail_len=0 pass_window=0
    itap=12, cur_val=1 fail_len=0 pass_window=0
    itap=13, cur_val=1 fail_len=0 pass_window=0
    itap=14, cur_val=1 fail_len=0 pass_window=0
    itap=15, cur_val=0 fail_len=1 pass_window=0
    itap=16, cur_val=1 fail_len=1 pass_window=16
    itap=17, cur_val=1 fail_len=1 pass_window=16
    itap=18, cur_val=1 fail_len=1 pass_window=16
    itap=19, cur_val=1 fail_len=1 pass_window=16
    itap=20, cur_val=1 fail_len=1 pass_window=16
    itap=21, cur_val=1 fail_len=1 pass_window=16
    itap=22, cur_val=1 fail_len=1 pass_window=16
    itap=23, cur_val=1 fail_len=1 pass_window=16
    itap=24, cur_val=1 fail_len=1 pass_window=16
    itap=25, cur_val=1 fail_len=1 pass_window=16
    itap=26, cur_val=1 fail_len=1 pass_window=16
    itap=27, cur_val=1 fail_len=1 pass_window=16
    itap=28, cur_val=1 fail_len=1 pass_window=16
    itap=29, cur_val=1 fail_len=1 pass_window=16
    itap=30, cur_val=1 fail_len=1 pass_window=16
    itap=31, cur_val=1 fail_len=1 pass_window=16
    MMC tuning itap=31, pass_window=16, pass_len=31 fail_len=1
    OK
    In:    serial@2800000
    Out:   serial@2800000
    Err:   serial@2800000
    Net:   eth0: ethernet@8000000port@1
    Hit any key to stop autoboot:  0
    17000960 bytes read in 150 ms (108.1 MiB/s)
    28695 bytes read in 3 ms (9.1 MiB/s)
    ## Flattened Device Tree blob at 88000000
       Booting using the fdt blob at 0x88000000
       Loading Device Tree to 000000008fef5000, end 000000008fffffff ... OK
    
    Starting kernel ...

    /Magnus

  • Magnus, 

    Is it possible for you to monitor two registers while running tuning? You can refer to table 12-2879 in the TRM. 

    MMCSD0_CONTROL2:SAMPLING_CLK_SELECT

    MMCSD0_PRESENTSTATE:RETUNING_REQ

    The sampling_clk_select bit should indicate that we are succesfully tuned and the retuning_req bit should indicate if retuning is required due to poor margin. If this can be checked between each tuning step it would help reveal if there are any marginal tuning passes. 

    Thanks,

    Chris 

  • Hello again

    I am not sure I have done exactly what you wanted.

    I have added reading of the register you wanted, but I am not sure if is the right place to read them or the return values are correct.

    If you want me to read the register somewhere else just tell me.

    static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
    {
    	struct udevice *dev = mmc->dev;
    	struct am654_sdhci_plat *plat = dev_get_platdata(dev);
    	int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len;
    	u32 itap;
    	u32 reg;
    
    	debug("\n%s %x\n", __func__);
    
    	// Just checking in_le32 function
    	regmap_read(plat->base, PHY_CTRL4, &reg);
    	debug("PHY_CTRL4 %x\n", reg);
    	reg = in_le32(0xfa18000 + PHY_CTRL4);
    	debug("PHY_CTRL4 %x %x\n", 0xfa18000 + PHY_CTRL4, reg);
    
    	/* Enable ITAPDLY */
    	regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK,
    			   1 << ITAPDLYENA_SHIFT);
    
    	for (itap = 0; itap < ITAP_MAX; itap++) {
    		am654_sdhci_write_itapdly(plat, itap);
    
    		cur_val = !mmc_send_tuning(mmc, opcode, NULL);
    		if (cur_val && !prev_val)
    			pass_window = itap;
    
    		if (!cur_val)
    			fail_len++;
    		reg = in_le32(0xfa10024);
    		debug("presentstate %08x %08x\n", 0xfa10024, reg);
    		reg = in_le16(0xfa1003e);
    		debug("control2     %08x     %04x\n", 0xfa1003e, reg);
    
    		debug("itap=%d, cur_val=%d fail_len=%d pass_window=%d\n", itap, cur_val, fail_len, pass_window);
    
    		prev_val = cur_val;
    	}
    	/*
    	 * Having determined the length of the failing window and start of
    	 * the passing window calculate the length of the passing window and
    	 * set the final value halfway through it considering the range as a
    	 * circular buffer
    	 */
    	pass_len = ITAP_MAX - fail_len;
    	if(pass_len == ITAP_MAX)
    	{
    		itap = 0;
    	}
    	else
    	{
    		itap = (pass_window + (pass_len >> 1)) % ITAP_MAX;
    	}
    	am654_sdhci_write_itapdly(plat, itap);
    
    	debug("MMC tuning itap=%d, pass_window=%d, pass_len=%d fail_len=%d \n", itap, pass_window, pass_len, fail_len);
    
    	return 0;
    }
    

    U-Boot SPL 2021.01-00031-g46a7712e22-dirty (Mar 17 2023 - 10:12:07 +0100)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.4.7--v08.04.07 (Jolly Jellyfi')
    Trying to boot from MMC1
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find 
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    
    am654_sdhci_execute_tuning 110
    PHY_CTRL4 105100
    PHY_CTRL4 fa1810c 105100
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=0, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=1, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=2, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=3, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=4, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=5, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=6, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=7, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=8, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=9, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=10, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=11, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=12, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=13, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=14, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=15, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=16, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=17, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=18, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=19, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=20, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=21, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=22, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=23, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=24, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=25, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=26, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=27, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=28, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=29, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=30, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=31, cur_val=1 fail_len=0 pass_window=0
    MMC tuning itap=0, pass_window=0, pass_len=32 fail_len=0 
    Starting ATF on ARM64 core...
    
    NOTICE:  BL31: v2.7(release):v2.7.0-dirty
    NOTICE:  BL31: Built : 16:41:25, Sep 27 2022
    
    U-Boot SPL 2021.01-00031-g46a7712e22-dirty (Mar 17 2023 - 10:11:50 +0100)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.4.7--v08.04.07 (Jolly Jellyfi')
    Trying to boot from MMC1
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find 
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    
    am654_sdhci_execute_tuning 80093ec0
    PHY_CTRL4 105100
    PHY_CTRL4 fa1810c 105100
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=0, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=1, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=2, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=3, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=4, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=5, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=6, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=7, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=8, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=9, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=10, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=11, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=12, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=13, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=14, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=15, cur_val=0 fail_len=1 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=16, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=17, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=18, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=19, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=20, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=21, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=22, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=23, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=24, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=25, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=26, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=27, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=28, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=29, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=30, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=31, cur_val=1 fail_len=1 pass_window=16
    MMC tuning itap=31, pass_window=16, pass_len=31 fail_len=1 
    
    
    U-Boot 2021.01-00031-g46a7712e22-dirty (Mar 17 2023 - 10:11:50 +0100)
    
    SoC:   AM62X SR1.0 GP
    Model: Parker Hannifin AM625 IQAN-MD5
    DRAM:  512 MiB
    MMC:   am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sd-hs
    am654_sdhci mmc@fa10000: Couldn't find <NULL>
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr12
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr25
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-ddr50
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-sdr104
    am654_sdhci mmc@fa10000: Couldn't find ti,otap-del-sel-hs400
    mmc@fa10000: 0
    Loading Environment from MMC... 
    am654_sdhci_execute_tuning 9ff7e688
    PHY_CTRL4 105100
    PHY_CTRL4 fa1810c 105100
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=0, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=1, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=2, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=3, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=4, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=5, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=6, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=7, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=8, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=9, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=10, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=11, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=12, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=13, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=14, cur_val=1 fail_len=0 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=15, cur_val=0 fail_len=1 pass_window=0
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=16, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=17, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=18, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=19, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=20, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=21, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=22, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=23, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=24, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=25, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=26, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=27, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=28, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=29, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=30, cur_val=1 fail_len=1 pass_window=16
    presentstate 0fa10024 01ff00f0
    control2     0fa1003e     0003
    itap=31, cur_val=1 fail_len=1 pass_window=16
    MMC tuning itap=31, pass_window=16, pass_len=31 fail_len=1 
    OK
    In:    serial@2800000
    Out:   serial@2800000
    Err:   serial@2800000
    Net:   eth0: ethernet@8000000port@1
    Hit any key to stop autoboot:  2 
    

    Regards

    Magnus

  • Magnus,

    Apologies on the delayed response, I am returning from being out of office. I have reviewed the data and it appears to be collected correctly and does not reveal any anomalies. Let me discuss internally to try and come up with next steps and I will follow up.

    Thanks,

    Chris

  • Can you confirm what SDK version you are using as a baseline? Also, can you try and modify the OTAP to 0x6 as indicated in the datasheet and rerun?

    I would imagine this would only improve timing and since this is a false positive I am not sure it will have an impact, but it is worth ensuring we conform to the datasheet timing value.

    For background, we have run characterization using this tuning algorithm across PVT and have not seen a similar false pass so it is challenging to debug and may be system related. I am looking for ways to isolate SW vs HW.

    Thanks,

    Chris

  • We are using Linux SDK 08.04.01.03.

    I have tested with OTAP 0x6 and with SDK 08.06.00.42. I don’t see any difference.

    /Magnus

  • Magnus, 

    Thank you for attempting this. 

    The tuning algorithm, when run, is going to write a known 128MB pattern to the flash and then read the pattern back and check for success. Because you are seeing sporadic pass/fail and we are not able to replicate on our platform I am assuming your failures are extremely marginal at those ITAP values and it is able to occasionally pass this quick test, but not robust enough to function outside of tuning. The fact that you do see failures occasionally leads me to believe that there is not a software implementation that is leading to always incorrectly recording a pass.

    One other curiosity, how frequently to you see a result where all ITAP delays are passing and are they back to back? Because we are trying to accommodate for any change in process, voltage, or temperature by running this tuning algorithm I am not sure how reliable it is to assume that a tuning result with failing window should be hard coded to an ITAP of 0. 

    I would propose a couple of options:

    • After tuning, check if there was no failing window and, if so, retune.
    • After tuning, run an expanded stress test (beyond 128MB write/read) and if this fails, retune and log that ITAP as invalid. 

    The first would be potentially faster, but if there are many back to back incidences where you do not detect a fail it could cause a long delay in tuning. 

    Let me know your thoughts or if there are any other clarifications needed.

    Thanks,

    Chris 

  • Hello again,

    How frequently to you see a result where all ITAP delays are passing and are they back to back?

    We have 1 unit out of 20 that we see this problem on that all ITAP is passing in the Tuning sequence. This is in room temperature.

    It doesn’t happen every startup, so it is not back to back if that is what you mean. It could happen in R5 SPL one startup. In A53 SPL a second.

    We also think that we have other units that have this problem at high temperature (Starting up in 70degree). It is not proven from my side that it is that, but with the Tuning patch (setting ITAP to 0 if all pass) we don’t see any issue with starting up in 70 degrees.

    Maybe this isn’t a problem. Could it be that our HW have a very good design for eMMC?

    Do you have any idee how common is it that failing window in the tuning algorithm is just one ITAP? I guess if the window would be 2 or 3 and 1 fail sometimes pass it would make no difference since there always will be at least on fail.

    How is your failing window your AM62? How many fails do you have?

    Is it a must to Tune or just a recommendation? Maybe we could turn it off and set a ITAP value our self.

     

    Good proposal!

    I think that we should retune instead of setting 0 as ITAP, that is probably the safest solution.

     

    Regards

    Magnus

  • Magnus, 

    Sorry I misrepresented the tuning algorithm in my previous post. A 128MB pattern was used as part of the internal characterization to run a more strenuous case to confirm the tuning results. We did have some instances where this more stressful tuning pattern demonstrated failing ITAP values that did not fail when running the default tuning. The number of failing ITAPs varied depending on unit, voltage, temp, etc but typically it was at least two. 

    Tuning is going to simply write and read back a small, known pattern so it is possible that this is able to pass on your board marginally for all ITAPs but this is not something we have seen before. This will be a relationship of the AM62 device, the board design, and the flash memory being used so it is very difficult to try and determine what could be the cause of this via a forum. If you wanted to run some experimentation, you could potentially force the ITAP to be the presumed failing value of 16 and run some basic read/write tests. Based on the details you have posted I assume this will fail, but if some of the reads/writes are valid then it is possible that the small check during the tuning procedure is missing fails. 

    It is not required to tune, however since this is a high speed interface it is always recommended as this can account for changing variables boot to boot. As noted before, many variables contribute to identifying a proper tuning value so if down the road you change your flash or board design and the ITAP of 0 is no longer optimal it could introduce a failure that is difficult to root cause. I will defer to you if this is an acceptable risk. 

    I tend to agree, the most robust would be to tune and either reject the result and rerun if no failing window is detected, or run some more stressful read/write with the tuned ITAP value and if this fails, re-tune. Since the incidence of failure seems low, it does not seem that this will have a notable performance impact. 

    Thanks,

    Chris 

  • Hello,

    Could the ITAP tuning value change on the same unit if it starts up in low temp vs high temp? If yes, how is it handle when starting in very cold temp and then temp is rising to high temp and unit is running all the time?

    Magnus

  • Magnus, 

    It is possible that it could tune to a different point depending on environmental conditions, but on the same device the delta would generally be minimal, if at all. During characterization we collect data across temperature ranges to ensure that the valid/invalid window stays relatively constant.

    Basically, the tuning algorithm selects an ITAP in the middle of a data valid window that has significant enough margin the temperature variance will not cause invalid data even if runtime operation is different than tuning conditions. 

    Thanks,

    Chris 

  • Thanks Chris

    Thanks for all answers and comments, really appreciated. I don’t think we could do anything more.

    I will implement retune…