From: cym Date: Sat, 27 Apr 2013 01:30:57 +0000 (+0800) Subject: RK3188:ENABLE_DDR_CLCOK_GPLL_PATH,curtail idle_port and X-Git-Tag: firefly_0821_release~7210 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a82d7889fc73ceb1f9e7b7edb6e2e92ff5443022;p=firefly-linux-kernel-4.4.55.git RK3188:ENABLE_DDR_CLCOK_GPLL_PATH,curtail idle_port and disable fiq/irq time when change_ddr_freq --- diff --git a/arch/arm/mach-rk30/ddr.c b/arch/arm/mach-rk30/ddr.c index 178e715bc3cc..55b6f5d9cdb6 100755 --- a/arch/arm/mach-rk30/ddr.c +++ b/arch/arm/mach-rk30/ddr.c @@ -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) - { - 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; @@ -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 - { - 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;iSCFG.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;iSCFG.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); diff --git a/arch/arm/plat-rk/include/plat/ddr.h b/arch/arm/plat-rk/include/plat/ddr.h index c8187cb7bf48..574afaf778c1 100755 --- a/arch/arm/plat-rk/include/plat/ddr.h +++ b/arch/arm/plat-rk/include/plat/ddr.h @@ -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);