rk30/31 DDR:1.fix ddr_init err,especially DDR frenuency more then 480Mhz
authorcym <cym@rock-chips.com>
Fri, 25 Jan 2013 08:14:03 +0000 (16:14 +0800)
committercym <cym@rock-chips.com>
Fri, 25 Jan 2013 08:17:14 +0000 (16:17 +0800)
    2.support 16bit DDR bus width,must update loader at the same time

arch/arm/mach-rk30/ddr.c

index 93d4ac606bb49450e1d0bcd3435e5bc3ca38ee42..8d3db9400b1dfa6f4e206c677146ec3b7d2c56b6 100755 (executable)
@@ -38,7 +38,6 @@ typedef uint32_t uint32;
 #define SysSrv_DdrTiming        (RK30_CPU_AXI_BUS_BASE+0x0c)
 #define SysSrv_DdrMode          (RK30_CPU_AXI_BUS_BASE+0x10)
 #define SysSrv_ReadLatency      (RK30_CPU_AXI_BUS_BASE+0x14)
-#define ROM_CHIP_ID_ADDR    (RK30_ROM_BASE+0x27f0)
 
 #define ddr_print(x...) printk( "DDR DEBUG: " x )
 
@@ -927,99 +926,99 @@ typedef struct BACKUP_REG_Tag
 
 __sramdata BACKUP_REG_T ddr_reg;
 
-typedef struct DDR_CONFIG_2_RBC_Tag
+uint8_t  ddr_cfg_2_rbc[] =
 {
-    unsigned int row;
-    unsigned int bank;
-    unsigned int col;
-}DDR_CONFIG_2_RBC_T;
-
-DDR_CONFIG_2_RBC_T  ddr_cfg_2_rbc[16] = 
-{
-    {15,3,11},  // bank ahead
-    {15,3,10},
-    {14,3,10},
-    {13,3,10},
-    {15,3,11},
-    {14,3,11},
-    {13,3,11},
-    {14,3,9},
-    {13,3,9},
-    {15,2,11},
-    {14,2,11},
-    {15,2,10},
-    {14,2,10},
-    {14,2,9},
-    {13,2,9},
-    {15,3,10}   // bank ahead
+    /****************************/
+    // [7:6]  bank(n:n bit bank)
+    // [5:4]  row(13+n)
+    // [3:2]  bank(n:n bit bank)
+    // [1:0]  col(9+n)
+    /****************************/
+    //bank, row,    bank,  col
+    ((3<<6)|(2<<4)|(0<<2)|2),  // 0 bank ahead
+    ((0<<6)|(2<<4)|(3<<2)|1),  // 1
+    ((0<<6)|(1<<4)|(3<<2)|1),  // 2
+    ((0<<6)|(0<<4)|(3<<2)|1),  // 3
+    ((0<<6)|(2<<4)|(3<<2)|2),  // 4
+    ((0<<6)|(1<<4)|(3<<2)|2),  // 5
+    ((0<<6)|(0<<4)|(3<<2)|2),  // 6
+    ((0<<6)|(1<<4)|(3<<2)|0),  // 7
+    ((0<<6)|(0<<4)|(3<<2)|0),  // 8
+    ((1<<6)|(2<<4)|(2<<2)|2),  // 9
+    ((1<<6)|(1<<4)|(2<<2)|2),  // 10
+    ((1<<6)|(2<<4)|(2<<2)|1),  // 11
+    ((1<<6)|(1<<4)|(2<<2)|1),  // 12
+    ((1<<6)|(2<<4)|(2<<2)|0),  // 13
+    ((1<<6)|(1<<4)|(2<<2)|0),  // 14
+    ((3<<6)|(2<<4)|(0<<2)|1),  // 15 bank ahead
 };
 
 __attribute__((aligned(4096))) uint32_t ddr_data_training_buf[32];
 
-uint32_t __sramdata ddr3_cl_cwl[22][4]={
+uint8_t __sramdata ddr3_cl_cwl[22][4]={
 /*   0~330           330~400         400~533        speed
 * tCK  >3             2.5~3          1.875~2.5      1.5~1.875
-*    cl<<16, cwl    cl<<16, cwl     cl<<16, cwl              */
-    {((5<<16)|5),   ((5<<16)|5),    0          ,   0}, //DDR3_800D
-    {((5<<16)|5),   ((6<<16)|5),    0          ,   0}, //DDR3_800E
-
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   0}, //DDR3_1066E
-    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   0}, //DDR3_1066F
-    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   0}, //DDR3_1066G
-
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((7<<16)|7)}, //DDR3_1333F
-    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((8<<16)|7)}, //DDR3_1333G
-    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((9<<16)|7)}, //DDR3_1333H
-    {((5<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((10<<16)|7)}, //DDR3_1333J
-
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((7<<16)|7)}, //DDR3_1600G
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((8<<16)|7)}, //DDR3_1600H
-    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_1600J
-    {((5<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((10<<16)|7)}, //DDR3_1600K
-
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((8<<16)|7)}, //DDR3_1866J
-    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((8<<16)|7)}, //DDR3_1866K
-    {((6<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_1866L
-    {((6<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((10<<16)|7)}, //DDR3_1866M
-
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((7<<16)|7)}, //DDR3_2133K
-    {((5<<16)|5),   ((5<<16)|5),    ((6<<16)|6),   ((8<<16)|7)}, //DDR3_2133L
-    {((5<<16)|5),   ((5<<16)|5),    ((7<<16)|6),   ((9<<16)|7)}, //DDR3_2133M
-    {((6<<16)|5),   ((6<<16)|5),    ((7<<16)|6),   ((9<<16)|7)},  //DDR3_2133N
-
-    {((6<<16)|5),   ((6<<16)|5),    ((8<<16)|6),   ((10<<16)|7)} //DDR3_DEFAULT
-
+*    cl<<4, cwl     cl<<4, cwl    cl<<4, cwl              */
+    {((5<<4)|5),   ((5<<4)|5),    0          ,   0}, //DDR3_800D
+    {((5<<4)|5),   ((6<<4)|5),    0          ,   0}, //DDR3_800E
+
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   0}, //DDR3_1066E
+    {((5<<4)|5),   ((6<<4)|5),    ((7<<4)|6),   0}, //DDR3_1066F
+    {((5<<4)|5),   ((6<<4)|5),    ((8<<4)|6),   0}, //DDR3_1066G
+
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   ((7<<4)|7)}, //DDR3_1333F
+    {((5<<4)|5),   ((5<<4)|5),    ((7<<4)|6),   ((8<<4)|7)}, //DDR3_1333G
+    {((5<<4)|5),   ((6<<4)|5),    ((8<<4)|6),   ((9<<4)|7)}, //DDR3_1333H
+    {((5<<4)|5),   ((6<<4)|5),    ((8<<4)|6),   ((10<<4)|7)}, //DDR3_1333J
+
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   ((7<<4)|7)}, //DDR3_1600G
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   ((8<<4)|7)}, //DDR3_1600H
+    {((5<<4)|5),   ((5<<4)|5),    ((7<<4)|6),   ((9<<4)|7)}, //DDR3_1600J
+    {((5<<4)|5),   ((6<<4)|5),    ((7<<4)|6),   ((10<<4)|7)}, //DDR3_1600K
+
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   ((8<<4)|7)}, //DDR3_1866J
+    {((5<<4)|5),   ((5<<4)|5),    ((7<<4)|6),   ((8<<4)|7)}, //DDR3_1866K
+    {((6<<4)|5),   ((6<<4)|5),    ((7<<4)|6),   ((9<<4)|7)}, //DDR3_1866L
+    {((6<<4)|5),   ((6<<4)|5),    ((8<<4)|6),   ((10<<4)|7)}, //DDR3_1866M
+
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   ((7<<4)|7)}, //DDR3_2133K
+    {((5<<4)|5),   ((5<<4)|5),    ((6<<4)|6),   ((8<<4)|7)}, //DDR3_2133L
+    {((5<<4)|5),   ((5<<4)|5),    ((7<<4)|6),   ((9<<4)|7)}, //DDR3_2133M
+    {((6<<4)|5),   ((6<<4)|5),    ((7<<4)|6),   ((9<<4)|7)},  //DDR3_2133N
+
+    {((6<<4)|5),   ((6<<4)|5),    ((8<<4)|6),   ((10<<4)|7)} //DDR3_DEFAULT
 };
-uint32_t __sramdata ddr3_tRC_tFAW[22]={
+
+uint16_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
+    ((50<<8)|50), //DDR3_800D
+    ((53<<8)|50), //DDR3_800E
+
+    ((49<<8)|50), //DDR3_1066E
+    ((51<<8)|50), //DDR3_1066F
+    ((53<<8)|50), //DDR3_1066G
+
+    ((47<<8)|45), //DDR3_1333F
+    ((48<<8)|45), //DDR3_1333G
+    ((50<<8)|45), //DDR3_1333H
+    ((51<<8)|45), //DDR3_1333J
+
+    ((45<<8)|40), //DDR3_1600G
+    ((47<<8)|40), //DDR3_1600H
+    ((48<<8)|40), //DDR3_1600J
+    ((49<<8)|40), //DDR3_1600K
+
+    ((45<<8)|35), //DDR3_1866J
+    ((46<<8)|35), //DDR3_1866K
+    ((47<<8)|35), //DDR3_1866L
+    ((48<<8)|35), //DDR3_1866M
+
+    ((44<<8)|35), //DDR3_2133K
+    ((45<<8)|35), //DDR3_2133L
+    ((46<<8)|35), //DDR3_2133M
+    ((47<<8)|35), //DDR3_2133N
+
+    ((53<<8)|50)  //DDR3_DEFAULT
 };
 
 __sramdata uint32_t mem_type;    // 0:LPDDR, 1:DDR, 2:DDR2, 3:DDR3, 4:LPDDR2
@@ -1065,7 +1064,7 @@ uint32 ddr_get_row(void)
     uint32 row;
 
     i = *(volatile uint32*)SysSrv_DdrConf;
-    row = ddr_cfg_2_rbc[i].row;
+    row = 13+((ddr_cfg_2_rbc[i]>>4)&0x3);
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
     if(pGRF_Reg_RK3066B->GRF_SOC_CON[2] &  (1<<1))
     {
@@ -1083,17 +1082,72 @@ uint32 ddr_get_row(void)
 uint32 ddr_get_bank(void)
 {
     uint32 i;
+    uint32 bank;
 
     i = *(volatile uint32*)SysSrv_DdrConf;
-    return ddr_cfg_2_rbc[i].bank;
+    bank = ((ddr_cfg_2_rbc[i]>>6)&0x3) + ((ddr_cfg_2_rbc[i]>>2)&0x3);
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
+    if(pGRF_Reg_RK3066B->GRF_SOC_CON[2] &  (1<<2))
+    {
+        bank -= 1;
+    }
+#else
+    if(pGRF_Reg->GRF_SOC_CON[2] &  (1<<2))
+    {
+        bank -= 1;
+    }
+#endif
+    return bank;
 }
 
 uint32 ddr_get_col(void)
 {
     uint32 i;
+    uint32 col;
 
     i = *(volatile uint32*)SysSrv_DdrConf;
-    return ddr_cfg_2_rbc[i].col;
+    col = 9+(ddr_cfg_2_rbc[i]&0x3);
+    if(pDDR_Reg->PPCFG & 1)
+    {
+        col +=1;
+    }
+    return col;
+}
+
+__sramlocalfunc uint32 ddr_get_bw(void)
+{
+    uint32 bw;
+
+    if(pDDR_Reg->PPCFG & 1)
+    {
+        bw=1;
+    }
+    else
+    {
+        bw=2;
+    }
+    return bw;
+}
+
+uint32 ddr_get_cs(void)
+{
+    uint32 cs;
+    
+    switch((pPHY_Reg->PGCR>>18) & 0xF)
+    {
+        case 0xF:
+            cs = 4;
+        case 7:
+            cs = 3;
+            break;
+        case 3:
+            cs = 2;
+            break;
+        default:
+            cs = 1;
+            break;
+    }
+    return cs;
 }
 
 uint32_t ddr_get_datatraing_addr(void)
@@ -1103,6 +1157,8 @@ uint32_t ddr_get_datatraing_addr(void)
     uint32_t          col = 0;
     uint32_t          row = 0;
     uint32_t          bank = 0;
+    uint32_t          bw = 0;
+    uint32_t          i;
     
     // caculate aglined physical address 
     addr =  __pa((unsigned long)ddr_data_training_buf);
@@ -1115,20 +1171,32 @@ uint32_t ddr_get_datatraing_addr(void)
     row = ddr_get_row();
     bank = ddr_get_bank();
     col = ddr_get_col();
+    bw = ddr_get_bw();
     // according different address mapping, caculate DTAR register value
-    switch(*(volatile uint32*)SysSrv_DdrConf)
+    i = (*(volatile uint32*)SysSrv_DdrConf);
+    value |= (addr>>bw) & ((0x1<<col)-1);  // col
+    if(row==16)
     {
-        case 0:
-        case 15:
-            value |= (addr>>2) & ((0x1<<col)-1);  // col
-            value |= ((addr>>(2+col)) & ((0x1<<row)-1)) << 12;  // row
-            value |= ((addr>>(2+col+row)) & ((0x1<<bank)-1)) << 28;  // bank
-            break;
-        default:
-            value |= (addr>>2) & ((0x1<<col)-1);  // col
-            value |= ((addr>>(2+col+bank)) & ((0x1<<row)-1)) << 12;  // row
-            value |= ((addr>>(2+col)) & ((0x1<<bank)-1)) << 28;  // bank
-            break;
+        value |= ((addr>>(bw+col+((ddr_cfg_2_rbc[i]>>2)&0x3))) & 0x7FFF) << 12;  // row
+        value |= (((addr>>(bw+col+bank+15))&0x1)<<15)<<12;
+        row = 15;  //use for bank
+    }
+    else
+    {
+        value |= ((addr>>(bw+col+((ddr_cfg_2_rbc[i]>>2)&0x3))) & ((0x1<<row)-1)) << 12;  // row
+    }
+    if(((ddr_cfg_2_rbc[i]>>6)&0x3)==1)
+    {
+        value |= (((addr>>(bw+col)) & 0x3) << 28)
+                 | (((addr>>(bw+col+2+row)) & (bank-2))  << 30);  // bank
+    }
+    else if(((ddr_cfg_2_rbc[i]>>6)&0x3)==3)
+    {
+        value |= (((addr>>(bw+col+row)) & ((0x1<<bank)-1))  << 28);  // bank
+    }
+    else
+    {
+        value |= (((addr>>(bw+col)) & 0x7) << 28);  // bank
     }
 
     return value;
@@ -1139,14 +1207,20 @@ __sramlocalfunc void ddr_reset_dll(void)
     pPHY_Reg->ACDLLCR &= ~0x40000000;
     pPHY_Reg->DATX8[0].DXDLLCR &= ~0x40000000;
     pPHY_Reg->DATX8[1].DXDLLCR &= ~0x40000000;
-    pPHY_Reg->DATX8[2].DXDLLCR &= ~0x40000000;
-    pPHY_Reg->DATX8[3].DXDLLCR &= ~0x40000000;
+    if(!(pDDR_Reg->PPCFG & 1))
+    {
+        pPHY_Reg->DATX8[2].DXDLLCR &= ~0x40000000;
+        pPHY_Reg->DATX8[3].DXDLLCR &= ~0x40000000;
+    }
     ddr_delayus(1);
     pPHY_Reg->ACDLLCR |= 0x40000000;
     pPHY_Reg->DATX8[0].DXDLLCR |= 0x40000000;
     pPHY_Reg->DATX8[1].DXDLLCR |= 0x40000000;
-    pPHY_Reg->DATX8[2].DXDLLCR |= 0x40000000;
-    pPHY_Reg->DATX8[3].DXDLLCR |= 0x40000000;
+    if(!(pDDR_Reg->PPCFG & 1))
+    {
+        pPHY_Reg->DATX8[2].DXDLLCR |= 0x40000000;
+        pPHY_Reg->DATX8[3].DXDLLCR |= 0x40000000;
+    }
     ddr_delayus(1);
 }
 
@@ -1278,6 +1352,11 @@ uint32_t __sramlocalfunc ddr_data_training(void)
     value = pDDR_Reg->TREFI;
     pDDR_Reg->TREFI = 0;
     dsb();
+    if(mem_type != LPDDR2)
+    {
+        // passive window
+        pPHY_Reg->PGCR |= (1<<1);    
+    }
     // clear DTDONE status
     pPHY_Reg->PIR |= CLRSR;
     cs = ((pPHY_Reg->PGCR>>18) & 0xF);
@@ -1287,9 +1366,12 @@ uint32_t __sramlocalfunc ddr_data_training(void)
     // wait echo byte DTDONE
     while((pPHY_Reg->DATX8[0].DXGSR[0] & cs) != cs);
     while((pPHY_Reg->DATX8[1].DXGSR[0] & cs) != cs);
-    while((pPHY_Reg->DATX8[2].DXGSR[0] & cs) != cs);
-    while((pPHY_Reg->DATX8[3].DXGSR[0] & cs) != cs);  //²âµ½1¸öCSµÄDTT×ʱ¼äÊÇ10.7us¡£×î¶à²¹2´ÎË¢ÐÂ
-    // send some auto refresh to complement the lost while DTT
+    if(!(pDDR_Reg->PPCFG & 1))
+    {
+        while((pPHY_Reg->DATX8[2].DXGSR[0] & cs) != cs);
+        while((pPHY_Reg->DATX8[3].DXGSR[0] & cs) != cs);  
+    }
+    // send some auto refresh to complement the lost while DTT£¬//²âµ½1¸öCSµÄDTT×ʱ¼äÊÇ10.7us¡£×î¶à²¹2´ÎË¢ÐÂ
     if(cs > 1)
     {
         ddr_send_command(cs, REF_cmd, 0);
@@ -1301,7 +1383,12 @@ uint32_t __sramlocalfunc ddr_data_training(void)
     {
         ddr_send_command(cs, REF_cmd, 0);
         ddr_send_command(cs, REF_cmd, 0);
-    }  
+    }
+    if(mem_type != LPDDR2)
+    {
+        // active window
+        pPHY_Reg->PGCR &= ~(1<<1);
+    }
     // resume auto refresh
     pDDR_Reg->TREFI = value;
 
@@ -1343,8 +1430,11 @@ void __sramlocalfunc ddr_set_dll_bypass(uint32 freq)
         pPHY_Reg->ACDLLCR &= ~0x80000000;
         pPHY_Reg->DATX8[0].DXDLLCR &= ~0x80000000;
         pPHY_Reg->DATX8[1].DXDLLCR &= ~0x80000000;
-        pPHY_Reg->DATX8[2].DXDLLCR &= ~0x80000000;
-        pPHY_Reg->DATX8[3].DXDLLCR &= ~0x80000000;
+        if(!(pDDR_Reg->PPCFG & 1))
+        {
+            pPHY_Reg->DATX8[2].DXDLLCR &= ~0x80000000;
+            pPHY_Reg->DATX8[3].DXDLLCR &= ~0x80000000;
+        }
         pPHY_Reg->PIR &= ~DLLBYP;
     }
 }
@@ -1581,8 +1671,8 @@ uint32_t ddr_get_parameter(uint32_t nMHz)
         {
             tmp = 3;
         }
-        cl = ddr3_cl_cwl[ddr_speed_bin][tmp] >> 16;
-        cwl = ddr3_cl_cwl[ddr_speed_bin][tmp] & 0x0ff;
+        cl = (ddr3_cl_cwl[ddr_speed_bin][tmp] >> 4)&0xf;
+        cwl = ddr3_cl_cwl[ddr_speed_bin][tmp] & 0xf;
         if(cl == 0)
             ret = -4;
         if(nMHz <= DDR3_DDR2_ODT_DISABLE_FREQ)
@@ -1649,9 +1739,9 @@ uint32_t ddr_get_parameter(uint32_t nMHz)
         /*
          * tRC=tRAS+tRP
          */
-        p_pctl_timing->trc = ((((ddr3_tRC_tFAW[ddr_speed_bin]>>16)*nMHz+999)/1000)&0x3F);
-        p_noc_timing->b.ActToAct = ((((ddr3_tRC_tFAW[ddr_speed_bin]>>16)*nMHz+999)/1000)&0x3F);
-        p_publ_timing->dtpr0.b.tRC = (((ddr3_tRC_tFAW[ddr_speed_bin]>>16)*nMHz+999)/1000)&0xF;
+        p_pctl_timing->trc = ((((ddr3_tRC_tFAW[ddr_speed_bin]>>8)*nMHz+999)/1000)&0x3F);
+        p_noc_timing->b.ActToAct = ((((ddr3_tRC_tFAW[ddr_speed_bin]>>8)*nMHz+999)/1000)&0x3F);
+        p_publ_timing->dtpr0.b.tRC = (((ddr3_tRC_tFAW[ddr_speed_bin]>>8)*nMHz+999)/1000)&0xF;
 
         p_pctl_timing->trtw = (cl+2-cwl);//DDR3_tRTW;
         p_publ_timing->dtpr1.b.tRTW = 0;
@@ -2825,35 +2915,35 @@ uint32_t __sramlocalfunc ddr_update_mr(void)
         {
             if(dll_off)  // off -> on
             {
-                ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(p_publ_timing->mr[1])));  //DLL enable
-                ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr(((uint8_t)(p_publ_timing->mr[0]))| DDR3_DLL_RESET));  //DLL reset
+                ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((p_publ_timing->mr[1])));  //DLL enable
+                ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr(((p_publ_timing->mr[0]))| DDR3_DLL_RESET));  //DLL reset
                 ddr_delayus(2);  //at least 200 DDR cycle
-                ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_publ_timing->mr[0])));
+                ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((p_publ_timing->mr[0])));
             }
             else // on -> on
             {
-                ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(p_publ_timing->mr[1])));
-                ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_publ_timing->mr[0])));
+                ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((p_publ_timing->mr[1])));
+                ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((p_publ_timing->mr[0])));
             }
         }
         else
         {
-            pPHY_Reg->MR[1] = (((uint8_t)(p_publ_timing->mr[1])) | DDR3_DLL_DISABLE);
-            ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((uint8_t)(p_publ_timing->mr[1])) | DDR3_DLL_DISABLE));  //DLL disable
-            ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_publ_timing->mr[0])));
+            pPHY_Reg->MR[1] = (((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE);
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE));  //DLL disable
+            ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((p_publ_timing->mr[0])));
         }
-        ddr_send_command(cs, MRS_cmd, bank_addr(0x2) | cmd_addr((uint8_t)(p_publ_timing->mr[2])));
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x2) | cmd_addr((p_publ_timing->mr[2])));
     }
     else if(mem_type == LPDDR2)
     {
-        ddr_send_command(cs, MRS_cmd, lpddr2_ma(0x1) | lpddr2_op((uint8_t)(p_publ_timing->mr[1])));
-        ddr_send_command(cs, MRS_cmd, lpddr2_ma(0x2) | lpddr2_op((uint8_t)(p_publ_timing->mr[2])));
-        ddr_send_command(cs, MRS_cmd, lpddr2_ma(0x3) | lpddr2_op((uint8_t)(p_publ_timing->mr[3])));
+        ddr_send_command(cs, MRS_cmd, lpddr2_ma(0x1) | lpddr2_op((p_publ_timing->mr[1])));
+        ddr_send_command(cs, MRS_cmd, lpddr2_ma(0x2) | lpddr2_op((p_publ_timing->mr[2])));
+        ddr_send_command(cs, MRS_cmd, lpddr2_ma(0x3) | lpddr2_op((p_publ_timing->mr[3])));
     }
     else //mDDR
     {
-        ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((uint8_t)(p_publ_timing->mr[0])));
-        ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((uint8_t)(p_publ_timing->mr[2]))); //mr[2] is mDDR MR1
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x0) | cmd_addr((p_publ_timing->mr[0])));
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr((p_publ_timing->mr[2]))); //mr[2] is mDDR MR1
     }
     return 0;
 }
@@ -2869,24 +2959,33 @@ void __sramlocalfunc ddr_update_odt(void)
         {
             pPHY_Reg->DATX8[0].DXGCR &= ~(0x3<<9);  //dynamic RTT disable
             pPHY_Reg->DATX8[1].DXGCR &= ~(0x3<<9);
-            pPHY_Reg->DATX8[2].DXGCR &= ~(0x3<<9);
-            pPHY_Reg->DATX8[3].DXGCR &= ~(0x3<<9);
+            if(!(pDDR_Reg->PPCFG & 1))
+            {
+                pPHY_Reg->DATX8[2].DXGCR &= ~(0x3<<9);
+                pPHY_Reg->DATX8[3].DXGCR &= ~(0x3<<9);
+            }
         }
         else
         {
             pPHY_Reg->DATX8[0].DXGCR |= (0x3<<9);  //dynamic RTT enable
             pPHY_Reg->DATX8[1].DXGCR |= (0x3<<9);
-            pPHY_Reg->DATX8[2].DXGCR |= (0x3<<9);
-            pPHY_Reg->DATX8[3].DXGCR |= (0x3<<9);
+            if(!(pDDR_Reg->PPCFG & 1))
+            {
+                pPHY_Reg->DATX8[2].DXGCR |= (0x3<<9);
+                pPHY_Reg->DATX8[3].DXGCR |= (0x3<<9);
+            }
         }
     }
     else
     {
         pPHY_Reg->DATX8[0].DXGCR &= ~(0x3<<9);  //dynamic RTT disable
         pPHY_Reg->DATX8[1].DXGCR &= ~(0x3<<9);
-        pPHY_Reg->DATX8[2].DXGCR &= ~(0x3<<9);
-        pPHY_Reg->DATX8[3].DXGCR &= ~(0x3<<9);
-    }    
+        if(!(pDDR_Reg->PPCFG & 1))
+        {
+            pPHY_Reg->DATX8[2].DXGCR &= ~(0x3<<9);
+            pPHY_Reg->DATX8[3].DXGCR &= ~(0x3<<9);
+        }
+    }
     tmp = (0x1<<28) | (0x2<<15) | (0x2<<10) | (0xb<<5) | 0xb;  //DS=34ohm,ODT=171ohm
     cs = ((pPHY_Reg->PGCR>>18) & 0xF);
     if(cs > 1)
@@ -2936,19 +3035,6 @@ __sramfunc void ddr_adjust_config(uint32_t dram_type)
     //enter config state
     ddr_move_to_Config_state();
 
-    //extend capability for debug
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
-    if(pGRF_Reg_RK3066B->GRF_SOC_CON[2] & (0x1<<1))
-    {
-        pGRF_Reg_RK3066B->GRF_SOC_CON[2] = rank_to_row15_en;
-    }
-#else
-    if(pGRF_Reg->GRF_SOC_CON[2] & (0x1<<1))
-    {
-        pGRF_Reg->GRF_SOC_CON[2] = rank_to_row15_en;
-    }
-#endif
-
     //set data training address
     pPHY_Reg->DTAR = value;
 
@@ -2961,6 +3047,14 @@ __sramfunc void ddr_adjust_config(uint32_t dram_type)
     //enable the hardware low-power interface
     pDDR_Reg->SCFG.b.hw_low_power_en = 1;
 
+    if(pDDR_Reg->PPCFG & 1)
+    {
+        pPHY_Reg->DATX8[2].DXGCR &= ~(1);          //disable byte
+        pPHY_Reg->DATX8[3].DXGCR &= ~(1);
+        pPHY_Reg->DATX8[2].DXDLLCR |= 0x80000000;  //disable DLL
+        pPHY_Reg->DATX8[3].DXDLLCR |= 0x80000000;
+    }
+
     ddr_update_odt();
 
     //enter access state
@@ -3099,8 +3193,8 @@ void __sramlocalfunc ddr_selfrefresh_enter(uint32 nMHz)
     if((nMHz<=DDR3_DDR2_DLL_DISABLE_FREQ) && ((mem_type == DDR3) || (mem_type == DDR2)))  // DLL disable
     {
         cs = ((pPHY_Reg->PGCR>>18) & 0xF);
-        pPHY_Reg->MR[1] = (((uint8_t)(p_publ_timing->mr[1])) | DDR3_DLL_DISABLE);
-        ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((uint8_t)(p_publ_timing->mr[1])) | DDR3_DLL_DISABLE));
+        pPHY_Reg->MR[1] = (((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE);
+        ddr_send_command(cs, MRS_cmd, bank_addr(0x1) | cmd_addr(((p_publ_timing->mr[1])) | DDR3_DLL_DISABLE));
     }
     ddr_move_to_Lowpower_state();
     
@@ -3288,40 +3382,7 @@ EXPORT_SYMBOL(ddr_resume);
 //»ñÈ¡ÈÝÁ¿£¬·µ»Ø×Ö½ÚÊý
 uint32 ddr_get_cap(void)
 {
-    uint32 i;
-    uint32 row;
-    uint32 cs;
-
-    i = *(volatile uint32*)SysSrv_DdrConf;
-    switch((pPHY_Reg->PGCR>>18) & 0xF)
-    {
-        case 0xF:
-            cs = 4;
-        case 7:
-            cs = 3;
-            break;
-        case 3:
-            cs = 2;
-            break;
-        default:
-            cs = 1;
-            break;
-    }
-    row = ddr_cfg_2_rbc[i].row;
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
-    if(pGRF_Reg_RK3066B->GRF_SOC_CON[2] &  (1<<1))
-    {
-        row += 1;
-    }
-#else
-    if(pGRF_Reg->GRF_SOC_CON[2] &  (1<<1))
-    {
-        row += 1;
-    }
-#endif
-
-    return (1 << (row+(ddr_cfg_2_rbc[i].col)+(ddr_cfg_2_rbc[i].bank)+2))*cs;
+    return (1 << (ddr_get_row()+ddr_get_col()+ddr_get_bank()+ddr_get_bw()))*ddr_get_cs();
 }
 EXPORT_SYMBOL(ddr_get_cap);
 
@@ -3411,10 +3472,10 @@ __attribute__((aligned(4))) __sramdata uint32 ddr_reg_resume[] =
 int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
 {
     volatile uint32_t value = 0;
-    uint32_t cs,die=1;
+    uint32_t die=1;
     uint32_t gsr,dqstr;
 
-    ddr_print("version 1.00 20130124-2 \n");
+    ddr_print("version 1.00 20130125 \n");
 
     mem_type = pPHY_Reg->DCR.b.DDRMD;
     ddr_speed_bin = dram_speed_bin;
@@ -3444,27 +3505,14 @@ int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
             ddr_print("LPDDR Device\n");
             break;
     }
-    switch((pPHY_Reg->PGCR>>18) & 0xF)
-    {
-        case 0xF:
-            cs = 4;
-        case 7:
-            cs = 3;
-            break;
-        case 3:
-            cs = 2;
-            break;
-        default:
-            cs = 1;
-            break;
-    }
     //get capability per chip, not total size, used for calculate tRFC
-    ddr_capability_per_die = ddr_get_cap()/(cs*die);
-    ddr_print("%d CS, ROW=%d, Bank=%d, COL=%d, Total Capability=%dMB\n", 
-                                                                    cs, \
-                                                                    ddr_get_row(), \
-                                                                    (0x1<<(ddr_get_bank())), \
+    ddr_capability_per_die = ddr_get_cap()/(ddr_get_cs()*die);
+    ddr_print("Bus Width=%d Col=%d Bank=%d Row=%d CS=%d Total Capability=%dMB\n", 
+                                                                    ddr_get_bw()*16,\
                                                                     ddr_get_col(), \
+                                                                    (0x1<<(ddr_get_bank())), \
+                                                                    ddr_get_row(), \
+                                                                    ddr_get_cs(), \
                                                                     (ddr_get_cap()>>20));
     ddr_adjust_config(mem_type);
 
@@ -3474,7 +3522,7 @@ int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
         value=ddr_change_freq(clk_get_rate(clk_get(NULL, "ddr_pll"))/1000000);
 
     clk_set_rate(clk_get(NULL, "ddr_pll"), 0);
-    ddr_print("init success!!! freq=%dMHz\n", clk_get_rate(clk_get(NULL, "ddr_pll"))/1000000);
+    ddr_print("init success!!! freq=%luMHz\n", clk_get_rate(clk_get(NULL, "ddr_pll"))/1000000);
 
     for(value=0;value<4;value++)
     {