/*
 * drivers/amlogic/media/stream_input/parser/tsdemux.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/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/dma-mapping.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/frame_sync/tsync.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/module.h>

#include <linux/uaccess.h>
/* #include <mach/am_regs.h> */
#include <linux/clk.h>
/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
/* #include <mach/mod_gate.h> */
/* #endif */

#include "../../frame_provider/decoder/utils/vdec.h"
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../amports/streambuf_reg.h"
#include "../amports/streambuf.h"
#include <linux/amlogic/media/utils/amports_config.h>
#include <linux/amlogic/media/frame_sync/tsync_pcr.h>

#include "tsdemux.h"
#include <linux/reset.h>
#include "../amports/amports_priv.h"

#define MAX_DRM_PACKAGE_SIZE 0x500000


MODULE_PARM_DESC(reset_demux_enable, "\n\t\t Reset demux enable");
static int reset_demux_enable = 0;
module_param(reset_demux_enable, int, 0644);

static const char tsdemux_fetch_id[] = "tsdemux-fetch-id";
static const char tsdemux_irq_id[] = "tsdemux-irq-id";

static u32 curr_pcr_num = 0xffff;
static u32 curr_vid_id = 0xffff;
static u32 curr_aud_id = 0xffff;
static u32 curr_sub_id = 0xffff;
static u32 curr_pcr_id = 0xffff;

static DECLARE_WAIT_QUEUE_HEAD(wq);
static u32 fetch_done;
static u32 discontinued_counter;
static u32 first_pcr;
static u8 pcrscr_valid;
static u8 pcraudio_valid;
static u8 pcrvideo_valid;
static u8 pcr_init_flag;

static int demux_skipbyte;

static struct tsdemux_ops *demux_ops;
static DEFINE_SPINLOCK(demux_ops_lock);

static int enable_demux_driver(void)
{
	return demux_ops ? 1 : 0;
}

void tsdemux_set_ops(struct tsdemux_ops *ops)
{
	unsigned long flags;

	spin_lock_irqsave(&demux_ops_lock, flags);
	demux_ops = ops;
	spin_unlock_irqrestore(&demux_ops_lock, flags);
}
EXPORT_SYMBOL(tsdemux_set_ops);

int tsdemux_set_reset_flag_ext(void)
{
	int r = 0;

	if (demux_ops && demux_ops->set_reset_flag)
		r = demux_ops->set_reset_flag();

	return r;
}

int tsdemux_set_reset_flag(void)
{
	unsigned long flags;
	int r;

	spin_lock_irqsave(&demux_ops_lock, flags);
	r = tsdemux_set_reset_flag_ext();
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_reset(void)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->reset) {
		tsdemux_set_reset_flag_ext();
		r = demux_ops->reset();
	}
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_request_irq(irq_handler_t handler, void *data)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->request_irq)
		r = demux_ops->request_irq(handler, data);
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_free_irq(void)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->free_irq)
		r = demux_ops->free_irq();
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_set_vid(int vpid)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->set_vid)
		r = demux_ops->set_vid(vpid);
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_set_aid(int apid)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->set_aid)
		r = demux_ops->set_aid(apid);
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_set_sid(int spid)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->set_sid)
		r = demux_ops->set_sid(spid);
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_set_pcrid(int pcrpid)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->set_pcrid)
		r = demux_ops->set_pcrid(pcrpid);
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_set_skip_byte(int skipbyte)
{
	unsigned long flags;
	int r = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->set_skipbyte)
		r = demux_ops->set_skipbyte(skipbyte);
	spin_unlock_irqrestore(&demux_ops_lock, flags);

	return r;
}

static int tsdemux_config(void)
{
	return 0;
}

static void tsdemux_pcr_set(unsigned int pcr);
/*TODO irq*/
/* bit 15 ---------------*/
/* bit 12 --VIDEO_PTS[32]*/
/* bit 0  ---------------*/
/*Read the 13th bit of STB_PTS_DTS_STATUS register
correspond to the highest bit of video pts*/
static irqreturn_t tsdemux_isr(int irq, void *dev_id)
{
	u32 int_status = 0;
	int id = (long)dev_id;

	if (!enable_demux_driver()) {
		int_status = READ_DEMUX_REG(STB_INT_STATUS);
	} else {
		if (id == 0)
			int_status = READ_DEMUX_REG(STB_INT_STATUS);
		else if (id == 1)
			int_status = READ_DEMUX_REG(STB_INT_STATUS_2);
		else if (id == 2)
			int_status = READ_DEMUX_REG(STB_INT_STATUS_3);
	}

	if (int_status & (1 << NEW_PDTS_READY)) {
		if (!enable_demux_driver()) {
			u32 pdts_status = READ_DEMUX_REG(STB_PTS_DTS_STATUS);
			u64 vpts;

			vpts = READ_MPEG_REG(VIDEO_PTS_DEMUX);
			vpts &= 0x00000000FFFFFFFF;
			if (pdts_status & 0x1000) {
				vpts = vpts | (1LL<<32);
			}

			if (pdts_status & (1 << VIDEO_PTS_READY))
				pts_checkin_wrptr_pts33(PTS_TYPE_VIDEO,
					READ_DEMUX_REG(VIDEO_PDTS_WR_PTR),
					vpts);

			if (pdts_status & (1 << AUDIO_PTS_READY))
				pts_checkin_wrptr(PTS_TYPE_AUDIO,
					READ_DEMUX_REG(AUDIO_PDTS_WR_PTR),
					READ_DEMUX_REG(AUDIO_PTS_DEMUX));

			WRITE_DEMUX_REG(STB_PTS_DTS_STATUS, pdts_status);
		} else {
#define DMX_READ_REG(i, r)\
	((i) ? ((i == 1) ? READ_DEMUX_REG(r##_2) : \
		READ_DEMUX_REG(r##_3)) : READ_DEMUX_REG(r))
			u64 vpts;
			u32 pdts_status = DMX_READ_REG(id, STB_PTS_DTS_STATUS);
			vpts = DMX_READ_REG(id, VIDEO_PTS_DEMUX);
			vpts &= 0x00000000FFFFFFFF;
			if (pdts_status & 0x1000) {
				vpts = vpts | (1LL<<32);
			}

			if (pdts_status & (1 << VIDEO_PTS_READY))
				pts_checkin_wrptr_pts33(PTS_TYPE_VIDEO,
					DMX_READ_REG(id, VIDEO_PDTS_WR_PTR),
					vpts);

			if (pdts_status & (1 << AUDIO_PTS_READY))
				pts_checkin_wrptr(PTS_TYPE_AUDIO,
					DMX_READ_REG(id, AUDIO_PDTS_WR_PTR),
					DMX_READ_REG(id, AUDIO_PTS_DEMUX));

			if (id == 1)
				WRITE_DEMUX_REG(STB_PTS_DTS_STATUS_2,
							pdts_status);
			else if (id == 2)
				WRITE_DEMUX_REG(STB_PTS_DTS_STATUS_3,
							pdts_status);
			else
				WRITE_DEMUX_REG(STB_PTS_DTS_STATUS,
							pdts_status);
		}
	}
	if (int_status & (1 << DIS_CONTINUITY_PACKET)) {
		discontinued_counter++;
		/* pr_info("discontinued counter=%d\n",discontinued_counter); */
	}
	if (int_status & (1 << SUB_PES_READY)) {
		/* TODO: put data to somewhere */
		/* pr_info("subtitle pes ready\n"); */
		wakeup_sub_poll();
	}
	if (int_status & (1<<PCR_READY)) {
		unsigned int pcr_pts = 0xffffffff;
		pcr_pts = DMX_READ_REG(id, PCR_DEMUX);
		tsdemux_pcr_set(pcr_pts);
	}

	if (!enable_demux_driver())
		WRITE_DEMUX_REG(STB_INT_STATUS, int_status);

	return IRQ_HANDLED;
}

static irqreturn_t parser_isr(int irq, void *dev_id)
{
	u32 int_status = READ_PARSER_REG(PARSER_INT_STATUS);

	WRITE_PARSER_REG(PARSER_INT_STATUS, int_status);

	if (int_status & PARSER_INTSTAT_FETCH_CMD) {
		fetch_done = 1;

		wake_up_interruptible(&wq);
	}

	return IRQ_HANDLED;
}

static ssize_t _tsdemux_write(const char __user *buf, size_t count,
							  int isphybuf)
{
	size_t r = count;
	const char __user *p = buf;
	u32 len;
	int ret;
	dma_addr_t dma_addr = 0;

	if (r > 0) {
		if (isphybuf)
			len = count;
		else {
			len = min_t(size_t, r, FETCHBUF_SIZE);
			if (copy_from_user(fetchbuf, p, len))
				return -EFAULT;

			dma_addr =
				dma_map_single(amports_get_dma_device(),
						fetchbuf,
						FETCHBUF_SIZE, DMA_TO_DEVICE);
			if (dma_mapping_error(amports_get_dma_device(),
						dma_addr))
				return -EFAULT;


		}

		fetch_done = 0;

		wmb();		/* Ensure fetchbuf  contents visible */

		if (isphybuf) {
			u32 buf_32 = (unsigned long)buf & 0xffffffff;
			WRITE_PARSER_REG(PARSER_FETCH_ADDR, buf_32);
		} else {
			WRITE_PARSER_REG(PARSER_FETCH_ADDR, dma_addr);
			dma_unmap_single(amports_get_dma_device(), dma_addr,
					FETCHBUF_SIZE, DMA_TO_DEVICE);
		}

		WRITE_PARSER_REG(PARSER_FETCH_CMD, (7 << FETCH_ENDIAN) | len);


		ret =
			wait_event_interruptible_timeout(wq, fetch_done != 0,
					HZ / 2);
		if (ret == 0) {
			WRITE_PARSER_REG(PARSER_FETCH_CMD, 0);
			pr_info("write timeout, retry\n");
			return -EAGAIN;
		} else if (ret < 0)
			return -ERESTARTSYS;

		p += len;
		r -= len;
	}

	return count - r;
}

#define PCR_EN                     12

static int reset_pcr_regs(void)
{
	u32 pcr_num;
	u32 pcr_regs = 0;
	if (curr_pcr_id >= 0x1FFF)
		return 0;
	/* set paramater to fetch pcr */
	pcr_num = 0;
	if (curr_pcr_id == curr_vid_id)
		pcr_num = 0;
	else if (curr_pcr_id == curr_aud_id)
		pcr_num = 1;
	else if (curr_pcr_id == curr_sub_id)
		pcr_num = 2;
	else
		pcr_num = 3;
	if (pcr_num != curr_pcr_num) {
		u32 clk_unit = 0;
		u32 clk_81 = 0;
		struct clk *clk;
		//clk = clk_get(NULL,"clk81");
		clk= devm_clk_get(amports_get_dma_device(),"clk_81");
		if (IS_ERR(clk) || clk == 0) {
			pr_info("[%s:%d] error clock\n", __func__, __LINE__);
			return 0;
		}
		clk_81 = clk_get_rate(clk);
		clk_unit = clk_81 / 90000;
		pr_info("[%s:%d] clk_81 = %x clk_unit =%x\n", __func__,
				__LINE__, clk_81, clk_unit);
		pcr_regs = 1 << PCR_EN | clk_unit;
		pr_info("[tsdemux_init] the set pcr_regs =%x\n", pcr_regs);
		if (READ_DEMUX_REG(TS_HIU_CTL_2) & 0x80) {
			WRITE_DEMUX_REG(PCR90K_CTL_2, pcr_regs);
			WRITE_DEMUX_REG(ASSIGN_PID_NUMBER_2, pcr_num);
			pr_info("[tsdemux_init] To use device 2,pcr_num=%d\n",
					pcr_num);
			pr_info("tsdemux_init] the read  pcr_regs= %x\n",
				READ_DEMUX_REG(PCR90K_CTL_2));
		} else if (READ_DEMUX_REG(TS_HIU_CTL_3) & 0x80) {
			WRITE_DEMUX_REG(PCR90K_CTL_3, pcr_regs);
			WRITE_DEMUX_REG(ASSIGN_PID_NUMBER_3, pcr_num);
			pr_info("[tsdemux_init] To use device 3,pcr_num=%d\n",
					pcr_num);
			pr_info("tsdemux_init] the read  pcr_regs= %x\n",
				READ_DEMUX_REG(PCR90K_CTL_3));
		} else {
			WRITE_DEMUX_REG(PCR90K_CTL, pcr_regs);
			WRITE_DEMUX_REG(ASSIGN_PID_NUMBER, pcr_num);
			pr_info("[tsdemux_init] To use device 1,pcr_num=%d\n",
					pcr_num);
			pr_info("tsdemux_init] the read  pcr_regs= %x\n",
				READ_DEMUX_REG(PCR90K_CTL));
		}
		curr_pcr_num = pcr_num;
	}
	return 1;
}

s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc,
		struct vdec_s *vdec)
{
	s32 r;
	u32 parser_sub_start_ptr;
	u32 parser_sub_end_ptr;
	u32 parser_sub_rp;
	pcrvideo_valid = 0;
	pcraudio_valid = 0;
	pcr_init_flag = 0;

	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
	/*TODO clk */
	/*
	 *switch_mod_gate_by_type(MOD_DEMUX, 1);
	 */
	/* #endif */

	amports_switch_gate("demux", 1);

	parser_sub_start_ptr = READ_PARSER_REG(PARSER_SUB_START_PTR);
	parser_sub_end_ptr = READ_PARSER_REG(PARSER_SUB_END_PTR);
	parser_sub_rp = READ_PARSER_REG(PARSER_SUB_RP);

	WRITE_RESET_REG(RESET1_REGISTER, RESET_PARSER);

	if (enable_demux_driver()) {
		tsdemux_reset();
	} else {
		WRITE_RESET_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB);

		WRITE_DEMUX_REG(STB_TOP_CONFIG, 0);
		WRITE_DEMUX_REG(DEMUX_CONTROL, 0);
	}

	/* set PID filter */
	pr_info
		("tsdemux video_pid = 0x%x, audio_pid = 0x%x,",
		 vid, aid);
	pr_info
		("sub_pid = 0x%x, pcrid = 0x%x\n",
		 sid, pcrid);

	if (!enable_demux_driver()) {
		WRITE_DEMUX_REG(FM_WR_DATA,
				(((vid < 0x1fff)
					? (vid & 0x1fff) | (VIDEO_PACKET << 13)
					: 0xffff) << 16)
				| ((aid < 0x1fff)
					? (aid & 0x1fff) | (AUDIO_PACKET << 13)
					: 0xffff));
		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8000);
		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
			;

		WRITE_DEMUX_REG(FM_WR_DATA,
				(((sid < 0x1fff)
					? (sid & 0x1fff) | (SUB_PACKET << 13)
					: 0xffff) << 16)
				| 0xffff);
		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8001);
		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
			;

		WRITE_DEMUX_REG(MAX_FM_COMP_ADDR, 1);

		WRITE_DEMUX_REG(STB_INT_MASK, 0);
		WRITE_DEMUX_REG(STB_INT_STATUS, 0xffff);

		/* TS data path */
		WRITE_DEMUX_REG(FEC_INPUT_CONTROL, 0x7000);
		WRITE_DEMUX_REG(DEMUX_MEM_REQ_EN,
				(1 << VIDEO_PACKET) |
				(1 << AUDIO_PACKET) | (1 << SUB_PACKET));
		WRITE_DEMUX_REG(DEMUX_ENDIAN,
				(7 << OTHER_ENDIAN) |
				(7 << BYPASS_ENDIAN) | (0 << SECTION_ENDIAN));
		WRITE_DEMUX_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE);
		WRITE_DEMUX_REG(TS_FILE_CONFIG,
				(demux_skipbyte << 16) |
				(6 << DES_OUT_DLY) |
				(3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) |
				(1 << TS_HIU_ENABLE) | (4 << FEC_FILE_CLK_DIV));

		/* enable TS demux */
		WRITE_DEMUX_REG(DEMUX_CONTROL,
				(1 << STB_DEMUX_ENABLE) |
				(1 << KEEP_DUPLICATE_PACKAGE));
	}

	if (fetchbuf == 0) {
		pr_info("%s: no fetchbuf\n", __func__);
		return -ENOMEM;
	}

	/* hook stream buffer with PARSER */
	if (has_hevc_vdec() && is_hevc) {
		WRITE_PARSER_REG(PARSER_VIDEO_START_PTR, vdec->input.start);
		WRITE_PARSER_REG(PARSER_VIDEO_END_PTR, vdec->input.start +
			vdec->input.size - 8);

		if (vdec_single(vdec)) {
			CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL,
					ES_VID_MAN_RD_PTR);
			/* set vififo_vbuf_rp_sel=>hevc */
			WRITE_VREG(DOS_GEN_CTRL0, 3 << 1);
			/* set use_parser_vbuf_wp */
			SET_VREG_MASK(HEVC_STREAM_CONTROL,
					  (1 << 3) | (0 << 4));
			/* set stream_fetch_enable */
			SET_VREG_MASK(HEVC_STREAM_CONTROL, 1);
			/* set stream_buffer_hole with 256 bytes */
			SET_VREG_MASK(HEVC_STREAM_FIFO_CTL,
					  (1 << 29));
		} else {
			SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
					ES_VID_MAN_RD_PTR);
			WRITE_PARSER_REG(PARSER_VIDEO_WP, vdec->input.start);
			WRITE_PARSER_REG(PARSER_VIDEO_RP, vdec->input.start);
		}
	} else {
		WRITE_PARSER_REG(PARSER_VIDEO_START_PTR, vdec->input.start);
		WRITE_PARSER_REG(PARSER_VIDEO_END_PTR, vdec->input.start +
			vdec->input.size - 8);

		if (vdec_single(vdec)) {
			CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL,
					ES_VID_MAN_RD_PTR);

			WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
			CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL,
					MEM_BUFCTRL_INIT);
			/* set vififo_vbuf_rp_sel=>vdec */
			if (has_hevc_vdec())
				WRITE_VREG(DOS_GEN_CTRL0, 0);
		} else {
			SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
					ES_VID_MAN_RD_PTR);
			WRITE_PARSER_REG(PARSER_VIDEO_WP, vdec->input.start);
			WRITE_PARSER_REG(PARSER_VIDEO_RP, vdec->input.start);
		}
	}

	WRITE_PARSER_REG(PARSER_AUDIO_START_PTR,
				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
	WRITE_PARSER_REG(PARSER_AUDIO_END_PTR,
				   READ_AIU_REG(AIU_MEM_AIFIFO_END_PTR));
	CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);

	WRITE_PARSER_REG(PARSER_CONFIG,
				   (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) |
				   (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) |
				   (16 << PS_CFG_MAX_FETCH_CYCLE_BIT));

	WRITE_AIU_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
	CLEAR_AIU_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);

	if (!enable_demux_driver() || ((sid > 0) && (sid < 0x1fff))) {
		WRITE_PARSER_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
		WRITE_PARSER_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
		WRITE_PARSER_REG(PARSER_SUB_RP, parser_sub_rp);
	}
	SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
			(7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);

	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
	if (vid != 0xffff) {
		if (has_hevc_vdec())
			r = pts_start((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO);
		else
			/* #endif */
			r = pts_start(PTS_TYPE_VIDEO);
		if ((r < 0) && (r != -EBUSY)) {
			pr_info("Video pts start failed.(%d)\n", r);
			goto err1;
		}
	}

	if (aid != 0xffff) {
		r = pts_start(PTS_TYPE_AUDIO);
		if ((r < 0) && (r != -EBUSY)) {
			pr_info("Audio pts start failed.(%d)\n", r);
			goto err2;
		}
	}
	/*TODO irq */

	r = vdec_request_irq(PARSER_IRQ, parser_isr,
			"tsdemux-fetch", (void *)tsdemux_fetch_id);

	if (r)
		goto err3;

	WRITE_PARSER_REG(PARSER_INT_STATUS, 0xffff);
	WRITE_PARSER_REG(PARSER_INT_ENABLE,
			PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT);

	WRITE_PARSER_REG(PARSER_VIDEO_HOLE, 0x400);
	WRITE_PARSER_REG(PARSER_AUDIO_HOLE, 0x400);

	discontinued_counter = 0;

	if (!enable_demux_driver()) {
		/*TODO irq */

		r = vdec_request_irq(DEMUX_IRQ, tsdemux_isr,
				"tsdemux-irq", (void *)tsdemux_irq_id);

		WRITE_DEMUX_REG(STB_INT_MASK, (1 << SUB_PES_READY)
					   | (1 << NEW_PDTS_READY)
					   | (1 << DIS_CONTINUITY_PACKET));
		if (r)
			goto err4;
	} else {
		tsdemux_config();
		tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id);
		if (vid < 0x1FFF) {
			curr_vid_id = vid;
			tsdemux_set_vid(vid);
			pcrvideo_valid = 1;
		}
		if (aid < 0x1FFF) {
			curr_aud_id = aid;
			tsdemux_set_aid(aid);
			pcraudio_valid = 1;
		}
		if (sid < 0x1FFF) {
			curr_sub_id = sid;
			tsdemux_set_sid(sid);
		}

		curr_pcr_id = pcrid;
		pcrscr_valid = reset_pcr_regs();

		if ((pcrid < 0x1FFF) && (pcrid != vid) && (pcrid != aid)
			&& (pcrid != sid))
			tsdemux_set_pcrid(pcrid);
	}

	first_pcr = 0;

	return 0;

err4:
	/*TODO irq */

	if (!enable_demux_driver())
		vdec_free_irq(PARSER_IRQ, (void *)tsdemux_fetch_id);

err3:
	pts_stop(PTS_TYPE_AUDIO);
err2:
	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
	if (has_hevc_vdec())
		pts_stop((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO);
	else
		/* #endif */
		pts_stop(PTS_TYPE_VIDEO);
err1:
	pr_info("TS Demux init failed.\n");
	return -ENOENT;
}

void tsdemux_release(void)
{
	pcrscr_valid = 0;
	first_pcr = 0;
	pcr_init_flag = 0;

	WRITE_PARSER_REG(PARSER_INT_ENABLE, 0);
	WRITE_PARSER_REG(PARSER_VIDEO_HOLE, 0);
	WRITE_PARSER_REG(PARSER_AUDIO_HOLE, 0);

	/*TODO irq */

	vdec_free_irq(PARSER_IRQ, (void *)tsdemux_fetch_id);

	if (!enable_demux_driver()) {
		WRITE_DEMUX_REG(STB_INT_MASK, 0);
		/*TODO irq */

		vdec_free_irq(DEMUX_IRQ, (void *)tsdemux_irq_id);
	} else {

		tsdemux_set_aid(0xffff);
		tsdemux_set_vid(0xffff);
		tsdemux_set_sid(0xffff);
		tsdemux_set_pcrid(0xffff);
		tsdemux_free_irq();

		curr_vid_id = 0xffff;
		curr_aud_id = 0xffff;
		curr_sub_id = 0xffff;
		curr_pcr_id = 0xffff;
		curr_pcr_num = 0xffff;
	}

	pts_stop(PTS_TYPE_VIDEO);
	pts_stop(PTS_TYPE_AUDIO);

	WRITE_RESET_REG(RESET1_REGISTER, RESET_PARSER);
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
	SET_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);
	WRITE_PARSER_REG(PARSER_VIDEO_WP, 0);
	WRITE_PARSER_REG(PARSER_VIDEO_RP, 0);
#endif

	if (enable_demux_driver())
		tsdemux_reset();

	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
	/*TODO clk */
	/*
	 *switch_mod_gate_by_type(MOD_DEMUX, 0);
	 */
	/* #endif */
	amports_switch_gate("demux", 0);

}
EXPORT_SYMBOL(tsdemux_release);

static int limited_delay_check(struct file *file,
		struct stream_buf_s *vbuf,
		struct stream_buf_s *abuf,
		const char __user *buf, size_t count)
{
	struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
	struct stream_port_s *port = priv->port;
	int write_size;

	if (!((port->flag & PORT_FLAG_VID) &&
		(port->flag & PORT_FLAG_AID))) {
		struct stream_buf_s *buf =
			(port->flag & PORT_FLAG_VID) ? vbuf : abuf;

		return min_t(int, count, stbuf_space(buf));
	}

	if (vbuf->max_buffer_delay_ms > 0 && abuf->max_buffer_delay_ms > 0 &&
		stbuf_level(vbuf) > 1024 && stbuf_level(abuf) > 256) {
		int vdelay =
			calculation_stream_delayed_ms(PTS_TYPE_VIDEO,
					NULL, NULL);
		int adelay =
			calculation_stream_delayed_ms(PTS_TYPE_AUDIO,
					NULL, NULL);
		/*max wait 100ms,if timeout,try again top level. */
		int maxretry = 10;
		/*too big  delay,do wait now. */
		/*if noblock mode,don't do wait. */
		if (!(file->f_flags & O_NONBLOCK)) {
			while (vdelay > vbuf->max_buffer_delay_ms
				   && adelay > abuf->max_buffer_delay_ms
				   && maxretry-- > 0) {
				msleep(20);
				vdelay =
					calculation_stream_delayed_ms
					(PTS_TYPE_VIDEO, NULL, NULL);
				adelay =
					calculation_stream_delayed_ms
					(PTS_TYPE_AUDIO, NULL, NULL);
			}
		}
		if (vdelay > vbuf->max_buffer_delay_ms
			&& adelay > abuf->max_buffer_delay_ms)
			return 0;
	}
	write_size = min(stbuf_space(vbuf), stbuf_space(abuf));
	write_size = min_t(int, count, write_size);
	return write_size;
}

ssize_t drm_tswrite(struct file *file,
					struct stream_buf_s *vbuf,
					struct stream_buf_s *abuf,
					const char __user *buf, size_t count)
{
	s32 r;
	u32 realcount = count;
	u32 havewritebytes = 0;

	struct drm_info tmpmm;
	struct drm_info *drm = &tmpmm;
	u32 res = 0;
	int isphybuf = 0;
	unsigned long realbuf;

	struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
	struct stream_port_s *port = priv->port;
	size_t wait_size, write_size;

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

	res = copy_from_user(drm, buf, sizeof(struct drm_info));
	if (res) {
		pr_info("drm kmalloc failed res[%d]\n", res);
		return -EFAULT;
	}

	if (drm->drm_flag == TYPE_DRMINFO && drm->drm_level == DRM_LEVEL1) {
		/* buf only has drminfo not have esdata; */
		if (drm->drm_pktsize <= MAX_DRM_PACKAGE_SIZE)
			realcount = drm->drm_pktsize;
		else {
			pr_err("drm package size is error, size is %u\n", drm->drm_pktsize);
			return -EINVAL;
		}
		realbuf = drm->drm_phy;
		isphybuf = 1;
	} else
	    realbuf = (unsigned long)buf;
	/* pr_info("drm->drm_flag = 0x%x,realcount = %d , buf = 0x%x ",*/
	   /*drm->drm_flag,realcount, buf); */

	count = realcount;

	while (count > 0) {
		if ((stbuf_space(vbuf) < count) ||
				(stbuf_space(abuf) < count)) {
			if (file->f_flags & O_NONBLOCK) {
				int v_stbuf_space = stbuf_space(vbuf);
				int a_stbuf_space = stbuf_space(abuf);

				write_size = min(v_stbuf_space, a_stbuf_space);
				/*have 188 bytes,write now., */
				if (write_size <= 188)
					return -EAGAIN;
			} else {
				wait_size =
					min(stbuf_canusesize(vbuf) / 8,
						stbuf_canusesize(abuf) / 4);
				if ((port->flag & PORT_FLAG_VID)
					&& (stbuf_space(vbuf) < wait_size)) {
					r = stbuf_wait_space(vbuf, wait_size);

					if (r < 0) {
						if (r != -EAGAIN)
							pr_info
							("write no space--- ");
						if (r != -EAGAIN)
							pr_info
							("no space,%d--%d,r-%d\n",
							stbuf_space(vbuf),
							stbuf_space(abuf), r);
						return r;
					}
				}

				if ((port->flag & PORT_FLAG_AID)
					&& (stbuf_space(abuf) < wait_size)) {
					r = stbuf_wait_space(abuf, wait_size);

					if (r < 0) {
						pr_info
						("write no stbuf_wait_space--");
						pr_info
						("no space,%d--%d,r-%d\n",
						 stbuf_space(vbuf),
						 stbuf_space(abuf), r);
						return r;
					}
				}
			}
		}

		if ((port->flag & PORT_FLAG_VID) &&
			(port->flag & PORT_FLAG_AID)) {
			write_size = min(stbuf_space(vbuf), stbuf_space(abuf));
			write_size = min(count, write_size);
		} else {
			struct stream_buf_s *buf =
				(port->flag & PORT_FLAG_VID) ? vbuf : abuf;

			write_size = min_t(int, count, stbuf_space(buf));
		}
		/* pr_info("write_size = %d,count = %d,\n",*/
		   /*write_size, count); */
		if (write_size > 0) {
			r = _tsdemux_write((const char __user *)realbuf + havewritebytes,
				write_size, isphybuf);
			if (r < 0) {
				if (r != -EAGAIN)
					pr_info
					("vspace %d--aspace %d,r-%d\n",
					stbuf_space(vbuf),
					stbuf_space(abuf), r);
				return r;
			}
		}
		else
			return -EAGAIN;

		havewritebytes += r;

		/* pr_info("havewritebytes = %d, r = %d,\n",*/
		   /*havewritebytes,  r); */
		if (havewritebytes == realcount)
			break;	/* write ok; */
		else if (havewritebytes > realcount)
			pr_info(" error ! write too much havewritebytes = %u, r = %u\n",
			(u32)havewritebytes,(u32)realcount);

		count -= r;
	}
	return havewritebytes;
}

ssize_t tsdemux_write(struct file *file,
					  struct stream_buf_s *vbuf,
					  struct stream_buf_s *abuf,
					  const char __user *buf, size_t count)
{
	s32 r;
	struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
	struct stream_port_s *port = priv->port;
	size_t wait_size, write_size;

	if ((stbuf_space(vbuf) < count) || (stbuf_space(abuf) < count)) {
		if (file->f_flags & O_NONBLOCK) {
			write_size = min(stbuf_space(vbuf), stbuf_space(abuf));
			if (write_size <= 188)	/*have 188 bytes,write now., */
				return -EAGAIN;
		} else {
			wait_size =
				min(stbuf_canusesize(vbuf) / 8,
					stbuf_canusesize(abuf) / 4);
			if ((port->flag & PORT_FLAG_VID)
				&& (stbuf_space(vbuf) < wait_size)) {
				r = stbuf_wait_space(vbuf, wait_size);

				if (r < 0) {
					/* pr_info("write no space--- ");
					 *   pr_info("no space,%d--%d,r-%d\n",
					 *   stbuf_space(vbuf),
					 *   stbuf_space(abuf),r);
					 */
					return r;
				}
			}

			if ((port->flag & PORT_FLAG_AID)
				&& (stbuf_space(abuf) < wait_size)) {
				r = stbuf_wait_space(abuf, wait_size);

				if (r < 0) {
					/* pr_info("write no stbuf_wait_space")'
					 * pr_info{"---no space,%d--%d,r-%d\n",
					 * stbuf_space(vbuf),
					 * stbuf_space(abuf),r);
					 */
					return r;
				}
			}
		}
	}
	vbuf->last_write_jiffies64 = jiffies_64;
	abuf->last_write_jiffies64 = jiffies_64;
	write_size = limited_delay_check(file, vbuf, abuf, buf, count);
	if (write_size > 0)
		return _tsdemux_write(buf, write_size, 0);
	else
		return -EAGAIN;
}

int get_discontinue_counter(void)
{
	return discontinued_counter;
}
EXPORT_SYMBOL(get_discontinue_counter);

static ssize_t discontinue_counter_show(struct class *class,
		struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", discontinued_counter);
}

static CLASS_ATTR_RO(discontinue_counter);

static struct attribute *tsdemux_class_attrs[] = {
	&class_attr_discontinue_counter.attr,
	NULL
};

ATTRIBUTE_GROUPS(tsdemux_class);

static struct class tsdemux_class = {
	.name = "tsdemux",
	.class_groups = tsdemux_class_groups,
};

int tsdemux_class_register(void)
{
	int r = class_register(&tsdemux_class);

	if (r < 0)
		pr_info("register tsdemux class error!\n");
	discontinued_counter = 0;
	return r;
}

void tsdemux_class_unregister(void)
{
	class_unregister(&tsdemux_class);
}

void tsdemux_change_avid(unsigned int vid, unsigned int aid)
{
	if (!enable_demux_driver()) {
		WRITE_DEMUX_REG(FM_WR_DATA,
				(((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16)
				| ((aid & 0x1fff) | (AUDIO_PACKET << 13)));
		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8000);
		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
			;
	} else {
		if (curr_vid_id != vid) {
			tsdemux_set_vid(vid);
			curr_vid_id = vid;
		}
		if (curr_aud_id != aid) {
			tsdemux_set_aid(aid);
			curr_aud_id = aid;
		}
		reset_pcr_regs();
	}
}

void tsdemux_change_sid(unsigned int sid)
{
	if (!enable_demux_driver()) {
		WRITE_DEMUX_REG(FM_WR_DATA,
				(((sid & 0x1fff) | (SUB_PACKET << 13)) << 16)
				| 0xffff);
		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8001);
		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
			;
	} else {
		curr_sub_id = sid;

		tsdemux_set_sid(sid);

		reset_pcr_regs();
	}

}

void tsdemux_audio_reset(void)
{
	ulong flags;
	unsigned long xflags = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->hw_dmx_lock)
		xflags = demux_ops->hw_dmx_lock(xflags);

	WRITE_PARSER_REG(PARSER_AUDIO_WP,
				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
	WRITE_PARSER_REG(PARSER_AUDIO_RP,
				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));

	WRITE_PARSER_REG(PARSER_AUDIO_START_PTR,
				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
	WRITE_PARSER_REG(PARSER_AUDIO_END_PTR,
				   READ_AIU_REG(AIU_MEM_AIFIFO_END_PTR));
	CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);

	WRITE_AIU_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
	CLEAR_AIU_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);

	if (demux_ops && demux_ops->hw_dmx_unlock)
		demux_ops->hw_dmx_unlock(xflags);
	spin_unlock_irqrestore(&demux_ops_lock, flags);
	if (reset_demux_enable == 1)
		tsdemux_reset();
}

void tsdemux_sub_reset(void)
{
	ulong flags;
	u32 parser_sub_start_ptr;
	u32 parser_sub_end_ptr;
	unsigned long xflags = 0;

	spin_lock_irqsave(&demux_ops_lock, flags);
	if (demux_ops && demux_ops->hw_dmx_lock)
		xflags = demux_ops->hw_dmx_lock(xflags);

	parser_sub_start_ptr = READ_PARSER_REG(PARSER_SUB_START_PTR);
	parser_sub_end_ptr = READ_PARSER_REG(PARSER_SUB_END_PTR);

	WRITE_PARSER_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
	WRITE_PARSER_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
	WRITE_PARSER_REG(PARSER_SUB_RP, parser_sub_start_ptr);
	WRITE_PARSER_REG(PARSER_SUB_WP, parser_sub_start_ptr);
	SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
			(7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);

	if (demux_ops && demux_ops->hw_dmx_unlock)
		demux_ops->hw_dmx_unlock(xflags);
	spin_unlock_irqrestore(&demux_ops_lock, flags);
}

void tsdemux_set_skipbyte(int skipbyte)
{
	if (!enable_demux_driver())
		demux_skipbyte = skipbyte;
	else
		tsdemux_set_skip_byte(skipbyte);

}

void tsdemux_set_demux(int dev)
{
	if (enable_demux_driver()) {
		unsigned long flags;
		int r = 0;

		spin_lock_irqsave(&demux_ops_lock, flags);
		if (demux_ops && demux_ops->set_demux)
			r = demux_ops->set_demux(dev);
		spin_unlock_irqrestore(&demux_ops_lock, flags);
	}
}

u32 tsdemux_pcrscr_get(void)
{
	u32 pcr = 0;

	if (pcrscr_valid == 0)
		return 0;

	if (READ_DEMUX_REG(TS_HIU_CTL_2) & 0x80)
		pcr = READ_DEMUX_REG(PCR_DEMUX_2);
	else if (READ_DEMUX_REG(TS_HIU_CTL_3) & 0x80)
		pcr = READ_DEMUX_REG(PCR_DEMUX_3);
	else
		pcr = READ_DEMUX_REG(PCR_DEMUX);
	if (first_pcr == 0)
		first_pcr = pcr;
	return pcr;
}

u32 tsdemux_first_pcrscr_get(void)
{
	if (pcrscr_valid == 0)
		return 0;

	if (first_pcr == 0) {
		u32 pcr;
		if (READ_DEMUX_REG(TS_HIU_CTL_2) & 0x80)
			pcr = READ_DEMUX_REG(PCR_DEMUX_2);
		else if (READ_DEMUX_REG(TS_HIU_CTL_3) & 0x80)
			pcr = READ_DEMUX_REG(PCR_DEMUX_3);
		else
			pcr = READ_DEMUX_REG(PCR_DEMUX);
		first_pcr = pcr;
		/* pr_info("set first_pcr = 0x%x\n", pcr); */
	}

	return first_pcr;
}

u8 tsdemux_pcrscr_valid(void)
{
	return pcrscr_valid;
}

u8 tsdemux_pcraudio_valid(void)
{
	return pcraudio_valid;
}

u8 tsdemux_pcrvideo_valid(void)
{
	return pcrvideo_valid;
}

void tsdemux_pcr_set(unsigned int pcr)
{
	if (pcr_init_flag == 0) {
		/*timestamp_pcrscr_set(pcr);
		timestamp_pcrscr_enable(1);*/
		pcr_init_flag = 1;
	}
}

void tsdemux_tsync_func_init(void)
{
	register_tsync_callbackfunc(
		TSYNC_PCRSCR_VALID, (void *)(tsdemux_pcrscr_valid));
	register_tsync_callbackfunc(
		TSYNC_PCRSCR_GET, (void *)(tsdemux_pcrscr_get));
	register_tsync_callbackfunc(
		TSYNC_FIRST_PCRSCR_GET, (void *)(tsdemux_first_pcrscr_get));
	register_tsync_callbackfunc(
		TSYNC_PCRAUDIO_VALID, (void *)(tsdemux_pcraudio_valid));
	register_tsync_callbackfunc(
		TSYNC_PCRVIDEO_VALID, (void *)(tsdemux_pcrvideo_valid));
	register_tsync_callbackfunc(
		TSYNC_BUF_BY_BYTE, (void *)(get_buf_by_type));
	register_tsync_callbackfunc(
		TSYNC_STBUF_LEVEL, (void *)(stbuf_level));
	register_tsync_callbackfunc(
		TSYNC_STBUF_SPACE, (void *)(stbuf_space));
	register_tsync_callbackfunc(
		TSYNC_STBUF_SIZE, (void *)(stbuf_size));
}

static int tsparser_stbuf_init(struct stream_buf_s *stbuf,
			       struct vdec_s *vdec)
{
	int ret = -1;

	ret = stbuf_init(stbuf, vdec);
	if (ret)
		goto out;

	ret = tsdemux_init(stbuf->pars.vid,
			   stbuf->pars.aid,
			   stbuf->pars.sid,
			   stbuf->pars.pcrid,
			   stbuf->is_hevc,
			   vdec);
	if (ret)
		goto out;

	tsync_pcr_start();

	stbuf->flag |= BUF_FLAG_IN_USE;
out:
	return ret;
}

static void tsparser_stbuf_release(struct stream_buf_s *stbuf)
{
	tsync_pcr_stop();

	tsdemux_release();

	stbuf_release(stbuf);
}

static struct stream_buf_ops tsparser_stbuf_ops = {
	.init	= tsparser_stbuf_init,
	.release = tsparser_stbuf_release,
	.get_wp	= parser_get_wp,
	.set_wp	= parser_set_wp,
	.get_rp	= parser_get_rp,
	.set_rp	= parser_set_rp,
};

struct stream_buf_ops *get_tsparser_stbuf_ops(void)
{
	return &tsparser_stbuf_ops;
}
EXPORT_SYMBOL(get_tsparser_stbuf_ops);


