--- /dev/null
+/****************************************************************\r
+* CopyRight(C) 2010 by Rock-Chip Fuzhou\r
+* All Rights Reserved\r
+* ÎļþÃû:ddr.c\r
+* ÃèÊö: ddr driver implement\r
+* ×÷Õß:hcy\r
+* ´´½¨ÈÕÆÚ:2011-01-04\r
+* ¸ü¸Ä¼Ç¼:\r
+* $Log: ddr.c,v $\r
+* µ±Ç°°æ±¾: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
+//#include <linux/module.h>\r
+//#include <linux/device.h>\r
+//#include <linux/err.h>\r
+\r
+\r
+\r
+unsigned long save_sp;\r
+#define DDR_SAVE_SP do { save_sp = ddr_save_sp((SRAM_DATA_END&(~7))); } while (0)\r
+#define DDR_RESTORE_SP do { ddr_save_sp(save_sp); } while (0)\r
+//unsigned long ddr_save_sp( unsigned long new_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
+/* 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; //µ¥¸öCSµÄÈÝÁ¿\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
+#if 0\r
+asm( \r
+" .section \".sram.text\",\"ax\"\n" \r
+" .align\n"\r
+" .type ddr_save_sp, #function\n"\r
+" .global ddr_save_sp\n"\r
+"ddr_save_sp:\n"\r
+" mov r1,sp\n" \r
+" mov sp,r0\n" \r
+" mov r0,r1\n" \r
+" mov pc,lr\n"\r
+" .previous"\r
+);\r
+#endif\r
+\r
+/****************************************************************************\r
+ÄÚ²¿sram µÄus ÑÓʱº¯Êý\r
+¼Ù¶¨cpu ×î¸ßƵÂÊ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
+//º¯ÊýÃû:SDRAM_EnterSelfRefresh\r
+//ÃèÊö:SDRAM½øÈë×ÔË¢ÐÂģʽ\r
+//²ÎÊý˵Ã÷:\r
+//·µ»ØÖµ:\r
+//Ïà¹ØÈ«¾Ö±äÁ¿:\r
+//×¢Òâ:(1)ϵͳÍêÈ«idleºó²ÅÄܽøÈë×ÔË¢ÐÂģʽ£¬½øÈë×Ôˢкó²»ÄÜÔÙ·ÃÎÊSDRAM\r
+// (2)Òª½øÈë×ÔË¢ÐÂģʽ£¬±ØÐë±£Ö¤ÔËÐÐʱÕâ¸öº¯ÊýËùµ÷Óõ½µÄËùÓдúÂë²»ÔÚSDRAMÉÏ\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<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x2<<27) | (0x1<<31)); //enter Self Refresh\r
+ delayus(10);\r
+}\r
+\r
+/****************************************************************/\r
+//º¯ÊýÃû:SDRAM_ExitSelfRefresh\r
+//ÃèÊö:SDRAMÍ˳ö×ÔË¢ÐÂģʽ\r
+//²ÎÊý˵Ã÷:\r
+//·µ»ØÖµ:\r
+//Ïà¹ØÈ«¾Ö±äÁ¿:\r
+//×¢Òâ:(1)SDRAMÔÚ×ÔË¢ÐÂģʽºó²»Äܱ»·ÃÎÊ£¬±ØÐëÏÈÍ˳ö×ÔË¢ÐÂģʽ\r
+// (2)±ØÐë±£Ö¤ÔËÐÐʱÕâ¸öº¯ÊýµÄ´úÂë²»ÔÚSDRAMÉÏ\r
+/****************************************************************/\r
+void __sramfunc ExitDDRSelfRefresh(void)\r
+{\r
+ volatile u32 n;\r
+\r
+ pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x7<<27) | (0x1<<31)); //exit\r
+ delayus(10); //wait for exit self refresh dll lock\r
+ pSCU_Reg->CRU_SOFTRST_CON[0] |= (0x1F<<19); //reset DLL\r
+ delayus(10);\r
+ pSCU_Reg->CRU_SOFTRST_CON[0] &= ~(0x1F<<19);\r
+ delayus(100); \r
+ //pDDR_Reg->CCR |= DTT;\r
+ n = pDDR_Reg->CCR;\r
+ delayus(100);\r
+ pDDR_Reg->CCR |= HOSTEN; //enable host port\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------\r
+Name : PLLGetAHBFreq\r
+Desc : »ñÈ¡DDRµÄƵÂÊ\r
+Params :\r
+Return : DDRƵÂÊ, KHz Ϊµ¥Î»\r
+Notes :\r
+-------------------------------------------------------------------*/\r
+static u32 PLLGetDDRFreq(void)\r
+{\r
+ u32 nr;\r
+ u32 nf;\r
+ u32 no;\r
+ u32 div;\r
+ \r
+ nr = (((pSCU_Reg->CRU_DPLL_CON) >> 10) & 0x1F) + 1;\r
+ nf = (((pSCU_Reg->CRU_DPLL_CON) >> 3) & 0x7F) + 1;\r
+ no = (0x1 << (((pSCU_Reg->CRU_DPLL_CON) >> 1) & 0x3));\r
+ div = ((pSCU_Reg->CRU_CLKSEL_CON[7] >> 26) & 0x7);\r
+ div = 0x1 << div;\r
+ \r
+ return ((24000*nf)/(nr*no*div));\r
+}\r
+\r
+static void DDRPreUpdateRef(u32 MHz)\r
+{\r
+ u32 tmp;\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
+ u32 value;\r
+ u32 memType = (pDDR_Reg->DCR & 0x3);\r
+ u32 cl;\r
+\r
+ if(memType == DDRII)\r
+ {\r
+ cl = GetDDRCL(newMHz);\r
+\r
+ pDDR_Reg->CCR |= FLUSH; //flush\r
+ delayus(10);\r
+ pDDR_Reg->CCR &= ~HOSTEN; //disable host port\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
+ 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(void)\r
+{\r
+ if(bFreqRaise) //ÉýƵ\r
+ {\r
+ DDRUpdateRef();\r
+ }\r
+ else //½µÆµ\r
+ {\r
+ DDRUpdateTiming();\r
+ }\r
+ ExitDDRSelfRefresh();\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
+ // ddr slow\r
+ pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
+ pSCU_Reg->CRU_MODE_CON |= 0x0<<6;\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) | ((56)<<3) | (1<<1); //high band\r
+ break;\r
+ case 400:\r
+ pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | ((66)<<3) | (1<<1); //high band\r
+ break;\r
+ case 533:\r
+ pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | (43<<3) | (0<<1); //high band\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
+ pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
+ pSCU_Reg->CRU_MODE_CON |= 0x1<<6;\r
+\r
+ // ddr_pll_clk: clk_ddr=1:1 \r
+ pSCU_Reg->CRU_CLKSEL_CON[7] &=~(0x1F<<24);\r
+ pSCU_Reg->CRU_CLKSEL_CON[7] |= (0x0 <<26)| (0x0<<24);\r
+\r
+}\r
+\r
+\r
+static void __sramfunc DDR_ChangePrior(void)\r
+{\r
+ // 2_Display(0) > 1_PERI(1) & 3_GPU(1) > 4_VCODEC(2) & 0_CPU(2)\r
+ pGRF_Reg->GRF_MEM_CON = (pGRF_Reg->GRF_MEM_CON & ~0x3FF) | 0x246;\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();\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
+ {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, 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
+ {0, 0, 0, 0},\r
+ {0, 0, 0, 0},\r
+ }\r
+};\r
+\r
+\r
+/****************************************************************/\r
+//º¯ÊýÃû:SDRAM_Init\r
+//ÃèÊö:DDR ³õʼ»¯\r
+//²ÎÊý˵Ã÷:\r
+//·µ»ØÖµ:\r
+//Ïà¹ØÈ«¾Ö±äÁ¿:\r
+//×¢Òâ:\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
+ //ËãÎïÀí¶ÔÆëµØÖ·\r
+ n = (unsigned long)ddrDataTraining;\r
+ printk("\n#################### VA = 0x%x\n", n);\r
+ addr = __pa((unsigned long)ddrDataTraining);\r
+ printk("#################### PA = 0x%x", addr);\r
+ if(addr&0x1F)\r
+ {\r
+ addr += (32-(addr&0x1F));\r
+ }\r
+ addr -= 0x60000000;\r
+ printk("#################### PA aligned = 0x%x\n", addr);\r
+ //ËãÊý¾ÝÏß¿í\r
+ bw = ((((pDDR_Reg->DCR >> 7) & 0x7)+1)>>1);\r
+ //²é³ö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
+ printk("#################### bw = 0x%x, col = 0x%x, row = 0x%x, bank = 0x%x\n", bw, col, row, bank);\r
+ //¸ù¾Ý²»Í¬µÄµØÖ·Ó³É䷽ʽ£¬Ëã³öDTAR¼Ä´æÆ÷µÄÅäÖÃ\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: //²»Ö§³ÖÕâÖ̶ֹ¨µÄ·½Ê½\r
+ default:\r
+ break;\r
+ }\r
+ printk("#################### value = 0x%x\n", value);\r
+ pDDR_Reg->DTAR = value;\r
+\r
+ if(memType == DDRII)\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
+ DDRPreUpdateRef(MHz);\r
+ DDRPreUpdateTiming(MHz);\r
+ DDRUpdateRef();\r
+ DDRUpdateTiming();\r
+}\r
+\r
+void DDR_ChangeFreq(u32 DDRoldMHz, u32 DDRnewMHz)\r
+{\r
+\r
+ DDRPreUpdateRef(DDRnewMHz);\r
+ DDRPreUpdateTiming(DDRnewMHz); \r
+ DDR_SAVE_SP;\r
+ flush_cache_all(); // 20100615,HSL@RK.\r
+ __cpuc_flush_user_all();\r
+ ChangeDDRFreqInSram(DDRoldMHz, DDRnewMHz);\r
+ DDR_RESTORE_SP;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////////////////\r
+\r
+/****************************************************************/\r
+//º¯ÊýÃû:SDRAM_EnterSelfRefresh\r
+//ÃèÊö:SDRAM½øÈë×ÔË¢ÐÂģʽ\r
+//²ÎÊý˵Ã÷:\r
+//·µ»ØÖµ:\r
+//Ïà¹ØÈ«¾Ö±äÁ¿:\r
+//×¢Òâ:(1)ϵͳÍêÈ«idleºó²ÅÄܽøÈë×ÔË¢ÐÂģʽ£¬½øÈë×Ôˢкó²»ÄÜÔÙ·ÃÎÊSDRAM\r
+// (2)Òª½øÈë×ÔË¢ÐÂģʽ£¬±ØÐë±£Ö¤ÔËÐÐʱÕâ¸öº¯ÊýËùµ÷Óõ½µÄËùÓдúÂë²»ÔÚSDRAMÉÏ\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 \r
+ delayus(10);\r
+ // ddr slow\r
+ pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
+ pSCU_Reg->CRU_MODE_CON |= 0x0<<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
+//º¯ÊýÃû:SDRAM_ExitSelfRefresh\r
+//ÃèÊö:SDRAMÍ˳ö×ÔË¢ÐÂģʽ\r
+//²ÎÊý˵Ã÷:\r
+//·µ»ØÖµ:\r
+//Ïà¹ØÈ«¾Ö±äÁ¿:\r
+//×¢Òâ:(1)SDRAMÔÚ×ÔË¢ÐÂģʽºó²»Äܱ»·ÃÎÊ£¬±ØÐëÏÈÍ˳ö×ÔË¢ÐÂģʽ\r
+// (2)±ØÐë±£Ö¤ÔËÐÐʱÕâ¸öº¯ÊýµÄ´úÂë²»ÔÚSDRAMÉÏ\r
+/****************************************************************/\r
+void __sramfunc DDR_ExitSelfRefresh(void)\r
+{\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
+ pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
+ pSCU_Reg->CRU_MODE_CON |= 0x1<<6; \r
+ delayus(10); \r
+ pSCU_Reg->CRU_CLKGATE_CON[0] &= ~(0x1<<18); //enable DDR PHY 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
+// ¿¼ÂÇcpu Ԥȡ¡¢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
+#if 0\r
+ n = * (volatile u32 *)SRAM_CODE_OFFSET;\r
+ n = * (volatile u32 *)(SRAM_CODE_OFFSET + 4096);\r
+ n = * (volatile u32 *)(SRAM_CODE_OFFSET + 8192);\r
+ n = * (volatile u32 *)(SRAM_CODE_OFFSET + 12288);\r
+#endif\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
+ \r
+ // printk("do_selfrefreshtest tlb \n");\r
+ DDR_EnterSelfRefresh();\r
+ //delayus(100000000);\r
+ //delayus(1000*1000*100);\r
+ DDR_ExitSelfRefresh();\r
+ dsb(); //dmb();\r
+#if 1\r
+ delayus(1);\r
+ delayus(1);\r
+ delayus(1);\r
+ delayus(1);\r
+\r
+#endif\r
+}\r
+\r
+static void selfrefreshtest(void)\r
+{\r
+ DDR_SAVE_SP;\r
+ do_selfrefreshtest();\r
+ DDR_RESTORE_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;\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;\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
+#if 0\r
+ unsigned long flags , i;\r
+ printk("DDR enter self-refresh!\n");\r
+ \r
+ local_irq_save(flags);\r
+ \r
+ DDR_Init();\r
+ //DDR_ChangeFreq(333); \r
+ \r
+ for (i=0;i<1000000;i++)\r
+ {\r
+ printk("%d ", i);\r
+ if(!(i%50))\r
+ printk("\n");\r
+\r
+ selfrefreshtest();\r
+ //changefreqtest(200); \r
+ //delayus(10000000);\r
+ //changefreqtest(333);\r
+ }\r
+ \r
+ local_irq_restore(flags);\r
+ \r
+ printk("DDR exit self-refresh!\n");\r
+ \r
+#endif\r
+ \r
+\r
+ return 0;\r
+}\r
+\r
+core_initcall_sync(ddr_update_freq);\r
+//late_initcall(ddr_update_freq);\r
+\r