/*
 * 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 platform 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, didn'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

