From 9a62e17354926f3f98ba1bbf45de6c6395896950 Mon Sep 17 00:00:00 2001 From: xxm Date: Thu, 24 Apr 2014 17:46:19 +0800 Subject: [PATCH] midgard gpu : 1, dvfs sampling time change to 100ms 2, runtime_off not to set clock when gpu dvfs off 3, new way to get gpu freq table from dts --- .../arm/midgard/mali_kbase_config_defaults.h | 2 +- .../platform/rk/mali_kbase_config_rk.c | 23 ++- .../arm/midgard/platform/rk/mali_kbase_dvfs.c | 145 +++++++++++------- .../midgard/platform/rk/mali_kbase_platform.h | 4 - 4 files changed, 108 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h b/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h index 7c735815b6d1..df3b129ee845 100755 --- a/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h +++ b/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h @@ -164,7 +164,7 @@ /*** Begin Power Manager defaults */ /* Milliseconds */ -#define DEFAULT_PM_DVFS_FREQ 500 +#define DEFAULT_PM_DVFS_FREQ 100 /** * Default poweroff tick granuality, in nanoseconds diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c index 880bba6ddd6d..9d21dbd7b87d 100755 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c +++ b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c @@ -70,7 +70,7 @@ int get_cpu_clock_speed(u32 *cpu_clock); #define KBASE_VE_JS_RESET_TIMEOUT_MS 500 /* 3s before cancelling stuck jobs */ #define KBASE_VE_JS_CTX_TIMESLICE_NS 1000000 /* 1ms - an agressive timeslice for testing purposes (causes lots of scheduling out for >4 ctxs) */ #define KBASE_VE_SECURE_BUT_LOSS_OF_PERFORMANCE ((uintptr_t)MALI_FALSE) /* By default we prefer performance over security on r0p0-15dev0 and KBASE_CONFIG_ATTR_ earlier */ -//#define KBASE_VE_POWER_MANAGEMENT_CALLBACKS ((uintptr_t)&pm_callbacks) +/*#define KBASE_VE_POWER_MANAGEMENT_CALLBACKS ((uintptr_t)&pm_callbacks)*/ #define KBASE_VE_CPU_SPEED_FUNC ((uintptr_t)&get_cpu_clock_speed) static int mali_pm_notifier(struct notifier_block *nb,unsigned long event,void* cmd); @@ -108,14 +108,16 @@ static int mali_pm_notifier(struct notifier_block *nb,unsigned long event,void* switch (event) { case PM_SUSPEND_PREPARE: #ifdef CONFIG_MALI_MIDGARD_DVFS - //if (kbase_platform_dvfs_enable(false, MALI_DVFS_BL_CONFIG_FREQ)!= MALI_TRUE) + /*if (kbase_platform_dvfs_enable(false, MALI_DVFS_BL_CONFIG_FREQ)!= MALI_TRUE)*/ + /*printk("%s,PM_SUSPEND_PREPARE\n",__func__);*/ if (kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) err = NOTIFY_BAD; #endif break; case PM_POST_SUSPEND: #ifdef CONFIG_MALI_MIDGARD_DVFS - //if (kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ)!= MALI_TRUE) + /*if (kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ)!= MALI_TRUE)*/ + /*printk("%s,PM_POST_SUSPEND\n",__func__);*/ if (kbase_platform_dvfs_enable(true, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) err = NOTIFY_BAD; #endif @@ -219,7 +221,8 @@ static int pm_callback_runtime_on(kbase_device *kbdev) kbase_platform_clock_on(kbdev); #ifdef CONFIG_MALI_MIDGARD_DVFS if (platform->dvfs_enabled) { - //if (kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ)!= MALI_TRUE) + /*if (kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ)!= MALI_TRUE)*/ + /*printk("%s\n",__func__);*/ if (kbase_platform_dvfs_enable(true, p_mali_dvfs_infotbl[MALI_DVFS_STEP-1].clock)!= MALI_TRUE) return -EPERM; } else { @@ -232,11 +235,19 @@ static int pm_callback_runtime_on(kbase_device *kbdev) static void pm_callback_runtime_off(kbase_device *kbdev) { +#ifdef CONFIG_MALI_MIDGARD_DVFS + struct rk_context *platform = (struct rk_context *)kbdev->platform_context; +#endif + kbase_platform_clock_off(kbdev); kbase_platform_power_off(kbdev); #ifdef CONFIG_MALI_MIDGARD_DVFS - if (kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) - printk("[err] disabling dvfs is faled\n"); + if (platform->dvfs_enabled) + { + /*printk("%s\n",__func__);*/ + if (kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) + printk("[err] disabling dvfs is faled\n"); + } #endif } diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c index 8e371b6f59e5..5f06b76d6fe1 100755 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c +++ b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c @@ -47,6 +47,11 @@ /* This table and variable are using the check time share of GPU Clock */ /***********************************************************/ +#define level0_min 0 +#define level0_max 70 +#define levelf_max 100 +static u32 div_dvfs = 0 ; + static mali_dvfs_info mali_dvfs_infotbl[] = { {925000, 100000, 0, 70, 0}, {925000, 160000, 50, 65, 0}, @@ -80,7 +85,6 @@ struct mutex mali_enable_clock_lock; #ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS static void update_time_in_state(int level); #endif - /*dvfs status*/ static mali_dvfs_status mali_dvfs_status_current; @@ -88,6 +92,8 @@ static void mali_dvfs_event_proc(struct work_struct *w) { unsigned long flags; mali_dvfs_status *dvfs_status; + static int level_down_time = 0; + static int level_up_time = 0; struct rk_context *platform; mutex_lock(&mali_enable_clock_lock); @@ -97,34 +103,52 @@ static void mali_dvfs_event_proc(struct work_struct *w) mutex_unlock(&mali_enable_clock_lock); return; } - platform = (struct rk_context *)dvfs_status->kbdev->platform_context; spin_lock_irqsave(&mali_dvfs_spinlock, flags); if ((dvfs_status->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) && (dvfs_status->step < MALI_DVFS_STEP-1)) { - #if 0 - if (dvfs_status->step==kbase_platform_dvfs_get_level(450)) - { - if (platform->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) - dvfs_status->step++; - BUG_ON(dvfs_status->step >= MALI_DVFS_STEP); - } - else + level_up_time++; + if(level_up_time == MALI_DVFS_TIME_INTERVAL) { + /* + printk("up,utilisation=%d,current clock=%d,",dvfs_status->utilisation,mali_dvfs_infotbl[dvfs_status->step].clock); + */ dvfs_status->step++; + level_up_time = 0; + /* + printk("next clock=%d\n",mali_dvfs_infotbl[dvfs_status->step].clock); + */ BUG_ON(dvfs_status->step >= MALI_DVFS_STEP); } - #endif - dvfs_status->step++; - BUG_ON(dvfs_status->step >= MALI_DVFS_STEP); + level_down_time = 0; } - //else if((dvfs_status->step > 0) && (dvfs_status->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) - else if((dvfs_status->step > 0) && (platform->time_tick == MALI_DVFS_TIME_INTERVAL) && (platform->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) + else if((dvfs_status->step > 0) && (dvfs_status->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) + /*else if((dvfs_status->step > 0) && (platform->time_tick == MALI_DVFS_TIME_INTERVAL) && (platform->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) */ { - BUG_ON(dvfs_status->step <= 0); - dvfs_status->step--; + level_down_time++; + if(level_down_time==MALI_DVFS_TIME_INTERVAL) + { + /* + printk("down,utilisation=%d,current clock=%d,",dvfs_status->utilisation,mali_dvfs_infotbl[dvfs_status->step].clock); + */ + BUG_ON(dvfs_status->step <= 0); + dvfs_status->step--; + level_down_time = 0; + /* + printk(" next clock=%d\n",mali_dvfs_infotbl[dvfs_status->step].clock); + */ + } + level_up_time = 0; + } + else + { + level_down_time = 0; + level_up_time = 0; + /* + printk("keep,utilisation=%d,current clock=%d\n",dvfs_status->utilisation,mali_dvfs_infotbl[dvfs_status->step].clock); + */ } #ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK if ((dvfs_status->upper_lock >= 0) && (dvfs_status->step > dvfs_status->upper_lock)) @@ -139,7 +163,6 @@ static void mali_dvfs_event_proc(struct work_struct *w) } #endif spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - //printk("%n",__func__); kbase_platform_dvfs_set_level(dvfs_status->kbdev, dvfs_status->step); mutex_unlock(&mali_enable_clock_lock); @@ -242,7 +265,6 @@ int kbase_platform_dvfs_enable(bool enable, int freq) platform->utilisation = 0; dvfs_status->step = kbase_platform_dvfs_get_level(freq); spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - //printk("%s,freq = %d\n",__func__,freq); kbase_platform_dvfs_set_level(dvfs_status->kbdev, dvfs_status->step); } @@ -250,6 +272,44 @@ int kbase_platform_dvfs_enable(bool enable, int freq) return MALI_TRUE; } +#define dividend 7 +#define fix_float(a) ((((a)*dividend)%10)?((((a)*dividend)/10)+1):(((a)*dividend)/10)) +static bool calculate_dvfs_max_min_threshold(u32 level) +{ + u32 pre_level; + u32 tmp ; + if(0 == level) + { + mali_dvfs_infotbl[level].min_threshold = level0_min; + mali_dvfs_infotbl[level].max_threshold = level0_max; + } + else + { + pre_level = level - 1; + if((MALI_DVFS_STEP-1) == level) + { + mali_dvfs_infotbl[level].max_threshold = levelf_max; + } + else + { + mali_dvfs_infotbl[level].max_threshold = mali_dvfs_infotbl[pre_level].max_threshold + div_dvfs; + } + mali_dvfs_infotbl[level].min_threshold = (mali_dvfs_infotbl[pre_level].max_threshold * (mali_dvfs_infotbl[pre_level].clock/1000)) + / (mali_dvfs_infotbl[level].clock/1000); + + tmp = mali_dvfs_infotbl[level].max_threshold - mali_dvfs_infotbl[level].min_threshold; + + mali_dvfs_infotbl[level].min_threshold += fix_float(tmp); + } + #if 1 + printk("mali_dvfs_infotbl[%d].clock=%d,min_threshold=%d,max_threshold=%d\n",level, + mali_dvfs_infotbl[level].clock, + mali_dvfs_infotbl[level].min_threshold, + mali_dvfs_infotbl[level].max_threshold + ); + #endif + return MALI_TRUE; +} int kbase_platform_dvfs_init(struct kbase_device *kbdev) { @@ -277,41 +337,15 @@ int kbase_platform_dvfs_init(struct kbase_device *kbdev) MALI_DVFS_STEP = 0; for (i = 0; mali_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - if((mali_freq_table[i].frequency > 0) && (mali_freq_table[i].frequency <= 100000)) - { - mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; - mali_dvfs_infotbl[i].min_threshold = 0; - mali_dvfs_infotbl[i].max_threshold = 70; - MALI_DVFS_STEP++; - } - else if ((mali_freq_table[i].frequency > 100000) && (mali_freq_table[i].frequency <= 200000)) - { - mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; - mali_dvfs_infotbl[i].min_threshold = 50; - mali_dvfs_infotbl[i].max_threshold = 65; - MALI_DVFS_STEP++; - } - else if ((mali_freq_table[i].frequency > 200000) && (mali_freq_table[i].frequency <= 300000)) - { - mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; - mali_dvfs_infotbl[i].min_threshold = 60; - mali_dvfs_infotbl[i].max_threshold = 78; - MALI_DVFS_STEP++; - } - else if ((mali_freq_table[i].frequency > 300000) && (mali_freq_table[i].frequency <= 400000)) - { - mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; - mali_dvfs_infotbl[i].min_threshold = 65; - mali_dvfs_infotbl[i].max_threshold = 75; - MALI_DVFS_STEP++; - } - else if ((mali_freq_table[i].frequency > 400000) && (mali_freq_table[i].frequency <= 500000)) - { - mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; - mali_dvfs_infotbl[i].min_threshold = 90; - mali_dvfs_infotbl[i].max_threshold = 100; - MALI_DVFS_STEP++; - } + mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; + MALI_DVFS_STEP++; + } + div_dvfs = round_up(((levelf_max - level0_max)/(MALI_DVFS_STEP-1)),1); + printk("MALI_DVFS_STEP=%d,div_dvfs=%d\n",MALI_DVFS_STEP,div_dvfs); + + for(i=0;i= 0 && level > mali_dvfs_status_current.upper_lock) level = mali_dvfs_status_current.upper_lock; @@ -499,6 +533,7 @@ void kbase_platform_dvfs_set_level(kbase_device *kbdev, int level) #ifdef CONFIG_MALI_MIDGARD_DVFS mutex_lock(&mali_set_clock_lock); #endif + kbase_platform_dvfs_set_clock(kbdev, mali_dvfs_infotbl[level].clock); #if defined(CONFIG_MALI_MIDGARD_DEBUG_SYS) && defined(CONFIG_MALI_MIDGARD_DVFS) update_time_in_state(prev_level); diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h index ce017f08a291..8b105b8cf530 100755 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h +++ b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h @@ -19,12 +19,8 @@ struct rk_context { int cmu_pmu_status; /** cmd & pmu lock */ spinlock_t cmu_pmu_lock; - struct clk *clk_mali; struct clk *mali_pd; -#if 1 - struct clk * mali_pd_node; struct dvfs_node * mali_clk_node; -#endif #ifdef CONFIG_MALI_MIDGARD_DVFS /*To calculate utilization for x sec */ int time_tick; -- 2.34.1