Hi,
This is additional question to the original post.
https://e2e.ti.com/support/processors/f/791/p/877712/3333133#3333133
Customer had DDR3 data corruption issue on the 1st proto board.
We had some discussion and concluded there was leveling issue due to board layout.
Based on the discussion, customer modified the layout and now 2nd proto board is ready.
But the issue still persists and data corruption occurs at DDR3-1600 operation.
Please see attached excel sheet.
DDR3 Leveling waveforms.xlsx
- “Data corruption” sheet shows the symptom. DDR3 memory contents changed each time memory window is refreshed.
The issue is depending of DDR3 leveling results.
-“Waveform” sheet shows PHY registers in OK cases(no data corruption) and Failing cases.
When leveling is done properly, DX1LCDLR2 register value is around 0x3A and no data corruption is seen.
On the other hand, when the issue happens the register value is around 0x0D.
The sheet also shows waveforms under leveling in each cases. Leveling is done by GEL file (ddr3A_64bit_DDR1600_setup2()).
Customer found leveling takes longer time in failing cases compared to OK cases (see waveforms attached around AB38 cell)
/*----------------------------------------------------- DDR3A : DDR1600, 64bit,TEST--------------------------------------------------------------------------*/ ddr3A_64bit_DDR1600_setup2() { unsigned int multiplier = 39; unsigned int divider = 0; int temp,i, delay=1000; unsigned int OD_val = 10; KICK0 = 0x83E70B13; KICK1 = 0x95A4F1E0; //1. Poll for IDONE=1 in the PHY General Status Register 0 (address offset 0x010). do { read_val = DDR3A_PGSR0; } while ((read_val&0x00000001) != 0x00000001); // Clocks are enabled and frequency is stable--------------------------------------- // DDR3A PLL setup GEL_TextOut ( "DDR3 PLL Setup ... \n"); // DDR3APLLCTL0 = DDR3APLLCTL0 & 0xFF7FFFFF; // Set ENSAT = 1 DDR3APLLCTL1 |= 0x00000040; // Put the PLL in PLL Mode DDR3APLLCTL0 |= 0x00800000; // Program the necessary multipliers/dividers and BW adjustments // Set the divider values DDR3APLLCTL0 &= ~(0x0000003F); DDR3APLLCTL0 |= (divider & 0x0000003F); // Program OD[3:0] in the SECCTL register DDR3APLLCTL0 &= OUTPUT_DIVIDE_MASK; // clear the OD bit field DDR3APLLCTL0 |= ~OUTPUT_DIVIDE_MASK & (OD_val - 1) << OUTPUT_DIVIDE_OFFSET; // set the OD[3:0] bit field of PLLD to OD_val // Set the Multipler values DDR3APLLCTL0 &= ~(0x0007FFC0); DDR3APLLCTL0 |= ((multiplier << 6) & 0x0007FFC0 ); temp = ((multiplier + 1) >> 1) - 1; DDR3APLLCTL0 &= ~(0xFF000000); DDR3APLLCTL0 |= ((temp << 24) & 0xFF000000); DDR3APLLCTL1 &= ~(0x0000000F); DDR3APLLCTL1 |= ((temp >> 8) & 0x0000000F); // In PLL Controller, reset the PLL (bit 13 in DDR3APLLCTL1 register) DDR3APLLCTL1 |= 0x00004000; for(i=0;i<delay;i++); // In DDR3PLLCTL1, write PLLRST = 0 to bring PLL out of reset DDR3APLLCTL1 &= ~(0x00004000); for(i=0;i<delay;i++); // Put the PLL in PLL Mode DDR3APLLCTL0 &= ~(0x00800000); // ReSet the Bit 23 GEL_TextOut( "DDR3 PLL Setup complete, DDR3A clock now running at 800 MHz.\n" ); //DDR3A PLL setup complete --------------------------------------- /*------------------------------- ECO FIX -----------------------------------------*/ /*----------------------------- LEVELING FIX --------------------------------------*/ // DDR3 write leveling ECO - Assert & release DDR PHY RESET after DDR PLL setup... DDR3APLLCTL1 = DDR3APLLCTL1 | 0x80000000; //Assert DDR PHY reset after PLL enabled for(i=0;i<delay;i++); DDR3APLLCTL1 = DDR3APLLCTL1 & 0x7FFFFFFF; //Release DDR PHY reset do { // Poll IDONE after resetting PHY read_val = DDR3A_PGSR0; } while ((read_val&0x00000001) != 0x00000001); /*------------------------- Start PHY Configuration -------------------------------*/ //DDR3A_PGCR1 = 0x0280C487; //5.a Program FRQSEL in the PLL Control Register (address offset 0x018). DDR3A_PLLCR = 0x1C000; //Set FRQSEL=11 //5.b. Program WLSTEP=1, IODDRM=1, and ZCKSEL in the PHY General Configuration Register 1 (address offset 0x00C). DDR3A_PGCR1 |= (1 << 2); //WLSTEP = 1 DDR3A_PGCR1 &= ~(IODDRM_MASK); DDR3A_PGCR1 |= (( 1 << 7) & IODDRM_MASK); DDR3A_PGCR1 &= ~(ZCKSEL_MASK); DDR3A_PGCR1 |= (( 1 << 23) & ZCKSEL_MASK); //5.c. Program PHY Timing Parameters Register 0-4 (address offset 0x01C - 0x02C). DDR3A_PTR0 = 0x42C21590; DDR3A_PTR1 = 0xD05612C0; // Maintaining default values of Phy Timing Parameters Register 2 in PUB DDR3A_PTR3 = 0x0D861A80;//0x072515C2; //0x0B4515C2;//0x18061A80; DDR3A_PTR4 = 0x0C827100;//0x0AAE7100; //5.d. Program PDQ, MPRDQ, and BYTEMASK in the DRAM Configuration Register (address offset 0x044). // All other fields must be left at their default values. DDR3A_DCR &= ~(PDQ_MASK); //PDQ = 0 DDR3A_DCR &= ~(MPRDQ_MASK); //MPRDQ = 0 DDR3A_DCR &= ~(BYTEMASK_MASK); DDR3A_DCR |= (( 1 << 10) & BYTEMASK_MASK); //Uncomment for Dual Rank, Address Mirrored DIMMS //DDR3A_DCR &= ~(NOSRA_MASK); //DDR3A_DCR |= (( 1 << 27) & NOSRA_MASK); //DDR3A_DCR &= ~(UDIMM_MASK); //DDR3A_DCR |= (( 1 << 29) & UDIMM_MASK); //5.e. Program DRAM Timing Parameters Register 0-2 (address offset 0x048 - 0x050). DDR3A_DTPR0 = 0x9D9CBB66; DDR3A_DTPR1 = 0x32868400; DDR3A_DTPR2 = 0x5002D200; //5.f. Program BL=0, CL, WR, and PD=1 in the Mode Register 0 (address offset 0x054). //All other fields must be left at their default values. DDR3A_MR0 = 0x00001C70; //50 //5.g. Program DIC, RTT, and TDQS in the Mode Register 1 (address offset 0x058). //All other fields must be left at their default values. DDR3A_MR1 = 0x00000006; //--------------------------------------------------------------------------------------------------------- //5.h. Program Mode Register 2 (address offset 0x05C). // Maintaining default values of Program Mode Register 2 DDR3A_MR2 = 0x00000018; //5.i. Program DTMPR=1, DTEXD, DTEXG, RANKEN=1 or 3, and RFSHDT=7 in the Data Training Configuration Register (address offset 0x068). //All other fields must be left at their default values. DDR3A_DTCR = 0x710035C7; //Single-Rank //DDR3A_DTCR = 0x730035C7; //Dual-Rank //5.j. Program tREFPRD=(5*tREFI/ddr_clk_period) in the PHY General Configuration Register 2 (address offset 0x08C). //All other fields must be left at their default values. DDR3A_PGCR2 = 0x00F079E0; //Set Impedence Register DDR3A_ZQ0CR1 = 0x0001005D; DDR3A_ZQ1CR1 = 0x0001005B; DDR3A_ZQ2CR1 = 0x0001005B; //DDR3A_ZQ3CR1 = 0x0000005D; //6. Re-trigger PHY initialization in DDR PHY through the VBUSP interface. //6.a. Program 0x00000033 to the PHY Initialization Register (address offset 0x004) to re-trigger PLL, ZCAL, and DCAL initialization. DDR3A_PIR = 0x00000033; //6.b. Poll for IDONE=1 in the PHY General Status Register 0 (address offset 0x010). do { read_val = DDR3A_PGSR0; } while ((read_val&0x00000001) != 0x00000001); //--------------------------------------------------------------------------------------------------------- // 7. Trigger DDR3 initialization and leveling/training in DDR PHY through the VBUSP interface. // a. If using a 16-bit wide DDR interface, program DXEN=0 in the DATX8 2-7 General Configuration Registers (address offsets 0x240, 0x280, 0x2C0, 0x300, 0x340, and 0x380) to disable the leveling/training for the upper byte lanes. // b. If using a 32-bit wide DDR interface, program DXEN=0 in the DATX8 4-7 General Configuration Registers (address offsets 0x2C0, 0x300, 0x340, and 0x380) to disable the leveling/training for the upper byte lanes. // c. If ECC is not required, program DXEN=0 in the DATX8 8 General Configuration Register (address offset 0x3C0) to disable the leveling/training for the ECC byte lane. // NOTE: Setup supports 64-bit by default, ECC enable by default. //7.d. Program 0x0000XF81 to the PHY Initialization Register (address offset 0x004) to trigger DDR3 initialization and leveling/training sequences DDR3A_PIR = 0x0000FF81; //WLADJ - ON //DDR3A_PIR = 0x00000781; //WLADJ - OFF //--------------------------------------------------------------------------------------------------------- //7.e. Poll for IDONE=1 in the PHY General Status Register 0 (address offset 0x010). do { read_val = DDR3A_PGSR0; } while ((read_val&0x00000001) != 0x00000001); /* End PHY Configuration */ //--------------------------------------------------------------------------------------------------------- /* START EMIF INITIALIZATION ++++++++++++++++++SDCFG Register Calculation+++++++++++++++++++ | 31 - 29 | 28 |27 - 25 | 24 | 23 - 22| 21 - 17 | |SDRAM_TYPE|Rsvd|DDR_TERM| DDQS | DYN_ODT| Rsvd | | 0x011 | 0 | 0x001 | 0x0 | 0x00 | 0x0 | | 16-14 |13 - 12 | 11 - 8 | 7 |6 - 5 | 4 | 3 | 2 | 1 - 0 | | CWL | NM | CL | Rsvd |IBANK | Rsvd|EBANK| Rsvd|PAGE_SIZE| | 0x11 | 0x00 | 0x1110 | 0x0 | 0x110| 0x0 | 0 | 0 | 0x10 | SDCFG = 0x0110 0011 0010 0010 0011 0011 1011 0010 SDCFG = 0x6200CE62; SDRAM_TYPE = 3 DDR_TERM = 3 (RZQ/4 = 1; RZQ/6=3) DDQS = 1 DYN_ODT = 0 CWL = 3 (CWL5=0; CWL6=1; CWL7=2; CWL8=3) NM = 0 (64-bit=0, 32-bit=1, 16-bit=2) CL = 14 (CL5=2; CL6=4; CL7=6; CL8=8; CL9=10; CL10=12; CL11=14) IBANK = 3 (8bank) EBANK = 0 (0 - pad_cs_o_n[0] , 1 - pad_cs_o_n[1:0]) PAGE_SIZE = 2 (1024page-size=2; 2048page-size=3) */ /* Start DDR3A EMIF Configuration */ //8. Configure the EMIF through the VBUSM interface. //8.a. Program all EMIF MMR<92>s. DDR3A_SDCFG = 0x6200CE62; // Single-Rank //DDR3A_SDCFG = 0x6200CE6A; // Dual-Rank DDR3A_SDTIM1 = 0x166C9875; DDR3A_SDTIM2 = 0x00001D4A; DDR3A_SDTIM3 = 0x435DFF53; DDR3A_SDTIM4 = 0x543F0CFF; DDR3A_ZQCFG = 0x70073200; // Single-Rank //DDR3A_ZQCFG = 0xF0073200; // Dual-Rank //8.b. Program reg_initref_dis=0 in the SDRAM Refresh Control Register (address offset 0x10). DDR3A_SDRFC = 0x00001860; GEL_TextOut("DDR3A initialization complete \n"); /* End DDR3A EMIF Configuration */ }
Customer checked waveforms in details (see column AO or later).
Sequential reads(0,1,0,1,0…) in leveling steps take longer time in failing cases.
As a result, read timings are different. (see waveforms around BL87 cell)
- Customer compared waveforms with EVMK2H. See “Comparing with EVMK2H” sheet.
On EVMK2H, the sequential reads takes less time.
And DQS line release timing is earlier in read access. This is similar in OK cases on customer board.
In failing case, DQS line is released just before read access.
Customer checked DQS-DQ timings on both boards, but no clear differences are seen.(Column AL and later)
Customer gets stuck and need TI help for further investigation to solve this issue.
Could you check the leveling waveform and provide your feedback?
Raw data (*.csv format) are available to send in separate e-mail. (see “Raw data” sheet for waveform information)
Customer can provide *.wfm format, if you have an environment to see keysight oscilloscope data.
Thanks and regards,
Koichiro Tashiro