aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c')
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c847
1 files changed, 0 insertions, 847 deletions
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
deleted file mode 100644
index cc1164e..0000000
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/**
- * @file mali_platform_dvfs.c
- * Platform specific Mali driver dvfs functions
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-
-#include <asm/io.h>
-
-#include "mali_device_pause_resume.h"
-#include <linux/workqueue.h>
-
-#define MAX_MALI_DVFS_STEPS 5
-#define MALI_DVFS_WATING 10 // msec
-
-#ifdef CONFIG_CPU_FREQ
-#include <mach/asv.h>
-#define EXYNOS4_ASV_ENABLED
-#endif
-
-#include <plat/cpu.h>
-
-static int bMaliDvfsRun=0;
-
-static _mali_osk_atomic_t bottomlock_status;
-int bottom_lock_step = 0;
-
-typedef struct mali_dvfs_tableTag{
- unsigned int clock;
- unsigned int freq;
- unsigned int vol;
-}mali_dvfs_table;
-
-typedef struct mali_dvfs_statusTag{
- unsigned int currentStep;
- mali_dvfs_table * pCurrentDvfs;
-
-}mali_dvfs_currentstatus;
-
-typedef struct mali_dvfs_thresholdTag{
- unsigned int downthreshold;
- unsigned int upthreshold;
-}mali_dvfs_threshold_table;
-
-typedef struct mali_dvfs_staycount{
- unsigned int staycount;
-}mali_dvfs_staycount_table;
-
-typedef struct mali_dvfs_stepTag{
- int clk;
- int vol;
-}mali_dvfs_step;
-
-mali_dvfs_step step[MALI_DVFS_STEPS]={
- /*step 0 clk*/ {160, 875000},
-#if (MALI_DVFS_STEPS > 1)
- /*step 1 clk*/ {266, 900000},
-#if (MALI_DVFS_STEPS > 2)
- /*step 2 clk*/ {350, 950000},
-#if (MALI_DVFS_STEPS > 3)
- /*step 3 clk*/ {440, 1025000},
-#if (MALI_DVFS_STEPS > 4)
- /*step 4 clk*/ {533, 1075000}
-#endif
-#endif
-#endif
-#endif
-};
-
-mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={
- /*step 0*/{0},
-#if (MALI_DVFS_STEPS > 1)
- /*step 1*/{0},
-#if (MALI_DVFS_STEPS > 2)
- /*step 2*/{0},
-#if (MALI_DVFS_STEPS > 3)
- /*step 3*/{0},
-#if (MALI_DVFS_STEPS > 4)
- /*step 4*/{0}
-#endif
-#endif
-#endif
-#endif
-};
-
-/* dvfs information */
-// L0 = 533Mhz, 1.075V
-// L1 = 440Mhz, 1.025V
-// L2 = 350Mhz, 0.95V
-// L3 = 266Mhz, 0.90V
-// L4 = 160Mhz, 0.875V
-
-int step0_clk = 160;
-int step0_vol = 875000;
-#if (MALI_DVFS_STEPS > 1)
-int step1_clk = 266;
-int step1_vol = 900000;
-int step0_up = 70;
-int step1_down = 62;
-#if (MALI_DVFS_STEPS > 2)
-int step2_clk = 350;
-int step2_vol = 950000;
-int step1_up = 90;
-int step2_down = 85;
-#if (MALI_DVFS_STEPS > 3)
-int step3_clk = 440;
-int step3_vol = 1025000;
-int step2_up = 90;
-int step3_down = 85;
-#if (MALI_DVFS_STEPS > 4)
-int step4_clk = 533;
-int step4_vol = 1075000;
-int step3_up = 90;
-int step4_down = 95;
-#endif
-#endif
-#endif
-#endif
-
-mali_dvfs_table mali_dvfs_all[MAX_MALI_DVFS_STEPS]={
- {160 ,1000000 , 875000},
- {266 ,1000000 , 900000},
- {350 ,1000000 , 950000},
- {440 ,1000000 , 1025000},
- {533 ,1000000 , 1075000} };
-
-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
- {160 ,1000000 , 875000},
-#if (MALI_DVFS_STEPS > 1)
- {266 ,1000000 , 900000},
-#if (MALI_DVFS_STEPS > 2)
- {350 ,1000000 , 950000},
-#if (MALI_DVFS_STEPS > 3)
- {440 ,1000000 ,1025000},
-#if (MALI_DVFS_STEPS > 4)
- {533 ,1000000 ,1075000}
-#endif
-#endif
-#endif
-#endif
-};
-
-mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
- {0 , 70},
-#if (MALI_DVFS_STEPS > 1)
- {62 , 90},
-#if (MALI_DVFS_STEPS > 2)
- {85 , 90},
-#if (MALI_DVFS_STEPS > 3)
- {85 ,90},
-#if (MALI_DVFS_STEPS > 4)
- {95 ,100}
-#endif
-#endif
-#endif
-#endif
-};
-
-#ifdef EXYNOS4_ASV_ENABLED
-#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */
-#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */
-
-static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
- { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */
-#if (MALI_DVFS_STEPS > 1)
- { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */
-#if (MALI_DVFS_STEPS > 2)
- { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */
-#if (MALI_DVFS_STEPS > 3)
- { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */
-#endif
-#endif
-#endif
-};
-
-static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
- { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */
-#if (MALI_DVFS_STEPS > 1)
- { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */
-#if (MALI_DVFS_STEPS > 2)
- { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */
-#if (MALI_DVFS_STEPS > 3)
- { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */
-#endif
-#endif
-#endif
-};
-
-static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = {
- { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000}, /* L4(160Mhz) */
-#if (MALI_DVFS_STEPS > 1)
- { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 862500}, /* L3(266Mhz) */
-#if (MALI_DVFS_STEPS > 2)
- { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 925000, 912500}, /* L2(350Mhz) */
-#if (MALI_DVFS_STEPS > 3)
- { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500, 975000}, /* L1(440Mhz) */
-#if (MALI_DVFS_STEPS > 4)
- { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(600Mhz) */
-#endif
-#endif
-#endif
-#endif
-};
-#endif /* ASV_LEVEL */
-
-/*dvfs status*/
-mali_dvfs_currentstatus maliDvfsStatus;
-int mali_dvfs_control=0;
-
-static u32 mali_dvfs_utilization = 255;
-
-static void mali_dvfs_work_handler(struct work_struct *w);
-
-static struct workqueue_struct *mali_dvfs_wq = 0;
-extern mali_io_address clk_register_map;
-extern _mali_osk_lock_t *mali_dvfs_lock;
-
-int mali_runtime_resumed = -1;
-
-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
-
-/* lock/unlock CPU freq by Mali */
-#include <linux/types.h>
-#include <mach/cpufreq.h>
-
-atomic_t mali_cpufreq_lock;
-
-int cpufreq_lock_by_mali(unsigned int freq)
-{
-#ifdef CONFIG_EXYNOS4_CPUFREQ
-/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */
- unsigned int level;
-
- if (atomic_read(&mali_cpufreq_lock) == 0) {
- if (exynos_cpufreq_get_level(freq * 1000, &level)) {
- printk(KERN_ERR
- "Mali: failed to get cpufreq level for %dMHz",
- freq);
- return -EINVAL;
- }
-
- if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) {
- printk(KERN_ERR
- "Mali: failed to cpufreq lock for L%d", level);
- return -EINVAL;
- }
-
- atomic_set(&mali_cpufreq_lock, 1);
- printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level,
- freq);
- }
-#endif
- return 0;
-}
-
-void cpufreq_unlock_by_mali(void)
-{
-#ifdef CONFIG_EXYNOS4_CPUFREQ
-/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */
- if (atomic_read(&mali_cpufreq_lock) == 1) {
- exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D);
- atomic_set(&mali_cpufreq_lock, 0);
- printk(KERN_DEBUG "Mali: cpufreq locked off\n");
- }
-#endif
-}
-
-static unsigned int get_mali_dvfs_status(void)
-{
- return maliDvfsStatus.currentStep;
-}
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-int get_mali_dvfs_control_status(void)
-{
- return mali_dvfs_control;
-}
-
-mali_bool set_mali_dvfs_current_step(unsigned int step)
-{
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- maliDvfsStatus.currentStep = step % MAX_MALI_DVFS_STEPS;
- if (step >= MAX_MALI_DVFS_STEPS)
- mali_runtime_resumed = maliDvfsStatus.currentStep;
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- return MALI_TRUE;
-}
-#endif
-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
-{
- u32 validatedStep=step;
- int err;
-
-#ifdef CONFIG_REGULATOR
- if (mali_regulator_get_usecount() == 0) {
- MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n"));
- return MALI_FALSE;
- }
-#endif
-
- if (boostup) {
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
- } else {
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
- }
-
-#ifdef EXYNOS4_ASV_ENABLED
- if (samsung_rev() < EXYNOS4412_REV_2_0) {
- if (mali_dvfs[step].clock == 160)
- exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
- else
- exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
- }
-#endif
-
-
- set_mali_dvfs_current_step(validatedStep);
- /*for future use*/
- maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
-
-#if CPUFREQ_LOCK_DURING_440
- /* lock/unlock CPU freq by Mali */
- if (mali_dvfs[step].clock == 440)
- err = cpufreq_lock_by_mali(1200);
- else
- cpufreq_unlock_by_mali();
-#endif
-
- return MALI_TRUE;
-}
-
-static void mali_platform_wating(u32 msec)
-{
- /*sample wating
- change this in the future with proper check routine.
- */
- unsigned int read_val;
- while(1) {
- read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
- if ((read_val & 0x8000)==0x0000) break;
- _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218
- }
- /* _mali_osk_time_ubusydelay(msec*1000);*/
-}
-
-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
-{
-
- MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
-
- if (!set_mali_dvfs_status(step, boostup)) {
- MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
- return MALI_FALSE;
- }
-
- /*wait until clock and voltage is stablized*/
- mali_platform_wating(MALI_DVFS_WATING); /*msec*/
-
- return MALI_TRUE;
-}
-
-#ifdef EXYNOS4_ASV_ENABLED
-extern unsigned int exynos_result_of_asv;
-
-static mali_bool mali_dvfs_table_update(void)
-{
- unsigned int i;
- unsigned int step_num = MALI_DVFS_STEPS;
-
- if(samsung_rev() < EXYNOS4412_REV_2_0)
- step_num = MALI_DVFS_STEPS - 1;
-
- if(soc_is_exynos4412()) {
- if (exynos_armclk_max == 1000000) {
- MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
- }
- } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) {
- MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000;
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol));
- }
- } else if (samsung_rev() >= EXYNOS4412_REV_2_0) {
- MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
- }
- } else {
- MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
- }
- }
- }
-
- return MALI_TRUE;
-}
-#endif
-
-static unsigned int decideNextStatus(unsigned int utilization)
-{
- static unsigned int level = 0; // 0:stay, 1:up
- static int mali_dvfs_clk = 0;
-
- if (mali_runtime_resumed >= 0) {
- level = mali_runtime_resumed;
- mali_runtime_resumed = -1;
- }
-
- if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold
- <= mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) {
- MALI_PRINT(("upthreadshold is smaller than downthreshold: %d < %d\n",
- mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold,
- mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold));
- return level;
- }
-
- if (!mali_dvfs_control && level == maliDvfsStatus.currentStep) {
- if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) &&
- level < MALI_DVFS_STEPS - 1) {
- level++;
- if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
- level=get_mali_dvfs_status();
- }
- }
- if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) &&
- level > 0) {
- level--;
- }
- } else if (mali_dvfs_control == 999) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[i].clock;
- }
-#ifdef EXYNOS4_ASV_ENABLED
- mali_dvfs_table_update();
-#endif
- i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs[i].clock = step[i].clk;
- }
- mali_dvfs_control = 0;
- level = 0;
-
- step0_clk = step[0].clk;
- change_dvfs_tableset(step0_clk, 0);
-#if (MALI_DVFS_STEPS > 1)
- step1_clk = step[1].clk;
- change_dvfs_tableset(step1_clk, 1);
-#if (MALI_DVFS_STEPS > 2)
- step2_clk = step[2].clk;
- change_dvfs_tableset(step2_clk, 2);
-#if (MALI_DVFS_STEPS > 3)
- step3_clk = step[3].clk;
- change_dvfs_tableset(step3_clk, 3);
-#if (MALI_DVFS_STEPS > 4)
- step4_clk = step[4].clk;
- change_dvfs_tableset(step4_clk, 4);
-#endif
-#endif
-#endif
-#endif
- } else if (mali_dvfs_control != mali_dvfs_clk && mali_dvfs_control != 999) {
- if (mali_dvfs_control < mali_dvfs_all[1].clock && mali_dvfs_control > 0) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[0].clock;
- }
- maliDvfsStatus.currentStep = 0;
- } else if (mali_dvfs_control < mali_dvfs_all[2].clock && mali_dvfs_control >= mali_dvfs_all[1].clock) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[1].clock;
- }
- maliDvfsStatus.currentStep = 1;
- } else if (mali_dvfs_control < mali_dvfs_all[3].clock && mali_dvfs_control >= mali_dvfs_all[2].clock) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[2].clock;
- }
- maliDvfsStatus.currentStep = 2;
- } else if (mali_dvfs_control < mali_dvfs_all[4].clock && mali_dvfs_control >= mali_dvfs_all[3].clock) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[3].clock;
- }
- maliDvfsStatus.currentStep = 3;
- } else {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[4].clock;
- }
- maliDvfsStatus.currentStep = 4;
- }
- step0_clk = step[0].clk;
- change_dvfs_tableset(step0_clk, 0);
-#if (MALI_DVFS_STEPS > 1)
- step1_clk = step[1].clk;
- change_dvfs_tableset(step1_clk, 1);
-#if (MALI_DVFS_STEPS > 2)
- step2_clk = step[2].clk;
- change_dvfs_tableset(step2_clk, 2);
-#if (MALI_DVFS_STEPS > 3)
- step3_clk = step[3].clk;
- change_dvfs_tableset(step3_clk, 3);
-#if (MALI_DVFS_STEPS > 4)
- step4_clk = step[4].clk;
- change_dvfs_tableset(step4_clk, 4);
-#endif
-#endif
-#endif
-#endif
- level = maliDvfsStatus.currentStep;
- }
-
- mali_dvfs_clk = mali_dvfs_control;
-
- if (_mali_osk_atomic_read(&bottomlock_status) > 0) {
- if (level < bottom_lock_step)
- level = bottom_lock_step;
- }
-
- return level;
-}
-
-static mali_bool mali_dvfs_status(u32 utilization)
-{
- unsigned int nextStatus = 0;
- unsigned int curStatus = 0;
- mali_bool boostup = MALI_FALSE;
- static int stay_count = 0;
-#ifdef EXYNOS4_ASV_ENABLED
- static mali_bool asv_applied = MALI_FALSE;
-#endif
-
- MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization));
-#ifdef EXYNOS4_ASV_ENABLED
- if (asv_applied == MALI_FALSE) {
- mali_dvfs_table_update();
- change_mali_dvfs_status(1, 0);
- asv_applied = MALI_TRUE;
-
- return MALI_TRUE;
- }
-#endif
-
- /*decide next step*/
- curStatus = get_mali_dvfs_status();
- nextStatus = decideNextStatus(utilization);
-
- MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
-
- /*if next status is same with current status, don't change anything*/
- if ((curStatus != nextStatus && stay_count == 0)) {
- /*check if boost up or not*/
- if (nextStatus > maliDvfsStatus.currentStep) boostup = 1;
-
- /*change mali dvfs status*/
- if (!change_mali_dvfs_status(nextStatus,boostup)) {
- MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
- return MALI_FALSE;
- }
- stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount;
- } else {
- if (stay_count > 0)
- stay_count--;
- }
-
- return MALI_TRUE;
-}
-
-
-
-int mali_dvfs_is_running(void)
-{
- return bMaliDvfsRun;
-
-}
-
-
-
-void mali_dvfs_late_resume(void)
-{
- // set the init clock as low when resume
- set_mali_dvfs_status(0,0);
-}
-
-
-static void mali_dvfs_work_handler(struct work_struct *w)
-{
- int change_clk = 0;
- int change_step = 0;
- bMaliDvfsRun=1;
-
- /* dvfs table change when clock was changed */
- if (step0_clk != mali_dvfs[0].clock) {
- MALI_PRINT(("::: step0_clk change to %d Mhz\n", step0_clk));
- change_clk = step0_clk;
- change_step = 0;
- step0_clk = change_dvfs_tableset(change_clk, change_step);
- }
-#if (MALI_DVFS_STEPS > 1)
- if (step1_clk != mali_dvfs[1].clock) {
- MALI_PRINT(("::: step1_clk change to %d Mhz\n", step1_clk));
- change_clk = step1_clk;
- change_step = 1;
- step1_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step0_up != mali_dvfs_threshold[0].upthreshold) {
- MALI_PRINT(("::: step0_up change to %d %\n", step0_up));
- mali_dvfs_threshold[0].upthreshold = step0_up;
- }
- if (step1_down != mali_dvfs_threshold[1].downthreshold) {
- MALI_PRINT((":::step1_down change to %d %\n", step1_down));
- mali_dvfs_threshold[1].downthreshold = step1_down;
- }
-#if (MALI_DVFS_STEPS > 2)
- if (step2_clk != mali_dvfs[2].clock) {
- MALI_PRINT(("::: step2_clk change to %d Mhz\n", step2_clk));
- change_clk = step2_clk;
- change_step = 2;
- step2_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step1_up != mali_dvfs_threshold[1].upthreshold) {
- MALI_PRINT((":::step1_up change to %d %\n", step1_up));
- mali_dvfs_threshold[1].upthreshold = step1_up;
- }
- if (step2_down != mali_dvfs_threshold[2].downthreshold) {
- MALI_PRINT((":::step2_down change to %d %\n", step2_down));
- mali_dvfs_threshold[2].downthreshold = step2_down;
- }
-#if (MALI_DVFS_STEPS > 3)
- if (step3_clk != mali_dvfs[3].clock) {
- MALI_PRINT(("::: step3_clk change to %d Mhz\n", step3_clk));
- change_clk = step3_clk;
- change_step = 3;
- step3_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step2_up != mali_dvfs_threshold[2].upthreshold) {
- MALI_PRINT((":::step2_up change to %d %\n", step2_up));
- mali_dvfs_threshold[2].upthreshold = step2_up;
- }
- if (step3_down != mali_dvfs_threshold[3].downthreshold) {
- MALI_PRINT((":::step3_down change to %d %\n", step3_down));
- mali_dvfs_threshold[3].downthreshold = step3_down;
- }
-#if (MALI_DVFS_STEPS > 4)
- if (step4_clk != mali_dvfs[4].clock) {
- MALI_PRINT(("::: step4_clk change to %d Mhz\n", step4_clk));
- change_clk = step4_clk;
- change_step = 4;
- step4_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step3_up != mali_dvfs_threshold[3].upthreshold) {
- MALI_PRINT((":::step3_up change to %d %\n", step3_up));
- mali_dvfs_threshold[3].upthreshold = step3_up;
- }
- if (step4_down != mali_dvfs_threshold[4].downthreshold) {
- MALI_PRINT((":::step4_down change to %d %\n", step4_down));
- mali_dvfs_threshold[4].downthreshold = step4_down;
- }
-#endif
-#endif
-#endif
-#endif
-
-
-#ifdef DEBUG
- mali_dvfs[0].vol = step0_vol;
- mali_dvfs[1].vol = step1_vol;
- mali_dvfs[2].vol = step2_vol;
- mali_dvfs[3].vol = step3_vol;
- mali_dvfs[4].vol = step4_vol;
-#endif
- MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
-
- if (!mali_dvfs_status(mali_dvfs_utilization))
- MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
-
- bMaliDvfsRun=0;
-}
-
-mali_bool init_mali_dvfs_status(int step)
-{
- /*default status
- add here with the right function to get initilization value.
- */
- if (!mali_dvfs_wq)
- mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
-
- _mali_osk_atomic_init(&bottomlock_status, 0);
-
- /*add a error handling here*/
- set_mali_dvfs_current_step(step);
-
- return MALI_TRUE;
-}
-
-void deinit_mali_dvfs_status(void)
-{
- if (mali_dvfs_wq)
- destroy_workqueue(mali_dvfs_wq);
-
- _mali_osk_atomic_term(&bottomlock_status);
-
- mali_dvfs_wq = NULL;
-}
-
-mali_bool mali_dvfs_handler(u32 utilization)
-{
- mali_dvfs_utilization = utilization;
- queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work);
-
- /*add error handle here*/
- return MALI_TRUE;
-}
-
-int change_dvfs_tableset(int change_clk, int change_step)
-{
- int err;
-
- if (change_clk < mali_dvfs_all[1].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[0].clock;
- } else if (change_clk < mali_dvfs_all[2].clock && change_clk >= mali_dvfs_all[1].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[1].clock;
- } else if (change_clk < mali_dvfs_all[3].clock && change_clk >= mali_dvfs_all[2].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[2].clock;
- } else if (change_clk < mali_dvfs_all[4].clock && change_clk >= mali_dvfs_all[3].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[3].clock;
- } else {
- mali_dvfs[change_step].clock = mali_dvfs_all[4].clock;
- }
-
- MALI_PRINT((":::mali dvfs step %d clock and voltage = %d Mhz, %d V\n",change_step, mali_dvfs[change_step].clock, mali_dvfs[change_step].vol));
-
- if (maliDvfsStatus.currentStep == change_step) {
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[change_step].vol, mali_dvfs[change_step].vol);
-#endif
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[change_step].clock, mali_dvfs[change_step].freq);
-
-#if CPUFREQ_LOCK_DURING_440
- /* lock/unlock CPU freq by Mali */
- if (mali_dvfs[change_step].clock == 440)
- err = cpufreq_lock_by_mali(1200);
- else
- cpufreq_unlock_by_mali();
-#endif
- }
-
- return mali_dvfs[change_step].clock;
-}
-
-void mali_default_step_set(int step, mali_bool boostup)
-{
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-
- if (maliDvfsStatus.currentStep == 1)
- set_mali_dvfs_status(step, boostup);
-}
-
-int mali_dvfs_bottom_lock_push(int lock_step)
-{
- int prev_status = _mali_osk_atomic_read(&bottomlock_status);
-
- if (prev_status < 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for push\n"));
- return -1;
- }
- if (bottom_lock_step < lock_step) {
- bottom_lock_step = lock_step;
- if (get_mali_dvfs_status() < lock_step) {
- mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol);
- mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq);
- set_mali_dvfs_current_step(lock_step);
- }
- }
- return _mali_osk_atomic_inc_return(&bottomlock_status);
-}
-
-int mali_dvfs_bottom_lock_pop(void)
-{
- int prev_status = _mali_osk_atomic_read(&bottomlock_status);
- if (prev_status <= 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for pop\n"));
- return -1;
- } else if (prev_status == 1) {
- bottom_lock_step = 0;
- MALI_PRINT(("gpu bottom lock release\n"));
- }
-
- return _mali_osk_atomic_dec_return(&bottomlock_status);
-}
-
-int mali_dvfs_get_vol(int step)
-{
- step = step % MAX_MALI_DVFS_STEPS;
- MALI_DEBUG_ASSERT(step<MAX_MALI_DVFS_STEPS);
-
- return mali_dvfs[step].vol;
-}
-
-#if MALI_VOLTAGE_LOCK
-int mali_vol_get_from_table(int vol)
-{
- int i;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- if (mali_dvfs[i].vol >= vol)
- return mali_dvfs[i].vol;
- }
- MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol));
- return 0;
-}
-#endif