/*
 * drivers/amlogic/media/stream_input/parser/streambuf.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/spinlock.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/iomap.h>
#include <asm/cacheflush.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
/* #include <mach/am_regs.h> */

#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../frame_provider/decoder/utils/vdec.h"
#include "streambuf_reg.h"
#include "streambuf.h"
#include <linux/amlogic/media/utils/amports_config.h>
#include "../amports/amports_priv.h"
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>

#define STBUF_SIZE   (64*1024)
#define STBUF_WAIT_INTERVAL  (HZ/100)
#define MEM_NAME "streambuf"

void *fetchbuf = 0;

static s32 _stbuf_alloc(struct stream_buf_s *buf, bool is_secure)
{
	if (buf->buf_size == 0)
		return -ENOBUFS;

	while (buf->buf_start == 0) {
		int flags = CODEC_MM_FLAGS_DMA;

		buf->buf_page_num = PAGE_ALIGN(buf->buf_size) / PAGE_SIZE;
		if (buf->type == BUF_TYPE_SUBTITLE)
			flags = CODEC_MM_FLAGS_DMA_CPU;

		/*
		 *if 4k,
		 *used cma first,for less mem fragments.
		 */
		if (((buf->type == BUF_TYPE_HEVC) ||
			(buf->type == BUF_TYPE_VIDEO)) &&
			buf->for_4k)
			flags |= CODEC_MM_FLAGS_CMA_FIRST;
		if (buf->buf_size > 20 * 1024 * 1024)
			flags |= CODEC_MM_FLAGS_CMA_FIRST;

		if ((buf->type == BUF_TYPE_HEVC) ||
			(buf->type == BUF_TYPE_VIDEO)) {
			flags |= CODEC_MM_FLAGS_FOR_VDECODER;
		} else if (buf->type == BUF_TYPE_AUDIO) {
			flags |= CODEC_MM_FLAGS_FOR_ADECODER;
			flags |= CODEC_MM_FLAGS_DMA_CPU;
		}

		if (is_secure)
			flags |= CODEC_MM_FLAGS_TVP;

		buf->buf_start = codec_mm_alloc_for_dma(MEM_NAME,
			buf->buf_page_num, 4+PAGE_SHIFT, flags);
		if (!buf->buf_start) {
			int is_video = (buf->type == BUF_TYPE_HEVC) ||
					(buf->type == BUF_TYPE_VIDEO);
			if (is_video && buf->buf_size >= 9 * SZ_1M) {/*min 6M*/
				int old_size = buf->buf_size;

				buf->buf_size  =
					PAGE_ALIGN(buf->buf_size * 2/3);
				pr_info("%s stbuf alloced size = %d failed try small %d size\n",
				(buf->type == BUF_TYPE_HEVC) ? "HEVC" :
				(buf->type == BUF_TYPE_VIDEO) ? "Video" :
				(buf->type == BUF_TYPE_AUDIO) ? "Audio" :
				"Subtitle", old_size, buf->buf_size);
				continue;
			}
			pr_info("%s stbuf alloced size = %d failed\n",
				(buf->type == BUF_TYPE_HEVC) ? "HEVC" :
				(buf->type == BUF_TYPE_VIDEO) ? "Video" :
				(buf->type == BUF_TYPE_AUDIO) ? "Audio" :
				"Subtitle", buf->buf_size);
			return -ENOMEM;
		}

		buf->is_secure = is_secure;

		pr_debug("%s stbuf alloced at %p, secure = %d, size = %d\n",
				(buf->type == BUF_TYPE_HEVC) ? "HEVC" :
				(buf->type == BUF_TYPE_VIDEO) ? "Video" :
				(buf->type == BUF_TYPE_AUDIO) ? "Audio" :
				"Subtitle", (void *)buf->buf_start,
				buf->is_secure,
				buf->buf_size);
	}

	buf->canusebuf_size = buf->buf_size;
	buf->flag |= BUF_FLAG_ALLOC;

	return 0;
}

int stbuf_change_size(struct stream_buf_s *buf, int size, bool is_secure)
{
	unsigned long old_buf;
	int old_size, old_pagenum;
	int ret;

	pr_info("buffersize=%d,%d,start=%p, secure=%d\n", size, buf->buf_size,
			(void *)buf->buf_start, is_secure);

	if (buf->buf_size == size && buf->buf_start != 0)
		return 0;

	old_buf = buf->buf_start;
	old_size = buf->buf_size;
	old_pagenum = buf->buf_page_num;
	buf->buf_start = 0;
	buf->buf_size = size;
	ret = size;

	if (size == 0 ||
		_stbuf_alloc(buf, is_secure) == 0) {
		/*
		 * size=0:We only free the old memory;
		 * alloc ok,changed to new buffer
		 */
		if (old_buf != 0) {
			codec_mm_free_for_dma(MEM_NAME, old_buf);
		}

		if (size == 0)
			buf->is_secure = false;

		pr_info("changed the (%d) buffer size from %d to %d\n",
				buf->type, old_size, size);
		return 0;
	} else {
		/* alloc failed */
		buf->buf_start = old_buf;
		buf->buf_size = old_size;
		buf->buf_page_num = old_pagenum;
		pr_info("changed the (%d) buffer size from %d to %d,failed\n",
				buf->type, old_size, size);
	}

	return ret;
}

int stbuf_fetch_init(void)
{
	if (NULL != fetchbuf)
		return 0;

	fetchbuf = (void *)__get_free_pages(GFP_KERNEL,
						get_order(FETCHBUF_SIZE));

	if (!fetchbuf) {
		pr_info("%s: Can not allocate fetch working buffer\n",
				__func__);
		return -ENOMEM;
	}
	return 0;
}
EXPORT_SYMBOL(stbuf_fetch_init);

void stbuf_fetch_release(void)
{
	if (0 && fetchbuf) {
		/* always don't free.for safe alloc/free*/
		free_pages((unsigned long)fetchbuf, get_order(FETCHBUF_SIZE));
		fetchbuf = 0;
	}
}

static void _stbuf_timer_func(struct timer_list *arg)
{
	struct stream_buf_s *p = (struct stream_buf_s *)arg;

	if (stbuf_space(p) < p->wcnt) {
		p->timer.expires = jiffies + STBUF_WAIT_INTERVAL;

		add_timer(&p->timer);
	} else
		wake_up_interruptible(&p->wq);

}

u32 stbuf_level(struct stream_buf_s *buf)
{
	if ((buf->type == BUF_TYPE_HEVC) || (buf->type == BUF_TYPE_VIDEO)) {
		if (buf->no_parser) {
			int level = buf->buf_wp - buf->buf_rp;
			if (level < 0)
				level += buf->buf_size;
			return level;
		} else {
			if (READ_PARSER_REG(PARSER_ES_CONTROL) & 1) {
				int level = READ_PARSER_REG(PARSER_VIDEO_WP) -
					READ_PARSER_REG(PARSER_VIDEO_RP);
				if (level < 0)
					level += READ_PARSER_REG(PARSER_VIDEO_END_PTR) -
					READ_PARSER_REG(PARSER_VIDEO_START_PTR) + 8;
				return (u32)level;
			} else
				return (buf->type == BUF_TYPE_HEVC) ?
					READ_VREG(HEVC_STREAM_LEVEL) :
					_READ_ST_REG(LEVEL);
		}
	}

	return _READ_ST_REG(LEVEL);
}

u32 stbuf_rp(struct stream_buf_s *buf)
{
	if ((buf->type == BUF_TYPE_HEVC) || (buf->type == BUF_TYPE_VIDEO)) {
		if (buf->no_parser)
			return buf->buf_rp;
		else {
			if (READ_PARSER_REG(PARSER_ES_CONTROL) & 1)
				return READ_PARSER_REG(PARSER_VIDEO_RP);
			else
				return (buf->type == BUF_TYPE_HEVC) ?
					READ_VREG(HEVC_STREAM_RD_PTR) :
					_READ_ST_REG(RP);
		}
	}

	return _READ_ST_REG(RP);
}

u32 stbuf_space(struct stream_buf_s *buf)
{
	/* reserved space for safe write,
	 *   the parser fifo size is 1024byts, so reserve it
	 */
	int size;

	size = buf->canusebuf_size - stbuf_level(buf);

	if (buf->canusebuf_size >= buf->buf_size / 2) {
		/* old reversed value,tobe full, reversed only... */
		size = size - 6 * 1024;
	}

	if (!buf->no_parser) {
		if ((buf->type == BUF_TYPE_VIDEO)
			|| (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC))
			size -= READ_PARSER_REG(PARSER_VIDEO_HOLE);
	}
	return size > 0 ? size : 0;
}

u32 stbuf_size(struct stream_buf_s *buf)
{
	return buf->buf_size;
}

u32 stbuf_canusesize(struct stream_buf_s *buf)
{
	return buf->canusebuf_size;
}

s32 stbuf_init(struct stream_buf_s *buf, struct vdec_s *vdec)
{
	s32 r;
	u32 dummy;
	u32 addr32;

	VDEC_PRINT_FUN_LINENO(__func__, __LINE__);

	if (!buf->buf_start) {
		r = _stbuf_alloc(buf, (vdec) ?
			vdec->port_flag & PORT_FLAG_DRM : 0);
		if (r < 0)
			return r;
	}
	addr32 = buf->buf_start & 0xffffffff;
	buf->use_ptsserv = true;
	init_waitqueue_head(&buf->wq);

	/*
	 * For multidec, do not touch HW stream buffers during port
	 * init and release.
	 */
	if ((buf->type == BUF_TYPE_VIDEO) || (buf->type == BUF_TYPE_HEVC)) {
		if (vdec) {
			if (vdec_stream_based(vdec))
				vdec_set_input_buffer(vdec, addr32,
						buf->buf_size);
			else
				return vdec_set_input_buffer(vdec, addr32,
						buf->buf_size);
		}
	}

	buf->write_thread = 0;
	if (((vdec && !vdec_single(vdec)) || (buf->is_multi_inst)) &&
		(vdec_get_debug_flags() & 0x2) == 0)
		return 0;
	if (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC) {
		CLEAR_VREG_MASK(HEVC_STREAM_CONTROL, 1);
		WRITE_VREG(HEVC_STREAM_START_ADDR, addr32);
		WRITE_VREG(HEVC_STREAM_END_ADDR, addr32 + buf->buf_size);
		WRITE_VREG(HEVC_STREAM_RD_PTR, addr32);
		WRITE_VREG(HEVC_STREAM_WR_PTR, addr32);

		return 0;
	}

	if (buf->type == BUF_TYPE_VIDEO) {
		VDEC_PRINT_FUN_LINENO(__func__, __LINE__);

		_WRITE_ST_REG(CONTROL, 0);
		/* reset VLD before setting all pointers */
		WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT, 0);
		/*TODO: only > m6*/
#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
		WRITE_VREG(DOS_SW_RESET0, (1 << 4));
		WRITE_VREG(DOS_SW_RESET0, 0);
#else
		WRITE_RESET_REG(RESET0_REGISTER, RESET_VLD);
#endif

		dummy = READ_RESET_REG(RESET0_REGISTER);
		WRITE_VREG(POWER_CTL_VLD, 1 << 4);
	} else if (buf->type == BUF_TYPE_AUDIO) {
		_WRITE_ST_REG(CONTROL, 0);

		WRITE_AIU_REG(AIU_AIFIFO_GBIT, 0x80);
	}

	if (buf->type == BUF_TYPE_SUBTITLE) {
		WRITE_PARSER_REG(PARSER_SUB_RP, addr32);
		WRITE_PARSER_REG(PARSER_SUB_START_PTR, addr32);
		WRITE_PARSER_REG(PARSER_SUB_END_PTR,
					   addr32 + buf->buf_size - 8);

		return 0;
	}

	_WRITE_ST_REG(START_PTR, addr32);
	_WRITE_ST_REG(CURR_PTR, addr32);
	_WRITE_ST_REG(END_PTR, addr32 + buf->buf_size - 8);

	_SET_ST_REG_MASK(CONTROL, MEM_BUFCTRL_INIT);
	_CLR_ST_REG_MASK(CONTROL, MEM_BUFCTRL_INIT);

	_WRITE_ST_REG(BUF_CTRL, MEM_BUFCTRL_MANUAL);
	_WRITE_ST_REG(WP, addr32);

	_SET_ST_REG_MASK(BUF_CTRL, MEM_BUFCTRL_INIT);
	_CLR_ST_REG_MASK(BUF_CTRL, MEM_BUFCTRL_INIT);

	_SET_ST_REG_MASK(CONTROL,
			(0x11 << 16) | MEM_FILL_ON_LEVEL | MEM_CTRL_FILL_EN |
			MEM_CTRL_EMPTY_EN);

	if (buf->no_parser)
		_SET_ST_REG_MASK(CONTROL, 7 << 3);

	return 0;
}
EXPORT_SYMBOL(stbuf_init);

void stbuf_vdec2_init(struct stream_buf_s *buf)
{

	_WRITE_VDEC2_ST_REG(CONTROL, 0);

	_WRITE_VDEC2_ST_REG(START_PTR, _READ_ST_REG(START_PTR));
	_WRITE_VDEC2_ST_REG(END_PTR, _READ_ST_REG(END_PTR));
	_WRITE_VDEC2_ST_REG(CURR_PTR, _READ_ST_REG(CURR_PTR));

	_WRITE_VDEC2_ST_REG(CONTROL, MEM_FILL_ON_LEVEL | MEM_BUFCTRL_INIT);
	_WRITE_VDEC2_ST_REG(CONTROL, MEM_FILL_ON_LEVEL);

	_WRITE_VDEC2_ST_REG(BUF_CTRL, MEM_BUFCTRL_INIT);
	_WRITE_VDEC2_ST_REG(BUF_CTRL, 0);

	_WRITE_VDEC2_ST_REG(CONTROL,
			(0x11 << 16) | MEM_FILL_ON_LEVEL | MEM_CTRL_FILL_EN
			| MEM_CTRL_EMPTY_EN);
}

s32 stbuf_wait_space(struct stream_buf_s *stream_buf, size_t count)
{
	struct stream_buf_s *p = stream_buf;
	long time_out = 200;

	p->wcnt = count;

	timer_setup(&p->timer, _stbuf_timer_func, (ulong) p);

	mod_timer(&p->timer, jiffies + STBUF_WAIT_INTERVAL);

	if (wait_event_interruptible_timeout
		(p->wq, stbuf_space(p) >= count,
		 msecs_to_jiffies(time_out)) == 0) {
		del_timer_sync(&p->timer);

		return -EAGAIN;
	}

	del_timer_sync(&p->timer);

	return 0;
}

void stbuf_release(struct stream_buf_s *buf)
{
	int r;

	buf->first_tstamp = INVALID_PTS;
	if (!buf->ext_buf_addr) {
		r = stbuf_init(buf, NULL);/* reinit buffer */
		if (r < 0)
			pr_err("stbuf_release %d, stbuf_init failed\n", __LINE__);
	}
	if (buf->flag & BUF_FLAG_ALLOC && buf->buf_start) {
		codec_mm_free_for_dma(MEM_NAME, buf->buf_start);
		buf->flag &= ~BUF_FLAG_ALLOC;
		buf->buf_start = 0;
		buf->is_secure = false;
	}
	buf->flag &= ~BUF_FLAG_IN_USE;
}
EXPORT_SYMBOL(stbuf_release);

u32 stbuf_sub_rp_get(void)
{
	return READ_PARSER_REG(PARSER_SUB_RP);
}

void stbuf_sub_rp_set(unsigned int sub_rp)
{
	WRITE_PARSER_REG(PARSER_SUB_RP, sub_rp);
	return;
}

u32 stbuf_sub_wp_get(void)
{
	return READ_PARSER_REG(PARSER_SUB_WP);
}

u32 stbuf_sub_start_get(void)
{
	return READ_PARSER_REG(PARSER_SUB_START_PTR);
}

u32 parser_get_wp(struct stream_buf_s *vb)
{
	return READ_PARSER_REG(PARSER_VIDEO_WP);
}
EXPORT_SYMBOL(parser_get_wp);

void parser_set_wp(struct stream_buf_s *vb, u32 val)
{
	WRITE_PARSER_REG(PARSER_VIDEO_WP, val);
}
EXPORT_SYMBOL(parser_set_wp);

u32 parser_get_rp(struct stream_buf_s *vb)
{
	return READ_PARSER_REG(PARSER_VIDEO_RP);
}
EXPORT_SYMBOL(parser_get_rp);

void parser_set_rp(struct stream_buf_s *vb, u32 val)
{
	WRITE_PARSER_REG(PARSER_VIDEO_RP, val);
}
EXPORT_SYMBOL(parser_set_rp);

