fix ddr enter and exit self-refresh by hcy
authorhxy/ubuntu <hxy@rockchip.com>
Fri, 11 Mar 2011 09:37:53 +0000 (17:37 +0800)
committerhxy/ubuntu <hxy@rockchip.com>
Fri, 11 Mar 2011 09:37:53 +0000 (17:37 +0800)
arch/arm/mach-rk29/ddr.c

index 60b44cee43e0f55d272c71c5d10e8d9f6beb40e9..93961ea507386c93257a6d8654c0b11bd8874339 100644 (file)
@@ -275,6 +275,12 @@ static unsigned long save_sp;
 #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
@@ -483,7 +489,9 @@ void __sramfunc EnterDDRSelfRefresh(void)
     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
+    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
@@ -497,46 +505,30 @@ Notes   :         1.  ddr enter sel-refresh must be after system enter idle ,after ddr
 -------------------------------------------------------------------*/\r
 void __sramfunc ExitDDRSelfRefresh(void)\r
 {\r
-\r
-    pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x7<<27) | (0x1<<31)); //exit\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
-    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
-    delayus(100);\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
-\r
-/*-------------------------------------------------------------------\r
-Name    : PLLGetAHBFreq\r
-Desc    :  get DDR frequency\r
-Params  :\r
-Return  : DDR frequency,  min is KHz\r
-Notes   :\r
--------------------------------------------------------------------*/\r
-static u32 PLLGetDDRFreq(void)  // ??????????????? need to check it by huangtao , Is DPLL only used by DDR?\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
@@ -688,30 +680,10 @@ static void DDRPreUpdateTiming(u32 MHz)
 \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
+    pDDR_Reg->CCR |= FLUSH;    //flush\r
+    delayus(10);\r
+    pDDR_Reg->CCR &= ~HOSTEN;  //disable host port\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
@@ -725,8 +697,12 @@ static void __sramfunc StopDDR(u32 oldMHz, u32 newMHz)
     }\r
 }\r
 \r
-static void __sramfunc ResumeDDR(void)\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
@@ -736,6 +712,23 @@ static void __sramfunc ResumeDDR(void)
         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
@@ -747,11 +740,14 @@ Notes   :
 -------------------------------------------------------------------*/\r
 void __sramfunc PLLSetAUXFreq(u32 freq)\r
 {\r
+               u32 value;\r
+               \r
     // ddr slow\r
-    pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
-    pSCU_Reg->CRU_MODE_CON |= 0x0<<6;\r
+    value = pSCU_Reg->CRU_MODE_CON;\r
+    value &=~(0x3<<6);\r
+    pSCU_Reg->CRU_MODE_CON = value;\r
 \r
-   delayus(10);\r
+    delayus(10);\r
     \r
     pSCU_Reg->CRU_DPLL_CON |= (0x1 << 15); //power down pll\r
     delayus(1);  //delay at least 500ns\r
@@ -767,13 +763,13 @@ void __sramfunc PLLSetAUXFreq(u32 freq)
             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
+            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\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\r
+            pSCU_Reg->CRU_DPLL_CON = (0x1<<16) | (0x1<<15) | (1<<10) | (43<<3) | (0<<1);  //high band 528\r
             break;\r
     }\r
        \r
@@ -782,20 +778,23 @@ void __sramfunc PLLSetAUXFreq(u32 freq)
     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
+    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
-       // 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
+       // 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
@@ -808,7 +807,7 @@ void __sramfunc ChangeDDRFreqInSram(u32 oldMHz, u32 newMHz)
 {\r
     StopDDR(oldMHz, newMHz);\r
     PLLSetAUXFreq(newMHz);\r
-    ResumeDDR();\r
+    ResumeDDR(newMHz);\r
 }\r
 \r
 void __sramfunc DDRDLLSetMode(eDDRDLLMode_t DLLmode, u32 freq)\r
@@ -876,17 +875,17 @@ DDR_CONFIG_T    ddrConfig[3][10] = {
     },\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
-        {0,  0, 0,  0},\r
-        {0,  0, 0,  0},\r
     }\r
 };\r
 \r
@@ -1031,11 +1030,10 @@ void __sramfunc DDR_EnterSelfRefresh(void)
 {\r
     EnterDDRSelfRefresh();\r
 #if 1\r
-    pSCU_Reg->CRU_CLKGATE_CON[0] |= (0x7<<18);  //close DDR PHY clock  / DDR CPU AXI clock / DDR REG AXI clock\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
-    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
@@ -1052,15 +1050,18 @@ Notes   :       1.  ddr enter sel-refresh must be after system enter idle ,after ddr
 -------------------------------------------------------------------*/\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
-    pSCU_Reg->CRU_MODE_CON &=~(0x3<<6);\r
-    pSCU_Reg->CRU_MODE_CON |= 0x1<<6; \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] &= ~(0x7<<18);  //enable DDR PHY clock / DDR CPU AXI clock / DDR REG AXI clock\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