typedef uint32_t uint32;
+#define ENABLE_DDR_CLCOK_GPLL_PATH //for RK3188
+
#define DDR3_DDR2_DLL_DISABLE_FREQ (125)
#define DDR3_DDR2_ODT_DISABLE_FREQ (333)
#define SR_IDLE (0x1) //unit:32*DDR clk cycle, and 0 for disable auto self-refresh
static __sramdata uint32_t clkr;
static __sramdata uint32_t clkf;
static __sramdata uint32_t clkod;
+
+static __sramdata uint32_t dpllvaluel=0;
+static __sramdata uint32_t gpllvaluel=0;
+static __sramdata bool ddr_select_gpll=false;
+
/*****************************************
NR NO NF Fout freq Step finally use
1 8 12.5 - 62.5 37.5MHz - 187.5MHz 3MHz 50MHz <= 150MHz
if(!set)
{
- if(nMHz <= 150)
- {
- clkod = 14;
- }
- else if(nMHz <= 200)
- {
- clkod = 8;
- }
- else if(nMHz <= 300)
- {
- clkod = 6;
- }
- else if(nMHz <= 550)
- {
- clkod = 4;
- }
- else if(nMHz <= 1100)
+ // freq = (Fin/NR)*NF/OD
+ if(((pCRU_Reg->CRU_MODE_CON>>4)&3) == 1) // DPLL Normal mode
+ dpllvaluel= 24 *((pCRU_Reg->CRU_PLL_CON[1][1]&0xffff)+1) // NF = 2*(CLKF+1)
+ /((((pCRU_Reg->CRU_PLL_CON[1][0]>>8)&0x3f)+1) // NR = CLKR+1
+ *((pCRU_Reg->CRU_PLL_CON[1][0]&0x3F)+1)); // OD = 2^CLKOD
+ else
+ dpllvaluel = 24;
+
+ // freq = (Fin/NR)*NF/OD
+ if(((pCRU_Reg->CRU_MODE_CON>>12)&3) == 1) // GPLL Normal mode
+ gpllvaluel= 24 *((pCRU_Reg->CRU_PLL_CON[3][1]&0xffff)+1) // NF = 2*(CLKF+1)
+ /((((pCRU_Reg->CRU_PLL_CON[3][0]>>8)&0x3f)+1) // NR = CLKR+1
+ *((pCRU_Reg->CRU_PLL_CON[3][0]&0x3F)+1)); // OD = 2^CLKOD
+ else
+ gpllvaluel = 24;
+
+ if(ddr_select_gpll == true)
{
- clkod = 2;
+ if(gpllvaluel > 800)
+ ret = gpllvaluel/4;
+ else if(gpllvaluel > 400)
+ ret = gpllvaluel/2;
+ else
+ ret=gpllvaluel;
}
else
{
- clkod = 1;
+ if(nMHz <= 150)
+ {
+ clkod = 14;
+ }
+ else if(nMHz <= 200)
+ {
+ clkod = 8;
+ }
+ else if(nMHz <= 300)
+ {
+ clkod = 6;
+ }
+ else if(nMHz <= 550)
+ {
+ clkod = 4;
+ }
+ else if(nMHz <= 1100)
+ {
+ clkod = 2;
+ }
+ else
+ {
+ clkod = 1;
+ }
+ clkr = 1;
+ clkf=(nMHz*clkr*clkod)/24;
+ ret = (24*clkf)/(clkr*clkod);
}
- clkr = 1;
- clkf=(nMHz*clkr*clkod)/24;
- ret = (24*clkf)/(clkr*clkod);
+
}
else
{
- pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) + 16)) | (0x0<<(pll_id*4)); //PLL slow-mode
- dsb();
-
- pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_RESET_RK3066B;
- ddr_delayus(1);
- pCRU_Reg->CRU_PLL_CON[pll_id][0] = NR_RK3066B(clkr) | NO_RK3066B(clkod);
- pCRU_Reg->CRU_PLL_CON[pll_id][1] = NF_RK3066B(clkf);
-// pCRU_Reg->CRU_PLL_CON[pll_id][2] = NB(clkf>>1);
- ddr_delayus(1);
- pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_DE_RESET_RK3066B;
- dsb();
- while (delay > 0)
+ if(ddr_select_gpll == true)
{
+ if(gpllvaluel > 800)
+ {
+ pCRU_Reg->CRU_CLKGATE_CON[1] = 0x00800000;
+ pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
+ | (0x1<<8) //clk_ddr_src = G PLL
+ | 2; //clk_ddr_src:clk_ddrphy = 4:1
+ }
+ if(gpllvaluel > 400)
+ {
+ pCRU_Reg->CRU_CLKGATE_CON[1] = 0x00800000;
+ pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
+ | (0x1<<8) //clk_ddr_src = G PLL
+ | 1; //clk_ddr_src:clk_ddrphy = 2:1
+ }
+ else
+ {
+ pCRU_Reg->CRU_CLKGATE_CON[1] = 0x00800000;
+ pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
+ | (0x1<<8) //clk_ddr_src = G PLL
+ | 0; //clk_ddr_src:clk_ddrphy = 1:1
+ }
+ dsb();
+ }
+ else if(nMHz==dpllvaluel)
+ {
+ // ddr_pll_clk: clk_ddr=1:1
+ pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
+ | (0x0<<8) //clk_ddr_src = DDR PLL
+ | 0; //clk_ddr_src:clk_ddrphy = 1:1
+ dsb();
+ }
+ else
+ {
+ pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) + 16)) | (0x0<<(pll_id*4)); //PLL slow-mode
+ dsb();
+
+ pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_RESET_RK3066B;
+ ddr_delayus(1);
+ pCRU_Reg->CRU_PLL_CON[pll_id][0] = NR_RK3066B(clkr) | NO_RK3066B(clkod);
+ pCRU_Reg->CRU_PLL_CON[pll_id][1] = NF_RK3066B(clkf);
+ // pCRU_Reg->CRU_PLL_CON[pll_id][2] = NB(clkf>>1);
ddr_delayus(1);
- if (pGRF_Reg_RK3066B->GRF_SOC_STATUS0 & (0x1<<5))
- break;
- delay--;
+ pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_DE_RESET_RK3066B;
+ dsb();
+ while (delay > 0)
+ {
+ ddr_delayus(1);
+ if (pGRF_Reg_RK3066B->GRF_SOC_STATUS0 & (0x1<<5))
+ break;
+ delay--;
+ }
+
+ pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
+ | (0x0<<8) //clk_ddr_src = DDR PLL
+ | 0; //clk_ddr_src:clk_ddrphy = 1:1
+
+ pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) + 16)) | (0x1<<(pll_id*4)); //PLL normal
+ dsb();
}
-
- pCRU_Reg->CRU_CLKSEL_CON[26] = ((0x3 | (0x1<<8))<<16)
- | (0x0<<8) //clk_ddr_src = DDR PLL
- | 0; //clk_ddr_src:clk_ddrphy = 1:1
-
- pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) + 16)) | (0x1<<(pll_id*4)); //PLL normal
- dsb();
}
out:
return ret;
}
#endif
-uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
+uint32_t __sramfunc ddr_change_freq_sram(uint32_t nMHz)
{
uint32_t ret;
u32 i;
isb();
DDR_SAVE_SP(save_sp);
-#if defined(CONFIG_ARCH_RK3066B)
- for(i=0;i<4;i++) //16KB
- {
- n=temp[1024*i];
- barrier();
- }
-#endif
-#if defined(CONFIG_ARCH_RK3188)
- for(i=0;i<8;i++) //32KB
- {
- n=temp[1024*i];
- barrier();
- }
+#if defined(CONFIG_ARCH_RK30)
+#define SRAM_SIZE RK30_IMEM_SIZE
+#elif defined(CONFIG_ARCH_RK3188)
+#define SRAM_SIZE RK3188_IMEM_SIZE
#endif
-#if defined(CONFIG_ARCH_RK30XX)
- for(i=0;i<16;i++) //64KB
+ for(i=0;i<SRAM_SIZE/4096;i++)
{
n=temp[1024*i];
barrier();
}
-#endif
n= pDDR_Reg->SCFG.d32;
n= pPHY_Reg->RIDR;
dsb();
/** 2. ddr enter self-refresh mode or precharge power-down mode */
- idle_port();
+ idle_port();
#if defined(CONFIG_ARCH_RK3066B)
ddr_set_pll_enter_3168(freq_slew);
#else
local_irq_restore(flags);
return ret;
}
+
+uint32_t ddr_change_freq(uint32_t nMHz)
+{
+#if defined(ENABLE_DDR_CLCOK_GPLL_PATH) && defined(CONFIG_ARCH_RK3188)
+
+ uint32_t freq_gpll;
+ int delay = 1000;
+ uint32_t pll_id=1; //DPLL
+
+ if(((pCRU_Reg->CRU_MODE_CON>>12)&3) == 1) // GPLL Normal mode
+ gpllvaluel= 24 *((pCRU_Reg->CRU_PLL_CON[3][1]&0xffff)+1) // NF = 2*(CLKF+1)
+ /((((pCRU_Reg->CRU_PLL_CON[3][0]>>8)&0x3f)+1) // NR = CLKR+1
+ *((pCRU_Reg->CRU_PLL_CON[3][0]&0x3F)+1)); // OD = 2^CLKOD
+ else
+ gpllvaluel = 24;
+
+ if(200 < gpllvaluel <1600) //GPLL:200MHz~1600MHz
+ {
+ if( gpllvaluel > 800)
+ freq_gpll = gpllvaluel/4;
+ else if( gpllvaluel > 400)
+ freq_gpll = gpllvaluel/2;
+ else
+ freq_gpll = gpllvaluel;
+
+ ddr_select_gpll=true;
+ ddr_change_freq_sram(freq_gpll);
+ ddr_select_gpll=false;
+
+ //set DPLL,when ddr_clock select GPLL
+ if(nMHz <= 150)
+ {
+ clkod = 14;
+ }
+ else if(nMHz <= 200)
+ {
+ clkod = 8;
+ }
+ else if(nMHz <= 300)
+ {
+ clkod = 6;
+ }
+ else if(nMHz <= 550)
+ {
+ clkod = 4;
+ }
+ else if(nMHz <= 1100)
+ {
+ clkod = 2;
+ }
+ else
+ {
+ clkod = 1;
+ }
+ clkr = 1;
+ clkf=(nMHz*clkr*clkod)/24;
+
+ pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) + 16)) | (0x0<<(pll_id*4)); //PLL slow-mode
+ dsb();
+
+ pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_RESET_RK3066B;
+ ddr_delayus(1);
+ pCRU_Reg->CRU_PLL_CON[pll_id][0] = NR_RK3066B(clkr) | NO_RK3066B(clkod);
+ pCRU_Reg->CRU_PLL_CON[pll_id][1] = NF_RK3066B(clkf);
+ // pCRU_Reg->CRU_PLL_CON[pll_id][2] = NB(clkf>>1);
+ ddr_delayus(1);
+ pCRU_Reg->CRU_PLL_CON[pll_id][3] = PLL_DE_RESET_RK3066B;
+ dsb();
+ while (delay > 0)
+ {
+ ddr_delayus(1);
+ if (pGRF_Reg_RK3066B->GRF_SOC_STATUS0 & (0x1<<5))
+ break;
+ delay--;
+ }
+ pCRU_Reg->CRU_MODE_CON = (0x3<<((pll_id*4) + 16)) | (0x1<<(pll_id*4)); //PLL normal
+ //set DPLL end
+ }
+ else
+ {
+ ddr_print("GPLL frequency = %dMHz,Not suitable for ddr_clock \n",gpllvaluel);
+ }
+#endif
+
+ return ddr_change_freq_sram(nMHz);
+
+}
EXPORT_SYMBOL(ddr_change_freq);
void ddr_set_auto_self_refresh(bool en)
flush_cache_all();
outer_flush_all();
//flush_tlb_all();
-
- for(i=0;i<16;i++)
+
+#if defined(CONFIG_ARCH_RK30)
+#define SRAM_SIZE RK30_IMEM_SIZE
+#elif defined(CONFIG_ARCH_RK3188)
+#define SRAM_SIZE RK3188_IMEM_SIZE
+#endif
+ for(i=0;i<SRAM_SIZE/4096;i++)
{
n=temp[1024*i];
barrier();
}
+
n= pDDR_Reg->SCFG.d32;
n= pPHY_Reg->RIDR;
n= pCRU_Reg->CRU_PLL_CON[0][0];
uint32_t die=1;
uint32_t gsr,dqstr;
- ddr_print("version 1.00 20130325 \n");
+ ddr_print("version 1.00 20130427 \n");
mem_type = pPHY_Reg->DCR.b.DDRMD;
ddr_speed_bin = dram_speed_bin;
ddr_adjust_config(mem_type);
if(freq != 0)
- value=ddr_change_freq(freq);
+ value=ddr_change_freq_sram(freq);
else
- value=ddr_change_freq(clk_get_rate(clk_get(NULL, "ddr_pll"))/1000000);
+ value=ddr_change_freq_sram(clk_get_rate(clk_get(NULL, "ddr_pll"))/1000000);
clk_set_rate(clk_get(NULL, "ddr_pll"), 0);
ddr_print("init success!!! freq=%luMHz\n", clk_get_rate(clk_get(NULL, "ddr_pll"))/1000000);