From a44a5fd1e905c814eef53da626b5b9b869d0cec1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E6=9D=9C=E5=9D=A4=E6=98=8E?= Date: Thu, 30 Dec 2010 15:21:25 +0800 Subject: [PATCH] limit gpu to use size of dma-mem --- .../XAQ2/hal/kernel/gc_hal_kernel_hardware.c | 51 +++++++++++++- .../rk29/vivante/hal/inc/gc_hal_options.h | 8 +++ .../os/linux/kernel/gc_hal_kernel_driver.c | 66 ++++++++++++++++++- .../hal/os/linux/kernel/gc_hal_kernel_os.c | 2 +- 4 files changed, 121 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c index ec451ae665ad..55523b990ee7 100644 --- a/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c +++ b/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c @@ -19,13 +19,56 @@ *****************************************************************************/ - - #include "gc_hal.h" #include "gc_hal_kernel.h" #define _GC_OBJ_ZONE gcvZONE_HARDWARE +#if gcdENABLE_AUTO_FREQ +#include +u32 usec_run = 0; +u32 usec_idle = 0; +gceCHIPPOWERSTATE lastState = gcvPOWER_IDLE; +struct timeval tv_on, tv_idle; + +void get_run_idle(u32 *run, u32 *idle) +{ + if(gcvPOWER_IDLE==lastState) + { + do_gettimeofday(&tv_on); + usec_idle += (1000000*(tv_on.tv_sec-tv_idle.tv_sec)+(tv_on.tv_usec-tv_idle.tv_usec)); + tv_idle = tv_on; + *idle = usec_idle; + *run = usec_run; + } else { + do_gettimeofday(&tv_idle); + usec_run += (1000000*(tv_idle.tv_sec-tv_on.tv_sec)+(tv_idle.tv_usec-tv_on.tv_usec)); + tv_on = tv_idle; + *idle = usec_idle; + *run = usec_run; + } + usec_idle = 0; + usec_run = 0; +} + +inline void cal_run_idle(gceCHIPPOWERSTATE State) +{ + if(gcvPOWER_IDLE==lastState && gcvPOWER_ON==State) //gcvPOWER_IDLE->gcvPOWER_ON + { + do_gettimeofday(&tv_on); + usec_idle += (1000000*(tv_on.tv_sec-tv_idle.tv_sec)+(tv_on.tv_usec-tv_idle.tv_usec)); + } + if(gcvPOWER_ON==lastState && gcvPOWER_IDLE==State) //gcvPOWER_ON->gcvPOWER_IDLE + { + do_gettimeofday(&tv_idle); + usec_run += (1000000*(tv_idle.tv_sec-tv_on.tv_sec)+(tv_idle.tv_usec-tv_on.tv_usec)); + } + + lastState = State; +} + +#endif + /******************************************************************************\ ********************************* Support Code ********************************* \******************************************************************************/ @@ -2935,6 +2978,10 @@ gckHARDWARE_SetPowerManagementState( break; } +#if gcdENABLE_AUTO_FREQ + cal_run_idle(State); +#endif + /* Get current process and thread IDs. */ gcmkONERROR(gckOS_GetProcessID(&process)); gcmkONERROR(gckOS_GetThreadID(&thread)); diff --git a/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h b/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h index ede2d686e389..3e1ea984a0aa 100644 --- a/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h +++ b/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h @@ -255,5 +255,13 @@ # define gcdGPU_TIMEOUT 0 #endif + +/* + gcdENABLE_AUTO_FREQ + + ¸ù¾ÝGPU¸ººÉ×Ô¶¯µ÷½ÚGPUµÄCOREƵÂÊ +*/ +#define gcdENABLE_AUTO_FREQ 0 + #endif /* __gc_hal_options_h_ */ diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c index 5804c10d9e96..38f5f6e335a4 100644 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c @@ -63,7 +63,7 @@ module_param(contiguousBase, ulong, 0644); long bankSize = 32 << 20; module_param(bankSize, long, 0644); -int fastClear = 0; //-1; +int fastClear = 0; //-1; module_param(fastClear, int, 0644); int compression = -1; @@ -79,7 +79,7 @@ int showArgs = 0; module_param(showArgs, int, 0644); #if ENABLE_GPU_CLOCK_BY_DRIVER -unsigned long coreClock = 156000000; +unsigned long coreClock = 552*1000000; module_param(coreClock, ulong, 0644); #endif @@ -97,6 +97,57 @@ struct file_operations driver_fops = .mmap = drv_mmap, }; +#if gcdENABLE_AUTO_FREQ +#include +struct timer_list gpu_timer; +extern void get_run_idle(u32 *run, u32 *idle); +int power_cnt = 0; +int last_precent = 0; +int last_freq = 0; +void gputimer_callback(unsigned long arg) +{ + u32 run, idle; + int precent, freq, diff; + struct clk * clk_gpu = clk_get(NULL, "gpu"); + + mod_timer(&gpu_timer, jiffies + HZ/10); + + get_run_idle(&run, &idle); + precent = (int)((run*100)/(run+idle)); + + if(precent<90) { + power_cnt--; + } else if (precent==100){ + power_cnt += 2; + } else { + diff = precent - last_precent; + if(diff>0) { + if(diff>5) power_cnt += 2; + else power_cnt += 1; + } else { + power_cnt--; + } + } + if(power_cnt<0) power_cnt = 0; + if(power_cnt>10) power_cnt = 10; + last_precent = precent; + + if(power_cnt<=0) freq = 360; + else if(power_cnt>=6) freq = 552; + else freq = 456; + + if(freq!=last_freq) { + clk_set_parent(clk_gpu, clk_get(NULL, "general_pll")); + clk_set_rate(clk_get(NULL, "codec_pll"), freq*1000000); + clk_set_rate(clk_gpu, freq*1000000); + clk_set_parent(clk_gpu, clk_get(NULL, "codec_pll")); + } + + last_freq = freq; + printk("%8d /%8d = %3d %%, freq = %dM (%d)\n", (int)run, (int)(run+idle), precent, freq, power_cnt); +} +#endif + int drv_open(struct inode *inode, struct file* filp) { gcsHAL_PRIVATE_DATA_PTR private; @@ -500,8 +551,10 @@ static int drv_init(void) printk("clk_gpu get error: %d\n", retval); return -ENODEV; } + + clk_set_rate(clk_get(NULL, "codec_pll"), coreClock); /* APMU_GC_156M, APMU_GC_624M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently */ - if (clk_set_rate(clk_gpu, 552000000)) //designed on 500M + if (clk_set_rate(clk_gpu, coreClock)) //designed on 500M { gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER, "[galcore] Can't set core clock."); @@ -697,6 +750,13 @@ static int __devinit gpu_probe(struct platform_device *pdev) contiguousBase = res->start; contiguousSize = res->end-res->start; +#if gcdENABLE_AUTO_FREQ + init_timer(&gpu_timer); + gpu_timer.function = gputimer_callback; + gpu_timer.expires = jiffies + 15*HZ; + add_timer(&gpu_timer); +#endif + ret = drv_init(); if(!ret) { platform_set_drvdata(pdev,galDevice); diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c index 7326be921799..04c281491d23 100644 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c @@ -42,7 +42,7 @@ #define _GC_OBJ_ZONE gcvZONE_OS -#define PAGE_ALLOC_LIMIT 0 // ÏÞÖÆPageÉêÇëÊý +#define PAGE_ALLOC_LIMIT 1 // ÏÞÖÆPageÉêÇëÊý #if PAGE_ALLOC_LIMIT int g_pages_alloced = 0; -- 2.34.1