ddr3 function support
authoryangkai <yangkai@ubuntu-fs>
Wed, 16 Mar 2011 13:20:01 +0000 (21:20 +0800)
committeryangkai <yangkai@ubuntu-fs>
Wed, 16 Mar 2011 13:20:01 +0000 (21:20 +0800)
arch/arm/mach-rk29/ddr.c [changed mode: 0644->0755]
arch/arm/mach-rk29/pm.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 93961ea..89a9fd4
-/****************************************************************\r
-*      CopyRight(C) 2010 by Rock-Chip Fuzhou\r
-*     All Rights Reserved\r
-*      File name       :ddr.c\r
-*      Description: ddr driver implement\r
-*      Author :hcy\r
-*      Create date :2011-01-04\r
-*      Change log:\r
-*      Current version:1.00   20110104 hcy \r
-****************************************************************/\r
-\r
-#include <linux/init.h>\r
-#include <linux/kernel.h>\r
-#include <linux/irqflags.h>\r
-#include <linux/string.h>\r
-#include <linux/version.h>\r
-#include <linux/compiler.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/time.h>\r
-#include <linux/hrtimer.h>\r
-#include <linux/earlysuspend.h>\r
-\r
-#include <mach/rk29_iomap.h>\r
-#include <mach/memory.h>\r
-#include <mach/sram.h>\r
-#include <linux/clk.h>\r
-\r
-#include <asm/delay.h>\r
-#include <asm/tlbflush.h>\r
-#include <asm/cacheflush.h>\r
-\r
-\r
-#include <asm/io.h>\r
-\r
-// save_sp  must be static global variable  \r
-\r
-static unsigned long save_sp;\r
-\r
-\r
-//CCR;                    //Controller Configuration Register                            \r
-#define ECCEN                                  (1)\r
-#define NOMRWR                                 (1<<1)\r
-#define HOSTEN                                 (1<<2)\r
-#define RRB                                            (1<<13)\r
-#define DQSCFG                                 (1<<14)\r
-#define DFTLM_NO                        (0<<15)\r
-#define DFTLM_90                        (1<<15)\r
-#define DFTLM_180                       (2<<15)\r
-#define DFTLM_270                       (3<<15)\r
-#define DFTCMP                                 (1<<17)\r
-#define FLUSH                                  (1<<27)\r
-#define ITMRST                                 (1<<28)\r
-#define IB                                             (1<<29)\r
-#define DTT                                            (1<<30)\r
-#define IT                                             (1<<31)\r
-//DCR;                    //DRAM Configuration Register                                  \r
-#define DDRII                                          (0)\r
-#define DDR3                                           (1)\r
-#define Mobile_DDR                             (2)\r
-                                        \r
-#define DIO_8                                  (1<<2)\r
-#define DIO_16                                 (2<<2)\r
-#define DIO_32                                 (3<<2)\r
-                                        \r
-#define DSIZE_64Mb                             (0<<4)\r
-#define DSIZE_128Mb                            (1<<4)\r
-#define DSIZE_256Mb                            (2<<4)\r
-#define DSIZE_512Mb                            (3<<4)\r
-#define DSIZE_1Gb                              (4<<4)\r
-#define DSIZE_2Gb                              (5<<4)\r
-#define DSIZE_4Gb                              (6<<4)\r
-#define DSIZE_8Gb                              (7<<4)\r
-                                        \r
-#define SIO(n)                          (((n)-1)<<7)\r
-#define PIO                                            (1<<10)\r
-#define RANKS(n)                        ((((n)-1)&0x3)<<11)\r
-#define RNKALL                                 (1<<13)\r
-                                        \r
-#define AMAP_RBRC                              (0<<14)  //rank,bank,row,column\r
-#define AMAP_RRBC                              (1<<14)  //rank,row,bank,column\r
-#define AMAP_BRRC                              (2<<14)  //bank,row,rank,column\r
-#define AMAP_FIX                               (3<<14)  //Fixed address\r
-\r
-#define PDQ(n)                          (((n)&0x7)<<16)\r
-#define MPRDQ                                  (1<<19)\r
-#define MVAR                                           (1<<20)\r
-#define RDIMM                                  (1<<21)\r
-#define DO_INIT                                (1<<24)\r
-#define EXE_RANK(n)                     (((n)&3)<<25)\r
-\r
-#define CMD_NOP                                (0<<27)\r
-#define CMD_ClockStop                          (1<<27)\r
-#define CMD_SelfRefresh                        (2<<27)\r
-#define CMD_Refresh                            (3<<27)\r
-#define CMD_DDR3_Reset                (4<<27)\r
-#define CMD_PrechargeAll               (5<<27)\r
-#define CMD_DeepPowerDown                                      (6<<27)\r
-#define CMD_SDRAM_Mode_Exit                            (7<<27)\r
-#define CMD_SDRAM_ZQ_Calibration_Short         (0xB<<27)\r
-#define CMD_SDRAM_ZQ_Calibration_Long          (0xC<<27)\r
-#define CMD_PowerDown                                          (0xE<<27)\r
-#define CMD_SDRAM_NOP                                          (0xF<<27)\r
-\r
-#define EXE                                            (1<<31)\r
-\r
-//IOCR;                   //IO Configuration Register   \r
-#define DQ_ODT                                 (1)\r
-#define DQS_ODT                                (1<<1)\r
-#define TESTEN                                 (1<<2)\r
-#define DQ_RTT_DIS                             (0<<3)\r
-#define DQ_RTT_150                             (1<<3)\r
-#define DQ_RTT_75                              (2<<3)\r
-#define DQ_RTT_50                              (3<<3)\r
-#define DQS_RTT_DIS                            (0<<5)\r
-#define DQS_RTT_150                            (1<<5)\r
-#define DQS_RTT_75                             (2<<5)\r
-#define DQS_RTT_50                             (3<<5)\r
-#define DQ_DS_FULL                             (1<<7)\r
-#define DQ_DS_REDUCE                   (0<<7)\r
-#define DQS_DS_FULL                            (1<<8)\r
-#define DQS_DS_REDUCE                  (0<<8)\r
-#define ADD_DS_FULL                            (1<<9)\r
-#define ADD_DS_REDUCE                  (0<<9)\r
-#define CK_DS_FULL                             (1<<10)\r
-#define CK_DS_REDUCE                           (0<<10)\r
-\r
-#define AUTO_CMD_IOPD(n)                (((n)&0x3)<<18)\r
-#define AUTO_DATA_IOPD(n)               (((n)&0x3)<<22)\r
-#define RTTOH(n)                        (((n)&0x7)<<26)\r
-#define RTTOE                                  (1<<29)\r
-#define DQRTT                                  (1<<30)\r
-#define DQSRTT                                 (1<<31)\r
-\r
-//CSR;                    //Controller Status Register   \r
-#define DFTERR                                 (1<<18)\r
-#define ECCERR                                 (1<<19)\r
-#define DTERR                                  (1<<20)\r
-#define DTIERR                                 (1<<21)\r
-#define ECCSEC                                 (1<<22)\r
-#define TQ                                             (1<<23)\r
-\r
-//DRR;                    //DRAM Refresh Register       \r
-#define TRFC(n)                         ((n)&0xFF)\r
-#define TRFPRD(n)                       (((n)&0xFFFF)<<8)\r
-#define RFBURST(n)                      ((((n)-1)&0xF)<<24)\r
-#define RD                                             (1<<31)\r
-\r
-//TPR[3];                 //SDRAM Timing Parameters Registers   \r
-//TPR0\r
-#define TMRD(n)                         ((n)&0x3)\r
-#define TRTP(n)                         (((n)&0x7)<<2)\r
-#define TWTR(n)                         (((n)&0x7)<<5)\r
-#define TRP(n)                          (((n)&0xF)<<8)\r
-#define TRCD(n)                         (((n)&0xF)<<12)\r
-#define TRAS(n)                         (((n)&0x1F)<<16)\r
-#define TRRD(n)                         (((n)&0xF)<<21)\r
-#define TRC(n)                          (((n)&0x3F)<<25)\r
-#define TCCD                                           (1<<31)\r
-//TPR1                                  \r
-#define TAOND_2                                (0)\r
-#define TAOND_3                                (1)\r
-#define TAOND_4                                (2)\r
-#define TAOND_5                                (3)\r
-#define TRTW                                   (1<<2)\r
-#define TFAW(n)                         (((n)&0x3F)<<3)\r
-#define TMOD(n)                         (((n)&0x3)<<9)\r
-#define TRTODT                          (1<<11)\r
-#define TRNKRTR(n)                      ((((n)-1)&0x3)<<12)\r
-#define TRNKWTW(n)                      (((n)&0x3)<<14)\r
-//TPR2                                  \r
-#define TXS(n)                          ((n)&0x3FF)\r
-#define TXP(n)                          (((n)&0x1F)<<10)\r
-#define TCKE(n)                         (((n)&0xF)<<15)\r
-\r
-//DLLCR;                  //Global DLL Control  Register                                 \r
-//DLLCR09[10];            //DDR Control  Register 0-9                                    \r
-#define DD                                             (1<<31)\r
-\r
-//RSLR[4];                //Rank System Latency  Register 0-3                            \r
-#define SL(n,value)                     (((value)&0x7)<<((n)*3))\r
-\r
-//RDGR[4];                //Rank DQS Gating  Register 0-3                                \r
-#define DQSSEL(n, value)                (((value)&0x3)<<((n)*2))\r
-\r
-//DQTR[9];                //DQ Timing  Register 0-8    \r
-#define DQDLY_DQS(n, value)             (((value)&0x3)<<((n)*4))\r
-#define DQDLY_DQSb(n, value)            (((value)&0x3)<<(((n)*4)+2))\r
-\r
-//DQSTR;                  //DQS Timing  Register                                         \r
-//DQSBTR;                 //DQS_b Timing  Register                                       \r
-#define DQSDLY(n, value)                (((value)&0x7)<<((n)*3))\r
-\r
-//ODTCR;                  //ODT Configuration  Register                                  \r
-#define RDODT(rank, value)              (((value)&0xF)<<((rank)*4))\r
-#define WRODT(rank, value)              (((value)&0xF)<<(((rank)*4)+16))\r
-\r
-//DTR[2];                 //Data Training Register 0-1                                   \r
-//DTAR;                   //Data Training Address  Register                              \r
-#define DTCOL(col)                      ((col)&0xFFF)\r
-#define DTROW(row)                      (((row)&0xFFFF)<<12)\r
-#define DTBANK(bank)                    (((bank)&0x7)<<28)\r
-#define DTMPR                                  (1<<31)\r
-\r
-//ZQCR[3];                //SDRAM ZQ Control Register and SDRAM ZQCS Control Register 0-2\r
-//ZQCR0\r
-#define ZQDATA(n)                       ((n)&0xFFFFF)\r
-#define ZPROG_OUT(n)                    (((n)&0xF)<<20)\r
-#define ZPROG_ODT(n)                    (((n)&0xF)<<24)\r
-#define ZQDEN                                  (1<<28)\r
-#define ZQCLK                                  (1<<29)\r
-#define NOICAL                                 (1<<30)\r
-#define ZQCAL                                  (1<<31)\r
-//ZQCR1                                 \r
-#define ZQ_CALPRD(n)                    ((n)&0x7FFF)\r
-#define ZQ_CAL_EN                              (1<<31)\r
-//ZQCR2                                 \r
-#define ZQCS_CALPRD(n)                  ((n)&0x7FFF)\r
-#define ZQCS_CAL_EN                            (1<<31)\r
-\r
-//ZQSR;                   //SDRAM ZQ Status Register                                     \r
-//TPR3;                   //SDRAM Timing Parameters Register 3                           \r
-#define BL2                                            (0)\r
-#define BL4                                            (1)\r
-#define BL8                                            (2)\r
-#define BL16                                           (3)\r
-#define BLOTF_EN                               (1<<2)\r
-#define CL(n)                           (((n)&0xF)<<3)\r
-#define CWL(n)                          (((n)&0xF)<<7)\r
-#define WR(n)                           (((n)&0xF)<<11)\r
-#define AL(n)                           (((n)&0xF)<<15)\r
-\r
-//ALPMR;                  //Automatic Low Power Mode Register                            \r
-#define LPPERIOD_CLK_STOP(n)            ((n)&0xFF)\r
-#define LPPERIOD_POWER_DOWN(n)          (((n)&0xFF)<<8)\r
-#define AUTOCS                                 (1<<25)\r
-#define AUTOPD                                 (1<<26)\r
-\r
-//Reserved[0x7c-0x30];                                                                   \r
-//MR;                     //Mode Register                                                \r
-#define DDR_BL4                                (2)\r
-#define DDR_BL8                                (3)\r
-#define DDR_CL(n)         (((n)&0x7)<<4)\r
-#define DDR2_WR(n)        ((((n)-1)&0x7)<<9)\r
-\r
-//EMR;                    //Extended Mode Register      \r
-#define DDR2_STR_FULL                  (0)\r
-#define DDR2_STR_REDUCE                (1<<1)\r
-#define DDR2_AL(n)        (((n)&0x7)<<3)\r
-#define DDR2_ODT_DIS                   (0)\r
-#define DDR2_ODT_150                   (0x40)\r
-#define DDR2_ODT_75                    (0x4)\r
-#define DDR2_ODT_50                    (0x44)\r
-\r
-//EMR2;                   //Extended Mode Register 2                                     \r
-//EMR3;                   //Extended Mode Register 3                                     \r
-//y Management Unit Registers                                                            \r
-//HPCR[32];               //Host Port Configuration Register 0-31                        \r
-#define HPBL(n)                         ((n)&0xFF)\r
-#define HCBP                                           (1<<8)\r
-#define HNPC                                           (1<<9)\r
-\r
-//PQCR[8];                //Priority Queue Configuration Register 0-7                    \r
-#define TOUT(n)                         ((n)&0xFF)\r
-#define TOUT_MUL_1                             (0<<8)\r
-#define TOUT_MUL_16                     (1<<8)\r
-#define TOUT_MUL_64                     (2<<8)\r
-#define TOUT_MUL_256                   (3<<8)\r
-#define LPQS(n)                         (((n)&0x3)<<10)\r
-#define PQBL(n)                         (((n)&0xFF)<<12)\r
-#define SWAIT(n)                        (((n)&0x1F)<<20)\r
-#define INTRPT(n)                       (((n)&0x7)<<25)\r
-#define APQS                                           (1<<28)\r
-\r
-//MMGCR;                  //Memory Manager General Configuration Register                \r
-#define PORT0_NORMAL_PRIO              (0)\r
-#define PORT0_HIGH_PRIO                (2)\r
-\r
-#define VCODEC_PRIO(n)                   (((n)&0x3)<<8)\r
-#define GPU_PRIO(n)                      (((n)&0x3)<<6)\r
-#define LCD_PRIO(n)                      (((n)&0x3)<<4)\r
-#define PERI_PRIO(n)                     (((n)&0x3)<<2)\r
-#define CPU_PRIO(n)                      (((n)&0x3)<<0)\r
-\r
-/* DDR Controller register struct */\r
-typedef volatile struct DDR_REG_Tag\r
-{\r
-    volatile unsigned int CCR;                    //Controller Configuration Register\r
-    volatile unsigned int DCR;                    //DRAM Configuration Register\r
-    volatile unsigned int IOCR;                   //IO Configuration Register\r
-    volatile unsigned int CSR;                    //Controller Status Register\r
-    volatile unsigned int DRR;                    //DRAM Refresh Register\r
-    volatile unsigned int TPR[3];                 //SDRAM Timing Parameters Registers\r
-    volatile unsigned int DLLCR;                  //Global DLL Control  Register\r
-    volatile unsigned int DLLCR09[10];            //DDR Control  Register 0-9\r
-    volatile unsigned int RSLR[4];                //Rank System Latency  Register 0-3\r
-    volatile unsigned int RDGR[4];                //Rank DQS Gating  Register 0-3\r
-    volatile unsigned int DQTR[9];                //DQ Timing  Register 0-8\r
-    volatile unsigned int DQSTR;                  //DQS Timing  Register\r
-    volatile unsigned int DQSBTR;                 //DQS_b Timing  Register\r
-    volatile unsigned int ODTCR;                  //ODT Configuration  Register\r
-    volatile unsigned int DTR[2];                 //Data Training Register 0-1\r
-    volatile unsigned int DTAR;                   //Data Training Address  Register\r
-    volatile unsigned int ZQCR[3];                //SDRAM ZQ Control Register and SDRAM ZQCS Control Register 0-2\r
-    volatile unsigned int ZQSR;                   //SDRAM ZQ Status Register\r
-    volatile unsigned int TPR3;                   //SDRAM Timing Parameters Register 3\r
-    volatile unsigned int ALPMR;                  //Automatic Low Power Mode Register\r
-    volatile unsigned int Reserved[0x7c-0x30];    \r
-    volatile unsigned int MR;                     //Mode Register\r
-    volatile unsigned int EMR;                    //Extended Mode Register\r
-    volatile unsigned int EMR2;                   //Extended Mode Register 2\r
-    volatile unsigned int EMR3;                   //Extended Mode Register 3\r
-    //Memory Management Unit Registers\r
-    volatile unsigned int HPCR[32];               //Host Port Configuration Register 0-31\r
-    volatile unsigned int PQCR[8];                //Priority Queue Configuration Register 0-7\r
-    volatile unsigned int MMGCR;                  //Memory Manager General Configuration Register\r
-}DDR_REG_T, *pDDR_REG_T;\r
-\r
-typedef struct tagGPIO_IOMUX\r
-{\r
-    volatile unsigned int GPIOL_IOMUX;\r
-    volatile unsigned int GPIOH_IOMUX;\r
-}GPIO_IOMUX_T;\r
-\r
-//GRF Registers\r
-typedef volatile struct tagREG_FILE\r
-{\r
-    volatile unsigned int GRF_GPIO_DIR[6]; \r
-    volatile unsigned int GRF_GPIO_DO[6];\r
-    volatile unsigned int GRF_GPIO_EN[6];\r
-    GPIO_IOMUX_T GRF_GPIO_IOMUX[6];\r
-    volatile unsigned int GRF_GPIO_PULL[7];\r
-    volatile unsigned int GRF_UOC_CON[2];\r
-    volatile unsigned int GRF_USB_CON;\r
-    volatile unsigned int GRF_CPU_CON[2];\r
-    volatile unsigned int GRF_CPU_STATUS;\r
-    volatile unsigned int GRF_MEM_CON;\r
-    volatile unsigned int GRF_MEM_STATUS[3];\r
-    volatile unsigned int GRF_SOC_CON[5];\r
-    volatile unsigned int GRF_OS_REG[4];\r
-} REG_FILE, *pREG_FILE;\r
-\r
-//CRU Registers\r
-typedef volatile struct tagCRU_REG \r
-{\r
-    volatile unsigned int CRU_APLL_CON; \r
-    volatile unsigned int CRU_DPLL_CON;\r
-    volatile unsigned int CRU_CPLL_CON;\r
-    volatile unsigned int CRU_PPLL_CON;\r
-    volatile unsigned int CRU_MODE_CON;\r
-    volatile unsigned int CRU_CLKSEL_CON[18];\r
-    volatile unsigned int CRU_CLKGATE_CON[4];\r
-    volatile unsigned int CRU_SOFTRST_CON[3];\r
-} CRU_REG, *pCRU_REG;\r
-\r
-typedef enum tagDDRDLLMode\r
-{\r
-       DLL_BYPASS=0,\r
-       DLL_NORMAL\r
-}eDDRDLLMode_t;\r
-\r
-\r
-#define pDDR_Reg       ((pDDR_REG_T)RK29_DDRC_BASE)\r
-\r
-#define pGRF_Reg       ((pREG_FILE)RK29_GRF_BASE)\r
-#define pSCU_Reg       ((pCRU_REG)RK29_CRU_BASE)\r
-\r
-//#define  read32(address)           (*((volatile unsigned int volatile*)(address)))\r
-//#define  write32(address, value)   (*((volatile unsigned int volatile*)(address)) = value)\r
-\r
-//u32 GetDDRCL(u32 newMHz);\r
-//void EnterDDRSelfRefresh(void);\r
-//void ExitDDRSelfRefresh(void);\r
-//void ChangeDDRFreqInSram(u32 oldMHz, u32 newMHz);\r
-\r
-\r
-static __sramdata u32 bFreqRaise;\r
-static __sramdata u32 capability;  // one chip cs capability\r
-\r
-//DDR2\r
-static __sramdata u32 tRFC;\r
-static __sramdata u32 tRFPRD;\r
-static __sramdata u32 tRTP;\r
-static __sramdata u32 tWTR;\r
-static __sramdata u32 tRAS;\r
-static __sramdata u32 tRRD;\r
-static __sramdata u32 tRC;\r
-static __sramdata u32 tFAW;\r
-//Mobile-DDR\r
-static __sramdata u32 tXS;\r
-static __sramdata u32 tXP;\r
-\r
-\r
-/****************************************************************************\r
-Internal sram us delay function\r
-Cpu highest frequency is 1.2 GHz\r
-1 cycle = 1/1.2 ns\r
-1 us = 1000 ns = 1000 * 1.2 cycles = 1200 cycles\r
-*****************************************************************************/\r
-void __sramfunc delayus(u32 us)\r
-{      \r
-     u32 count;\r
-     count = us * 533;\r
-     while(count--)  // 3 cycles\r
-               barrier();\r
-\r
-}\r
-\r
-void __sramfunc DDRUpdateRef(void)\r
-{\r
-    volatile u32 value = 0;\r
-\r
-    value = pDDR_Reg->DRR;\r
-    value &= ~(0xFFFF00);\r
-    pDDR_Reg->DRR = value | TRFPRD(tRFPRD);\r
-}\r
-\r
-\r
-void __sramfunc DDRUpdateTiming(void)\r
-{\r
-    u32 value;\r
-    u32 memType = (pDDR_Reg->DCR & 0x3);\r
-\r
-    value = pDDR_Reg->DRR;\r
-    value &= ~(0xFF);\r
-    pDDR_Reg->DRR = TRFC(tRFC) | value;\r
-    if(memType == DDRII)\r
-    {\r
-        value = pDDR_Reg->TPR[0];\r
-        value &= ~((0x7<<2)|(0x7<<5)|(0x1F<<16)|(0xF<<21)|(0x3F<<25));\r
-        pDDR_Reg->TPR[0] = value | TRTP(tRTP) | TWTR(tWTR) | TRAS(tRAS) | TRRD(tRRD) | TRC(tRC);\r
-        value = pDDR_Reg->TPR[1];\r
-        value &= ~(0x3F<<3);\r
-        pDDR_Reg->TPR[1] = value | TFAW(tFAW);\r
-        value = pDDR_Reg->TPR[2];\r
-        value &= ~(0x1F<<10);\r
-        pDDR_Reg->TPR[2] = value | TXP(tXP);\r
-    }\r
-    else\r
-    {\r
-        value = pDDR_Reg->TPR[0];\r
-        value &= ~((0x1F<<16)|(0xF<<21)|(0x3F<<25));\r
-        pDDR_Reg->TPR[0] = value | TRAS(tRAS) | TRRD(tRRD) | TRC(tRC);\r
-        value = pDDR_Reg->TPR[2];\r
-        value &= ~(0x7FFF);\r
-        pDDR_Reg->TPR[2] = value | TXS(tXS) | TXP(tXP);\r
-    }\r
-}\r
-\r
-\r
-u32 __sramfunc GetDDRCL(u32 newMHz)\r
-{\r
-    u32          memType = (pDDR_Reg->DCR & 0x3);\r
-\r
-    if(memType == DDRII)\r
-    {\r
-        if(newMHz <= 266)\r
-        {\r
-            return 4;\r
-        }\r
-        else if((newMHz > 266) && (newMHz <= 333))\r
-        {\r
-            return 5;\r
-        }\r
-        else if((newMHz > 333) && (newMHz <= 400))\r
-        {\r
-            return 6;\r
-        }\r
-        else // > 400MHz\r
-        {\r
-            return 7;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        return 3;\r
-    }\r
-}\r
-\r
-/*-------------------------------------------------------------------\r
-Name    : EnterDDRSelfRefresh\r
-Desc    :   DDR enter self refresh\r
-Params  :\r
-Return  :\r
-Notes   :      1.  ddr enter sel-refresh must be after system enter idle ,after ddr enter sel-refresh must not access ddr \r
-               2.  ddr enter sel-refresh code must not be in ddr \r
--------------------------------------------------------------------*/\r
-void __sramfunc EnterDDRSelfRefresh(void)\r
-{    \r
-    pDDR_Reg->CCR &= ~HOSTEN;  //disable host port\r
-    pDDR_Reg->CCR |= FLUSH;    //flush\r
-    delayus(10);\r
-    pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<24) | (0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x2<<27) | (0x1<<31));  //enter Self Refresh\r
-    delayus(10);\r
-    pSCU_Reg->CRU_SOFTRST_CON[0] |= (0x1f<<19);  //reset DLL\r
-    delayus(10);\r
-}\r
-\r
-/*-------------------------------------------------------------------\r
-Name   :   ExitDDRSelfRefresh\r
-Desc    :   DDR exit self refresh\r
-Params  :\r
-Return  :\r
-Notes   :      1.  ddr enter sel-refresh must be after system enter idle ,after ddr enter sel-refresh must not access ddr \r
-              2.  ddr enter sel-refresh code must not be in ddr \r
--------------------------------------------------------------------*/\r
-void __sramfunc ExitDDRSelfRefresh(void)\r
-{\r
-         pSCU_Reg->CRU_SOFTRST_CON[0] &= ~(0x1f<<19);  //de-reset DLL\r
-    delayus(10);     \r
-    pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<24) | (0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x7<<27) | (0x1<<31)); //exit\r
-    delayus(10); //wait for exit self refresh dll lock\r
-    while(1)\r
-    {\r
-        pDDR_Reg->DRR |= RD;  //auto refresh\r
-        pDDR_Reg->CCR |= DTT;\r
-        delayus(1000);\r
-        pDDR_Reg->DRR &= ~RD;\r
-        if(pDDR_Reg->CSR & (0x1<<20))\r
-        {\r
-                 pDDR_Reg->CSR &=  ~(0x1<<20);\r
-        }\r
-        else\r
-        {\r
-            break;\r
-        }\r
-    }\r
-    pDDR_Reg->CCR |= HOSTEN;  //enable host port\r
-}\r
-\r
-static void DDRPreUpdateRef(u32 MHz)\r
-{\r
-    tRFPRD = ((59*MHz) >> 3) & 0x3FFF;  // 62/8 = 7.75us\r
-}\r
-\r
-static void DDRPreUpdateTiming(u32 MHz)\r
-{\r
-    u32 tmp;\r
-    u32 cl;\r
-    u32 memType = (pDDR_Reg->DCR & 0x3);\r
-\r
-    cl = GetDDRCL(MHz);\r
-    //ʱÐò\r
-    if(memType == DDRII)\r
-    {\r
-        if(capability <= 0x2000000)  // 256Mb\r
-        {\r
-            tmp = (75*MHz/1000) + ((((75*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else if(capability <= 0x4000000) // 512Mb\r
-        {\r
-            tmp = (105*MHz/1000) + ((((105*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else if(capability <= 0x8000000)  // 1Gb\r
-        {\r
-            tmp = (128*MHz/1000) + ((((128*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else  // 4Gb\r
-        {\r
-            tmp = (328*MHz/1000) + ((((328*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        //tRFC = 75ns(256Mb)/105ns(512Mb)/127.5ns(1Gb)/327.5ns(4Gb)\r
-        tmp = (tmp > 0xFF) ? 0xFF : tmp;\r
-        tRFC = tmp;\r
-        // tRTP = 7.5ns\r
-        tmp = (8*MHz/1000) + ((((8*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 6) ? 6 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tRTP = tmp;\r
-        //tWTR = 10ns(DDR2-400), 7.5ns (DDR2-533/667/800)\r
-        if(MHz <= 200)\r
-        {\r
-            tmp = (10*MHz/1000) + ((((10*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else\r
-        {\r
-            tmp = (8*MHz/1000) + ((((8*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        tmp = (tmp > 6) ? 6 : tmp;\r
-        tmp = (tmp < 1) ? 1 : tmp;\r
-        tWTR = tmp;\r
-        //tRAS_min = 45ns\r
-        tmp = (45*MHz/1000) + ((((45*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 31) ? 31 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tRAS = tmp;\r
-        // tRRD = 10ns\r
-        tmp = (10*MHz/1000) + ((((10*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 8) ? 8 : tmp;\r
-        tmp = (tmp < 1) ? 1 : tmp;\r
-        tRRD = tmp;\r
-        if(MHz <= 200)  //tRC = 65ns\r
-        {\r
-            tmp = (65*MHz/1000) + ((((65*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else //tRC = 60ns\r
-        {\r
-            tmp = (60*MHz/1000) + ((((60*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        tmp = (tmp > 42) ? 42 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tRC = tmp;\r
-        //tFAW = 50ns\r
-        tmp = (50*MHz/1000) + ((((50*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 31) ? 31 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tFAW = tmp;\r
-        if(MHz <= 333)\r
-        {\r
-            tXP = 7;\r
-        }\r
-        else\r
-        {\r
-            tXP = 8;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        if(capability <= 0x2000000)  // 128Mb,256Mb\r
-        {\r
-            // 128Mb,256Mb  tRFC=80ns\r
-            tmp = (80*MHz/1000) + ((((80*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else if(capability <= 0x4000000) // 512Mb\r
-        {\r
-            // 512Mb  tRFC=110ns\r
-            tmp = (110*MHz/1000) + ((((110*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else if(capability <= 0x8000000)  // 1Gb\r
-        {\r
-            // 1Gb tRFC=140ns\r
-            tmp = (140*MHz/1000) + ((((140*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else  // 4Gb\r
-        {\r
-            // ´óÓÚ1GbûÕÒµ½£¬°´DDR2µÄ tRFC=328ns\r
-            tmp = (328*MHz/1000) + ((((328*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        //tRFC = 80ns(128Mb,256Mb)/110ns(512Mb)/140ns(1Gb)\r
-        tmp = (tmp > 0xFF) ? 0xFF : tmp;\r
-        tRFC = tmp;\r
-        if(MHz <= 100)  //tRAS_min = 50ns\r
-        {\r
-            tmp = (50*MHz/1000) + ((((50*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else //tRAS_min = 45ns\r
-        {\r
-            tmp = (45*MHz/1000) + ((((45*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        tmp = (tmp > 31) ? 31 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tRAS = tmp;\r
-        // tRRD = 15ns\r
-        tmp = (15*MHz/1000) + ((((15*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 8) ? 8 : tmp;\r
-        tmp = (tmp < 1) ? 1 : tmp;\r
-        tRRD = tmp;\r
-        if(MHz <= 100)  //tRC = 80ns\r
-        {\r
-            tmp = (80*MHz/1000) + ((((80*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        else //tRC = 75ns\r
-        {\r
-            tmp = (75*MHz/1000) + ((((75*MHz)%1000) > 0) ? 1:0);\r
-        }\r
-        tmp = (tmp > 42) ? 42 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tRC = tmp;\r
-        //tXSR = 200 ns\r
-        tmp = (200*MHz/1000) + ((((200*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 1023) ? 1023 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tXS = tmp;\r
-        //tXP=25ns\r
-        tmp = (25*MHz/1000) + ((((25*MHz)%1000) > 0) ? 1:0);\r
-        tmp = (tmp > 31) ? 31 : tmp;\r
-        tmp = (tmp < 2) ? 2 : tmp;\r
-        tXP = tmp;\r
-    }\r
-}\r
-\r
-static void __sramfunc StopDDR(u32 oldMHz, u32 newMHz)\r
-{\r
-    pDDR_Reg->CCR |= FLUSH;    //flush\r
-    delayus(10);\r
-    pDDR_Reg->CCR &= ~HOSTEN;  //disable host port\r
-\r
-    EnterDDRSelfRefresh();\r
-    if(oldMHz < newMHz)  //ÉýƵ\r
-    {\r
-        DDRUpdateTiming();\r
-        bFreqRaise = 1;\r
-    }\r
-    else //½µÆµ\r
-    {\r
-        DDRUpdateRef();\r
-        bFreqRaise = 0;\r
-    }\r
-}\r
-\r
-static void __sramfunc ResumeDDR(u32 newMHz)\r
-{\r
-               u32 value;\r
-    u32 memType = (pDDR_Reg->DCR & 0x3);\r
-    u32 cl;\r
-    \r
-    if(bFreqRaise)  //ÉýƵ\r
-    {\r
-        DDRUpdateRef();\r
-    }\r
-    else //½µÆµ\r
-    {\r
-        DDRUpdateTiming();\r
-    }\r
-    ExitDDRSelfRefresh();\r
-    \r
-    if(memType == DDRII)\r
-    {\r
-        cl = GetDDRCL(newMHz);\r
-\r
-        value = pDDR_Reg->TPR[0];\r
-        value &= ~((0xF<<8)|(0xF<<12));\r
-        pDDR_Reg->TPR[0] = value | TRP(cl) | TRCD(cl);\r
-        value = pDDR_Reg->TPR3;\r
-        value &= ~((0xF<<3)|(0xF<<7)|(0xF<<11));\r
-        pDDR_Reg->TPR3 = value | CL(cl) | CWL(cl-1) | WR(cl);\r
-        //set mode register cl\r
-        pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x5<<27) | (0x1<<31));  //precharge-all\r
-        value = pDDR_Reg->MR;\r
-        value &= ~((0x7<<4)|(0x7<<9));\r
-        pDDR_Reg->MR = value | DDR_CL(cl) | DDR2_WR(cl);        \r
-    }\r
-}\r
-\r
-/*-------------------------------------------------------------------\r
-Name    : PLLSetAUXFreq\r
-Desc    : »ñÈ¡AUXƵÂÊ\r
-Params  :\r
-Return  : AUXƵÂÊ,  MHz Îªµ¥Î»\r
-Notes   :\r
--------------------------------------------------------------------*/\r
-void __sramfunc PLLSetAUXFreq(u32 freq)\r
-{\r
-               u32 value;\r
-               \r
-    // ddr slow\r
-    value = pSCU_Reg->CRU_MODE_CON;\r
-    value &=~(0x3<<6);\r
-    pSCU_Reg->CRU_MODE_CON = value;\r
-\r
-    delayus(10);\r
-    \r
-    pSCU_Reg->CRU_DPLL_CON |= (0x1 << 15); //power down pll\r
-    delayus(1);  //delay at least 500ns\r
-    switch(freq)    //  Êµ¼ÊƵÂÊÒªºÍϵͳȷÈÏ ?????????\r
-    {\r
-        case 136:\r
-            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | (44<<3) | (2<<1);  //high band 135\r
-            break;\r
-        case 200:\r
-            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | (66<<3) | (2<<1);  //high band 201\r
-            break;\r
-        case 266:\r
-            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | (43<<3) | (1<<1);  //high band 264\r
-            break;\r
-        case 333:\r
-            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | ((54)<<3) | (1<<1);  //high band 330\r
-            break;\r
-        case 400:\r
-            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | ((66)<<3) | (1<<1);  //high band 402\r
-            break;\r
-        case 533:\r
-            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | (43<<3) | (0<<1);  //high band 528\r
-            break;\r
-    }\r
-       \r
-    delayus(1);  //delay at least 500ns\r
-    pSCU_Reg->CRU_DPLL_CON &= ~(0x1<<15);\r
-    delayus(2000); // 7.2us*140=1.008ms\r
-\r
-    // ddr pll normal\r
-    value = pSCU_Reg->CRU_MODE_CON;\r
-    value &=~(0x3<<6);\r
-    value |= 0x1<<6;\r
-    pSCU_Reg->CRU_MODE_CON = value;\r
-\r
-    // ddr_pll_clk: clk_ddr=1:1 \r
-    value = pSCU_Reg->CRU_CLKSEL_CON[7];\r
-    value &=~(0x1F<<24);\r
-    value |= (0x0 <<26)| (0x0<<24);\r
-    pSCU_Reg->CRU_CLKSEL_CON[7] = value;\r
-}\r
-\r
-\r
-static void __sramfunc DDR_ChangePrior(void)\r
-{\r
-       // 4_VCODEC(2) 3_GPU(1) 2_LCD(0) 1_PERI(1) 0_CPU(2)\r
-       pGRF_Reg->GRF_MEM_CON = (pGRF_Reg->GRF_MEM_CON & ~0x3FF) | VCODEC_PRIO(2) | GPU_PRIO(1) | LCD_PRIO(0) | PERI_PRIO(1) | CPU_PRIO(2);\r
-}\r
-\r
-//Õâ¸öº¯ÊýµÄÇ°ÌáÌõ¼þÊÇ:\r
-// 1, ²»ÄÜÓÐDDR·ÃÎÊ\r
-// 2, ChangeDDRFreqº¯Êý¼°º¯ÊýÖÐËùµ÷Óõ½µÄËùÓк¯Êý¶¼²»·ÅÔÚDDRÖÐ\r
-// 3, ¶ÑÕ»²»·ÅÔÚDDRÖÐ\r
-// 4, ÖжϹرգ¬·ñÔò¿ÉÄÜÖжϻáÒýÆð·ÃÎÊDDR\r
-\r
-void __sramfunc ChangeDDRFreqInSram(u32 oldMHz, u32 newMHz)\r
-{\r
-    StopDDR(oldMHz, newMHz);\r
-    PLLSetAUXFreq(newMHz);\r
-    ResumeDDR(newMHz);\r
-}\r
-\r
-void __sramfunc DDRDLLSetMode(eDDRDLLMode_t DLLmode, u32 freq)\r
-{\r
-   if( DLLmode == DLL_BYPASS )\r
-       {\r
-               pDDR_Reg->DLLCR09[0] |= 1<<28;\r
-               pDDR_Reg->DLLCR09[1] |= 1<<28;\r
-               pDDR_Reg->DLLCR09[2] |= 1<<28;\r
-               pDDR_Reg->DLLCR09[3] |= 1<<28;\r
-               pDDR_Reg->DLLCR09[4] |= 1<<28;\r
-       if(freq <= 100)\r
-             pDDR_Reg->DLLCR &= ~(1<<23);      \r
-       else if(freq <=200)\r
-            pDDR_Reg->DLLCR |= 1<<23;\r
-       }\r
-   else\r
-       {\r
-              pDDR_Reg->DLLCR09[0] &= ~(1<<28);\r
-               pDDR_Reg->DLLCR09[1] &= ~(1<<28);\r
-               pDDR_Reg->DLLCR09[2] &= ~(1<<28);\r
-               pDDR_Reg->DLLCR09[3] &= ~(1<<28);\r
-               pDDR_Reg->DLLCR09[4] &= ~(1<<28);   \r
-       }       \r
-}\r
-typedef struct DDR_CONFIG_Tag\r
-{\r
-    u32 row;\r
-    u32 bank;\r
-    u32 col;\r
-    u32 config;\r
-}DDR_CONFIG_T;\r
-\r
-DDR_CONFIG_T    ddrConfig[3][10] = {\r
-    //row, bank, col, config\r
-    {\r
-        //DDR2\r
-        // x16\r
-        {15, 8, 10, (DIO_16 | DSIZE_4Gb)},\r
-        {14, 8, 10, (DIO_16 | DSIZE_2Gb)},\r
-        {13, 8, 10, (DIO_16 | DSIZE_1Gb)},\r
-        {13, 4, 10, (DIO_16 | DSIZE_512Mb)},\r
-        {13, 4, 9,  (DIO_16 | DSIZE_256Mb)},\r
-        // x8\r
-        {16, 8, 10, (DIO_8  | DSIZE_4Gb)},\r
-        {15, 8, 10, (DIO_8  | DSIZE_2Gb)},\r
-        {14, 8, 10, (DIO_8  | DSIZE_1Gb)},\r
-        {14, 4, 10, (DIO_8  | DSIZE_512Mb)},\r
-        {13, 4, 10, (DIO_8  | DSIZE_256Mb)},\r
-    },\r
-    {\r
-        //DDR3\r
-        // x16\r
-        {16, 8, 10, (DIO_16 | DSIZE_8Gb)},\r
-        {15, 8, 10, (DIO_16 | DSIZE_4Gb)},\r
-        {14, 8, 10, (DIO_16 | DSIZE_2Gb)},\r
-        {13, 8, 10, (DIO_16 | DSIZE_1Gb)},\r
-        {12, 8, 10, (DIO_16 | DSIZE_512Mb)},\r
-        // x8\r
-        {16, 8, 11, (DIO_16 | DSIZE_8Gb)},\r
-        {16, 8, 10, (DIO_16 | DSIZE_4Gb)},\r
-        {15, 8, 10, (DIO_16 | DSIZE_2Gb)},\r
-        {14, 8, 10, (DIO_16 | DSIZE_1Gb)},\r
-        {13, 8, 10, (DIO_16 | DSIZE_512Mb)},\r
-    },\r
-    {\r
-        // x32\r
-        {14, 4, 10, (DIO_32 | DSIZE_2Gb)},\r
-        {13, 4, 10, (DIO_32 | DSIZE_1Gb)},\r
-        {13, 4, 9,  (DIO_32 | DSIZE_512Mb)},\r
-        {12, 4, 9,  (DIO_32 | DSIZE_256Mb)},\r
-        // x16\r
-        {14, 4, 11, (DIO_16 | DSIZE_2Gb)},\r
-        {14, 4, 10, (DIO_16 | DSIZE_1Gb)},\r
-        {13, 4, 10, (DIO_16 | DSIZE_512Mb)},\r
-        {13, 4, 9,  (DIO_16 | DSIZE_256Mb)},\r
-        {12, 4, 9,  (DIO_16 | DSIZE_128Mb)},\r
-        {0,  0, 0,  0},\r
-    }\r
-};\r
-\r
-/*-------------------------------------------------------------------\r
-Name    : DDR_Init\r
-Desc    :  ddr initialize\r
-Params  :\r
-Return  :\r
-Notes   : \r
--------------------------------------------------------------------*/\r
-u32 ddrDataTraining[16];\r
-void DDR_Init(void)\r
-{\r
-    volatile u32 value = 0;\r
-       u32          addr;\r
-    u32          MHz;\r
-    unsigned long Hz;\r
-    u32          memType = (pDDR_Reg->DCR & 0x3);  \r
-    u32          bw;\r
-    u32          col;\r
-    u32          row;\r
-    u32          bank;\r
-    u32          n;\r
-\r
-    // caculate aglined physical address \r
-    addr =  __pa((unsigned long)ddrDataTraining);\r
-    if(addr&0x1F)\r
-    {\r
-        addr += (32-(addr&0x1F));\r
-    }\r
-    addr -= 0x60000000;\r
-    // caculate data width\r
-    bw = ((((pDDR_Reg->DCR >> 7) & 0x7)+1)>>1);\r
-    // find out col£¬row£¬bank\r
-    for(n=0;n<10; n++)\r
-    {\r
-        if(ddrConfig[(pDDR_Reg->DCR & 0x3)][n].config == (pDDR_Reg->DCR & 0x7c))\r
-        {\r
-            col = ddrConfig[(pDDR_Reg->DCR & 0x3)][n].col;\r
-            row = ddrConfig[(pDDR_Reg->DCR & 0x3)][n].row;\r
-            bank = ddrConfig[(pDDR_Reg->DCR & 0x3)][n].bank;\r
-            bank >>= 2;  // 8=>3, 4=>2\r
-            bank += 1;\r
-            break;\r
-        }\r
-    }\r
-    if(n == 10)\r
-    {\r
-        //ASSERT\r
-    }\r
-\r
-    // according different address mapping, caculate DTAR register value\r
-    value = pDDR_Reg->DTAR;\r
-    value &= ~(0x7FFFFFFF);\r
-    switch(pDDR_Reg->DCR & (0x3<<14))\r
-    {\r
-        case AMAP_RBRC:\r
-            value |= (addr>>bw) & ((0x1<<col)-1);  // col\r
-            value |= ((addr>>(bw+col)) & ((0x1<<row)-1)) << 12;  // row\r
-            value |= ((addr>>(bw+col+row)) & ((0x1<<bank)-1)) << 28;  // bank\r
-            break;\r
-        case AMAP_RRBC:\r
-            value |= (addr>>bw) & ((0x1<<col)-1);  // col\r
-            value |= ((addr>>(bw+col+bank)) & ((0x1<<row)-1)) << 12;  // row\r
-            value |= ((addr>>(bw+col)) & ((0x1<<bank)-1)) << 28;  // bank\r
-            break;\r
-        case AMAP_BRRC:\r
-            value |= (addr>>bw) & ((0x1<<col)-1);  // col\r
-            if((pDDR_Reg->DCR >> 11) & 0x3)\r
-            {\r
-                value |= ((addr>>(bw+col+1)) & ((0x1<<row)-1)) << 12;  // row\r
-                value |= ((addr>>(bw+col+row+1)) & ((0x1<<bank)-1)) << 28;  // bank\r
-            }\r
-            else\r
-            {\r
-                value |= ((addr>>(bw+col)) & ((0x1<<row)-1)) << 12;  // row\r
-                value |= ((addr>>(bw+col+row)) & ((0x1<<bank)-1)) << 28;  // bank\r
-            }\r
-            break;\r
-        case AMAP_FIX:    // can not support AMAP_FIX mode \r
-        default:\r
-            break;\r
-    }\r
-    pDDR_Reg->DTAR = value;\r
-\r
-    if((memType == DDRII) || (memType == DDR3))\r
-    {\r
-        pDDR_Reg->ALPMR = LPPERIOD_POWER_DOWN(0xFF)|AUTOPD;\r
-    }\r
-    else\r
-    {\r
-        pDDR_Reg->ALPMR = LPPERIOD_CLK_STOP(0xFF) | LPPERIOD_POWER_DOWN(0xFF) | AUTOCS | AUTOPD;\r
-    }\r
-    DDR_ChangePrior();\r
-    value = (((pDDR_Reg->DCR >> 7) & 0x7)+1) >> ((pDDR_Reg->DCR >> 2) & 0x3);\r
-    capability = 0x800000 << (((pDDR_Reg->DCR >> 4) & 0x7) + value + ((pDDR_Reg->DCR >> 11) & 0x3));\r
-\r
-    Hz = clk_get_rate(clk_get(NULL,"ddr"));\r
-    MHz = Hz/1000000;   //PLLGetDDRFreq()/1000;\r
-    printk("DDR_Init: freq=%dMHz\n", MHz);\r
-    if((memType == DDRII) || (memType == Mobile_DDR))\r
-    {\r
-    DDRPreUpdateRef(MHz);\r
-    DDRPreUpdateTiming(MHz);\r
-    DDRUpdateRef();\r
-    DDRUpdateTiming();\r
-    }\r
-       \r
-}\r
-\r
-/*-------------------------------------------------------------------\r
-Name    : DDR_ChangeFreq\r
-Desc    :  change ddr frequency \r
-Params  :\r
-Return  :\r
-Notes   :  close interrupt before call it\r
-              open interrupt after call it\r
--------------------------------------------------------------------*/\r
-void DDR_ChangeFreq(u32 DDRoldMHz, u32 DDRnewMHz)\r
-{\r
-\r
-    DDRPreUpdateRef(DDRnewMHz);\r
-    DDRPreUpdateTiming(DDRnewMHz);     \r
-    DDR_SAVE_SP(save_sp);\r
-    flush_cache_all();      // 20100615,HSL@RK.\r
-    __cpuc_flush_user_all();\r
-    ChangeDDRFreqInSram(DDRoldMHz, DDRnewMHz);\r
-    DDR_RESTORE_SP(save_sp);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////////////////\r
-\r
-/*-------------------------------------------------------------------\r
-Name    :  DDR_EnterSelfRefresh\r
-Desc    :   DDR enter self refresh call in ddr\r
-Params  :\r
-Return  :\r
-Notes   :      1.  ddr enter sel-refresh must be after system enter idle ,after ddr enter sel-refresh must not access ddr \r
-               2.  ddr enter sel-refresh code must not be in ddr \r
--------------------------------------------------------------------*/\r
-void __sramfunc DDR_EnterSelfRefresh(void)\r
-{\r
-    EnterDDRSelfRefresh();\r
-#if 1\r
-    pSCU_Reg->CRU_CLKGATE_CON[0] |= (0x1<<18);  //close DDR PHY clock  / DDR CPU AXI clock / DDR REG AXI clock\r
-    delayus(10);\r
-    // ddr slow\r
-    pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
-    delayus(10);       \r
-    pSCU_Reg->CRU_DPLL_CON |= (0x1 << 15);  //power down DPLL\r
-    delayus(10);  //delay at least 500ns\r
-#endif\r
-}\r
-\r
-/*-------------------------------------------------------------------\r
-Name   :   DDR_ExitSelfRefresh\r
-Desc    :   DDR exit self refresh\r
-Params  :\r
-Return  :\r
-Notes   :      1.  ddr enter sel-refresh must be after system enter idle ,after ddr enter sel-refresh must not access ddr \r
-              2.  ddr enter sel-refresh code must not be in ddr \r
--------------------------------------------------------------------*/\r
-void __sramfunc DDR_ExitSelfRefresh(void)\r
-{\r
-               u32 value;\r
-#if 1\r
-     pSCU_Reg->CRU_DPLL_CON &= ~(0x1 << 15);  //power on DPLL   \r
-    //   while(!(pGRF_Reg->GRF_SOC_CON[0] & (1<<28)));\r
-     delayus(200); // 7.2us*140=1.008ms // Ëø¶¨pll\r
-    // ddr pll normal\r
-    value = pSCU_Reg->CRU_MODE_CON;\r
-    value &=~(0x3<<6);\r
-    value |= 0x1<<6;\r
-    pSCU_Reg->CRU_MODE_CON = value;\r
-    delayus(10);       \r
-    pSCU_Reg->CRU_CLKGATE_CON[0] &= ~(0x1<<18);  //enable DDR PHY clock / DDR CPU AXI clock / DDR REG AXI clock\r
-    delayus(10);    \r
-#endif\r
-    ExitDDRSelfRefresh();\r
-\r
-}\r
- void preload_sram_addr(unsigned int vaddr)\r
-{\r
-       \r
-       __asm__(\r
-               "mcr p15,0,%0,c8,c5,1 \n\t"\r
-               "mcr p15,0,%1,c10,c0,1 \n\t"\r
-               "mcr p15,0,%0,c10,c1,1 \n\t"\r
-               "mcr p15,0,%2,c10,c0,1\n\t"\r
-               ::"r"(vaddr) , "r"(0x00000001), "r"(0x08400000));\r
-}\r
-// consider  cpu prefetch¡¢mmu cache\r
-static void __sramfunc do_selfrefreshtest(void)\r
-{\r
-       volatile u32 n; \r
-       //local_flush_tlb_all();\r
-       //preload_sram_addr(0xff400000);\r
-       flush_cache_all();      // 20100615,HSL@RK.\r
-       __cpuc_flush_kern_all();\r
-       __cpuc_flush_user_all();\r
-\r
-       \r
-    //  pSCU_Reg->CRU_CLKGATE_CON[1] |= 1<<6; // disable DDR Periph clock\r
-   //   pSCU_Reg->CRU_CLKGATE_CON[3] |= 1<<1 |1<<11|1<<13|1<<16; // disable DDR LCDC / DDR VPU / DDR GPU clock\r
-               \r
-#if 1\r
-volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;\r
-n=temp[0];\r
-barrier();\r
-n=temp[1024];\r
-barrier();\r
-n=temp[1024*2];\r
-barrier();\r
-n=temp[1024*3];\r
-barrier();\r
-\r
-\r
-\r
-#endif\r
-       n= pDDR_Reg->CCR;\r
-       n= pSCU_Reg->CRU_SOFTRST_CON[0];\r
-       dsb();\r
-         \r
-       DDR_EnterSelfRefresh();\r
-       DDR_ExitSelfRefresh();\r
-       dsb(); \r
-}\r
-\r
-static void selfrefreshtest(void)\r
-{\r
-       DDR_SAVE_SP(save_sp);\r
-       do_selfrefreshtest();\r
-       DDR_RESTORE_SP(save_sp);\r
-}\r
-\r
-static void changefreqtest(u32 DDRnewMHz)\r
-{\r
-    u32 MHz;\r
-    u32 value =0;\r
-    unsigned long Hz;\r
-\r
-    Hz = clk_get_rate(clk_get(NULL,"ddr"));\r
-    MHz =  Hz /1000000; // PLLGetDDRFreq()/1000;\r
-    DDRPreUpdateRef(DDRnewMHz);\r
-    DDRPreUpdateTiming(DDRnewMHz);     \r
-    DDR_SAVE_SP(save_sp);\r
-    flush_cache_all();      // 20100615,HSL@RK.\r
-    __cpuc_flush_user_all();\r
-    ChangeDDRFreqInSram(MHz, DDRnewMHz);\r
-    DDRDLLSetMode(DLL_BYPASS,DDRnewMHz);\r
-    DDR_RESTORE_SP(save_sp);\r
-}\r
-\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-\r
-\r
-static __sramdata u32 gfreq = 0;\r
-static void suspend(struct early_suspend *h)\r
-{\r
-       u32 MHz;\r
-       unsigned long Hz;\r
-       unsigned long flags;\r
-         \r
-      local_irq_save(flags);   \r
-      Hz = clk_get_rate(clk_get(NULL,"ddr"));\r
-      MHz =  Hz /1000000; \r
-      gfreq = MHz;\r
-\r
-      udelay(1000);\r
-         \r
-      DDR_ChangeFreq(MHz,200);\r
-\r
-      local_irq_restore(flags);\r
-\r
-     //printk("enter ddr early suspend\n");\r
-}\r
-\r
-static void resume(struct early_suspend *h)\r
-{\r
-\r
-      unsigned long flags;\r
-         \r
-      local_irq_save(flags);\r
-\r
-      udelay(1000);\r
-         \r
-      DDR_ChangeFreq(200,333);\r
-         \r
-      local_irq_restore(flags);\r
-         \r
-      //printk("enter ddr early suspend resume \n");  \r
-}\r
-\r
-struct early_suspend early_suspend_info = {\r
-       .suspend = suspend,\r
-       .resume = resume,\r
-       .level = EARLY_SUSPEND_LEVEL_DISABLE_FB +1,\r
-};\r
-#endif\r
-\r
-\r
-void __sramfunc ddr_suspend(void)\r
-{\r
-       volatile u32 n; \r
-       flush_cache_all();      // 20100615,HSL@RK.\r
-       __cpuc_flush_kern_all();\r
-       __cpuc_flush_user_all();\r
-\r
-       \r
-    //  pSCU_Reg->CRU_CLKGATE_CON[1] |= 1<<6; // disable DDR Periph clock\r
-   //   pSCU_Reg->CRU_CLKGATE_CON[3] |= 1<<1 |1<<11|1<<13|1<<16; // disable DDR LCDC / DDR VPU / DDR GPU clock\r
-               \r
-#if 1\r
-       volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;\r
-       n=temp[0];\r
-       barrier();\r
-       n=temp[1024];\r
-       barrier();\r
-       n=temp[1024*2];\r
-       barrier();\r
-       n=temp[1024*3];\r
-       barrier();\r
-\r
-#endif\r
-       n= pDDR_Reg->CCR;\r
-       n= pSCU_Reg->CRU_SOFTRST_CON[0];\r
-      //       flush_cache_all();      // 20100615,HSL@RK.\r
-       //__cpuc_flush_kern_all();\r
-       //__cpuc_flush_user_all();\r
-       //barrier();\r
-       dsb();//dmb();    \r
-       DDR_EnterSelfRefresh();\r
-}\r
-\r
-void __sramfunc ddr_resume(void)\r
-{\r
-#if 0\r
-       unsigned long flags;\r
-         \r
-      local_irq_save(flags);\r
-      udelay(1000);      \r
-      DDR_ChangeFreq(200,333);   \r
-      local_irq_restore(flags);\r
-#else\r
-       DDR_ExitSelfRefresh();\r
-       dsb(); \r
-#endif\r
-}\r
-\r
-static int __init ddr_update_freq(void)\r
-{\r
-\r
-  DDR_Init();\r
-   \r
-#if 0 //#ifdef CONFIG_HAS_EARLYSUSPEND\r
-       register_early_suspend(&early_suspend_info);\r
-#endif\r
-\r
-\r
-   \r
-\r
-   return 0;\r
-}\r
-\r
-core_initcall_sync(ddr_update_freq);\r
-//late_initcall(ddr_update_freq);\r
-\r
+/*
+ * arch/arm/mach-rk29/ddr.c
+ *
+ * Function Driver for DDR controller
+ *
+ * Copyright (C) 2011 Fuzhou Rockchip Electronics Co.,Ltd
+ * Author: 
+ * hcy@rock-chips.com
+ * yk@rock-chips.com
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/irqflags.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/compiler.h>
+#include <linux/platform_device.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/earlysuspend.h>
+#include <linux/random.h> 
+#include <linux/crc32.h>
+
+#include <mach/rk29_iomap.h>
+#include <mach/memory.h>
+#include <mach/sram.h>
+#include <linux/clk.h>
+
+#include <asm/delay.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+
+#include <asm/io.h>
+
+#define ddr_print(x...) printk( "ddr init: " x )
+
+// save_sp  must be static global variable  
+
+static unsigned long save_sp;
+
+
+//CCR;                    //Controller Configuration Register                            
+#define ECCEN                                  (1)
+#define NOMRWR                                 (1<<1)
+#define HOSTEN                                 (1<<2)
+#define RRB                                            (1<<13)
+#define DQSCFG                                 (1<<14)
+#define DFTLM_NO                        (0<<15)
+#define DFTLM_90                        (1<<15)
+#define DFTLM_180                       (2<<15)
+#define DFTLM_270                       (3<<15)
+#define DFTCMP                                 (1<<17)
+#define FLUSH                                  (1<<27)
+#define ITMRST                                 (1<<28)
+#define IB                                             (1<<29)
+#define DTT                                            (1<<30)
+#define IT                                             (1<<31)
+//DCR;                    //DRAM Configuration Register                                  
+#define DDRII                                          (0)
+#define DDR3                                           (1)
+#define Mobile_DDR                             (2)
+                                        
+#define DIO_8                                  (1<<2)
+#define DIO_16                                 (2<<2)
+#define DIO_32                                 (3<<2)
+                                        
+#define DSIZE_64Mb                             (0<<4)
+#define DSIZE_128Mb                            (1<<4)
+#define DSIZE_256Mb                            (2<<4)
+#define DSIZE_512Mb                            (3<<4)
+#define DSIZE_1Gb                              (4<<4)
+#define DSIZE_2Gb                              (5<<4)
+#define DSIZE_4Gb                              (6<<4)
+#define DSIZE_8Gb                              (7<<4)
+                                        
+#define SIO(n)                          (((n)-1)<<7)
+#define PIO                                            (1<<10)
+#define RANKS(n)                        ((((n)-1)&0x3)<<11)
+#define RNKALL                                 (1<<13)
+                                        
+#define AMAP_RBRC                              (0<<14)  //rank,bank,row,column
+#define AMAP_RRBC                              (1<<14)  //rank,row,bank,column
+#define AMAP_BRRC                              (2<<14)  //bank,row,rank,column
+#define AMAP_FIX                               (3<<14)  //Fixed address
+
+#define PDQ(n)                          (((n)&0x7)<<16)
+#define MPRDQ                                  (1<<19)
+#define MVAR                                           (1<<20)
+#define RDIMM                                  (1<<21)
+#define DO_INIT                                (1<<24)
+#define EXE_RANK(n)                     (((n)&3)<<25)
+
+#define CMD_NOP                                (0<<27)
+#define CMD_ClockStop                          (1<<27)
+#define CMD_SelfRefresh                        (2<<27)
+#define CMD_Refresh                            (3<<27)
+#define CMD_DDR3_Reset                (4<<27)
+#define CMD_PrechargeAll               (5<<27)
+#define CMD_DeepPowerDown                                      (6<<27)
+#define CMD_SDRAM_Mode_Exit                            (7<<27)
+#define CMD_SDRAM_ZQ_Calibration_Short         (0xB<<27)
+#define CMD_SDRAM_ZQ_Calibration_Long          (0xC<<27)
+#define CMD_PowerDown                                          (0xE<<27)
+#define CMD_SDRAM_NOP                                          (0xF<<27)
+
+#define EXE                                            (1<<31)
+
+//IOCR;                   //IO Configuration Register   
+#define DQ_ODT                                 (1)
+#define DQS_ODT                                (1<<1)
+#define TESTEN                                 (1<<2)
+#define DQ_RTT_DIS                             (0<<3)
+#define DQ_RTT_150                             (1<<3)
+#define DQ_RTT_75                              (2<<3)
+#define DQ_RTT_50                              (3<<3)
+#define DQS_RTT_DIS                            (0<<5)
+#define DQS_RTT_150                            (1<<5)
+#define DQS_RTT_75                             (2<<5)
+#define DQS_RTT_50                             (3<<5)
+#define DQ_DS_FULL                             (1<<7)
+#define DQ_DS_REDUCE                   (0<<7)
+#define DQS_DS_FULL                            (1<<8)
+#define DQS_DS_REDUCE                  (0<<8)
+#define ADD_DS_FULL                            (1<<9)
+#define ADD_DS_REDUCE                  (0<<9)
+#define CK_DS_FULL                             (1<<10)
+#define CK_DS_REDUCE                           (0<<10)
+
+#define AUTO_CMD_IOPD(n)                (((n)&0x3)<<18)
+#define AUTO_DATA_IOPD(n)               (((n)&0x3)<<22)
+#define RTTOH(n)                        (((n)&0x7)<<26)
+#define RTTOE                                  (1<<29)
+#define DQRTT                                  (1<<30)
+#define DQSRTT                                 (1<<31)
+
+//CSR;                    //Controller Status Register   
+#define DFTERR                                 (1<<18)
+#define ECCERR                                 (1<<19)
+#define DTERR                                  (1<<20)
+#define DTIERR                                 (1<<21)
+#define ECCSEC                                 (1<<22)
+#define TQ                                             (1<<23)
+
+//DRR;                    //DRAM Refresh Register       
+#define TRFC(n)                         ((n)&0xFF)
+#define TRFPRD(n)                       (((n)&0xFFFF)<<8)
+#define RFBURST(n)                      ((((n)-1)&0xF)<<24)
+#define RD                                             (1<<31)
+
+//TPR[3];                 //SDRAM Timing Parameters Registers   
+//TPR0
+#define TMRD(n)                         ((n)&0x3)
+#define TRTP(n)                         (((n)&0x7)<<2)
+#define TWTR(n)                         (((n)&0x7)<<5)
+#define TRP(n)                          (((n)&0xF)<<8)
+#define TRCD(n)                         (((n)&0xF)<<12)
+#define TRAS(n)                         (((n)&0x1F)<<16)
+#define TRRD(n)                         (((n)&0xF)<<21)
+#define TRC(n)                          (((n)&0x3F)<<25)
+#define TCCD                                           (1<<31)
+//TPR1                                  
+#define TAOND_2                                (0)
+#define TAOND_3                                (1)
+#define TAOND_4                                (2)
+#define TAOND_5                                (3)
+#define TRTW                                   (1<<2)
+#define TFAW(n)                         (((n)&0x3F)<<3)
+#define TMOD(n)                         (((n)&0x3)<<9)
+#define TRTODT                          (1<<11)
+#define TRNKRTR(n)                      ((((n)-1)&0x3)<<12)
+#define TRNKWTW(n)                      (((n)&0x3)<<14)
+//TPR2                                  
+#define TXS(n)                          ((n)&0x3FF)
+#define TXP(n)                          (((n)&0x1F)<<10)
+#define TCKE(n)                         (((n)&0xF)<<15)
+
+//DLLCR;                  //Global DLL Control  Register                                 
+//DLLCR09[10];            //DDR Control  Register 0-9                                    
+#define DD                                             (1<<31)
+
+//RSLR[4];                //Rank System Latency  Register 0-3                            
+#define SL(n,value)                     (((value)&0x7)<<((n)*3))
+
+//RDGR[4];                //Rank DQS Gating  Register 0-3                                
+#define DQSSEL(n, value)                (((value)&0x3)<<((n)*2))
+
+//DQTR[9];                //DQ Timing  Register 0-8    
+#define DQDLY_DQS(n, value)             (((value)&0x3)<<((n)*4))
+#define DQDLY_DQSb(n, value)            (((value)&0x3)<<(((n)*4)+2))
+
+//DQSTR;                  //DQS Timing  Register                                         
+//DQSBTR;                 //DQS_b Timing  Register                                       
+#define DQSDLY(n, value)                (((value)&0x7)<<((n)*3))
+
+//ODTCR;                  //ODT Configuration  Register                                  
+#define RDODT(rank, value)              (((value)&0xF)<<((rank)*4))
+#define WRODT(rank, value)              (((value)&0xF)<<(((rank)*4)+16))
+
+//DTR[2];                 //Data Training Register 0-1                                   
+//DTAR;                   //Data Training Address  Register                              
+#define DTCOL(col)                      ((col)&0xFFF)
+#define DTROW(row)                      (((row)&0xFFFF)<<12)
+#define DTBANK(bank)                    (((bank)&0x7)<<28)
+#define DTMPR                                  (1<<31)
+
+//ZQCR[3];                //SDRAM ZQ Control Register and SDRAM ZQCS Control Register 0-2
+//ZQCR0
+#define ZQDATA(n)                       ((n)&0xFFFFF)
+#define ZPROG_OUT(n)                    (((n)&0xF)<<20)
+#define ZPROG_ODT(n)                    (((n)&0xF)<<24)
+#define ZQDEN                                  (1<<28)
+#define ZQCLK                                  (1<<29)
+#define NOICAL                                 (1<<30)
+#define ZQCAL                                  (1<<31)
+//ZQCR1                                 
+#define ZQ_CALPRD(n)                    ((n)&0x7FFF)
+#define ZQ_CAL_EN                              (1<<31)
+//ZQCR2                                 
+#define ZQCS_CALPRD(n)                  ((n)&0x7FFF)
+#define ZQCS_CAL_EN                            (1<<31)
+
+//ZQSR;                   //SDRAM ZQ Status Register                                     
+//TPR3;                   //SDRAM Timing Parameters Register 3                           
+#define BL2                                            (0)
+#define BL4                                            (1)
+#define BL8                                            (2)
+#define BL16                                           (3)
+#define BLOTF_EN                               (1<<2)
+#define CL(n)                           (((n)&0xF)<<3)
+#define CWL(n)                          (((n)&0xF)<<7)
+#define WR(n)                           (((n)&0xF)<<11)
+#define AL(n)                           (((n)&0xF)<<15)
+
+//ALPMR;                  //Automatic Low Power Mode Register                            
+#define LPPERIOD_CLK_STOP(n)            ((n)&0xFF)
+#define LPPERIOD_POWER_DOWN(n)          (((n)&0xFF)<<8)
+#define AUTOCS                                 (1<<25)
+#define AUTOPD                                 (1<<26)
+
+//Reserved[0x7c-0x30];                                                                   
+//MR;                     //Mode Register                                                
+#define DDR_BL4                                (2)
+#define DDR_BL8                                (3)
+#define DDR_CL(n)         (((n)&0x7)<<4)
+#define DDR2_WR(n)        ((((n)-1)&0x7)<<9)
+
+//mr0 for ddr3
+#define DDR3_BL8          (0)
+#define DDR3_BC4_8        (1)
+#define DDR3_BC4          (2)
+#define DDR3_BL(n)        (n)
+#define DDR3_CL(n)        ((((n-4)&0x7)<<4)|(((n-4)&0x8)>>1))
+#define DDR3_MR0_CL(n)    ((((n-4)&0x7)<<4)|(((n-4)&0x8)>>1))
+#define DDR3_MR0_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_MR1_DIC(n) (((n&1)<<1)|((n&2)<<4))
+#define DDR3_MR1_RTT_NOM(n) (((n&1)<<2)|((n&2)<<5)|((n&4)<<7))
+
+//mr2 for ddr3
+#define DDR3_MR2_CWL(n) (((n-5)&0x7)<<3)
+
+//EMR;                    //Extended Mode Register      
+#define DDR2_STR_FULL                  (0)
+#define DDR2_STR_REDUCE                (1<<1)
+#define DDR2_AL(n)        (((n)&0x7)<<3)
+#define DDR2_ODT_DIS                   (0)
+#define DDR2_ODT_150                   (0x40)
+#define DDR2_ODT_75                    (0x4)
+#define DDR2_ODT_50                    (0x44)
+
+//EMR2;                   //Extended Mode Register 2                                     
+//EMR3;                   //Extended Mode Register 3                                     
+//y Management Unit Registers                                                            
+//HPCR[32];               //Host Port Configuration Register 0-31                        
+#define HPBL(n)                         ((n)&0xFF)
+#define HCBP                                           (1<<8)
+#define HNPC                                           (1<<9)
+
+//PQCR[8];                //Priority Queue Configuration Register 0-7                    
+#define TOUT(n)                         ((n)&0xFF)
+#define TOUT_MUL_1                             (0<<8)
+#define TOUT_MUL_16                     (1<<8)
+#define TOUT_MUL_64                     (2<<8)
+#define TOUT_MUL_256                   (3<<8)
+#define LPQS(n)                         (((n)&0x3)<<10)
+#define PQBL(n)                         (((n)&0xFF)<<12)
+#define SWAIT(n)                        (((n)&0x1F)<<20)
+#define INTRPT(n)                       (((n)&0x7)<<25)
+#define APQS                                           (1<<28)
+
+#define PLL_CLKR(i)    ((((i) - 1) & 0x1f) << 10)
+
+#define PLL_CLKF(i)    ((((i) - 1) & 0x7f) << 3)
+
+#define PLL_CLKOD(i)   (((i) & 0x03) << 1)
+
+//MMGCR;                  //Memory Manager General Configuration Register                
+#define PORT0_NORMAL_PRIO              (0)
+#define PORT0_HIGH_PRIO                (2)
+
+#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 DDR3_NONE   (22)
+
+#ifdef CONFIG_RK29_DDR3_TYPE
+#define DDR3_TYPE CONFIG_RK29_DDR3_TYPE
+#else
+#define DDR3_TYPE   DDR3_DEFAULT//DDR3_NONE
+#endif
+/* DDR Controller register struct */
+typedef volatile struct DDR_REG_Tag
+{
+    volatile unsigned int CCR;                    //Controller Configuration Register
+    volatile unsigned int DCR;                    //DRAM Configuration Register
+    volatile unsigned int IOCR;                   //IO Configuration Register
+    volatile unsigned int CSR;                    //Controller Status Register
+    volatile unsigned int DRR;                    //DRAM Refresh Register
+    volatile unsigned int TPR[3];                 //SDRAM Timing Parameters Registers
+    volatile unsigned int DLLCR;                  //Global DLL Control  Register
+    volatile unsigned int DLLCR09[10];            //DDR Control  Register 0-9
+    volatile unsigned int RSLR[4];                //Rank System Latency  Register 0-3
+    volatile unsigned int RDGR[4];                //Rank DQS Gating  Register 0-3
+    volatile unsigned int DQTR[9];                //DQ Timing  Register 0-8
+    volatile unsigned int DQSTR;                  //DQS Timing  Register
+    volatile unsigned int DQSBTR;                 //DQS_b Timing  Register
+    volatile unsigned int ODTCR;                  //ODT Configuration  Register
+    volatile unsigned int DTR[2];                 //Data Training Register 0-1
+    volatile unsigned int DTAR;                   //Data Training Address  Register
+    volatile unsigned int ZQCR[3];                //SDRAM ZQ Control Register and SDRAM ZQCS Control Register 0-2
+    volatile unsigned int ZQSR;                   //SDRAM ZQ Status Register
+    volatile unsigned int TPR3;                   //SDRAM Timing Parameters Register 3
+    volatile unsigned int ALPMR;                  //Automatic Low Power Mode Register
+    volatile unsigned int Reserved[0x7c-0x30];    
+    volatile unsigned int MR;                     //Mode Register
+    volatile unsigned int EMR;                    //Extended Mode Register
+    volatile unsigned int EMR2;                   //Extended Mode Register 2
+    volatile unsigned int EMR3;                   //Extended Mode Register 3
+    //Memory Management Unit Registers
+    volatile unsigned int HPCR[32];               //Host Port Configuration Register 0-31
+    volatile unsigned int PQCR[8];                //Priority Queue Configuration Register 0-7
+    volatile unsigned int MMGCR;                  //Memory Manager General Configuration Register
+}DDR_REG_T, *pDDR_REG_T;
+
+typedef struct tagGPIO_IOMUX
+{
+    volatile unsigned int GPIOL_IOMUX;
+    volatile unsigned int GPIOH_IOMUX;
+}GPIO_IOMUX_T;
+
+//GRF Registers
+typedef volatile struct tagREG_FILE
+{
+    volatile unsigned int GRF_GPIO_DIR[6]; 
+    volatile unsigned int GRF_GPIO_DO[6];
+    volatile unsigned int GRF_GPIO_EN[6];
+    GPIO_IOMUX_T GRF_GPIO_IOMUX[6];
+    volatile unsigned int GRF_GPIO_PULL[7];
+    volatile unsigned int GRF_UOC_CON[2];
+    volatile unsigned int GRF_USB_CON;
+    volatile unsigned int GRF_CPU_CON[2];
+    volatile unsigned int GRF_CPU_STATUS;
+    volatile unsigned int GRF_MEM_CON;
+    volatile unsigned int GRF_MEM_STATUS[3];
+    volatile unsigned int GRF_SOC_CON[5];
+    volatile unsigned int GRF_OS_REG[4];
+} REG_FILE, *pREG_FILE;
+
+//CRU Registers
+typedef volatile struct tagCRU_REG 
+{
+    volatile unsigned int CRU_APLL_CON; 
+    volatile unsigned int CRU_DPLL_CON;
+    volatile unsigned int CRU_CPLL_CON;
+    volatile unsigned int CRU_PPLL_CON;
+    volatile unsigned int CRU_MODE_CON;
+    volatile unsigned int CRU_CLKSEL_CON[18];
+    volatile unsigned int CRU_CLKGATE_CON[4];
+    volatile unsigned int CRU_SOFTRST_CON[3];
+} CRU_REG, *pCRU_REG;
+
+// controller base address
+#define pDDR_Reg           ((pDDR_REG_T)RK29_DDRC_BASE)
+#define pGRF_Reg        ((pREG_FILE)RK29_GRF_BASE)
+#define pSCU_Reg        ((pCRU_REG)RK29_CRU_BASE)
+
+typedef struct DDR_CONFIG_Tag
+{
+    u32 row;
+    u32 bank;
+    u32 col;
+    u32 config;
+}DDR_CONFIG_T;
+
+uint32_t ddrDataTraining[16];
+
+DDR_CONFIG_T    ddrConfig[3][10] = {
+    //row, bank, col, config
+    {
+        //DDR2
+        // x16
+        {15, 8, 10, (DIO_16 | DSIZE_4Gb)},
+        {14, 8, 10, (DIO_16 | DSIZE_2Gb)},
+        {13, 8, 10, (DIO_16 | DSIZE_1Gb)},
+        {13, 4, 10, (DIO_16 | DSIZE_512Mb)},
+        {13, 4, 9,  (DIO_16 | DSIZE_256Mb)},
+        // x8
+        {16, 8, 10, (DIO_8  | DSIZE_4Gb)},
+        {15, 8, 10, (DIO_8  | DSIZE_2Gb)},
+        {14, 8, 10, (DIO_8  | DSIZE_1Gb)},
+        {14, 4, 10, (DIO_8  | DSIZE_512Mb)},
+        {13, 4, 10, (DIO_8  | DSIZE_256Mb)},
+    },
+    {
+        //DDR3
+        // x16
+        {16, 8, 10, (DIO_16 | DSIZE_8Gb)},
+        {15, 8, 10, (DIO_16 | DSIZE_4Gb)},
+        {14, 8, 10, (DIO_16 | DSIZE_2Gb)},
+        {13, 8, 10, (DIO_16 | DSIZE_1Gb)},
+        {12, 8, 10, (DIO_16 | DSIZE_512Mb)},
+        // x8
+        {16, 8, 11, (DIO_16 | DSIZE_8Gb)},
+        {16, 8, 10, (DIO_16 | DSIZE_4Gb)},
+        {15, 8, 10, (DIO_16 | DSIZE_2Gb)},
+        {14, 8, 10, (DIO_16 | DSIZE_1Gb)},
+        {13, 8, 10, (DIO_16 | DSIZE_512Mb)},
+    },
+    {
+               //mobile DDR
+        // x32
+        {14, 4, 10, (DIO_32 | DSIZE_2Gb)},
+        {13, 4, 10, (DIO_32 | DSIZE_1Gb)},
+        {13, 4, 9,  (DIO_32 | DSIZE_512Mb)},
+        {12, 4, 9,  (DIO_32 | DSIZE_256Mb)},
+        // x16
+        {14, 4, 11, (DIO_16 | DSIZE_2Gb)},
+        {14, 4, 10, (DIO_16 | DSIZE_1Gb)},
+        {13, 4, 10, (DIO_16 | DSIZE_512Mb)},
+        {13, 4, 9,  (DIO_16 | DSIZE_256Mb)},
+        {12, 4, 9,  (DIO_16 | DSIZE_128Mb)},
+        {0,  0, 0,  0},
+    }
+};
+
+uint32_t __sramdata ddr3_cl_cwl[22][3]={
+/*   0~330           330~400         400~533        speed
+* tCK  >3             2.5~3          1.875~2.5
+*    cl<<16, cwl    cl<<16, cwl     cl<<16, cwl              */
+    {((5<<16)|5),   ((5<<16)|5),    0        }, //DDR3_800D
+    {((5<<16)|5),   ((6<<16)|5),    0        }, //DDR3_800E
+    
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_1066E
+    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6) }, //DDR3_1066F
+    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6) }, //DDR3_1066G
+    
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_1333F
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6) }, //DDR3_1333G
+    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6) }, //DDR3_1333H
+    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6) }, //DDR3_1333J
+    
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_1600G
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_1600H
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6) }, //DDR3_1600J
+    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6) }, //DDR3_1600K
+    
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_1866J
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6) }, //DDR3_1866K
+    {((6<<16)|5),   ((6<<16)|5),    ((7<<16)|6) }, //DDR3_1866L
+    {((6<<16)|5),   ((6<<16)|5),    ((8<<16)|6) }, //DDR3_1866M
+    
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_2133K
+    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6) }, //DDR3_2133L
+    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6) }, //DDR3_2133M
+    {((6<<16)|5),   ((6<<16)|5),    ((7<<16)|6) },  //DDR3_2133N
+
+    {((6<<16)|5),   ((6<<16)|5),    ((8<<16)|6) } //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;
+static __sramdata uint32_t capability;  // one chip cs capability
+
+//DDR2
+static __sramdata uint32_t tRFC;
+static __sramdata uint32_t tRFPRD;
+static __sramdata uint32_t tRTP;
+static __sramdata uint32_t tWTR;
+static __sramdata uint32_t tRAS;
+static __sramdata uint32_t tRRD;
+static __sramdata uint32_t tRC;
+static __sramdata uint32_t tFAW;
+//Mobile-DDR
+static __sramdata uint32_t tXS;
+static __sramdata uint32_t tXP;
+//DDR3
+static __sramdata uint32_t tWR;
+static __sramdata uint32_t tWR_MR0;
+static __sramdata uint32_t cl;
+static __sramdata uint32_t cwl;
+
+static __sramdata uint32_t cpu_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 
+void __sramlocalfunc delayus(uint32_t us)
+{      
+     uint32_t count;
+     if(cpu_freq == 600)
+         count = us * 150;//533;
+     else
+        count = us*6;
+     while(count--)  // 3 cycles
+               barrier();
+
+}
+
+static uint32_t __sramlocalfunc ddr_get_parameter(uint32_t nMHz)
+{
+    uint32_t tmp;
+    uint32_t ret = 0;
+    if(nMHz>533)
+    {
+        ret = -1;
+        goto out;
+    }
+    if(mem_type == DDR3)
+    {
+        if(DDR3_TYPE == DDR3_NONE)
+        {
+            ret = -2;
+            goto out;
+        }
+        /* 
+         * tREFI, average periodic refresh interval, 7.8us max
+         */
+        tRFPRD = ((59*nMHz) >> 3) & 0x3FFF;  // 62/8 = 7.75us
+
+        if(capability <= 0x4000000)         // 512Mb 90ns
+        {
+            tmp = (90*nMHz+999)/1000;
+        }
+        else if(capability <= 0x8000000)    // 1Gb 110ns
+        {
+            tmp = (110*nMHz+999)/1000;
+        }
+        else if(capability <= 0x10000000)   // 2Gb 160ns
+        {
+            tmp = (160*nMHz+999)/1000;
+        }
+        else if(capability <= 0x20000000)   // 4Gb 300ns
+        {
+            tmp = (300*nMHz+999)/1000;
+        }
+        else    // 8Gb  350ns
+        {
+            tmp = (350*nMHz+999)/1000;
+        }
+        /*
+         * tRFC DRR[7:0]
+         */
+        if(tmp > 0xff)
+        {
+            ret = -2;
+            goto out;
+        }
+        else 
+            tRFC = tmp;
+        
+        /*
+         * tRTP = max(4nCK,7.5ns), TPR0[4:2], valid values are 2~6
+         * tWTR = max(4nCK,7.5ns), TPR0[7:5], valid values are 1~6
+         * clock must <533MHz, then tRTP=tWTR=4
+         */
+        tRTP = 4;
+        tWTR = 4;
+
+        /*
+         * tRAS = 33/37.5~9*tREFI, 
+         * TPR0[20:16], valid values are 2~31
+         */
+        tRAS = (38*nMHz+999)/1000;
+            
+        /*
+         * 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)
+         *  
+         * TPR0[24:21], valid values are 1~8
+         */
+        tRRD = (10*nMHz+999)/1000;
+        
+        /*
+         * tRC  TPR0[30:25], valid values are 2~42
+         */
+        tRC = ((ddr3_tRC_tFAW[DDR3_TYPE]>>16)*nMHz+999)/1000;
+        
+        /*
+         * tFAW TPR1[8:3], valid values are 2~31
+         */
+        tFAW = ((ddr3_tRC_tFAW[DDR3_TYPE]&0x0ff)*nMHz+999)/1000;
+        
+        /*
+         * tXS TPR2[9:0], valid values are 2~1023
+         * MAX(tXS, tXSDLL) for DDR3, tXSDLL = tDLLK = 512CK
+         */
+        tXS = 512;
+        
+        /*
+         *       max(tXP, tXPDLL) for DDR3
+         * tXP = max(3nCK, 7.5ns), DDR3-800, DDR3-1066
+         *       max(3nCK, 6ns), DDR3-1333, DDR3-1600, DDR3-1866, DDR3-2133
+         * tXPDLL = max(10nCK, 24ns)
+         * TPR2[14:10], valid values are 2~31
+         */
+        if(nMHz <= 330)
+        {
+            tmp = 0;
+            tXP = 10;
+        }
+        else if(nMHz<=400)
+        {
+            tmp = 1;
+            tXP = 10;
+        }
+        else    // 533 MHz
+        {
+            tmp = 2;
+            tXP = 13;
+        }
+        
+        /*
+         * tWR TPR3[14:11], valid values are 2~12, 15ns
+         */
+        tWR = (15*nMHz+999)/1000;
+        if(tWR<9)
+            tWR_MR0 = tWR - 4;
+        else
+            tWR_MR0 = tWR>>1;
+
+        cl = ddr3_cl_cwl[DDR3_TYPE][tmp] >> 16;
+        cwl = ddr3_cl_cwl[DDR3_TYPE][tmp] & 0x0ff; 
+    }
+    else if(mem_type == DDRII)
+    {
+        /* 
+         * tREFI, average periodic refresh interval, 7.8us max
+         */
+        tRFPRD = ((59*nMHz) >> 3) & 0x3FFF;  // 62/8 = 7.75us
+        
+        if(capability <= 0x2000000)  // 256Mb
+        {
+            tmp = (75*nMHz/1000) + ((((75*nMHz)%1000) > 0) ? 1:0);
+        }
+        else if(capability <= 0x4000000) // 512Mb
+        {
+            tmp = (105*nMHz/1000) + ((((105*nMHz)%1000) > 0) ? 1:0);
+        }
+        else if(capability <= 0x8000000)  // 1Gb
+        {
+            tmp = (128*nMHz/1000) + ((((128*nMHz)%1000) > 0) ? 1:0);
+        }
+        else  // 4Gb
+        {
+            tmp = (328*nMHz/1000) + ((((328*nMHz)%1000) > 0) ? 1:0);
+        }
+        //tRFC = 75ns(256Mb)/105ns(512Mb)/127.5ns(1Gb)/327.5ns(4Gb)
+        tmp = (tmp > 0xFF) ? 0xFF : tmp;
+        tRFC = tmp;
+        // tRTP = 7.5ns
+        tmp = (8*nMHz/1000) + ((((8*nMHz)%1000) > 0) ? 1:0);
+        tmp = (tmp > 6) ? 6 : tmp;
+        tmp = (tmp < 2) ? 2 : tmp;
+        tRTP = tmp;
+        //tWTR = 10ns(DDR2-400), 7.5ns (DDR2-533/667/800)
+        if(nMHz <= 200)
+        {
+            tmp = (10*nMHz/1000) + ((((10*nMHz)%1000) > 0) ? 1:0);
+        }
+        else
+        {
+            tmp = (8*nMHz/1000) + ((((8*nMHz)%1000) > 0) ? 1:0);
+        }
+        tmp = (tmp > 6) ? 6 : tmp;
+        tmp = (tmp < 1) ? 1 : tmp;
+        tWTR = tmp;
+        //tRAS_min = 45ns
+        tmp = (45*nMHz/1000) + ((((45*nMHz)%1000) > 0) ? 1:0);
+        tmp = (tmp > 31) ? 31 : tmp;
+        tmp = (tmp < 2) ? 2 : tmp;
+        tRAS = tmp;
+        // tRRD = 10ns
+        tmp = (10*nMHz/1000) + ((((10*nMHz)%1000) > 0) ? 1:0);
+        tmp = (tmp > 8) ? 8 : tmp;
+        tmp = (tmp < 1) ? 1 : tmp;
+        tRRD = tmp;
+        if(nMHz <= 200)  //tRC = 65ns
+        {
+            tmp = (65*nMHz/1000) + ((((65*nMHz)%1000) > 0) ? 1:0);
+        }
+        else //tRC = 60ns
+        {
+            tmp = (60*nMHz/1000) + ((((60*nMHz)%1000) > 0) ? 1:0);
+        }
+        tmp = (tmp > 42) ? 42 : tmp;
+        tmp = (tmp < 2) ? 2 : tmp;
+        tRC = tmp;
+        //tFAW = 50ns
+        tmp = (50*nMHz/1000) + ((((50*nMHz)%1000) > 0) ? 1:0);
+        tmp = (tmp > 31) ? 31 : tmp;
+        tmp = (tmp < 2) ? 2 : tmp;
+        tFAW = tmp;
+        if(nMHz <= 333)
+        {
+            tXP = 7;
+        }
+        else
+        {
+            tXP = 8;
+        }
+       // don't need to modify tXS, tWR, tWR_MR0, cwl
+       
+        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;
+    }
+    else
+    {
+    }
+out:
+    return ret;
+}
+static uint32_t __sramlocalfunc ddr_update_timing(void)
+{
+    uint32_t value;
+    if(mem_type == DDR3)
+    {
+        pDDR_Reg->DRR = TRFC(tRFC) | TRFPRD(tRFPRD) | RFBURST(1);
+        value = pDDR_Reg->TPR[0];
+        value &= ~((0x7<<2)|(0x7<<5)|(0x1F<<16)|(0xF<<21)|(0x3F<<25));
+        pDDR_Reg->TPR[0] = value | TRTP(tRTP) | TWTR(tWTR) | TRAS(tRAS) | TRRD(tRRD) | TRC(tRC);
+        value = pDDR_Reg->TPR[1];
+        value &= ~(0x3F<<3);
+        pDDR_Reg->TPR[1] = value | TFAW(tFAW);
+        // ddr3 tCKE should be tCKESR=tCKE+1nCK
+        pDDR_Reg->TPR[2] = TXS(tXS) | TXP(tXP) | TCKE(4);//0x198c8;//       
+        
+    }
+    else if(mem_type == DDRII)
+    {
+             pDDR_Reg->DRR = TRFC(tRFC) | TRFPRD(tRFPRD) | RFBURST(1);
+        value = pDDR_Reg->TPR[0];
+        value &= ~((0x7<<2)|(0x7<<5)|(0x1F<<16)|(0xF<<21)|(0x3F<<25));
+        pDDR_Reg->TPR[0] = value | TRTP(tRTP) | TWTR(tWTR) | TRAS(tRAS) | TRRD(tRRD) | TRC(tRC);
+        value = pDDR_Reg->TPR[1];
+        value &= ~(0x3F<<3);
+        pDDR_Reg->TPR[1] = value | TFAW(tFAW);
+        value = pDDR_Reg->TPR[2];
+        value &= ~(0x1F<<10);
+        pDDR_Reg->TPR[2] = value | TXP(tXP);
+    }
+    return 0;
+}
+
+static uint32_t __sramlocalfunc ddr_update_mr(void)
+{
+    uint32_t value;
+    value = pDDR_Reg->TPR[0];
+    value &= ~(0x0FF<<8);
+    pDDR_Reg->TPR[0] = value | TRP(cl) | TRCD(cl);
+    value = pDDR_Reg->TPR3;
+    value &= ~((0xF<<3)|(0xF<<7)|(0xF<<11));
+       
+    if(mem_type == DDR3)
+    {
+        pDDR_Reg->TPR3 = value | CL(cl) | CWL(cwl) | WR(tWR);
+        pDDR_Reg->MR = DDR3_BL8 | DDR3_CL(cl) | DDR3_MR0_WR(tWR_MR0)/*15 ns*/;
+        delayus(1);
+        pDDR_Reg->EMR2 = DDR3_MR2_CWL(cwl);
+    }
+    else if(mem_type == DDRII)
+    {
+        pDDR_Reg->TPR3 = value | CL(cl) | CWL(cwl) | WR(cl);
+        //set mode register cl
+        value = pDDR_Reg->MR;
+        value &= ~((0x7<<4)|(0x7<<9));
+        pDDR_Reg->MR = value | DDR_CL(cl) | DDR2_WR(cl);       
+    }
+    return 0;
+}
+static __sramdata uint32_t clkr;
+static __sramdata uint32_t clkf;
+static __sramdata uint32_t clkod;
+static __sramdata uint32_t pllband = 0;
+static uint32_t __sramlocalfunc ddr_set_pll(uint32_t nMHz, uint32_t set)
+{
+    uint32_t ret = 0;
+    uint32_t temp;
+    
+   // ddr_print("%s \n", __func__);
+    if(nMHz == 24)
+    {
+        ret = 24;
+        goto out;
+    }
+    
+    if(!set)
+    {
+        pllband = 0;
+        if (nMHz<38)
+        {
+            nMHz = 38;
+            clkr = 1;
+            clkod = 3;
+        }
+        else if(nMHz <= 75 )
+        {
+            clkr = 1;
+            clkod = 3;
+        }
+        else if (nMHz <= 150)
+        {
+            clkr = 2;
+            clkod = 2;
+        }
+        else if (nMHz <= 300)
+        {
+            clkr = 2;
+            clkod = 1;
+        }
+        else if(nMHz <= 600)
+        {
+            clkr = 2;
+            clkod = 0;
+        }
+        else
+        {
+            clkr = 2;
+            clkod = 0;
+            pllband = (0x01u<<16);
+        }
+        temp = nMHz*clkr*(1<<clkod);
+        clkf = temp/24;
+        //if(temp%24)
+        //    clkf += 1;
+        ret = ((24*clkf)>>(clkr-1))>>clkod;
+    }
+    else
+    {
+         // ddr slow
+        pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);
+        
+        pSCU_Reg->CRU_DPLL_CON |= (0x1 << 15); //power down pll
+        delayus(1);  //delay at least 500ns
+        pSCU_Reg->CRU_DPLL_CON = pllband | (0x1<<15) |(PLL_CLKR(clkr))|(PLL_CLKF(clkf))|(PLL_CLKOD(clkod));
+
+        delayus(1);  //delay at least 500ns
+        pSCU_Reg->CRU_DPLL_CON &= ~(0x1<<15);
+        delayus(2000); // 7.2us*140=1.008ms
+
+        // ddr pll normal
+        pSCU_Reg->CRU_MODE_CON |= 0x1<<6;
+
+        // ddr_pll_clk: clk_ddr=1:1    
+        temp = pSCU_Reg->CRU_CLKSEL_CON[7];
+        temp &= ~(0x1F<<24);
+        pSCU_Reg->CRU_CLKSEL_CON[7] = temp;
+        delayus(1);
+    }
+out:
+    return ret;
+}
+
+
+void __sramlocalfunc ddr_selfrefresh_enter(void)
+{
+    /* 1. disables all host ports
+       2. Flushes the MCTL pipelines (including current automatically-scheduled refreshes)
+       3. Disables automatic scheduling of refreshes
+       4. Issues a Precharge All command
+       5. Waits for tRP clocks (programmable in TPR0 register)
+       6. Issues a Self-Refresh command
+       7. Clears the self-clearing bit DCR.EXE and waits for Mode Exit command
+     */
+    
+    //ddr_print("%s \n", __func__);
+    pDDR_Reg->CCR &= ~HOSTEN;  //disable host port
+    pDDR_Reg->CCR |= FLUSH;    //flush
+    delayus(10);
+    pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<24) | (0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x2<<27) | (0x1<<31));  //enter Self Refresh
+    delayus(1000); //wait for exit self refresh dll lock
+    pSCU_Reg->CRU_SOFTRST_CON[0] |= (0x1F<<19);  //reset DLL
+    delayus(10);
+}
+void __sramlocalfunc ddr_selfrefresh_exit(void)
+{
+    /* 1. Exits self-refresh when a Mode-Exit command is received
+       2. Waits for tXS clocks (programmable in TPR2 register)
+       3. Issues a Refresh command
+       4. Waits for tRFC clocks (programmable in DRR)
+       5. Clears the self-clearing bit DCR.EXE
+       6. Re-enables all host ports
+     */
+    pSCU_Reg->CRU_SOFTRST_CON[0] &= ~(0x1F<<19);
+    delayus(10); //wait for exit self refresh dll lock
+    pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<24) | (0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x7<<27) | (0x1<<31)); //exit    
+    delayus(10);
+    ddr_update_mr();
+    delayus(10);
+
+    // SDRAM ZQ Calibration Short
+   // pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<24) | (0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0xb<<27) | (0x1<<31)); 
+    //delayus(10); 
+
+refresh:
+    pDDR_Reg->DRR |= RD;
+    delayus(1);
+    pDDR_Reg->CCR |= DTT;
+    delayus(15);
+    //pDDR_Reg->DRR &= ~RD;
+    pDDR_Reg->DRR = TRFC(tRFC) | TRFPRD(tRFPRD) | RFBURST(8);
+    delayus(10);
+    pDDR_Reg->DRR = TRFC(tRFC) | TRFPRD(tRFPRD) | RFBURST(1);
+    delayus(10);
+    if(pDDR_Reg->CSR & 0x100000)
+    {
+        pDDR_Reg->CSR &= ~0x100000;
+        goto refresh;
+    }
+    pDDR_Reg->CCR |= HOSTEN;  //enable host port
+}
+
+void __sramfunc ddr_change_freq(uint32_t nMHz)
+{
+    uint32_t ret;
+       volatile u32 n; 
+    unsigned long flags;
+    volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
+
+    local_irq_save(flags);
+    //ddr_print("%s enter\n", __func__);
+    cpu_freq = clk_get_rate(clk_get(NULL,"core"));
+    cpu_freq = cpu_freq/1000000;
+    
+    ret = ddr_set_pll(nMHz, 0);
+    ddr_get_parameter(ret);
+    //while(test);
+    /** 1. Make sure there is no host access */
+#if 1
+    flush_cache_all();
+    __cpuc_flush_kern_all();
+    __cpuc_flush_user_all();
+    DDR_SAVE_SP(save_sp);
+    n=temp[0];
+    barrier();
+    n=temp[1024];
+    barrier();
+    n=temp[1024*2];
+    barrier();
+    n=temp[1024*3];
+    barrier();
+    n= pDDR_Reg->CCR;
+    n= pSCU_Reg->CRU_SOFTRST_CON[0];
+    dsb();
+#endif
+    
+    /** 2. ddr enter self-refresh mode or precharge power-down mode */
+    ddr_selfrefresh_enter();
+    delayus(100);
+    /** 3. change frequence  */
+    ddr_set_pll(ret, 1);
+
+    /** 4. update timing&parameter  */
+    ddr_update_timing();
+
+    /** 5. Issues a Mode Exit command   */
+    ddr_selfrefresh_exit();
+       dsb(); 
+    
+    DDR_RESTORE_SP(save_sp);
+    local_irq_restore(flags);
+    //ddr_print("%s exit\n", __func__);
+}
+void __sramfunc ddr_suspend(void)
+{
+    uint32_t n;
+    volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
+
+    //cpu_freq = clk_get_rate(clk_get(NULL,"core"));
+    //cpu_freq = cpu_freq/1000000;
+    cpu_freq = 24;
+       
+    //while(test);
+    /** 1. Make sure there is no host access */
+    flush_cache_all();
+    __cpuc_flush_kern_all();
+    __cpuc_flush_user_all();
+
+    n=temp[0];
+    barrier();
+    n=temp[1024];
+    barrier();
+    n=temp[1024*2];
+    barrier();
+    n=temp[1024*3];
+    barrier();
+    n= pDDR_Reg->CCR;
+    n= pSCU_Reg->CRU_SOFTRST_CON[0];
+    dsb();
+
+    ddr_selfrefresh_enter();
+
+    pSCU_Reg->CRU_CLKGATE_CON[0] |= (0x1<<18);  //close DDR PHY clock  / DDR CPU AXI clock / DDR REG AXI clock
+    delayus(10);
+    // ddr slow
+    pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);
+    delayus(10);       
+    pSCU_Reg->CRU_DPLL_CON |= (0x1 << 15);  //power down DPLL
+    delayus(10);  //delay at least 500ns
+
+}
+void __sramfunc ddr_resume(void)
+{
+    uint32_t value;
+#if 1
+     pSCU_Reg->CRU_DPLL_CON &= ~(0x1 << 15);  //power on DPLL   
+    //   while(!(pGRF_Reg->GRF_SOC_CON[0] & (1<<28)));
+     delayus(200); // 7.2us*140=1.008ms // Ëø¶¨pll
+    // ddr pll normal
+    value = pSCU_Reg->CRU_MODE_CON;
+    value &=~(0x3<<6);
+    value |= 0x1<<6;
+    pSCU_Reg->CRU_MODE_CON = value;
+    delayus(10);       
+    pSCU_Reg->CRU_CLKGATE_CON[0] &= ~(0x1<<18);  //enable DDR PHY clock / DDR CPU AXI clock / DDR REG AXI clock
+    delayus(10);    
+#endif
+
+    ddr_selfrefresh_exit();
+       dsb(); 
+}
+static void inline ddr_change_host_priority(void)
+{
+    /*
+        DMC AXI host N priority
+        00:higheset priority
+        01:second high priority
+        10:third high priority
+        
+        GRF_MEM_CON[1:0]: CPU       (host 0)
+                   [3:2]: PERI      (host 1)
+                   [5:4]: DISPLAY   (host 2)
+                   [7:6]: GPU       (host 3)
+                   [9:8]: VCODEC    (host 4)
+    */
+    pGRF_Reg->GRF_MEM_CON = (pGRF_Reg->GRF_MEM_CON & ~0x3FF) | ((2<<0)|(1<<2)|(0<<4)|(1<<6)|(2<<8));
+}
+static int __init ddr_probe(void)
+{
+    volatile uint32_t value = 0;
+       uint32_t          addr;
+    uint32_t          MHz;
+    unsigned long Hz;
+    uint32_t          bw;
+    uint32_t          col = 0;
+    uint32_t          row = 0;
+    uint32_t          bank = 0;
+    uint32_t          n;
+
+    ddr_print("%s \n", __func__);
+
+    mem_type = (pDDR_Reg->DCR & 0x3);
+//    ddr_debug = 0;
+
+    // caculate aglined physical address 
+    addr =  __pa((unsigned long)ddrDataTraining);
+    if(addr&0x1F)
+    {
+        addr += (32-(addr&0x1F));
+    }
+    addr -= 0x60000000;
+    // caculate data width
+    bw = ((((pDDR_Reg->DCR >> 7) & 0x7)+1)>>1);
+    // find out col£¬row£¬bank
+    for(n=0;n<10; n++)
+    {
+        if(ddrConfig[(pDDR_Reg->DCR & 0x3)][n].config == (pDDR_Reg->DCR & 0x7c))
+        {
+            col = ddrConfig[(pDDR_Reg->DCR & 0x3)][n].col;
+            row = ddrConfig[(pDDR_Reg->DCR & 0x3)][n].row;
+            bank = ddrConfig[(pDDR_Reg->DCR & 0x3)][n].bank;
+            bank >>= 2;  // 8=>3, 4=>2
+            bank += 1;
+            break;
+        }
+    }
+    if(n == 10)
+    {
+        //ASSERT
+    }
+
+    // according different address mapping, caculate DTAR register value
+    value = pDDR_Reg->DTAR;
+    value &= ~(0x7FFFFFFF);
+    switch(pDDR_Reg->DCR & (0x3<<14))
+    {
+        case AMAP_RBRC:
+            value |= (addr>>bw) & ((0x1<<col)-1);  // col
+            value |= ((addr>>(bw+col)) & ((0x1<<row)-1)) << 12;  // row
+            value |= ((addr>>(bw+col+row)) & ((0x1<<bank)-1)) << 28;  // bank
+            break;
+        case AMAP_RRBC:
+            value |= (addr>>bw) & ((0x1<<col)-1);  // col
+            value |= ((addr>>(bw+col+bank)) & ((0x1<<row)-1)) << 12;  // row
+            value |= ((addr>>(bw+col)) & ((0x1<<bank)-1)) << 28;  // bank
+            break;
+        case AMAP_BRRC:
+            value |= (addr>>bw) & ((0x1<<col)-1);  // col
+            if((pDDR_Reg->DCR >> 11) & 0x3)
+            {
+                value |= ((addr>>(bw+col+1)) & ((0x1<<row)-1)) << 12;  // row
+                value |= ((addr>>(bw+col+row+1)) & ((0x1<<bank)-1)) << 28;  // bank
+            }
+            else
+            {
+                value |= ((addr>>(bw+col)) & ((0x1<<row)-1)) << 12;  // row
+                value |= ((addr>>(bw+col+row)) & ((0x1<<bank)-1)) << 28;  // bank
+            }
+            break;
+        case AMAP_FIX:    // can not support AMAP_FIX mode 
+        default:
+            break;
+    }
+    pDDR_Reg->DTAR = value;
+
+    if((mem_type == DDRII) || (mem_type == DDR3))
+    {
+        pDDR_Reg->ALPMR = LPPERIOD_POWER_DOWN(0xFF);// | AUTOPD;
+    }
+    else
+    {
+        pDDR_Reg->ALPMR = LPPERIOD_CLK_STOP(0xFF) | LPPERIOD_POWER_DOWN(0xFF) | AUTOCS | AUTOPD;
+    }
+    ddr_change_host_priority();
+    value = (((pDDR_Reg->DCR >> 7) & 0x7)+1) >> ((pDDR_Reg->DCR >> 2) & 0x3);
+    capability = 0x800000 << (((pDDR_Reg->DCR >> 4) & 0x7) + value + ((pDDR_Reg->DCR >> 11) & 0x3));
+
+    Hz = clk_get_rate(clk_get(NULL,"ddr"));
+    MHz = Hz/1000000;
+    
+    ddr_change_freq(MHz);
+    ddr_print("ddr pll freq=%dMHz\n", MHz);
+
+   return 0;
+}
+core_initcall_sync(ddr_probe);
old mode 100644 (file)
new mode 100755 (executable)
index 9fbf1bf..db339c4
@@ -7,6 +7,8 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/suspend.h>
+#include <linux/random.h> 
+#include <linux/crc32.h>
 #ifdef CONFIG_RK29_PWM_REGULATOR
 #include <linux/regulator/rk29-pwm-regulator.h>
 #endif
@@ -44,9 +46,11 @@ static inline void delay_300us(void)
 
 extern void ddr_suspend(void);
 extern void ddr_resume(void);
+extern void delayus(uint32_t us);
+extern void ddr_change_freq(uint32_t nMHz);
 
 #ifdef DEBUG
-static void inline printch(char byte)
+static void/* inline*/ __sramfunc printch(char byte)
 {
        unsigned long flags;
        u32 gate1, gate2;
@@ -79,7 +83,7 @@ static void inline printascii(const char *s)
        }
 }
 
-static void inline printhex(unsigned int hex)
+static void /* inline*/ __sramfunc printhex(unsigned int hex)
 {
        int i = 8;
        printch('0');
@@ -132,11 +136,96 @@ static void __sramfunc rk29_set_core_voltage(int uV)
        cru_writel(gate1, CRU_CLKGATE1_CON);
 }
 #endif /* CONFIG_RK29_PWM_REGULATOR */
+/*volatile __sramdata */int ddr_debug;
+module_param(ddr_debug, int, 0644);
+#if 1
+static int inline calc_crc32(u32 addr, size_t len)
+{
+     return crc32_le(~0,(const unsigned char *)addr,len);
+}
+void __sramfunc ddr_testmode(void)
+{    
+    int32_t g_crc1,g_crc2;
+    uint32_t nMHz;
+    uint32_t n = 0;
+    extern char _stext[], _etext[];
+    if(ddr_debug == 1)
+    {
+        for (;;)
+        {
+               printch(' ');
+               printch('8');
+               printch('8');
+               printch('8');
+               printch(' ');
+            g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
+            nMHz = 333 + (random32()>>25);
+            if(nMHz > 402)
+                nMHz = 402;
+               printhex(nMHz);
+               printch(' ');
+               printhex(n++);
+            //ddr_print("%s change freq to: %d MHz\n", __func__, nMHz);
+            ddr_change_freq(nMHz);
+            g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
+            if (g_crc1!=g_crc2)
+            {
+                   printch(' ');
+                   printch('f');
+                   printch('a');
+                   printch('i');
+                   printch('l');
+               }
+               //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
+           //     printascii("change freq success\n");
+        }
+    }
+    else if(ddr_debug == 2)
+    {
+        for (;;)
+        {
+               printch(' ');
+               printch('9');
+               printch('9');
+               printch('9');
+               printch(' ');
+            g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
+            nMHz = (random32()>>13);// 16.7s max
+            ddr_suspend();
+            delayus(nMHz);
+            ddr_resume();
+               printhex(nMHz);
+               printch(' ');
+               printhex(n++);
+            g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
+            if (g_crc1!=g_crc2)
+            {
+                   printch(' ');
+                   printch('f');
+                   printch('a');
+                   printch('i');
+                   printch('l');
+               }
+              // ddr_print("check image crc32 fail!, count:%d\n", n++);
+            //    printascii("self refresh fail\n");
+            //else
+               //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
+            //    printascii("self refresh success\n");
+        }
+    }
+    
+}
+#else
+void __sramfunc ddr_testmode(void)
+{}
 
+#endif 
 static void __sramfunc rk29_sram_suspend(void)
 {
        u32 clksel0;
 
+    if(ddr_debug)
+        ddr_testmode();
        printch('5');
        ddr_suspend();
 
@@ -350,6 +439,7 @@ static int __init rk29_pm_init(void)
 
        /* set idle function */
        pm_idle = rk29_idle;
+       ddr_debug = 0;
 
        return 0;
 }