From df03e9ee535ff3cac014c286f9f0137fc891f00e Mon Sep 17 00:00:00 2001 From: typ Date: Thu, 22 Aug 2013 17:27:34 +0800 Subject: [PATCH] RK3028A DDR:add 3028a/3026 ddr idle port --- arch/arm/mach-rk2928/ddr.c | 140 +++++++++++++++++++++++++++- arch/arm/plat-rk/ddr_freq.c | 4 - arch/arm/plat-rk/include/plat/ddr.h | 6 +- 3 files changed, 139 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-rk2928/ddr.c b/arch/arm/mach-rk2928/ddr.c index 36dd58e8a0d3..6872f7bf761d 100755 --- a/arch/arm/mach-rk2928/ddr.c +++ b/arch/arm/mach-rk2928/ddr.c @@ -23,6 +23,8 @@ #include #include +#include + typedef uint32_t uint32 ; @@ -152,6 +154,21 @@ GRF_DDRC_STAT ********************************/ //REG FILE registers #if defined (CONFIG_ARCH_RK3026) +//GRF_SOC_STATUS0 +#define sys_pwr_idle (1<<27) +#define gpu_pwr_idle (1<<26) +#define vpu_pwr_idle (1<<25) +#define vio_pwr_idle (1<<24) +#define peri_pwr_idle (1<<23) +#define core_pwr_idle (1<<22) +//GRF_SOC_CON2 +#define core_pwr_idlereq (13) +#define peri_pwr_idlereq (12) +#define vio_pwr_idlereq (11) +#define vpu_pwr_idlereq (10) +#define gpu_pwr_idlereq (9) +#define sys_pwr_idlereq (8) + typedef volatile struct tagREG_FILE { uint32 reserved0[(0xa8-0x0)/4]; @@ -1952,6 +1969,85 @@ __sramfunc void ddr_adjust_config(uint32_t dram_type) DDR_RESTORE_SP(save_sp); } +#if defined (CONFIG_ARCH_RK3026) +void __sramlocalfunc idle_port(void) +{ + int i; + uint32 clk_gate[10]; + + //save clock gate status + for(i=0;i<10;i++) + { + clk_gate[i]=pCRU_Reg->CRU_CLKGATE_CON[i]; + } + //enable all clock gate for request idle + for(i=0;i<10;i++) + { + pCRU_Reg->CRU_CLKGATE_CON[i]=0xffff0000; + } + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+peri_pwr_idlereq))+(1 << peri_pwr_idlereq); //peri bit 12 + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & peri_pwr_idle) == 0);// bit 23 + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+vio_pwr_idlereq))+(1 << vio_pwr_idlereq); //vio + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & vio_pwr_idle) == 0); + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+vpu_pwr_idlereq))+(1 << vpu_pwr_idlereq); //vpu + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & vpu_pwr_idle) == 0); + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+gpu_pwr_idlereq))+(1 << gpu_pwr_idlereq); //gpu + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & gpu_pwr_idle) == 0); + + //resume clock gate status + for(i=0;i<10;i++) + pCRU_Reg->CRU_CLKGATE_CON[i]= (clk_gate[i] | 0xffff0000); +} + + +void __sramlocalfunc deidle_port(void) +{ + int i; + uint32 clk_gate[10]; + + //save clock gate status + for(i=0;i<10;i++) + { + clk_gate[i]=pCRU_Reg->CRU_CLKGATE_CON[i]; + } + //enable all clock gate for request idle + for(i=0;i<10;i++) + { + pCRU_Reg->CRU_CLKGATE_CON[i]=0xffff0000; + } + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+peri_pwr_idlereq))+(0 << peri_pwr_idlereq); //peri bit 12 + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & peri_pwr_idle) != 0); + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+vio_pwr_idlereq))+(0 << vio_pwr_idlereq); //vio + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & vio_pwr_idle) != 0); + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+vpu_pwr_idlereq))+(0 << vpu_pwr_idlereq); //vpu + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & vpu_pwr_idle) != 0); + + pGRF_Reg->GRF_SOC_CON[2] = (1 << (16+gpu_pwr_idlereq))+(0 << gpu_pwr_idlereq); //gpu + dsb(); + while( (pGRF_Reg->GRF_SOC_STATUS0 & gpu_pwr_idle) != 0); + + //resume clock gate status + for(i=0;i<10;i++) + pCRU_Reg->CRU_CLKGATE_CON[i]= (clk_gate[i] | 0xffff0000); + +} +#endif + + /*---------------------------------------------------------------------- Name : void __sramlocalfunc ddr_selfrefresh_enter(uint32 nMHz) Desc : ½øÈë×ÔˢР@@ -2085,7 +2181,7 @@ Params : nMHz -> Return : ƵÂÊÖµ Notes : ----------------------------------------------------------------------*/ -uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) +uint32_t __sramfunc ddr_change_freq_sram(uint32_t nMHz, struct ddr_freq_t ddr_freq_t) { uint32_t ret; u32 i; @@ -2137,7 +2233,34 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) n= *(volatile uint32_t *)SysSrv_DdrConf; n= pGRF_Reg->GRF_SOC_STATUS0; dsb(); - ddr_move_to_Config_state(); + +#if defined (CONFIG_ARCH_RK3026) +#if defined (DDR_CHANGE_FREQ_IN_LCDC_VSYNC) + n = ddr_freq_t.screen_ft_us; + n = ddr_freq_t.t0; + dsb(); + + if(ddr_freq_t.screen_ft_us > 0){ + + ddr_freq_t.t1 = cpu_clock(0); + ddr_freq_t.t2 = (u32)(ddr_freq_t.t1 - ddr_freq_t.t0); //ns + + + if( (ddr_freq_t.t2 > ddr_freq_t.screen_ft_us*1000) && (ddr_freq_t.screen_ft_us != 0xfefefefe)){ + + DDR_RESTORE_SP(save_sp); + local_fiq_enable(); + local_irq_restore(flags); + return 0; + }else{ + rk_fb_poll_wait_frame_complete(); + } + } +#endif + + idle_port(); +#endif + ddr_move_to_Config_state(); ddr_freq = ret; ddr_change_freq_in(freq_slew); ddr_move_to_Lowpower_state(); @@ -2154,6 +2277,11 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) ddr_move_to_Config_state(); ddr_change_freq_out(freq_slew); ddr_move_to_Access_state(); + +#if defined (CONFIG_ARCH_RK3026) + deidle_port(); +#endif + ddr_dtt_check(); /** 5. Issues a Mode Exit command */ DDR_RESTORE_SP(save_sp); @@ -2164,6 +2292,14 @@ out: return ret; } +uint32_t ddr_change_freq(uint32_t nMHz) +{ + struct ddr_freq_t ddr_freq_t; + ddr_freq_t.screen_ft_us = 0; + + return ddr_change_freq_sram(nMHz,ddr_freq_t); +} + EXPORT_SYMBOL(ddr_change_freq); diff --git a/arch/arm/plat-rk/ddr_freq.c b/arch/arm/plat-rk/ddr_freq.c index 9de24f7b1228..5ec16e38b7ef 100755 --- a/arch/arm/plat-rk/ddr_freq.c +++ b/arch/arm/plat-rk/ddr_freq.c @@ -211,11 +211,7 @@ static int _ddr_change_freq_(uint32_t nMHz,struct ddr_freq_t ddr_freq_t) } } -#ifdef CONFIG_ARCH_RK3026 - ret = ddr_change_freq(nMHz); -#else ret = ddr_change_freq_sram(nMHz,ddr_freq_t); -#endif set_other_cpus_pause(false); out: diff --git a/arch/arm/plat-rk/include/plat/ddr.h b/arch/arm/plat-rk/include/plat/ddr.h index dfcab775ed43..bfeedbe2f8ed 100755 --- a/arch/arm/plat-rk/include/plat/ddr.h +++ b/arch/arm/plat-rk/include/plat/ddr.h @@ -153,12 +153,8 @@ struct ddr_freq_t { void __sramfunc ddr_suspend(void); void __sramfunc ddr_resume(void); //void __sramlocalfunc delayus(uint32_t us); -#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) -uint32_t __sramfunc ddr_change_freq(uint32_t nMHz); -#else uint32_t ddr_change_freq(uint32_t nMHz); uint32_t __sramfunc ddr_change_freq_sram(uint32_t nMHz , struct ddr_freq_t ddr_freq_t); -#endif uint32_t ddr_get_cap(void); int ddr_init(uint32_t dram_type, uint32_t freq); void ddr_set_auto_self_refresh(bool en); @@ -168,7 +164,7 @@ uint32_t __sramlocalfunc ddr_set_pll_rk3066b(uint32_t nMHz, uint32_t set); int ddr_get_datatraing_value_3168(bool end_flag,uint32_t dqstr_value,uint32_t min_freq); #endif -#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188) +#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188) || defined(CONFIG_ARCH_RK3026) #define DDR_CHANGE_FREQ_IN_LCDC_VSYNC #endif -- 2.34.1