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.

TMS320C6657: DDR3 initialization is too long time

Part Number: TMS320C6657

Hi experts,

We have developed a custom board in 8 years ago.

We really appericated your support like you.

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/245248/ddr3-installation-issues

However 

we have sometimes found very long DDR3 auto levelling problem with below codes recently 

There is 20 ~ 30% boards which boots sometimes very long like 30 seconds.

There is not any boards in a year ago.

We must improve this ratio, and could  please give a comment  what points is important.

.

1856.ddr3.c
/*""FILE INCLUDE""*************************************************************/
#include    "ddr3_p.h"

//#include  "csl_emif4f.h"
//#include  "csl_bootcfgAux.h"

/*""FILE INCLUDE END""*********************************************************/


/*""Function Define""**********************************************************/
INT32 DDR3_TestMemory_s32(void)
{

    UINT32 *pWork = (UINT32 *)DDR3_TEST_START_ADDRESS; //point to start of DDR3
    UINT32 u32Tmp;
    BOOL bError = FALSE;

    printf ( "DDR3 memory test... Started. \n" );
    
    while (pWork < (UINT32 *)DDR3_TEST_END_ADDRESS)
    {
        *pWork = u32Tmp = ~(*pWork);
        if (u32Tmp != *pWork)
        {
            bError = TRUE;
            break;
        }
        pWork += 0x1;
    }
    
    if (bError == TRUE)
    {
        printf("DDR3 memory test... Failed. \n");
        return -1;
    }



    printf ( "DDR3 memory test... Passed. \n" );
    return 0;
}


INT32 DDR3_Init1_s32 (void)
{
    INT32 i;
    UINT32 TEMP;

    printf("DDR3 Configuration... \n");

    /*Unlock Boot Config*/
    CSL_BootCfgUnlockKicker();

    /* Wait for PLL to lock = min 500 ref clock cycles.
       With refclk = 100MHz, = 5000 ns = 5us */
    /////////for(i=0; i< 1000; i++)
    for(i=0; i< 1250; i++)              // ADD test_w
        asm(" nop 5");

    /***************** 3.2 DDR3 PLL Configuration ************/
    /* Done before */

    /**************** 3.0 Leveling Register Configuration ********************/
    /* Using partial automatic leveling due to errata */

    /**************** 3.3 Leveling register configuration ********************/
    boot_cfg_regs->DDR3_CONFIG_REG[0] &= ~(0x007FE000U);  // clear ctrl_slave_ratio field
    boot_cfg_regs->DDR3_CONFIG_REG[0] |= 0x00200000U;     // set ctrl_slave_ratio to 0x100
    boot_cfg_regs->DDR3_CONFIG_REG[12] |= 0x08000000U;    // Set invert_clkout = 1
    boot_cfg_regs->DDR3_CONFIG_REG[0] |= 0xFU;            // set dll_lock_diff to 15

    //From 4.2.1 Executing Partial Automatic Leveling -- Start
    boot_cfg_regs->DDR3_CONFIG_REG[52] |= 0x00000200U;    //Set bit 9 = 1 to use forced ratio leveling for read DQS
    boot_cfg_regs->DDR3_CONFIG_REG[53] |= 0x00000200U;
    boot_cfg_regs->DDR3_CONFIG_REG[54] |= 0x00000200U;
    boot_cfg_regs->DDR3_CONFIG_REG[55] |= 0x00000200U;
    boot_cfg_regs->DDR3_CONFIG_REG[60] |= 0x00000200U;
    //From 4.2.1 Executing Partial Automatic Leveling -- End

    //Values with invertclkout = 1
    /**************** 3.3 Partial Automatic Leveling ********************/
    /*WRLVL_INIT_RATIO*/
    boot_cfg_regs->DDR3_CONFIG_REG[2] = 0x5DU;
    boot_cfg_regs->DDR3_CONFIG_REG[3] = 0x5CU;
    boot_cfg_regs->DDR3_CONFIG_REG[4] = 0x51U;
    boot_cfg_regs->DDR3_CONFIG_REG[5] = 0x48U;
    boot_cfg_regs->DDR3_CONFIG_REG[8] = 0x00U;

    /*GTLVL_INIT_RATIO*/
    boot_cfg_regs->DDR3_CONFIG_REG[14] = 0xADU;
    boot_cfg_regs->DDR3_CONFIG_REG[15] = 0xAEU;
    boot_cfg_regs->DDR3_CONFIG_REG[16] = 0x93U;
    boot_cfg_regs->DDR3_CONFIG_REG[17] = 0x9DU;
    boot_cfg_regs->DDR3_CONFIG_REG[22] = 0x00U;

    //Do a PHY reset. Toggle DDR_PHY_CTRL_1 bit 15 0->1->0
    DDR_Regs->DDR_PHY_CTRL_1 &= ~(0x00008000U);
    DDR_Regs->DDR_PHY_CTRL_1 |= (0x00008000U);
    DDR_Regs->DDR_PHY_CTRL_1 &= ~(0x00008000U);

    /***************** 3.4 Basic Controller and DRAM Configuration ************/

    DDR_Regs->SDRAM_REF_CTRL = 0x00005161U;    // enable configuration

    /* SDRAM_TIM_1 */
    TEMP = 0U;
    TEMP |= 0x08U << 25; // T_RP bit field 28:25
    TEMP |= 0x08U << 21; // T_RCD bit field 24:21
    TEMP |= 0x09U << 17; // T_WR bit field 20:17
    TEMP |= 0x17U << 12; // T_RAS bit field 16:12
    TEMP |= 0x20U << 6; // T_RC bit field 11:6
    TEMP |= 0x7U << 3; // T_RRD bit field 5:3
    TEMP |= 0x4U; // T_WTR bit field 2:0
    DDR_Regs->SDRAM_TIM_1 = TEMP;

    /* SDRAM_TIM_2 */
    TEMP = 0U;
    TEMP |= 0x3U << 28; // T_XP bit field 30:28
    TEMP |= 0x71U << 16; // T_XSNR bit field 24:16
    TEMP |= 0x1ffU << 6; // T_XSRD bit field 15:6
    TEMP |= 0x4U << 3; // T_RTP bit field 5:3
    TEMP |= 0x3U; // T_CKE bit field 2:0
    DDR_Regs->SDRAM_TIM_2 = TEMP;

    /* SDRAM_TIM_3 */
    TEMP = 0U;
    TEMP |= 0x5U << 28; // T_PDLL_UL bit field 31:28 (fixed value)
    TEMP |= 0x5U << 24; // T_CSTA bit field 27:24 (fixed value)
    TEMP |= 0x4U << 21; // T_CKESR bit field 23:21
    TEMP |= 0x3fU << 15; // T_ZQCS bit field 20:15
    TEMP |= 0x6AU << 4; // T_RFC bit field 12:4
    TEMP |= 0xfU; // T_RAS_MAX bit field 3:0 (fixed value)
    DDR_Regs->SDRAM_TIM_3 = TEMP;

    DDR_Regs->DDR_PHY_CTRL_1  = 0x0010010FU;
    DDR_Regs->ZQ_CONFIG    = 0x70073214U;
    DDR_Regs->PWR_MGMT_CTRL    = 0x0U;

    DDR_Regs->SDRAM_REF_CTRL = 0x00005161U;    // enable configuration

    /* DDR_SDCFG */
    /* New value with DYN_ODT disabled and SDRAM_DRIVE = RZQ/7 //0x63222A32;    // last config write DRAM init occurs */
    TEMP = 0U;
    TEMP |= 0x3U << 29; // SDRAM_TYPE bit field 31:29 (fixed value)
    TEMP |= 0x0U << 27; // IBANK_POS bit field 28:27
    TEMP |= 0x3U << 24; // DDR_TERM bit field 26:24
    TEMP |= 0x0U << 21; // DYN_ODT bit field 22:21
    TEMP |= 0x0U << 18; // SDRAM_DRIVE bit field 19:18
    TEMP |= 0x2U << 16; // CWL bit field 17:16
    TEMP |= 0x1U << 14; // NM bit field 15:14
    TEMP |= 0xAU << 10; // CL bit field 13:10
    TEMP |= 0x5U << 7; // ROWSIZE bit field 9:7
    TEMP |= 0x3U << 4; // IBANK bit field 6:4
    TEMP |= 0x0U << 3; // EBANK bit field 3:3
    TEMP |= 0x2U; // PAGESIZE bit field 2:0
    DDR_Regs->SDRAM_CONFIG = TEMP;

    //Wait 600us for HW init to complete
    //for(i=0; i< 600*200; i++)
    for(i=0; i< 750*200; i++)           // ADD test_w
        asm(" nop 5");

    DDR_Regs->SDRAM_REF_CTRL    = 0x00001458U;       //Refresh rate = (7.8*666MHz)

    /**************** 4.2.1 Executing Partial Automatic Leveling ********************/

    DDR_Regs->RDWR_LVL_RMP_CTRL = 0x80000000U; //enable full leveling

    DDR_Regs->RDWR_LVL_CTRL = 0x80000000U; //Trigger full leveling - This ignores read DQS leveling result and uses ratio forced value

    //(0x34) instead
    //Wait for min 1048576 DDR clock cycles for leveling to complete = 1048576 * 1.5ns = 1572864ns = 1.57ms.
    //Actual time = ~10-15 ms
    //for(i=0; i<15*200000; i++)
    for(i=0; i<15*250000; i++)          // ADD test_w
        asm(" nop 5");
        
    i=0;
    while ((DDR_Regs->STATUS & 0x00000070U) && (i<0xf)) {
        i++;
        asm(" nop 5");
        ///if (i>3000000){ break; }
        if (i>3,750,000){ break; }          // ADD test_w
    }

    // Lock the kicker mechanism
    CSL_BootCfgLockKicker();

    //if (i>3000000)
    if (i>3,750,000)    // ADD test_w
    {
        printf("write leveling is failed! \n");
        return -1;
    }

    printf("DDR3 configuration is done! \n");
    return 0;
}



ddr3_p.h

Best regards,

Hidehiko

  • Hi experts,

    Could you please comment ?

    Best regards,

    Hidehiko

  • Hi Hidehiko,

    Just to confirm, is the 30 seconds only coming from the DDR initialization, or is this the total time for the device to boot the custom application?

    For the boards which this issue occurs on, does the issue occur 100% of the time?

    Which CPU is executing this code? Are you able to confirm  that the PLL for the CPU is locked at the correct frequency? I see in the code there is a loop to add delay. If the CPU PLL did not lock and is stuck in a bypass mode, then that could possibly explain the increase in time. You might try reducing this loop count to see if that has any impact.

    //(0x34) instead
    //Wait for min 1048576 DDR clock cycles for leveling to complete = 1048576 * 1.5ns = 1572864ns = 1.57ms.
    //Actual time = ~10-15 ms
    //for(i=0; i<15*200000; i++)
    for(i=0; i<15*250000; i++) // ADD test_w
    asm(" nop 5");

    Thanks,
    Kevin

  • Hello Kevin,

    Thank you for your support.

    I reply below.

    >Just to confirm,
    >is the 30 seconds only coming from the DDR initialization,
    >or is this the total time for the device to boot the custom application?

    I'm sorry, it is the total time,
    acutally the below loop might take too long time.

    DDR3_TestMemory_s32  is 16MB memory R/W test (bit swap W/R)

    However only when a read value is equal to a write value, this test continues.
    If not, it exits this memory test and next DDR3_iniit1_s32() is called.

    			do
    			{
    				DDR3_Init1_s32();
    				ret = DDR3_TestMemory_s32();
    			}while(ret != 0);
    

    >For the boards which this issue occurs on, does the issue occur 100% of the time?

    Repuroduce ratio depends on the boards.

    We produceted 20 boards recently.
    10 boards (/20) which have this issue.
    The reproduce ratio is 20 - 30%.


    >Which CPU is executing this code?

    CPU1

    > Are you able to confirm that the PLL for the CPU is locked at the correct frequency?

    Unfortunately it is not easy for us to measure it correctly with a oscilloscope.
    And we configure PLL before the auto leveling loop (do - while(ret != 0)) like below.

    1250kHz, (input 100MHz clock)

    following is extracted setting

    + PLL Secondary Control Register (SECCTL) (in sprugv2i 4.3
    CSL_PllcRegs * pllc_regs = (CSL_PllcRegs * )0x02310000; // CSL_PLL_CONTROLLER_REGS is not usable
    temp_u32 = pllc_regs->SECCTL & 0x00800000U; /* Check the Bit 23 value */
    -> temp_u32 = 0

    + PLL Multiplier Control Register (PLLM) (in sprugv2i 4.4)
    PLLM_u32=24
    pllc_regs->PLLM = (PLLM_u32 & 0x0000003FU); /* bits[5:0] */

    + Main PLL Control Register (MAINPLLCTL0) (in SPRS814D 6.6.3)
    #define CSL_BOOT_CFG_REGS (0x02620000)
    CSL_BootcfgRegs * boot_cfg_regs = (CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS;
    PLLD_u32=0
    boot_cfg_regs->CORE_PLL_CTL0 &= ~(0x0000003FU); /* Clear the Field */
    boot_cfg_regs->CORE_PLL_CTL0 |= (PLLD_u32 & 0x0000003FU);

    > I see in the code there is a loop to add delay.
    > If the CPU PLL did not lock and is stuck in a bypass mode,
    > then that could possibly explain the increase in time.
    > You might try reducing this loop count to see if that has any impact.

    Thank you for your comment.
    However they do not eliminate this issue whe we try.
    There is not different in two settings.

    ex)
    /////////for(i=0; i< 1000; i++)
    for(i=0; i< 1250; i++) // ADD test_w
    asm(" nop 5");

    //for(i=0; i< 600*200; i++)
    for(i=0; i< 750*200; i++) // ADD test_w

    ....

    Best regards,

    Hidehiko

  • Hello Kevin,

    Could you please comment about our try ?

    What's parameters we investigate more ?

    Best regards,

    Hidehiko

  • Hi,

    Since the 30 seconds is the total time, do we know how much of this is related to the DDR initialization? How does this compare to a "good" system? Is it possible to profile individual sections of the entire boot procedure to understand where the increase is coming from?

    Thanks,
    Kevin

  • Hi Kevin,

    Thank you for your comment.

    >Since the 30 seconds is the total time,
    >do we know how much of this is related to the DDR initialization?

    			do
    			{
    				DDR3_Init1_s32();
    				ret = DDR3_TestMemory_s32();
    			}while(ret != 0);
    

    This section which auto leveling process for DDR
    is related with too long time cases.

    a) DDR3_Init1_s32(): Using partial automatic leveling process
    b) DDR3_TestMemory_s32(): 16MB memory R/W test (bit swap W/R)

    Until b) test success, this loop continues.

    We inserted two functions in my 1st commnet.


    >How does this compare to a "good" system?
    >Is it possible to profile individual sections of the entire boot procedure
    >to understand where the increase is coming from?

    We have already tried to check each sections on our boot procedures
    and we found that this loop time increasd when "bad" boot problem happened
    Therefore we would like to know why auto leveling sometimes needs many leveling.
    ・What parameters is not proper for auto leveling ?
    ・How we should improve the worst case time of auto leveling.

    Could you please commnet ?

    This products were designed in 6 years ago.
    This problem was reported in th last 20 products (we have producted more than 300 boards).
    Therefore we have suspected DDR parts (quality, product number, and so on).

    However we expect that we avoid this problem to improve auto leveling time.


    Best regards,
    Hidehiko

  • Hidehiko,

    This may be due to PCB soldering issues.  Can you reflow a handful of the boards to see if the problem reduces or goes away?

    Thanks,

    Kyle

  • Hi Kyle,

    Thank you for your comment.

    >Can you reflow a handful of the boards to see if the problem reduces or goes away?

    We'll discuss with our product team.

    And could you please provide information if possible ?

     We need to know how we improved auto leveling process time 
    ・What parameters is not proper for auto leveling ?

    We attached "INT32 DDR3_Init1_s32 (void)" code in this issue.

    Could you let us know anything you find  in code when you read it ?

    Best regards,

    Hidehiko

  • Hello Hidehiko-san,

    Can you point to the code attachment.  I don't see the upload.

    Regards,

    Kyle

  • Hello, Kyle-san,

    >Can you point to the code attachment.  I don't see the upload.

    I attached ddr3.c.

    2548.ddr3.c
    /*""FILE COMMENT""**************************************************************
    ***  ModuleName :   ddr3
    ***  Contents   :   Source File
    ***  Note       :   for setting system PLL 
    ********************************************************************************
    ***  COPYRIGHT(C) Myway Plus Corporation
    ********************************************************************************
    ***""FILE COMMENT END""********************************************************/
    
    /*""FILE INCLUDE""*************************************************************/
    #include    "ddr3_p.h"
    
    //#include	"csl_emif4f.h"
    //#include	"csl_bootcfgAux.h"
    
    /*""FILE INCLUDE END""*********************************************************/
    
    
    /*""Function Define""**********************************************************/
    INT32 DDR3_TestMemory_s32(void)
    {
    #if 0
        UINT32 index_u32, value_u32;
    
        printf ( "DDR3 memory test... Started. \n" );
    
        /* Write a pattern */
        for (index_u32 = DDR3_TEST_START_ADDRESS; index_u32 < DDR3_TEST_END_ADDRESS; index_u32 += 4) {
            *(UINT32 *)index_u32 = index_u32;
        }
    
        /* Read and check the pattern */
        for (index_u32 = DDR3_TEST_START_ADDRESS; index_u32 < DDR3_TEST_END_ADDRESS; index_u32 += 4) {
    
            value_u32 = *(UINT32 *)index_u32;
    
            if (value_u32  != index_u32) {
                printf ( "DDR3 memory test... Failed. \n" );
                return -1;
            }
        }
    
        /* Write a pattern for complementary values */
        for (index_u32 = DDR3_TEST_START_ADDRESS; index_u32 < DDR3_TEST_END_ADDRESS; index_u32 += 4) {
            *(UINT32 *)index_u32 = ~index_u32;
        }
    
        /* Read and check the pattern */
        for (index_u32 = DDR3_TEST_START_ADDRESS; index_u32 < DDR3_TEST_END_ADDRESS; index_u32 += 4) {
    
            value_u32 = *(UINT32 *)index_u32;
    
            if (value_u32  != ~index_u32) {
                printf ( "DDR3 memory test... Failed. \n" );
                return -1;
            }
        }
    
    #else
        UINT32 *pWork = (UINT32 *)DDR3_TEST_START_ADDRESS; //point to start of DDR3
        UINT32 u32Tmp;
        BOOL bError = FALSE;
    
        printf ( "DDR3 memory test... Started. \n" );
    
        while (pWork < (UINT32 *)DDR3_TEST_END_ADDRESS)
        {
            *pWork = u32Tmp = ~(*pWork);
            if (u32Tmp != *pWork)
            {
                bError = TRUE;
                break;
            }
            pWork += 0x1;
        }
    
        if (bError == TRUE)
        {
            printf("DDR3 memory test... Failed. \n");
            return -1;
        }
    
    #endif
    
        printf ( "DDR3 memory test... Passed. \n" );
        return 0;
    }
    
    
    INT32 DDR3_Init_s32 (void)
    {
    	INT32 i;
    	
    	printf("DDR3 Configuration... \n");
    	
        /*Unlock Boot Config*/
        CSL_BootCfgUnlockKicker();
    	
        /* Wait for PLL to lock = min 500 ref clock cycles. 
           With refclk = 100MHz, = 5000 ns = 5us */
        for(i=0; i< 1000; i++)
            asm(" nop 5");
    	
        /***************** 3.2 DDR3 PLL Configuration ************/
        /* Done before */
    
        /**************** 3.0 Leveling Register Configuration ********************/
        /* Using partial automatic leveling due to errata */
        
        /**************** 3.3 Leveling register configuration ********************/
    	boot_cfg_regs->DDR3_CONFIG_REG[0] &= ~(0x007FE000U);  // clear ctrl_slave_ratio field
    	boot_cfg_regs->DDR3_CONFIG_REG[0] |= 0x00200000U;     // set ctrl_slave_ratio to 0x100
    	boot_cfg_regs->DDR3_CONFIG_REG[12] |= 0x08000000U;    // Set invert_clkout = 1
        boot_cfg_regs->DDR3_CONFIG_REG[0] |= 0xFU;            // set dll_lock_diff to 15
    
        //From 4.2.1 Executing Partial Automatic Leveling -- Start
        boot_cfg_regs->DDR3_CONFIG_REG[23] |= 0x00000200U;    //Set bit 9 = 1 to use forced ratio leveling for read DQS
        //From 4.2.1 Executing Partial Automatic Leveling -- End
    
        //Values with invertclkout = 1
        /**************** 3.3 Partial Automatic Leveling ********************/
        
    	/*WRLVL_INIT_RATIO*/
    	boot_cfg_regs->DDR3_CONFIG_REG[2] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[3] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[4] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[5] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[6] = 0x5CU;
    	boot_cfg_regs->DDR3_CONFIG_REG[7] = 0x5BU;
    	boot_cfg_regs->DDR3_CONFIG_REG[8] = 0x63U;
    	boot_cfg_regs->DDR3_CONFIG_REG[9] = 0x5AU;
    	boot_cfg_regs->DDR3_CONFIG_REG[10] = 0x00U;
    	
    	/*GTLVL_INIT_RATIO*/
    	boot_cfg_regs->DDR3_CONFIG_REG[14] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[15] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[16] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[17] = 0x00U;
    	boot_cfg_regs->DDR3_CONFIG_REG[18] = 0xACU;
    	boot_cfg_regs->DDR3_CONFIG_REG[19] = 0xADU;
    	boot_cfg_regs->DDR3_CONFIG_REG[20] = 0xA5U;
    	boot_cfg_regs->DDR3_CONFIG_REG[21] = 0xAFU;
    	boot_cfg_regs->DDR3_CONFIG_REG[22] = 0x00U;
    
        //Do a PHY reset. Toggle DDR_PHY_CTRL_1 bit 15 0->1->0
    	DDR_Regs->DDR_PHY_CTRL_1 &= ~(0x00008000U);
    	DDR_Regs->DDR_PHY_CTRL_1 |= (0x00008000U);
    	DDR_Regs->DDR_PHY_CTRL_1 &= ~(0x00008000U);
    
        /***************** 3.4 Basic Controller and DRAM Configuration ************/
    
    	DDR_Regs->SDRAM_REF_CTRL = 0x10005161U;    // enable configuration
        
    	DDR_Regs->SDRAM_TIM_1 = 0x11137834U;
    	DDR_Regs->SDRAM_TIM_2 = 0x30717FE3U;
    	DDR_Regs->SDRAM_TIM_3 = 0x559F86AFU;
    	
        DDR_Regs->DDR_PHY_CTRL_1  = 0x0010010FU;
        DDR_Regs->ZQ_CONFIG    = 0x70074c1fU;
        DDR_Regs->PWR_MGMT_CTRL    = 0x0U;
    	
    	DDR_Regs->SDRAM_CONFIG = 0x634272B0U;
    	
        //Wait 600us for HW init to complete
        for(i=0; i< 600*200; i++)
            asm(" nop 5");
    
        DDR_Regs->SDRAM_REF_CTRL    = 0x10001458U;       //Refresh rate = (7.8*666MHz)
    
        /**************** 4.2.1 Executing Partial Automatic Leveling ********************/
    
        DDR_Regs->RDWR_LVL_RMP_CTRL = 0x80000000; //enable full leveling
    
        DDR_Regs->RDWR_LVL_CTRL = 0x80000000; //Trigger full leveling - This ignores read DQS leveling result and uses ratio forced value  
    
        //(0x34) instead
        //Wait for min 1048576 DDR clock cycles for leveling to complete = 1048576 * 1.5ns = 1572864ns = 1.57ms.
        //Actual time = ~10-15 ms
        for(i=0; i<15*200000; i++)
            asm(" nop 5");
        i=0;
        while ((DDR_Regs->STATUS & 0x00000070U) && (i<0xf)) {
            i++;
            asm(" nop 5");
            if (i>3000000){ break; }
        }
        
        // Lock the kicker mechanism
        CSL_BootCfgLockKicker();
        
        if (i>3000000)
        {
            printf("write leveling is failed! \n");
            return -1;
        }
    
        printf("DDR3 configuration is done! \n");
        return 0;
    }
    
    INT32 DDR3_Init1_s32 (void)
    {
    	INT32 i;
    	UINT32 TEMP;
    
    	printf("DDR3 Configuration... \n");
    
        /*Unlock Boot Config*/
        CSL_BootCfgUnlockKicker();
    
        /* Wait for PLL to lock = min 500 ref clock cycles.
           With refclk = 100MHz, = 5000 ns = 5us */
        for(i=0; i< 1000; i++)
            asm(" nop 5");
    
        /***************** 3.2 DDR3 PLL Configuration ************/
        /* Done before */
    
        /**************** 3.0 Leveling Register Configuration ********************/
        /* Using partial automatic leveling due to errata */
    
        /**************** 3.3 Leveling register configuration ********************/
    	boot_cfg_regs->DDR3_CONFIG_REG[0] &= ~(0x007FE000U);  // clear ctrl_slave_ratio field
    	boot_cfg_regs->DDR3_CONFIG_REG[0] |= 0x00200000U;     // set ctrl_slave_ratio to 0x100
    	boot_cfg_regs->DDR3_CONFIG_REG[12] |= 0x08000000U;    // Set invert_clkout = 1
        boot_cfg_regs->DDR3_CONFIG_REG[0] |= 0xFU;            // set dll_lock_diff to 15
    
        //From 4.2.1 Executing Partial Automatic Leveling -- Start
        boot_cfg_regs->DDR3_CONFIG_REG[52] |= 0x00000200U;    //Set bit 9 = 1 to use forced ratio leveling for read DQS
        boot_cfg_regs->DDR3_CONFIG_REG[53] |= 0x00000200U;
        boot_cfg_regs->DDR3_CONFIG_REG[54] |= 0x00000200U;
        boot_cfg_regs->DDR3_CONFIG_REG[55] |= 0x00000200U;
        boot_cfg_regs->DDR3_CONFIG_REG[60] |= 0x00000200U;
        //From 4.2.1 Executing Partial Automatic Leveling -- End
    
        //Values with invertclkout = 1
        /**************** 3.3 Partial Automatic Leveling ********************/
    	/*WRLVL_INIT_RATIO*/
    	boot_cfg_regs->DDR3_CONFIG_REG[2] = 0x5DU;
    	boot_cfg_regs->DDR3_CONFIG_REG[3] = 0x5CU;
    	boot_cfg_regs->DDR3_CONFIG_REG[4] = 0x51U;
    	boot_cfg_regs->DDR3_CONFIG_REG[5] = 0x48U;
    	boot_cfg_regs->DDR3_CONFIG_REG[8] = 0x00U;
    
    	/*GTLVL_INIT_RATIO*/
    	boot_cfg_regs->DDR3_CONFIG_REG[14] = 0xADU;
    	boot_cfg_regs->DDR3_CONFIG_REG[15] = 0xAEU;
    	boot_cfg_regs->DDR3_CONFIG_REG[16] = 0x93U;
    	boot_cfg_regs->DDR3_CONFIG_REG[17] = 0x9DU;
    	boot_cfg_regs->DDR3_CONFIG_REG[22] = 0x00U;
    
        //Do a PHY reset. Toggle DDR_PHY_CTRL_1 bit 15 0->1->0
    	DDR_Regs->DDR_PHY_CTRL_1 &= ~(0x00008000U);
    	DDR_Regs->DDR_PHY_CTRL_1 |= (0x00008000U);
    	DDR_Regs->DDR_PHY_CTRL_1 &= ~(0x00008000U);
    
        /***************** 3.4 Basic Controller and DRAM Configuration ************/
    
    	DDR_Regs->SDRAM_REF_CTRL = 0x00005161U;    // enable configuration
    
        /* SDRAM_TIM_1 */
        TEMP = 0U;
        TEMP |= 0x08U << 25; // T_RP bit field 28:25
        TEMP |= 0x08U << 21; // T_RCD bit field 24:21
        TEMP |= 0x09U << 17; // T_WR bit field 20:17
        TEMP |= 0x17U << 12; // T_RAS bit field 16:12
        TEMP |= 0x20U << 6; // T_RC bit field 11:6
        TEMP |= 0x7U << 3; // T_RRD bit field 5:3
        TEMP |= 0x4U; // T_WTR bit field 2:0
        DDR_Regs->SDRAM_TIM_1 = TEMP;
    
        /* SDRAM_TIM_2 */
        TEMP = 0U;
        TEMP |= 0x3U << 28; // T_XP bit field 30:28
        TEMP |= 0x71U << 16; // T_XSNR bit field 24:16
        TEMP |= 0x1ffU << 6; // T_XSRD bit field 15:6
        TEMP |= 0x4U << 3; // T_RTP bit field 5:3
        TEMP |= 0x3U; // T_CKE bit field 2:0
        DDR_Regs->SDRAM_TIM_2 = TEMP;
    
        /* SDRAM_TIM_3 */
        TEMP = 0U;
        TEMP |= 0x5U << 28; // T_PDLL_UL bit field 31:28 (fixed value)
        TEMP |= 0x5U << 24; // T_CSTA bit field 27:24 (fixed value)
        TEMP |= 0x4U << 21; // T_CKESR bit field 23:21
        TEMP |= 0x3fU << 15; // T_ZQCS bit field 20:15
        TEMP |= 0x6AU << 4; // T_RFC bit field 12:4
        TEMP |= 0xfU; // T_RAS_MAX bit field 3:0 (fixed value)
        DDR_Regs->SDRAM_TIM_3 = TEMP;
    
        DDR_Regs->DDR_PHY_CTRL_1  = 0x0010010FU;
        DDR_Regs->ZQ_CONFIG    = 0x70073214U;
        DDR_Regs->PWR_MGMT_CTRL    = 0x0U;
    
        DDR_Regs->SDRAM_REF_CTRL = 0x00005161U;    // enable configuration
    
        /* DDR_SDCFG */
        /* New value with DYN_ODT disabled and SDRAM_DRIVE = RZQ/7 //0x63222A32;    // last config write DRAM init occurs */
        TEMP = 0U;
        TEMP |= 0x3U << 29; // SDRAM_TYPE bit field 31:29 (fixed value)
        TEMP |= 0x0U << 27; // IBANK_POS bit field 28:27
        TEMP |= 0x3U << 24; // DDR_TERM bit field 26:24
        TEMP |= 0x0U << 21; // DYN_ODT bit field 22:21
        TEMP |= 0x0U << 18; // SDRAM_DRIVE bit field 19:18
        TEMP |= 0x2U << 16; // CWL bit field 17:16
        TEMP |= 0x1U << 14; // NM bit field 15:14
        TEMP |= 0xAU << 10; // CL bit field 13:10
        TEMP |= 0x5U << 7; // ROWSIZE bit field 9:7
        TEMP |= 0x3U << 4; // IBANK bit field 6:4
        TEMP |= 0x0U << 3; // EBANK bit field 3:3
        TEMP |= 0x2U; // PAGESIZE bit field 2:0
        DDR_Regs->SDRAM_CONFIG = TEMP;
    
        //Wait 600us for HW init to complete
        for(i=0; i< 600*200; i++)
            asm(" nop 5");
    
        DDR_Regs->SDRAM_REF_CTRL    = 0x00001458U;       //Refresh rate = (7.8*666MHz)
    
        /**************** 4.2.1 Executing Partial Automatic Leveling ********************/
    
        DDR_Regs->RDWR_LVL_RMP_CTRL = 0x80000000U; //enable full leveling
    
        DDR_Regs->RDWR_LVL_CTRL = 0x80000000U; //Trigger full leveling - This ignores read DQS leveling result and uses ratio forced value
    
        //(0x34) instead
        //Wait for min 1048576 DDR clock cycles for leveling to complete = 1048576 * 1.5ns = 1572864ns = 1.57ms.
        //Actual time = ~10-15 ms
        for(i=0; i<15*200000; i++)
            asm(" nop 5");
        i=0;
        while ((DDR_Regs->STATUS & 0x00000070U) && (i<0xf)) {
            i++;
            asm(" nop 5");
            if (i>3000000){ break; }
        }
    
        // Lock the kicker mechanism
        CSL_BootCfgLockKicker();
    
        if (i>3000000)
        {
            printf("write leveling is failed! \n");
            return -1;
        }
    
        printf("DDR3 configuration is done! \n");
        return 0;
    }
    
    
    
    
    #if 0
    #define	uint32_t unsigned int
    #define	uint8_t unsigned char
    
    /* Set the desired DDR3 configuration -- assumes 66.67 MHz DDR3 clock input */
    int DDR3Init_s32(void)
    {
    
        CSL_Status status = CSL_SOK;
        volatile unsigned int loopCount;
        uint32_t ddr3config, ddrPhyCtrl;
        uint8_t ddrPHYReadLatency;
        EMIF4F_TIMING1_CONFIG sdram_tim1;
        EMIF4F_TIMING2_CONFIG sdram_tim2;
        EMIF4F_TIMING3_CONFIG sdram_tim3;
        EMIF4F_OUTPUT_IMP_CONFIG    zqcfg;
        EMIF4F_PWR_MGMT_CONFIG      pwrmgmtcfg;
        EMIF4F_SDRAM_CONFIG         sdramcfg;
    
        CSL_BootCfgUnlockKicker();
    
        /* Wait for PLL to lock = min 500 ref clock cycles.
           With refclk = 100MHz, = 5000 ns = 5us */
        platform_delaycycles(50000);
    
        /**************** 3.3 Leveling Register Configuration ********************/
        CSL_BootCfgGetDDRConfig(0, &ddr3config);
        ddr3config &= ~(0x007FE000);  // clear ctrl_slave_ratio field
        CSL_BootCfgSetDDRConfig(0, ddr3config);
    
        CSL_BootCfgGetDDRConfig(0, &ddr3config);
        ddr3config |= 0x00200000;     // set ctrl_slave_ratio to 0x100
        CSL_BootCfgSetDDRConfig(0, ddr3config);
    
        CSL_BootCfgGetDDRConfig(12, &ddr3config);
        ddr3config |= 0x08000000;    // Set invert_clkout = 1
        CSL_BootCfgSetDDRConfig(12, ddr3config);
    
        CSL_BootCfgGetDDRConfig(0, &ddr3config);
        ddr3config |= 0xF;            // set dll_lock_diff to 15
        CSL_BootCfgSetDDRConfig(0, ddr3config);
    
        CSL_BootCfgGetDDRConfig(23, &ddr3config);
        ddr3config |= 0x00000200;    // See section 4.2.1, set for partial automatic levelling
        CSL_BootCfgSetDDRConfig(23, ddr3config);
    
        /**************** 3.3 Partial Automatic Leveling ********************/
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(2,  ddr3config);
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(3,  ddr3config);
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(4,  ddr3config);
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(5,  ddr3config);
        ddr3config = 0x00000033;  CSL_BootCfgSetDDRConfig(6,  ddr3config);
        ddr3config = 0x0000003A;  CSL_BootCfgSetDDRConfig(7,  ddr3config);
        ddr3config = 0x0000002C;  CSL_BootCfgSetDDRConfig(8,  ddr3config);
        ddr3config = 0x0000002C;  CSL_BootCfgSetDDRConfig(9,  ddr3config);
        ddr3config = 0x0000001C;  CSL_BootCfgSetDDRConfig(10, ddr3config);
    
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(14,  ddr3config);
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(15,  ddr3config);
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(16,  ddr3config);
        ddr3config = 0x00;        CSL_BootCfgSetDDRConfig(17,  ddr3config);
        ddr3config = 0x000000B7;  CSL_BootCfgSetDDRConfig(18,  ddr3config);
        ddr3config = 0x000000B1;  CSL_BootCfgSetDDRConfig(19,  ddr3config);
        ddr3config = 0x000000A4;  CSL_BootCfgSetDDRConfig(20,  ddr3config);
        ddr3config = 0x000000A4;  CSL_BootCfgSetDDRConfig(21,  ddr3config);
        ddr3config = 0x00000098;  CSL_BootCfgSetDDRConfig(22,  ddr3config);
    
        /*Do a PHY reset. Toggle DDR_PHY_CTRL_1 bit 15 0->1->0 */
        CSL_EMIF4F_GetPhyControl(&ddrPhyCtrl, &ddrPHYReadLatency);
        ddrPhyCtrl &= ~(0x00008000);
        CSL_EMIF4F_SetPhyControl(ddrPhyCtrl,  ddrPHYReadLatency);
    
        CSL_EMIF4F_GetPhyControl(&ddrPhyCtrl, &ddrPHYReadLatency);
        ddrPhyCtrl |= (0x00008000);
        CSL_EMIF4F_SetPhyControl(ddrPhyCtrl,  ddrPHYReadLatency);
    
        CSL_EMIF4F_GetPhyControl(&ddrPhyCtrl, &ddrPHYReadLatency);
        ddrPhyCtrl &= ~(0x00008000);
        CSL_EMIF4F_SetPhyControl(ddrPhyCtrl,  ddrPHYReadLatency);
    
        /***************** 3.4 Basic Controller and DRAM configuration ************/
        /* enable configuration */
        /*    hEmif->SDRAM_REF_CTRL    = 0x00006180; */
        CSL_EMIF4F_EnableInitRefresh();
        CSL_EMIF4F_SetRefreshRate(0x515C);
    
        sdram_tim1.t_wtr    = 4;
        sdram_tim1.t_rrd    = 1;
        sdram_tim1.t_rc     = 0x20;
        sdram_tim1.t_ras    = 0x17;
        sdram_tim1.t_wr     = 0x09;
        sdram_tim1.t_rcd    = 0x09;
        sdram_tim1.t_rp     = 0x09;
        CSL_EMIF4F_SetTiming1Config(&sdram_tim1);
    
        /*    hEmif->SDRAM_TIM_2   = 0x40877FEC; */
        sdram_tim2.t_cke    = 3;
        sdram_tim2.t_rtp    = 4;
        sdram_tim2.t_xsrd   = 0x1FF;
        sdram_tim2.t_xsnr   = 0x071;
        sdram_tim2.t_xp     = 3;
        sdram_tim2.t_odt    = 0;
        CSL_EMIF4F_SetTiming2Config (&sdram_tim2);
    
        /*    hEmif->SDRAM_TIM_3   = 0x55BF87FF; */
        sdram_tim3.t_rasMax     = 0xF;
        sdram_tim3.t_rfc        = 0x06A;
        sdram_tim3.t_tdqsckmax  = 0;
        sdram_tim3.zq_zqcs      = 0x3F;
        sdram_tim3.t_ckesr      = 4;
        sdram_tim3.t_csta       = 0x5;
        sdram_tim3.t_pdll_ul    = 0x5;
        CSL_EMIF4F_SetTiming3Config (&sdram_tim3);
    
        /*    hEmif->DDR_PHY_CTRL_1   = 0x0010010F; */
        ddrPHYReadLatency   = 0x0F;
        ddrPhyCtrl          = (0x0010010F);
        CSL_EMIF4F_SetPhyControl(ddrPhyCtrl,  ddrPHYReadLatency);
    
        /*    hEmif->ZQ_CONFIG        = 0x70074C1F; */
        zqcfg.zqRefInterval     = 0x4C1F;
        zqcfg.zqZQCLMult        = 3;
        zqcfg.zqZQCLInterval    = 1;
        zqcfg.zqSFEXITEn        = 1;
        zqcfg.zqDualCSEn        = 1;
        zqcfg.zqCS0En           = 1;
        zqcfg.zqCS1En           = 0;
        CSL_EMIF4F_SetOutputImpedanceConfig(&zqcfg);
    
        /*    hEmif->PWR_MGMT_CTRL    = 0x0; */
        pwrmgmtcfg.csTime           = 0;
        pwrmgmtcfg.srTime           = 0;
        pwrmgmtcfg.lpMode           = 0;
        pwrmgmtcfg.dpdEnable        = 0;
        pwrmgmtcfg.pdTime           = 0;
        CSL_EMIF4F_SetPowerMgmtConfig  (&pwrmgmtcfg);
    
        /* New value with DYN_ODT disabled and SDRAM_DRIVE = RZQ/7 */
        /*    hEmif->SDRAM_CONFIG     = 0x63077AB3; */
        CSL_EMIF4F_GetSDRAMConfig (&sdramcfg);
        sdramcfg.pageSize           = 2;
        sdramcfg.eBank              = 0;
        sdramcfg.iBank              = 3;
        sdramcfg.rowSize            = 5;
        sdramcfg.CASLatency         = 14;
        sdramcfg.narrowMode         = 1;
        sdramcfg.CASWriteLat        = 3;
        sdramcfg.SDRAMDrive         = 1;
        sdramcfg.disableDLL         = 0;
        sdramcfg.dynODT             = 2;
        sdramcfg.ddrDDQS            = 0;
        sdramcfg.ddrTerm            = 2;
        sdramcfg.iBankPos           = 0;
        sdramcfg.type               = 3;
        CSL_EMIF4F_SetSDRAMConfig (&sdramcfg);
    
        pll_delay(840336); /*Wait 600us for HW init to complete*/
    
        /* Refresh rate = (7.8*666MHz] */
        /*    hEmif->SDRAM_REF_CTRL   = 0x00001450;     */
        CSL_EMIF4F_SetRefreshRate(0x0000144F);
    
        /***************** 4.2.1 Partial automatic leveling ************/
        /*    hEmif->RDWR_LVL_RMP_CTRL      =  0x80000000; */
        CSL_EMIF4F_SetLevelingRampControlInfo(1, 0, 0, 0, 0);
    
        /* Trigger full leveling - This ignores read DQS leveling result and uses ratio forced value */
        /*    hEmif->RDWR_LVL_CTRL          =  0x80000000; */
        CSL_EMIF4F_SetLevelingControlInfo(1, 0, 0, 0, 0);
    
        /************************************************************
          Wait for min 1048576 DDR clock cycles for leveling to complete
          = 1048576 * 1.5ns = 1572864ns = 1.57ms.
          Actual time = ~10-15 ms
         **************************************************************/
        pll_delay(4201680); //Wait 3ms for leveling to complete
    
        return (status);
    
    }
    
    #endif
    
    
    /*""Function Define END""******************************************************/
    
    /*******************************************************************************
        END OF FILE
    *******************************************************************************/
    

    			do
    			{
    				//DDR3_Init_s32();
    				DDR3_Init1_s32();
    				ret = DDR3_TestMemory_s32();
    			}while(ret != 0);
    

    We think that this loop can sometimes take too long time.

    Best regards,

    Hidehiko

  • Hello, Kyle-san,

    Could you let us know if you need our code ?

    Best regards,

    Hidehiko

  • Hidehiko-san,

    I don't see any obvious problems in the code that you have provided.  Have you tried to reflow/resolder the PCBs?

    Can you also try swapping a) DDR memories, and b) SoC from "good" PCBs to "bad" PCBs.  The swap should be done one at a time to id if the problem follows the SoC or the memory.

    Thanks,

    Kyle

  • Hello, Kyle-san,

    >I don't see any obvious problems in the code that you have provided.

    Thank you for  your comment.

    If you have an idea to try in software, could you let us know ?

    And I'm re-investigating our code, could let me ask a question if I find anything ?

    >Have you tried to reflow/resolder the PCBs?

    We changed DDR memories to DDR memory (High grade) on several bad PCBs

    but it did not eliminate this problem.

    And we tried to change some parts but it did not.

    This problem reproduces randomly on a boards.

    One day it reproduced easily, another day it did rarely.

    We suspect that it depends on temperature and

    test several PCBs with our constant temperature bath.

    As a result, it can reproduce high rate while temperature is changing (ex, 20 -> 5 deg, etc)

    We'll try to change DSP grade (0 to 85 -> -40to+100).

    Best regards,

    Hidehiko