/*
 * ../vendor/amlogic/common/gpu/utgard/platform/meson_bu/scaling.c
 *
 * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

/**
 * @file arm_core_scaling.c
 * Example core scaling policy.
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/mali/mali_utgard.h>
#include <mali_kernel_common.h>
#include <mali_osk_profiling.h>

#if AMLOGIC_GPU_USE_GPPLL
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 16)
#include <linux/amlogic/amports/gp_pll.h>
#else
#include <linux/amlogic/media/clk/gp_pll.h>
#endif
#endif
#define LOG_MALI_SCALING 1
#include "meson_main2.h"
#include "mali_clock.h"

static int currentStep;
#ifndef CONFIG_MALI_DVFS
static int num_cores_enabled;
static int lastStep;
static struct work_struct wq_work;
static mali_plat_info_t* pmali_plat = NULL;
#endif
static int  scaling_mode = MALI_PP_FS_SCALING;
//static int  scaling_mode = MALI_SCALING_DISABLE;
//static int  scaling_mode = MALI_PP_SCALING;

#if AMLOGIC_GPU_USE_GPPLL
static struct gp_pll_user_handle_s *gp_pll_user_gpu;
static int is_gp_pll_get;
static int is_gp_pll_put;
#endif

static unsigned scaling_dbg_level = 0;
module_param(scaling_dbg_level, uint, 0644);
MODULE_PARM_DESC(scaling_dbg_level , "scaling debug level");

#define scalingdbg(level, fmt, arg...)				   \
	do {											   \
		if (scaling_dbg_level >= (level))			   \
		printk(fmt , ## arg);						   \
	} while (0)

#ifndef CONFIG_MALI_DVFS
static inline void mali_clk_exected(void)
{
	mali_dvfs_threshold_table * pdvfs = pmali_plat->dvfs_table;
	uint32_t execStep = currentStep;
	mali_dvfs_threshold_table *dvfs_tbl = &pmali_plat->dvfs_table[currentStep];

	//if (pdvfs[currentStep].freq_index == pdvfs[lastStep].freq_index) return;
	if ((pdvfs[execStep].freq_index == pdvfs[lastStep].freq_index) ||
		(pdvfs[execStep].clk_freq == pdvfs[lastStep].clk_freq)){
		return;
	}

#if AMLOGIC_GPU_USE_GPPLL
	if (0 == strcmp(dvfs_tbl->clk_parent, "gp0_pll")) {
		gp_pll_request(gp_pll_user_gpu);
		if (!is_gp_pll_get) {
			//printk("not get pll\n");
			execStep = currentStep - 1;
		}
	} else {
		//not get the gp pll, do need put
		is_gp_pll_get = 0;
		is_gp_pll_put = 0;
		gp_pll_release(gp_pll_user_gpu);
	}
#else
	if ((0 == strcmp(dvfs_tbl->clk_parent, "gp0_pll")) &&
            !IS_ERR(dvfs_tbl->clkp_handle) &&
            (0 != dvfs_tbl->clkp_freq)) {
        clk_prepare_enable(dvfs_tbl->clkp_handle);
        clk_set_rate(dvfs_tbl->clkp_handle, dvfs_tbl->clkp_freq);
    }

#endif

	//mali_dev_pause();
	mali_clock_set(pdvfs[execStep].freq_index);
	//mali_dev_resume();
#if AMLOGIC_GPU_USE_GPPLL==0
	if ((0 == strcmp(pdvfs[lastStep].clk_parent,"gp0_pll")) &&
		(0 != strcmp(pdvfs[execStep].clk_parent, "gp0_pll"))) {
				clk_disable_unprepare(pdvfs[lastStep].clkp_handle);
	}
#endif
	lastStep = execStep;
#if AMLOGIC_GPU_USE_GPPLL
	if (is_gp_pll_put) {
		//printk("release gp0 pll\n");
		gp_pll_release(gp_pll_user_gpu);
		gp_pll_request(gp_pll_user_gpu);
		is_gp_pll_get = 0;
		is_gp_pll_put = 0;
	}
#endif

}
#if AMLOGIC_GPU_USE_GPPLL
static int gp_pll_user_cb_gpu(struct gp_pll_user_handle_s *user,
		int event)
{
	if (event == GP_PLL_USER_EVENT_GRANT) {
		//printk("granted\n");
		is_gp_pll_get = 1;
		is_gp_pll_put = 0;
		schedule_work(&wq_work);
	} else if (event == GP_PLL_USER_EVENT_YIELD) {
		//printk("ask for yield\n");
		is_gp_pll_get = 0;
		is_gp_pll_put = 1;
		schedule_work(&wq_work);
	}

	return 0;
}
#endif

static void do_scaling(struct work_struct *work)
{
	mali_dvfs_threshold_table * pdvfs = pmali_plat->dvfs_table;
	int err = mali_perf_set_num_pp_cores(num_cores_enabled);
	scalingdbg(1, "set pp cores to %d\n", num_cores_enabled);
	MALI_DEBUG_ASSERT(0 == err);
	MALI_IGNORE(err);
	scalingdbg(1, "pdvfs[%d].freq_index=%d, pdvfs[%d].freq_index=%d\n",
			currentStep, pdvfs[currentStep].freq_index,
			lastStep, pdvfs[lastStep].freq_index);
	mali_clk_exected();
#ifdef 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,
			get_current_frequency(),
			0,	0,	0,	0);
#endif
}
#endif

u32 revise_set_clk(u32 val, u32 flush)
{
	u32 ret = 0;
#ifndef CONFIG_MALI_DVFS
	mali_scale_info_t* pinfo;

	pinfo = &pmali_plat->scale_info;

	if (val < pinfo->minclk)
		val = pinfo->minclk;
	else if (val >  pinfo->maxclk)
		val =  pinfo->maxclk;

	if (val != currentStep) {
		currentStep = val;
		if (flush)
			schedule_work(&wq_work);
		else
			ret = 1;
	}
#endif
	return ret;
}

void get_mali_rt_clkpp(u32* clk, u32* pp)
{
#ifndef CONFIG_MALI_DVFS
	*clk = currentStep;
	*pp = num_cores_enabled;
#endif
}

u32 set_mali_rt_clkpp(u32 clk, u32 pp, u32 flush)
{
	u32 ret = 0;
#ifndef CONFIG_MALI_DVFS
	mali_scale_info_t* pinfo;
	u32 flush_work = 0;

	pinfo = &pmali_plat->scale_info;
	if (clk < pinfo->minclk)
		clk = pinfo->minclk;
	else if (clk >  pinfo->maxclk)
		clk =  pinfo->maxclk;

	if (clk != currentStep) {
		currentStep = clk;
		if (flush)
			flush_work++;
		else
			ret = 1;
	}
	if (pp < pinfo->minpp)
		pp = pinfo->minpp;
	else if (pp > pinfo->maxpp)
		pp = pinfo->maxpp;

	if (pp != num_cores_enabled) {
		num_cores_enabled = pp;
		if (flush)
			flush_work++;
		else
			ret = 1;
	}

	if (flush_work)
		schedule_work(&wq_work);
#endif
	return ret;
}

void revise_mali_rt(void)
{
#ifndef CONFIG_MALI_DVFS
	set_mali_rt_clkpp(currentStep, num_cores_enabled, 1);
#endif
}

void flush_scaling_job(void)
{
#ifndef CONFIG_MALI_DVFS
	cancel_work_sync(&wq_work);
#endif
}

#ifndef CONFIG_MALI_DVFS
static u32 enable_one_core(void)
{
	scalingdbg(2, "meson:	 one more pp, curent has %d pp cores\n",  num_cores_enabled + 1);
	return set_mali_rt_clkpp(currentStep, num_cores_enabled + 1, 0);
}

static u32 disable_one_core(void)
{
	scalingdbg(2, "meson: disable one pp, current has %d pp cores\n",  num_cores_enabled - 1);
	return set_mali_rt_clkpp(currentStep, num_cores_enabled - 1, 0);
}

static u32 enable_max_num_cores(void)
{
	return set_mali_rt_clkpp(currentStep, pmali_plat->scale_info.maxpp, 0);
}

static u32 enable_pp_cores(u32 val)
{
	scalingdbg(2, "meson: enable %d pp cores\n", val);
	return set_mali_rt_clkpp(currentStep, val, 0);
}
#endif

int mali_core_scaling_init(mali_plat_info_t *mali_plat)
{
#ifndef CONFIG_MALI_DVFS
	if (mali_plat == NULL) {
		scalingdbg(2, " Mali platform data is NULL!!!\n");
		return -1;
	}

	pmali_plat = mali_plat;
	num_cores_enabled = pmali_plat->sc_mpp;
#if AMLOGIC_GPU_USE_GPPLL
	gp_pll_user_gpu = gp_pll_user_register("gpu", 1,
		gp_pll_user_cb_gpu);
	//not get the gp pll, do need put
	is_gp_pll_get = 0;
	is_gp_pll_put = 0;
	if (gp_pll_user_gpu == NULL) printk("register gp pll user for gpu failed\n");
#endif

	currentStep = pmali_plat->def_clock;
	lastStep = currentStep;
	INIT_WORK(&wq_work, do_scaling);
#endif
	return 0;
	/* NOTE: Mali is not fully initialized at this point. */
}

void mali_core_scaling_term(void)
{
#ifndef CONFIG_MALI_DVFS
	flush_scheduled_work();
#if AMLOGIC_GPU_USE_GPPLL
	gp_pll_user_unregister(gp_pll_user_gpu);
#endif
#endif
}

#ifndef CONFIG_MALI_DVFS
static u32 mali_threshold [] = {
	102, /* 40% */
	128, /* 50% */
	230, /* 90% */
};
#endif

void mali_pp_scaling_update(struct mali_gpu_utilization_data *data)
{
#ifndef CONFIG_MALI_DVFS
	int ret = 0;

	if (mali_threshold[2] < data->utilization_pp)
		ret = enable_max_num_cores();
	else if (mali_threshold[1]< data->utilization_pp)
		ret = enable_one_core();
	else if (0 < data->utilization_pp)
		ret = disable_one_core();
	if (ret == 1)
		schedule_work(&wq_work);
#endif
}

#if LOG_MALI_SCALING
void trace_utilization(struct mali_gpu_utilization_data *data, u32 current_idx, u32 next,
		u32 current_pp, u32 next_pp)
{
	char direction;
	if (next > current_idx)
		direction = '>';
	else if ((current_idx > pmali_plat->scale_info.minpp) && (next < current_idx))
		direction = '<';
	else
		direction = '~';

	scalingdbg(2, "[SCALING]%c (%3d-->%3d)@%3d{%3d - %3d}. pp:(%d-->%d)\n",
			direction,
			get_mali_freq(current_idx),
			get_mali_freq(next),
			data->utilization_gpu,
			pmali_plat->dvfs_table[current_idx].downthreshold,
			pmali_plat->dvfs_table[current_idx].upthreshold,
			current_pp, next_pp);
}
#endif

#ifndef CONFIG_MALI_DVFS
static int mali_stay_count = 0;
static void mali_decide_next_status(struct mali_gpu_utilization_data *data, int* next_fs_idx,
		int* pp_change_flag)
{
	u32 utilization, mali_up_limit, decided_fs_idx;
	u32 ld_left, ld_right;
	u32 ld_up, ld_down;
	u32 change_mode;

	*pp_change_flag = 0;
	change_mode = 0;
	utilization = data->utilization_gpu;

	scalingdbg(5, "line(%d), scaling_mode=%d, MALI_TURBO_MODE=%d, turbo=%d, maxclk=%d\n",
			__LINE__,  scaling_mode, MALI_TURBO_MODE,
		    pmali_plat->turbo_clock, pmali_plat->scale_info.maxclk);

	mali_up_limit = (scaling_mode ==  MALI_TURBO_MODE) ?
		pmali_plat->turbo_clock : pmali_plat->scale_info.maxclk;
	decided_fs_idx = currentStep;

	ld_up = pmali_plat->dvfs_table[currentStep].upthreshold;
	ld_down = pmali_plat->dvfs_table[currentStep].downthreshold;

	scalingdbg(2, "utilization=%d,  ld_up=%d\n ", utilization,  ld_up);
	if (utilization >= ld_up) { /* go up */

		scalingdbg(2, "currentStep=%d,  mali_up_limit=%d\n ", currentStep, mali_up_limit);
		if (currentStep < mali_up_limit) {
			change_mode = 1;
			if ((currentStep < pmali_plat->def_clock) && (utilization > pmali_plat->bst_gpu))
				decided_fs_idx = pmali_plat->def_clock;
			else
				decided_fs_idx++;
		}
		if ((data->utilization_pp >= ld_up) &&
				(num_cores_enabled < pmali_plat->scale_info.maxpp)) {
			if ((num_cores_enabled < pmali_plat->sc_mpp) && (data->utilization_pp >= pmali_plat->bst_pp)) {
				*pp_change_flag = 1;
				change_mode = 1;
			} else if (change_mode == 0) {
				*pp_change_flag = 2;
				change_mode = 1;
			}
		}
#if LOG_MALI_SCALING
		scalingdbg(2, "[nexting..] [LD:%d]-> FS[CRNT:%d LMT:%d NEXT:%d] PP[NUM:%d LMT:%d MD:%d][F:%d]\n",
				data->utilization_pp, currentStep, mali_up_limit, decided_fs_idx,
				num_cores_enabled, pmali_plat->scale_info.maxpp, *pp_change_flag, change_mode);
#endif
	} else if (utilization <= ld_down) { /* go down */
		if (mali_stay_count > 0) {
			*next_fs_idx = decided_fs_idx;
			mali_stay_count--;
			return;
		}

		if (num_cores_enabled > pmali_plat->sc_mpp) {
			change_mode = 1;
			if (data->utilization_pp <= ld_down) {
				ld_left = data->utilization_pp * num_cores_enabled;
				ld_right = (pmali_plat->dvfs_table[currentStep].upthreshold) *
					(num_cores_enabled - 1);
				if (ld_left < ld_right) {
					change_mode = 2;
				}
			}
		} else if (currentStep > pmali_plat->scale_info.minclk) {
			change_mode = 1;
		} else if (num_cores_enabled > 1) { /* decrease PPS */
			if (data->utilization_pp <= ld_down) {
				ld_left = data->utilization_pp * num_cores_enabled;
				ld_right = (pmali_plat->dvfs_table[currentStep].upthreshold) *
					(num_cores_enabled - 1);
				scalingdbg(2, "ld_left=%d, ld_right=%d\n", ld_left, ld_right);
				if (ld_left < ld_right) {
					change_mode = 2;
				}
			}
		}

		if (change_mode == 1) {
			decided_fs_idx--;
		} else if (change_mode == 2) { /* decrease PPS */
			*pp_change_flag = -1;
		}
	}

	if (decided_fs_idx < 0 ) {
		printk("gpu debug, next index below 0\n");
		decided_fs_idx = 0;
	}
	if (decided_fs_idx > pmali_plat->scale_info.maxclk) {
		decided_fs_idx = pmali_plat->scale_info.maxclk;
		scalingdbg(1, "gpu debug, next index above max, set to %d\n", decided_fs_idx);
	}

	if (change_mode)
		mali_stay_count = pmali_plat->dvfs_table[decided_fs_idx].keep_count;
	*next_fs_idx = decided_fs_idx;
}
#endif

void mali_pp_fs_scaling_update(struct mali_gpu_utilization_data *data)
{
#ifndef CONFIG_MALI_DVFS
	int ret = 0;
	int pp_change_flag = 0;
	u32 next_idx = 0;

#if LOG_MALI_SCALING
	u32 last_pp = num_cores_enabled;
#endif
	mali_decide_next_status(data, &next_idx, &pp_change_flag);

	if (pp_change_flag == 1)
		ret = enable_pp_cores(pmali_plat->sc_mpp);
	else if (pp_change_flag == 2)
		ret = enable_one_core();
	else if (pp_change_flag == -1) {
		ret = disable_one_core();
	}

#if LOG_MALI_SCALING
	if (pp_change_flag || (next_idx != currentStep))
		trace_utilization(data, currentStep, next_idx, last_pp, num_cores_enabled);
#endif

	if (next_idx != currentStep) {
		ret = 1;
		currentStep = next_idx;
	}

	if (ret == 1)
		schedule_work(&wq_work);
#ifdef CONFIG_MALI400_PROFILING
	else
		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
				MALI_PROFILING_EVENT_CHANNEL_GPU |
				MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
				get_current_frequency(),
				0,	0,	0,	0);
#endif
#endif
}

u32 get_mali_schel_mode(void)
{
	return scaling_mode;
}

void set_mali_schel_mode(u32 mode)
{
#ifndef CONFIG_MALI_DVFS
	MALI_DEBUG_ASSERT(mode < MALI_SCALING_MODE_MAX);
	if (mode >= MALI_SCALING_MODE_MAX)
		return;
	scaling_mode = mode;

	//disable thermal in turbo mode
	if (scaling_mode == MALI_TURBO_MODE) {
		pmali_plat->limit_on = 0;
	} else {
		pmali_plat->limit_on = 1;
	}
	/* set default performance range. */
	pmali_plat->scale_info.minclk = pmali_plat->cfg_min_clock;
	pmali_plat->scale_info.maxclk = pmali_plat->cfg_clock;
	pmali_plat->scale_info.minpp = pmali_plat->cfg_min_pp;
	pmali_plat->scale_info.maxpp = pmali_plat->cfg_pp;

	/* set current status and tune max freq */
	if (scaling_mode == MALI_PP_FS_SCALING) {
		pmali_plat->scale_info.maxclk = pmali_plat->cfg_clock;
		enable_pp_cores(pmali_plat->sc_mpp);
	} else if (scaling_mode == MALI_SCALING_DISABLE) {
		pmali_plat->scale_info.maxclk = pmali_plat->cfg_clock;
		enable_max_num_cores();
	} else if (scaling_mode == MALI_TURBO_MODE) {
		pmali_plat->scale_info.maxclk = pmali_plat->turbo_clock;
		enable_max_num_cores();
	}
	currentStep = pmali_plat->scale_info.maxclk;
	schedule_work(&wq_work);
#endif
}

u32 get_current_frequency(void)
{
	return get_mali_freq(currentStep);
}

void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
{
#ifndef CONFIG_MALI_DVFS
	if (mali_pm_statue)
		return;

	switch (scaling_mode) {
		case MALI_PP_FS_SCALING:
			mali_pp_fs_scaling_update(data);
			break;
		case MALI_PP_SCALING:
			mali_pp_scaling_update(data);
			break;
		default:
			break;
	}
#endif
}
static u32 clk_cntl_save = 0;
void mali_dev_freeze(void)
{
	clk_cntl_save = mplt_read(HHI_MALI_CLK_CNTL);
}

void mali_dev_restore(void)
{

	mplt_write(HHI_MALI_CLK_CNTL, clk_cntl_save);
	if (pmali_plat && pmali_plat->pdev) {
		mali_clock_init_clk_tree(pmali_plat->pdev);
	} else {
		printk("error: init clock failed, pmali_plat=%p, pmali_plat->pdev=%p\n",
				pmali_plat, pmali_plat == NULL ? NULL: pmali_plat->pdev);
	}
}

int mali_meson_get_gpu_data(struct mali_gpu_device_data *mgpu_data)
{
	mgpu_data->get_clock_info = NULL;
	mgpu_data->get_freq = NULL;
	mgpu_data->set_freq = NULL;
	mgpu_data->utilization_callback = mali_gpu_utilization_callback;
	return 0;
}
