limit gpu to use size of dma-mem
author杜坤明 <dkm@rockchip.com>
Thu, 30 Dec 2010 07:21:25 +0000 (15:21 +0800)
committer杜坤明 <dkm@rockchip.com>
Thu, 30 Dec 2010 07:21:25 +0000 (15:21 +0800)
drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c

index ec451ae665adf3872a087aa477dc366926e24e9b..55523b990ee7e6f783d679290cac456313161c94 100644 (file)
 *****************************************************************************/
 
 
-
-
 #include "gc_hal.h"
 #include "gc_hal_kernel.h"
 
 #define _GC_OBJ_ZONE    gcvZONE_HARDWARE
 
+#if gcdENABLE_AUTO_FREQ
+#include <linux/time.h>
+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));
index ede2d686e389a7450b7c815893f7b107d5836859..3e1ea984a0aa08a07032589518103fca82e3edd3 100644 (file)
 #   define gcdGPU_TIMEOUT                   0
 #endif
 
+
+/*
+    gcdENABLE_AUTO_FREQ
+
+    ¸ù¾ÝGPU¸ººÉ×Ô¶¯µ÷½ÚGPUµÄCOREƵÂÊ
+*/
+#define gcdENABLE_AUTO_FREQ                 0
+
 #endif /* __gc_hal_options_h_ */
 
index 5804c10d9e96cf7fd3e3657e9f99212c4ec4f19a..38f5f6e335a48d3baefc7c0b6ca15a41f00f2aed 100644 (file)
@@ -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 <linux/timer.h>
+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);
index 7326be92179971e8099c64c3cbc6a59a71aae1c5..04c281491d234c627dd45115c6b523b8af0f3bb5 100644 (file)
@@ -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;