Hi experts,
We have developed a custom board in 8 years ago.
We really appericated your support like you.
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.
.
/*""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; }
Best regards,
Hidehiko