/*
 * drivers/amlogic/media/frame_provider/decoder/utils/vdec_canvas_utils.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/types.h>
#include "vdec_canvas_utils.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "vdec.h"

static struct canvas_status_s canvas_stat[CANVAS_MAX_SIZE];
static struct canvas_status_s mdec_cav_stat[MDEC_CAV_LUT_MAX];
static struct canvas_config_s *mdec_cav_pool = NULL;

extern u32 vdec_get_debug(void);


bool is_support_vdec_canvas(void)
{
	/* vdec canvas note:
	 * 1. canvas params config to display, do not use
	 *    vf->canvasxAddr, should use vf->canvasxconfig[].
	 * 2. the endian can not config with canvas. and hevc
	 *    core should not config canvas. config endian in
	 *    probe function like h265/vp9/av1/avs2.
	*/
	if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) ||
		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5W))
		return true;
	return false;
}
EXPORT_SYMBOL(is_support_vdec_canvas);

static int get_canvas(unsigned int index, unsigned int base)
{
	int start;
	int canvas_index = index * base;
	int ret = 0;

	if ((base > 4) || (base == 0))
		return -1;

	if ((AMVDEC_CANVAS_START_INDEX + canvas_index + base - 1)
		<= AMVDEC_CANVAS_MAX1) {
		start = AMVDEC_CANVAS_START_INDEX + base * index;
	} else {
		canvas_index -= (AMVDEC_CANVAS_MAX1 -
			AMVDEC_CANVAS_START_INDEX + 1) / base * base;
		if (canvas_index <= AMVDEC_CANVAS_MAX2)
			start = canvas_index / base;
		else
			return -1;
	}

	if (base == 1) {
		ret = start;
	} else if (base == 2) {
		ret = ((start + 1) << 16) | ((start + 1) << 8) | start;
	} else if (base == 3) {
		ret = ((start + 2) << 16) | ((start + 1) << 8) | start;
	} else if (base == 4) {
		ret = (((start + 3) << 24) | (start + 2) << 16) |
			((start + 1) << 8) | start;
	}

	return ret;
}

static int get_canvas_ex(int type, int id)
{
	int i;
	unsigned long flags;

	flags = vdec_canvas_lock();

	for (i = 0; i < CANVAS_MAX_SIZE; i++) {
		/*0x10-0x15 has been used by rdma*/
		if ((i >= 0x10) && (i <= 0x15))
				continue;
		if ((canvas_stat[i].type == type) &&
			(canvas_stat[i].id & (1 << id)) == 0) {
			canvas_stat[i].canvas_used_flag++;
			canvas_stat[i].id |= (1 << id);
			if (vdec_get_debug() & 4)
				pr_debug("get used canvas %d\n", i);
			vdec_canvas_unlock(flags);
			if (i < AMVDEC_CANVAS_MAX2 + 1)
				return i;
			else
				return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1);
		}
	}

	for (i = 0; i < CANVAS_MAX_SIZE; i++) {
		/*0x10-0x15 has been used by rdma*/
		if ((i >= 0x10) && (i <= 0x15))
				continue;
		if (canvas_stat[i].type == 0) {
			canvas_stat[i].type = type;
			canvas_stat[i].canvas_used_flag = 1;
			canvas_stat[i].id = (1 << id);
			if (vdec_get_debug() & 4) {
				pr_debug("get canvas %d\n", i);
				pr_debug("canvas_used_flag %d\n",
					canvas_stat[i].canvas_used_flag);
				pr_debug("canvas_stat[i].id %d\n",
					canvas_stat[i].id);
			}
			vdec_canvas_unlock(flags);
			if (i < AMVDEC_CANVAS_MAX2 + 1)
				return i;
			else
				return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1);
		}
	}
	vdec_canvas_unlock(flags);

	pr_info("cannot get canvas\n");

	return -1;
}

static void free_canvas_ex(int index, int id)
{
	unsigned long flags;
	int offset;

	flags = vdec_canvas_lock();
	if (index >= 0 &&
		index < AMVDEC_CANVAS_MAX2 + 1)
		offset = index;
	else if ((index >= AMVDEC_CANVAS_START_INDEX) &&
		(index <= AMVDEC_CANVAS_MAX1))
		offset = index + AMVDEC_CANVAS_MAX2 + 1 - AMVDEC_CANVAS_START_INDEX;
	else {
		vdec_canvas_unlock(flags);
		return;
	}

	if ((canvas_stat[offset].canvas_used_flag > 0) &&
		(canvas_stat[offset].id & (1 << id))) {
		canvas_stat[offset].canvas_used_flag--;
		canvas_stat[offset].id &= ~(1 << id);
		if (canvas_stat[offset].canvas_used_flag == 0) {
			canvas_stat[offset].type = 0;
			canvas_stat[offset].id = 0;
		}
		if (vdec_get_debug() & 4) {
			pr_debug("free index %d used_flag %d, type = %d, id = %d\n",
				offset,
				canvas_stat[offset].canvas_used_flag,
				canvas_stat[offset].type,
				canvas_stat[offset].id);
		}
	}
	vdec_canvas_unlock(flags);

	return;
}


static int get_internal_cav_lut(unsigned int index, unsigned int base)
{
	int start;
	int canvas_index = index * base;
	int ret = 0;

	if ((base > 4) || (base == 0))
		return -1;

	if (canvas_index + base - 1 < MDEC_CAV_LUT_MAX)
		start = canvas_index;
	else
		return -1;

	if (base == 1) {
		ret = start;
	} else if (base == 2) {
		ret = ((start + 1) << 16) | ((start + 1) << 8) | start;
	} else if (base == 3) {
		ret = ((start + 2) << 16) | ((start + 1) << 8) | start;
	} else if (base == 4) {
		ret = (((start + 3) << 24) | (start + 2) << 16) |
			((start + 1) << 8) | start;
	}

	return ret;
}

static int get_internal_cav_lut_ex(int type, int id)
{
	int i;
	unsigned long flags;

	flags = vdec_canvas_lock();

	for (i = 0; i < MDEC_CAV_LUT_MAX; i++) {
		if ((mdec_cav_stat[i].type == type) &&
			(mdec_cav_stat[i].id & (1 << id)) == 0) {
			mdec_cav_stat[i].canvas_used_flag++;
			mdec_cav_stat[i].id |= (1 << id);
			if (vdec_get_debug() & 4)
				pr_debug("get used cav lut %d\n", i);
			vdec_canvas_unlock(flags);
			return i;
		}
	}

	for (i = 0; i < MDEC_CAV_LUT_MAX; i++) {
		if (mdec_cav_stat[i].type == 0) {
			mdec_cav_stat[i].type = type;
			mdec_cav_stat[i].canvas_used_flag = 1;
			mdec_cav_stat[i].id = (1 << id);
			if (vdec_get_debug() & 4)
				pr_debug("get cav lut %d\n", i);
			vdec_canvas_unlock(flags);
			return i;
		}
	}
	vdec_canvas_unlock(flags);

	pr_info("cannot get cav lut\n");

	return -1;
}

static void free_internal_cav_lut(int index, int id)
{
	unsigned long flags;
	int offset;

	flags = vdec_canvas_lock();
	if (index > 0 && index < MDEC_CAV_LUT_MAX)
		offset = index;
	else {
		vdec_canvas_unlock(flags);
		return;
	}
	if ((mdec_cav_stat[offset].canvas_used_flag > 0) &&
		(mdec_cav_stat[offset].id & (1 << id))) {
		mdec_cav_stat[offset].canvas_used_flag--;
		mdec_cav_stat[offset].id &= ~(1 << id);
		if (mdec_cav_stat[offset].canvas_used_flag == 0) {
			mdec_cav_stat[offset].type = 0;
			mdec_cav_stat[offset].id = 0;
		}
		if (vdec_get_debug() & 4) {
			pr_debug("free index %d used_flag %d, type = %d, id = %d\n",
				offset,
				mdec_cav_stat[offset].canvas_used_flag,
				mdec_cav_stat[offset].type,
				mdec_cav_stat[offset].id);
		}
	}
	vdec_canvas_unlock(flags);

	return;
}

unsigned long vdec_cav_get_addr(int index)
{
	if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
		pr_err("%s, error index %d\n", __func__, index);
		return -1;
	}

	return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].phy_addr;
}
EXPORT_SYMBOL(vdec_cav_get_addr);

unsigned int vdec_cav_get_width(int index)
{
	if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
		pr_err("%s, error index %d\n", __func__, index);
		return -1;
	}

	return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].width;
}
EXPORT_SYMBOL(vdec_cav_get_width);

unsigned int vdec_cav_get_height(int index)
{
	if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
		pr_err("%s, error index %d\n", __func__, index);
		return -1;
	}
	return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].height;
}
EXPORT_SYMBOL(vdec_cav_get_height);

void cav_lut_info_store(u32 index, ulong addr, u32 width,
	u32 height, u32 wrap, u32 blkmode, u32 endian)
{
	struct canvas_config_s *pool = NULL;

	if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
		pr_err("%s, error index %d\n", __func__, index);
		return;
	}
	if (mdec_cav_pool == NULL)
		mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s)
			* (MDEC_CAV_LUT_MAX + 1));

	if (mdec_cav_pool == NULL) {
		pr_err("%s failed, mdec_cav_pool null\n", __func__);
		return;
	}
	pool = &mdec_cav_pool[index];
	pool->width = width;
	pool->height = height;
	pool->block_mode = blkmode;
	pool->endian = endian;
	pool->phy_addr = addr;
}

void config_cav_lut_ex(u32 index, ulong addr, u32 width,
	u32 height, u32 wrap, u32 blkmode,
	u32 endian, enum vdec_type_e core)
{
	unsigned long datah_temp, datal_temp;

	if (!is_support_vdec_canvas()) {
		canvas_config_ex(index, addr, width, height, wrap, blkmode, endian);
		if (vdec_get_debug() & 0x40000000) {
			pr_info("%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n",
				__func__, index, addr, width, height, blkmode, endian);
		}
	} else {
		/*
		datal_temp = (cav_lut.start_addr & 0x1fffffff) |
			((cav_lut.cav_width & 0x7 ) << 29 );
		datah_temp = ((cav_lut.cav_width  >> 3) & 0x1ff) |
			(( cav_lut.cav_hight & 0x1fff) <<9 ) |
			((cav_lut.x_wrap_en & 1) << 22 ) |
			(( cav_lut.y_wrap_en & 1) << 23) |
			(( cav_lut.blk_mode & 0x3) << 24);
		*/
		u32 addr_bits_l = ((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) << CAV_WADDR_LBIT);
		u32 width_l     = ((((width    + 7) >> 3) & CANVAS_WIDTH_LMASK) << CAV_WIDTH_LBIT);
		u32 width_h     = ((((width    + 7) >> 3) >> CANVAS_WIDTH_LWID) << CAV_WIDTH_HBIT);
		u32 height_h    = (height & CANVAS_HEIGHT_MASK) << CAV_HEIGHT_HBIT;
		u32 blkmod_h    = (blkmode & CANVAS_BLKMODE_MASK) << CAV_BLKMODE_HBIT;
		u32 switch_bits_ctl = (endian & 0xf) << CAV_ENDIAN_HBIT;
		u32 wrap_h      = (0 << 23);
		datal_temp = addr_bits_l | width_l;
		datah_temp = width_h | height_h | wrap_h | blkmod_h | switch_bits_ctl;

		if (core == VDEC_1) {
			if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T3) && (endian == 7))
				WRITE_VREG(MDEC_CAV_CFG0, 0x1ff << 17);
			else
				WRITE_VREG(MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode
			WRITE_VREG(MDEC_CAV_LUT_DATAL, datal_temp);
			WRITE_VREG(MDEC_CAV_LUT_DATAH, datah_temp);
			WRITE_VREG(MDEC_CAV_LUT_ADDR,  index);
		}

		cav_lut_info_store(index, addr, width, height, wrap, blkmode, endian);

		if (vdec_get_debug() & 0x40000000) {
			pr_info("%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n",
				__func__, index, addr, width, height, blkmode, endian);
			pr_info("data(h,l): 0x%8lx, 0x%8lx\n", datah_temp, datal_temp);
	    }
	}
}
EXPORT_SYMBOL(config_cav_lut_ex);

void config_cav_lut(int index, struct canvas_config_s *cfg,
	enum vdec_type_e core)
{
	config_cav_lut_ex(index,
		cfg->phy_addr,
		cfg->width,
		cfg->height,
		CANVAS_ADDR_NOWRAP,
		cfg->block_mode,
		cfg->endian,
		core);
}
EXPORT_SYMBOL(config_cav_lut);


void vdec_canvas_port_register(struct vdec_s *vdec)
{
	if (is_support_vdec_canvas()) {
		vdec->get_canvas = get_internal_cav_lut;
		vdec->get_canvas_ex = get_internal_cav_lut_ex;
		vdec->free_canvas_ex = free_internal_cav_lut;
		if (mdec_cav_pool == NULL) {
			mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s)
			* (MDEC_CAV_LUT_MAX + 1));
		}
	} else {
		vdec->get_canvas = get_canvas;
		vdec->get_canvas_ex = get_canvas_ex;
		vdec->free_canvas_ex = free_canvas_ex;
	}
}
EXPORT_SYMBOL(vdec_canvas_port_register);
