/*
 * drivers/amlogic/media/stream_input/parser/stream_buffer_base.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.
 *
 */
#define DEBUG
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../../frame_provider/decoder/utils/vdec.h"
#include "amports_priv.h"
#include "stream_buffer_base.h"
#include "thread_rw.h"

#define DEFAULT_VIDEO_BUFFER_SIZE		(1024 * 1024 * 3)
#define DEFAULT_VIDEO_BUFFER_SIZE_4K		(1024 * 1024 * 6)
#define DEFAULT_VIDEO_BUFFER_SIZE_TVP		(1024 * 1024 * 10)
#define DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP	(1024 * 1024 * 15)

static struct stream_buf_s vdec_buf_def = {
	.reg_base	= VLD_MEM_VIFIFO_REG_BASE,
	.type		= BUF_TYPE_VIDEO,
	.buf_start	= 0,
	.buf_size	= DEFAULT_VIDEO_BUFFER_SIZE,
	.default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
	.first_tstamp	= INVALID_PTS
};

static struct stream_buf_s hevc_buf_def = {
	.reg_base	= HEVC_STREAM_REG_BASE,
	.type		= BUF_TYPE_HEVC,
	.buf_start	= 0,
	.buf_size	= DEFAULT_VIDEO_BUFFER_SIZE_4K,
	.default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
	.first_tstamp	= INVALID_PTS
};

static struct stream_buf_s *get_def_parms(int f)
{
	switch (f) {
	case VFORMAT_HEVC:
	case VFORMAT_AVS2:
	case VFORMAT_AV1:
	case VFORMAT_VP9:
		return &hevc_buf_def;
	default:
		return &vdec_buf_def;
	}
}

int stream_buffer_base_init(struct stream_buf_s *stbuf,
				struct stream_buf_ops *ops,
				struct parser_args *pars)
{
	struct vdec_s *vdec =
		container_of(stbuf, struct vdec_s, vbuf);
	struct stream_port_s *port = NULL;
	u32 format, width, height;

	/* sanity check. */
	if (WARN_ON(!stbuf) || WARN_ON(!ops))
		return -EINVAL;

	port	= vdec->port;
	format	= vdec->port->vformat;
	width	= vdec->sys_info->width;
	height	= vdec->sys_info->height;

	if (!stbuf->ext_buf_addr) {
		memcpy(stbuf, get_def_parms(format),
			sizeof(*stbuf));
	}

	stbuf->id	= vdec->id;
	stbuf->is_hevc	= ((format == VFORMAT_HEVC) ||
			(format == VFORMAT_AVS2) ||
			(format == VFORMAT_AV1) ||
			(format == VFORMAT_VP9));
	stbuf->for_4k	= ((width * height) >
			(1920 * 1088)) ? 1 : 0;
	stbuf->is_multi_inst = !vdec_single(vdec);
	memcpy(&stbuf->pars, pars, sizeof(*pars));

	/* register ops func. */
	stbuf->ops	= ops;

	return 0;
}
EXPORT_SYMBOL(stream_buffer_base_init);

void stream_buffer_set_ext_buf(struct stream_buf_s *stbuf,
			       ulong addr,
			       u32 size,
			       u32 flag)
{
	stbuf->ext_buf_addr	= addr;
	stbuf->buf_size 	= size;
	stbuf->is_secure	= ((flag & STBUF_META_FLAG_SECURE) != 0);
	stbuf->use_ptsserv	= ((flag & STBUF_META_FLAG_PTS_SERV) != 0);
	/*
	pr_debug("%s, addr %lx, size 0x%x, secure %d\n", __func__,
		stbuf->ext_buf_addr, stbuf->buf_size, stbuf->is_secure);
	*/
}
EXPORT_SYMBOL(stream_buffer_set_ext_buf);

#ifdef VDEC_FCC_SUPPORT
void fcc_wakeup_jump_back(struct vdec_s *vdec,
	struct stream_buffer_metainfo *meta)
{
	u32 first_ptr;
	u32 round_down_size = 0;
	if (fcc_debug_enable())
		pr_info("[%d][FCC]: jump_back_done = %d jump_back_flag = %d stbuf_pktaddr = 0x%x size = 0x%x\n",
			vdec->id, vdec->jump_back_done, meta->jump_back_flag,
			meta->stbuf_pktaddr, meta->stbuf_size);
	if (vdec->fcc_mode == FCC_DEC_MODE && vdec->fcc_status != SWITCH_DONE_STATUS) {
		mutex_lock(&vdec->jump_back_mutex);
		if (meta->jump_back_flag && !vdec->jump_back_done) {
			if (vdec->input.target == VDEC_INPUT_TARGET_HEVC)
				round_down_size = 0x80;
			else if (vdec->input.target == VDEC_INPUT_TARGET_VLD)
				round_down_size = 0x100;

			if (vdec->vbuf.ext_buf_addr > (meta->stbuf_pktaddr - round_down_size))
				first_ptr = vdec->vbuf.ext_buf_addr;
			else {
				first_ptr = round_down(meta->stbuf_pktaddr, round_down_size);
			}
			vdec->jump_back_done = 1;
			vdec->jump_back_rp = first_ptr;
			wake_up_interruptible(&vdec->jump_back_wq);
		} else if (!vdec->jump_back_done && !vdec->jump_back_error) {
			vdec->jump_back_error = 1;
			wake_up_interruptible(&vdec->jump_back_wq);
		}
		mutex_unlock(&vdec->jump_back_mutex);
	}

	return;
}
#endif

void stream_buffer_meta_write(struct stream_buf_s *stbuf,
	struct stream_buffer_metainfo *meta)
{
	u32 wp = stbuf->ops->get_wp(stbuf);

	if ((stbuf->stream_offset == 0) &&
		/*(wp == stbuf->ext_buf_addr) &&*/ /*For fcc, when switching to dec mode it doesn't meet*/
		(meta->stbuf_pktaddr > stbuf->ext_buf_addr)) {
		struct vdec_s *vdec = container_of(stbuf, struct vdec_s, vbuf);
		u32 first_ptr;
		u32 round_down_size = 0;

		/*RP max alignment requirement*/
		if (vdec->input.target == VDEC_INPUT_TARGET_HEVC)
			round_down_size = 0x80;
		else if (vdec->input.target == VDEC_INPUT_TARGET_VLD)
			round_down_size = 0x100;

		if (stbuf->ext_buf_addr > (meta->stbuf_pktaddr - round_down_size))
			first_ptr = stbuf->ext_buf_addr;
		else {
			first_ptr = round_down(meta->stbuf_pktaddr, round_down_size);
			pr_info("warn: first packet_wp(%x round_down %x) is not stbuf start addr(%lx)\n",
				meta->stbuf_pktaddr, first_ptr, stbuf->ext_buf_addr);
		}

		stbuf->ops->set_wp(stbuf, first_ptr);
		stbuf->ops->set_rp(stbuf, first_ptr);
		vdec->input.swap_rp = first_ptr;
		if (vdec->slave)
			vdec->slave->input.swap_rp = first_ptr;
		if (vdec->input.target != VDEC_INPUT_TARGET_HEVC)
			stbuf->stream_offset += (meta->stbuf_pktaddr - stbuf->ext_buf_addr);
		else
			stbuf->stream_offset += (meta->stbuf_pktaddr - first_ptr);
	}

	if (meta->stbuf_pktaddr + meta->stbuf_pktsize < stbuf->buf_start + stbuf->buf_size)
		wp = meta->stbuf_pktaddr + meta->stbuf_pktsize;
	else
		wp = meta->stbuf_pktaddr + meta->stbuf_pktsize - stbuf->buf_size;

	stbuf->ops->set_wp(stbuf, wp);

	stbuf->stream_offset += meta->stbuf_pktsize;

#ifdef VDEC_FCC_SUPPORT
	fcc_wakeup_jump_back(container_of(stbuf, struct vdec_s, vbuf), meta);
#endif
	/*
	pr_debug("%s, update wp 0x%x + sz 0x%x --> 0x%x, stream_offset 0x%x\n",
		__func__, meta->stbuf_pktaddr, meta->stbuf_pktsize, wp, stbuf->stream_offset);
	*/
}
EXPORT_SYMBOL(stream_buffer_meta_write);

ssize_t stream_buffer_write_ex(struct file *file,
		       struct stream_buf_s *stbuf,
		       const char __user *buf,
		       size_t count, int flags)
{
	int r;
	u32 len = count;

	if (buf == NULL || count == 0)
		return -EINVAL;

	if (stbuf_space(stbuf) < count) {
		if ((flags & 2) || ((file != NULL) &&
				(file->f_flags & O_NONBLOCK))) {
			len = stbuf_space(stbuf);
			if (len < 256)	/* <1k.do eagain, */
				return -EAGAIN;
		} else {
			len = min(stbuf_canusesize(stbuf) / 8, len);
			if (stbuf_space(stbuf) < len) {
				r = stbuf_wait_space(stbuf, len);
				if (r < 0)
					return r;
			}
		}
	}

	stbuf->last_write_jiffies64 = jiffies_64;
	stbuf->is_phybuf = (flags & 1);

	len = min_t(u32, len, count);

	r = stbuf->ops->write(stbuf, buf, len);
	if (r > 0)
		stbuf->stream_offset += r;

	return r;
}
EXPORT_SYMBOL(stream_buffer_write_ex);

int stream_buffer_write(struct file *file,
		       struct stream_buf_s *stbuf,
		       const char *buf,
		       size_t count)
{
	if (stbuf->write_thread)
		return threadrw_write(file, stbuf, buf, count);
	else
		return stream_buffer_write_ex(file, stbuf, buf, count, 0);
}
EXPORT_SYMBOL(stream_buffer_write);

