RK3188:ENABLE_DDR_CLCOK_GPLL_PATH,curtail idle_port and

disable fiq/irq time when change_ddr_freq
This commit is contained in:
cym
2013-04-27 09:30:57 +08:00
parent 6d6f4f61d6
commit a82d7889fc
2 changed files with 224 additions and 70 deletions

View File

@@ -24,6 +24,8 @@
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
@@ -1447,6 +1449,11 @@ void __sramlocalfunc ddr_set_dll_bypass(uint32 freq)
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
@@ -1548,61 +1555,126 @@ uint32_t __sramlocalfunc ddr_set_pll_rk3066b(uint32_t nMHz, uint32_t set)
if(!set)
{
if(nMHz <= 150)
// 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 = 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;
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)
{
ddr_delayus(1);
if (pGRF_Reg_RK3066B->GRF_SOC_STATUS0 & (0x1<<5))
break;
delay--;
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);
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;
@@ -3318,7 +3390,7 @@ void __sramlocalfunc ddr_set_pll_exit_3168(uint32 freq_slew,uint32_t dqstr_value
}
#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;
@@ -3365,27 +3437,16 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
isb();
DDR_SAVE_SP(save_sp);
#if defined(CONFIG_ARCH_RK3066B)
for(i=0;i<4;i++) //16KB
#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();
}
#endif
#if defined(CONFIG_ARCH_RK3188)
for(i=0;i<8;i++) //32KB
{
n=temp[1024*i];
barrier();
}
#endif
#if defined(CONFIG_ARCH_RK30XX)
for(i=0;i<16;i++) //64KB
{
n=temp[1024*i];
barrier();
}
#endif
n= pDDR_Reg->SCFG.d32;
n= pPHY_Reg->RIDR;
@@ -3400,7 +3461,7 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
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
@@ -3428,6 +3489,93 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
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)
@@ -3447,12 +3595,18 @@ void __sramfunc ddr_suspend(void)
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];
@@ -3602,7 +3756,7 @@ int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
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;
@@ -3644,9 +3798,9 @@ int ddr_init(uint32_t dram_speed_bin, uint32_t freq)
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);

View File

@@ -146,7 +146,7 @@
void __sramfunc ddr_suspend(void);
void __sramfunc ddr_resume(void);
//void __sramlocalfunc delayus(uint32_t us);
uint32_t __sramfunc ddr_change_freq(uint32_t nMHz);
uint32_t ddr_change_freq(uint32_t nMHz);
uint32_t ddr_get_cap(void);
int ddr_init(uint32_t dram_type, uint32_t freq);
void ddr_set_auto_self_refresh(bool en);