reduce ddr change freq period
authorhcy <hcy@rock-chips.com>
Wed, 16 Apr 2014 07:59:31 +0000 (15:59 +0800)
committerhcy <hcy@rock-chips.com>
Wed, 16 Apr 2014 07:59:31 +0000 (15:59 +0800)
arch/arm/mach-rockchip/ddr_rk32.c

index c54b87a173af53d811da0183d6365dbaebe6b4c4..a11a1a631e959d7750b6587021e37934d8c84180 100755 (executable)
@@ -1474,7 +1474,7 @@ NR   NO     NF               Fout                       freq Step     finally us
 static uint32 __sramfunc ddr_set_pll_rk3188_plus(uint32 nMHz, uint32 set)
 {
     uint32 ret = 0;
-    int delay = 1000;
+    int delay;
 
     if(nMHz == 24)
     {
@@ -1482,7 +1482,7 @@ static uint32 __sramfunc ddr_set_pll_rk3188_plus(uint32 nMHz, uint32 set)
         goto out;
     }
 
-    if(!set)
+    if(set==0)
     {
         if(nMHz <= 150)
         {
@@ -1508,8 +1508,10 @@ static uint32 __sramfunc ddr_set_pll_rk3188_plus(uint32 nMHz, uint32 set)
         clkf=(nMHz*clkr*clkod)/24;
         ret = (24*clkf)/(clkr*clkod);
     }
-    else
+    else if(set == 1)
     {
+        SET_DDR_PLL_SRC(1, (DATA(ddr_select_gpll_div)-1));  //clk_ddr_src = GPLL
+        
         SET_PLL_MODE(DPLL,0);            //PLL slow-mode
         dsb();
 
@@ -1521,20 +1523,23 @@ static uint32 __sramfunc ddr_set_pll_rk3188_plus(uint32 nMHz, uint32 set)
         ddr_delayus(1);
         pCRU_Reg->CRU_PLL_CON[DPLL][3] = PLL_DE_RESET;
         dsb();
+    }
+    else
+    {
+        delay = 1000;
         while (delay > 0)
         {
-            ddr_delayus(1);
             if (GET_DPLL_LOCK_STATUS())
                 break;
+            ddr_delayus(1);
             delay--;
         }
 
-        if(set == 1)
-            SET_DDR_PLL_SRC(0, 0);  //clk_ddr_src = DDR PLL,clk_ddr_src:clk_ddrphy = 1:1
+        SET_DDR_PLL_SRC(0, 0);  //clk_ddr_src = DDR PLL,clk_ddr_src:clk_ddrphy = 1:1
         SET_PLL_MODE(DPLL,1);            //PLL normal
         dsb();
     }
-    dsb();
+    
 out:
     return ret;
 }
@@ -1548,9 +1553,13 @@ static uint32 (*p_ddr_set_pll)(uint32 nMHz, uint32 set);
 
 static void __sramfunc idle_port(void)
 {
-    int i;
+    register int i,j;
     uint32 clk_gate[14];
 
+    pPMU_Reg->PMU_IDLE_REQ |= idle_req_core_cfg;
+    dsb();
+    while( (pPMU_Reg->PMU_IDLE_ST & idle_core) == 0 );
+
     //save clock gate status
     for(i=0;i<14;i++)
         clk_gate[i]=pCRU_Reg->CRU_CLKGATE_CON[i];
@@ -1559,48 +1568,37 @@ static void __sramfunc idle_port(void)
     for(i=0;i<14;i++)
         pCRU_Reg->CRU_CLKGATE_CON[i]=0xffff0000;
 
-    pPMU_Reg->PMU_IDLE_REQ |= idle_req_dma_cfg;
-    dsb();
-    while(((pPMU_Reg->PMU_IDLE_ST) & idle_dma) == 0);
-
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_peri_pwr_st) == 0 )
+    i = pPMU_Reg->PMU_PWRDN_ST;
+    j = idle_req_dma_cfg;
+    
+    if ( (i & pd_peri_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ |= idle_req_peri_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_peri) == 0 );
+        j |= idle_req_peri_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_vio_pwr_st) == 0 )
+    if ( (i & pd_video_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ |= idle_req_vio_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_vio) == 0 );
+        j |= idle_req_video_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_video_pwr_st) == 0 )
+    if ( (i & pd_gpu_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ |= idle_req_video_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_video) == 0 );
+        j |= idle_req_gpu_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_gpu_pwr_st) == 0 )
+    if ( (i & pd_hevc_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ |= idle_req_gpu_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_gpu) == 0 );
+        j |= idle_req_hevc_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_hevc_pwr_st) == 0 )
+    if ( (i & pd_vio_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ |= idle_req_hevc_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_hevc) == 0 );
+        j |= idle_req_vio_cfg;
     }
 
-    pPMU_Reg->PMU_IDLE_REQ |= idle_req_core_cfg;
+    pPMU_Reg->PMU_IDLE_REQ |= j;
     dsb();
-    while( (pPMU_Reg->PMU_IDLE_ST & idle_core) == 0 );
+    while( (pPMU_Reg->PMU_IDLE_ST & j) != j );
 
     //resume clock gate status
     for(i=0;i<14;i++)
@@ -1609,7 +1607,7 @@ static void __sramfunc idle_port(void)
 
 static void __sramfunc deidle_port(void)
 {
-    int i;
+    register int i,j;
     uint32 clk_gate[14];
 
     //save clock gate status
@@ -1619,46 +1617,39 @@ static void __sramfunc deidle_port(void)
     //enable all clock gate for request idle
     for(i=0;i<14;i++)
         pCRU_Reg->CRU_CLKGATE_CON[i]=0xffff0000;
+
+    i = pPMU_Reg->PMU_PWRDN_ST;
+    j = idle_req_dma_cfg;
     
-    pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_dma_cfg;
-    dsb();
-    while( (pPMU_Reg->PMU_IDLE_ST & idle_dma) != 0 );
-    
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_peri_pwr_st) == 0 )
+    if ( (i & pd_peri_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_peri_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_peri) != 0 );
+        j |= idle_req_peri_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_vio_pwr_st) == 0 )
+    if ( (i & pd_video_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_vio_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_vio) != 0 );
+        j |= idle_req_video_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_video_pwr_st) == 0 )
+    if ( (i & pd_gpu_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_video_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_video) != 0 );
+        j |= idle_req_gpu_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_gpu_pwr_st) == 0 )
+    if ( (i & pd_hevc_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_gpu_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_gpu) != 0 );
+        j |= idle_req_hevc_cfg;
     }
 
-    if ( (pPMU_Reg->PMU_PWRDN_ST & pd_hevc_pwr_st) == 0 )
+    if ( (i & pd_vio_pwr_st) == 0 )
     {
-        pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_hevc_cfg;
-        dsb();
-        while( (pPMU_Reg->PMU_IDLE_ST & idle_hevc) != 0 );
+        j |= idle_req_vio_cfg;
     }
 
+    pPMU_Reg->PMU_IDLE_REQ &= ~j;
+    dsb();
+    while( (pPMU_Reg->PMU_IDLE_ST & j) != 0 );
+
     pPMU_Reg->PMU_IDLE_REQ &= ~idle_req_core_cfg;
     dsb();
     while( (pPMU_Reg->PMU_IDLE_ST & idle_core) != 0 );
@@ -1694,11 +1685,11 @@ static void __sramfunc ddr_delayus(uint32 us)
     } while (0);
 }
 
-void PIE_FUNC(ddr_copy)(uint32 *pDest, uint32 *pSrc, uint32 words)
+void PIE_FUNC(ddr_copy)(uint64_t *pDest, uint64_t *pSrc, uint32 wword)
 {
     uint32 i;
 
-    for(i=0; i<words; i++)
+    for(i=0; i<wword; i++)
     {
         pDest[i] = pSrc[i];
     }
@@ -1855,8 +1846,8 @@ static __sramfunc void ddr_reset_dll(uint32 ch)
 
 static __sramfunc void ddr_move_to_Lowpower_state(uint32 ch)
 {
-    volatile uint32 value;
-    pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
+    register uint32 value;
+    register pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
 
     while(1)
     {
@@ -1888,9 +1879,9 @@ static __sramfunc void ddr_move_to_Lowpower_state(uint32 ch)
 
 static __sramfunc void ddr_move_to_Access_state(uint32 ch)
 {
-    volatile uint32 value;
-    pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
-    pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
+    register uint32 value;
+    register pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
+    register pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
 
     //set auto self-refresh idle
     pDDR_Reg->MCFG1=(pDDR_Reg->MCFG1&0xffffff00) | DATA(ddr_sr_idle) | (1<<31);
@@ -1932,9 +1923,9 @@ static __sramfunc void ddr_move_to_Access_state(uint32 ch)
 
 static __sramfunc void ddr_move_to_Config_state(uint32 ch)
 {
-    volatile uint32 value;
-    pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
-    pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
+    register uint32 value;
+    register pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
+    register pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
 
     /* hw_wakeup :disable auto sr */
     DDR_HW_WAKEUP(ch,1);
@@ -1979,14 +1970,13 @@ static void __sramfunc ddr_send_command(uint32 ch, uint32 rank, uint32 cmd, uint
 //¶ÔtypeÀàÐ͵ÄDDRµÄ¼¸¸öcs½øÐÐDTT
 //0  DTT³É¹¦
 //!0 DTTʧ°Ü
-static uint32 __sramfunc ddr_data_training(uint32 ch)
+static uint32 __sramfunc ddr_data_training_trigger(uint32 ch)
 {
-    uint32        value,cs,i,byte=2;
+    uint32        cs;
     pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
     pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
 
     // disable auto refresh
-    value = pDDR_Reg->TREFI;
     pDDR_Reg->TREFI = 0;
     dsb();
     if((DATA(ddr_ch[ch]).mem_type != LPDDR2)
@@ -2001,7 +1991,17 @@ static uint32 __sramfunc ddr_data_training(uint32 ch)
     pPHY_Reg->PGCR = (pPHY_Reg->PGCR & (~(0xF<<18))) | (1<<18);  //use cs0 dtt
     // trigger DTT
     pPHY_Reg->PIR |= INIT | QSTRN | LOCKBYP | ZCALBYP | CLRSR | ICPC;
-    dsb();
+    return cs;
+}
+//¶ÔtypeÀàÐ͵ÄDDRµÄ¼¸¸öcs½øÐÐDTT
+//0  DTT³É¹¦
+//!0 DTTʧ°Ü
+static uint32 __sramfunc ddr_data_training(uint32 ch, uint32 cs)
+{
+    uint32        i,byte;
+    pDDR_REG_T    pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
+    pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
+    
     // wait echo byte DTDONE
     while((pPHY_Reg->DATX8[0].DXGSR[0] & 1) != 1);
     while((pPHY_Reg->DATX8[1].DXGSR[0] & 1) != 1);
@@ -2038,7 +2038,7 @@ static uint32 __sramfunc ddr_data_training(uint32 ch)
         pPHY_Reg->PGCR &= ~(1<<1);
     }
     // resume auto refresh
-    pDDR_Reg->TREFI = value;
+    pDDR_Reg->TREFI = DATA(ddr_reg).pctl.pctl_timing.trefi;
 
     if(pPHY_Reg->PGSR & DTERR)
     {
@@ -2496,7 +2496,7 @@ static noinline uint32 ddr_get_parameter(uint32 nMHz)
     }
     else if(mem_type == LPDDR2)
     {
-        #define LPDDR2_tREFI_3_9_us    (38)  //unit 100ns
+        #define LPDDR2_tREFI_3_9_us    (39)  //unit 100ns
         #define LPDDR2_tREFI_7_8_us    (78)  //unit 100ns
         #define LPDDR2_tMRD            (5)   //tCK
         #define LPDDR2_tRFC_8Gb        (210)  //ns
@@ -2891,7 +2891,7 @@ static noinline uint32 ddr_get_parameter(uint32 nMHz)
     }
     else if(mem_type == LPDDR3)
     {
-        #define LPDDR3_tREFI_3_9_us    (38)  //unit 100ns
+        #define LPDDR3_tREFI_3_9_us    (39)  //unit 100ns
         #define LPDDR3_tMRD            (10)   //tCK
         #define LPDDR3_tRFC_8Gb        (210)  //ns
         #define LPDDR3_tRFC_4Gb        (130)  //ns
@@ -3282,8 +3282,10 @@ static uint32 __sramfunc ddr_update_timing(uint32 ch)
     pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
     pMSCH_REG     pMSCH_Reg= DATA(ddr_ch[ch]).pMSCH_Reg;
 
-    FUNC(ddr_copy)((uint32 *)&(pDDR_Reg->TOGCNT1U), (uint32*)&(p_pctl_timing->togcnt1u), 34);
-    FUNC(ddr_copy)((uint32 *)&(pPHY_Reg->DTPR[0]), (uint32*)&(p_publ_timing->dtpr0), 3);    
+    FUNC(ddr_copy)((uint64_t *)&(pDDR_Reg->TOGCNT1U), (uint64_t*)&(p_pctl_timing->togcnt1u), 17);
+    pPHY_Reg->DTPR[0] = p_publ_timing->dtpr0.d32;
+    pPHY_Reg->DTPR[1] = p_publ_timing->dtpr1.d32;
+    pPHY_Reg->DTPR[2] = p_publ_timing->dtpr2.d32;
     pMSCH_Reg->ddrtiming.d32 = (pMSCH_Reg->ddrtiming.b.BwRatio) | p_noc_timing->d32;
     pMSCH_Reg->activate.d32 = p_noc_activate->d32;
     // Update PCTL BL
@@ -3340,16 +3342,17 @@ static uint32 __sramfunc ddr_update_mr(uint32 ch)
 
     cs = ((pPHY_Reg->PGCR>>18) & 0xF);
     dll_off = (pPHY_Reg->MR[1] & DDR3_DLL_DISABLE) ? 1:0;
-    FUNC(ddr_copy)((uint32 *)&(pPHY_Reg->MR[0]), (uint32*)&(p_publ_timing->mr[0]), 4);
+    FUNC(ddr_copy)((uint64_t *)&(pPHY_Reg->MR[0]), (uint64_t*)&(p_publ_timing->mr[0]), 2);
     if(DATA(ddr_ch[ch]).mem_type == DDR3)
     {
+        ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x2) | cmd_addr((p_publ_timing->mr[2])));
         if(DATA(ddr_freq)>DDR3_DDR2_DLL_DISABLE_FREQ)
         {
             if(dll_off)  // off -> on
             {
                 ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x1) | cmd_addr((p_publ_timing->mr[1])));  //DLL enable
                 ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x0) | cmd_addr(((p_publ_timing->mr[0]))| DDR3_DLL_RESET));  //DLL reset
-                ddr_delayus(2);  //at least 200 DDR cycle
+                ddr_delayus(1);  //at least 200 DDR cycle
                 ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x0) | cmd_addr((p_publ_timing->mr[0])));
             }
             else // on -> on
@@ -3364,7 +3367,6 @@ static uint32 __sramfunc ddr_update_mr(uint32 ch)
             ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE));  //DLL disable
             ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x0) | cmd_addr((p_publ_timing->mr[0])));
         }
-        ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x2) | cmd_addr((p_publ_timing->mr[2])));
     }    
     else if((DATA(ddr_ch[ch]).mem_type == LPDDR2)||(DATA(ddr_ch[ch]).mem_type == LPDDR3))    
     {
@@ -3543,8 +3545,7 @@ static void ddr_adjust_config(void)
 
 static void __sramfunc ddr_selfrefresh_enter(uint32 nMHz)
 {
-    PHY_TIMING_T  *p_publ_timing=&(DATA(ddr_reg).publ.phy_timing);
-    uint32 cs,ch;
+    uint32 ch;
     pDDR_REG_T    pDDR_Reg;
     pDDRPHY_REG_T pPHY_Reg;
 
@@ -3555,52 +3556,8 @@ static void __sramfunc ddr_selfrefresh_enter(uint32 nMHz)
 
         if(DATA(ddr_ch[ch]).mem_type != DRAM_MAX)
         {
-            ddr_move_to_Config_state(ch);
-            pDDR_Reg->TZQCSI = 0;
-            if((nMHz<=DDR3_DDR2_DLL_DISABLE_FREQ) && (DATA(ddr_ch[ch]).mem_type == DDR3))  // DLL disable
-            {
-                cs = ((pPHY_Reg->PGCR>>18) & 0xF);
-                pPHY_Reg->MR[1] = (((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE);
-                ddr_send_command(ch,cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE));
-            }
             ddr_move_to_Lowpower_state(ch);
-
-            ddr_set_dll_bypass(ch,0);  //dll bypass
-            SET_DDRPHY_CLKGATE(ch,1);  //disable DDR PHY clock
-        }
-    }
-    ddr_delayus(1);
-}
-
-static void __sramfunc ddr_selfrefresh_exit(void)
-{
-    uint32 n,ch;
-    pDDR_REG_T    pDDR_Reg;
-    pDDRPHY_REG_T pPHY_Reg;
-
-    for(ch=0;ch<CH_MAX;ch++)
-    {
-        pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg;
-        pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg;
-
-        if(DATA(ddr_ch[ch]).mem_type != DRAM_MAX)
-        {
-            SET_DDRPHY_CLKGATE(ch,0);  //enable DDR PHY clock
-            dsb();
-            ddr_set_dll_bypass(ch,DATA(ddr_freq));
-            ddr_reset_dll(ch);
-            //ddr_delayus(10);   //wait DLL lock
-
-            ddr_move_to_Config_state(ch);
-            ddr_update_timing(ch);
-            ddr_update_mr(ch);
-            ddr_update_odt(ch);
-            n = ddr_data_training(ch);
-            ddr_move_to_Access_state(ch);
-            if(n!=0)
-            {
-                sram_printascii("DTT failed!\n");
-            }
+            pDDR_Reg->TZQCSI = 0;
         }
     }
 }
@@ -3692,9 +3649,19 @@ void __sramlocalfunc ddr_set_pll_exit_3168(uint32 freq_slew,uint32 dqstr_value)
 }
 #endif
 
+static void __sramfunc ddr_chb_update_timing_odt(void)
+{
+    ddr_set_dll_bypass(1,0); //always use dll bypass
+    ddr_update_timing(1);
+    ddr_update_odt(1);
+}
+
 /* Make sure ddr_SRE_2_SRX paramter less than 4 */
 static void __sramfunc ddr_SRE_2_SRX(uint32 freq, uint32 freq_slew,uint32 dqstr_value)
 {
+    uint32 n,ch;
+    uint32 cs[CH_MAX];
+    
     /** 2. ddr enter self-refresh mode or precharge power-down mode */
     idle_port();
 #if defined(CONFIG_ARCH_RK3066B)
@@ -3711,7 +3678,40 @@ static void __sramfunc ddr_SRE_2_SRX(uint32 freq, uint32 freq_slew,uint32 dqstr_
 #if defined(CONFIG_ARCH_RK3066B)
     ddr_set_pll_exit_3168(freq_slew,dqstr_value);
 #else
-    ddr_selfrefresh_exit();
+    //ddr_selfrefresh_exit();
+    if(DATA(ddr_ch[1]).mem_type != DRAM_MAX)
+    {
+        ddr_chb_update_timing_odt();
+    }
+    ddr_set_dll_bypass(0,0); //always use dll bypass
+    ddr_update_timing(0);
+    ddr_update_odt(0);
+    FUNC(ddr_set_pll)(freq,2);
+    for(ch=0;ch<CH_MAX;ch++)
+    {
+        if(DATA(ddr_ch[ch]).mem_type != DRAM_MAX)
+        {
+            ddr_set_dll_bypass(ch,DATA(ddr_freq));
+            ddr_reset_dll(ch);
+            //ddr_delayus(10);   //wait DLL lock
+
+            ddr_move_to_Config_state(ch);
+            ddr_update_mr(ch);
+            cs[ch] = ddr_data_training_trigger(ch);
+        }
+    }
+    for(ch=0;ch<CH_MAX;ch++)
+    {
+        if(DATA(ddr_ch[ch]).mem_type != DRAM_MAX)
+        {
+            n = ddr_data_training(ch,cs[ch]);
+            ddr_move_to_Access_state(ch);
+            if(n!=0)
+            {
+                sram_printascii("DTT failed!\n");
+            }
+        }
+    }
 #endif
     deidle_port();
     dsb();
@@ -3743,6 +3743,7 @@ static noinline uint32 ddr_change_freq_sram(uint32 nMHz , struct ddr_freq_t ddr_
     volatile uint32 n;
     volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
     uint32 i;
+    uint32 gpllvaluel;
 
 #if defined(CONFIG_ARCH_RK3066B)
     if(dqstr_flag==true)
@@ -3753,6 +3754,26 @@ static noinline uint32 ddr_change_freq_sram(uint32 nMHz , struct ddr_freq_t ddr_
 #endif
 
     param.arm_freq = ddr_get_pll_freq(APLL);
+    gpllvaluel = ddr_get_pll_freq(GPLL);
+    if((200 < gpllvaluel) ||( gpllvaluel <1600))      //GPLL:200MHz~1600MHz
+    {
+        if( gpllvaluel > 800)     //800-1600MHz  /4:200MHz-400MHz
+        {
+            *kern_to_pie(rockchip_pie_chunk, &DATA(ddr_select_gpll_div)) = 4;
+        }
+        else if( gpllvaluel > 400)    //400-800MHz  /2:200MHz-400MHz
+        {
+            *kern_to_pie(rockchip_pie_chunk, &DATA(ddr_select_gpll_div)) = 2;
+        }
+        else        //200-400MHz  /1:200MHz-400MHz
+        {
+            *kern_to_pie(rockchip_pie_chunk, &DATA(ddr_select_gpll_div)) = 1;
+        }
+    }
+    else
+    {
+        ddr_print("GPLL frequency = %dMHz,Not suitable for ddr_clock \n",gpllvaluel);
+    }
     freq=p_ddr_set_pll(nMHz,0);
 
     ddr_get_parameter(freq);
@@ -3869,7 +3890,7 @@ static uint32 ddr_change_freq_gpll_dpll(uint32 nMHz)
 static int _ddr_change_freq(uint32 nMHz)
 {
        struct ddr_freq_t ddr_freq_t;
-       //int test_count=0;
+       int test_count=0;
 
        ddr_freq_t.screen_ft_us = 0;
        ddr_freq_t.t0 = 0;
@@ -3986,9 +4007,9 @@ static void __sramfunc ddr_resume(void)
     dsb();
     while (delay > 0)
     {
-           ddr_delayus(1);
         if (GET_DPLL_LOCK_STATUS())
             break;
+        ddr_delayus(1);
         delay--;
     }
 
@@ -4041,7 +4062,7 @@ void ddr_reg_save(uint32 *pArg)
     }
     
     //PCTLR    
-    (fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_copy)))((uint32*)&(p_ddr_reg->pctl.pctl_timing.togcnt1u), (uint32 *)&(pDDR_Reg->TOGCNT1U), 34);
+    (fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_copy)))((uint64_t*)&(p_ddr_reg->pctl.pctl_timing.togcnt1u), (uint64_t *)&(pDDR_Reg->TOGCNT1U), 17);
     p_ddr_reg->pctl.SCFG = pDDR_Reg->SCFG.d32;
     p_ddr_reg->pctl.CMDTSTATEN = pDDR_Reg->CMDTSTATEN;
     p_ddr_reg->pctl.MCFG1 = pDDR_Reg->MCFG1;
@@ -4074,7 +4095,8 @@ void ddr_reg_save(uint32 *pArg)
     p_ddr_reg->pctl.DFILPCFG0 = pDDR_Reg->DFILPCFG0;
 
     //PUBL  
-    (fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_copy)))((uint32*)&(p_ddr_reg->publ.phy_timing.dtpr0), (uint32 *)&(pPHY_Reg->DTPR[0]), 7);
+    p_ddr_reg->publ.phy_timing.dtpr0.d32 = pPHY_Reg->DTPR[0];
+    (fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_copy)))((uint64_t*)&(p_ddr_reg->publ.phy_timing.dtpr1), (uint64_t *)&(pPHY_Reg->DTPR[1]), 3);
     p_ddr_reg->publ.PIR = pPHY_Reg->PIR;
     p_ddr_reg->publ.PGCR = pPHY_Reg->PGCR;
     p_ddr_reg->publ.DLLGCR = pPHY_Reg->DLLGCR;