add ddr code
authorhcy <hcy@rock-chips.com>
Thu, 23 Aug 2012 09:46:29 +0000 (17:46 +0800)
committerhcy <hcy@rock-chips.com>
Thu, 23 Aug 2012 09:46:29 +0000 (17:46 +0800)
arch/arm/mach-rk2928/Makefile [changed mode: 0644->0755]
arch/arm/mach-rk2928/common.c [changed mode: 0644->0755]
arch/arm/mach-rk2928/ddr.c [new file with mode: 0755]
arch/arm/mach-rk2928/include/mach/ddr.h [new file with mode: 0755]

old mode 100644 (file)
new mode 100755 (executable)
index e68d38b..a0ebbd6
@@ -6,6 +6,7 @@ obj-y += devices.o
 obj-y += iomux.o
 obj-y += clock.o
 obj-y += clock_data.o
+obj-y += ddr.o
 obj-$(CONFIG_CPU_FREQ) += cpufreq.o
 obj-$(CONFIG_DVFS) += dvfs.o
 obj-$(CONFIG_PM) += pm.o
old mode 100644 (file)
new mode 100755 (executable)
index be08809..41b7a3b
@@ -14,7 +14,7 @@
 #include <mach/iomux.h>
 #include <mach/fiq.h>
 #include <mach/loader.h>
-//#include <mach/ddr.h>
+#include <mach/ddr.h>
 
 static void __init rk2928_cpu_axi_init(void)
 {
@@ -122,7 +122,7 @@ void __init rk2928_map_io(void)
        rk29_sram_init();
        board_clock_init();
        rk2928_l2_cache_init();
-//     ddr_init(DDR_TYPE, DDR_FREQ);
+       ddr_init(DDR_TYPE, DDR_FREQ);
 //     clk_disable_unused();
        rk2928_iomux_init();
        rk2928_boot_mode_init();
diff --git a/arch/arm/mach-rk2928/ddr.c b/arch/arm/mach-rk2928/ddr.c
new file mode 100755 (executable)
index 0000000..518f412
--- /dev/null
@@ -0,0 +1,2189 @@
+/*
+ * arch/arm/mach-rk2928/ddr.c-- for ddr3&ddr2
+ *
+ * Function Driver for DDR controller
+ *
+ * Copyright (C) 2012 Fuzhou Rockchip Electronics Co.,Ltd
+ * Author: 
+ * hcy@rock-chips.com
+ * yk@rock-chips.com
+ * typ@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 DDR3_DDR2_DLL_DISABLE_FREQ    (125)   //lvddr3 ÆµÂÊÌ«µÍʱdll²»ÄÜÕý³£¹¤×÷
+#define DDR3_DDR2_ODT_DISABLE_FREQ    (333)
+#define SR_IDLE                       (0x1)   //unit:32*DDR clk cycle, and 0 for disable auto self-refresh
+#define PD_IDLE                       (0X40)  //unit:DDR clk cycle, and 0 for disable auto power-down
+
+//#define PMU_BASE_ADDR           RK30_PMU_BASE //??RK 2928 PMUÔÚÄÄÀï
+#define SDRAMC_BASE_ADDR        RK2928_DDR_PCTL_BASE
+#define DDR_PHY_BASE            RK2928_DDR_PHY_BASE
+#define CRU_BASE_ADDR           RK2928_CRU_BASE
+#define REG_FILE_BASE_ADDR      RK2928_GRF_BASE
+#define SysSrv_DdrConf          (RK2928_CPU_AXI_BUS_BASE+0x08)
+#define SysSrv_DdrTiming        (RK2928_CPU_AXI_BUS_BASE+0x0c)
+#define SysSrv_DdrMode          (RK2928_CPU_AXI_BUS_BASE+0x10)
+#define SysSrv_ReadLatency      (RK2928_CPU_AXI_BUS_BASE+0x14)
+
+#define ddr_print(x...) printk( "DDR DEBUG: " x )
+
+
+/***********************************
+ * 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_DLL_RESET    (1<<8)
+#define DDR3_DLL_DeRESET  (0<<8)
+    
+//mr1 for ddr3
+#define DDR3_DLL_ENABLE    (0)
+#define DDR3_DLL_DISABLE   (1)
+#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)
+#define DDR2_DLL_RESET    (1<<8)
+#define DDR2_DLL_DeRESET  (0<<8)
+    
+//EMR;                    //Extended Mode Register      
+#define DDR2_DLL_ENABLE    (0)
+#define DDR2_DLL_DISABLE   (1)
+
+#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)
+
+
+#define DDR_PLL_REFDIV  (1)
+#define FBDIV(n)        ((0xFFF<<16) | (n&0xfff))
+#define REFDIV(n)       ((0x3F<<16) | (n&0x3f))
+#define POSTDIV1(n)     ((0x7<<(12+16)) | ((n&0x7)<<12))
+#define POSTDIV2(n)     ((0x7<<(6+16)) | ((n&0x7)<<6))
+
+#define PLL_LOCK_STATUS  (0x1<<10)
+ //CRU Registers
+typedef volatile struct tagCRU_STRUCT
+{
+    uint32 CRU_PLL_CON[4][4];           //cru_pll_con[][4] reserved
+    uint32 CRU_MODE_CON;
+    uint32 CRU_CLKSEL_CON[35];
+    uint32 CRU_CLKGATE_CON[10];
+    uint32 reserved2[(0x100-0xf8)/4];
+    uint32 CRU_GLB_SRST_FST_VALUE;
+    uint32 CRU_GLB_SRST_SND_VALUE;
+    uint32 reserved3[(0x110-0x108)/4];
+    uint32 CRU_SOFTRST_CON[9];
+    uint32 CRU_MISC_CON;
+    uint32 reserved4[(0x140-0x138)/4];
+    uint32 CRU_GLB_CNT_TH;
+} CRU_REG, *pCRU_REG;
+
+#define pCRU_Reg ((pCRU_REG)CRU_BASE_ADDR)
+
+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;
+
+//GRF_OS_REG1   ddr message
+#define DDR_RANK_COUNT   (11)
+#define DDR_COL_COUNT    (9)
+#define DDR_BANK_COUNT   (8)
+#define DDR_ROW_COUNT    (6)
+/********************************
+GRF ¼Ä´æÆ÷ÖÐGRF_OS_REG1 ´æddr rank£¬typeµÈÐÅÏ¢
+GRF_SOC_CON2¼Ä´æÆ÷ÖпØÖÆc_sysreqÐźÅÏòpctl·¢ËͽøÈëlow power ÇëÇó
+GRF_DDRC_STAT ¿É²éѯpctlÊÇ·ñ½ÓÊÜÇëÇó ½øÈëlow power 
+********************************/
+//REG FILE registers    
+typedef volatile struct tagREG_FILE
+{
+    uint32 reserved1[(0xa8-0x0)/4];     //42
+    uint32 GRF_GPIO_IOMUX[16];      //ÆäÖР12£¬13reserved
+    uint32 reserved2[(0x118-0xe8)/4];   //12
+    GPIO_LH_T GRF_GPIO_PULL[4];
+    uint32 reserved3[(0x140-0x138)/4];  // 2
+    uint32 GRF_SOC_CON[3];
+    uint32 GRF_SOC_STATUS0;
+    uint32 GRF_LCDS_CON0;
+    uint32 reserved4[(0x15c-0x154)/4];  // 2
+    uint32 GRF_DMAC1_CON[3];
+    uint32 reserved5[(0x16c-0x168)/4];  // 1
+    uint32 GRF_UOC0_CON[5];
+    uint32 GRF_UOC1_CON[6];
+    uint32 reserved6[(0x19c-0x198)/4];  // 1
+    uint32 GRF_DDRC_STAT;
+    uint32 reserved7[(0x1c8-0x1a0)/4];  //10
+    uint32 GRF_OS_REG[4];
+} REG_FILE, *pREG_FILE;
+
+#define pGRF_Reg ((pREG_FILE)REG_FILE_BASE_ADDR)
+
+//SCTL
+#define INIT_STATE                     (0)
+#define CFG_STATE                      (1)
+#define GO_STATE                       (2)
+#define SLEEP_STATE                    (3)
+#define WAKEUP_STATE                   (4)
+
+//STAT
+#define Init_mem                       (0)
+#define Config                         (1)
+#define Config_req                     (2)
+#define Access                         (3)
+#define Access_req                     (4)
+#define Low_power                      (5)
+#define Low_power_entry_req            (6)
+#define Low_power_exit_req             (7)
+
+//MCFG
+#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)
+#define ddr3_en                        (1<<5)
+#define lpddr2_s2                      (0<<6)
+#define lpddr2_s4                      (1<<6)
+#define mddr_lpddr2_bl_2               (0<<20)
+#define mddr_lpddr2_bl_4               (1<<20)
+#define mddr_lpddr2_bl_8               (2<<20)
+#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 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)
+
+//POWCTL
+#define power_up_start                 (1<<0)
+
+//POWSTAT
+#define power_up_done                  (1<<0)
+
+//DFISTSTAT0
+#define dfi_init_complete              (1<<0)
+
+//CMDTSTAT
+#define cmd_tstat                      (1<<0)
+
+//CMDTSTATEN
+#define cmd_tstat_en                   (1<<1)
+
+//MCMD
+#define Deselect_cmd                   (0)
+#define PREA_cmd                       (1)
+#define REF_cmd                        (2)
+#define MRS_cmd                        (3)
+#define ZQCS_cmd                       (4)
+#define ZQCL_cmd                       (5)
+#define RSTL_cmd                       (6)
+#define MRR_cmd                        (8)
+#define DPDE_cmd                       (9)
+
+#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 start_cmd                      (1u<<31)
+
+typedef union STAT_Tag
+{
+    uint32 d32;
+    struct
+    {
+        unsigned ctl_stat : 3;
+        unsigned reserved3 : 1;
+        unsigned lp_trig : 3;
+        unsigned reserved7_31 : 25;
+    }b;
+}STAT_T;
+
+typedef union SCFG_Tag
+{
+    uint32 d32;
+    struct
+    {
+        unsigned hw_low_power_en : 1;
+        unsigned reserved1_5 : 5;
+        unsigned nfifo_nif1_dis : 1;
+        unsigned reserved7 : 1;
+        unsigned bbflags_timing : 4;
+        unsigned reserved12_31 : 20;
+    } b;
+}SCFG_T;
+
+/* DDR Controller register struct */
+typedef volatile struct DDR_REG_Tag
+{
+    //Operational State, Control, and Status Registers
+    SCFG_T SCFG;                   //State Configuration Register
+    volatile uint32 SCTL;                   //State Control Register
+    STAT_T STAT;                   //State Status Register
+    volatile uint32 INTRSTAT;               //Interrupt Status Register
+    uint32 reserved0[(0x40-0x10)/4];
+    //Initailization Control and Status Registers
+    volatile uint32 MCMD;                   //Memory Command Register
+    volatile uint32 POWCTL;                 //Power Up Control Registers
+    volatile uint32 POWSTAT;                //Power Up Status Register
+    volatile uint32 CMDTSTAT;               //Command Timing Status Register
+    volatile uint32 CMDTSTATEN;             //Command Timing Status Enable Register
+    uint32 reserved1[(0x60-0x54)/4];
+    volatile uint32 MRRCFG0;                //MRR Configuration 0 Register
+    volatile uint32 MRRSTAT0;               //MRR Status 0 Register
+    volatile uint32 MRRSTAT1;               //MRR Status 1 Register
+    uint32 reserved2[(0x7c-0x6c)/4];
+    //Memory Control and Status Registers
+    volatile uint32 MCFG1;                  //Memory Configuration 1 Register
+    volatile uint32 MCFG;                   //Memory Configuration Register
+    volatile uint32 PPCFG;                  //Partially Populated Memories Configuration Register
+    volatile uint32 MSTAT;                  //Memory Status Register
+    volatile uint32 LPDDR2ZQCFG;            //LPDDR2 ZQ Configuration Register
+    uint32 reserved3;
+    //DTU Control and Status Registers
+    volatile uint32 DTUPDES;                //DTU Status Register
+    volatile uint32 DTUNA;                  //DTU Number of Random Addresses Created Register
+    volatile uint32 DTUNE;                  //DTU Number of Errors Register
+    volatile uint32 DTUPRD0;                //DTU Parallel Read 0
+    volatile uint32 DTUPRD1;                //DTU Parallel Read 1
+    volatile uint32 DTUPRD2;                //DTU Parallel Read 2
+    volatile uint32 DTUPRD3;                //DTU Parallel Read 3
+    volatile uint32 DTUAWDT;                //DTU Address Width
+    uint32 reserved4[(0xc0-0xb4)/4];
+    //Memory Timing Registers
+    volatile uint32 TOGCNT1U;               //Toggle Counter 1U Register
+    volatile uint32 TINIT;                  //t_init Timing Register
+    volatile uint32 TRSTH;                  //Reset High Time Register
+    volatile uint32 TOGCNT100N;             //Toggle Counter 100N Register
+    volatile uint32 TREFI;                  //t_refi Timing Register
+    volatile uint32 TMRD;                   //t_mrd Timing Register
+    volatile uint32 TRFC;                   //t_rfc Timing Register
+    volatile uint32 TRP;                    //t_rp Timing Register
+    volatile uint32 TRTW;                   //t_rtw Timing Register
+    volatile uint32 TAL;                    //AL Latency Register
+    volatile uint32 TCL;                    //CL Timing Register
+    volatile uint32 TCWL;                   //CWL Register
+    volatile uint32 TRAS;                   //t_ras Timing Register
+    volatile uint32 TRC;                    //t_rc Timing Register
+    volatile uint32 TRCD;                   //t_rcd Timing Register
+    volatile uint32 TRRD;                   //t_rrd Timing Register
+    volatile uint32 TRTP;                   //t_rtp Timing Register
+    volatile uint32 TWR;                    //t_wr Timing Register
+    volatile uint32 TWTR;                   //t_wtr Timing Register
+    volatile uint32 TEXSR;                  //t_exsr Timing Register
+    volatile uint32 TXP;                    //t_xp Timing Register
+    volatile uint32 TXPDLL;                 //t_xpdll Timing Register
+    volatile uint32 TZQCS;                  //t_zqcs Timing Register
+    volatile uint32 TZQCSI;                 //t_zqcsi Timing Register
+    volatile uint32 TDQS;                   //t_dqs Timing Register
+    volatile uint32 TCKSRE;                 //t_cksre Timing Register
+    volatile uint32 TCKSRX;                 //t_cksrx Timing Register
+    volatile uint32 TCKE;                   //t_cke Timing Register
+    volatile uint32 TMOD;                   //t_mod Timing Register
+    volatile uint32 TRSTL;                  //Reset Low Timing Register
+    volatile uint32 TZQCL;                  //t_zqcl Timing Register
+    volatile uint32 TMRR;                   //t_mrr Timing Register
+    volatile uint32 TCKESR;                 //t_ckesr Timing Register
+    volatile uint32 TDPD;                   //t_dpd Timing Register
+    uint32 reserved5[(0x180-0x148)/4];
+    //ECC Configuration, Control, and Status Registers
+    volatile uint32 ECCCFG;                   //ECC Configuration Register
+    volatile uint32 ECCTST;                   //ECC Test Register
+    volatile uint32 ECCCLR;                   //ECC Clear Register
+    volatile uint32 ECCLOG;                   //ECC Log Register
+    uint32 reserved6[(0x200-0x190)/4];
+    //DTU Control and Status Registers
+    volatile uint32 DTUWACTL;                 //DTU Write Address Control Register
+    volatile uint32 DTURACTL;                 //DTU Read Address Control Register
+    volatile uint32 DTUCFG;                   //DTU Configuration Control Register
+    volatile uint32 DTUECTL;                  //DTU Execute Control Register
+    volatile uint32 DTUWD0;                   //DTU Write Data 0
+    volatile uint32 DTUWD1;                   //DTU Write Data 1
+    volatile uint32 DTUWD2;                   //DTU Write Data 2
+    volatile uint32 DTUWD3;                   //DTU Write Data 3
+    volatile uint32 DTUWDM;                   //DTU Write Data Mask
+    volatile uint32 DTURD0;                   //DTU Read Data 0
+    volatile uint32 DTURD1;                   //DTU Read Data 1
+    volatile uint32 DTURD2;                   //DTU Read Data 2
+    volatile uint32 DTURD3;                   //DTU Read Data 3
+    volatile uint32 DTULFSRWD;                //DTU LFSR Seed for Write Data Generation
+    volatile uint32 DTULFSRRD;                //DTU LFSR Seed for Read Data Generation
+    volatile uint32 DTUEAF;                   //DTU Error Address FIFO
+    //DFI Control Registers
+    volatile uint32 DFITCTRLDELAY;            //DFI tctrl_delay Register
+    volatile uint32 DFIODTCFG;                //DFI ODT Configuration Register
+    volatile uint32 DFIODTCFG1;               //DFI ODT Configuration 1 Register
+    volatile uint32 DFIODTRANKMAP;            //DFI ODT Rank Mapping Register
+    //DFI Write Data Registers
+    volatile uint32 DFITPHYWRDATA;            //DFI tphy_wrdata Register
+    volatile uint32 DFITPHYWRLAT;             //DFI tphy_wrlat Register
+    uint32 reserved7[(0x260-0x258)/4];
+    volatile uint32 DFITRDDATAEN;             //DFI trddata_en Register
+    volatile uint32 DFITPHYRDLAT;             //DFI tphy_rddata Register
+    uint32 reserved8[(0x270-0x268)/4];
+    //DFI Update Registers
+    volatile uint32 DFITPHYUPDTYPE0;          //DFI tphyupd_type0 Register
+    volatile uint32 DFITPHYUPDTYPE1;          //DFI tphyupd_type1 Register
+    volatile uint32 DFITPHYUPDTYPE2;          //DFI tphyupd_type2 Register
+    volatile uint32 DFITPHYUPDTYPE3;          //DFI tphyupd_type3 Register
+    volatile uint32 DFITCTRLUPDMIN;           //DFI tctrlupd_min Register
+    volatile uint32 DFITCTRLUPDMAX;           //DFI tctrlupd_max Register
+    volatile uint32 DFITCTRLUPDDLY;           //DFI tctrlupd_dly Register
+    uint32 reserved9;
+    volatile uint32 DFIUPDCFG;                //DFI Update Configuration Register
+    volatile uint32 DFITREFMSKI;              //DFI Masked Refresh Interval Register
+    volatile uint32 DFITCTRLUPDI;             //DFI tctrlupd_interval Register
+    uint32 reserved10[(0x2ac-0x29c)/4];
+    volatile uint32 DFITRCFG0;                //DFI Training Configuration 0 Register
+    volatile uint32 DFITRSTAT0;               //DFI Training Status 0 Register
+    volatile uint32 DFITRWRLVLEN;             //DFI Training dfi_wrlvl_en Register
+    volatile uint32 DFITRRDLVLEN;             //DFI Training dfi_rdlvl_en Register
+    volatile uint32 DFITRRDLVLGATEEN;         //DFI Training dfi_rdlvl_gate_en Register
+    //DFI Status Registers
+    volatile uint32 DFISTSTAT0;               //DFI Status Status 0 Register
+    volatile uint32 DFISTCFG0;                //DFI Status Configuration 0 Register
+    volatile uint32 DFISTCFG1;                //DFI Status configuration 1 Register
+    uint32 reserved11;
+    volatile uint32 DFITDRAMCLKEN;            //DFI tdram_clk_enalbe Register
+    volatile uint32 DFITDRAMCLKDIS;           //DFI tdram_clk_disalbe Register
+    volatile uint32 DFISTCFG2;                //DFI Status configuration 2 Register
+    volatile uint32 DFISTPARCLR;              //DFI Status Parity Clear Register
+    volatile uint32 DFISTPARLOG;              //DFI Status Parity Log Register
+    uint32 reserved12[(0x2f0-0x2e4)/4];
+    //DFI Low Power Registers
+    volatile uint32 DFILPCFG0;                //DFI Low Power Configuration 0 Register
+    uint32 reserved13[(0x300-0x2f4)/4];
+    //DFI Training 2 Registers
+    volatile uint32 DFITRWRLVLRESP0;          //DFI Training dif_wrlvl_resp Status 0 Register
+    volatile uint32 DFITRWRLVLRESP1;          //DFI Training dif_wrlvl_resp Status 1 Register
+    volatile uint32 DFITRWRLVLRESP2;          //DFI Training dif_wrlvl_resp Status 2 Register
+    volatile uint32 DFITRRDLVLRESP0;          //DFI Training dif_rdlvl_resp Status 0 Register
+    volatile uint32 DFITRRDLVLRESP1;          //DFI Training dif_rdlvl_resp Status 1 Register
+    volatile uint32 DFITRRDLVLRESP2;          //DFI Training dif_rdlvl_resp Status 2 Register
+    volatile uint32 DFITRWRLVLDELAY0;         //DFI Training dif_wrlvl_delay Configuration 0 Register
+    volatile uint32 DFITRWRLVLDELAY1;         //DFI Training dif_wrlvl_delay Configuration 1 Register
+    volatile uint32 DFITRWRLVLDELAY2;         //DFI Training dif_wrlvl_delay Configuration 2 Register
+    volatile uint32 DFITRRDLVLDELAY0;         //DFI Training dif_rdlvl_delay Configuration 0 Register
+    volatile uint32 DFITRRDLVLDELAY1;         //DFI Training dif_rdlvl_delay Configuration 1 Register
+    volatile uint32 DFITRRDLVLDELAY2;         //DFI Training dif_rdlvl_delay Configuration 2 Register
+    volatile uint32 DFITRRDLVLGATEDELAY0;     //DFI Training dif_rdlvl_gate_delay Configuration 0 Register
+    volatile uint32 DFITRRDLVLGATEDELAY1;     //DFI Training dif_rdlvl_gate_delay Configuration 1 Register
+    volatile uint32 DFITRRDLVLGATEDELAY2;     //DFI Training dif_rdlvl_gate_delay Configuration 2 Register
+    volatile uint32 DFITRCMD;                 //DFI Training Command Register
+    uint32 reserved14[(0x3f8-0x340)/4];
+    //IP Status Registers
+    volatile uint32 IPVR;                     //IP Version Register
+    volatile uint32 IPTR;                     //IP Type Register
+}DDR_REG_T, *pDDR_REG_T;
+
+#define pDDR_Reg ((pDDR_REG_T)SDRAMC_BASE_ADDR)
+
+//PHY_REG2
+#define PHY_AUTO_CALIBRATION (1<<0)
+#define PHY_SW_CALIBRATION   (1<<1)
+#define PHY_MEM_TYPE         (6)
+
+//PHY_REG22,25,26,27,28
+#define PHY_RON_DISABLE     (0)
+#define PHY_RON_138O        (1)
+//#define PHY_RON_69O         (2)
+//#define PHY_RON_46O         (3)
+#define PHY_RON_69O         (4)
+#define PHY_RON_46O         (5)
+#define PHY_RON_34O         (6)
+#define PHY_RON_28O         (7)
+
+#define PHY_RTT_DISABLE     (0)
+#define PHY_RTT_212O        (1)
+#define PHY_RTT_106O        (4)
+#define PHY_RTT_71O         (5)
+#define PHY_RTT_53O         (6)
+#define PHY_RTT_42O         (7)
+
+
+
+/* DDR PHY register struct */
+typedef volatile struct DDRPHY_REG_Tag
+{
+    volatile uint32 PHY_REG1;               //PHY soft reset Register
+    volatile uint32 PHY_REG3;               //Burst type select Register
+    volatile uint32 PHY_REG2;               //PHY DQS squelch calibration Register
+    uint32 reserved1[(0x38-0x0a)/4];
+    volatile uint32 PHY_REG4a;              //CL,AL set register
+    volatile uint32 PHY_REG4b;              //dqs gata delay select bypass mode register
+    uint32 reserved2[(0x54-0x40)/4];
+    volatile uint32 PHY_REG16;              //
+    uint32 reserved3[(0x5c-0x58)/4];
+    volatile uint32 PHY_REG18;              //0x5c
+    volatile uint32 PHY_REG19;
+    uint32 reserved4[(0x68-0x64)/4];
+    volatile uint32 PHY_REG21;              //0x68
+    uint32 reserved5[(0x70-0x6c)/4];     
+    volatile uint32 PHY_REG22;              //0x70
+    uint32 reserved6[(0x80-0x74)/4];
+    volatile uint32 PHY_REG25;              //0x80
+    volatile uint32 PHY_REG26;
+    volatile uint32 PHY_REG27;
+    volatile uint32 PHY_REG28;
+    uint32 reserved7[(0xd4-0x90)/4];
+    volatile uint32 PHY_REG6;               //0xd4
+    volatile uint32 PHY_REG7;
+    uint32 reserved8[(0xe0-0xdc)/4];
+    volatile uint32 PHY_REG8;               //0xe0
+    uint32 reserved9[(0x114-0xe4)/4];
+    volatile uint32 PHY_REG9;               //0x114
+    volatile uint32 PHY_REG10;
+    uint32 reserved10[(0x120-0x11c)/4];
+    volatile uint32 PHY_REG11;              //0x120
+    uint32 reserved11[(0x1c0-0x124)/4];
+    volatile uint32 PHY_REG29;              //0x1c0
+    uint32 reserved12[(0x264-0x1c4)/4];
+       volatile uint32 PHY_REG264;
+       uint32 reserved13[(0x2b0-0x268)/4];
+    volatile uint32 PHY_REG2a;              //0x2b0
+    uint32 reserved14[(0x2c4-0x2b4)/4];
+//    volatile uint32 PHY_TX_DeSkew[24];        //0x2c4-0x320
+    volatile uint32 PHY_REG30;
+    volatile uint32 PHY_REG31;
+    volatile uint32 PHY_REG32;
+    volatile uint32 PHY_REG33;
+    volatile uint32 PHY_REG34;
+    volatile uint32 PHY_REG35;
+    volatile uint32 PHY_REG36;
+    volatile uint32 PHY_REG37;
+    volatile uint32 PHY_REG38;
+    volatile uint32 PHY_REG39;
+    volatile uint32 PHY_REG40;
+    volatile uint32 PHY_REG41;
+    volatile uint32 PHY_REG42;
+    volatile uint32 PHY_REG43;
+    volatile uint32 PHY_REG44;
+    volatile uint32 PHY_REG45;
+    volatile uint32 PHY_REG46;
+    volatile uint32 PHY_REG47;
+    volatile uint32 PHY_REG48;
+    volatile uint32 PHY_REG49;
+    volatile uint32 PHY_REG50;
+    volatile uint32 PHY_REG51;
+    volatile uint32 PHY_REG52;
+    volatile uint32 PHY_REG53;
+    uint32 reserved15[(0x328-0x324)/4];
+//    volatile uint32 PHY_RX_DeSkew[11];      //0x328-0x350
+    volatile uint32 PHY_REG54;
+    volatile uint32 PHY_REG55;
+    volatile uint32 PHY_REG56;
+    volatile uint32 PHY_REG57;
+    volatile uint32 PHY_REG58;
+    volatile uint32 PHY_REG59;
+    volatile uint32 PHY_REG5a;
+    volatile uint32 PHY_REG5b;
+    volatile uint32 PHY_REG5c;
+    volatile uint32 PHY_REG5d;
+    volatile uint32 PHY_REG5e;    
+    uint32 reserved16[(0x3c4-0x354)/4];
+    volatile uint32 PHY_REG5f;              //0x3c4
+    uint32 reserved17[(0x3e0-0x3c8)/4];
+    volatile uint32 PHY_REG60;
+    volatile uint32 PHY_REG61;
+    volatile uint32 PHY_REG62;            
+}DDRPHY_REG_T, *pDDRPHY_REG_T;
+
+#define pPHY_Reg ((pDDRPHY_REG_T)DDR_PHY_BASE)
+
+typedef enum DRAM_TYPE_Tag
+{
+    LPDDR = 0,
+    DDR,
+    DDR2,
+    DDR3,
+    LPDDR2_S2,
+    LPDDR2_S4,
+
+    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 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 PCTL_REG_Tag
+{
+    uint32 SCFG;
+    uint32 CMDTSTATEN;
+    uint32 MCFG1;
+    uint32 MCFG;
+    PCTL_TIMING_T pctl_timing;
+    //DFI Control Registers
+    uint32 DFITCTRLDELAY;
+    uint32 DFIODTCFG;
+    uint32 DFIODTCFG1;
+    uint32 DFIODTRANKMAP;
+    //DFI Write Data Registers
+    uint32 DFITPHYWRDATA;
+    uint32 DFITPHYWRLAT;
+    //DFI Read Data Registers
+    uint32 DFITRDDATAEN;
+    uint32 DFITPHYRDLAT;
+    //DFI Update Registers
+    uint32 DFITPHYUPDTYPE0;
+    uint32 DFITPHYUPDTYPE1;
+    uint32 DFITPHYUPDTYPE2;
+    uint32 DFITPHYUPDTYPE3;
+    uint32 DFITCTRLUPDMIN;
+    uint32 DFITCTRLUPDMAX;
+    uint32 DFITCTRLUPDDLY;
+    uint32 DFIUPDCFG;
+    uint32 DFITREFMSKI;
+    uint32 DFITCTRLUPDI;
+    //DFI Status Registers
+    uint32 DFISTCFG0;
+    uint32 DFISTCFG1;
+    uint32 DFITDRAMCLKEN;
+    uint32 DFITDRAMCLKDIS;
+    uint32 DFISTCFG2;
+    //DFI Low Power Register
+    uint32 DFILPCFG0;
+}PCTL_REG_T;
+
+typedef struct BACKUP_REG_Tag
+{
+    PCTL_REG_T pctl;
+    uint32 DdrConf;
+    NOC_TIMING_T noc_timing;
+    uint32 DdrMode;
+    uint32 ReadLatency;
+    uint32 ddrMR[4];
+}BACKUP_REG_T;
+
+__sramdata BACKUP_REG_T ddr_reg;
+
+
+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
+};
+
+__sramdata uint32_t mem_type;    //0:DDR3  1:DDR2  ;ÓëInno PHY µÄPHY_REG2 ÀïÉèÖõÄÖµÏàÒ»ÖÂ
+static __sramdata uint32_t ddr_speed_bin;    // used for ddr3 only
+static __sramdata uint32_t ddr_capability_per_die;  // one chip cs capability
+static __sramdata uint32_t ddr_freq;
+static __sramdata uint32_t ddr_sr_idle;
+static __sramdata uint32_t ddr_dll_status;  // ¼Ç¼ddr dllµÄ״̬£¬ÔÚselfrefresh exitʱѡÔñÊÇ·ñ½øÐÐdll reset
+
+/****************************************************************************
+Internal sram us delay function
+Cpu highest frequency is 1.6 GHz
+1 cycle = 1/1.6 ns
+1 us = 1000 ns = 1000 * 1.6 cycles = 1600 cycles
+*****************************************************************************/
+static __sramdata uint32_t loops_per_us;
+
+#define LPJ_100MHZ  999456UL
+
+/*----------------------------------------------------------------------
+Name   : void __sramlocalfunc ddr_delayus(uint32_t us)
+Desc   : ddr ÑÓʱº¯Êý
+Params  : uint32_t us  --ÑÓʱʱ¼ä
+Return  : void
+Notes   : loops_per_us ÎªÈ«¾Ö±äÁ¿ ÐèÒª¸ù¾Ýarm freq¶ø¶¨
+----------------------------------------------------------------------*/
+
+/*static*/ void __sramlocalfunc ddr_delayus(uint32_t us)
+{   
+    uint32_t count;
+     
+    count = loops_per_us*us;
+    while(count--)  // 3 cycles
+        barrier();
+}
+
+/*----------------------------------------------------------------------
+Name   : __sramfunc void ddr_copy(uint32 *pDest, uint32 *pSrc, uint32 words)
+Desc   : ddr ¿½±´¼Ä´æÆ÷º¯Êý
+Params  : pDest ->Ä¿±ê¼Ä´æÆ÷Ê×µØÖ·
+          pSrc  ->Ô´±ê¼Ä´æÆ÷Ê×µØÖ·
+          words ->¿½±´³¤¶È
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+
+__sramfunc void ddr_copy(uint32 *pDest, uint32 *pSrc, uint32 words)
+{
+    uint32 i;
+
+    for(i=0; i<words; i++)
+    {
+        pDest[i] = pSrc[i];
+    }
+}
+
+/*----------------------------------------------------------------------
+Name   : uint32 ddr_get_row(void)
+Desc   : »ñÈ¡ddr row ÐÅÏ¢
+Params  : void
+Return  : row Êý
+Notes   : 
+----------------------------------------------------------------------*/
+uint32 ddr_get_row(void)
+{
+    return (13+((pGRF_Reg->GRF_OS_REG[1] >> DDR_ROW_COUNT) & 0x3));
+}
+
+/*----------------------------------------------------------------------
+Name   : uint32 ddr_get_bank(void)
+Desc   : »ñÈ¡ddr bank ÐÅÏ¢
+Params  : void
+Return  : bank Êý
+Notes   : 
+----------------------------------------------------------------------*/
+uint32 ddr_get_bank(void)
+{
+     return (((pGRF_Reg->GRF_OS_REG[1] >> DDR_BANK_COUNT) & 0x1)? 2:3);
+}
+
+/*----------------------------------------------------------------------
+Name   : uint32 ddr_get_col(void)
+Desc   : »ñÈ¡ddr col ÐÅÏ¢
+Params  : void
+Return  : col Êý
+Notes   : 
+----------------------------------------------------------------------*/
+uint32 ddr_get_col(void)
+{
+    return (9 + ((pGRF_Reg->GRF_OS_REG[1]>>DDR_COL_COUNT)&0x3));
+}
+
+/*----------------------------------------------------------------------
+Name   : __sramfunc void ddr_move_to_Lowpower_state(void)
+Desc   : pctl ½øÈë lowpower state
+Params  : void
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+__sramfunc void ddr_move_to_Lowpower_state(void)
+{
+    volatile uint32 value;
+
+    while(1)
+    {
+        value = pDDR_Reg->STAT.b.ctl_stat;
+        if(value == Low_power)
+        {
+            break;
+        }
+        switch(value)
+        {
+            case Init_mem:
+                pDDR_Reg->SCTL = CFG_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Config);
+            case Config:
+                pDDR_Reg->SCTL = GO_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Access);
+            case Access:
+                pDDR_Reg->SCTL = SLEEP_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Low_power);
+                break;
+            default:  //Transitional state
+                break;
+        }
+    }
+}
+
+/*----------------------------------------------------------------------
+Name   : __sramfunc void ddr_move_to_Access_state(void)
+Desc   : pctl ½øÈë Access state
+Params  : void
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+__sramfunc void ddr_move_to_Access_state(void)
+{
+    volatile uint32 value;
+
+    //set auto self-refresh idle
+    pDDR_Reg->MCFG1=(pDDR_Reg->MCFG1&0xffffff00)|ddr_sr_idle;
+
+    while(1)
+    {
+        value = pDDR_Reg->STAT.b.ctl_stat;
+        if((value == Access)
+           || ((pDDR_Reg->STAT.b.lp_trig == 1) && ((pDDR_Reg->STAT.b.ctl_stat) == Low_power)))
+        {
+            break;
+        }
+        switch(value)
+        {
+            case Low_power:
+                pDDR_Reg->SCTL = WAKEUP_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Access);
+                break;
+            case Init_mem:
+                pDDR_Reg->SCTL = CFG_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Config);
+            case Config:
+                pDDR_Reg->SCTL = GO_STATE;
+                while(!(((pDDR_Reg->STAT.b.ctl_stat) == Access)
+                      || ((pDDR_Reg->STAT.b.lp_trig == 1) && ((pDDR_Reg->STAT.b.ctl_stat) == Low_power))));
+                break;
+            default:  //Transitional state
+                break;
+        }
+    }
+}
+
+/*----------------------------------------------------------------------
+Name   : __sramfunc void ddr_move_to_Config_state(void)
+Desc   : pctl ½øÈë config state
+Params  : void
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+__sramfunc void ddr_move_to_Config_state(void)
+{
+    volatile uint32 value;
+
+    //clear auto self-refresh idle
+    if(pDDR_Reg->MCFG1 & 0xFF)
+    {
+        //access state ÏÂдMCFG1ÎÞЧ È·±£½øÈëlowpower
+        while(pDDR_Reg->STAT.b.ctl_stat == Access);
+        pDDR_Reg->MCFG1=(pDDR_Reg->MCFG1&0xffffff00)|0x0;
+        dsb();
+    }
+
+    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);
+            case Access:
+            case Init_mem:
+                pDDR_Reg->SCTL = CFG_STATE;
+                while((pDDR_Reg->STAT.b.ctl_stat) != Config);
+                break;
+            default:  //Transitional state
+                break;
+        }
+    }
+}
+
+/*----------------------------------------------------------------------
+Name   : void __sramlocalfunc ddr_send_command(uint32 rank, uint32 cmd, uint32 arg)
+Desc   : Í¨¹ýд pctl MCMD¼Ä´æÆ÷Ïòddr·¢ËÍÃüÁî
+Params  : rank ->ddr rank Êý
+          cmd  ->·¢ËÍÃüÁîÀàÐÍ
+          arg  ->·¢Ë͵ÄÊý¾Ý
+Return  : void 
+Notes   : arg°üÀ¨bank_addrºÍcmd_addr
+----------------------------------------------------------------------*/
+void __sramlocalfunc ddr_send_command(uint32 rank, uint32 cmd, uint32 arg)
+{
+    pDDR_Reg->MCMD = (start_cmd | (rank<<20) | arg | cmd);
+    dsb();
+    while(pDDR_Reg->MCMD & start_cmd);
+}
+
+__sramdata uint32 copy_data[8]={0xffffffff,0x00000000,0x55555555,0xAAAAAAAA,
+                               0xEEEEEEEE,0x11111111,0x22222222,0xDDDDDDDD};/**/
+
+/*----------------------------------------------------------------------
+Name   : uint32_t __sramlocalfunc ddr_data_training(void)
+Desc   : ¶Ôddr×ödata training
+Params  : void
+Return  : void 
+Notes   : Ã»ÓÐ×ödata trainingУÑé
+----------------------------------------------------------------------*/
+uint32_t __sramlocalfunc ddr_data_training(void)
+{
+    uint32 value, cs;
+    value = pDDR_Reg->TREFI;
+    pDDR_Reg->TREFI = 0;
+    cs = (pGRF_Reg->GRF_OS_REG[1] >> DDR_RANK_COUNT) & 0x1;
+    cs = cs + (1 << cs);                               //case 0:1rank cs=1; case 1:2rank cs =3;
+    // trigger DTT
+    pPHY_Reg->PHY_REG2 = ((pPHY_Reg->PHY_REG2 & (~0x3)) | PHY_AUTO_CALIBRATION);
+    // wait echo byte DTDONE
+    ddr_delayus(6);
+    // stop DTT
+    while((pPHY_Reg->PHY_REG62 & 0x3)!=0x3);
+    pPHY_Reg->PHY_REG2 = (pPHY_Reg->PHY_REG2 & (~0x3));
+    // send some auto refresh to complement the lost while DTT
+    ddr_send_command(cs, REF_cmd, 0);    
+    ddr_send_command(cs, REF_cmd, 0);
+    ddr_send_command(cs, REF_cmd, 0);    
+    ddr_send_command(cs, REF_cmd, 0);
+
+    // resume auto refresh
+    pDDR_Reg->TREFI = value;
+
+    return(0);
+}
+
+/*----------------------------------------------------------------------
+Name    : void __sramlocalfunc ddr_set_dll_bypass(uint32 freq)
+Desc    : ÉèÖÃPHY dll ¹¤×÷ģʽ
+Params  : freq -> ddr¹¤×÷ƵÂÊ
+Return  : void 
+Notes   : 
+----------------------------------------------------------------------*/
+void __sramlocalfunc ddr_set_dll_bypass(uint32 freq)
+{
+    if(freq <= 266)
+    {
+        pPHY_Reg->PHY_REG2a = 0x1F;         //set cmd,left right dll bypass
+        pPHY_Reg->PHY_REG19 = 0x08;         //cmd slave dll
+        pPHY_Reg->PHY_REG6 = 0x18;          //left TX DQ DLL
+        pPHY_Reg->PHY_REG7 = 0x00;          //left TX DQS DLL
+        pPHY_Reg->PHY_REG9 = 0x18;          //right TX DQ DLL
+        pPHY_Reg->PHY_REG10 = 0x00;         //right TX DQS DLL
+    }
+    else 
+    {
+        pPHY_Reg->PHY_REG2a = 0x00;         //set cmd,left right dll bypass
+        pPHY_Reg->PHY_REG19 = 0x08;         //cmd slave dll
+        pPHY_Reg->PHY_REG6 = 0x0c;          //left TX DQ DLL
+        pPHY_Reg->PHY_REG7 = 0x00;          //left TX DQS DLL
+        pPHY_Reg->PHY_REG9 = 0x0c;          //right TX DQ DLL
+        pPHY_Reg->PHY_REG10 = 0x00;         //right TX DQS DLL                
+    }
+
+    //ÆäËûÓëdllÏà¹ØµÄ¼Ä´æÆ÷ÓÐ:REG8(RX DQS),REG11(RX DQS),REG18(CMD),REG21(CK) ±£³ÖĬÈÏÖµ
+}
+
+
+static __sramdata uint32_t clkFbDiv;
+static __sramdata uint32_t clkPostDiv1;
+static __sramdata uint32_t clkPostDiv2;
+
+/*****************************************
+REFDIV   FBDIV     POSTDIV1/POSTDIV2      FOUTPOSTDIV           freq Step        FOUTPOSRDIV            finally use
+==================================================================================================================
+1        17 - 66   4                      100MHz - 400MHz          6MHz          200MHz  <= 300MHz             <= 150MHz
+1        17 - 66   3                      133MHz - 533MHz          8MHz             
+1        17 - 66   2                      200MHz - 800MHz          12MHz         300MHz  <= 600MHz      150MHz <= 300MHz
+1        17 - 66   1                      400MHz - 1600MHz         24MHz         600MHz  <= 1200MHz     300MHz <= 600MHz
+******************************************/
+//for minimum jitter operation, the highest VCO and FREF frequencies should be used.
+/*----------------------------------------------------------------------
+Name    : uint32_t __sramlocalfunc ddr_set_pll(uint32_t nMHz, uint32_t set)
+Desc    : ÉèÖÃddr pll
+Params  : nMHZ -> ddr¹¤×÷ƵÂÊ
+          set  ->0»ñÈ¡ÉèÖõÄƵÂÊÐÅÏ¢
+                 1ÉèÖÃddr pll
+Return  : ÉèÖõÄƵÂÊÖµ 
+Notes   : ÔÚ±äƵʱÐèÒªÏÈset=0µ÷ÓÃÒ»´Îddr_set_pll£¬ÔÙset=1 µ÷ÓÃddr_set_pll
+----------------------------------------------------------------------*/
+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     
+    
+    if(nMHz == 24)
+    {
+        ret = 24;
+        goto out;
+    }
+    
+    if(!set)
+    {
+        if(nMHz <= 150)
+        {
+            clkPostDiv1 = 4;
+        }
+        else if(nMHz <= 300)
+        {
+            clkPostDiv1 = 2;
+        }
+        else
+        {
+            clkPostDiv1 = 1;
+        }
+        clkPostDiv2 = 1;
+        clkFbDiv = (nMHz * 2 * DDR_PLL_REFDIV * clkPostDiv1 * clkPostDiv2)/24;//×îºóËÍÈëddrµÄÊÇÔÙ¾­¹ý2·ÖƵ
+        ret = (24 * clkFbDiv)/(2 * DDR_PLL_REFDIV * clkPostDiv1 * clkPostDiv2);
+    }
+    else
+    {
+        pCRU_Reg->CRU_MODE_CON = (0x1<<((pll_id*4) +  16)) | (0x0<<(pll_id*4));            //PLL slow-mode
+    
+        pCRU_Reg->CRU_PLL_CON[pll_id][0] = FBDIV(clkFbDiv) | POSTDIV1(clkPostDiv1);
+        pCRU_Reg->CRU_PLL_CON[pll_id][1] = REFDIV(DDR_PLL_REFDIV) | POSTDIV2(clkPostDiv2) | (0x10001<<12);//interger mode
+
+        ddr_delayus(1);
+
+        while (delay > 0) 
+        {
+           ddr_delayus(1);
+               if (pCRU_Reg->CRU_PLL_CON[pll_id][1] & (PLL_LOCK_STATUS))        // wait for pll locked
+                       break;
+               delay--;
+       }
+        
+        pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3<<16) | 0x0);           //clk_ddr_src:clk_ddrphy = 1:1       
+        pCRU_Reg->CRU_MODE_CON = (0x1<<((pll_id*4) +  16))  | (0x1<<(pll_id*4));            //PLL normal
+    }
+out:
+    return ret;
+}
+
+/*----------------------------------------------------------------------
+Name    : uint32_t ddr_get_parameter(uint32_t nMHz)
+Desc    : »ñÈ¡ÅäÖòÎÊý
+Params  : nMHZ -> ddr¹¤×÷ƵÂÊ     
+Return  : 0 ³É¹¦
+          -1 Ê§°Ü
+          -4 ÆµÂÊÖµ³¬¹ý¿ÅÁ£×î´óƵÂÊ
+Notes   : 
+----------------------------------------------------------------------*/
+uint32_t ddr_get_parameter(uint32_t nMHz)
+{
+    uint32_t tmp;
+    uint32_t ret = 0;
+    uint32_t al;
+    uint32_t bl;
+    uint32_t cl;
+    uint32_t cwl;    
+    PCTL_TIMING_T *p_pctl_timing=&(ddr_reg.pctl.pctl_timing);
+    NOC_TIMING_T  *p_noc_timing=&(ddr_reg.noc_timing);
+
+    p_pctl_timing->togcnt1u = nMHz;
+    p_pctl_timing->togcnt100n = nMHz/10;
+    p_pctl_timing->tinit = 200;
+    p_pctl_timing->trsth = 500;
+
+    if(mem_type == DDR3)
+    {
+        if(ddr_speed_bin > DDR3_DEFAULT)
+        {
+            ret = -1;
+            goto out;
+        }
+
+        #define DDR3_tREFI_7_8_us    (78)
+        #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_speed_bin][tmp] >> 16;
+        cwl = ddr3_cl_cwl[ddr_speed_bin][tmp] & 0x0ff;
+        if(cl == 0)
+        {
+            ret = -4; //³¬¹ý¿ÅÁ£µÄ×î´óƵÂÊ
+        }
+        if(nMHz <= DDR3_DDR2_ODT_DISABLE_FREQ)     
+        {
+            ddr_reg.ddrMR[1] = DDR3_DS_40 | DDR3_Rtt_Nom_DIS;
+        }
+        else
+        {
+            ddr_reg.ddrMR[1] = DDR3_DS_40 | DDR3_Rtt_Nom_120;
+        }
+        ddr_reg.ddrMR[2] = DDR3_MR2_CWL(cwl) /* | DDR3_Rtt_WR_60 */;
+        ddr_reg.ddrMR[3] = 0;
+        /**************************************************
+         * PCTL Timing
+         **************************************************/
+        /*
+         * tREFI, average periodic refresh interval, 7.8us
+         */
+        p_pctl_timing->trefi = DDR3_tREFI_7_8_us;
+        /*
+         * tMRD, 4 tCK
+         */
+        p_pctl_timing->tmrd = DDR3_tMRD & 0x7;
+        /*
+         * tRFC, 90ns(512Mb),110ns(1Gb),160ns(2Gb),300ns(4Gb),350ns(8Gb)
+         */
+        if(ddr_capability_per_die <= 0x4000000)         // 512Mb 90ns
+        {
+            tmp = DDR3_tRFC_512Mb;
+        }
+        else if(ddr_capability_per_die <= 0x8000000)    // 1Gb 110ns
+        {
+            tmp = DDR3_tRFC_1Gb;
+        }
+        else if(ddr_capability_per_die <= 0x10000000)   // 2Gb 160ns
+        {
+            tmp = DDR3_tRFC_2Gb;
+        }
+        else if(ddr_capability_per_die <= 0x20000000)   // 4Gb 300ns
+        {
+            tmp = DDR3_tRFC_4Gb;
+        }
+        else    // 8Gb  350ns
+        {
+            tmp = DDR3_tRFC_8Gb;
+        }
+        p_pctl_timing->trfc = (tmp*nMHz+999)/1000;
+        /*
+         * tXSR, =tDLLK=512 tCK
+         */
+        p_pctl_timing->texsr = DDR3_tDLLK;
+        /*
+         * tRP=CL
+         */
+        p_pctl_timing->trp = cl;
+        /*
+         * WrToMiss=WL*tCK + tWR + tRP + tRCD
+         */
+        p_noc_timing->b.WrToMiss = ((cwl+((DDR3_tWR*nMHz+999)/1000)+cl+cl)&0x3F);
+        /*
+         * tRC=tRAS+tRP
+         */
+        p_pctl_timing->trc = ((((ddr3_tRC_tFAW[ddr_speed_bin]>>16)*nMHz+999)/1000)&0x3F);
+        p_noc_timing->b.ActToAct = ((((ddr3_tRC_tFAW[ddr_speed_bin]>>16)*nMHz+999)/1000)&0x3F);
+
+        p_pctl_timing->trtw = (cl+2-cwl);//DDR3_tRTW;
+        p_noc_timing->b.RdToWr = ((cl+2-cwl)&0x1F);
+        p_pctl_timing->tal = al;
+        p_pctl_timing->tcl = cl;
+        p_pctl_timing->tcwl = cwl;
+        /*
+         * tRAS, 37.5ns(400MHz)     37.5ns(533MHz)
+         */
+        p_pctl_timing->tras = (((DDR3_tRAS*nMHz+(nMHz>>1)+999)/1000)&0x3F);
+        /*
+         * tRCD=CL
+         */
+        p_pctl_timing->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_pctl_timing->trrd = (tmp&0xF);
+        /*
+         * tRTP, max(4 tCK,7.5ns)
+         */
+        tmp = ((DDR3_tRTP*nMHz+(nMHz>>1)+999)/1000);
+        if(tmp < 4)
+        {
+            tmp = 4;
+        }
+        p_pctl_timing->trtp = tmp&0xF;
+        /*
+         * RdToMiss=tRTP+tRP + tRCD - (BL/2 * tCK)
+         */
+        p_noc_timing->b.RdToMiss = ((tmp+cl+cl-(bl>>1))&0x3F);
+        /*
+         * tWR, 15ns
+         */
+        tmp = ((DDR3_tWR*nMHz+999)/1000);
+        p_pctl_timing->twr = tmp&0x1F;
+        if(tmp<9)
+            tmp = tmp - 4;
+        else
+            tmp = tmp>>1;
+        ddr_reg.ddrMR[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_pctl_timing->twtr = tmp&0xF;
+        p_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_pctl_timing->txp = tmp&0x7;
+        /*
+         * tXPDLL, max(10 tCK,24ns)
+         */
+        tmp = ((DDR3_tXPDLL*nMHz+999)/1000);
+        if(tmp < 10)
+        {
+            tmp = 10;
+        }
+        p_pctl_timing->txpdll = tmp & 0x3F;
+        /*
+         * tZQCS, max(64 tCK, 80ns)
+         */
+        tmp = ((DDR3_tZQCS*nMHz+999)/1000);
+        if(tmp < 64)
+        {
+            tmp = 64;
+        }
+        p_pctl_timing->tzqcs = tmp&0x7F;
+        /*
+         * tZQCSI,
+         */
+        p_pctl_timing->tzqcsi = DDR3_tZQCSI;
+        /*
+         * tDQS,
+         */
+        p_pctl_timing->tdqs = DDR3_tDQS;
+        /*
+         * tCKSRE, max(5 tCK, 10ns)
+         */
+        tmp = ((DDR3_tCKSRE*nMHz+999)/1000);
+        if(tmp < 5)
+        {
+            tmp = 5;
+        }
+        p_pctl_timing->tcksre = tmp & 0x1F;
+        /*
+         * tCKSRX, max(5 tCK, 10ns)
+         */
+        p_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_pctl_timing->tcke = tmp & 0x7;
+        /*
+         * tCKESR, =tCKE + 1tCK
+         */
+        p_pctl_timing->tckesr = (tmp+1)&0xF;
+        /*
+         * tMOD, max(12 tCK,15ns)
+         */
+        tmp = ((DDR3_tMOD*nMHz+999)/1000);
+        if(tmp < 12)
+        {
+            tmp = 12;
+        }
+        p_pctl_timing->tmod = tmp&0x1F;
+        /*
+         * tRSTL, 100ns
+         */
+        p_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_pctl_timing->tzqcl = tmp&0x3FF;
+        /*
+         * tMRR, 0 tCK
+         */
+        p_pctl_timing->tmrr = 0;
+        /*
+         * tDPD, 0
+         */
+        p_pctl_timing->tdpd = 0;
+
+        /**************************************************
+         * NOC Timing
+         **************************************************/
+        p_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;
+        if(nMHz <= DDR3_DDR2_ODT_DISABLE_FREQ)
+        {
+            ddr_reg.ddrMR[1] = DDR2_STR_REDUCE | DDR2_Rtt_Nom_DIS;
+        }
+        else
+        {
+            ddr_reg.ddrMR[1] = DDR2_STR_REDUCE | DDR2_Rtt_Nom_75;
+        }
+        ddr_reg.ddrMR[2] = 0;
+        ddr_reg.ddrMR[3] = 0;
+        /**************************************************
+         * PCTL Timing
+         **************************************************/
+        /*
+         * tREFI, average periodic refresh interval, 7.8us
+         */
+        p_pctl_timing->trefi = DDR2_tREFI_7_8_us;
+        /*
+         * tMRD, 2 tCK
+         */
+        p_pctl_timing->tmrd = DDR2_tMRD & 0x7;
+        /*
+         * tRFC, 75ns(256Mb) 105ns(512Mb) 127.5ns(1Gb) 195ns(2Gb) 327.5ns(4Gb)
+         */
+        if(ddr_capability_per_die <= 0x2000000)  // 256Mb
+        {
+            tmp = DDR2_tRFC_256Mb;
+        }
+        else if(ddr_capability_per_die <= 0x4000000) // 512Mb
+        {
+            tmp = DDR2_tRFC_512Mb;
+        }
+        else if(ddr_capability_per_die <= 0x8000000)  // 1Gb
+        {
+            tmp = DDR2_tRFC_1Gb;
+        }
+        else if(ddr_capability_per_die <= 0x10000000)  // 2Gb
+        {
+            tmp = DDR2_tRFC_2Gb;
+        }
+        else  // 4Gb
+        {
+            tmp = DDR2_tRFC_4Gb;
+        }
+        p_pctl_timing->trfc = (tmp*nMHz+999)/1000;
+        /*
+         * tXSR, max(tRFC+10,200 tCK)
+         */
+        tmp = (((tmp+10)*nMHz+999)/1000);
+        if(tmp<200)
+        {
+            tmp = 200;
+        }
+        p_pctl_timing->texsr = tmp&0x3FF;
+        /*
+         * tRP=CL  DDR2 8bank need to add 1 additional cycles for PREA
+         */
+        if(ddr_get_bank() == 8)
+        {
+            p_pctl_timing->trp = (1<<16) | cl;
+        }
+        else
+        {
+            p_pctl_timing->trp = cl;
+        }
+        /*
+         * WrToMiss=WL*tCK + tWR + tRP + tRCD
+         */
+        p_noc_timing->b.WrToMiss = ((cwl+((DDR2_tWR*nMHz+999)/1000)+cl+cl)&0x3F);
+        /*
+         * tRAS, 45ns
+         */
+        tmp=((DDR2_tRAS*nMHz+999)/1000);
+        p_pctl_timing->tras = (tmp&0x3F);
+        /*
+         * tRC=tRAS+tRP
+         */
+        p_pctl_timing->trc = ((tmp+cl)&0x3F);
+        p_noc_timing->b.ActToAct = ((tmp+cl)&0x3F);
+
+        p_pctl_timing->trtw = (cl+2-cwl);//DDR2_tRTW;
+        p_noc_timing->b.RdToWr = ((cl+2-cwl)&0x1F);
+        p_pctl_timing->tal = al;
+        p_pctl_timing->tcl = cl;
+        p_pctl_timing->tcwl = cwl;
+        /*
+         * tRCD=CL
+         */
+        p_pctl_timing->trcd = cl;
+        /*
+         * tRRD = 10ns(2KB page)
+         *
+         */
+        p_pctl_timing->trrd = (((DDR2_tRRD*nMHz+999)/1000)&0xF);
+        /*
+         * tRTP, 7.5ns
+         */
+        tmp = ((DDR2_tRTP*nMHz+(nMHz>>1)+999)/1000);
+        p_pctl_timing->trtp = tmp&0xF;
+        /*
+         * RdToMiss=tRTP+tRP + tRCD - (BL/2 * tCK)
+         */
+        p_noc_timing->b.RdToMiss = ((tmp+cl+cl-(bl>>1))&0x3F);
+        /*
+         * tWR, 15ns
+         */
+        tmp = ((DDR2_tWR*nMHz+999)/1000);
+        p_pctl_timing->twr = tmp&0x1F;
+        /*
+         * 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_pctl_timing->twtr = tmp&0xF;
+        p_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_pctl_timing->txp = tmp&0x7;
+        /*
+         * tXPDLL, =tXP
+         */
+        p_pctl_timing->txpdll = tmp & 0x3F;
+        /*
+         * tZQCS, 0
+         */
+        p_pctl_timing->tzqcs = 0;
+        /*
+         * tZQCSI,
+         */
+        p_pctl_timing->tzqcsi = 0;
+        /*
+         * tDQS,
+         */
+        p_pctl_timing->tdqs = DDR2_tDQS;
+        /*
+         * tCKSRE, 1 tCK
+         */
+        p_pctl_timing->tcksre = DDR2_tCKSRE & 0x1F;
+        /*
+         * tCKSRX, no such timing
+         */
+        p_pctl_timing->tcksrx = DDR2_tCKSRX & 0x1F;
+        /*
+         * tCKE, 3 tCK
+         */
+        p_pctl_timing->tcke = DDR2_tCKE & 0x7;
+        /*
+         * tCKESR, =tCKE
+         */
+        p_pctl_timing->tckesr = DDR2_tCKESR&0xF;
+        /*
+         * tMOD, 12ns
+         */
+        p_pctl_timing->tmod = ((DDR2_tMOD*nMHz+999)/1000)&0x1F;
+        /*
+         * tRSTL, 0
+         */
+        p_pctl_timing->trstl = 0;
+        /*
+         * tZQCL, 0
+         */
+        p_pctl_timing->tzqcl = 0;
+        /*
+         * tMRR, 0 tCK
+         */
+        p_pctl_timing->tmrr = 0;
+        /*
+         * tDPD, 0
+         */
+        p_pctl_timing->tdpd = 0;
+
+        /**************************************************
+         * NOC Timing
+         **************************************************/
+        p_noc_timing->b.BurstLen = ((bl>>1)&0x7);
+    }
+    
+out:
+    return ret;
+}
+
+/*----------------------------------------------------------------------
+Name    : uint32_t __sramlocalfunc ddr_update_timing(void)
+Desc    : ¸üÐÂpctl phy Ïà¹Øtiming¼Ä´æÆ÷
+Params  : void  
+Return  : 0 ³É¹¦
+Notes   : 
+----------------------------------------------------------------------*/
+uint32_t __sramlocalfunc ddr_update_timing(void)
+{
+    PCTL_TIMING_T *p_pctl_timing = &(ddr_reg.pctl.pctl_timing);
+    NOC_TIMING_T  *p_noc_timing = &(ddr_reg.noc_timing);
+
+    ddr_copy((uint32_t *)&(pDDR_Reg->TOGCNT1U), (uint32_t*)&(p_pctl_timing->togcnt1u), 34);
+    pPHY_Reg->PHY_REG3 = (0x12 << 1) | (ddr2_ddr3_bl_8);   //0x12Ϊ±£ÁôλµÄĬÈÏÖµ£¬ÒÔĬÈÏÖµ»Øд
+    pPHY_Reg->PHY_REG4a = ((p_pctl_timing->tcl << 4) | (p_pctl_timing->tal));
+    *(volatile uint32_t *)SysSrv_DdrTiming = p_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->TAL + pDDR_Reg->TCL)-3;  //trdata_en = rl-3
+        pDDR_Reg->DFITPHYWRLAT   = pDDR_Reg->TCWL-1;
+    }
+    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);
+    }
+    return 0;
+}
+
+/*----------------------------------------------------------------------
+Name    : uint32_t __sramlocalfunc ddr_update_mr(void)
+Desc    : ¸üпÅÁ£MR¼Ä´æÆ÷
+Params  : void  
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+uint32_t __sramlocalfunc ddr_update_mr(void)
+{
+    uint32_t cs;
+
+    cs = (pGRF_Reg->GRF_OS_REG[1] >> DDR_RANK_COUNT) & 0x1;
+    cs = cs + (1 << cs);                               //case 0:1rank cs=1; case 1:2rank cs =3;
+    if(ddr_freq > DDR3_DDR2_DLL_DISABLE_FREQ)
+    {
+        if(ddr_dll_status == DDR3_DLL_DISABLE)  // off -> on
+        {
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(ddr_reg.ddrMR[1])));  //DLL enable
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr(((uint8_t)(ddr_reg.ddrMR[0]))| DDR3_DLL_RESET));  //DLL reset
+            ddr_delayus(2);  //at least 200 DDR cycle
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(ddr_reg.ddrMR[0])));
+            ddr_dll_status = DDR3_DLL_ENABLE;
+        }
+        else // on -> on
+        {
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(ddr_reg.ddrMR[1])));
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(ddr_reg.ddrMR[0])));
+        }
+    }
+    else
+    {
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((uint8_t)(ddr_reg.ddrMR[1])) | DDR3_DLL_DISABLE));  //DLL disable
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(ddr_reg.ddrMR[0])));
+        ddr_dll_status = DDR3_DLL_DISABLE;
+    }
+    ddr_send_command(cs, MRS_cmd, bank_addr(0x2) | cmd_addr((uint8_t)(ddr_reg.ddrMR[2])));
+
+    return 0;
+}
+
+/*----------------------------------------------------------------------
+Name    : void __sramlocalfunc ddr_update_odt(void)
+Desc    : update PHY odt & PHY driver impedance
+Params  : void  
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+void __sramlocalfunc ddr_update_odt(void)
+{
+    uint32_t tmp;
+    
+    //adjust DRV and ODT
+    if(ddr_freq <= DDR3_DDR2_ODT_DISABLE_FREQ)
+    {
+        pPHY_Reg->PHY_REG27 = PHY_RTT_DISABLE;  //dynamic RTT disable, Left 8bit ODT
+        pPHY_Reg->PHY_REG28 = PHY_RTT_DISABLE;  //Right 8bit ODT
+    }
+    else
+    {
+        pPHY_Reg->PHY_REG27 = ((PHY_RTT_212O<<3) | PHY_RTT_212O);       //0x5 ODT =  71ohm
+        pPHY_Reg->PHY_REG28 = ((PHY_RTT_212O<<3) | PHY_RTT_212O);       
+    }
+    
+    tmp = ((PHY_RON_46O<<3) | PHY_RON_46O);     //0x5 = 46ohm
+    pPHY_Reg->PHY_REG16 = tmp;  //CMD driver strength
+    pPHY_Reg->PHY_REG22 = tmp;  //CK driver strength    
+    pPHY_Reg->PHY_REG25 = tmp;  //Left 8bit DQ driver strength
+    pPHY_Reg->PHY_REG26 = tmp;  //Right 8bit DQ driver strength
+}
+
+/*----------------------------------------------------------------------
+Name    : __sramfunc void ddr_adjust_config(uint32_t dram_type)
+Desc    : 
+Params  : dram_type ->¿ÅÁ£ÀàÐÍ
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+__sramfunc void ddr_adjust_config(uint32_t dram_type)
+{
+//    uint32 value;
+    unsigned long save_sp;
+    uint32 i;
+    volatile uint32 n; 
+    volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
+
+    //get data training address before idle port
+//    value = ddr_get_datatraing_addr();    //Inno PHY ²»ÐèÒªtraining address
+
+    /** 1. Make sure there is no host access */
+    flush_cache_all();
+    outer_flush_all();
+    flush_tlb_all();
+    DDR_SAVE_SP(save_sp);
+
+    for(i=0;i<8;i++)        //8KB SRAM
+    {
+        n=temp[1024*i];
+        barrier();
+    }
+    n= pDDR_Reg->SCFG.d32;
+    n= pPHY_Reg->PHY_REG1;
+    n= pCRU_Reg->CRU_PLL_CON[0][0];
+    n= *(volatile uint32_t *)SysSrv_DdrConf;
+    dsb();
+    
+    //enter config state
+    ddr_move_to_Config_state();
+
+    //set auto power down idle
+    pDDR_Reg->MCFG=(pDDR_Reg->MCFG&0xffff00ff)|(PD_IDLE<<8);
+
+    //enable the hardware low-power interface
+    pDDR_Reg->SCFG.b.hw_low_power_en = 1;
+
+    ddr_update_odt();
+
+    //enter access state
+    ddr_move_to_Access_state();
+
+    DDR_RESTORE_SP(save_sp);
+}
+
+/*----------------------------------------------------------------------
+Name    : void __sramlocalfunc ddr_selfrefresh_enter(uint32 nMHz)
+Desc    : ½øÈë×ÔË¢ÐÂ
+Params  : nMHz ->ddrƵÂÊ
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+void __sramlocalfunc ddr_selfrefresh_enter(uint32 nMHz)
+{
+    uint32 ddrMR1 = ddr_reg.ddrMR[1];
+    uint32 cs;
+
+    ddr_move_to_Config_state();
+    pDDR_Reg->TZQCSI = 0;
+    if((nMHz<=DDR3_DDR2_DLL_DISABLE_FREQ) && ((mem_type == DDR3) || (mem_type == DDR2)))  // DLL disable
+    {
+        cs = (pGRF_Reg->GRF_OS_REG[1] >> DDR_RANK_COUNT) & 0x1;            //get rank num
+        cs = cs + (1 << cs);                                //case 0:1rank cs=1; case 1:2rank cs =3;
+        ddr_dll_status =  DDR3_DLL_DISABLE;
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((uint8_t)ddrMR1) | DDR3_DLL_DISABLE));
+    }
+    ddr_move_to_Lowpower_state();
+       pPHY_Reg->PHY_REG264 &= ~(1<<1);
+    pPHY_Reg->PHY_REG1 = (pPHY_Reg->PHY_REG1 & (~(0x3<<2)));     //phy soft reset
+    dsb();
+    ddr_set_dll_bypass(0);  //phy dll bypass
+    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (1<<2);  //disable DDR PHY clock
+    ddr_delayus(1);
+}
+
+/*----------------------------------------------------------------------
+Name    : void __sramlocalfunc ddr_selfrefresh_exit(void)
+Desc    : Í˳ö×ÔË¢ÐÂ
+Params  : void
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+void __sramlocalfunc ddr_selfrefresh_exit(void)
+{
+    uint32 i;
+    volatile uint32* p;    
+    pCRU_Reg->CRU_CLKGATE_CON[0] = ((0x1<<2)<<16) | (0<<2);  //enable DDR PHY clock
+    dsb();
+    ddr_delayus(1);
+    ddr_set_dll_bypass(ddr_freq);    //set phy dll mode;
+       pPHY_Reg->PHY_REG1 = (pPHY_Reg->PHY_REG1 | (0x3 << 2)); //phy soft de-reset
+       pPHY_Reg->PHY_REG264 |= (1<<1);
+       dsb();
+    ddr_move_to_Config_state();    
+    ddr_update_timing();
+    ddr_update_mr();  
+    ddr_update_odt();    
+    ddr_data_training();   
+    ddr_move_to_Access_state();
+    p = phys_to_virt(0x60000000);
+    for(i=0;i<8;i++)
+    {
+        p[i] = copy_data[i];
+    }
+    for(i=0;i<8;i++)
+    {
+        if(p[i] != copy_data[i])
+        {
+            sram_printascii("DTT failed!\n");
+            break;
+        }
+        p[i] = 0;
+    }
+}
+
+/*----------------------------------------------------------------------
+Name    : uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
+Desc    : ddr±äƵ
+Params  : nMHz -> ±äƵµÄƵÂÊÖµ
+Return  : ÆµÂÊÖµ
+Notes   :
+----------------------------------------------------------------------*/
+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;
+    uint32_t regvalue0 = pCRU_Reg->CRU_PLL_CON[0][0];
+    uint32_t regvalue1 = pCRU_Reg->CRU_PLL_CON[0][1];
+    uint32_t freq;
+       
+     // freq = (fin*fbdiv/(refdiv * postdiv1 * postdiv2))
+     if((pCRU_Reg->CRU_MODE_CON & 1) == 1)             // CPLL Normal mode
+     {
+         freq = 24*(regvalue0&0xfff)     
+                /((regvalue1&0x3f)*((regvalue0>>12)&0x3)*((regvalue1>>6)&0x3));                  
+     }  
+     else
+     {
+        freq = 24;
+     }     
+    loops_per_us = LPJ_100MHZ*freq / 1000000;
+    
+    ret=ddr_set_pll(nMHz,0);
+    ddr_get_parameter(ret);
+
+    /** 1. Make sure there is no host access */
+    local_irq_save(flags);
+       local_fiq_disable();
+    flush_cache_all();
+       outer_flush_all();
+       flush_tlb_all();
+       DDR_SAVE_SP(save_sp);
+       for(i=0;i<8;i++)    //8KB SRAM
+       {
+           n=temp[1024*i];
+        barrier();
+       }
+    n= pDDR_Reg->SCFG.d32;
+    n= pPHY_Reg->PHY_REG1;
+    n= pCRU_Reg->CRU_PLL_CON[0][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(ret);
+
+    /** 3. change frequence  */
+    ddr_set_pll(ret,1);
+    ddr_freq = ret;
+    
+    /** 5. Issues a Mode Exit command   */
+    ddr_selfrefresh_exit();
+
+       dsb();
+    DDR_RESTORE_SP(save_sp);
+    local_fiq_enable();
+    local_irq_restore(flags);
+    clk_set_rate(clk_get(NULL, "ddr_pll"), 0);
+    return ret;
+}
+
+EXPORT_SYMBOL(ddr_change_freq);
+
+/*----------------------------------------------------------------------
+Name    : void ddr_set_auto_self_refresh(bool en)
+Desc    : ÉèÖýøÈë selfrefesh µÄÖÜÆÚÊý
+Params  : en -> Ê¹ÄÜauto selfrefresh
+Return  : ÆµÂÊÖµ
+Notes   : ÖÜÆÚÊýΪ1*32 cycle  
+----------------------------------------------------------------------*/
+void ddr_set_auto_self_refresh(bool en)
+{
+    //set auto self-refresh idle
+    ddr_sr_idle = en ? SR_IDLE : 0;
+}
+EXPORT_SYMBOL(ddr_set_auto_self_refresh);
+
+/*----------------------------------------------------------------------
+Name    : void __sramfunc ddr_suspend(void)
+Desc    : ½øÈëddr suspend
+Params  : void
+Return  : void
+Notes   :  
+----------------------------------------------------------------------*/
+void __sramfunc ddr_suspend(void)
+{
+    u32 i;
+    volatile u32 n;    
+    volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;  
+    /** 1. Make sure there is no host access */
+    flush_cache_all();
+    outer_flush_all();
+    flush_tlb_all();
+
+    for(i=0;i<8;i++)  //sram size = 8KB
+    {
+        n=temp[1024*i];
+        barrier();
+    }
+    n= pDDR_Reg->SCFG.d32;
+    n= pPHY_Reg->PHY_REG1;
+    n= pCRU_Reg->CRU_PLL_CON[0][0];
+    n= *(volatile uint32_t *)SysSrv_DdrConf;
+    dsb();
+//    sram_printch('b');
+    ddr_selfrefresh_enter(0);
+    pCRU_Reg->CRU_MODE_CON = (0x1<<((1*4) +  16)) | (0x0<<(1*4));   //PLL slow-mode
+    dsb();
+    ddr_delayus(1);    
+    pCRU_Reg->CRU_PLL_CON[1][1] = ((0x1<<13)<<16) | (0x1<<13);         //PLL power-down
+    dsb();
+    ddr_delayus(1);    
+    
+}
+EXPORT_SYMBOL(ddr_suspend);
+
+/*----------------------------------------------------------------------
+Name    : void __sramfunc ddr_resume(void)
+Desc    : ddr resume
+Params  : void
+Return  : void
+Notes   : 
+----------------------------------------------------------------------*/
+void __sramfunc ddr_resume(void)
+{
+    int delay=1000;
+    
+    pCRU_Reg->CRU_PLL_CON[1][1] = ((0x1<<13)<<16) | (0x0<<13);         //PLL no power-down
+    dsb();
+    while (delay > 0) 
+    {
+           ddr_delayus(1);
+               if (pCRU_Reg->CRU_PLL_CON[1][1] & (0x1<<10))
+                       break;
+               delay--;
+       }
+    
+    pCRU_Reg->CRU_MODE_CON = (0x1<<((1*4) +  16))  | (0x1<<(1*4));   //PLL normal
+    dsb();
+
+    ddr_selfrefresh_exit();
+}
+EXPORT_SYMBOL(ddr_resume);
+
+/*----------------------------------------------------------------------
+Name    : uint32 ddr_get_cap(void)
+Desc    : »ñÈ¡ÈÝÁ¿£¬·µ»Ø×Ö½ÚÊý
+Params  : void
+Return  : ¿ÅÁ£ÈÝÁ¿
+Notes   :  
+----------------------------------------------------------------------*/
+uint32 ddr_get_cap(void)
+{
+    uint32 value;
+    uint32 cs, bank, row, col;
+    value = pGRF_Reg->GRF_OS_REG[1];
+    bank = (((value >> DDR_BANK_COUNT) & 0x1)? 2:3);
+    row = (13+((value >> DDR_ROW_COUNT) & 0x3));
+    col = (9 + ((value >> DDR_COL_COUNT)&0x3));
+    cs = (1 + ((value >> DDR_RANK_COUNT)&0x1)); 
+    return ((1 << (row + col + bank + 1))*cs);
+}
+EXPORT_SYMBOL(ddr_get_cap);
+
+/*----------------------------------------------------------------------
+Name    : void ddr_reg_save(void)
+Desc    : ±£´æ¿ØÖÆÆ÷¼Ä´æÆ÷Öµ
+Params  : void
+Return  : void
+Notes   :  
+----------------------------------------------------------------------*/
+void ddr_reg_save(void)
+{
+    //PCTLR
+    ddr_reg.pctl.SCFG = pDDR_Reg->SCFG.d32;
+    ddr_reg.pctl.CMDTSTATEN = pDDR_Reg->CMDTSTATEN;
+    ddr_reg.pctl.MCFG1 = pDDR_Reg->MCFG1;
+    ddr_reg.pctl.MCFG = pDDR_Reg->MCFG;
+    ddr_reg.pctl.pctl_timing.ddrFreq = ddr_freq;
+    ddr_reg.pctl.DFITCTRLDELAY = pDDR_Reg->DFITCTRLDELAY;
+    ddr_reg.pctl.DFIODTCFG = pDDR_Reg->DFIODTCFG;
+    ddr_reg.pctl.DFIODTCFG1 = pDDR_Reg->DFIODTCFG1;
+    ddr_reg.pctl.DFIODTRANKMAP = pDDR_Reg->DFIODTRANKMAP;
+    ddr_reg.pctl.DFITPHYWRDATA = pDDR_Reg->DFITPHYWRDATA;
+    ddr_reg.pctl.DFITPHYWRLAT = pDDR_Reg->DFITPHYWRLAT;
+    ddr_reg.pctl.DFITRDDATAEN = pDDR_Reg->DFITRDDATAEN;
+    ddr_reg.pctl.DFITPHYRDLAT = pDDR_Reg->DFITPHYRDLAT;
+    ddr_reg.pctl.DFITPHYUPDTYPE0 = pDDR_Reg->DFITPHYUPDTYPE0;
+    ddr_reg.pctl.DFITPHYUPDTYPE1 = pDDR_Reg->DFITPHYUPDTYPE1;
+    ddr_reg.pctl.DFITPHYUPDTYPE2 = pDDR_Reg->DFITPHYUPDTYPE2;
+    ddr_reg.pctl.DFITPHYUPDTYPE3 = pDDR_Reg->DFITPHYUPDTYPE3;
+    ddr_reg.pctl.DFITCTRLUPDMIN = pDDR_Reg->DFITCTRLUPDMIN;
+    ddr_reg.pctl.DFITCTRLUPDMAX = pDDR_Reg->DFITCTRLUPDMAX;
+    ddr_reg.pctl.DFITCTRLUPDDLY = pDDR_Reg->DFITCTRLUPDDLY;
+    
+    ddr_reg.pctl.DFIUPDCFG = pDDR_Reg->DFIUPDCFG;
+    ddr_reg.pctl.DFITREFMSKI = pDDR_Reg->DFITREFMSKI;
+    ddr_reg.pctl.DFITCTRLUPDI = pDDR_Reg->DFITCTRLUPDI;
+    ddr_reg.pctl.DFISTCFG0 = pDDR_Reg->DFISTCFG0;
+    ddr_reg.pctl.DFISTCFG1 = pDDR_Reg->DFISTCFG1;
+    ddr_reg.pctl.DFITDRAMCLKEN = pDDR_Reg->DFITDRAMCLKEN;
+    ddr_reg.pctl.DFITDRAMCLKDIS = pDDR_Reg->DFITDRAMCLKDIS;
+    ddr_reg.pctl.DFISTCFG2 = pDDR_Reg->DFISTCFG2;
+    ddr_reg.pctl.DFILPCFG0 = pDDR_Reg->DFILPCFG0;
+
+    //NOC
+    ddr_reg.DdrConf = *(volatile uint32_t *)SysSrv_DdrConf;
+    ddr_reg.DdrMode = *(volatile uint32_t *)SysSrv_DdrMode;
+    ddr_reg.ReadLatency = *(volatile uint32_t *)SysSrv_ReadLatency;
+}
+EXPORT_SYMBOL(ddr_reg_save);
+/*
+__attribute__((aligned(4))) __sramdata uint32 ddr_reg_resume[] = 
+{
+#include "ddr_reg_resume.inc"
+};
+*/
+
+
+
+/*----------------------------------------------------------------------
+Name    : int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
+Desc    : ddr  ³õʼ»¯º¯Êý
+Params  : dram_speed_bin ->ddr¿ÅÁ£ÀàÐÍ
+          freq ->ƵÂÊÖµ
+Return  : 0 ³É¹¦
+Notes   :  
+----------------------------------------------------------------------*/
+int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
+{
+    volatile uint32_t value = 0;
+    uint32_t cs,die=1;
+    uint32_t calStatusLeft, calStatusRight;
+
+    ddr_print("version 1.00 20120803 \n");
+    cs = (1 << (((pGRF_Reg->GRF_OS_REG[1]) >> DDR_RANK_COUNT)&0x1));    //case 0:1rank ; case 1:2rank ;                            
+    mem_type = ((pGRF_Reg->GRF_OS_REG[1] >> 13) &0x7);
+    ddr_speed_bin = dram_speed_bin;
+    ddr_freq = freq;
+    ddr_sr_idle = 0;
+    ddr_dll_status = DDR3_DLL_DISABLE;
+
+    switch(mem_type)
+    {
+        case DDR3:
+            die = 1;
+            break;
+               case DDR2:
+                       die = 1;
+                       break;
+        default:
+            ddr_print("ddr type error type=%d\n",mem_type);
+            break;
+    }
+       
+    
+    //get capability per chip, not total size, used for calculate tRFC
+    ddr_capability_per_die = ddr_get_cap()/(cs * die);
+    ddr_print("%d CS, ROW=%d, Bank=%d, COL=%d, Total Capability=%dMB\n", 
+                                                                    cs, \
+                                                                    ddr_get_row(), \
+                                                                    (0x1<<(ddr_get_bank())), \
+                                                                    ddr_get_col(), \
+                                                                    (ddr_get_cap()>>20));
+    ddr_adjust_config(mem_type);
+
+    value=ddr_change_freq(freq);
+    ddr_print("init success!!! freq=%dMHz\n", value);
+
+    calStatusLeft = pPHY_Reg->PHY_REG60;
+    calStatusRight = pPHY_Reg->PHY_REG61;
+
+
+    ddr_print("left channel:Dllsel=%x, Ophsel=%x, Cycsel=%x\n",\
+                                    (calStatusRight >> 5) & 0x07,\
+                                    (calStatusRight >> 3) & 0x03,\
+                                    calStatusRight  & 0x07);
+    ddr_print("right channel:Dllsel=%x, Ophsel=%x, Cycsel=%x\n",\
+                                    (calStatusLeft >> 5) & 0x07,\
+                                    (calStatusLeft >> 3) & 0x03,\
+                                    calStatusLeft  & 0x07);                                                        
+    
+    ddr_print("DRV Pull-Up=0x%x, DRV Pull-Dwn=0x%x\n", (pPHY_Reg->PHY_REG25>>3)&0x7, pPHY_Reg->PHY_REG25&0x7);
+    ddr_print("ODT Pull-Up=0x%x, ODT Pull-Dwn=0x%x\n", (pPHY_Reg->PHY_REG27>>3)&0x7, pPHY_Reg->PHY_REG27&0x7);         
+
+    return 0;
+}
+
+EXPORT_SYMBOL(ddr_init);
+
diff --git a/arch/arm/mach-rk2928/include/mach/ddr.h b/arch/arm/mach-rk2928/include/mach/ddr.h
new file mode 100755 (executable)
index 0000000..fd733fc
--- /dev/null
@@ -0,0 +1,155 @@
+/* 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 360
+#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);
+void ddr_set_auto_self_refresh(bool en);
+uint32_t __sramlocalfunc ddr_set_pll(uint32_t nMHz, uint32_t set);
+
+
+#endif