能否共享一下现成的DDR3的初始化函数,替代GEL
我们的开发板和TCI6638的评估板均可以使用安装文件自带的GEL,
将GEL文件中的程序抽出来写成函数运行,但是运行后,实际是有问题的
具体的是访问DDR3的内存,访问DDR3EMIF寄存器内存,都无法访问
可以访问DDR3 PHY寄存器内,比对用函数和GEL后的差别,在偏移值0x10(PGSR0)有差别,错误的时候0x81C001FB,正确的时候是0x800000FFF;
能否提供一个现成的初始化函数?
先谢谢各位大神了!
附上错误的函数,是从GEL文件xtcievmk2x.gel 剥离的,寄存器地址宏定义完全取自这个GEL文件,
void ddr3A_32bit_DDR1333_setup() ;
void ddr3B_64bit_DDR1600_setup();
ddr3A_32bit_DDR1333_setup()
{
unsigned int multiplier = 19;
unsigned int divider = 0;
int temp;
unsigned int OD_val = 6;
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);
//4. Clocks are enabled and frequency is stable—————————————
//DDR3A PLL setup
GEL_TextOut ( "DDR3 PLL (PLL2) Setup … \n");
//DDR3APLLCTL0 = DDR3APLLCTL0 & 0xFF7FFFFF;
// Set ENSAT = 1
DDR3APLLCTL1 |= 0x00000040;
// Put the PLL in PLL Mode DDR3APLLCTL0 |= 0x00800000;
// In PLL Controller, reset the PLL (bit 13 in DDR3APLLCTL1 register) DDR3APLLCTL1 |= 0x00002000;
// Program the necessary multipliers/dividers and BW adjustments // Set the divider values DDR3APLLCTL0 &= ~(0x0000003F);
DDR3APLLCTL0 |= (divider & 0x0000003F);
/* Step 7: Programming 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 DDR3PLLCTL1, write PLLRST = 0 to bring PLL out of reset DDR3APLLCTL1 &= ~(0x00002000);
// Put the PLL in PLL Mode DDR3APLLCTL0 &= ~(0x00800000); // ReSet the Bit 23
GEL_TextOut( "DDR3 PLL Setup complete, DDR3A clock now running at 666 MHz.\n" );
//DDR3A PLL setup complete —————————————
/*————————- Start PHY Configuration ——————————-*/
//DDR3A_PGCR1 = 0x0280C487;
//5.a Program FRQSEL in the PLL Control Register (address offset 0x018).
DDR3A_PLLCR = 0x5C000; //Set FRQSEL=11, for ctl_clk between 166-275MHz
//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 = 0x0B4515C2;//0x072515C2; //0x0B4515C2;//0x18061A80;
DDR3A_PTR4 = 0x0A6E08B4;//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);
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 = 0x8558AA75;//0x85589975;//0x8558AA55;
DDR3A_DTPR1 = 0x12857280;//0x12835A80;//0x12857280;
DDR3A_DTPR2 = 0x5002C200;
//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 = 0x00001A60; //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 = 0x00000010;
//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; //0x730035C7;
//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 = 0x00F065B8; //NOBUB = 0, FXDLAT = 0
//DDR3A_PGCR2 = 0x00F83D09; //NOBUB = 0, FXDLAT = 1
//Set Impedence Register
DDR3A_ZQ0CR1 = 0x0000005D;DDR3A_ZQ1CR1 = 0x0000005B;
DDR3A_ZQ2CR1 = 0x0000005B;
//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 | 0x011 | 0x1 | 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 | 0x11 | 0x0 | 0 | 0 | 0x10 |
SDCFG = 0x0110 0011 0010 0010 0011 0011 1011 0010
SDCFG = 0x6700486A;//0x63223332
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抯.
DDR3A_SDCFG = 0x62009C62; // 9A62//0x62008C62 ;//0x6600CE62=single rank,0x6600CE6A=dual rank
DDR3A_SDTIM1 = 0x125C8044;
DDR3A_SDTIM2 = 0x00001D29;
DDR3A_SDTIM3 = 0x32CDFF43;
DDR3A_SDTIM4 = 0x543F0ADF;
DDR3A_ZQCFG = 0x70073200;
//8.b. Program reg_initref_dis=0 in the SDRAM Refresh Control Register (address offset 0x10).
DDR3A_SDRFC = 0x00001457;
GEL_TextOut("DDR3A initialization complete \n");
/* End DDR3A EMIF Configuration */
}
ddr3B_64bit_DDR1600_setup()
{
unsigned int multiplier = 15;
unsigned int divider = 0;
int temp;
unsigned int OD_val = 4;
KICK0 = 0x83E70B13;
KICK1 = 0x95A4F1E0;
//1. Poll for IDONE=1 in the PHY General Status Register 0 (address offset 0x010).
do { read_val = DDR3B_PGSR0;
} while ((read_val&0x00000001) != 0x00000001);
//4. Clocks are enabled and frequency is stable—————————————
//DDR3B PLL setup
GEL_TextOut ( "DDR3 PLL Setup … \n");
//DDR3BPLLCTL0 = DDR3BPLLCTL0 & 0xFF7FFFFF;
// Set ENSAT = 1
DDR3BPLLCTL1 |= 0x00000040;
// Put the PLL in PLL Mode DDR3BPLLCTL0 |= 0x00800000;
// In PLL Controller, reset the PLL (bit 13 in DDR3BPLLCTL1 register) DDR3BPLLCTL1 |= 0x00002000;
// Program the necessary multipliers/dividers and BW adjustments // Set the divider values DDR3BPLLCTL0 &= ~(0x0000003F);
DDR3BPLLCTL0 |= (divider & 0x0000003F);
/* Step 7: Programming OD[3:0] in the SECCTL register */ DDR3BPLLCTL0 &= OUTPUT_DIVIDE_MASK; // clear the OD bit field
DDR3BPLLCTL0 |= ~OUTPUT_DIVIDE_MASK & (OD_val – 1) << OUTPUT_DIVIDE_OFFSET; // set the OD[3:0] bit field of PLLD to OD_val
//DDR3BPLLCTL0 &= ~(0x00780000);
//DDR3BPLLCTL0 |= ((OD_val << 19)& 0x00780000);
/* Set the Multipler values */
DDR3BPLLCTL0 &= ~(0x0007FFC0);
DDR3BPLLCTL0 |= ((multiplier << 6) & 0x0007FFC0 );
temp = ((multiplier + 1) >> 1) – 1;
DDR3BPLLCTL0 &= ~(0xFF000000); DDR3BPLLCTL0 |= ((temp << 24) & 0xFF000000);
DDR3BPLLCTL1 &= ~(0x0000000F);
DDR3BPLLCTL1 |= ((temp >> 8) & 0x0000000F);
//In DDR3PLLCTL1, write PLLRST = 0 to bring PLL out of reset DDR3BPLLCTL1 &= ~(0x00002000);
// Put the PLL in PLL Mode DDR3BPLLCTL0 &= ~(0x00800000); // ReSet the Bit 23
GEL_TextOut( "DDR3 PLL Setup complete, DDR3B clock now running at 800MHz.\n" );
//DDR3B PLL setup complete —————————————
/*————————- Start PHY Configuration ——————————-*/
//DDR3B_PGCR1 = 0x0280C487;
//5.a Program FRQSEL in the PLL Control Register (address offset 0x018).
DDR3B_PLLCR = 0x1C000; //Set FRQSEL=11, for ctl_clk between 166-275MHz
//5.b. Program WLSTEP=1, IODDRM=1, and ZCKSEL in the PHY General Configuration Register 1 (address offset 0x00C). DDR3B_PGCR1 |= (1 << 2); //WLSTEP = 1
DDR3B_PGCR1 &= ~(IODDRM_MASK);
DDR3B_PGCR1 |= (( 1 << 7) & IODDRM_MASK);
DDR3B_PGCR1 &= ~(ZCKSEL_MASK);
DDR3B_PGCR1 |= (( 1 << 23) & ZCKSEL_MASK);
//5.c. Program PHY Timing Parameters Register 0-4 (address offset 0x01C – 0x02C).
DDR3B_PTR0 = 0x42C21590;
DDR3B_PTR1 = 0xD05612C0;
// Maintaining default values of Phy Timing Parameters Register 2 in PUB
DDR3B_PTR3 = 0x0D861A80;//
DDR3B_PTR4 = 0x0C827100;
//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.
DDR3B_DCR &= ~(PDQ_MASK); //PDQ = 0
DDR3B_DCR &= ~(MPRDQ_MASK); //MPRDQ = 0
DDR3B_DCR &= ~(BYTEMASK_MASK);
DDR3B_DCR |= (( 1 << 10) & BYTEMASK_MASK);
DDR3B_DCR &= ~(NOSRA_MASK);
DDR3B_DCR |= (( 1 << 27) & NOSRA_MASK);
//DDR3B_DCR &= ~(UDIMM_MASK);
//DDR3B_DCR |= (( 1 << 29) & UDIMM_MASK);
//5.e. Program DRAM Timing Parameters Register 0-2 (address offset 0x048 – 0x050).
DDR3B_DTPR0 = 0xA19DBB66;
DDR3B_DTPR1 = 0x12868300;
DDR3B_DTPR2 = 0x50035200;
//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.
DDR3B_MR0 = 0x00001C70; //-CL – 11, CWL -8
//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.
DDR3B_MR1 = 0x00000006;
//———————————————————————————————————
//5.h. Program Mode Register 2 (address offset 0x05C).
// Maintaining default values of Program Mode Register 2
// DDR3B_MR2 = 0x00000018;
DDR3B_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.
DDR3B_DTCR = 0x710035C7; //0x730035C7;
//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.
DDR3B_PGCR2 = 0x00F07A12; //NOBUB = 0, FXDLAT = 0
//DDR3B_PGCR2 = 0x00F83D09; //NOBUB = 0, FXDLAT = 1
//Set Impedence Register
DDR3B_ZQ0CR1 = 0x0000005D;DDR3B_ZQ1CR1 = 0x0000005B;
DDR3B_ZQ2CR1 = 0x0000005B;
//DDR3B_ZQ3CR1 = 0x0000005D;
//DDR3B_DATX8_8 &= ~(ECC_MASK);
//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.
DDR3B_PIR = 0x00000033;
//6.b. Poll for IDONE=1 in the PHY General Status Register 0 (address offset 0x010).
do { read_val = DDR3B_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
DDR3B_PIR = 0x0000FF81; //WLADJ – ON
//DDR3B_PIR = 0x00000781; //WLADJ – OFF
//———————————————————————————————————
//7.e. Poll for IDONE=1 in the PHY General Status Register 0 (address offset 0x010).
do { read_val = DDR3B_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 | 0x011 | 0x1 | 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 | 0x11 | 0x0 | 0 | 0 | 0x10 |
SDCFG = 0x0110 0011 0010 0010 0011 0011 1011 0010
SDCFG = 0x6700486A;//0x63223332
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 DDR3B EMIF Configuration */
//8. Configure the EMIF through the VBUSM interface.
//8.a. Program all EMIF MMR抯.
DDR3B_SDCFG = 0x6200CE62 ;//0x66004862=single rank, 0x6600486A=dual rank CL- 11
DDR3B_SDTIM1 = 0x16709C55;
DDR3B_SDTIM2 = 0x00001D4A;
DDR3B_SDTIM3 = 0x435DFF54;
DDR3B_SDTIM4 = 0x553F0CFF;
DDR3B_ZQCFG = 0xF0073200;
//8.b. Program reg_initref_dis=0 in the SDRAM Refresh Control Register (address offset 0x10).
DDR3B_SDRFC = 0x00001869;
GEL_TextOut("DDR3B initialization complete \n");
/* End DDR3B EMIF Configuration */
}
Shine:
请参考置顶贴里KeystoneII的STK例程,里面的Memory_Test有初始化DDR代码。
e2echina.ti.com/…/74528
user1358304:
回复 Shine:
我们用的是CCS5.5版本,我看手册上说是CCS6.1以上版本,而且实际上编译不通过,提示找不到DNUM,TSCL,以及IER等一系列寄存器