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.

TDA4VM: BIST initialize DRAM doesn't work normally

Part Number: TDA4VM
Other Parts Discussed in Thread: TDA4VH

Tool/software:

Dear expert, 

I'm trying to collect BIST write latency on ECC protected DRAM area, compared with CPU write in R5 u-boot.

  • Ref board: J721E/TDA4 ref board
  • SDK: ti-processor-sdk-linux-adas-j721e-evm-10_01_00_04

In 1st test, I write "k3_ddrss_preload_ecc_mem_region()" function in R5 u-boot,

CPU loop write on 0xC000-0000 ~ 0xD000-0000 with u64 patten 0x1234-5678-dead-beef

I check the DRAM content in u-boot prompt, it works well .

=> md.l 0xc0000000 0x10
c0000000: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c0000010: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c0000020: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c0000030: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
=> md.l 0xcfffffe0 0x10
cfffffe0: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
cffffff0: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
d0000000: 008a81c1 c00090f4 1c100002 01809008 ................
d0000010: 82884431 cca20202 801010a8 65924309 1D...........C.e
=>

In 2nd test, after cpu write on 0xC000-0000 ~ 0xD000-0000 with pattern 0x1234-5678-dead-beef in R5 u-boot

then I call u-boot function "k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x11223344)"

to initial write 0xD000-0000 ~ 0xE000-0000 with u32 pattern 0x1122-3344

But get below result in u-boot prompt

=> md.l 0xc0000000 0x10
c0000000: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c0000010: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c0000020: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c0000030: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
=> md.l 0xc71c71e0 0x10
c71c71e0: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c71c71f0: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
c71c7200: 11223344 11223344 00000000 00000000 D3".D3".........
c71c7210: 11223344 11223344 00000000 00000000 D3".D3".........
=> md.l 0xd5555560
d5555560: 11223344 11223344 00000000 00000000 D3".D3".........
d5555570: 11223344 11223344 00000000 00000000 D3".D3".........
d5555580: c8108008 14042783 091d0400 141289c4 .....'..........
d5555590: 0b894888 411488ac 410a9198 8201d814 .H.....A...A....
=>

Seems that BIST write gets 2 issues:

  1. DRAM range c71c7200 ~ d5555580  is not expected.
  2. some area is not initialized with zeros instead of pattern.

Below is my u-boot code in 2nd test, could you help check what's wrong?

file: ti-processor-sdk-linux-adas-j721e-evm-10_01_00_04/board-support/ti-u-boot-2024.04+git/drivers/ram/k3-ddrss/k3-ddrss.c
static void k3_ddrss_preload_ecc_mem_region(u64 *addr, u64 size, u64 pattern)
{
    u64 i = 0;
    for (i = 0; i < (size / 8); i++)
        addr[i] = pattern;
}

static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
{

    //... skip

     done = get_timer(0);
     k3_ddrss_preload_ecc_mem_region( (u64 *)0xC0000000, 0x10000000, 0x12345678deadbeef);
     printf("ECC: priming DDR area 0xC000-0000, size 0x1000-0000 with CPU, completed in %lu msec\n", get_timer(done));

     done = get_timer(0);  // BIST require bus addr ? am I right? (0xD000-0000 - 0x8000-0000) = 0x5000-0000
     k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x11223344);
     printf("ECC: priming DDR area 0xD000-0000, size 0x1000-0000 with BIST, completed in %lu msec\n", get_timer(done));   

    // ... skip

}

Thanks a lot for your support !

Best, 
Leon

  • Hello Leon,

    By default the SDK does:

    /* Preload the full memory with 0's using the BIST engine of
    * the LPDDR4 controller.
    */
    k3_ddrss_lpddr4_preload_full_mem(ddrss, ddrss->ddr_ram_size, 0);

    Could you please try with 0 and make sure that all your target memory is zeroed correctly?

    If that works well using BIST then we compare the 0 writing with CPU vs Bist?

    - Keerthy

  • Hi, Keerthy, 

    Thanks for your quick response. 

    I modify my u-boot code as below, leverage BIST initial write with zero:

    // cpu write 0xC000-0000 ~ 0xF000-0000 with pattern 0x1234-5678-dead-beef

    k3_ddrss_preload_ecc_mem_region( (u64 *)0xC0000000, 0x30000000, 0x12345678deadbeef);

    // BIST write 0xD000-0000 ~ 0xE000-0000 with pattern zero

    k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x0);

     

    But unfortunately, the result is still not within expectation:

    Hit any key to stop autoboot: 0
    => md.l 0xC0000000 0x10
    c0000000: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    c0000010: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    c0000020: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    c0000030: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    => md.l 0xc71c71e0 0x10
    c71c71e0: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    c71c71f0: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    c71c7200: 00000000 00000000 00000000 00000000 ................
    c71c7210: 00000000 00000000 00000000 00000000 ................
    => md.l 0xd5555560
    d5555560: 00000000 00000000 00000000 00000000 ................
    d5555570: 00000000 00000000 00000000 00000000 ................
    d5555580: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    d5555590: deadbeef 12345678 deadbeef 12345678 ....xV4.....xV4.
    =>

     

    I concern there may be something wrong when call below function: 

    k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x0);   // for BIST write 0xD000-0000 ~ 0xE000-0000 with pattern zero

    • addr: It should be DRAM bus addr, that is to say, 0xD000-0000 - 0x8000-0000 = 0x5000-0000,  Am I right ?
    • len: 0x1000-0000, length in bytes. 
    • pattern: 0 as you recommended.

    Could you help check my above code ?

    Thanks.

  • Okay. I will try to reproduce this at my end and get back to you by tomorrow. 

    Thanks, 

    Keerthy 

  • Hi, Keerthy, 

    Sorry for pushing you, is there any update?

    BTW, below are some tips to enable in-line ECC and BIST module in R5 u-boot dts file.

    file: ti-processor-sdk-linux-adas-j721e-evm-10_01_00_04/board-support/ti-u-boot-2024.04+git/arch/arm/dts/k3-j721e-ddr.dtsi

    memorycontroller@0298e000 {

    compatible = "ti,j721e-ddrss";

    reg = <0x0 0x02990000 0x0 0x4000>,
    <0x0 0x0114000 0x0 0x100>,
    <0x0 0x02980000 0x0 0x200>;
    reg-names = "cfg", "ctrl_mmr_lp4", "ss_cfg" ;

    ti,ecc-enable = "true";

     

    Thanks.

  • Thanks. I will get back by tomorrow evening. 

    Regards, 

    Keerthy 

  • Hello Leon,

    Our internal team is looking into this issue. We will keep you posted on the updates by tomorrow.

    Thanks for your patience,
    Keerthy

  • Hi, Keerthy, 

    Sorry for pushing you, is there any update?

    Or is there any other technical note or sample code I can refer to for BIST module usage? 

    Thanks.

  • Hello Leon,

    We are yet to reproduce the issue. Can you use the BIST only to prime the memory only once?

    Say you write 0x0 just once?

    Only write 0s using BIST once and no other value & see if this still fails to write 0s even at the first instance.

    - Keerthy

  • Hi, Keerthy, 

    Thanks for your feedback.

    I modify u-boot per your suggestion, this time I delete cpu initial write, only BIST write 0xD000-0000 ~ 0xE000-0000 with pattern zero

    Then get the same unexpected result as before:

    Hit any key to stop autoboot: 0
    => md.l 0xc0000000 0x10
    c0000000: 108b5319 91510749 12311909 16d80e10 .S..I.Q...1.....
    c0000010: 51cdd3b4 a5dc6c14 099d8181 8043b91f ...Q.l........C.
    c0000020: d59501c6 6d144c20 8d501199 55551881 .... L.m..P...UU
    c0000030: 0d089891 26541941 560d4110 5430fa81 ....A.T&.A.V..0T
    => md.l 0xc71c71e0 0x10
    c71c71e0: 734458ce 1251119c ba4f014e e2a7a6f1 .XDs..Q.N.O.....
    c71c71f0: ec280980 31a30945 90092d07 708ee113 ..(.E..1.-.....p
    c71c7200: 00000000 00000000 00000000 00000000 ................
    c71c7210: 00000000 00000000 00000000 00000000 ................
    => md.l 0xd5555560 0x10
    d5555560: 00000000 00000000 00000000 00000000 ................
    d5555570: 00000000 00000000 00000000 00000000 ................
    d5555580: c810803a 1446279b 0b190680 3c12e9d4 :....'F........<
    d5555590: 0be98d8d 4d14e8ac 410a91b8 9315d81c .......M...A....
    =>

    I still concern there may be wrong usage with BIST.  

    Please check my code : 

    k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x0);   // for BIST write 0xD000-0000 ~ 0xE000-0000 with pattern zero

    • addr: It should be DRAM bus addr, that is to say, 0xD000-0000 - 0x8000-0000 = 0x5000-0000,  Am I right ?
    • len: 0x1000-0000, length in bytes. 
    • pattern: 0 as you recommended.

    Below is my modification on k3-ddrss.c, hope it may help reproduce the issue.

    diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
    index eaf31cd4..db06139f 100644
    --- a/drivers/ram/k3-ddrss/k3-ddrss.c
    +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
    @@ -807,9 +807,17 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
     	u64 ecc_range = ddrss->ecc_regions[0].range;
     	u32 base = (u32)ddrss->ddrss_ss_cfg;
     	u32 val;
    +	u32 done = 0;
     
    +#if 0 
     	/* Only Program region 0 which covers full ddr space */
     	k3_ddrss_set_ecc_range_r0(base, ecc_region_start, ecc_range);
    +#else
    +	// leonwang modify, enable ecc region 0 to cover partial area on low mem
    +	//printf("---> leonwang add %s %d ECC protected cpu phy addr: 0xC000_0000 ~ 0xD001_ffff \n", __FILE__, __LINE__);
    +	//printf("---> leonwang add %s %d ECC protected ram bus addr: 0x4000_0000 ~ 0x5001_ffff \n", __FILE__, __LINE__);
    +	//k3_ddrss_set_ecc_range_r0(base, 0x40000000, 0x10020000);
    +#endif
     
     	/* Enable ECC, RMW, WR_ALLOC */
     	writel(DDRSS_ECC_CTRL_REG_ECC_EN | DDRSS_ECC_CTRL_REG_RMW_EN |
    @@ -818,7 +826,25 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
     	/* Preload the full memory with 0's using the BIST engine of
     	 * the LPDDR4 controller.
     	 */
    +#if 0	
     	k3_ddrss_lpddr4_preload_full_mem(ddrss, ddrss->ddr_ram_size, 0);
    +#else
    +	// leonwang modify, cpu vs BIST initial write on ecc protected area
    +	/* cpu initial write ecc area on low mem */
    +	//printf("---> leonwang add %s %d \"CPU\" init write to cpu addr: 0xC000_0000 ~ 0xD000_0000\n", __FILE__, __LINE__);
    +	//done = get_timer(0);
    +	//k3_ddrss_preload_ecc_mem_region( (u64 *)0xC0000000, 0x10000000, 0x12345678deadbeef);
    +	//printf("ECC: priming DDR with CPU, completed in %lu msec\n", get_timer(done));
    +
    +	/* bist initial write */
    +	printf("---> leonwang add %s %d \"BIST\" initial write on cpu phy addr: 0xD000_0000 + 0x1000_0000\n", __FILE__, __LINE__);
    +	printf("---> leonwang add %s %d \"BIST\" initial write on ram bus addr: 0x5000_0000 + 0x1000_0000\n", __FILE__, __LINE__);
    +	done = get_timer(0);
    +	//k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x11223344);
    +	k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0);
    +	printf("ECC: priming DDR with BIST, completed in %lu msec\n", get_timer(done));
    +#endif
     
     	/* Clear Error Count Register */
     	writel(0x1, base + DDRSS_ECC_1B_ERR_CNT_REG);
    @@ -826,12 +852,31 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
     	writel(DDRSS_V2A_INT_SET_REG_ECC1BERR_EN | DDRSS_V2A_INT_SET_REG_ECC2BERR_EN |
     		   DDRSS_V2A_INT_SET_REG_ECCM1BERR_EN, base + DDRSS_V2A_INT_SET_REG);
     
    +#if 0	// leonwang del for test
     	/* Enable ECC Check */
     	val = readl(base + DDRSS_ECC_CTRL_REG);
     	val |= DDRSS_ECC_CTRL_REG_ECC_CK;
     	writel(val, base + DDRSS_ECC_CTRL_REG);
    +#endif
     }

    Thanks.

  • k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x0);   // for BIST write 0xD000-0000 ~ 0xE000-0000 with pattern zero

    • addr: It should be DRAM bus addr, that is to say, 0xD000-0000 - 0x8000-0000 = 0x5000-0000,  Am I right ?

    That is correct.

    Below is my modification on k3-ddrss.c, hope it may help reproduce the issue.

    We are trying to reproduce. I will get back by tomorrow with updates.

    - Keerthy

  • Hi, Keerthy, 

    Sorry for pushing you again, is there any update ?

    Do you encounter any issue when reproduce ? maybe I can help.

    thanks.

  • Hi Wang,

    Thanks for checking.

    I am currently facing the below issue:

    U-Boot SPL 2024.04-ti-dirty (May 20 2025 - 11:37:59 +0530)
    SYSFW ABI: 4.0 (firmware rev 0x000a '10.1.6--v10.01.06 (Fiery Fox)')
    read error from device: 41c863bc register: x!
    ECC is enabled, priming DDR which will take several seconds.
    ERROR: Timeout while priming the memory.
    ### ERROR ### Please RESET the board ###
    

    Changes that I have made:

    diff --git a/arch/arm/dts/k3-j721e-ddr.dtsi b/arch/arm/dts/k3-j721e-ddr.dtsi
    index 7d2ccd95..b59673bc 100644
    --- a/arch/arm/dts/k3-j721e-ddr.dtsi
    +++ b/arch/arm/dts/k3-j721e-ddr.dtsi
    @@ -7,8 +7,10 @@
            memorycontroller: memorycontroller@0298e000 {
                    compatible = "ti,j721e-ddrss";
                    reg = <0x0 0x02990000 0x0 0x4000>,
    -                     <0x0 0x0114000 0x0 0x100>;
    -               reg-names = "cfg", "ctrl_mmr_lp4";
    +                     <0x0 0x0114000 0x0 0x100>,
    +                     <0x0 0x02980000 0x0 0x200>;
    +               reg-names = "cfg", "ctrl_mmr_lp4", "ss_cfg";
    +               ti,ecc-enable = "true";
                    power-domains = <&k3_pds 47 TI_SCI_PD_SHARED>,
                            <&k3_pds 90 TI_SCI_PD_SHARED>;
                    clocks = <&k3_clks 47 2>, <&k3_clks 30 9>;
    

    I am checking internally on why this error comes up.

    Did you face the issue at your end?

    - Keerthy

  • Hi, Keerthy, 

    Seems that you encounter two issues

    1. "read error from device: 41c863bc register: x! "

    I don't encounter it before.

    I search the u-boot source code, seems that it's related to PMIC driver.

    If it doesn't block our test, then maybe we can ignore it temporarily.  

    2. ERROR: Timeout while priming the memory.

    It takes too long time for BIST to initialize DRAM (10 sec+)

    One simple workaround solution is not to check the timeout.

    file: ti-processor-sdk-linux-adas-j721e-evm-10_01_00_04/board-support/ti-u-boot-2024.04+git/drivers/ram/k3-ddrss/k3-ddrss.c

    #define BIST_MODE_MEM_INIT      4
    #define BIST_MEM_INIT_TIMEOUT       10000 /* 1msec loops per block = 10s */
    static void k3_lpddr4_bist_init_mem_region(struct k3_ddrss_desc *ddrss,
                           u64 addr, u64 size,
                           u32 pattern)
    {
        // ...
        #if 0 // you can del it to workaround timeout issue
        if (i == BIST_MEM_INIT_TIMEOUT) {
            printf("ERROR: Timeout while priming the memory.\n");
            hang();
        }
        #endif
    }

    Thanks.

  • It takes too long time for BIST to initialize DRAM (10 sec+)

    One simple workaround solution is not to check the timeout.

    Have you added the above code when you are testing?

    I believe if we come out without BIST completion. Then may be we will see that uninitialized issue that you are seeing?
    We are not allowing BIST to complete fully?

    Are you using the above code? I am seeing that BIST completion is not done.

    - Keerthy

  • Hi, Keerthy, 

    In default u-boot code, seems that it try to initialize "all DRAM" through BIST.  

    k3_ddrss_lpddr4_ecc_init()

    --> k3_ddrss_lpddr4_preload_full_mem(ddrss, ddrss->ddr_ram_size, 0);

        --> k3_lpddr4_bist_init_mem_region(ddrss, 0, total_size, pattern);   

              // I concern there is some bug here,  because the 2 bank DRAM address are not continuous.

              // maybe that's why you see BIST never complete ?

    In my test, I just want to initialize "part of DRAM" 

    k3_ddrss_lpddr4_ecc_init()

    --> k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0); 

         // just initialize partial DRAM area in 1st bank. You can ref to my patch in above chat for more detail

         // BIST can finish without timeout issue, but find range and pattern are not expected.  

    Thanks.

  • In my test, I just want to initialize "part of DRAM" 

    k3_ddrss_lpddr4_ecc_init()

    --> k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0); 

         // just initialize partial DRAM area in 1st bank. You can ref to my patch in above chat for more detail

         // BIST can finish without timeout issue, but find range and pattern are not expected

    Even this is hanging for me.

    U-Boot SPL 2024.04-ti-dirty (May 20 2025 - 12:03:20 +0530)
    SYSFW ABI: 4.0 (firmware rev 0x000a '10.1.6--v10.01.06 (Fiery Fox)')
    read error from device: 41c863bc register: x!
    ECC is enabled, priming DDR which will take several seconds.
    ECC: priming DDR completed in 760 msec

    Also I double checked with our development team. This is validated only on TDA4VH and not on TDA4VM. 

    - Keerthy

  • Hi, Keerthy, 

    Thanks for your info. 

    Currently we only have TDA4VM ref board at hand for the BIST test... 

    From hardware view, the TDA4VM SoC supports BIST, right ?

    It should be doable to make BIST work on TDA4VM. 

    At least, my TDA4VM ref board can boot with BIST enabled.

    I concern the root cause of your board failure is PMIC driver failure "read error from device: 41c863bc register: x!

    I search u-boot build output folder and find this:

    ~/ti-j7/board-support/ti-u-boot-2024.04+git$ ls build/r5/drivers/power/pmic/
    built-in.o pmic-uclass.o pmic-uclass.su tps65941.o tps65941.su

    The related drive source code is 

    file: drivers/power/pmic/tps65941.c

    static int tps65941_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
    {
        if (dm_i2c_read(dev, reg, buff, len)) {
              pr_err("read error from device: %p register: %#x!\n", dev, reg);
              return -EIO;
         }

    I guess there may be something wrong with PMIC 65941 in your board.

    Could you try another TDA4VM ref board ?

    Hope the issue maybe gone.

    Thanks.

  • Hi, Keerthy, 

    Another finding 

    From your failure log, seems that you just use BIST to initialize part of ECC protected area.

    Could you help double check if ECC check is disabled in the end of k3_ddrss_lpddr4_ecc_init() ?

    otherwise the ECC error will make system stuck.

    Thanks.

  • Hi,

    Let me try with a different board and cross check if i see the same issue. I will get back by tomorrow evening.

    Could you help double check if ECC check is disabled in the end of k3_ddrss_lpddr4_ecc_init() ?

    otherwise the ECC error will make system stuck.

    Did you add the explicitly?

    - Keerthy

  • Hi, Keerthy, 

    If you just initialize part of ECC protect area, you need to disable ECC check.

    file: ti-processor-sdk-linux-adas-j721e-evm-10_01_00_04/board-support/ti-u-boot-2024.04+git/drivers/ram/k3-ddrss/k3-ddrss.c

    static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
    {
    
    // ...... skip 
    
    #if 0   // leonwang del for test
        /* Enable ECC Check */
        val = readl(base + DDRSS_ECC_CTRL_REG);
        val |= DDRSS_ECC_CTRL_REG_ECC_CK;
        writel(val, base + DDRSS_ECC_CTRL_REG);
    #endif
    }
    

    Below is my full my modification on k3-ddrss.c, please refer to it. (partial initialization and ECC check disabled)

    diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
    index eaf31cd4..db06139f 100644
    --- a/drivers/ram/k3-ddrss/k3-ddrss.c
    +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
    @@ -807,9 +807,17 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
     	u64 ecc_range = ddrss->ecc_regions[0].range;
     	u32 base = (u32)ddrss->ddrss_ss_cfg;
     	u32 val;
    +	u32 done = 0;
     
    +#if 0 
     	/* Only Program region 0 which covers full ddr space */
     	k3_ddrss_set_ecc_range_r0(base, ecc_region_start, ecc_range);
    +#else
    +	// leonwang modify, enable ecc region 0 to cover partial area on low mem
    +	//printf("---> leonwang add %s %d ECC protected cpu phy addr: 0xC000_0000 ~ 0xD001_ffff \n", __FILE__, __LINE__);
    +	//printf("---> leonwang add %s %d ECC protected ram bus addr: 0x4000_0000 ~ 0x5001_ffff \n", __FILE__, __LINE__);
    +	//k3_ddrss_set_ecc_range_r0(base, 0x40000000, 0x10020000);
    +#endif
     
     	/* Enable ECC, RMW, WR_ALLOC */
     	writel(DDRSS_ECC_CTRL_REG_ECC_EN | DDRSS_ECC_CTRL_REG_RMW_EN |
    @@ -818,7 +826,25 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
     	/* Preload the full memory with 0's using the BIST engine of
     	 * the LPDDR4 controller.
     	 */
    +#if 0	
     	k3_ddrss_lpddr4_preload_full_mem(ddrss, ddrss->ddr_ram_size, 0);
    +#else
    +	// leonwang modify, cpu vs BIST initial write on ecc protected area
    +	/* cpu initial write ecc area on low mem */
    +	//printf("---> leonwang add %s %d \"CPU\" init write to cpu addr: 0xC000_0000 ~ 0xD000_0000\n", __FILE__, __LINE__);
    +	//done = get_timer(0);
    +	//k3_ddrss_preload_ecc_mem_region( (u64 *)0xC0000000, 0x10000000, 0x12345678deadbeef);
    +	//printf("ECC: priming DDR with CPU, completed in %lu msec\n", get_timer(done));
    +
    +	/* bist initial write */
    +	printf("---> leonwang add %s %d \"BIST\" initial write on cpu phy addr: 0xD000_0000 + 0x1000_0000\n", __FILE__, __LINE__);
    +	printf("---> leonwang add %s %d \"BIST\" initial write on ram bus addr: 0x5000_0000 + 0x1000_0000\n", __FILE__, __LINE__);
    +	done = get_timer(0);
    +	//k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0x11223344);
    +	k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0);
    +	printf("ECC: priming DDR with BIST, completed in %lu msec\n", get_timer(done));
    +#endif
     
     	/* Clear Error Count Register */
     	writel(0x1, base + DDRSS_ECC_1B_ERR_CNT_REG);
    @@ -826,12 +852,31 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
     	writel(DDRSS_V2A_INT_SET_REG_ECC1BERR_EN | DDRSS_V2A_INT_SET_REG_ECC2BERR_EN |
     		   DDRSS_V2A_INT_SET_REG_ECCM1BERR_EN, base + DDRSS_V2A_INT_SET_REG);
     
    +#if 0	// leonwang del for test
     	/* Enable ECC Check */
     	val = readl(base + DDRSS_ECC_CTRL_REG);
     	val |= DDRSS_ECC_CTRL_REG_ECC_CK;
     	writel(val, base + DDRSS_ECC_CTRL_REG);
    +#endif
     }
       

    BTW,

    To avoid misunderstanding, 

    my board can boots well with ECC check enabled. TDA4VM: In-line ECC error handling in J721E - Processors forum - Processors - TI E2E support forums

    Currently I want to test BIST function, so I disable ECC check temporarily for test.  

    Thanks.

  • Okay thank you for sharing the full set of changes. I will try on a different board and get back. 

    Best Regards,

    Keerthy 

  • Hi Leon,

    Thanks for all the changes. I am seeing the behavior that you observe:

    k3_lpddr4_bist_init_mem_region(ddrss, 0x50000000, 0x10000000, 0);

    So 0xD0000000 - 0xE0000000 --> The whole range should be 0.

    But i do see:

    =>
    => md 0xd8000000
    d8000000: ffffdfff ffffffff bdffffdd ffffdfff ................
    d8000010: ffddbfef fffffdff ffffff7f ffffffff ................
    d8000020: ffffffff ffffffff ffffffbf ffffdfff ................
    d8000030: ffffffdf ffffffff 7effffff fffffeff ...........~....
    d8000040: ffffffff ffeffbf7 ffffffff ffbfffff ................
    d8000050: ffffffff fffffeff ffbffbff ffffff7f ................
    d8000060: dffe7fff dfefffff fff7fdff fffffdff ................
    d8000070: ffffffff d7f77fff bfffffff fdffffff ................
    d8000080: ffffffff ffffffff ffffbdff ffffffdf ................
    d8000090: ffffffff ffffffff ffffffff f7ffffff ................
    d80000a0: ffffffff ffffffff fffffffe ffffbeff ................
    d80000b0: fffffedf ffffefff ffffdfff fffffeff ................
    d80000c0: ffffffff ffffffff fd7ffdff fffefff7 ................
    d80000d0: bfffffff ffffffff ffffffff ffdfffff ................
    d80000e0: fefdffff fff9bfff 7ffffffb ffbfffff ................
    d80000f0: ffbffffb ffffffff ffffb9ff ffffffff ................
    =>

    These are non-zero values & not expected. That said at this point I am unsure if BIST has written the complete range.

    - Keerthy

  • Hello Leon,

    One quick observation:

    k3_lpddr4_bist_init_mem_region(ddrss, 0x10000000, 0x10000000, 0);

    Basically trying to write 0s from 0x90000000 - 0xA0000000.

    That seemed to work well. I saw all of the range 0. So can you try that at your end and check?

    - Keerthy

  • Hi, Keerthy, 

    After apply k3_lpddr4_bist_init_mem_region(ddrss, 0x10000000, 0x10000000, 0)

    Unfortunately, here is my result 

    => md.l 0x8e38e340 0x20
    8e38e340: fdffb7ff ffffdede 1eaffbff ef6f3dfe .............=o.
    8e38e350: fffe7ff7 ff3ffff5 bddffd7f cffefdbf ......?.........
    8e38e360: ffd6f7ff bffbdfff 87ffafff fafffdeb ................
    8e38e370: dff7ff7f fffff9ff ff6f5def affffffd .........]o.....
    8e38e380: 00000000 00000000 00000000 00000000 ................
    8e38e390: 00000000 00000000 00000000 00000000 ................
    8e38e3a0: 00000000 00000000 00000000 00000000 ................
    8e38e3b0: 00000000 00000000 00000000 00000000 ................


    => md.l 0x90000000 0x20
    90000000: 00000000 00000000 00000000 00000000 ................
    90000010: 00000000 00000000 00000000 00000000 ................
    90000020: 00000000 00000000 00000000 00000000 ................
    90000030: 00000000 00000000 00000000 00000000 ................
    90000040: 00000000 00000000 00000000 00000000 ................
    90000050: 00000000 00000000 00000000 00000000 ................
    90000060: 00000000 00000000 00000000 00000000 ................
    90000070: 00000000 00000000 00000000 00000000 ................


    => md.l 0x9c71c6c0 0x20
    9c71c6c0: 00000000 00000000 00000000 00000000 ................
    9c71c6d0: 00000000 00000000 00000000 00000000 ................
    9c71c6e0: 00000000 00000000 00000000 00000000 ................
    9c71c6f0: 00000000 00000000 00000000 00000000 ................
    9c71c700: 9dffbdf7 9f7fffc7 bdb3ebfd ff7ffeff ................
    9c71c710: dfffffbf cdfff97f 9bd5fa9f fbffc97f ................
    9c71c720: badf3eff 7dff7fbf af7fbfef dff3fd9f .>.....}........
    9c71c730: bfb9dffa fdfffbdd ffbfbbff fefffffe ................
    =>

    Could you help double check your result ? 

    not only check the dram content start at 0x9000-0000,  but also include other area.

    Thanks.

  • Hi Leon,

    I did a random check towards the end as well. Let me check at these addresses and get back to you today.

    - Keerthy

  • Hi Leon,

    As the J721e is not implemented in the SDK. I have raised a requirement to support the J721e Inline ECC support for DDR in the next SDK.
    The implementation should also look at resolving the priming issue that you have identified.

    Thanks for your patience. Please check out next SDK release notes as this is a missing feature we are going back to the development team for the implementation. Please feel free to reply back on this if any additional details are needed.

    Thanks,
    Keerthy

  • Hi, Keerthy, 

    Thanks for your support.

    I will try in next SDK release.

    Best Regards, 
    Leon