/*
 * Copyright (C) 2010-2012, 2014, 2016 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.
 */

#include <linux/mali/mali_utgard.h>
#include "mali_kernel_common.h"
#include "mali_scheduler.h"
#include "mali_dvfs_policy.h"
#include "mali_osk_mali.h"
#include "mali_osk_profiling.h"

#define CLOCK_TUNING_TIME_DEBUG 0

#define MAX_PERFORMANCE_VALUE 256
#define MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(percent) ((int) ((percent)*(MAX_PERFORMANCE_VALUE)/100.0 + 0.5))

/** The max fps the same as display vsync default 60, can set by module insert parameter */
int mali_max_system_fps = 60;
/** A lower limit on their desired FPS default 58, can set by module insert parameter */
int mali_desired_fps = 58;

static int mali_fps_step1 = 0;
static int mali_fps_step2 = 0;

static int clock_step = -1;
static int cur_clk_step = -1;
static struct mali_gpu_clock *gpu_clk = NULL;

/*Function prototype */
static int (*mali_gpu_set_freq)(int) = NULL;
static int (*mali_gpu_get_freq)(void) = NULL;

static mali_bool mali_dvfs_enabled = MALI_FALSE;

#define NUMBER_OF_NANOSECONDS_PER_SECOND  1000000000ULL
static u32 calculate_window_render_fps(u64 time_period)
{
	u32 max_window_number;
	u64 tmp;
	u64 max = time_period;
	u32 leading_zeroes;
	u32 shift_val;
	u32 time_period_shift;
	u32 max_window_number_shift;
	u32 ret_val;

	max_window_number = mali_session_max_window_num();

	/* To avoid float division, extend the dividend to ns unit */
	tmp = (u64)max_window_number * NUMBER_OF_NANOSECONDS_PER_SECOND;
	if (tmp > time_period) {
		max = tmp;
	}

	/*
	 * We may have 64-bit values, a dividend or a divisor or both
	 * To avoid dependencies to a 64-bit divider, we shift down the two values
	 * equally first.
	 */
	leading_zeroes = _mali_osk_clz((u32)(max >> 32));
	shift_val = 32 - leading_zeroes;

	time_period_shift = (u32)(time_period >> shift_val);
	max_window_number_shift = (u32)(tmp >> shift_val);

	ret_val = max_window_number_shift / time_period_shift;

	return ret_val;
}

static bool mali_pickup_closest_avail_clock(int target_clock_mhz, mali_bool pick_clock_up)
{
	int i = 0;
	bool clock_changed = false;

	/* Round up the closest available frequency step for target_clock_hz */
	for (i = 0; i < gpu_clk->num_of_steps; i++) {
		/* Find the first item > target_clock_hz */
		if (((int)(gpu_clk->item[i].clock) - target_clock_mhz) > 0) {
			break;
		}
	}

	/* If the target clock greater than the maximum clock just pick the maximum one*/
	if (i == gpu_clk->num_of_steps) {
		i = gpu_clk->num_of_steps - 1;
	} else {
		if ((!pick_clock_up) && (i > 0)) {
			i = i - 1;
		}
	}

	clock_step = i;
	if (cur_clk_step != clock_step) {
		clock_changed = true;
	}

	return clock_changed;
}

void mali_dvfs_policy_realize(struct mali_gpu_utilization_data *data, u64 time_period)
{
	int under_perform_boundary_value = 0;
	int over_perform_boundary_value = 0;
	int current_fps = 0;
	int current_gpu_util = 0;
	bool clock_changed = false;
#if CLOCK_TUNING_TIME_DEBUG
	struct timeval start;
	struct timeval stop;
	unsigned int elapse_time;
	do_gettimeofday(&start);
#endif
	u32 window_render_fps;

	if (NULL == gpu_clk) {
		MALI_DEBUG_PRINT(2, ("Enable DVFS but patform doesn't Support freq change. \n"));
		return;
	}

	window_render_fps = calculate_window_render_fps(time_period);

	current_fps = window_render_fps;
	current_gpu_util = data->utilization_gpu;

	/* Get the specific under_perform_boundary_value and over_perform_boundary_value */
	if ((mali_desired_fps <= current_fps) && (current_fps < mali_max_system_fps)) {
		under_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(90);
		over_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(70);
	} else if ((mali_fps_step1 <= current_fps) && (current_fps < mali_desired_fps)) {
		under_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(55);
		over_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(35);
	} else if ((mali_fps_step2 <= current_fps) && (current_fps < mali_fps_step1)) {
		under_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(70);
		over_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(50);
	} else {
		under_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(55);
		over_perform_boundary_value = MALI_PERCENTAGE_TO_UTILIZATION_FRACTION(35);
	}

	MALI_DEBUG_PRINT(5, ("Using ARM power policy: gpu util = %d \n", current_gpu_util));
	MALI_DEBUG_PRINT(5, ("Using ARM power policy: under_perform = %d,  over_perform = %d \n", under_perform_boundary_value, over_perform_boundary_value));
	MALI_DEBUG_PRINT(5, ("Using ARM power policy: render fps = %d,  pressure render fps = %d \n", current_fps, window_render_fps));

	/* Get current clock value */
	cur_clk_step = mali_gpu_get_freq();

	/* Consider offscreen */
	if (0 == current_fps) {
		/* GP or PP under perform, need to give full power */
		if (current_gpu_util > over_perform_boundary_value) {
			if (cur_clk_step != gpu_clk->num_of_steps - 1) {
				clock_changed = true;
				clock_step = gpu_clk->num_of_steps - 1;
			}
		}

		/* If GPU is idle, use lowest power */
		if (0 == current_gpu_util) {
			if (cur_clk_step != 0) {
				clock_changed = true;
				clock_step = 0;
			}
		}

		goto real_setting;
	}

	/* 2. Calculate target clock if the GPU clock can be tuned */
	if (-1 != cur_clk_step) {
		int target_clk_mhz = -1;
		mali_bool pick_clock_up = MALI_TRUE;

		if (current_gpu_util > under_perform_boundary_value) {
			/* when under perform, need to consider the fps part */
			target_clk_mhz = gpu_clk->item[cur_clk_step].clock * current_gpu_util * mali_desired_fps / under_perform_boundary_value / current_fps;
			pick_clock_up = MALI_TRUE;
		} else if (current_gpu_util < over_perform_boundary_value) {
			/* when over perform, did't need to consider fps, system didn't want to reach desired fps */
			target_clk_mhz = gpu_clk->item[cur_clk_step].clock * current_gpu_util / under_perform_boundary_value;
			pick_clock_up = MALI_FALSE;
		}

		if (-1 != target_clk_mhz) {
			clock_changed = mali_pickup_closest_avail_clock(target_clk_mhz, pick_clock_up);
		}
	}

real_setting:
	if (clock_changed) {
		mali_gpu_set_freq(clock_step);

		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
					      MALI_PROFILING_EVENT_CHANNEL_GPU |
					      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
					      gpu_clk->item[clock_step].clock,
					      gpu_clk->item[clock_step].vol / 1000,
					      0, 0, 0);
	}

#if CLOCK_TUNING_TIME_DEBUG
	do_gettimeofday(&stop);

	elapse_time = timeval_to_ns(&stop) - timeval_to_ns(&start);
	MALI_DEBUG_PRINT(2, ("Using ARM power policy:  eclapse time = %d\n", elapse_time));
#endif
}

_mali_osk_errcode_t mali_dvfs_policy_init(void)
{
	_mali_osk_device_data data;
	_mali_osk_errcode_t err = _MALI_OSK_ERR_OK;

	if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
		if ((NULL != data.get_clock_info) && (NULL != data.set_freq) && (NULL != data.get_freq)) {
			MALI_DEBUG_PRINT(2, ("Mali DVFS init: using arm dvfs policy \n"));


			mali_fps_step1 = mali_max_system_fps / 3;
			mali_fps_step2 = mali_max_system_fps / 5;

			data.get_clock_info(&gpu_clk);

			if (gpu_clk != NULL) {
#ifdef DEBUG
				int i;
				for (i = 0; i < gpu_clk->num_of_steps; i++) {
					MALI_DEBUG_PRINT(5, ("mali gpu clock info: step%d clock(%d)Hz,vol(%d) \n",
							     i, gpu_clk->item[i].clock, gpu_clk->item[i].vol));
				}
#endif
			} else {
				MALI_DEBUG_PRINT(2, ("Mali DVFS init: platform didn't define enough info for ddk to do DVFS \n"));
			}

			mali_gpu_get_freq = data.get_freq;
			mali_gpu_set_freq = data.set_freq;

			if ((NULL != gpu_clk) && (gpu_clk->num_of_steps > 0)
			    && (NULL != mali_gpu_get_freq) && (NULL != mali_gpu_set_freq)) {
				mali_dvfs_enabled = MALI_TRUE;
			}
		} else {
			MALI_DEBUG_PRINT(2, ("Mali DVFS init: platform function callback incomplete, need check mali_gpu_device_data in platform .\n"));
		}
	} else {
		err = _MALI_OSK_ERR_FAULT;
		MALI_DEBUG_PRINT(2, ("Mali DVFS init: get platform data error .\n"));
	}

	return err;
}

/*
 * Always give full power when start a new period,
 * if mali dvfs enabled, for performance consideration
 */
void mali_dvfs_policy_new_period(void)
{
	/* Always give full power when start a new period */
	unsigned int cur_clk_step = 0;

	cur_clk_step = mali_gpu_get_freq();

	if (cur_clk_step != (gpu_clk->num_of_steps - 1)) {
		mali_gpu_set_freq(gpu_clk->num_of_steps - 1);

		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
					      MALI_PROFILING_EVENT_CHANNEL_GPU |
					      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, gpu_clk->item[gpu_clk->num_of_steps - 1].clock,
					      gpu_clk->item[gpu_clk->num_of_steps - 1].vol / 1000, 0, 0, 0);
	}
}

mali_bool mali_dvfs_policy_enabled(void)
{
	return mali_dvfs_enabled;
}

#if defined(CONFIG_MALI400_PROFILING)
void mali_get_current_gpu_clk_item(struct mali_gpu_clk_item *clk_item)
{
	if (mali_platform_device != NULL) {

		struct mali_gpu_device_data *device_data = NULL;
		device_data = (struct mali_gpu_device_data *)mali_platform_device->dev.platform_data;

		if ((NULL != device_data->get_clock_info) && (NULL != device_data->get_freq)) {

			int cur_clk_step = device_data->get_freq();
			struct mali_gpu_clock *mali_gpu_clk = NULL;

			device_data->get_clock_info(&mali_gpu_clk);
			clk_item->clock = mali_gpu_clk->item[cur_clk_step].clock;
			clk_item->vol = mali_gpu_clk->item[cur_clk_step].vol;
		} else {
			MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: platform function callback incomplete, need check mali_gpu_device_data in platform .\n"));
		}
	}
}
#endif

