1,add ddr_change_freq function, and support menuconfig to change DDR frequce
authorhecanyang <hcy@ubuntu-fs.(none)>
Tue, 24 Apr 2012 11:19:48 +0000 (19:19 +0800)
committerhecanyang <hcy@ubuntu-fs.(none)>
Tue, 24 Apr 2012 11:37:22 +0000 (19:37 +0800)
  2,DDR3 ODT use 120ohm, to save power
  3,decrease auto power-down idle cnt to 0x40, to save power
  4,resolve ddr_suspend and ddr_resume problem
  5,enable ddr_testmode in pm.c

arch/arm/mach-rk30/common.c
arch/arm/mach-rk30/ddr.c [changed mode: 0644->0755]
arch/arm/mach-rk30/include/mach/ddr.h [new file with mode: 0755]
arch/arm/mach-rk30/platsmp.c [changed mode: 0644->0755]
arch/arm/mach-rk30/pm.c

index 0a5c2ca28162b5c0bc86cf5c160cfd37890dbe1c..e19e0e39770975b3b84e61e5db0ec81733a875dc 100755 (executable)
@@ -14,6 +14,7 @@
 #include <mach/fiq.h>
 #include <mach/pmu.h>
 #include <mach/loader.h>
+#include <mach/ddr.h>
 
 static void __init rk30_cpu_axi_init(void)
 {
@@ -127,6 +128,7 @@ void __init rk30_map_io(void)
        rk29_sram_init();
        board_clock_init();
        rk30_l2_cache_init();
+    ddr_init(DDR_TYPE, DDR_FREQ);
        rk30_iomux_init();
        rk30_boot_mode_init();
 }
old mode 100644 (file)
new mode 100755 (executable)
index 4e56392..400471d
+/*
+ * arch/arm/mach-rk30/ddr.c
+ *
+ * Function Driver for DDR controller
+ *
+ * Copyright (C) 2011 Fuzhou Rockchip Electronics Co.,Ltd
+ * Author: 
+ * hcy@rock-chips.com
+ * yk@rock-chips.com
+ * 
+ * v1.00 
+ */
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
 #include <mach/sram.h>
+#include <mach/ddr.h>
 
 typedef uint32_t uint32;
 #define PMU_BASE_ADDR           RK30_PMU_BASE
 #define SDRAMC_BASE_ADDR        RK30_DDR_PCTL_BASE
 #define DDR_PUBL_BASE           RK30_DDR_PUBL_BASE
 #define CRU_BASE_ADDR           RK30_CRU_BASE
-#define Delay_us(usecs)                sram_udelay(usecs)
+#define REG_FILE_BASE_ADDR      RK30_GRF_BASE
+#define SysSrv_DdrConf          (RK30_CPU_AXI_BUS_BASE+0x08)
+#define SysSrv_DdrTiming        (RK30_CPU_AXI_BUS_BASE+0x0c)
+#define SysSrv_DdrMode          (RK30_CPU_AXI_BUS_BASE+0x10)
+#define SysSrv_ReadLatency      (RK30_CPU_AXI_BUS_BASE+0x14)
+
+#define ddr_print(x...) printk( "DDR DEBUG: " x )
+
+/***********************************
+ * LPDDR2 define
+ ***********************************/
+//MR0 (Device Information)
+#define  LPDDR2_DAI    (0x1)        // 0:DAI complete, 1:DAI still in progress
+#define  LPDDR2_DI     (0x1<<1)     // 0:S2 or S4 SDRAM, 1:NVM
+#define  LPDDR2_DNVI   (0x1<<2)     // 0:DNV not supported, 1:DNV supported
+#define  LPDDR2_RZQI   (0x3<<3)     // 00:RZQ self test not supported, 01:ZQ-pin may connect to VDDCA or float
+                                    // 10:ZQ-pin may short to GND.     11:ZQ-pin self test completed, no error condition detected.
+
+//MR1 (Device Feature)
+#define LPDDR2_BL4     (0x2)
+#define LPDDR2_BL8     (0x3)
+#define LPDDR2_BL16    (0x4)
+#define LPDDR2_nWR(n)  (((n)-2)<<5)
+
+//MR2 (Device Feature 2)
+#define LPDDR2_RL3_WL1  (0x1)
+#define LPDDR2_RL4_WL2  (0x2)
+#define LPDDR2_RL5_WL2  (0x3)
+#define LPDDR2_RL6_WL3  (0x4)
+#define LPDDR2_RL7_WL4  (0x5)
+#define LPDDR2_RL8_WL4  (0x6)
+
+//MR3 (IO Configuration 1)
+#define LPDDR2_DS_34    (0x1)
+#define LPDDR2_DS_40    (0x2)
+#define LPDDR2_DS_48    (0x3)
+#define LPDDR2_DS_60    (0x4)
+#define LPDDR2_DS_80    (0x6)
+#define LPDDR2_DS_120   (0x7)   //optional
+
+//MR4 (Device Temperature)
+#define LPDDR2_tREF_MASK (0x7)
+#define LPDDR2_4_tREF    (0x1)
+#define LPDDR2_2_tREF    (0x2)
+#define LPDDR2_1_tREF    (0x3)
+#define LPDDR2_025_tREF  (0x5)
+#define LPDDR2_025_tREF_DERATE    (0x6)
+
+#define LPDDR2_TUF       (0x1<<7)
+
+//MR8 (Basic configuration 4)
+#define LPDDR2_S4        (0x0)
+#define LPDDR2_S2        (0x1)
+#define LPDDR2_N         (0x2)
+#define LPDDR2_Density(mr8)  (8<<(((mr8)>>2)&0xf))   // Unit:MB
+#define LPDDR2_IO_Width(mr8) (32>>(((mr8)>>6)&0x3))
+
+//MR10 (Calibration)
+#define LPDDR2_ZQINIT   (0xFF)
+#define LPDDR2_ZQCL     (0xAB)
+#define LPDDR2_ZQCS     (0x56)
+#define LPDDR2_ZQRESET  (0xC3)
+
+//MR16 (PASR Bank Mask)
+// S2 SDRAM Only
+#define LPDDR2_PASR_Full (0x0)    
+#define LPDDR2_PASR_1_2  (0x1)
+#define LPDDR2_PASR_1_4  (0x2)
+#define LPDDR2_PASR_1_8  (0x3)
+
+//MR17 (PASR Segment Mask) 1Gb-8Gb S4 SDRAM only
+
+//MR32 (DQ Calibration Pattern A)
+
+//MR40 (DQ Calibration Pattern B)
+
+/***********************************
+ * DDR3 define
+ ***********************************/
+//mr0 for ddr3
+#define DDR3_BL8          (0)
+#define DDR3_BC4_8        (1)
+#define DDR3_BC4          (2)
+#define DDR3_CL(n)        (((((n)-4)&0x7)<<4)|((((n)-4)&0x8)>>1))
+#define DDR3_WR(n)        (((n)&0x7)<<9)
+#define DDR3_MR0_DLL_RESET    (1<<8)
+#define DDR3_MR0_DLL_NOR   (0<<8)
+    
+    //mr1 for ddr3
+#define DDR3_MR1_AL(n)  (((n)&0x7)<<3)
+    
+#define DDR3_DS_40            (0)
+#define DDR3_DS_34            (1<<1)
+#define DDR3_Rtt_Nom_DIS      (0)
+#define DDR3_Rtt_Nom_60       (1<<2)
+#define DDR3_Rtt_Nom_120      (1<<6)
+#define DDR3_Rtt_Nom_40       ((1<<2)|(1<<6))
+    
+    //mr2 for ddr3
+#define DDR3_MR2_CWL(n) ((((n)-5)&0x7)<<3)
+#define DDR3_Rtt_WR_DIS       (0)
+#define DDR3_Rtt_WR_60        (1<<9)
+#define DDR3_Rtt_WR_120       (2<<9)
+
+/***********************************
+ * DDR2 define
+ ***********************************/
+//MR;                     //Mode Register                                                
+#define DDR2_BL4           (2)
+#define DDR2_BL8           (3)
+#define DDR2_CL(n)         (((n)&0x7)<<4)
+#define DDR2_WR(n)        ((((n)-1)&0x7)<<9)
+    
+//EMR;                    //Extended Mode Register      
+#define DDR2_STR_FULL     (0)
+#define DDR2_STR_REDUCE   (1<<1)
+#define DDR2_AL(n)        (((n)&0x7)<<3)
+#define DDR2_Rtt_Nom_DIS      (0)
+#define DDR2_Rtt_Nom_150      (0x40)
+#define DDR2_Rtt_Nom_75       (0x4)
+#define DDR2_Rtt_Nom_50       (0x44)
+
+/***********************************
+ * LPDDR define
+ ***********************************/
+#define mDDR_BL2           (1)
+#define mDDR_BL4           (2)
+#define mDDR_BL8           (3)
+#define mDDR_CL(n)         (((n)&0x7)<<4)
+    
+#define mDDR_DS_Full       (0)
+#define mDDR_DS_1_2        (1<<5)
+#define mDDR_DS_1_4        (2<<5)
+#define mDDR_DS_1_8        (3<<5)
+#define mDDR_DS_3_4        (4<<5)
 
 
 //PMU_MISC_CON1
@@ -47,10 +201,16 @@ typedef volatile struct tagPMU_FILE
 
 #define pPMU_Reg ((pPMU_FILE)PMU_BASE_ADDR)
 
+#define PLL_RESET  (((0x1<<5)<<16) | (0x1<<5))
+#define PLL_DE_RESET  (((0x1<<5)<<16) | (0x0<<5))
+#define NR(n)      ((0x3F<<(8+16)) | (((n)-1)<<8))
+#define NO(n)      ((0xF<<16) | ((n)-1))
+#define NF(n)      ((0x1FFF<<16) | ((n)-1))
+#define NB(n)      ((0xFFF<<16) | ((n)-1))
  //CRU Registers
-typedef volatile struct tagCRU_STRUCT 
+typedef volatile struct tagCRU_STRUCT
 {
-    uint32 CRU_PLL_CON[4][4]; 
+    uint32 CRU_PLL_CON[4][4];
     uint32 CRU_MODE_CON;
     uint32 CRU_CLKSEL_CON[35];
     uint32 CRU_CLKGATE_CON[10];
@@ -66,6 +226,46 @@ typedef volatile struct tagCRU_STRUCT
 
 #define pCRU_Reg ((pCRU_REG)CRU_BASE_ADDR)
 
+#define bank2_to_rank_en   ((1<<2) | ((1<<2)<<16))
+#define bank2_to_rank_dis   ((0<<2) | ((1<<2)<<16))
+#define rank_to_row15_en   ((1<<1) | ((1<<1)<<16))
+#define rank_to_row15_dis   ((0<<1) | ((1<<1)<<16))
+
+typedef struct tagGPIO_LH
+{
+    uint32 GPIOL;
+    uint32 GPIOH;
+}GPIO_LH_T;
+
+typedef struct tagGPIO_IOMUX
+{
+    uint32 GPIOA_IOMUX;
+    uint32 GPIOB_IOMUX;
+    uint32 GPIOC_IOMUX;
+    uint32 GPIOD_IOMUX;
+}GPIO_IOMUX_T;
+
+//REG FILE registers
+typedef volatile struct tagREG_FILE
+{
+    GPIO_LH_T GRF_GPIO_DIR[7];
+    GPIO_LH_T GRF_GPIO_DO[7];
+    GPIO_LH_T GRF_GPIO_EN[7];
+    GPIO_IOMUX_T GRF_GPIO_IOMUX[7];
+    GPIO_LH_T GRF_GPIO_PULL[7];
+    uint32 GRF_SOC_CON[3];
+    uint32 GRF_SOC_STATUS0;
+    uint32 GRF_DMAC1_CON[3];
+    uint32 GRF_DMAC2_CON[4];
+    uint32 GRF_UOC0_CON[3];
+    uint32 GRF_UOC1_CON[4];
+    uint32 GRF_DDRC_CON0;
+    uint32 GRF_DDRC_STAT;
+    uint32 reserved[(0x1c8-0x1a0)/4];
+    uint32 GRF_OS_REG[4];
+} REG_FILE, *pREG_FILE;
+
+#define pGRF_Reg ((pREG_FILE)REG_FILE_BASE_ADDR)
 
 //SCTL
 #define INIT_STATE                     (0)
@@ -85,8 +285,8 @@ typedef volatile struct tagCRU_STRUCT
 #define Low_power_exit_req             (7)
 
 //MCFG
-#define mddr_lpddr2_clk_stop_idle(n)   (n<<24)
-#define pd_idle(n)                     (n<<8)
+#define mddr_lpddr2_clk_stop_idle(n)   ((n)<<24)
+#define pd_idle(n)                     ((n)<<8)
 #define mddr_en                        (2<<22)
 #define lpddr2_en                      (3<<22)
 #define ddr2_en                        (0<<5)
@@ -99,13 +299,13 @@ typedef volatile struct tagCRU_STRUCT
 #define mddr_lpddr2_bl_16              (3<<20)
 #define ddr2_ddr3_bl_4                 (0)
 #define ddr2_ddr3_bl_8                 (1)
-#define tfaw_cfg(n)                    ((n-4)<<18)
+#define tfaw_cfg(n)                    (((n)-4)<<18)
 #define pd_exit_slow                   (0<<17)
 #define pd_exit_fast                   (1<<17)
-#define pd_type(n)                     (n<<16)
-#define two_t_en(n)                    (n<<3)
-#define bl8int_en(n)                   (n<<2)
-#define cke_or_en(n)                   (n<<1)
+#define pd_type(n)                     ((n)<<16)
+#define two_t_en(n)                    ((n)<<3)
+#define bl8int_en(n)                   ((n)<<2)
+#define cke_or_en(n)                   ((n)<<1)
 
 //POWCTL
 #define power_up_start                 (1<<0)
@@ -133,11 +333,11 @@ typedef volatile struct tagCRU_STRUCT
 #define MRR_cmd                        (8)
 #define DPDE_cmd                       (9)
 
-#define lpddr2_op(n)                   (n<<12)
-#define lpddr2_ma(n)                   (n<<4)
+#define lpddr2_op(n)                   ((n)<<12)
+#define lpddr2_ma(n)                   ((n)<<4)
 
-#define bank_addr(n)                   (n<<17)
-#define cmd_addr(n)                    (n<<4)
+#define bank_addr(n)                   ((n)<<17)
+#define cmd_addr(n)                    ((n)<<4)
 
 #define start_cmd                      (1u<<31)
 
@@ -156,7 +356,7 @@ typedef union STAT_Tag
 typedef union SCFG_Tag
 {
     uint32 d32;
-    struct 
+    struct
     {
         unsigned hw_low_power_en : 1;
         unsigned reserved1_5 : 5;
@@ -350,11 +550,11 @@ typedef volatile struct DDR_REG_Tag
 #define INITBYP              (1u<<31)
 
 //PGCR
-#define DFTLMT(n)            (n<<3)
-#define DFTCMP(n)            (n<<2)
-#define DQSCFG(n)            (n<<1)
-#define ITMDMD(n)            (n<<0)
-#define RANKEN(n)            (n<<18)
+#define DFTLMT(n)            ((n)<<3)
+#define DFTCMP(n)            ((n)<<2)
+#define DQSCFG(n)            ((n)<<1)
+#define ITMDMD(n)            ((n)<<0)
+#define RANKEN(n)            ((n)<<18)
 
 //PGSR
 #define IDONE                (1<<0)
@@ -368,26 +568,26 @@ typedef volatile struct DDR_REG_Tag
 #define TQ                   (1u<<31)
 
 //PTR0
-#define tITMSRST(n)          (n<<18)
-#define tDLLLOCK(n)          (n<<6)
-#define tDLLSRST(n)          (n<<0)
+#define tITMSRST(n)          ((n)<<18)
+#define tDLLLOCK(n)          ((n)<<6)
+#define tDLLSRST(n)          ((n)<<0)
 
 //PTR1
-#define tDINIT1(n)           (n<<19)
-#define tDINIT0(n)           (n<<0)
+#define tDINIT1(n)           ((n)<<19)
+#define tDINIT0(n)           ((n)<<0)
 
 //PTR2
-#define tDINIT3(n)           (n<<17)
-#define tDINIT2(n)           (n<<0)
+#define tDINIT3(n)           ((n)<<17)
+#define tDINIT2(n)           ((n)<<0)
 
 //DSGCR
-#define DQSGE(n)             (n<<8)
-#define DQSGX(n)             (n<<5)
+#define DQSGE(n)             ((n)<<8)
+#define DQSGX(n)             ((n)<<5)
 
 typedef union DCR_Tag
 {
     uint32 d32;
-    struct 
+    struct
     {
         unsigned DDRMD : 3;
         unsigned DDR8BNK : 1;
@@ -433,13 +633,13 @@ typedef volatile struct DDRPHY_REG_Tag
     volatile uint32 ODTCR;                  //ODT Configuration Register
     volatile uint32 DTAR;                   //Data Training Address Register
     volatile uint32 DTDR[2];                //Data Training Data Register 0-1
-    
+
     uint32 reserved1[0x30-0x18];
     uint32 DCU[0x38-0x30];
     uint32 reserved2[0x40-0x38];
     uint32 BIST[0x51-0x40];
     uint32 reserved3[0x60-0x51];
-    
+
     volatile uint32 ZQ0CR[2];               //ZQ 0 Impedance Control Register 0-1
     volatile uint32 ZQ0SR[2];               //ZQ 0 Impedance Status Register 0-1
     volatile uint32 ZQ1CR[2];               //ZQ 1 Impedance Control Register 0-1
@@ -448,37 +648,398 @@ typedef volatile struct DDRPHY_REG_Tag
     volatile uint32 ZQ2SR[2];               //ZQ 2 Impedance Status Register 0-1
     volatile uint32 ZQ3CR[2];               //ZQ 3 Impedance Control Register 0-1
     volatile uint32 ZQ3SR[2];               //ZQ 3 Impedance Status Register 0-1
-    
-    DATX8_REG_T     DATX8[9];               //DATX8 Register 
+
+    DATX8_REG_T     DATX8[9];               //DATX8 Register
 }DDRPHY_REG_T, *pDDRPHY_REG_T;
 
 #define pPHY_Reg ((pDDRPHY_REG_T)DDR_PUBL_BASE)
 
-__sramfunc static void Idle_port(void)
+typedef enum DRAM_TYPE_Tag
+{
+    LPDDR = 0,
+    DDR,
+    DDR2,
+    DDR3,
+    LPDDR2,
+
+    DRAM_MAX
+}DRAM_TYPE;
+
+typedef struct PCTRL_TIMING_Tag
+{
+    uint32 ddrFreq;
+    //Memory Timing Registers
+    uint32 togcnt1u;               //Toggle Counter 1U Register
+    uint32 tinit;                  //t_init Timing Register
+    uint32 trsth;                  //Reset High Time Register
+    uint32 togcnt100n;             //Toggle Counter 100N Register
+    uint32 trefi;                  //t_refi Timing Register
+    uint32 tmrd;                   //t_mrd Timing Register
+    uint32 trfc;                   //t_rfc Timing Register
+    uint32 trp;                    //t_rp Timing Register
+    uint32 trtw;                   //t_rtw Timing Register
+    uint32 tal;                    //AL Latency Register
+    uint32 tcl;                    //CL Timing Register
+    uint32 tcwl;                   //CWL Register
+    uint32 tras;                   //t_ras Timing Register
+    uint32 trc;                    //t_rc Timing Register
+    uint32 trcd;                   //t_rcd Timing Register
+    uint32 trrd;                   //t_rrd Timing Register
+    uint32 trtp;                   //t_rtp Timing Register
+    uint32 twr;                    //t_wr Timing Register
+    uint32 twtr;                   //t_wtr Timing Register
+    uint32 texsr;                  //t_exsr Timing Register
+    uint32 txp;                    //t_xp Timing Register
+    uint32 txpdll;                 //t_xpdll Timing Register
+    uint32 tzqcs;                  //t_zqcs Timing Register
+    uint32 tzqcsi;                 //t_zqcsi Timing Register
+    uint32 tdqs;                   //t_dqs Timing Register
+    uint32 tcksre;                 //t_cksre Timing Register
+    uint32 tcksrx;                 //t_cksrx Timing Register
+    uint32 tcke;                   //t_cke Timing Register
+    uint32 tmod;                   //t_mod Timing Register
+    uint32 trstl;                  //Reset Low Timing Register
+    uint32 tzqcl;                  //t_zqcl Timing Register
+    uint32 tmrr;                   //t_mrr Timing Register
+    uint32 tckesr;                 //t_ckesr Timing Register
+    uint32 tdpd;                   //t_dpd Timing Register
+}PCTL_TIMING_T;
+
+typedef union DTPR_0_Tag
+{
+    uint32 d32;
+    struct 
+    {
+        unsigned tMRD : 2;
+        unsigned tRTP : 3;
+        unsigned tWTR : 3;
+        unsigned tRP : 4;
+        unsigned tRCD : 4;
+        unsigned tRAS : 5;
+        unsigned tRRD : 4;
+        unsigned tRC : 6;
+        unsigned tCCD : 1;
+    } b;
+}DTPR_0_T;
+
+typedef union DTPR_1_Tag
+{
+    uint32 d32;
+    struct 
+    {
+        unsigned tAOND : 2;
+        unsigned tRTW : 1;
+        unsigned tFAW : 6;
+        unsigned tMOD : 2;
+        unsigned tRTODT : 1;
+        unsigned reserved12_15 : 4;
+        unsigned tRFC : 8;
+        unsigned tDQSCK : 3;
+        unsigned tDQSCKmax : 3;
+        unsigned reserved30_31 : 2;
+    } b;
+}DTPR_1_T;
+
+typedef union DTPR_2_Tag
+{
+    uint32 d32;
+    struct 
+    {
+        unsigned tXS : 10;
+        unsigned tXP : 5;
+        unsigned tCKE : 4;
+        unsigned tDLLK : 10;
+        unsigned reserved29_31 : 3;
+    } b;
+}DTPR_2_T;
+
+typedef struct PHY_TIMING_Tag
+{
+    DTPR_0_T  dtpr0;
+    DTPR_1_T  dtpr1;
+    DTPR_2_T  dtpr2;
+    uint32    mr[4];   //LPDDR2 no MR0, mr[2] is mDDR MR1
+}PHY_TIMING_T;
+
+typedef union NOC_TIMING_Tag
+{
+    uint32 d32;
+    struct 
+    {
+        unsigned ActToAct : 6;
+        unsigned RdToMiss : 6;
+        unsigned WrToMiss : 6;
+        unsigned BurstLen : 3;
+        unsigned RdToWr : 5;
+        unsigned WrToRd : 5;
+        unsigned BwRatio : 1;
+    } b;
+}NOC_TIMING_T;
+
+typedef struct DDR_TIMING_Tag
+{
+    PCTL_TIMING_T  pctl_timing;
+    PHY_TIMING_T   phy_timing;
+    NOC_TIMING_T   noc_timing;
+}DDR_TIMING_T;
+
+__sramdata DDR_TIMING_T ddr_timing;
+
+typedef struct DDR_CONFIG_2_RBC_Tag
+{
+    unsigned int row;
+    unsigned int bank;
+    unsigned int col;
+}DDR_CONFIG_2_RBC_T;
+
+DDR_CONFIG_2_RBC_T  ddr_cfg_2_rbc[16] = 
+{
+    {15,3,11},  // bank ahead
+    {15,3,10},
+    {14,3,10},
+    {13,3,10},
+    {15,3,11},
+    {14,3,11},
+    {13,3,11},
+    {14,3,9},
+    {13,3,9},
+    {15,2,11},
+    {14,2,11},
+    {15,2,10},
+    {14,2,10},
+    {14,2,9},
+    {13,2,9},
+    {15,3,10}   // bank ahead
+};
+
+uint32_t ddrDataTraining[32];
+
+uint32_t __sramdata ddr3_cl_cwl[22][4]={
+/*   0~330           330~400         400~533        speed
+* tCK  >3             2.5~3          1.875~2.5     1.875~1.5
+*    cl<<16, cwl    cl<<16, cwl     cl<<16, cwl              */
+    {((5<<16)|5),   ((5<<16)|5),    0          ,   0}, //DDR3_800D
+    {((5<<16)|5),   ((6<<16)|5),    0          ,   0}, //DDR3_800E
+
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   0}, //DDR3_1066E
+    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   0}, //DDR3_1066F
+    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   0}, //DDR3_1066G
+
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((7<<16)|7)}, //DDR3_1333F
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((8<<16)|7)}, //DDR3_1333G
+    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_1333H
+    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((10<<16)|7)}, //DDR3_1333J
+
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((7<<16)|7)}, //DDR3_1600G
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((8<<16)|7)}, //DDR3_1600H
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_1600J
+    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((10<<16)|7)}, //DDR3_1600K
+
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((8<<16)|7)}, //DDR3_1866J
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((8<<16)|7)}, //DDR3_1866K
+    {((6<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_1866L
+    {((6<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((10<<16)|7)}, //DDR3_1866M
+
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((7<<16)|7)}, //DDR3_2133K
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((8<<16)|7)}, //DDR3_2133L
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_2133M
+    {((6<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((9<<16)|7)},  //DDR3_2133N
+
+    {((6<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((10<<16)|7)} //DDR3_DEFAULT
+
+};
+uint32_t __sramdata ddr3_tRC_tFAW[22]={
+/**    tRC    tFAW   */
+    ((50<<16)|50), //DDR3_800D
+    ((53<<16)|50), //DDR3_800E
+
+    ((49<<16)|50), //DDR3_1066E
+    ((51<<16)|50), //DDR3_1066F
+    ((53<<16)|50), //DDR3_1066G
+
+    ((47<<16)|45), //DDR3_1333F
+    ((48<<16)|45), //DDR3_1333G
+    ((50<<16)|45), //DDR3_1333H
+    ((51<<16)|45), //DDR3_1333J
+
+    ((45<<16)|40), //DDR3_1600G
+    ((47<<16)|40), //DDR3_1600H
+    ((48<<16)|40), //DDR3_1600J
+    ((49<<16)|40), //DDR3_1600K
+
+    ((45<<16)|35), //DDR3_1866J
+    ((46<<16)|35), //DDR3_1866K
+    ((47<<16)|35), //DDR3_1866L
+    ((48<<16)|35), //DDR3_1866M
+
+    ((44<<16)|35), //DDR3_2133K
+    ((45<<16)|35), //DDR3_2133L
+    ((46<<16)|35), //DDR3_2133M
+    ((47<<16)|35), //DDR3_2133N
+
+    ((53<<16)|50)  //DDR3_DEFAULT
+};
+static __sramdata uint32_t mem_type;    // 0:DDR2, 1:DDR3, 2:LPDDR
+static __sramdata uint32_t ddr_type;    // used for ddr3 only
+static __sramdata uint32_t capability;  // one chip cs capability
+
+static __sramdata uint32_t al;
+static __sramdata uint32_t bl;
+static __sramdata uint32_t cl;
+static __sramdata uint32_t cwl;
+
+static __sramdata uint32_t ddr_freq;
+
+/****************************************************************************
+Internal sram us delay function
+Cpu highest frequency is 1.2 GHz
+1 cycle = 1/1.2 ns
+1 us = 1000 ns = 1000 * 1.2 cycles = 1200 cycles
+*****************************************************************************/
+static __sramdata uint32_t loops_per_us;
+
+#define LPJ_100MHZ  499728UL
+
+/*static*/ void __sramlocalfunc delayus(uint32_t us)
+{   
+    uint32_t count;
+     
+    count = loops_per_us*us;
+    while(count--)  // 3 cycles
+        barrier();
+}
+
+static __sramfunc void copy(uint32 *pDest, uint32 *pSrc, uint32 words)
+{
+    uint32 i;
+
+    for(i=0; i<words; i++)
+    {
+        pDest[i] = pSrc[i];
+    }
+}
+
+static uint32 get_row(void)
+{
+    uint32 i;
+    uint32 row;
+
+    i = *(volatile uint32*)SysSrv_DdrConf;
+    row = ddr_cfg_2_rbc[i].row;
+    if(pGRF_Reg->GRF_SOC_CON[2] &  (1<<1))
+    {
+        row += 1;
+    }
+    return row;
+}
+
+static uint32 get_bank(void)
+{
+    uint32 i;
+
+    i = *(volatile uint32*)SysSrv_DdrConf;
+    return ddr_cfg_2_rbc[i].bank;
+}
+
+static uint32 get_col(void)
+{
+    uint32 i;
+
+    i = *(volatile uint32*)SysSrv_DdrConf;
+    return ddr_cfg_2_rbc[i].col;
+}
+
+static uint32 get_cs0_cap(void)
+{
+    uint32 i;
+
+    i = *(volatile uint32*)SysSrv_DdrConf;
+    return (1 << ((ddr_cfg_2_rbc[i].row)+(ddr_cfg_2_rbc[i].col)+(ddr_cfg_2_rbc[i].bank)+2));
+}
+
+static uint32_t get_datatraing_addr(void)
+{
+    uint32_t          value=0;
+    uint32_t          addr;
+    uint32_t          col = 0;
+    uint32_t          row = 0;
+    uint32_t          bank = 0;
+    
+    // caculate aglined physical address 
+    addr =  __pa((unsigned long)ddrDataTraining);
+    if(addr&0x3F)
+    {
+        addr += (64-(addr&0x3F));
+    }
+    addr -= 0x60000000;
+    // find out col£¬row£¬bank
+    row = get_row();
+    bank = get_bank();
+    col = get_col();
+    // according different address mapping, caculate DTAR register value
+    switch(*(volatile uint32*)SysSrv_DdrConf)
+    {
+        case 0:
+        case 15:
+            value |= (addr>>2) & ((0x1<<col)-1);  // col
+            value |= ((addr>>(2+col)) & ((0x1<<row)-1)) << 12;  // row
+            value |= ((addr>>(2+col+row)) & ((0x1<<bank)-1)) << 28;  // bank
+            break;
+        default:
+            value |= (addr>>2) & ((0x1<<col)-1);  // col
+            value |= ((addr>>(2+col+bank)) & ((0x1<<row)-1)) << 12;  // row
+            value |= ((addr>>(2+col)) & ((0x1<<bank)-1)) << 28;  // bank
+            break;
+    }
+
+    return value;
+}
+
+static __sramfunc void idle_port(void)
 {
-    pPMU_Reg->PMU_MISC_CON1 = (pPMU_Reg->PMU_MISC_CON1 & (~(0xF<<2)))
+    pPMU_Reg->PMU_MISC_CON1 = (pPMU_Reg->PMU_MISC_CON1 & (~(0x1F<<1)))
+                                        | idle_req_cpu_cfg
                                         | idle_req_peri_cfg
                                         | idle_req_gpu_cfg
                                         | idle_req_video_cfg
                                         | idle_req_vio_cfg;
     while(((pPMU_Reg->PMU_PWRDN_ST) & (idle_peri
                                         | idle_gpu
+                                        | idle_cpu
                                         | idle_video
                                         | idle_vio)) != (idle_peri
                                         | idle_gpu
+                                        | idle_cpu
                                         | idle_video
                                         | idle_vio));
 }
 
-__sramfunc static void DeIdle_port(void)
+
+static __sramfunc void deIdle_port(void)
 {
     pPMU_Reg->PMU_MISC_CON1 &= ~(idle_req_peri_cfg
                                  | idle_req_gpu_cfg
+                                 | idle_req_cpu_cfg
                                  | idle_req_video_cfg
                                  | idle_req_vio_cfg);
 }
 
-__sramfunc void Move_to_Lowpower_state(void)
+static __sramlocalfunc void reset_dll(void)
+{
+    pPHY_Reg->ACDLLCR &= ~0x40000000;
+    pPHY_Reg->DATX8[0].DXDLLCR &= ~0x40000000;
+    pPHY_Reg->DATX8[1].DXDLLCR &= ~0x40000000;
+    pPHY_Reg->DATX8[2].DXDLLCR &= ~0x40000000;
+    pPHY_Reg->DATX8[3].DXDLLCR &= ~0x40000000;
+    delayus(10);
+    pPHY_Reg->ACDLLCR |= 0x40000000;
+    pPHY_Reg->DATX8[0].DXDLLCR |= 0x40000000;
+    pPHY_Reg->DATX8[1].DXDLLCR |= 0x40000000;
+    pPHY_Reg->DATX8[2].DXDLLCR |= 0x40000000;
+    pPHY_Reg->DATX8[3].DXDLLCR |= 0x40000000;
+    delayus(10);
+}
+static __sramfunc void move_to_Lowpower_state(void)
 {
     volatile uint32 value;
 
@@ -508,7 +1069,7 @@ __sramfunc void Move_to_Lowpower_state(void)
     }
 }
 
-__sramfunc void Move_to_Access_state(void)
+static __sramfunc void move_to_Access_state(void)
 {
     volatile uint32 value;
 
@@ -540,67 +1101,1745 @@ __sramfunc void Move_to_Access_state(void)
     }
 }
 
-__sramfunc void ddr_selfrefresh_enter(void)
+static __sramfunc void move_to_Config_state(void)
+{
+    volatile uint32 value;
+
+    while(1)
+    {
+        value = pDDR_Reg->STAT.b.ctl_stat;
+        if(value == Config)
+        {
+            break;
+        }
+        switch(value)
+        {
+            case Low_power:
+                pDDR_Reg->SCTL = WAKEUP_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Access);
+                while((pPHY_Reg->PGSR & DLDONE) != DLDONE);  //wait DLL lock
+            case Access:
+            case Init_mem:
+                pDDR_Reg->SCTL = CFG_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Config);
+                break;
+            default:  //Transitional state
+                break;
+        }
+    }
+}
+
+//arg°üÀ¨bank_addrºÍcmd_addr
+static void __sramlocalfunc send_command(uint32 rank, uint32 cmd, uint32 arg)
 {
     uint32 i;
-    
-//    Idle_port();
-    Move_to_Lowpower_state();
+    pDDR_Reg->MCMD = (start_cmd | (rank<<20) | arg | cmd);
+    for (i = 0; i < 10; i ++) {;}
+    while(pDDR_Reg->MCMD & start_cmd);
+}
 
-    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (1<<2);  //disable DDR PHY clock
+//¶ÔtypeÀàÐ͵ÄDDRµÄ¼¸¸öcs½øÐÐDTT
+//0  DTT³É¹¦
+//!0 DTTʧ°Ü
+static uint32_t __sramlocalfunc data_training(void)
+{
+    uint32 i,value;
 
-    pCRU_Reg->CRU_MODE_CON = (0x3<<((1*4) +  16)) | (0x0<<(1*4));            //PLL slow-mode
+    value = pDDR_Reg->TREFI;
+    pDDR_Reg->TREFI = 0;
     
-    pPHY_Reg->ACDLLCR |= 0x80000000;
-    pPHY_Reg->DATX8[0].DXDLLCR |= 0x80000000;
-    pPHY_Reg->DATX8[1].DXDLLCR |= 0x80000000;
-    pPHY_Reg->DATX8[2].DXDLLCR |= 0x80000000;
-    pPHY_Reg->DATX8[3].DXDLLCR |= 0x80000000;
-    pPHY_Reg->PIR = INIT | DLLBYP;
+    pPHY_Reg->PIR = INIT | CLRSR;
+    delayus(1);
+    pPHY_Reg->PIR = INIT | QSTRN | LOCKBYP | ZCALBYP | CLRSR;
     for (i = 0; i < 10; i ++) {;}
-    while((pPHY_Reg->PGSR & IDONE) != IDONE);
+    while((pPHY_Reg->PGSR & (IDONE | DTDONE)) != (IDONE | DTDONE));
+    
+    pDDR_Reg->TREFI = value>>3;
+    delayus(20);
+    pDDR_Reg->TREFI = value;
+
+    if(pPHY_Reg->PGSR & DTERR)
+    {
+        return (-1);
+    }
+    else
+    {
+        return 0;
+    }
 }
 
-__sramfunc void ddr_selfrefresh_exit(void)
+static void __sramlocalfunc phy_dll_bypass_set(uint32 freq)
 {
-    uint32 i;
+    if(freq<=150)
+    {
+        pPHY_Reg->DLLGCR &= ~(1<<23);
+        pPHY_Reg->ACDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[0].DXDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[1].DXDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[2].DXDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[3].DXDLLCR |= 0x80000000;
+    }
+    else if(freq<=250)
+    {
+        pPHY_Reg->DLLGCR |= (1<<23);
+        pPHY_Reg->ACDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[0].DXDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[1].DXDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[2].DXDLLCR |= 0x80000000;
+        pPHY_Reg->DATX8[3].DXDLLCR |= 0x80000000;
+    }
+    else
+    {
+        pPHY_Reg->DLLGCR &= ~(1<<23);
+        pPHY_Reg->ACDLLCR &= ~0x80000000;
+        pPHY_Reg->DATX8[0].DXDLLCR &= ~0x80000000;
+        pPHY_Reg->DATX8[1].DXDLLCR &= ~0x80000000;
+        pPHY_Reg->DATX8[2].DXDLLCR &= ~0x80000000;
+        pPHY_Reg->DATX8[3].DXDLLCR &= ~0x80000000;
+    }
+}
+
+static __sramdata uint32_t clkr;
+static __sramdata uint32_t clkf;
+static __sramdata uint32_t clkod;
+/*****************************************
+NR   NO     NF               Fout                       freq Step     finally use
+1    8      12.5 - 62.5      37.5MHz  - 187.5MHz        3MHz          50MHz   <= 150MHz
+1    6      12.5 - 62.5      50MHz    - 250MHz          4MHz          150MHz  <= 200MHz
+1    4      12.5 - 62.5      75MHz    - 375MHz          6MHz          200MHz  <= 300MHz
+1    2      12.5 - 62.5      150MHz   - 750MHz          12MHz         300MHz  <= 600MHz
+1    1      12.5 - 62.5      300MHz   - 1500MHz         24MHz         600MHz  <= 1200MHz      
+******************************************/
+static uint32_t __sramlocalfunc ddr_set_pll(uint32_t nMHz, uint32_t set)
+{
+    uint32_t ret = 0;
+    int delay = 1000;
+    uint32_t pll_id=1;  //DPLL
+    //NOÒ»¶¨ÒªÅ¼Êý,NR¾¡Á¿Ð¡£¬jitter¾Í»áС
     
-    pPHY_Reg->ACDLLCR &= ~0x80000000;
-    pPHY_Reg->DATX8[0].DXDLLCR &= ~0x80000000;
-    pPHY_Reg->DATX8[1].DXDLLCR &= ~0x80000000;
-    pPHY_Reg->DATX8[2].DXDLLCR &= ~0x80000000;
-    pPHY_Reg->DATX8[3].DXDLLCR &= ~0x80000000;
-    pPHY_Reg->PIR = INIT;
-    for (i = 0; i < 10; i ++) {;}
-    while((pPHY_Reg->PGSR & IDONE) != IDONE);
+    if(nMHz == 24)
+    {
+        ret = 24;
+        goto out;
+    }
+    
+    if(!set)
+    {
+        if(nMHz <= 150)
+        {
+            clkod = 8;
+        }
+        else if(nMHz <= 200)
+        {
+            clkod = 6;
+        }
+        else if(nMHz <= 300)
+        {
+            clkod = 4;
+        }
+        else if(nMHz <= 600)
+        {
+            clkod = 2;
+        }
+        else
+        {
+            clkod = 1;
+        }
+        clkr = 1;
+        clkf=(nMHz*clkr*clkod)/24;
+        ret = (24*clkf)/(clkr*clkod);
+    }
+    else
+    {
+        pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) +  16)) | (0x0<<(pll_id*4));            //PLL slow-mode
+    
+        pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_RESET;
+        pCRU_Reg->CRU_PLL_CON[pll_id][0] = NR(clkr) | NO(clkod);
+        pCRU_Reg->CRU_PLL_CON[pll_id][1] = NF(clkf);
+        pCRU_Reg->CRU_PLL_CON[pll_id][2] = NB(clkf>>1);
+        delayus(1);
+        pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_DE_RESET;
 
-    pCRU_Reg->CRU_MODE_CON = (0x3<<((1*4) +  16))  | (0x1<<(1*4));            //PLL normal
-    Delay_us(10);   //wait pll lock
+        while (delay > 0) 
+        {
+           delayus(1);
+               //if (pGRF_Reg->GRF_SOC_STATUS0 & (0x1<<4))
+               //      break;
+               delay--;
+       }
+        
+        pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
+                                                  | (0x0<<8)     //clk_ddr_src = DDR PLL
+                                                  | 0;           //clk_ddr_src:clk_ddrphy = 1:1
+        
+        pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) +  16))  | (0x1<<(pll_id*4));            //PLL normal
+    }
+out:
+    return ret;
+}
 
-    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (0<<2);  //enable DDR PHY clock
-    Delay_us(10);   //wait
+static __sramfunc void ddr_adjust_config(uint32_t dram_type)
+{
+    uint32 value;
+    unsigned long save_sp;
+
+    DDR_SAVE_SP(save_sp);
+
+    //get data training address before idle port
+    value = get_datatraing_addr();
+
+    //enter config state
+    idle_port();
+    move_to_Config_state();
+
+    //set data training address
+    pPHY_Reg->DTAR = value;
+
+    //set auto power down idle
+    pDDR_Reg->MCFG=(pDDR_Reg->MCFG&0xffff00ff)|(0x40<<8);
+
+    //adjust DRV and ODT
+    if(dram_type == DDR3)
+    {
+        pPHY_Reg->ZQ0CR[1] = 0x1B;  //DS=40ohm,ODT=120ohm
+        pPHY_Reg->ZQ0CR[0] |= (1<<30);  //trigger
+    }
+    if (dram_type == DDR2)
+    {
+        pPHY_Reg->ZQ0CR[1] = 0x4B;  //DS=40ohm,ODT=75ohm
+        pPHY_Reg->ZQ0CR[0] |= (1<<30);  //trigger
+    }
+    else
+    {
+        pPHY_Reg->ZQ0CR[1] = 0x1B;  //DS=40ohm,ODT=120ohm
+        pPHY_Reg->ZQ0CR[0] |= (1<<30);  //trigger
+    }    
+    delayus(10);
+    while(!(pPHY_Reg->ZQ0SR[0] & (0x1u<<31)));
+    if(pPHY_Reg->ZQ0SR[0] & (0x1u<<30))
+    {
+        ddr_print("ZQCR error!\n");
+    }
+
+    //enter access state
+    move_to_Access_state();
+    deIdle_port();
+
+    DDR_RESTORE_SP(save_sp);
+}
+
+static uint32_t ddr_get_parameter(uint32_t nMHz)
+{
+    uint32_t tmp;
+    uint32_t ret = 0;
+    DDR_TIMING_T  *p_ddr_timing=&ddr_timing;
+
+    p_ddr_timing->pctl_timing.togcnt1u = nMHz;
+    p_ddr_timing->pctl_timing.togcnt100n = nMHz/10;
+    p_ddr_timing->pctl_timing.tinit = 200;
+    p_ddr_timing->pctl_timing.trsth = 500;
+
+    if(mem_type == DDR3)
+    {
+        if(ddr_type > DDR3_DEFAULT){
+            ret = -1;
+            goto out;
+        }
+
+        #define DDR3_tREFI_7_8_us    (39)
+        #define DDR3_tMRD            (4)
+        #define DDR3_tRFC_512Mb      (90)
+        #define DDR3_tRFC_1Gb        (110)
+        #define DDR3_tRFC_2Gb        (160)
+        #define DDR3_tRFC_4Gb        (300)
+        #define DDR3_tRFC_8Gb        (350)
+        #define DDR3_tRTW            (2)   //register min valid value
+        #define DDR3_tRAS            (37)
+        #define DDR3_tRRD            (10)
+        #define DDR3_tRTP            (7)
+        #define DDR3_tWR             (15)
+        #define DDR3_tWTR            (7)
+        #define DDR3_tXP             (7)
+        #define DDR3_tXPDLL          (24)
+        #define DDR3_tZQCS           (80)
+        #define DDR3_tZQCSI          (10000)
+        #define DDR3_tDQS            (1)
+        #define DDR3_tCKSRE          (10)
+        #define DDR3_tCKE_400MHz     (7)
+        #define DDR3_tCKE_533MHz     (6)
+        #define DDR3_tMOD            (15)
+        #define DDR3_tRSTL           (100)
+        #define DDR3_tZQCL           (320)
+        #define DDR3_tDLLK           (512)
+
+        al = 0;
+        bl = 8;
+        if(nMHz <= 330)
+        {
+            tmp = 0;
+        }
+        else if(nMHz<=400)
+        {
+            tmp = 1;
+        }
+        else if(nMHz<=533)
+        {
+            tmp = 2;
+        }
+        else //666MHz
+        {
+            tmp = 3;
+        }
+        cl = ddr3_cl_cwl[ddr_type][tmp] >> 16;
+        cwl = ddr3_cl_cwl[ddr_type][tmp] & 0x0ff;
+        if(cl == 0)
+            ret = -4;
+        p_ddr_timing->phy_timing.mr[1] = DDR3_DS_40 | DDR3_Rtt_Nom_120;
+        p_ddr_timing->phy_timing.mr[2] = DDR3_MR2_CWL(cwl) /* | DDR3_Rtt_WR_60 */;
+        p_ddr_timing->phy_timing.mr[3] = 0;
+        /**************************************************
+         * PCTL Timing
+         **************************************************/
+        /*
+         * tREFI, average periodic refresh interval, 7.8us
+         */
+        p_ddr_timing->pctl_timing.trefi = DDR3_tREFI_7_8_us;
+        /*
+         * tMRD, 4 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrd = DDR3_tMRD & 0x7;
+        p_ddr_timing->phy_timing.dtpr0.b.tMRD = DDR3_tMRD-4;
+        /*
+         * tRFC, 90ns(512Mb),110ns(1Gb),160ns(2Gb),300ns(4Gb),350ns(8Gb)
+         */
+        if(capability <= 0x4000000)         // 512Mb 90ns
+        {
+            tmp = DDR3_tRFC_512Mb;
+        }
+        else if(capability <= 0x8000000)    // 1Gb 110ns
+        {
+            tmp = DDR3_tRFC_1Gb;
+        }
+        else if(capability <= 0x10000000)   // 2Gb 160ns
+        {
+            tmp = DDR3_tRFC_2Gb;
+        }
+        else if(capability <= 0x20000000)   // 4Gb 300ns
+        {
+            tmp = DDR3_tRFC_4Gb;
+        }
+        else    // 8Gb  350ns
+        {
+            tmp = DDR3_tRFC_8Gb;
+        }
+        p_ddr_timing->pctl_timing.trfc = (tmp*nMHz+999)/1000;
+        p_ddr_timing->phy_timing.dtpr1.b.tRFC = ((tmp*nMHz+999)/1000)&0xFF;
+        /*
+         * tXSR, =tDLLK=512 tCK
+         */
+        p_ddr_timing->pctl_timing.texsr = DDR3_tDLLK;
+        p_ddr_timing->phy_timing.dtpr2.b.tXS = DDR3_tDLLK;
+        /*
+         * tRP=CL
+         */
+        p_ddr_timing->pctl_timing.trp = cl;
+        p_ddr_timing->phy_timing.dtpr0.b.tRP = cl;
+        /*
+         * WrToMiss=WL*tCK + tWR + tRP + tRCD
+         */
+        p_ddr_timing->noc_timing.b.WrToMiss = ((cwl+((DDR3_tWR*nMHz+999)/1000)+cl+cl)&0x3F);
+        /*
+         * tRC=tRAS+tRP
+         */
+        p_ddr_timing->pctl_timing.trc = ((((ddr3_tRC_tFAW[ddr_type]>>16)*nMHz+999)/1000)&0x3F);
+        p_ddr_timing->noc_timing.b.ActToAct = ((((ddr3_tRC_tFAW[ddr_type]>>16)*nMHz+999)/1000)&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRC = (((ddr3_tRC_tFAW[ddr_type]>>16)*nMHz+999)/1000)&0xF;
+
+        p_ddr_timing->pctl_timing.trtw = (cl+2-cwl);//DDR3_tRTW;
+        p_ddr_timing->phy_timing.dtpr1.b.tRTW = 0;
+        p_ddr_timing->noc_timing.b.RdToWr = ((cl+2-cwl)&0x1F);
+        p_ddr_timing->pctl_timing.tal = al;
+        p_ddr_timing->pctl_timing.tcl = cl;
+        p_ddr_timing->pctl_timing.tcwl = cwl;
+        /*
+         * tRAS, 37.5ns(400MHz)     37.5ns(533MHz)
+         */
+        p_ddr_timing->pctl_timing.tras = (((DDR3_tRAS*nMHz+(nMHz>>1)+999)/1000)&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRAS = ((DDR3_tRAS*nMHz+(nMHz>>1)+999)/1000)&0x1F;
+        /*
+         * tRCD=CL
+         */
+        p_ddr_timing->pctl_timing.trcd = cl;
+        p_ddr_timing->phy_timing.dtpr0.b.tRCD = cl;
+        /*
+         * tRRD = max(4nCK, 7.5ns), DDR3-1066(1K), DDR3-1333(2K), DDR3-1600(2K)
+         *        max(4nCK, 10ns), DDR3-800(1K,2K), DDR3-1066(2K)
+         *        max(4nCK, 6ns), DDR3-1333(1K), DDR3-1600(1K)
+         *
+         */
+        tmp = ((DDR3_tRRD*nMHz+999)/1000);
+        if(tmp < 4)
+        {
+            tmp = 4;
+        }
+        p_ddr_timing->pctl_timing.trrd = (tmp&0xF);
+        p_ddr_timing->phy_timing.dtpr0.b.tRRD = tmp&0xF;
+        /*
+         * tRTP, max(4 tCK,7.5ns)
+         */
+        tmp = ((DDR3_tRTP*nMHz+(nMHz>>1)+999)/1000);
+        if(tmp < 4)
+        {
+            tmp = 4;
+        }
+        p_ddr_timing->pctl_timing.trtp = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tRTP = tmp;
+        /*
+         * RdToMiss=tRTP+tRP + tRCD - (BL/2 * tCK)
+         */
+        p_ddr_timing->noc_timing.b.RdToMiss = ((tmp+cl+cl-(bl>>1))&0x3F);
+        /*
+         * tWR, 15ns
+         */
+        tmp = ((DDR3_tWR*nMHz+999)/1000);
+        p_ddr_timing->pctl_timing.twr = tmp&0x1F;
+        if(tmp<9)
+            tmp = tmp - 4;
+        else
+            tmp = tmp>>1;
+        p_ddr_timing->phy_timing.mr[0] = DDR3_BL8 | DDR3_CL(cl) | DDR3_WR(tmp);
+
+        /*
+         * tWTR, max(4 tCK,7.5ns)
+         */
+        tmp = ((DDR3_tWTR*nMHz+(nMHz>>1)+999)/1000);
+        if(tmp < 4)
+        {
+            tmp = 4;
+        }
+        p_ddr_timing->pctl_timing.twtr = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tWTR = tmp&0x7;
+        p_ddr_timing->noc_timing.b.WrToRd = ((tmp+cwl)&0x1F);
+        /*
+         * tXP, max(3 tCK, 7.5ns)(<933MHz)
+         */
+        tmp = ((DDR3_tXP*nMHz+(nMHz>>1)+999)/1000);
+        if(tmp < 3)
+        {
+            tmp = 3;
+        }
+        p_ddr_timing->pctl_timing.txp = tmp&0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tXP = tmp&0x1F;
+        /*
+         * tXPDLL, max(10 tCK,24ns)
+         */
+        tmp = ((DDR3_tXPDLL*nMHz+999)/1000);
+        if(tmp < 10)
+        {
+            tmp = 10;
+        }
+        p_ddr_timing->pctl_timing.txpdll = tmp & 0x3F;
+        /*
+         * tZQCS, max(64 tCK, 80ns)
+         */
+        tmp = ((DDR3_tZQCS*nMHz+999)/1000);
+        if(tmp < 64)
+        {
+            tmp = 64;
+        }
+        p_ddr_timing->pctl_timing.tzqcs = tmp&0x7F;
+        /*
+         * tZQCSI,
+         */
+        p_ddr_timing->pctl_timing.tzqcsi = DDR3_tZQCSI;
+        /*
+         * tDQS,
+         */
+        p_ddr_timing->pctl_timing.tdqs = DDR3_tDQS;
+        /*
+         * tCKSRE, max(5 tCK, 10ns)
+         */
+        tmp = ((DDR3_tCKSRE*nMHz+999)/1000);
+        if(tmp < 5)
+        {
+            tmp = 5;
+        }
+        p_ddr_timing->pctl_timing.tcksre = tmp & 0x1F;
+        /*
+         * tCKSRX, max(5 tCK, 10ns)
+         */
+        p_ddr_timing->pctl_timing.tcksrx = tmp & 0x1F;
+        /*
+         * tCKE, max(3 tCK,7.5ns)(400MHz) max(3 tCK,5.625ns)(533MHz)
+         */
+        if(nMHz>=533)
+        {
+            tmp = ((DDR3_tCKE_533MHz*nMHz+999)/1000);
+        }
+        else
+        {
+            tmp = ((DDR3_tCKE_400MHz*nMHz+(nMHz>>1)+999)/1000);
+        }
+        if(tmp < 3)
+        {
+            tmp = 3;
+        }
+        p_ddr_timing->pctl_timing.tcke = tmp & 0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tCKE = tmp;
+        /*
+         * tCKESR, =tCKE + 1tCK
+         */
+        p_ddr_timing->pctl_timing.tckesr = (tmp+1)&0xF;
+        /*
+         * tMOD, max(12 tCK,15ns)
+         */
+        tmp = ((DDR3_tMOD*nMHz+999)/1000);
+        if(tmp < 12)
+        {
+            tmp = 12;
+        }
+        p_ddr_timing->pctl_timing.tmod = tmp&0x1F;
+        p_ddr_timing->phy_timing.dtpr1.b.tMOD = tmp;
+        /*
+         * tRSTL, 100ns
+         */
+        p_ddr_timing->pctl_timing.trstl = ((DDR3_tRSTL*nMHz+999)/1000)&0x7F;
+        /*
+         * tZQCL, max(256 tCK, 320ns)
+         */
+        tmp = ((DDR3_tZQCL*nMHz+999)/1000);
+        if(tmp < 256)
+        {
+            tmp = 256;
+        }
+        p_ddr_timing->pctl_timing.tzqcl = tmp&0x3FF;
+        /*
+         * tMRR, 0 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrr = 0;
+        /*
+         * tDPD, 0
+         */
+        p_ddr_timing->pctl_timing.tdpd = 0;
+
+        /**************************************************
+         * PHY Timing
+         **************************************************/
+        /*
+         * tCCD, BL/2 for DDR2 and 4 for DDR3
+         */
+        p_ddr_timing->phy_timing.dtpr0.b.tCCD = 0;
+        /*
+         * tDQSCKmax,5.5ns
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tDQSCKmax = 0;
+        /*
+         * tRTODT, 0:ODT may be turned on immediately after read post-amble
+         *         1:ODT may not be turned on until one clock after the read post-amble
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tRTODT = 1;
+        /*
+         * tFAW,40ns(400MHz 1KB page) 37.5ns(533MHz 1KB page) 50ns(400MHz 2KB page)   50ns(533MHz 2KB page)
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tFAW = (((ddr3_tRC_tFAW[ddr_type]&0x0ff)*nMHz+999)/1000)&0x7F;
+        /*
+         * tAOND_tAOFD
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tAOND = 0;
+        /*
+         * tDLLK,512 tCK
+         */
+        p_ddr_timing->phy_timing.dtpr2.b.tDLLK = DDR3_tDLLK;
+        /**************************************************
+         * NOC Timing
+         **************************************************/
+        p_ddr_timing->noc_timing.b.BurstLen = ((bl>>1)&0x7);
+    }
+    else if(mem_type == LPDDR2)
+    {
+        #define LPDDR2_tREFI_3_9_us    (38)
+        #define LPDDR2_tREFI_7_8_us    (78)
+        #define LPDDR2_tMRD            (5)  //tCK
+        #define LPDDR2_tRFC_8Gb        (210)  //ns
+        #define LPDDR2_tRFC_4Gb        (130)  //ns
+        #define LPDDR2_tRP_4_BANK               (24)  //ns
+        #define LPDDR2_tRPab_SUB_tRPpb_4_BANK   (0)
+        #define LPDDR2_tRP_8_BANK               (27)  //ns
+        #define LPDDR2_tRPab_SUB_tRPpb_8_BANK   (3)
+        #define LPDDR2_tRTW          (1)   //tCK register min valid value
+        #define LPDDR2_tRAS          (42)  //ns
+        #define LPDDR2_tRCD          (24)  //ns
+        #define LPDDR2_tRRD          (10)  //ns
+        #define LPDDR2_tRTP          (7)   //ns
+        #define LPDDR2_tWR           (15)  //ns
+        #define LPDDR2_tWTR_GREAT_200MHz         (7)  //ns
+        #define LPDDR2_tWTR_LITTLE_200MHz        (10) //ns
+        #define LPDDR2_tXP           (7)  //ns
+        #define LPDDR2_tXPDLL        (0)
+        #define LPDDR2_tZQCS         (90) //ns
+        #define LPDDR2_tZQCSI        (10000)
+        #define LPDDR2_tDQS          (1)
+        #define LPDDR2_tCKSRE        (1)  //tCK
+        #define LPDDR2_tCKSRX        (2)  //tCK
+        #define LPDDR2_tCKE          (3)  //tCK
+        #define LPDDR2_tMOD          (0)
+        #define LPDDR2_tRSTL         (0)
+        #define LPDDR2_tZQCL         (360)  //ns
+        #define LPDDR2_tMRR          (2)    //tCK
+        #define LPDDR2_tCKESR        (15)   //ns
+        #define LPDDR2_tDPD_US       (500)
+        #define LPDDR2_tFAW_GREAT_200MHz    (50)  //ns
+        #define LPDDR2_tFAW_LITTLE_200MHz   (60)  //ns
+        #define LPDDR2_tDLLK         (2)  //tCK
+        #define LPDDR2_tDQSCK_MAX    (5)  //ns
+        #define LPDDR2_tDQSCK_MIN    (2)  //ns
+        #define LPDDR2_tDQSS         (1)  //tCK
+
+        al = 0;
+        bl = 8;
+        /*     1066 933 800 667 533 400 333
+         * RL,   8   7   6   5   4   3   3
+         * WL,   4   4   3   2   2   1   1
+         */
+        if(nMHz<=200)
+        {
+            cl = 3;
+            cwl = 1;
+            p_ddr_timing->phy_timing.mr[2] = LPDDR2_RL3_WL1;
+        }
+        else if(nMHz<=266)
+        {
+            cl = 4;
+            cwl = 2;
+            p_ddr_timing->phy_timing.mr[2] = LPDDR2_RL4_WL2;
+        }
+        else if(nMHz<=333)
+        {
+            cl = 5;
+            cwl = 2;
+            p_ddr_timing->phy_timing.mr[2] = LPDDR2_RL5_WL2;
+        }
+        else if(nMHz<=400)
+        {
+            cl = 6;
+            cwl = 3;
+            p_ddr_timing->phy_timing.mr[2] = LPDDR2_RL6_WL3;
+        }
+        else if(nMHz<=466)
+        {
+            cl = 7;
+            cwl = 4;
+            p_ddr_timing->phy_timing.mr[2] = LPDDR2_RL7_WL4;
+        }
+        else //(nMHz<=1066)
+        {
+            cl = 8;
+            cwl = 4;
+            p_ddr_timing->phy_timing.mr[2] = LPDDR2_RL8_WL4;
+        }
+        p_ddr_timing->phy_timing.mr[3] = LPDDR2_DS_48;
+        p_ddr_timing->phy_timing.mr[0] = 0;
+        /**************************************************
+         * PCTL Timing
+         **************************************************/
+        /*
+         * tREFI, average periodic refresh interval, 15.6us(<256Mb) 7.8us(256Mb-1Gb) 3.9us(2Gb-8Gb)
+         */
+        if(capability >= 0x10000000)   // 2Gb
+        {
+            p_ddr_timing->pctl_timing.trefi = LPDDR2_tREFI_3_9_us;
+        }
+        else
+        {
+            p_ddr_timing->pctl_timing.trefi = LPDDR2_tREFI_7_8_us;
+        }
+
+        /*
+         * tMRD, (=tMRW), 5 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrd = LPDDR2_tMRD & 0x7;
+        p_ddr_timing->phy_timing.dtpr0.b.tMRD = 3;
+        /*
+         * tRFC, 90ns(<=512Mb) 130ns(1Gb-4Gb) 210ns(8Gb)
+         */
+        if(capability >= 0x40000000)   // 8Gb
+        {
+            p_ddr_timing->pctl_timing.trfc = (LPDDR2_tRFC_8Gb*nMHz+999)/1000;
+            /*
+             * tXSR, tRFC+10ns
+             */
+            p_ddr_timing->pctl_timing.texsr = (((LPDDR2_tRFC_8Gb+10)*nMHz+999)/1000)&0x3FF;
+            p_ddr_timing->phy_timing.dtpr1.b.tRFC = ((LPDDR2_tRFC_8Gb*nMHz+999)/1000)&0xFF;
+            p_ddr_timing->phy_timing.dtpr2.b.tXS = (((LPDDR2_tRFC_8Gb+10)*nMHz+999)/1000)&0x3FF;
+        }
+        else
+        {
+            p_ddr_timing->pctl_timing.trfc = (LPDDR2_tRFC_4Gb*nMHz+999)/1000;
+            p_ddr_timing->pctl_timing.texsr = (((LPDDR2_tRFC_4Gb+10)*nMHz+999)/1000)&0x3FF;
+            p_ddr_timing->phy_timing.dtpr1.b.tRFC = ((LPDDR2_tRFC_4Gb*nMHz+999)/1000)&0xFF;
+            p_ddr_timing->phy_timing.dtpr2.b.tXS = (((LPDDR2_tRFC_4Gb+10)*nMHz+999)/1000)&0x3FF;
+        }
+
+        /*
+         * tRP, 4-bank:15ns(Fast) 18ns(Typ) 24ns(Slow), 8-bank:18ns(Fast) 21ns(Typ) 27ns(Slow)
+         */
+        if(pPHY_Reg->DCR.b.DDR8BNK)
+        {
+            p_ddr_timing->pctl_timing.trp = ((((LPDDR2_tRPab_SUB_tRPpb_8_BANK*nMHz+999)/1000) & 0x3)<<16) | (((LPDDR2_tRP_8_BANK*nMHz+999)/1000)&0xF);
+            p_ddr_timing->phy_timing.dtpr0.b.tRP = ((LPDDR2_tRP_8_BANK*nMHz+999)/1000);
+            /*
+             * WrToMiss=WL*tCK + tDQSS + tWR + tRP + tRCD
+             */
+            p_ddr_timing->noc_timing.b.WrToMiss = ((cwl+LPDDR2_tDQSS+(((LPDDR2_tWR+LPDDR2_tRP_8_BANK+LPDDR2_tRCD)*nMHz+999)/1000))&0x3F);
+            /*
+             * RdToMiss=tRTP + tRP + tRCD - (BL/2 * tCK)
+             */
+            p_ddr_timing->noc_timing.b.RdToMiss = (((((LPDDR2_tRTP+LPDDR2_tRP_8_BANK+LPDDR2_tRCD)*nMHz+(nMHz>>1)+999)/1000)-(bl>>1))&0x3F);
+            /*
+             * tRC=tRAS+tRP
+             */
+            p_ddr_timing->pctl_timing.trc = ((((LPDDR2_tRP_8_BANK+LPDDR2_tRAS)*nMHz+999)/1000)&0x3F);
+            p_ddr_timing->noc_timing.b.ActToAct = ((((LPDDR2_tRP_8_BANK+LPDDR2_tRAS)*nMHz+999)/1000)&0x3F);
+            p_ddr_timing->phy_timing.dtpr0.b.tRC = (((LPDDR2_tRP_8_BANK+LPDDR2_tRAS)*nMHz+999)/1000)&0xF;
+        }
+        else
+        {
+            p_ddr_timing->pctl_timing.trp = (LPDDR2_tRPab_SUB_tRPpb_4_BANK<<16) | (((LPDDR2_tRP_4_BANK*nMHz+999)/1000)&0xF);
+            p_ddr_timing->phy_timing.dtpr0.b.tRP = ((LPDDR2_tRP_4_BANK*nMHz+999)/1000);
+            p_ddr_timing->noc_timing.b.WrToMiss = ((cwl+LPDDR2_tDQSS+(((LPDDR2_tWR+LPDDR2_tRP_4_BANK+LPDDR2_tRCD)*nMHz+999)/1000))&0x3F);
+            p_ddr_timing->noc_timing.b.RdToMiss = (((((LPDDR2_tRTP+LPDDR2_tRP_4_BANK+LPDDR2_tRCD)*nMHz+(nMHz>>1)+999)/1000)-(bl>>1))&0x3F);
+            p_ddr_timing->pctl_timing.trc = ((((LPDDR2_tRP_4_BANK+LPDDR2_tRAS)*nMHz+999)/1000)&0x3F);
+            p_ddr_timing->noc_timing.b.ActToAct = ((((LPDDR2_tRP_4_BANK+LPDDR2_tRAS)*nMHz+999)/1000)&0x3F);
+            p_ddr_timing->phy_timing.dtpr0.b.tRC = (((LPDDR2_tRP_4_BANK+LPDDR2_tRAS)*nMHz+999)/1000)&0xF;
+        }
+
+        p_ddr_timing->pctl_timing.trtw = (cl+((LPDDR2_tDQSCK_MIN*nMHz+(nMHz>>1)+999)/1000)-cwl);//LPDDR2_tRTW;
+        p_ddr_timing->phy_timing.dtpr1.b.tRTW = 0;
+        /*
+         * RdToWr=RL+tDQSCK-WL
+         */
+        p_ddr_timing->noc_timing.b.RdToWr = ((cl+((LPDDR2_tDQSCK_MIN*nMHz+(nMHz>>1)+999)/1000)-cwl)&0x1F);
+        p_ddr_timing->pctl_timing.tal = al;
+        p_ddr_timing->pctl_timing.tcl = cl;
+        p_ddr_timing->pctl_timing.tcwl = cwl;
+        /*
+         * tRAS, 42ns
+         */
+        p_ddr_timing->pctl_timing.tras = (((LPDDR2_tRAS*nMHz+999)/1000)&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRAS = ((LPDDR2_tRAS*nMHz+999)/1000)&0x1F;
+        /*
+         * tRCD, 15ns(Fast) 18ns(Typ) 24ns(Slow)
+         */
+        p_ddr_timing->pctl_timing.trcd = (((LPDDR2_tRCD*nMHz+999)/1000)&0xF);
+        p_ddr_timing->phy_timing.dtpr0.b.tRCD = ((LPDDR2_tRCD*nMHz+999)/1000)&0xF;
+        /*
+         * tRRD, 10ns
+         */
+        p_ddr_timing->pctl_timing.trrd = (((LPDDR2_tRRD*nMHz+999)/1000)&0xF);
+        p_ddr_timing->phy_timing.dtpr0.b.tRRD = ((LPDDR2_tRRD*nMHz+999)/1000)&0xF;
+        /*
+         * tRTP, 7.5ns
+         */
+        tmp = ((LPDDR2_tRTP*nMHz+(nMHz>>1)+999)/1000);
+        p_ddr_timing->pctl_timing.trtp = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tRTP = (tmp<2) ? 2 : tmp;
+        /*
+         * tWR, 15ns
+         */
+        p_ddr_timing->pctl_timing.twr = ((LPDDR2_tWR*nMHz+999)/1000)&0x1F;
+        p_ddr_timing->phy_timing.mr[1] = LPDDR2_BL8 | LPDDR2_nWR(((LPDDR2_tWR*nMHz+999)/1000));
+        /*
+         * tWTR, 7.5ns(533-266MHz)  10ns(200-166MHz)
+         */
+        if(nMHz > 200)
+        {
+            p_ddr_timing->pctl_timing.twtr = ((LPDDR2_tWTR_GREAT_200MHz*nMHz+(nMHz>>1)+999)/1000)&0xF;
+            p_ddr_timing->phy_timing.dtpr0.b.tWTR = ((LPDDR2_tWTR_GREAT_200MHz*nMHz+(nMHz>>1)+999)/1000)&0x7;
+            /*
+             * WrToRd=WL+tDQSS+tWTR
+             */
+            p_ddr_timing->noc_timing.b.WrToRd = ((LPDDR2_tDQSS+((LPDDR2_tWTR_GREAT_200MHz*nMHz+(nMHz>>1)+999)/1000)+cwl)&0x1F);
+        }
+        else
+        {
+            p_ddr_timing->pctl_timing.twtr = ((LPDDR2_tWTR_LITTLE_200MHz*nMHz+999)/1000)&0xF;
+            p_ddr_timing->phy_timing.dtpr0.b.tWTR = ((LPDDR2_tWTR_LITTLE_200MHz*nMHz+999)/1000)&0x7;
+            p_ddr_timing->noc_timing.b.WrToRd = ((LPDDR2_tDQSS+((LPDDR2_tWTR_LITTLE_200MHz*nMHz+999)/1000)+cwl)&0x1F);
+        }
+        /*
+         * tXP, 7.5ns
+         */
+        p_ddr_timing->pctl_timing.txp = ((LPDDR2_tXP*nMHz+(nMHz>>1)+999)/1000)&0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tXP = ((LPDDR2_tXP*nMHz+(nMHz>>1)+999)/1000)&0x1F;
+        /*
+         * tXPDLL, 0ns
+         */
+        p_ddr_timing->pctl_timing.txpdll = LPDDR2_tXPDLL;
+        /*
+         * tZQCS, 90ns
+         */
+        p_ddr_timing->pctl_timing.tzqcs = ((LPDDR2_tZQCS*nMHz+999)/1000)&0x7F;
+        /*
+         * tZQCSI,
+         */
+        if(pDDR_Reg->MCFG &= lpddr2_s4)
+        {
+            p_ddr_timing->pctl_timing.tzqcsi = LPDDR2_tZQCSI;
+        }
+        else
+        {
+            p_ddr_timing->pctl_timing.tzqcsi = 0;
+        }
+        /*
+         * tDQS,
+         */
+        p_ddr_timing->pctl_timing.tdqs = LPDDR2_tDQS;
+        /*
+         * tCKSRE, 1 tCK
+         */
+        p_ddr_timing->pctl_timing.tcksre = LPDDR2_tCKSRE;
+        /*
+         * tCKSRX, 2 tCK
+         */
+        p_ddr_timing->pctl_timing.tcksrx = LPDDR2_tCKSRX;
+        /*
+         * tCKE, 3 tCK
+         */
+        p_ddr_timing->pctl_timing.tcke = LPDDR2_tCKE;
+        p_ddr_timing->phy_timing.dtpr2.b.tCKE = LPDDR2_tCKE;
+        /*
+         * tMOD, 0 tCK
+         */
+        p_ddr_timing->pctl_timing.tmod = LPDDR2_tMOD;
+        p_ddr_timing->phy_timing.dtpr1.b.tMOD = LPDDR2_tMOD;
+        /*
+         * tRSTL, 0 tCK
+         */
+        p_ddr_timing->pctl_timing.trstl = LPDDR2_tRSTL;
+        /*
+         * tZQCL, 360ns
+         */
+        p_ddr_timing->pctl_timing.tzqcl = ((LPDDR2_tZQCL*nMHz+999)/1000)&0x3FF;
+        /*
+         * tMRR, 2 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrr = LPDDR2_tMRR;
+        /*
+         * tCKESR, 15ns
+         */
+        p_ddr_timing->pctl_timing.tckesr = ((LPDDR2_tCKESR*nMHz+999)/1000)&0xF;
+        /*
+         * tDPD, 500us
+         */
+        p_ddr_timing->pctl_timing.tdpd = LPDDR2_tDPD_US;
+
+        /**************************************************
+         * PHY Timing
+         **************************************************/
+        /*
+         * tCCD, BL/2 for DDR2 and 4 for DDR3
+         */
+        p_ddr_timing->phy_timing.dtpr0.b.tCCD = 0;
+        /*
+         * tDQSCKmax,5.5ns
+         */
+        tmp = ((LPDDR2_tDQSCK_MAX*nMHz+(nMHz>>1)+999)/1000);      
+        p_ddr_timing->phy_timing.dtpr1.b.tDQSCKmax = 3;
+        /*
+         * tDQSCKmin,2.5ns
+         */
+        tmp = ((LPDDR2_tDQSCK_MAX*nMHz+(nMHz>>1))/1000);
+        p_ddr_timing->phy_timing.dtpr1.b.tDQSCK = 2;
+        /*
+         * tRTODT, 0:ODT may be turned on immediately after read post-amble
+         *         1:ODT may not be turned on until one clock after the read post-amble
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tRTODT = 1;
+        /*
+         * tFAW,50ns(200-533MHz)  60ns(166MHz)
+         */
+        if(nMHz>=200)
+        {
+            p_ddr_timing->phy_timing.dtpr1.b.tFAW = ((LPDDR2_tFAW_GREAT_200MHz*nMHz+999)/1000)&0x7F;
+        }
+        else
+        {
+            p_ddr_timing->phy_timing.dtpr1.b.tFAW = ((LPDDR2_tFAW_LITTLE_200MHz*nMHz+999)/1000)&0x7F;
+        }
+        /*
+         * tAOND_tAOFD
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tAOND = 0;
+        /*
+         * tDLLK,0
+         */
+        p_ddr_timing->phy_timing.dtpr2.b.tDLLK = LPDDR2_tDLLK;
+        /**************************************************
+         * NOC Timing
+         **************************************************/
+        p_ddr_timing->noc_timing.b.BurstLen = ((bl>>1)&0x7);
+    }
+    else if(mem_type == DDR2)
+    {
+        #define DDR2_tREFI_7_8_us     (78)
+        #define DDR2_tMRD             (2)
+        #define DDR2_tRFC_256Mb       (75)
+        #define DDR2_tRFC_512Mb       (105)
+        #define DDR2_tRFC_1Gb         (128)
+        #define DDR2_tRFC_2Gb         (195)
+        #define DDR2_tRFC_4Gb         (328)
+        #define DDR2_tRAS             (45)
+        #define DDR2_tRTW             (2)  //register min valid value
+        #define DDR2_tRRD             (10)
+        #define DDR2_tRTP             (7)
+        #define DDR2_tWR              (15)
+        #define DDR2_tWTR_LITTLE_200MHz   (10)
+        #define DDR2_tWTR_GREAT_200MHz    (7)
+        #define DDR2_tDQS             (1)
+        #define DDR2_tCKSRE           (1)
+        #define DDR2_tCKSRX           (1)
+        #define DDR2_tCKE             (3)
+        #define DDR2_tCKESR           DDR2_tCKE
+        #define DDR2_tMOD             (12)
+        #define DDR2_tFAW_333MHz      (50)
+        #define DDR2_tFAW_400MHz      (45)
+        #define DDR2_tDLLK            (200)
+
+        al = 0;
+        bl = 4;
+        if(nMHz <= 266)
+        {
+            cl =  4;
+        }
+        else if((nMHz > 266) && (nMHz <= 333))
+        {
+            cl =  5;
+        }
+        else if((nMHz > 333) && (nMHz <= 400))
+        {
+            cl =  6;
+        }
+        else // > 400MHz
+        {
+            cl =  7;
+        }
+        cwl = cl -1;
+        p_ddr_timing->phy_timing.mr[1] = DDR2_STR_REDUCE | DDR2_Rtt_Nom_75;
+        p_ddr_timing->phy_timing.mr[2] = 0;
+        p_ddr_timing->phy_timing.mr[3] = 0;
+        /**************************************************
+         * PCTL Timing
+         **************************************************/
+        /*
+         * tREFI, average periodic refresh interval, 7.8us
+         */
+        p_ddr_timing->pctl_timing.trefi = DDR2_tREFI_7_8_us;
+        /*
+         * tMRD, 2 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrd = DDR2_tMRD & 0x7;
+        p_ddr_timing->phy_timing.dtpr0.b.tMRD = DDR2_tMRD;
+        /*
+         * tRFC, 75ns(256Mb) 105ns(512Mb) 127.5ns(1Gb) 195ns(2Gb) 327.5ns(4Gb)
+         */
+        if(capability <= 0x2000000)  // 256Mb
+        {
+            tmp = DDR2_tRFC_256Mb;
+        }
+        else if(capability <= 0x4000000) // 512Mb
+        {
+            tmp = DDR2_tRFC_512Mb;
+        }
+        else if(capability <= 0x8000000)  // 1Gb
+        {
+            tmp = DDR2_tRFC_1Gb;
+        }
+        else if(capability <= 0x10000000)  // 2Gb
+        {
+            tmp = DDR2_tRFC_2Gb;
+        }
+        else  // 4Gb
+        {
+            tmp = DDR2_tRFC_4Gb;
+        }
+        p_ddr_timing->pctl_timing.trfc = (tmp*nMHz+999)/1000;
+        p_ddr_timing->phy_timing.dtpr1.b.tRFC = ((tmp*nMHz+999)/1000)&0xFF;
+        /*
+         * tXSR, max(tRFC+10,200 tCK)
+         */
+        tmp = (((tmp+10)*nMHz+999)/1000);
+        if(tmp<200)
+        {
+            tmp = 200;
+        }
+        p_ddr_timing->pctl_timing.texsr = tmp&0x3FF;
+        p_ddr_timing->phy_timing.dtpr2.b.tXS = tmp&0x3FF;
+        /*
+         * tRP=CL
+         */
+        if(pPHY_Reg->DCR.b.DDR8BNK)
+        {
+            p_ddr_timing->pctl_timing.trp = (1<<16) | cl;
+        }
+        else
+        {
+            p_ddr_timing->pctl_timing.trp = cl;
+        }
+        p_ddr_timing->phy_timing.dtpr0.b.tRP = cl;
+        /*
+         * WrToMiss=WL*tCK + tWR + tRP + tRCD
+         */
+        p_ddr_timing->noc_timing.b.WrToMiss = ((cwl+((DDR2_tWR*nMHz+999)/1000)+cl+cl)&0x3F);
+        /*
+         * tRAS, 45ns
+         */
+        tmp=((DDR2_tRAS*nMHz+999)/1000);
+        p_ddr_timing->pctl_timing.tras = (tmp&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRAS = tmp&0x1F;
+        /*
+         * tRC=tRAS+tRP
+         */
+        p_ddr_timing->pctl_timing.trc = ((tmp+cl)&0x3F);
+        p_ddr_timing->noc_timing.b.ActToAct = ((tmp+cl)&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRC = (tmp+cl)&0xF;
+
+        p_ddr_timing->pctl_timing.trtw = (cl+2-cwl);//DDR2_tRTW;
+        p_ddr_timing->phy_timing.dtpr1.b.tRTW = 0;
+        p_ddr_timing->noc_timing.b.RdToWr = ((cl+2-cwl)&0x1F);
+        p_ddr_timing->pctl_timing.tal = al;
+        p_ddr_timing->pctl_timing.tcl = cl;
+        p_ddr_timing->pctl_timing.tcwl = cwl;
+        /*
+         * tRCD=CL
+         */
+        p_ddr_timing->pctl_timing.trcd = cl;
+        p_ddr_timing->phy_timing.dtpr0.b.tRCD = cl;
+        /*
+         * tRRD = 10ns(2KB page)
+         *
+         */
+        p_ddr_timing->pctl_timing.trrd = (((DDR2_tRRD*nMHz+999)/1000)&0xF);
+        p_ddr_timing->phy_timing.dtpr0.b.tRRD = ((DDR2_tRRD*nMHz+999)/1000)&0xF;
+        /*
+         * tRTP, 7.5ns
+         */
+        tmp = ((DDR2_tRTP*nMHz+(nMHz>>1)+999)/1000);
+        p_ddr_timing->pctl_timing.trtp = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tRTP = tmp;
+        /*
+         * RdToMiss=tRTP+tRP + tRCD - (BL/2 * tCK)
+         */
+        p_ddr_timing->noc_timing.b.RdToMiss = ((tmp+cl+cl-(bl>>1))&0x3F);
+        /*
+         * tWR, 15ns
+         */
+        tmp = ((DDR2_tWR*nMHz+999)/1000);
+        p_ddr_timing->pctl_timing.twr = tmp&0x1F;
+        p_ddr_timing->phy_timing.mr[0] = DDR2_BL4 | DDR2_CL(cl) | DDR2_WR(tmp);
+        /*
+         * tWTR, 10ns(200MHz) 7.5ns(>200MHz)
+         */
+        if(nMHz<=200)
+        {
+            tmp = ((DDR2_tWTR_LITTLE_200MHz*nMHz+999)/1000);
+        }
+        else
+        {
+            tmp = ((DDR2_tWTR_GREAT_200MHz*nMHz+(nMHz>>1)+999)/1000);
+        }
+        p_ddr_timing->pctl_timing.twtr = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tWTR = tmp&0x7;
+        p_ddr_timing->noc_timing.b.WrToRd = ((tmp+cwl)&0x1F);
+        /*
+         * tXP, 6-AL(200MHz)         6-AL(266MHz)         7-AL(333MHz)         8-AL(400MHz)        10-AL(533MHz)
+         */
+        if(nMHz<=266)
+        {
+            tmp = 6-al;
+        }
+        else if(nMHz<=333)
+        {
+            tmp = 7-al;
+        }
+        else if(nMHz<=400)
+        {
+            tmp = 8-al;
+        }
+        else
+        {
+            tmp = 10-al;
+        }
+        p_ddr_timing->pctl_timing.txp = tmp&0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tXP = tmp&0x1F;
+        /*
+         * tXPDLL, =tXP
+         */
+        p_ddr_timing->pctl_timing.txpdll = tmp & 0x3F;
+        /*
+         * tZQCS, 0
+         */
+        p_ddr_timing->pctl_timing.tzqcs = 0;
+        /*
+         * tZQCSI,
+         */
+        p_ddr_timing->pctl_timing.tzqcsi = 0;
+        /*
+         * tDQS,
+         */
+        p_ddr_timing->pctl_timing.tdqs = DDR2_tDQS;
+        /*
+         * tCKSRE, 1 tCK
+         */
+        p_ddr_timing->pctl_timing.tcksre = DDR2_tCKSRE & 0x1F;
+        /*
+         * tCKSRX, no such timing
+         */
+        p_ddr_timing->pctl_timing.tcksrx = DDR2_tCKSRX & 0x1F;
+        /*
+         * tCKE, 3 tCK
+         */
+        p_ddr_timing->pctl_timing.tcke = DDR2_tCKE & 0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tCKE = DDR2_tCKE;
+        /*
+         * tCKESR, =tCKE
+         */
+        p_ddr_timing->pctl_timing.tckesr = DDR2_tCKESR&0xF;
+        /*
+         * tMOD, 12ns
+         */
+        p_ddr_timing->pctl_timing.tmod = ((DDR2_tMOD*nMHz+999)/1000)&0x1F;
+        p_ddr_timing->phy_timing.dtpr1.b.tMOD = ((DDR2_tMOD*nMHz+999)/1000);
+        /*
+         * tRSTL, 0
+         */
+        p_ddr_timing->pctl_timing.trstl = 0;
+        /*
+         * tZQCL, 0
+         */
+        p_ddr_timing->pctl_timing.tzqcl = 0;
+        /*
+         * tMRR, 0 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrr = 0;
+        /*
+         * tDPD, 0
+         */
+        p_ddr_timing->pctl_timing.tdpd = 0;
+
+        /**************************************************
+         * PHY Timing
+         **************************************************/
+        /*
+         * tCCD, BL/2 for DDR2 and 4 for DDR3
+         */
+        p_ddr_timing->phy_timing.dtpr0.b.tCCD = 0;
+        /*
+         * tDQSCKmax,5.5ns
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tDQSCKmax = 0;
+        /*
+         * tRTODT, 0:ODT may be turned on immediately after read post-amble
+         *         1:ODT may not be turned on until one clock after the read post-amble
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tRTODT = 1;
+        /*
+         * tFAW,50ns(<=333MHz 2KB page) 45ns(400MHz 2KB page) 45ns(533MHz 2KB page)
+         */
+        if(nMHz<=333)
+        {
+            tmp = DDR2_tFAW_333MHz;
+        }
+        else
+        {
+            tmp = DDR2_tFAW_400MHz;
+        }
+        p_ddr_timing->phy_timing.dtpr1.b.tFAW = ((tmp*nMHz+999)/1000)&0x7F;
+        /*
+         * tAOND_tAOFD
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tAOND = 0;
+        /*
+         * tDLLK,=tXSRD=200 tCK
+         */
+        p_ddr_timing->phy_timing.dtpr2.b.tDLLK = DDR2_tDLLK;
+        /**************************************************
+         * NOC Timing
+         **************************************************/
+        p_ddr_timing->noc_timing.b.BurstLen = ((bl>>1)&0x7);
+    }
+    else //if(mem_type == LPDDR)
+    {
+        #define mDDR_tREFI_7_8_us   (78)
+        #define mDDR_tMRD           (2)
+        #define mDDR_tRFC_256Mb     (80)
+        #define mDDR_tRFC_512Mb     (110)
+        #define mDDR_tRFC_1Gb       (140)
+        #define mDDR_tXSR           (200)
+        #define mDDR_tRAS_100MHz    (50)
+        #define mDDR_tRAS_133MHz    (45)
+        #define mDDR_tRAS_185MHz    (42)
+        #define mDDR_tRAS_200MHz    (40)
+        #define mDDR_tRTW           (3)  //register min valid value
+        #define mDDR_tRRD_133MHz    (15)
+        #define mDDR_tRRD_166MHz    (12)
+        #define mDDR_tRRD_185MHz    (11)
+        #define mDDR_tRRD_200MHz    (10)
+        #define mDDR_tRTP           (0)
+        #define mDDR_tWR            (15)
+        #define mDDR_tWTR_133MHz    (1)
+        #define mDDR_tWTR_200MHz    (2)
+        #define mDDR_tXP            (25)
+        #define mDDR_tDQS           (1)
+        #define mDDR_tCKSRE         (1)
+        #define mDDR_tCKSRX         (1)
+        #define mDDR_tCKE           (2)
+
+        al = 0;
+        bl = 4;
+        /*
+         * mobile DDR timing USE 3-3-3, CL always = 3
+         */
+        cl = 3;
+        cwl = 1;
+        p_ddr_timing->phy_timing.mr[0] = mDDR_BL4 | mDDR_CL(cl);
+        p_ddr_timing->phy_timing.mr[2] = mDDR_DS_3_4;  //mr[2] is mDDR MR1
+        p_ddr_timing->phy_timing.mr[1] = 0;
+        p_ddr_timing->phy_timing.mr[3] = 0;
+        /**************************************************
+         * PCTL Timing
+         **************************************************/
+        /*
+         * tREFI, average periodic refresh interval, 7.8us
+         */
+        p_ddr_timing->pctl_timing.trefi = mDDR_tREFI_7_8_us;
+        /*
+         * tMRD, 2 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrd = mDDR_tMRD & 0x7;
+        p_ddr_timing->phy_timing.dtpr0.b.tMRD = mDDR_tMRD;
+        /*
+         * tRFC, 80ns(128Mb,256Mb) 110ns(512Mb) 140ns(1Gb,2Gb)
+         */
+        if(capability <= 0x2000000)  // 256Mb
+        {
+            tmp = mDDR_tRFC_256Mb;
+        }
+        else if(capability <= 0x4000000) // 512Mb
+        {
+            tmp = mDDR_tRFC_512Mb;
+        }
+        else  // 1Gb,2Gb
+        {
+            tmp = mDDR_tRFC_1Gb;
+        }
+        p_ddr_timing->pctl_timing.trfc = (tmp*nMHz+999)/1000;
+        p_ddr_timing->phy_timing.dtpr1.b.tRFC = ((tmp*nMHz+999)/1000)&0xFF;
+        /*
+         * tCKESR, =tRFC
+         */
+        p_ddr_timing->pctl_timing.tckesr = tmp&0xF;
+        /*
+         * tXSR, 200ns
+         */
+        p_ddr_timing->pctl_timing.texsr = ((mDDR_tXSR*nMHz+999)/1000)&0x3FF;
+        p_ddr_timing->phy_timing.dtpr2.b.tXS = ((mDDR_tXSR*nMHz+999)/1000)&0x3FF;
+        /*
+         * tRP=CL
+         */
+        p_ddr_timing->pctl_timing.trp = cl;
+        p_ddr_timing->phy_timing.dtpr0.b.tRP = cl;
+        /*
+         * WrToMiss=WL*tCK + tWR + tRP + tRCD
+         */
+        p_ddr_timing->noc_timing.b.WrToMiss = ((cwl+((mDDR_tWR*nMHz+999)/1000)+cl+cl)&0x3F);
+        /*
+         * tRAS, 50ns(100MHz) 45ns(133MHz) 42ns(166MHz) 42ns(185MHz) 40ns(200MHz)
+         */
+        if(nMHz<=100)
+        {
+            tmp = mDDR_tRAS_100MHz;
+        }
+        else if(nMHz<=133)
+        {
+            tmp = mDDR_tRAS_133MHz;
+        }
+        else if(nMHz<=185)
+        {
+            tmp =mDDR_tRAS_185MHz;
+        }
+        else
+        {
+            tmp = mDDR_tRAS_200MHz;
+        }
+        tmp = ((tmp*nMHz+999)/1000);
+        p_ddr_timing->pctl_timing.tras = (tmp&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRAS = tmp&0x1F;
+        /*
+         * tRC=tRAS+tRP
+         */
+        p_ddr_timing->pctl_timing.trc = ((tmp+cl)&0x3F);
+        p_ddr_timing->noc_timing.b.ActToAct = ((tmp+cl)&0x3F);
+        p_ddr_timing->phy_timing.dtpr0.b.tRC = (tmp+cl)&0xF;
+        p_ddr_timing->pctl_timing.trtw = (cl+2-cwl);//mDDR_tRTW;
+        p_ddr_timing->phy_timing.dtpr1.b.tRTW = 0;
+        p_ddr_timing->noc_timing.b.RdToWr = ((cl+2-cwl)&0x1F);
+        p_ddr_timing->pctl_timing.tal = al;
+        p_ddr_timing->pctl_timing.tcl = cl;
+        p_ddr_timing->pctl_timing.tcwl = cwl;
+        /*
+         * tRCD=CL
+         */
+        p_ddr_timing->pctl_timing.trcd = cl;
+        p_ddr_timing->phy_timing.dtpr0.b.tRCD = cl;
+        /*
+         * tRRD,15ns(100MHz) 15ns(133MHz) 12ns(166MHz) 10.8ns(185MHz) 10ns(200MHz)
+         *
+         */
+        if(nMHz<=133)
+        {
+            tmp = mDDR_tRRD_133MHz;
+        }
+        else if(nMHz<=166)
+        {
+            tmp = mDDR_tRRD_166MHz;
+        }
+        else if(nMHz<=185)
+        {
+            tmp = mDDR_tRRD_185MHz;
+        }
+        else
+        {
+            tmp = mDDR_tRRD_200MHz;
+        }
+        p_ddr_timing->pctl_timing.trrd = (((tmp*nMHz+999)/1000)&0xF);
+        p_ddr_timing->phy_timing.dtpr0.b.tRRD = ((tmp*nMHz+999)/1000)&0xF;
+        /*
+         * tRTP, 0
+         */
+        tmp = ((mDDR_tRTP*nMHz+999)/1000);
+        p_ddr_timing->pctl_timing.trtp = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tRTP = tmp;
+        /*
+         * RdToMiss=tRTP+tRP + tRCD - (BL/2 * tCK)
+         */
+        p_ddr_timing->noc_timing.b.RdToMiss = ((tmp+cl+cl-(bl>>1))&0x3F);
+        /*
+         * tWR, 15ns
+         */
+        p_ddr_timing->pctl_timing.twr = ((mDDR_tWR*nMHz+999)/1000)&0x1F;
+        /*
+         * tWTR, 1 tCK(100MHz,133MHz) 2 tCK(166MHz,185MHz,200MHz)
+         */
+        if(nMHz <= 133)
+        {
+            tmp = mDDR_tWTR_133MHz;
+        }
+        else
+        {
+            tmp = mDDR_tWTR_200MHz;
+        }
+        p_ddr_timing->pctl_timing.twtr = tmp&0xF;
+        p_ddr_timing->phy_timing.dtpr0.b.tWTR = tmp&0x7;
+        p_ddr_timing->noc_timing.b.WrToRd = ((tmp+cwl)&0x1F);
+        /*
+         * tXP, 25ns
+         */
+
+        p_ddr_timing->pctl_timing.txp = ((mDDR_tXP*nMHz+999)/1000)&0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tXP = ((mDDR_tXP*nMHz+999)/1000)&0x1F;
+        /*
+         * tXPDLL, 0
+         */
+        p_ddr_timing->pctl_timing.txpdll = 0;
+        /*
+         * tZQCS, 0
+         */
+        p_ddr_timing->pctl_timing.tzqcs = 0;
+        /*
+         * tZQCSI,
+         */
+        p_ddr_timing->pctl_timing.tzqcsi = 0;
+        /*
+         * tDQS,
+         */
+        p_ddr_timing->pctl_timing.tdqs = mDDR_tDQS;
+        /*
+         * tCKSRE, 1 tCK
+         */
+        p_ddr_timing->pctl_timing.tcksre = mDDR_tCKSRE & 0x1F;
+        /*
+         * tCKSRX, no such timing
+         */
+        p_ddr_timing->pctl_timing.tcksrx = mDDR_tCKSRX & 0x1F;
+        /*
+         * tCKE, 2 tCK
+         */
+        p_ddr_timing->pctl_timing.tcke = mDDR_tCKE & 0x7;
+        p_ddr_timing->phy_timing.dtpr2.b.tCKE = mDDR_tCKE;
+        /*
+         * tMOD, 0
+         */
+        p_ddr_timing->pctl_timing.tmod = 0;
+        p_ddr_timing->phy_timing.dtpr1.b.tMOD = 0;
+        /*
+         * tRSTL, 0
+         */
+        p_ddr_timing->pctl_timing.trstl = 0;
+        /*
+         * tZQCL, 0
+         */
+        p_ddr_timing->pctl_timing.tzqcl = 0;
+        /*
+         * tMRR, 0 tCK
+         */
+        p_ddr_timing->pctl_timing.tmrr = 0;
+        /*
+         * tDPD, 0
+         */
+        p_ddr_timing->pctl_timing.tdpd = 0;
+
+        /**************************************************
+         * PHY Timing
+         **************************************************/
+        /*
+         * tCCD, BL/2 for DDR2 and 4 for DDR3
+         */
+        p_ddr_timing->phy_timing.dtpr0.b.tCCD = 0;
+        /*
+         * tDQSCKmax,5.5ns
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tDQSCKmax = 0;
+        /*
+         * tRTODT, 0:ODT may be turned on immediately after read post-amble
+         *         1:ODT may not be turned on until one clock after the read post-amble
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tRTODT = 1;
+        /*
+         * tFAW,0
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tFAW = 0;
+        /*
+         * tAOND_tAOFD
+         */
+        p_ddr_timing->phy_timing.dtpr1.b.tAOND = 0;
+        /*
+         * tDLLK,0
+         */
+        p_ddr_timing->phy_timing.dtpr2.b.tDLLK = 0;
+        /**************************************************
+         * NOC Timing
+         **************************************************/
+        p_ddr_timing->noc_timing.b.BurstLen = ((bl>>1)&0x7);
+    }
+out:
+    return ret;
+}
+
+static uint32_t __sramlocalfunc ddr_update_timing(void)
+{
+    uint32_t i;
+    DDR_TIMING_T  *p_ddr_timing=&ddr_timing;
+
+    copy((uint32_t *)&(pDDR_Reg->TOGCNT1U), (uint32_t*)&(p_ddr_timing->pctl_timing.togcnt1u), 34);
+    copy((uint32_t *)&(pPHY_Reg->DTPR[0]), (uint32_t*)&(p_ddr_timing->phy_timing.dtpr0), 3);
+    *(volatile uint32_t *)SysSrv_DdrTiming = p_ddr_timing->noc_timing.d32;
+    // Update PCTL BL
+    if(mem_type == DDR3)
+    {
+        pDDR_Reg->MCFG = (pDDR_Reg->MCFG & (~(0x1|(0x3<<18)|(0x1<<17)|(0x1<<16)))) | ddr2_ddr3_bl_8 | tfaw_cfg(5)|pd_exit_slow|pd_type(1);
+        pDDR_Reg->DFITRDDATAEN   = pDDR_Reg->TCL-2;
+        pDDR_Reg->DFITPHYWRLAT   = pDDR_Reg->TCWL-1;
+    }
+    if(mem_type == LPDDR2)
+    {
+        if(ddr_freq>=200)
+        {
+            pDDR_Reg->MCFG = (pDDR_Reg->MCFG & (~((0x3<<20)|(0x3<<18)|(0x1<<17)|(0x1<<16)))) | mddr_lpddr2_bl_8 | tfaw_cfg(5)|pd_exit_fast|pd_type(1);
+        }
+        else
+        {
+            pDDR_Reg->MCFG = (pDDR_Reg->MCFG & (~((0x3<<20)|(0x3<<18)|(0x1<<17)|(0x1<<16)))) | mddr_lpddr2_bl_8 | tfaw_cfg(6)|pd_exit_fast|pd_type(1);
+        }
+        i = ((pPHY_Reg->DTPR[1] >> 27) & 0x7) - ((pPHY_Reg->DTPR[1] >> 24) & 0x7);
+        pPHY_Reg->DSGCR = (pPHY_Reg->DSGCR & (~(0x3F<<5))) | (i<<5) | (i<<8);  //tDQSCKmax-tDQSCK
+        pDDR_Reg->DFITRDDATAEN   = pDDR_Reg->TCL;
+        pDDR_Reg->DFITPHYWRLAT   = pDDR_Reg->TCWL;
+    }
+    else if(mem_type == DDR2)
+    {
+        pDDR_Reg->MCFG = (pDDR_Reg->MCFG & (~(0x1|(0x3<<18)|(0x1<<17)|(0x1<<16)))) | ddr2_ddr3_bl_8 | tfaw_cfg(5)|pd_exit_fast|pd_type(1);
+    }
+    else// if(mem_type == LPDDR)
+    {
+        pDDR_Reg->MCFG = (pDDR_Reg->MCFG & (~((0x3<<20)|(0x3<<18)|(0x1<<17)|(0x1<<16)))) | mddr_lpddr2_bl_4 | tfaw_cfg(5)|pd_exit_fast|pd_type(1);
+    }
+    return 0;
+}
+
+static uint32_t __sramlocalfunc ddr_update_mr(void)
+{
+    DDR_TIMING_T  *p_ddr_timing=&ddr_timing;
+
+    copy((uint32_t *)&(pPHY_Reg->MR[0]), (uint32_t*)&(p_ddr_timing->phy_timing.mr[0]), 4);
+    if(mem_type == DDR3)
+    {
+        send_command(3, MRS_cmd, bank_addr(0x0) | cmd_addr(((uint8_t)(p_ddr_timing->phy_timing.mr[0]))|(0X1<<8)));
+        delayus(100);
+        send_command(3, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[0])));
+        send_command(3, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[1])));
+        send_command(3, MRS_cmd, bank_addr(0x2) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[2])));
+    }
+    else if(mem_type == LPDDR2)
+    {
+        send_command(3, MRS_cmd, lpddr2_ma(0x1) | lpddr2_op((uint8_t)(p_ddr_timing->phy_timing.mr[1])));
+        send_command(3, MRS_cmd, lpddr2_ma(0x2) | lpddr2_op((uint8_t)(p_ddr_timing->phy_timing.mr[2])));
+        send_command(3, MRS_cmd, lpddr2_ma(0x3) | lpddr2_op((uint8_t)(p_ddr_timing->phy_timing.mr[3])));
+    }
+    else if(mem_type == DDR2)
+    {
+        send_command(3, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[0])));
+        send_command(3, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[1])));
+    }
+    else //if(mem_type == LPDDR)
+    {
+        send_command(3, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[0])));
+        send_command(3, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(p_ddr_timing->phy_timing.mr[2]))); //mr[2] is mDDR MR1
+    }
     
-    // start to add by cjh 20120330   
-    // reset dll 
-    pPHY_Reg->ACDLLCR &= ~0x40000000;
-    pPHY_Reg->DATX8[0].DXDLLCR &= ~0x40000000;
-    pPHY_Reg->DATX8[1].DXDLLCR &= ~0x40000000;
-    pPHY_Reg->DATX8[2].DXDLLCR &= ~0x40000000;
-    pPHY_Reg->DATX8[3].DXDLLCR &= ~0x40000000;
+    return 0;
+}
+
+static void __sramlocalfunc ddr_selfrefresh_enter(void)
+{
+    idle_port();
+    move_to_Lowpower_state();
     
-    Delay_us(10);   //wait
+    //pPHY_Reg->ACDLLCR &= ~0x40000000;
+    //pPHY_Reg->DATX8[0].DXDLLCR &= ~0x40000000;
+    //pPHY_Reg->DATX8[1].DXDLLCR &= ~0x40000000;
+    //pPHY_Reg->DATX8[2].DXDLLCR &= ~0x40000000;
+    //pPHY_Reg->DATX8[3].DXDLLCR &= ~0x40000000;    //reset DLL
+    //delayus(1);
+    //pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16)|(0x1<<2);  //close DDR PHY clock
+    //phy_dll_bypass_set(0);  //dll bypass
+}
+
+static void __sramlocalfunc ddr_selfrefresh_exit(void)
+{
+    uint32 n;
+    //pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16)|(0x0<<2);  //open DDR PHY clock
+    //delayus(1000);
+    //pPHY_Reg->ACDLLCR |= 0x40000000;
+    //pPHY_Reg->DATX8[0].DXDLLCR |= 0x40000000;
+    //pPHY_Reg->DATX8[1].DXDLLCR |= 0x40000000;
+    //pPHY_Reg->DATX8[2].DXDLLCR |= 0x40000000;
+    //pPHY_Reg->DATX8[3].DXDLLCR |= 0x40000000;  //de-reset DLL
+    //delayus(10);
+    //pPHY_Reg->PIR = INIT | ITMSRST | LOCKBYP | ZCALBYP | CLRSR;  //reset ITM
     
-     // de-reset dll    
-    pPHY_Reg->ACDLLCR |= 0x40000000;
-    pPHY_Reg->DATX8[0].DXDLLCR |= 0x40000000;
-    pPHY_Reg->DATX8[1].DXDLLCR |= 0x40000000;
-    pPHY_Reg->DATX8[2].DXDLLCR |= 0x40000000;
-    pPHY_Reg->DATX8[3].DXDLLCR |= 0x40000000;  
+    move_to_Config_state();
+    ddr_update_timing();
+    ddr_update_mr();
+    n = data_training();
+    move_to_Access_state();
+    deIdle_port();
+    if(n!=0)
+    {
+        ddr_print("DTT failed!\n");
+    }
+}
+
+uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
+{
+    uint32_t ret;
+    u32 i;
+    volatile u32 n;    
+    unsigned long flags;
+    volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
+    unsigned long save_sp;
+    
+    ret=ddr_set_pll(nMHz,0);
+    ddr_get_parameter(ret);
+
+    /** 1. Make sure there is no host access */
+    local_irq_save(flags);
+    flush_cache_all();
+       outer_flush_all();
+       flush_tlb_all();
+       DDR_SAVE_SP(save_sp);
+       for(i=0;i<16;i++)
+       {
+           n=temp[1024*i];
+        barrier();
+       }
+    n= pDDR_Reg->SCFG.d32;
+    n= pPHY_Reg->RIDR;
+    n= pCRU_Reg->CRU_PLL_CON[0][0];
+    n= pPMU_Reg->PMU_WAKEUP_CFG[0];
+    n= *(volatile uint32_t *)SysSrv_DdrConf;
+    n= pGRF_Reg->GRF_SOC_STATUS0;
+    dsb();
+
+    /** 2. ddr enter self-refresh mode or precharge power-down mode */
+    ddr_selfrefresh_enter();
+
+    phy_dll_bypass_set(0);  //dll bypass
+    dsb();
+    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (1<<2);  //disable DDR PHY clock
+    delayus(1);
+    
+    /** 3. change frequence  */
+    ddr_set_pll(ret,1);
+    ddr_freq = ret;
+    
+    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (0<<2);  //enable DDR PHY clock
+    dsb();
+    delayus(1000);   //wait pll lock
+    phy_dll_bypass_set(ret);
+    dsb();
+    
+    reset_dll();
+    dsb(); 
+    /** 5. Issues a Mode Exit command   */
+    ddr_selfrefresh_exit();
+    dsb();     
+    DDR_RESTORE_SP(save_sp);
+    local_irq_restore(flags);
+    clk_set_rate(clk_get(NULL, "ddr_pll"), 0);
+    return ret;
+}
+
+EXPORT_SYMBOL(ddr_change_freq);
+
+void __sramfunc ddr_suspend(void)
+{
+    u32 i;
+    volatile u32 n;    
+    volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
     
-    Delay_us(10);   //wait
-    // end to add by cjh 20120330   
+    /** 1. Make sure there is no host access */
+    flush_cache_all();
+       outer_flush_all();
+       flush_tlb_all();
+
+       for(i=0;i<16;i++)
+       {
+           n=temp[1024*i];
+        barrier();
+       }
+    n= pDDR_Reg->SCFG.d32;
+    n= pPHY_Reg->RIDR;
+    n= pCRU_Reg->CRU_PLL_CON[0][0];
+    n= pPMU_Reg->PMU_WAKEUP_CFG[0];
+    n= *(volatile uint32_t *)SysSrv_DdrConf;
+    dsb();
     
-    Move_to_Access_state();
-//    DeIdle_port();
+    //idle_port();
+    move_to_Lowpower_state();
+
+    phy_dll_bypass_set(0);  //dll bypass
+    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (1<<2);  //disable DDR PHY clock
+    dsb();
+    delayus(1);
+    pCRU_Reg->CRU_MODE_CON = (0x3<<((1*4) +  16)) | (0x0<<(1*4));            //PLL slow-mode
+    dsb();
+    delayus(1);    
+
+    pPHY_Reg->DSGCR = pPHY_Reg->DSGCR&(~((0x1<<28)|(0x1<<29)));
+}
+EXPORT_SYMBOL(ddr_suspend);
+
+void __sramfunc ddr_resume(void)
+{
+    pPHY_Reg->DSGCR = pPHY_Reg->DSGCR|((0x1<<28)|(0x1<<29));
+    dsb();
+    
+    pCRU_Reg->CRU_MODE_CON = (0x3<<((1*4) +  16))  | (0x1<<(1*4));            //PLL normal
+    dsb();
+    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (0<<2);  //enable DDR PHY clock
+    dsb();
+    delayus(10);   //wait pll lock
+    phy_dll_bypass_set(ddr_freq);    
+    reset_dll();
+    move_to_Access_state();
+    //deIdle_port();
+}
+EXPORT_SYMBOL(ddr_resume);
+
+int ddr_init(uint32_t dram_type, uint32_t freq)
+{
+    volatile uint32_t value = 0;
+    uint32_t cs;
+    uint32_t gsr,dqstr;
+
+    ddr_print("version 1.00 20120424 \n");
+
+    mem_type = pPHY_Reg->DCR.b.DDRMD;
+    ddr_type = dram_type;
+    ddr_freq = freq;    
+    //get capability per chip, not total size, used for calculate tRFC
+    capability = get_cs0_cap();
+    switch(mem_type)
+    {
+        case DDR3:
+            ddr_print("DDR3 Device\n");
+            break;
+        case LPDDR2:
+            ddr_print("LPDDR2 Device\n");
+            break;
+        case DDR2:
+            ddr_print("DDR2 Device\n");
+            break;
+        case DDR:
+            ddr_print("DDR Device\n");
+            break;
+        default:
+            ddr_print("LPDDR Device\n");
+            break;
+    }
+    switch((pPHY_Reg->PGCR>>18) & 0xF)
+    {
+        case 0xF:
+            cs = 4;
+        case 7:
+            cs = 3;
+            break;
+        case 3:
+            cs = 2;
+            break;
+        default:
+            cs = 1;
+            break;
+    }
+    ddr_print("%d CS, ROW=%d, Bank=%d, COL=%d, Total Capability=%dMB\n", 
+                                                                    cs, \
+                                                                    get_row(), \
+                                                                    (0x1<<(get_bank())), \
+                                                                    get_col(), \
+                                                                    ((capability*cs)>>20));
+    ddr_adjust_config(mem_type);
+
+    value=ddr_change_freq(freq);
+    ddr_print("init success!!! freq=%dMHz\n", value);
+
+    for(value=0;value<4;value++)
+    {
+        gsr = pPHY_Reg->DATX8[value].DXGSR[0];
+        dqstr = pPHY_Reg->DATX8[value].DXDQSTR;
+        ddr_print("DTONE=0x%x, DTERR=0x%x, DTIERR=0x%x, DTPASS=0x%x, DGSL=%d extra clock, DGPS=%d\n", \
+                   (gsr&0xF), ((gsr>>4)&0xF), ((gsr>>8)&0xF), ((gsr>>13)&0xFFF), (dqstr&0x7), (((dqstr>>12)&0x3)*90));
+    }
+    ddr_print("ZERR=%x, ZDONE=%x, ZPD=0x%x, ZPU=0x%x, OPD=0x%x, OPU=0x%x\n", \
+                                                (pPHY_Reg->ZQ0SR[0]>>30)&0x1, \
+                                                (pPHY_Reg->ZQ0SR[0]>>31)&0x1, \
+                                                pPHY_Reg->ZQ0SR[1]&0x3,\
+                                                (pPHY_Reg->ZQ0SR[1]>>2)&0x3,\
+                                                (pPHY_Reg->ZQ0SR[1]>>4)&0x3,\
+                                                (pPHY_Reg->ZQ0SR[1]>>6)&0x3);
+    ddr_print("DRV Pull-Up=0x%x, DRV Pull-Dwn=0x%x\n", pPHY_Reg->ZQ0SR[0]&0x1F, (pPHY_Reg->ZQ0SR[0]>>5)&0x1F);
+    ddr_print("ODT Pull-Up=0x%x, ODT Pull-Dwn=0x%x\n", (pPHY_Reg->ZQ0SR[0]>>10)&0x1F, (pPHY_Reg->ZQ0SR[0]>>15)&0x1F);
+
+    return 0;
 }
+EXPORT_SYMBOL(ddr_init);
 
diff --git a/arch/arm/mach-rk30/include/mach/ddr.h b/arch/arm/mach-rk30/include/mach/ddr.h
new file mode 100755 (executable)
index 0000000..4351365
--- /dev/null
@@ -0,0 +1,152 @@
+/* arch/arm/mach-rk30/include/mach/ddr.h
+ *
+ * Copyright (C) 2011 ROCKCHIP, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_RK30_DDR_H
+#define __ARCH_ARM_MACH_RK30_DDR_H
+
+#include <linux/types.h>
+#include <mach/sram.h>
+
+#ifdef CONFIG_DDR_SDRAM_FREQ
+#define DDR_FREQ          (CONFIG_DDR_SDRAM_FREQ)
+#else
+#define DDR_FREQ 400
+#endif
+
+#define DDR3_800D   (0)     // 5-5-5
+#define DDR3_800E   (1)     // 6-6-6
+#define DDR3_1066E  (2)     // 6-6-6
+#define DDR3_1066F  (3)     // 7-7-7
+#define DDR3_1066G  (4)     // 8-8-8
+#define DDR3_1333F  (5)     // 7-7-7
+#define DDR3_1333G  (6)     // 8-8-8
+#define DDR3_1333H  (7)     // 9-9-9
+#define DDR3_1333J  (8)     // 10-10-10
+#define DDR3_1600G  (9)     // 8-8-8
+#define DDR3_1600H  (10)    // 9-9-9
+#define DDR3_1600J  (11)    // 10-10-10
+#define DDR3_1600K  (12)    // 11-11-11
+#define DDR3_1866J  (13)    // 10-10-10
+#define DDR3_1866K  (14)    // 11-11-11
+#define DDR3_1866L  (15)    // 12-12-12
+#define DDR3_1866M  (16)    // 13-13-13
+#define DDR3_2133K  (17)    // 11-11-11
+#define DDR3_2133L  (18)    // 12-12-12
+#define DDR3_2133M  (19)    // 13-13-13
+#define DDR3_2133N  (20)    // 14-14-14
+#define DDR3_DEFAULT (21)
+#define DDR_DDR2     (22)
+#define DDR_LPDDR    (23)
+#define DDR_LPDDR2   (24)
+
+#ifdef CONFIG_DDR_TYPE_DDR3_800D
+#define DDR_TYPE DDR3_800D
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_800E
+#define DDR_TYPE DDR3_800E
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1066E
+#define DDR_TYPE DDR3_1066E
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1066F
+#define DDR_TYPE DDR3_1066F
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1066G
+#define DDR_TYPE DDR3_1066G
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1333F
+#define DDR_TYPE DDR3_1333F
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1333G
+#define DDR_TYPE DDR3_1333G
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1333H
+#define DDR_TYPE DDR3_1333H
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1333J
+#define DDR_TYPE DDR3_1333J
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1600G
+#define DDR_TYPE DDR3_1600G
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1600H
+#define DDR_TYPE DDR3_1600H
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1600J
+#define DDR_TYPE DDR3_1600J
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1866J
+#define DDR_TYPE DDR3_1866J
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1866K
+#define DDR_TYPE DDR3_1866K
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1866L
+#define DDR_TYPE DDR3_1866L
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_1866M
+#define DDR_TYPE DDR3_1866M
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_2133K
+#define DDR_TYPE DDR3_2133K
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_2133L
+#define DDR_TYPE DDR3_2133L
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_2133M
+#define DDR_TYPE DDR3_2133M
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_2133N
+#define DDR_TYPE DDR3_2133N
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDR3_DEFAULT
+#define DDR_TYPE DDR3_DEFAULT
+#endif
+
+#ifdef CONFIG_DDR_TYPE_DDRII
+#define DDR_TYPE DDR_DDRII
+#endif
+
+#ifdef CONFIG_DDR_TYPE_LPDDR
+#define DDR_TYPE DDR_LPDDR
+#endif
+
+void __sramfunc ddr_suspend(void);
+void __sramfunc ddr_resume(void);
+//void __sramlocalfunc delayus(uint32_t us);
+uint32_t __sramfunc ddr_change_freq(uint32_t nMHz);
+int ddr_init(uint32_t dram_type, uint32_t freq);
+
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index ac0fb1d257670ff151304e6880c73404ffefe6c0..7537b86260c95d8a9f034f26b76a9fc1bf5e5133 100755 (executable)
@@ -21,6 +21,7 @@
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/cru.h>
+#include <mach/ddr.h>
 
 #define cru_readl(offset)      readl_relaxed(RK30_CRU_BASE + offset)
 #define cru_writel(v, offset)  do { writel_relaxed(v, RK30_CRU_BASE + offset); dsb(); } while (0)
@@ -73,7 +74,7 @@ void __sramfunc sram_printch(char byte)
 }
 
 #ifdef CONFIG_DDR_TEST
-static int ddr_debug;
+static int ddr_debug=0;
 module_param(ddr_debug, int, 0644);
 
 static int inline calc_crc32(u32 addr, size_t len)
@@ -90,13 +91,14 @@ static void __sramfunc ddr_testmode(void)
 
        if (ddr_debug == 1) {
                for (;;) {
-                       sram_printascii("change freq\n");
+                       sram_printascii("\n change freq:");
                        g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
-                       nMHz = 333 + random32();
-                       nMHz %= 490;
-                       if (nMHz < 100)
-                               nMHz = 100;
-//                     nMHz = ddr_change_freq(nMHz);
+                       do
+                       {
+                           nMHz = 300 + random32();
+                           nMHz %= 500;
+                       }while(nMHz < 300);
+                       nMHz = ddr_change_freq(nMHz);
                        sram_printhex(nMHz);
                        sram_printch(' ');
                        sram_printhex(n++);
@@ -117,9 +119,9 @@ static void __sramfunc ddr_testmode(void)
                        sram_printch(' ');
                        g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
                        nMHz = (random32()>>13);// 16.7s max
-//                     ddr_suspend();
-//                     delayus(nMHz);
-//                     ddr_resume();
+                       ddr_suspend();
+                       sram_udelay(nMHz);
+                       ddr_resume();
                        sram_printhex(nMHz);
                        sram_printch(' ');
                        sram_printhex(n++);
@@ -217,8 +219,8 @@ static void pm_pll_wait_lock(int pll_idx)
 
 static unsigned long save_sp;
 
-extern void __sramfunc ddr_selfrefresh_enter(void);
-extern void __sramfunc ddr_selfrefresh_exit(void);
+//extern void __sramfunc ddr_selfrefresh_enter(void);
+//extern void __sramfunc ddr_selfrefresh_exit(void);
 
 static noinline void interface_ctr_reg_pread(void)
 {
@@ -321,7 +323,7 @@ static void __sramfunc rk30_sram_suspend(void)
        int i;
 
        sram_printch('5');
-       ddr_selfrefresh_enter();
+       ddr_suspend();
        sram_printch('6');
 
        for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
@@ -369,7 +371,7 @@ static void __sramfunc rk30_sram_suspend(void)
        }
 
        sram_printch('6');
-       ddr_selfrefresh_exit();
+       ddr_resume();
        sram_printch('5');
 }
 
@@ -389,12 +391,6 @@ static int rk30_pm_enter(suspend_state_t state)
        u32 cru_mode_con;
        u32 pmu_pwrdn_st;
 
-#ifdef CONFIG_DDR_TEST
-       // memory tester
-       if (ddr_debug != 2)
-               ddr_testmode();
-#endif
-
        // dump GPIO INTEN for debug
        rk30_pm_dump_inten();
 
@@ -407,6 +403,12 @@ static int rk30_pm_enter(suspend_state_t state)
        pmu_pwrdn_st = pmu_readl(PMU_PWRDN_ST);
        rk30_pm_set_power_domain(pmu_pwrdn_st, false);
 
+       #ifdef CONFIG_DDR_TEST
+       // memory tester
+       if (ddr_debug != 0)
+               ddr_testmode();
+    #endif
+
        sram_printch('1');
        local_fiq_disable();