DSP

TI的C665X_DSP芯片的DDR3配置

2019-07-13 10:08发布

6655时钟PLL配置与DDR3的配置

1       时钟概述

PLL与PLL控制器的逻辑组成和处理流程如图1所示。PLL控制器能够通过PLLDIV1到PLLDIV16这些分频器灵活便利的配置和修改内部的时钟信号。PLL控制器也包含PLLM和SECCTL寄存器,如图1所示,这些寄存器能够配置好PLLM,OUTPUTDIVIDE和BYPASS的输出。PLL控制器决定DSP核心,外设或者其他模块的输出时钟。
图1 PLL图示

1       PLL的配置

PLL和PLL控制器的初始化在设备复位后由软件配置。PLL控制器寄存器只能由CPU或者仿真器修改,外部主设备,如PCIe,是无法直接操作PLL寄存器的。PLL控制器的初始化应该在程序启动或者复位的一瞬间完成,必须在外设初始化之前完成。PLL配置寄存器(MAINPLLCTL0和MAINPLLCTL1)在bootcfg中,上电的时候是被写保护的,所以软件想操作chip-level寄存器时,必须先解锁KICK0和KICK1。同时,使能任何指定的PLL之前必须使能其对应的电源管理单元。
1.1  MAIN PLL的配置
1.      设备上电后,需要等待一段时间使得PLL选通,时间为100us2.      检测SECCTL寄存器(0x02310108)的BYPASS(23位)位是否使能,如果BYPASS == 1则执行下面操作,如果BYPASS == 0则跳到步骤3执行。a)      在MAINPLLCTL1寄存器(0x0262032C)的ENSAT位(6位)写1(使得PLL得倒最佳的操作)b)     在PLLCTL寄存器(0x02310100)的PLLEN位写0(旁路使能PLL控制器开关)c)      在PLLCTL寄存器(0x02310100)的PLLENSRC位写0(使能PLLEN去控制PLL控制器开关)d)     等待4个CLKIN的时钟周期(为了确保PLL控制器开关在BYPASS模式,目标板晶振为25M)e)      在SECCTL寄存器(0x02310108)的BYPASS位写1(使能 BYPASS模式)f)       在PLLCTL寄存器(0x02310100)的PLLPWRDN位写1(关闭PLL模式)g)      等待至少5us(使得PLL关闭完成)h)     在PLLCTL寄存器(0x02310100)的PPLPWRDN位写0(打开PLL模式)3.      PLL控制器使能BYPASSa)      PLLCTL寄存器(0x02310100)的PLLEN位写0(PLL控制器开关使能BYPASS)b)     PLLCTL寄存器(0x02310100)的PLLENSR位写0(PLL控制器开关使能PLLEN)c)      等待4个CLKIN的时钟周期(为了确保PLL控制器开关在BYPASS模式了,板子晶振为25M)4.      PLLM的值分别写入两个寄存器,将PLLM[5:0]写入PLLM寄存器,将PLLM[12:6]写入MAINPLLCTL05.      BWADJ的值分别写入两个寄存器,将BWADJ[7:0]写入MAINPLLCTL0寄存器,将BWADJ[11:8]写入MAINPLLCTL1寄存器。BWADJ[11:0]可以由PLLM[12:0]计算得倒,计算公式为BWADJ= ((PLLM + 1) >> 1)- 16.      将PLLD值写入到MAINPLLCTL0寄存器7.      将SECCTL寄存器(0x02310108)的OD位写18.      对分频器PLLDIVn操作a)      检测PLLSTAT寄存器(0x0231013C)中的GOSTAT位为0,表明目前没有GO operation操作b)     PLLDIVn寄存器中的RATIO位中写入分频值,若RATIO中的值改变了,则PLL控制寄存器会在DCHANGE寄存器中的对应位标明其改变。c)      设置需要对齐SYSCLKS的位在ALNCTL寄存器中对应的ALNn位写1d)     设置PLLCMD寄存器(0x02310138)中的GOSET位为1,进入GO操作e)      读PLLSTAT寄存器(0x0231013C)中的GOSTAT位为0则表明完成DDR3 PLL初始化配置中的GO operation操作9.      在PLLCTL寄存器(0x02310100)的PLLRST位写1,进入PLL复位操作10.   等待最少7us(等待PLL复位完成)11.   在PLLCTL寄存器(0x02310100)的PLLRST位写0,表示完成PLL复位操作,使得PLLCTL离开复位12.   等待最少500*CLKIN cycles*(PLLD + 1)13.   SECTL寄存器(0x02310108)的BYPASS写0(使能PLL开关到PLL模式)14.   PLLCTL寄存器(0x02310100)的PLLEN写1(使能PLL控制器开关到PLL模式)15.   PLL与PLL控制器初始化位PLL模式完成
1.2  DDR3 PLL配置
MAIN PLL与PLL控制器的初始化必须在DDR3PLL初始化之前DDR3 PLL配置。1.      DDR3PLLCTL1寄存器的ENSAT位(6位)写1(使得PLL得倒最佳操作)2.      DDR3PLLCTL0寄存器的BYUPASS写1(设置PLL旁路模式)3.      将PLLM与PLLD的值写入到DDR3PLLCTL0寄存器中4.      将BWADJ[7:0]写入DDR3PLLCTL0寄存器,将BWADJ[11:8]写入DDR3 PLLCTL1寄存器,BWADJ[11:0]的值可以根据PLLM[12:0]推导出来,公式为:BWADJ = ((PLLM + 1)>> 1)- 15.      DDR3PLLCTL1寄存器的PLLRST写1(PLL复位)6.      等待最少5us(等待PLL复位完成)7.      DDR3PLLCTL1寄存器的PLLRST写0(PLL复位完成,离开复位状态)8.      等待最少500*REFCLK cycles *(PLLD + 1)  (PLL 锁定时间)9.      DDR3PLLCTL0寄存器的BYPASS写0(开关处在PLL模式)10.   DDR3 PLL初始化完成

代码实现:

1,DDR3时钟的配置#define PLL2_PLLD 0   // Must be less than 64 
#define PLL2_PLLM 19  // Must be less than 4096 

DDR3PLLCTL1 |= 0x00000040;  // Set ENSAT bit = 1 
DDR3PLLCTL0 |= 0x00800000;  // Set BYPASS bit = 1 

// Clear and program PLLD field 
DDR3PLLCTL0 &= ~(0x0000003F); 
DDR3PLLCTL0 |= (PLL2_PLLD & 0x0000003F); 
// Clear and program PLLM field 
DDR3PLLCTL0 &= ~(0x0007FFC0); 
DDR3PLLCTL0 |= ((PLL2_PLLM << 6) & 0x0007FFC0 ); 

// Clear and program BWADJ field 
PLL2_BWADJ = ((PLL2_PLLM + 1) >> 1) - 1; 
DDR3PLLCTL0 &= ~(0xFF000000); 
DDR3PLLCTL1 &= ~(0x0000000F); 
DDR3PLLCTL0 |= ((PLL2_BWADJ << 24) & 0xFF000000); 
DDR3PLLCTL1 |= ((PLL2_BWADJ >> 8) & 0x0000000F); 

DDR3PLLCTL1 |= 0x00002000;    // Set RESET bit = 1 
for(i=0;i<10000;i++); // Wait at least 5us for reset complete 

DDR3PLLCTL1 &= ~(0x00002000); // Clear RESET bit 
for(i=0;i<70000;i++); // Wait at least 50us for PLL lock 

DDR3PLLCTL0 &= ~(0x00800000); // Clear BYPASS bit = 0 
2,DDR3控制器配置   int i,TEMP,startlo, stoplo,starthi, stophi;
    KICK0 = KICK0_UNLOCK;
    KICK1 = KICK1_UNLOCK;
    /* Wait for PLL to lock = min 500 ref clock cycles. 
       With refclk = 100MHz, = 5000 ns = 5us */
    Delay_milli_seconds(1);
    /***************** 3.2 DDR3 PLL Configuration ************/
    /* Done before */

    /**************** 3.3 Leveling register configuration ********************/
    DDR3_CONFIG_REG_0 &= ~(0x007FE000);  // clear ctrl_slave_ratio field
    DDR3_CONFIG_REG_0 |= 0x00200000;     // set ctrl_slave_ratio to 0x100
    DDR3_CONFIG_REG_12 |= 0x08000000;    // Set invert_clkout = 1
    DDR3_CONFIG_REG_0 |= 0xF;            // set dll_lock_diff to 15
    //From 4.2.1 Executing Partial Automatic Leveling -- Start
    DDR3_CONFIG_REG_23 |= 0x00000200;    //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 ********************/
    DATA0_WRLVL_INIT_RATIO = 0x00;
    DATA1_WRLVL_INIT_RATIO = 0x00;
    DATA2_WRLVL_INIT_RATIO = 0x00;
    DATA3_WRLVL_INIT_RATIO = 0x00;
    DATA4_WRLVL_INIT_RATIO = 0x33;
    DATA5_WRLVL_INIT_RATIO = 0x3A;
    DATA6_WRLVL_INIT_RATIO = 0x2C;
    DATA7_WRLVL_INIT_RATIO = 0x2C;
    DATA8_WRLVL_INIT_RATIO = 0x21;
    DATA0_GTLVL_INIT_RATIO = 0x00;
    DATA1_GTLVL_INIT_RATIO = 0x00;
    DATA2_GTLVL_INIT_RATIO = 0x00;
    DATA3_GTLVL_INIT_RATIO = 0x00;
    DATA4_GTLVL_INIT_RATIO = 0xB7;
    DATA5_GTLVL_INIT_RATIO = 0xB1;
    DATA6_GTLVL_INIT_RATIO = 0xA4;
    DATA7_GTLVL_INIT_RATIO = 0xA4;
    DATA8_GTLVL_INIT_RATIO = 0x98;
    //Do a PHY reset. Toggle DDR_PHY_CTRL_1 bit 15 0->1->0
    DDR_DDRPHYC &= ~(0x00008000);
    DDR_DDRPHYC |= (0x00008000);
    DDR_DDRPHYC &= ~(0x00008000);
    /***************** 3.4 Basic Controller and DRAM Configuration ************/
    DDR_SDRFC    = 0x0000515C;    // enable configuration 
    /* DDR_SDTIM1   = 0x1557B9BD; */
    TEMP = 0;
    TEMP |= 0x09 << 25; // T_RP bit field 28:25
    TEMP |= 0x09 << 21; // T_RCD bit field 24:21
    TEMP |= 0x09 << 17; // T_WR bit field 20:17
    TEMP |= 0x17 << 12; // T_RAS bit field 16:12
    TEMP |= 0x20 << 6; // T_RC bit field 11:6
    TEMP |= 0x1 << 3; // T_RRD bit field 5:3
    TEMP |= 0x4; // T_WTR bit field 2:0
    DDR_SDTIM1 = TEMP;
    /* DDR_SDTIM2   = 0x304F7FE3; */
    TEMP = 0;
    TEMP |= 0x3 << 28; // T_XP bit field 30:28
    TEMP |= 0x71 << 16; // T_XSNR bit field 24:16
    TEMP |= 0x1ff << 6; // T_XSRD bit field 15:6
    TEMP |= 0x4 << 3; // T_RTP bit field 5:3
    TEMP |= 0x3; // T_CKE bit field 2:0
    DDR_SDTIM2 = TEMP;
    /*  DDR_SDTIM3   = 0x559F849F; */
    TEMP = 0;
    TEMP |= 0x5 << 28; // T_PDLL_UL bit field 31:28 (fixed value)
    TEMP |= 0x5 << 24; // T_CSTA bit field 27:24 (fixed value)
    TEMP |= 0x4 << 21; // T_CKESR bit field 23:21
    TEMP |= 0x3f << 15; // T_ZQCS bit field 20:15
    TEMP |= 0x6A << 4; // T_RFC bit field 12:4
    TEMP |= 0xf; // T_RAS_MAX bit field 3:0 (fixed value)
    DDR_SDTIM3 = TEMP; 
    DDR_DDRPHYC  = 0x0010010F;
    DDR_ZQCFG    = 0x70074c1f; 
    DDR_PMCTL    = 0x0;
    //DDR_SDRFC = 0x0000144F; // enable configuration
    /* DDR_SDCFG    = 0x63077AB3; */
    /* New value with DYN_ODT disabled and SDRAM_DRIVE = RZQ/7 //0x63222A32;    // last config write DRAM init occurs */
    TEMP = 0;
    TEMP |= 0x3 << 29; // SDRAM_TYPE bit field 31:29 (fixed value)
    TEMP |= 0x0 << 27; // IBANK_POS bit field 28:27
    TEMP |= 0x2 << 24; // DDR_TERM bit field 26:24
    TEMP |= 0x2 << 21; // DYN_ODT bit field 22:21
    TEMP |= 0x1 << 18; // SDRAM_DRIVE bit field 19:18
    TEMP |= 0x3 << 16; // CWL bit field 17:16
    TEMP |= 0x1 << 14; // NM bit field 15:14
    TEMP |= 0xE << 10; // CL bit field 13:10
    TEMP |= 0x5 << 7; // ROWSIZE bit field 9:7
    TEMP |= 0x3 << 4; // IBANK bit field 6:4
    TEMP |= 0x0 << 3; // EBANK bit field 3:3
    TEMP |= 0x2; // PAGESIZE bit field 2:0
    DDR_SDCFG = TEMP;
    //Wait 600us for HW init to complete
    Delay_milli_seconds(1);
    DDR_SDRFC = 0x0000144F;       //Refresh rate = (7.8*666MHz)
    /**************** 4.2.1 Executing Partial Automatic Leveling ********************/
    DDR_RDWR_LVL_RMP_CTRL = 0x80000000; //enable full leveling
    DDR_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
    Delay_milli_seconds(1);