-/****************************************************************\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¶meter */
+ 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);