summaryrefslogtreecommitdiff
path: root/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c')
-rw-r--r--drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c973
1 files changed, 0 insertions, 973 deletions
diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c
deleted file mode 100644
index 097115b0049..00000000000
--- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c
+++ /dev/null
@@ -1,973 +0,0 @@
-/* drivers/gpu/mali400/mali/platform/exynos3472/exynos4_pmm.c
- *
- * Copyright 2011 by S.LSI. Samsung Electronics Inc.
- * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
- *
- * Samsung SoC Mali400 DVFS driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software FoundatIon.
- */
-
-/**
- * @file exynos4_pmm.c
- * Platform specific Mali driver functions for the exynos 4XXX based platforms
- */
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "exynos4_pmm.h"
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-
-#if defined(CONFIG_MALI400_PROFILING)
-#include "mali_osk_profiling.h"
-#endif
-
-/* lock/unlock CPU freq by Mali */
-#include <linux/types.h>
-#include <mach/cpufreq.h>
-#include <mach/regs-clock.h>
-#include <mach/asv-exynos.h>
-#ifdef CONFIG_CPU_FREQ
-#define EXYNOS4_ASV_ENABLED
-#endif
-
-/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
-#ifndef S5P_G3D_CONFIGURATION
-#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION
-#endif
-#ifndef S5P_G3D_STATUS
-#define S5P_G3D_STATUS (EXYNOS4_G3D_CONFIGURATION + 0x4)
-#endif
-#ifndef S5P_INT_LOCAL_PWR_EN
-#define S5P_INT_LOCAL_PWR_EN EXYNOS_INT_LOCAL_PWR_EN
-#endif
-
-#include <asm/io.h>
-#include <mach/regs-pmu.h>
-#include <linux/workqueue.h>
-
-#define MALI_DVFS_STEPS 4
-
-#define MALI_DVFS_WATING 10 /* msec */
-#define MALI_DVFS_DEFAULT_STEP 0
-#define PD_G3D_LOCK_FLAG 2
-
-#define MALI_DVFS_CLK_DEBUG 0
-#define CPUFREQ_LOCK_DURING_440 1
-
-static int bMaliDvfsRun = 0;
-
-typedef struct mali_dvfs_tableTag{
- unsigned int clock;
- unsigned int freq;
- unsigned int vol;
- unsigned int downthreshold;
- unsigned int upthreshold;
-}mali_dvfs_table;
-
-typedef struct mali_dvfs_statusTag{
- unsigned int currentStep;
- mali_dvfs_table * pCurrentDvfs;
-
-} mali_dvfs_status_t;
-
-/*dvfs status*/
-mali_dvfs_status_t maliDvfsStatus;
-int mali_dvfs_control;
-
-typedef struct mali_runtime_resumeTag{
- int clk;
- int vol;
- unsigned int step;
-}mali_runtime_resume_table;
-
-mali_runtime_resume_table mali_runtime_resume = {266, 875000, 1};
-
-/* dvfs table updated on 140227 */
-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
- /*step 0*/{160, 1000000, 875000, 0, 70},
- /*step 1*/{266, 1000000, 875000, 62, 90},
- /*step 2*/{350, 1000000, 925000, 85, 90},
- /*step 3*/{440, 1000000, 1000000, 85, 100} };
-
-
-char *mali_freq_table = "440 350 266 160";
-
-#define EXTXTALCLK_NAME "ext_xtal"
-#define VPLLSRCCLK_NAME "mout_vpllsrc"
-#define FOUTVPLLCLK_NAME "fout_vpll"
-#define SCLEPLLCLK_NAME "sclk_epll_muxed"
-#define SCLVPLLCLK_NAME "mout_vpll"
-#define GPUMOUT1CLK_NAME "mout_g3d1"
-#define MPLLCLK_NAME "mout_mpll"
-#define SCLK_MPLL_PRE_DIV_CLK_NAME "sclk_mpll_pre_div"
-#define GPUMOUT0CLK_NAME "mout_g3d0"
-#define GPUCLK_NAME "sclk_g3d"
-#define CLK_DIV_STAT_G3D 0x1003C62C
-#define CLK_DESC "clk-divider-status"
-
-static struct clk *ext_xtal_clock = NULL;
-static struct clk *vpll_src_clock = NULL;
-static struct clk *mpll_clock = NULL;
-static struct clk *sclk_mpll_pre_div_clock;
-static struct clk *mali_mout0_clock;
-static struct clk *fout_vpll_clock = NULL;
-static struct clk *sclk_epll_clock;
-static struct clk *sclk_vpll_clock = NULL;
-static struct clk *mali_parent_clock;
-static struct clk *mali_clock = NULL;
-
-/* Exynos3472 */
-int mali_gpu_clk = 266;
-int mali_gpu_vol = 875000;
-static unsigned int GPU_MHZ = 1000000;
-static unsigned int const GPU_ASV_VOLT = 1000;
-static int nPowermode;
-static atomic_t clk_active;
-
-mali_io_address clk_register_map = 0;
-
-/* export GPU frequency as a read-only parameter so that it can be read in /sys */
-module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH);
-module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH);
-module_param(mali_freq_table, charp, S_IRUSR | S_IRGRP | S_IROTH);
-#ifdef CONFIG_MALI_DVFS
-module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
-DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state);
-MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS");
-#endif
-MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock");
-MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
-MODULE_PARM_DESC(mali_freq_table, "Mali frequency table");
-
-#ifdef CONFIG_REGULATOR
-struct regulator *g3d_regulator = NULL;
-#endif
-atomic_t mali_cpufreq_lock;
-
-/* DVFS */
-#ifdef CONFIG_MALI_DVFS
-static unsigned int mali_dvfs_utilization = 255;
-static void update_time_in_state(int level);
-u64 mali_dvfs_time[MALI_DVFS_STEPS];
-#endif
-
-static void mali_dvfs_work_handler(struct work_struct *w);
-static struct workqueue_struct *mali_dvfs_wq = 0;
-_mali_osk_mutex_t *mali_dvfs_lock;
-int mali_runtime_resumed = -1;
-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
-
-int cpufreq_lock_by_mali(unsigned int freq)
-{
-#ifdef CONFIG_EXYNOS4_CPUFREQ
- 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 (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
-}
-
-#ifdef CONFIG_REGULATOR
-void mali_regulator_disable(void)
-{
- if(IS_ERR_OR_NULL(g3d_regulator))
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
- return;
- }
- regulator_disable(g3d_regulator);
-}
-
-void mali_regulator_enable(void)
-{
- if(IS_ERR_OR_NULL(g3d_regulator))
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
- return;
- }
- regulator_enable(g3d_regulator);
-}
-
-void mali_regulator_set_voltage(int min_uV, int max_uV)
-{
- _mali_osk_mutex_wait(mali_dvfs_lock);
- if(IS_ERR_OR_NULL(g3d_regulator))
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
- _mali_osk_mutex_signal(mali_dvfs_lock);
- return;
- }
- MALI_DEBUG_PRINT(1, ("= regulator_set_voltage: %d, %d \n", min_uV, max_uV));
- regulator_set_voltage(g3d_regulator, min_uV, max_uV);
- mali_gpu_vol = regulator_get_voltage(g3d_regulator);
- MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
- _mali_osk_mutex_signal(mali_dvfs_lock);
-}
-#endif
-
-#ifdef CONFIG_MALI_DVFS
-static unsigned int get_mali_dvfs_status(void)
-{
- return maliDvfsStatus.currentStep;
-}
-#endif
-
-mali_bool mali_clk_get(void)
-{
- if (ext_xtal_clock == NULL) {
- ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME);
- if (IS_ERR(ext_xtal_clock)) {
- MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (vpll_src_clock == NULL) {
- vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME);
- if (IS_ERR(vpll_src_clock)) {
- MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (fout_vpll_clock == NULL) {
- fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME);
- if (IS_ERR(fout_vpll_clock)) {
- MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mpll_clock == NULL)
- {
- mpll_clock = clk_get(NULL,MPLLCLK_NAME);
-
- if (IS_ERR(mpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (sclk_epll_clock == NULL) {
- sclk_epll_clock = clk_get(NULL, SCLEPLLCLK_NAME);
- if (IS_ERR(sclk_epll_clock)) {
- MALI_PRINT(("MALI Error : failed to get source sclk_epll_clock\n"));
- }
- }
-
- if (sclk_mpll_pre_div_clock == NULL) {
- sclk_mpll_pre_div_clock = clk_get(NULL, SCLK_MPLL_PRE_DIV_CLK_NAME);
-
- if (IS_ERR(sclk_mpll_pre_div_clock)) {
- MALI_PRINT(("MALI Error : failed to get source sclk_mpll_pre_div clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_mout0_clock == NULL)
- {
- mali_mout0_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
-
- if (IS_ERR(mali_mout0_clock)) {
- MALI_PRINT(("MALI Error : failed to get source mali mout0 clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (sclk_vpll_clock == NULL) {
- sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME);
- if (IS_ERR(sclk_vpll_clock)) {
- MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_parent_clock == NULL) {
- mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
- if (IS_ERR(mali_parent_clock)) {
- MALI_PRINT(("MALI Error : failed to get source mali parent clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_clock == NULL) {
- mali_clock = clk_get(NULL, GPUCLK_NAME);
- if (IS_ERR(mali_clock)) {
- MALI_PRINT(("MALI Error : failed to get source mali clock\n"));
- return MALI_FALSE;
- }
- }
-
- return MALI_TRUE;
-}
-
-void mali_clk_put(mali_bool binc_mali_clock)
-{
- if (mali_parent_clock) {
- clk_put(mali_parent_clock);
- mali_parent_clock = NULL;
- }
-
- if (sclk_vpll_clock) {
- clk_put(sclk_vpll_clock);
- sclk_vpll_clock = NULL;
- }
-
- if (binc_mali_clock && fout_vpll_clock) {
- clk_put(fout_vpll_clock);
- fout_vpll_clock = NULL;
- }
-
- if (sclk_epll_clock) {
- clk_put(sclk_epll_clock);
- sclk_epll_clock = NULL;
- }
-
- if (mpll_clock) {
- clk_put(mpll_clock);
- mpll_clock = NULL;
- }
-
- if (sclk_mpll_pre_div_clock) {
- clk_put(sclk_mpll_pre_div_clock);
- sclk_mpll_pre_div_clock = NULL;
- }
-
- if (mali_mout0_clock) {
- clk_put(mali_mout0_clock);
- mali_mout0_clock = NULL;
- }
-
- if (vpll_src_clock) {
- clk_put(vpll_src_clock);
- vpll_src_clock = NULL;
- }
-
- if (ext_xtal_clock) {
- clk_put(ext_xtal_clock);
- ext_xtal_clock = NULL;
- }
-
- if (binc_mali_clock && mali_clock) {
- clk_put(mali_clock);
- mali_clock = NULL;
- }
-}
-
-void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
-{
- int err;
- unsigned int read_val;
- unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
- unsigned long CurRate = 0;
-
- _mali_osk_mutex_wait(mali_dvfs_lock);
- MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
-
- if (mali_clk_get() == MALI_FALSE) {
- _mali_osk_mutex_signal(mali_dvfs_lock);
- return;
- }
-
- CurRate = clk_get_rate(mali_clock);
-
- if (CurRate == 0) {
- _mali_osk_mutex_signal(mali_dvfs_lock);
- MALI_PRINT_ERROR(("clk_get_rate[mali_clock] is 0 - return\n"));
- return;
- }
-
- /* Use MPLL 200Mhz for a moment */
- err = clk_set_rate(mali_clock, CurRate / 4);
-
- if (err > 0)
- MALI_PRINT_ERROR(("Failed to set Mali clock before change PLL: %d\n", err));
-
- err = clk_set_parent(mali_mout0_clock, sclk_mpll_pre_div_clock);
-
- if (err)
- MALI_PRINT_ERROR(("mali_mout0_clock set parent to sclk_mpll_pre_div_clock failed\n"));
-
- err = clk_set_parent(mali_clock, mali_mout0_clock);
-
- if (err)
- MALI_PRINT_ERROR(("mali_clock set parent to mali_mout0_clock failed\n"));
-
- err = clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ);
-
- if (err > 0)
- MALI_PRINT_ERROR(("Failed to set fout_vpll clock: %d\n", err));
-
-
- err = clk_set_parent(vpll_src_clock, ext_xtal_clock);
-
- if (err)
- MALI_PRINT_ERROR(("vpll_src set parent to ext_xtal failed\n"));
-
- err = clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
-
- if (err)
- MALI_PRINT_ERROR(("sclk_vpll set parent to fout_vpll failed\n"));
-
- MALI_DEBUG_PRINT(3, ("Mali platform: set_parent_vpll : %8.x \n", (__raw_readl(EXYNOS4_CLKSRC_TOP0) >> 8) & 0x1));
-
- err = clk_set_parent(mali_parent_clock, sclk_vpll_clock);
-
- if (err)
- MALI_PRINT_ERROR(("mali_parent set parent to sclk_vpll failed\n"));
-
- do {
- cpu_relax();
- read_val = __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0);
- } while (((read_val >> 4) & 0x7) != 0x2);
-
- MALI_DEBUG_PRINT(3, ("SET to VPLL EXYNOS4_CLKMUX_STAT_G3D0 : 0x%08x\n", __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0)));
-
- err = clk_set_parent(mali_clock, mali_parent_clock);
-
- if (err)
- MALI_PRINT_ERROR(("mali_clock set parent to mali_parent failed\n"));
-
- if (atomic_read(&clk_active) == 0) {
- if (clk_enable(mali_clock) < 0) {
- _mali_osk_mutex_signal(mali_dvfs_lock);
- return;
- }
- atomic_set(&clk_active, 1);
- }
-
- err = clk_set_rate(mali_clock, rate);
-
- if (err > 0)
- MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
-
- rate = clk_get_rate(mali_clock);
-
- MALI_DEBUG_PRINT(1, ("Mali frequency %d\n", rate / mhz));
- GPU_MHZ = mhz;
-
- mali_gpu_clk = (int)(rate / mhz);
- mali_clk_put(MALI_FALSE);
-
- _mali_osk_mutex_signal(mali_dvfs_lock);
-}
-
-#ifdef CONFIG_MALI_DVFS
-mali_bool set_mali_dvfs_current_step(unsigned int step)
-{
- _mali_osk_mutex_wait(mali_dvfs_lock);
- maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
- _mali_osk_mutex_signal(mali_dvfs_lock);
- return MALI_TRUE;
-}
-
-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
-{
- u32 validatedStep = step;
-#if MALI_DVFS_CLK_DEBUG
- unsigned int *pRegMaliClkDiv;
- unsigned int *pRegMaliMpll;
-#endif
-
- if(boostup) {
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
-#ifdef EXYNOS4_ASV_ENABLED
- mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT));
-#ifdef EXYNOS4_ABB_ENABLED
- exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT));
-#endif
-#else
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
-#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
-#ifdef EXYNOS4_ASV_ENABLED
- /*change the voltage*/
- mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT));
-#ifdef EXYNOS4_ABB_ENABLED
- exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT));
-#endif
-#else
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
-#endif
- }
-
-#if defined(CONFIG_MALI400_PROFILING)
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
- MALI_PROFILING_EVENT_CHANNEL_GPU|
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
- mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
-#endif
- mali_clk_put(MALI_FALSE);
-
-#if MALI_DVFS_CLK_DEBUG
- pRegMaliClkDiv = ioremap(0x1003c52c, 32);
- pRegMaliMpll = ioremap(0x1003c22c, 32);
- MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n", *pRegMaliMpll, *pRegMaliClkDiv));
-#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)
- cpufreq_lock_by_mali(400);
- 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 */
- }
-}
-
-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
-{
- MALI_DEBUG_PRINT(4, ("> 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;
-}
-
-static unsigned int decideNextStatus(unsigned int utilization)
-{
- static unsigned int level = 0;
- int iStepCount = 0;
-
- if (mali_runtime_resumed >= 0) {
- level = mali_runtime_resumed;
- mali_runtime_resumed = -1;
- }
-
- if (mali_dvfs_control == 0) {
- if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
- level < MALI_DVFS_STEPS - 1) {
- level++;
- } else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
- level > 0) {
- level--;
- }
- } else {
- for (iStepCount = MALI_DVFS_STEPS - 1; iStepCount >= 0; iStepCount--) {
- if (mali_dvfs_control >= mali_dvfs[iStepCount].clock) {
- level = iStepCount;
- break;
- }
- }
- }
-
- return level;
-}
-
-static mali_bool mali_dvfs_status(unsigned int utilization)
-{
- unsigned int nextStatus = 0;
- unsigned int curStatus = 0;
- mali_bool boostup = MALI_FALSE;
- static int stay_count = 5;
-
- MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n", utilization));
-
- /* decide next step */
- curStatus = get_mali_dvfs_status();
- nextStatus = decideNextStatus(utilization);
-
- MALI_DEBUG_PRINT(4, ("= 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) {
- /*check if boost up or not*/
- if(maliDvfsStatus.currentStep < nextStatus) {
- boostup = 1;
- stay_count = 5;
- } else if (maliDvfsStatus.currentStep > nextStatus){
- stay_count--;
- }
-
- if( boostup == 1 || stay_count <= 0){
- /*change mali dvfs status*/
- update_time_in_state(curStatus);
- if (!change_mali_dvfs_status(nextStatus, boostup)) {
- MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
- return MALI_FALSE;
- }
- boostup = 0;
- stay_count = 5;
- }
- }
- else
- stay_count = 5;
-
- return MALI_TRUE;
-}
-#endif
-
-static void mali_dvfs_work_handler(struct work_struct *w)
-{
- bMaliDvfsRun = 1;
- MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
-
-#ifdef CONFIG_MALI_DVFS
- if(!mali_dvfs_status(mali_dvfs_utilization))
- MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler"));
-#endif
-
- bMaliDvfsRun = 0;
-}
-
-mali_bool init_mali_dvfs_status(void)
-{
- /*
- * default status
- * add here with the right function to get initilization value.
- */
- if (!mali_dvfs_wq)
- mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
-
- /* add a error handling here */
- maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
-
- return MALI_TRUE;
-}
-
-void deinit_mali_dvfs_status(void)
-{
- if (mali_dvfs_wq)
- destroy_workqueue(mali_dvfs_wq);
-
- mali_dvfs_wq = NULL;
-}
-
-#ifdef CONFIG_MALI_DVFS
-mali_bool mali_dvfs_handler(unsigned int utilization)
-{
- mali_dvfs_utilization = utilization;
- queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work);
-
- return MALI_TRUE;
-}
-#endif
-
-static mali_bool init_mali_clock(void)
-{
- mali_bool ret = MALI_TRUE;
- nPowermode = MALI_POWER_MODE_DEEP_SLEEP;
-
- if (mali_clock != 0)
- return ret; /* already initialized */
-
- mali_dvfs_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED, 0);
-
- if (mali_dvfs_lock == NULL)
- return _MALI_OSK_ERR_FAULT;
-
- if (!mali_clk_get())
- {
- MALI_PRINT(("Error: Failed to get Mali clock\n"));
- goto err_clk;
- }
-
- mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
-
- MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
-
-#ifdef CONFIG_REGULATOR
- g3d_regulator = regulator_get(NULL, "vdd_g3d");
-
- if (IS_ERR(g3d_regulator)) {
- MALI_PRINT(("MALI Error : failed to get vdd_g3d\n"));
- ret = MALI_FALSE;
- goto err_regulator;
- }
-
- mali_gpu_vol = mali_runtime_resume.vol;
-#ifdef EXYNOS4_ASV_ENABLED
- mali_gpu_vol = get_match_volt(ID_G3D, mali_gpu_clk * GPU_ASV_VOLT);
- mali_runtime_resume.vol = get_match_volt(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT);
-#endif
-
- regulator_enable(g3d_regulator);
- mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
-
-#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED)
- exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT));
-#endif
-#endif
-
-#if defined(CONFIG_MALI400_PROFILING)
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
- MALI_PROFILING_EVENT_CHANNEL_GPU|
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
- mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
-#endif
- mali_clk_put(MALI_FALSE);
-
- return MALI_TRUE;
-
-#ifdef CONFIG_REGULATOR
-err_regulator:
- regulator_put(g3d_regulator);
-#endif
-err_clk:
- mali_clk_put(MALI_TRUE);
-
- return ret;
-}
-
-static mali_bool deinit_mali_clock(void)
-{
- if (mali_clock == 0)
- return MALI_TRUE;
-
-#ifdef CONFIG_REGULATOR
- if (g3d_regulator) {
- regulator_put(g3d_regulator);
- g3d_regulator = NULL;
- }
-#endif
- mali_clk_put(MALI_TRUE);
- return MALI_TRUE;
-}
-
-static _mali_osk_errcode_t enable_mali_clocks(void)
-{
- int err;
-
- if (atomic_read(&clk_active) == 0) {
- err = clk_enable(mali_clock);
- MALI_DEBUG_PRINT(3, ("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
- atomic_set(&clk_active, 1);
- }
-
- /* set clock rate */
-#ifdef CONFIG_MALI_DVFS
-#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED)
- if (samsung_rev() == EXYNOS3470_REV_2_0)
- exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT));
-#endif
-
- if (mali_dvfs_control != 0 || mali_gpu_clk >= mali_runtime_resume.clk) {
- mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
- } else {
-#ifdef CONFIG_REGULATOR
- mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
-#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED)
- exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT));
-#endif
-#endif
- mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
- set_mali_dvfs_current_step(mali_runtime_resume.step);
- }
-#else
- mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
- maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
-#endif
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t disable_mali_clocks(void)
-{
-#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED)
- if (samsung_rev() == EXYNOS3470_REV_2_0)
- exynos_set_abb(ID_G3D, ABB_BYPASS);
-#endif
-
- if (atomic_read(&clk_active)) {
- clk_disable(mali_clock);
- MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p\n", mali_clock));
- atomic_set(&clk_active, 0);
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_init(struct device *dev)
-{
- atomic_set(&clk_active, 0);
- MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
-
-#ifdef CONFIG_MALI_DVFS
- if (!clk_register_map)
- clk_register_map = _mali_osk_mem_mapioregion(CLK_DIV_STAT_G3D, 0x20, CLK_DESC);
-
- if (!init_mali_dvfs_status())
- MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
-
- maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
-#endif
- mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_deinit(struct device *dev)
-{
- mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP);
- deinit_mali_clock();
-
-#ifdef CONFIG_MALI_DVFS
- deinit_mali_dvfs_status();
- if (clk_register_map) {
- _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
- clk_register_map = NULL;
- }
-#endif
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode)
-{
- switch (power_mode)
- {
- case MALI_POWER_MODE_ON:
- MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
- nPowermode ? "powering on" : "already on"));
- if (nPowermode == MALI_POWER_MODE_LIGHT_SLEEP || nPowermode == MALI_POWER_MODE_DEEP_SLEEP) {
- MALI_DEBUG_PRINT(4, ("enable clock\n"));
- enable_mali_clocks();
-
-#if defined(CONFIG_MALI400_PROFILING)
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_GPU |
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
- mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
-#endif
- nPowermode = power_mode;
- }
- break;
- case MALI_POWER_MODE_DEEP_SLEEP:
- case MALI_POWER_MODE_LIGHT_SLEEP:
- MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode == MALI_POWER_MODE_LIGHT_SLEEP ?
- "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP",
- nPowermode ? "already off" : "powering off"));
- if (nPowermode == MALI_POWER_MODE_ON) {
- disable_mali_clocks();
-
-#if defined(CONFIG_MALI400_PROFILING)
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_GPU |
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
- 0, 0, 0, 0, 0);
-#endif
- nPowermode = power_mode;
- }
- break;
- }
- MALI_SUCCESS;
-}
-
-void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data)
-{
- if (nPowermode == MALI_POWER_MODE_ON)
- {
-#ifdef CONFIG_MALI_DVFS
- if(!mali_dvfs_handler(data->utilization_gpu))
- MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n"));
-#endif
- }
-}
-
-#ifdef CONFIG_MALI_DVFS
-static void update_time_in_state(int level)
-{
- u64 current_time;
- static u64 prev_time = 0;
-
- if (prev_time == 0)
- prev_time = get_jiffies_64();
-
- current_time = get_jiffies_64();
- mali_dvfs_time[level] += current_time - prev_time;
- prev_time = current_time;
-}
-
-ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf)
-{
- ssize_t ret = 0;
- int i;
-
- update_time_in_state(maliDvfsStatus.currentStep);
-
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d %llu\n",
- mali_dvfs[i].clock,
- mali_dvfs_time[i]);
- }
-
- if (ret < PAGE_SIZE - 1) {
- ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
- } else {
- buf[PAGE_SIZE - 2] = '\n';
- buf[PAGE_SIZE - 1] = '\0';
- ret = PAGE_SIZE - 1;
- }
- return ret;
-}
-
-ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- int i;
-
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs_time[i] = 0;
- }
- return count;
-}
-#endif