/*
 * drivers/amlogic/media/common/arch/clk/clk.c
 *
 * Copyright (C) 2016 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.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>

#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/cpu_version.h>
#include "../../../stream_input/amports/amports_priv.h"
#include "../../../frame_provider/decoder/utils/vdec.h"
#include "../../chips/chips.h"
#include "clk_priv.h"
#include <linux/amlogic/media/utils/log.h>
#include "../../chips/decoder_cpu_ver_info.h"

#define p_vdec() (get_current_vdec_chip()->clk_mgr[VDEC_1])
#define p_vdec2() (get_current_vdec_chip()->clk_mgr[VDEC_2])
#define p_vdec_hcodec() (get_current_vdec_chip()->clk_mgr[VDEC_HCODEC])
#define p_vdec_hevc() (get_current_vdec_chip()->clk_mgr[VDEC_HEVC])
#define p_vdec_hevc_back() (get_current_vdec_chip()->clk_mgr[VDEC_HEVCB])

static int clock_source_wxhxfps_saved[VDEC_MAX + 1];

#define IF_HAVE_RUN(p, fn)\
	do {\
		if (p && p->fn)\
			p->fn();\
	} while (0)
/*
 *#define IF_HAVE_RUN_P1_RET(p, fn, p1)\
 *			do {\
 *				pr_debug("%s-----%d\n", __func__, clk);\
 *				if (p && p->fn)\
 *					return p->fn(p1);\
 *				else\
 *					return -1;\
 *			} while (0)
 *
 *#define IF_HAVE_RUN_RET(p, fn)\
 *	do {\
 *		if (p && p->fn)\
 *			return p->fn();\
 *		else\
 *			return 0;\
 *	} while (0)
 */

int vdec_clock_init(void)
{
	if (p_vdec() && p_vdec()->clock_init)
		return p_vdec()->clock_init();
	else
		return 0;
}
EXPORT_SYMBOL(vdec_clock_init);

/*
 *clk ==0 :
 *	to be release.
 *	released shared clk,
 *clk ==1 :default low clk
 *clk ==2 :default high clk
 */
int vdec_clock_set(int clk)
{
	pr_debug("%s-----%d\n", __func__, clk);
	if (p_vdec() && p_vdec()->clock_set)
		return p_vdec()->clock_set(clk);
	else
		return -1;
}
EXPORT_SYMBOL(vdec_clock_set);

void vdec_clock_enable(void)
{
	vdec_clock_set(1);
}
EXPORT_SYMBOL(vdec_clock_enable);

void vdec_clock_hi_enable(void)
{
	vdec_clock_set(2);
}
EXPORT_SYMBOL(vdec_clock_hi_enable);

void vdec_clock_on(void)
{
	IF_HAVE_RUN(p_vdec(), clock_on);
}
EXPORT_SYMBOL(vdec_clock_on);

void vdec_clock_off(void)
{
	IF_HAVE_RUN(p_vdec(), clock_off);
	clock_source_wxhxfps_saved[VDEC_1] = 0;
}
EXPORT_SYMBOL(vdec_clock_off);

int vdec2_clock_set(int clk)
{
	pr_debug("%s-----%d\n", __func__, clk);
	if (p_vdec2() && p_vdec2()->clock_set)
		return p_vdec2()->clock_set(clk);
	else
		return -1;
}
EXPORT_SYMBOL(vdec2_clock_set);

void vdec2_clock_enable(void)
{
	vdec2_clock_set(1);
}
EXPORT_SYMBOL(vdec2_clock_enable);

void vdec2_clock_hi_enable(void)
{
	vdec2_clock_set(2);
}
EXPORT_SYMBOL(vdec2_clock_hi_enable);

void vdec2_clock_on(void)
{
	IF_HAVE_RUN(p_vdec2(), clock_on);
}
EXPORT_SYMBOL(vdec2_clock_on);

void vdec2_clock_off(void)
{
	IF_HAVE_RUN(p_vdec2(), clock_off);
	clock_source_wxhxfps_saved[VDEC_2] = 0;
}
EXPORT_SYMBOL(vdec2_clock_off);

int hcodec_clock_set(int clk)
{
	pr_debug("%s-----%d\n", __func__, clk);
	if (p_vdec_hcodec() && p_vdec_hcodec()->clock_set)
		return p_vdec_hcodec()->clock_set(clk);
	else
		return -1;
}
EXPORT_SYMBOL(hcodec_clock_set);

void hcodec_clock_enable(void)
{
	hcodec_clock_set(1);
}
EXPORT_SYMBOL(hcodec_clock_enable);

void hcodec_clock_hi_enable(void)
{
	hcodec_clock_set(2);
}
EXPORT_SYMBOL(hcodec_clock_hi_enable);

void hcodec_clock_on(void)
{
	IF_HAVE_RUN(p_vdec_hcodec(), clock_on);
}
EXPORT_SYMBOL(hcodec_clock_on);

void hcodec_clock_off(void)
{
	IF_HAVE_RUN(p_vdec_hcodec(), clock_off);
	clock_source_wxhxfps_saved[VDEC_HCODEC] = 0;
}
EXPORT_SYMBOL(hcodec_clock_off);

int hevc_back_clock_init(void)
{
	if (p_vdec_hevc_back() && p_vdec_hevc_back()->clock_init)
		return p_vdec_hevc_back()->clock_init();
	else
		return 0;
}
EXPORT_SYMBOL(hevc_back_clock_init);

int hevc_back_clock_set(int clk)
{
	pr_debug("%s-----%d\n", __func__, clk);
	if (p_vdec_hevc_back() && p_vdec_hevc_back()->clock_set)
		return p_vdec_hevc_back()->clock_set(clk);
	else
		return -1;
}
EXPORT_SYMBOL(hevc_back_clock_set);

void hevc_back_clock_enable(void)
{
	hevc_back_clock_set(1);
}
EXPORT_SYMBOL(hevc_back_clock_enable);

void hevc_back_clock_hi_enable(void)
{
	hevc_back_clock_set(2);
}
EXPORT_SYMBOL(hevc_back_clock_hi_enable);

int hevc_clock_init(void)
{
	if (p_vdec_hevc() && p_vdec_hevc()->clock_init)
		return p_vdec_hevc()->clock_init();
	else
		return 0;
}
EXPORT_SYMBOL(hevc_clock_init);

int hevc_clock_set(int clk)
{
	pr_debug("%s-----%d\n", __func__, clk);
	if (p_vdec_hevc() && p_vdec_hevc()->clock_set)
		return p_vdec_hevc()->clock_set(clk);
	else
		return -1;
}
EXPORT_SYMBOL(hevc_clock_set);

void hevc_clock_enable(void)
{
	hevc_clock_set(1);
}
EXPORT_SYMBOL(hevc_clock_enable);

void hevc_clock_hi_enable(void)
{
	hevc_clock_set(2);
}
EXPORT_SYMBOL(hevc_clock_hi_enable);

void hevc_back_clock_on(void)
{
	IF_HAVE_RUN(p_vdec_hevc_back(), clock_on);
}
EXPORT_SYMBOL(hevc_back_clock_on);

void hevc_back_clock_off(void)
{
	IF_HAVE_RUN(p_vdec_hevc_back(), clock_off);
	clock_source_wxhxfps_saved[VDEC_HEVCB] = 0;
}
EXPORT_SYMBOL(hevc_back_clock_off);

void hevc_clock_on(void)
{
	IF_HAVE_RUN(p_vdec_hevc(), clock_on);
}
EXPORT_SYMBOL(hevc_clock_on);

void hevc_clock_off(void)
{
	IF_HAVE_RUN(p_vdec_hevc(), clock_off);
	clock_source_wxhxfps_saved[VDEC_HEVC] = 0;
}
EXPORT_SYMBOL(hevc_clock_off);

int vdec_source_get(enum vdec_type_e core)
{
	return clock_source_wxhxfps_saved[core];
}
EXPORT_SYMBOL(vdec_source_get);

int vdec_clk_get(enum vdec_type_e core)
{
	return get_current_vdec_chip()->clk_mgr[core]->clock_get(core);
}
EXPORT_SYMBOL(vdec_clk_get);

int get_clk_with_source(int format, int w_x_h_fps)
{
	struct clk_set_setting *p_setting;
	int i;
	int clk = -2;

	p_setting = get_current_vdec_chip()->clk_setting_array;
	if (!p_setting || format < 0 || format > VFORMAT_MAX) {
		pr_info("error on get_clk_with_source ,%p,%d\n",
			p_setting, format);
		return -1;	/*no setting found. */
	}
	p_setting = &p_setting[format];
	for (i = 0; i < MAX_CLK_SET; i++) {
		if (p_setting->set[i].wh_X_fps > w_x_h_fps) {
			clk = p_setting->set[i].clk_Mhz;
			break;
		}
	}
	return clk;
}
EXPORT_SYMBOL(get_clk_with_source);

int vdec_source_changed_for_clk_set(int format, int width, int height, int fps)
{
	int clk = get_clk_with_source(format, width * height * fps);
	int ret_clk;

	if (clk < 0) {
		pr_info("can't get valid clk for source ,%d,%d,%d\n",
			width, height, fps);
		if (format >= 1920 && width >= 1080 && fps >= 30)
			clk = 2;	/*default high clk */
		else
			clk = 0;	/*default clk. */
	}
	if (width * height * fps == 0)
		clk = 0;
	/*
	 *clk == 0
	 *is used for set default clk;
	 *if used supper clk.
	 *changed to default  min clk.
	 */

	if (format == VFORMAT_HEVC || format == VFORMAT_VP9
		|| format == VFORMAT_AVS2
		|| format == VFORMAT_AV1) {
		ret_clk = hevc_clock_set(clk);
		clock_source_wxhxfps_saved[VDEC_HEVC] = width * height * fps;
		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
			ret_clk = hevc_back_clock_set(clk);
			clock_source_wxhxfps_saved[VDEC_HEVCB] = width * height * fps;
		}
	} else if (format == VFORMAT_H264_ENC || format == VFORMAT_JPEG_ENC) {
		ret_clk = hcodec_clock_set(clk);
		clock_source_wxhxfps_saved[VDEC_HCODEC] = width * height * fps;
	} else if (format == VFORMAT_H264_4K2K &&
		get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_M8) {
		ret_clk = vdec2_clock_set(clk);
		clock_source_wxhxfps_saved[VDEC_2] = width * height * fps;
		ret_clk = vdec_clock_set(clk);
		clock_source_wxhxfps_saved[VDEC_1] = width * height * fps;
	} else {
		ret_clk = vdec_clock_set(clk);
		clock_source_wxhxfps_saved[VDEC_1] = width * height * fps;
	}
	return ret_clk;
}
EXPORT_SYMBOL(vdec_source_changed_for_clk_set);

static int register_vdec_clk_mgr_per_cpu(int cputype,
	enum vdec_type_e vdec_type, struct chip_vdec_clk_s *t_mgr)
{

	struct chip_vdec_clk_s *mgr;

	if (cputype != get_cpu_major_id() || vdec_type >= VDEC_MAX) {
		/*
		 *pr_info("ignore vdec clk mgr for vdec[%d] cpu=%d\n",
		 *vdec_type, cputype);
		 */
		return 0;	/* ignore don't needed firmare. */
	}
	mgr = vzalloc(sizeof(struct chip_vdec_clk_s));
	if (!mgr)
		return -ENOMEM;
	*mgr = *t_mgr;
	/*
	 *pr_info("register vdec clk mgr for vdec[%d]\n", vdec_type);
	 */
	if (mgr->clock_init) {
		if (mgr->clock_init()) {
			vfree(mgr);
			return -ENOMEM;
		}
	}
	get_current_vdec_chip()->clk_mgr[vdec_type] = mgr;
	return 0;
}

int register_vdec_clk_mgr(int cputype[], enum vdec_type_e vdec_type,
	struct chip_vdec_clk_s *t_mgr)
{
	int i = 0;

	while (cputype[i] > 0) {
		register_vdec_clk_mgr_per_cpu(cputype[i], vdec_type, t_mgr);
		i++;
	}
	return 0;
}
EXPORT_SYMBOL(register_vdec_clk_mgr);

int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type)
{
	vfree(get_current_vdec_chip()->clk_mgr[vdec_type]);

	return 0;
}
EXPORT_SYMBOL(unregister_vdec_clk_mgr);

static int register_vdec_clk_setting_per_cpu(int cputype,
	struct clk_set_setting *setting, int size)
{

	struct clk_set_setting *p_setting;

	if (cputype != get_cpu_major_id()) {
		/*
		 *pr_info("ignore clk_set_setting for cpu=%d\n",
		 *cputype);
		 */
		return 0;	/* ignore don't needed this setting . */
	}
	p_setting = vzalloc(size);
	if (!p_setting)
		return -ENOMEM;
	memcpy(p_setting, setting, size);

	pr_info("register clk_set_setting cpu[%d]\n", cputype);

	get_current_vdec_chip()->clk_setting_array = p_setting;
	return 0;
}

int register_vdec_clk_setting(int cputype[],
	struct clk_set_setting *p_seting, int size)
{
	int i = 0;

	while (cputype[i] > 0) {
		register_vdec_clk_setting_per_cpu(cputype[i], p_seting, size);
		i++;
	}
	return 0;
}
EXPORT_SYMBOL(register_vdec_clk_setting);

int unregister_vdec_clk_setting(void)
{
	vfree(get_current_vdec_chip()->clk_setting_array);

	return 0;
}
EXPORT_SYMBOL(unregister_vdec_clk_setting);

