From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198

---
 kernel/drivers/media/platform/rockchip/ispp/stream.c | 1898 +++-------------------------------------------------------
 1 files changed, 127 insertions(+), 1,771 deletions(-)

diff --git a/kernel/drivers/media/platform/rockchip/ispp/stream.c b/kernel/drivers/media/platform/rockchip/ispp/stream.c
index c5f1107..ab029f0 100644
--- a/kernel/drivers/media/platform/rockchip/ispp/stream.c
+++ b/kernel/drivers/media/platform/rockchip/ispp/stream.c
@@ -13,7 +13,8 @@
 #include <media/v4l2-subdev.h>
 #include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-dma-sg.h>
-#include <linux/rkisp1-config.h>
+#include <linux/rk-isp1-config.h>
+#include <uapi/linux/rk-video-format.h>
 
 #include "dev.h"
 #include "regs.h"
@@ -23,13 +24,6 @@
 
 /* memory align for mpp */
 #define RK_MPP_ALIGN 4096
-
-/*
- * DDR->|                                 |->MB------->DDR
- *      |->TNR->DDR->NR->SHARP->DDR->FEC->|->SCL0----->DDR
- * ISP->|                                 |->SCL1----->DDR
- *                                        |->SCL2----->DDR
- */
 
 static const struct capture_fmt input_fmts[] = {
 	{
@@ -188,16 +182,6 @@
 	},
 };
 
-static void set_y_addr(struct rkispp_stream *stream, u32 val)
-{
-	rkispp_write(stream->isppdev, stream->config->reg.cur_y_base, val);
-}
-
-static void set_uv_addr(struct rkispp_stream *stream, u32 val)
-{
-	rkispp_write(stream->isppdev, stream->config->reg.cur_uv_base, val);
-}
-
 static void set_vir_stride(struct rkispp_stream *stream, u32 val)
 {
 	rkispp_write(stream->isppdev, stream->config->reg.cur_vir_stride, val);
@@ -329,81 +313,16 @@
 		 "%s exit\n", __func__);
 }
 
-static void check_to_force_update(struct rkispp_device *dev, u32 mis_val)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_stream *stream;
-	u32 i, mask = NR_INT | SHP_INT;
-	bool is_fec_en = (vdev->module_ens & ISPP_MODULE_FEC);
-
-	if (mis_val & TNR_INT)
-		rkispp_module_work_event(dev, NULL, NULL,
-					 ISPP_MODULE_TNR, true);
-	if (mis_val & FEC_INT)
-		rkispp_module_work_event(dev, NULL, NULL,
-					 ISPP_MODULE_FEC, true);
-
-	/* wait nr_shp/fec/scl idle */
-	for (i = STREAM_S0; i <= STREAM_S2; i++) {
-		stream = &vdev->stream[i];
-		if (stream->is_upd && !is_fec_en &&
-		    rkispp_read(dev, stream->config->reg.ctrl) & SW_SCL_ENABLE)
-			mask |= stream->config->frame_end_id;
-	}
-
-	vdev->irq_ends |= (mis_val & mask);
-	v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev,
-		 "irq_ends:0x%x mask:0x%x\n",
-		 vdev->irq_ends, mask);
-	if (vdev->irq_ends != mask)
-		return;
-	vdev->irq_ends = 0;
-	rkispp_module_work_event(dev, NULL, NULL,
-				 ISPP_MODULE_NR, true);
-
-	for (i = STREAM_MB; i <= STREAM_S2; i++) {
-		stream = &vdev->stream[i];
-		if (stream->streaming)
-			stream->is_upd = true;
-	}
-}
-
 static void irq_work(struct work_struct *work)
 {
 	struct rkispp_device *dev = container_of(work, struct rkispp_device, irq_work);
 
 	rkispp_set_clk_rate(dev->hw_dev->clks[0], dev->hw_dev->core_clk_max);
-	check_to_force_update(dev, dev->mis_val);
+	dev->stream_vdev.stream_ops->check_to_force_update(dev, dev->mis_val);
 	dev->hw_dev->is_first = false;
 }
 
-static void update_mi(struct rkispp_stream *stream)
-{
-	struct rkispp_device *dev = stream->isppdev;
-	struct rkispp_dummy_buffer *dummy_buf;
-	u32 val;
-
-	if (stream->curr_buf) {
-		val = stream->curr_buf->buff_addr[RKISPP_PLANE_Y];
-		set_y_addr(stream, val);
-		val = stream->curr_buf->buff_addr[RKISPP_PLANE_UV];
-		set_uv_addr(stream, val);
-	}
-
-	if (stream->type == STREAM_OUTPUT && !stream->curr_buf) {
-		dummy_buf = &dev->hw_dev->dummy_buf;
-		set_y_addr(stream, dummy_buf->dma_addr);
-		set_uv_addr(stream, dummy_buf->dma_addr);
-	}
-
-	v4l2_dbg(2, rkispp_debug, &stream->isppdev->v4l2_dev,
-		 "%s stream:%d Y:0x%x UV:0x%x\n",
-		 __func__, stream->id,
-		 rkispp_read(dev, stream->config->reg.cur_y_base),
-		 rkispp_read(dev, stream->config->reg.cur_uv_base));
-}
-
-static void get_stream_buf(struct rkispp_stream *stream)
+void get_stream_buf(struct rkispp_stream *stream)
 {
 	unsigned long lock_flags = 0;
 
@@ -417,9 +336,10 @@
 	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
 }
 
-static int rkispp_frame_end(struct rkispp_stream *stream, u32 state)
+int rkispp_frame_end(struct rkispp_stream *stream, u32 state)
 {
 	struct rkispp_device *dev = stream->isppdev;
+	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
 	struct capture_fmt *fmt = &stream->out_cap_fmt;
 	struct rkisp_ispp_reg *reg_buf = NULL;
 	unsigned long lock_flags = 0;
@@ -513,90 +433,11 @@
 	}
 
 	get_stream_buf(stream);
-	update_mi(stream);
+	vdev->stream_ops->update_mi(stream);
 	return 0;
 }
 
-static bool is_en_done_early(struct rkispp_device *dev)
-{
-	u32 height = dev->ispp_sdev.out_fmt.height;
-	u32 line = dev->stream_vdev.wait_line;
-	bool en =  false;
-
-	if (line) {
-		if (line > height - 128)
-			dev->stream_vdev.wait_line = height - 128;
-		en = true;
-		v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-			 "wait %d line to wake up frame\n", line);
-	}
-
-	return en;
-}
-
-static enum hrtimer_restart rkispp_frame_done_early(struct hrtimer *timer)
-{
-	struct rkispp_stream_vdev *vdev =
-		container_of(timer, struct rkispp_stream_vdev, frame_qst);
-	struct rkispp_stream *stream = &vdev->stream[0];
-	struct rkispp_device *dev = stream->isppdev;
-	void __iomem *base = dev->hw_dev->base_addr;
-	bool is_fec_en = (vdev->module_ens & ISPP_MODULE_FEC);
-	enum hrtimer_restart ret = HRTIMER_NORESTART;
-	u32 threshold = vdev->wait_line / 128;
-	u32 tile, tile_mask, working, work_mask;
-	u32 i, seq, ycnt, shift, time, max_time;
-	u64 t, ns = ktime_get_ns();
-
-	working = readl(base + RKISPP_CTRL_SYS_STATUS);
-	tile = readl(base + RKISPP_CTRL_SYS_CTL_STA0);
-	if (is_fec_en) {
-		shift = 16;
-		work_mask = FEC_WORKING;
-		tile_mask = FEC_TILE_LINE_CNT_MASK;
-		t = vdev->fec.dbg.timestamp;
-		seq = vdev->fec.dbg.id;
-		max_time = 6000000;
-	} else {
-		shift = 8;
-		work_mask = NR_WORKING;
-		tile_mask = NR_TILE_LINE_CNT_MASK;
-		t = vdev->nr.dbg.timestamp;
-		seq = vdev->nr.dbg.id;
-		max_time = 2000000;
-	}
-	working &= work_mask;
-	tile &= tile_mask;
-	ycnt = tile >> shift;
-	time = (u32)(ns - t);
-	if (dev->ispp_sdev.state == ISPP_STOP) {
-		vdev->is_done_early = false;
-		goto end;
-	} else if (working && ycnt < threshold) {
-		if (!ycnt)
-			ns = max_time;
-		else
-			ns = time * (threshold - ycnt) / ycnt + 100 * 1000;
-		if (ns > max_time)
-			ns = max_time;
-		hrtimer_forward(timer, timer->base->get_time(), ns_to_ktime(ns));
-		ret = HRTIMER_RESTART;
-	} else {
-		v4l2_dbg(3, rkispp_debug, &stream->isppdev->v4l2_dev,
-			 "%s seq:%d line:%d ycnt:%d time:%dus\n",
-			 __func__, seq, vdev->wait_line, ycnt * 128, time / 1000);
-		for (i = 0; i < STREAM_MAX; i++) {
-			stream = &vdev->stream[i];
-			if (!stream->streaming || !stream->is_cfg || stream->stopping)
-				continue;
-			rkispp_frame_end(stream, FRAME_WORK);
-		}
-	}
-end:
-	return ret;
-}
-
-static void *get_pool_buf(struct rkispp_device *dev,
+void *get_pool_buf(struct rkispp_device *dev,
 			  struct rkisp_ispp_buf *dbufs)
 {
 	int i;
@@ -608,7 +449,7 @@
 	return NULL;
 }
 
-static void *dbuf_to_dummy(struct dma_buf *dbuf,
+void *dbuf_to_dummy(struct dma_buf *dbuf,
 			   struct rkispp_dummy_buffer *pool,
 			   int num)
 {
@@ -623,7 +464,7 @@
 	return NULL;
 }
 
-static void *get_list_buf(struct list_head *list, bool is_isp_ispp)
+void *get_list_buf(struct list_head *list, bool is_isp_ispp)
 {
 	void *buf = NULL;
 
@@ -641,540 +482,22 @@
 	return buf;
 }
 
-static void tnr_free_buf(struct rkispp_device *dev)
+void rkispp_start_3a_run(struct rkispp_device *dev)
 {
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkisp_ispp_buf *dbufs;
-	struct list_head *list;
-	int i;
-
-	list = &vdev->tnr.list_rd;
-	if (vdev->tnr.cur_rd) {
-		list_add_tail(&vdev->tnr.cur_rd->list, list);
-		if (vdev->tnr.nxt_rd == vdev->tnr.cur_rd)
-			vdev->tnr.nxt_rd = NULL;
-		vdev->tnr.cur_rd = NULL;
-	}
-	if (vdev->tnr.nxt_rd) {
-		list_add_tail(&vdev->tnr.nxt_rd->list, list);
-		vdev->tnr.nxt_rd = NULL;
-	}
-	while (!list_empty(list)) {
-		dbufs = get_list_buf(list, true);
-		v4l2_subdev_call(dev->ispp_sdev.remote_sd,
-				 video, s_rx_buffer, dbufs, NULL);
-	}
-
-	list = &vdev->tnr.list_wr;
-	if (vdev->tnr.cur_wr) {
-		list_add_tail(&vdev->tnr.cur_wr->list, list);
-		vdev->tnr.cur_wr = NULL;
-	}
-	while (!list_empty(list)) {
-		dbufs = get_list_buf(list, true);
-		kfree(dbufs);
-	}
-	list = &vdev->tnr.list_rpt;
-	while (!list_empty(list)) {
-		dbufs = get_list_buf(list, true);
-		kfree(dbufs);
-	}
-
-	for (i = 0; i < sizeof(vdev->tnr.buf) /
-	     sizeof(struct rkispp_dummy_buffer); i++)
-		rkispp_free_buffer(dev, &vdev->tnr.buf.iir + i);
-
-	vdev->tnr.is_buf_init = false;
-	vdev->tnr.is_trigger = false;
-}
-
-static int tnr_init_buf(struct rkispp_device *dev,
-			u32 pic_size, u32 gain_size)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkisp_ispp_buf *dbufs;
-	struct rkispp_dummy_buffer *buf;
-	int i, j, ret, cnt = RKISPP_BUF_MAX;
-	u32 buf_idx = 0;
-
-	if (dev->inp == INP_ISP && dev->isp_mode & ISP_ISPP_QUICK)
-		cnt = 1;
-	for (i = 0; i < cnt; i++) {
-		dbufs = kzalloc(sizeof(*dbufs), GFP_KERNEL);
-		if (!dbufs) {
-			ret = -ENOMEM;
-			goto err;
-		}
-		dbufs->is_isp = false;
-		for (j = 0; j < GROUP_BUF_MAX; j++) {
-			buf = &vdev->tnr.buf.wr[i][j];
-			buf->is_need_dbuf = true;
-			buf->is_need_dmafd = false;
-			buf->is_need_vaddr = true;
-			buf->size = !j ? pic_size : PAGE_ALIGN(gain_size);
-			buf->index = buf_idx++;
-			ret = rkispp_allow_buffer(dev, buf);
-			if (ret) {
-				kfree(dbufs);
-				goto err;
-			}
-			dbufs->dbuf[j] = buf->dbuf;
-			dbufs->didx[j] = buf->index;
-		}
-		list_add_tail(&dbufs->list, &vdev->tnr.list_wr);
-	}
-
-	if (dev->inp == INP_ISP && dev->isp_mode & ISP_ISPP_QUICK) {
-		buf = &vdev->tnr.buf.iir;
-		buf->size = pic_size;
-		ret = rkispp_allow_buffer(dev, buf);
-		if (ret < 0)
-			goto err;
-	}
-
-	buf = &vdev->tnr.buf.gain_kg;
-	buf->is_need_vaddr = true;
-	buf->is_need_dbuf = true;
-	buf->is_need_dmafd = false;
-	buf->size = PAGE_ALIGN(gain_size * 4);
-	buf->index = buf_idx++;
-	ret = rkispp_allow_buffer(dev, buf);
-	if (ret < 0)
-		goto err;
-
-	vdev->tnr.is_buf_init = true;
-	return 0;
-err:
-	tnr_free_buf(dev);
-	v4l2_err(&dev->v4l2_dev, "%s failed\n", __func__);
-	return ret;
-}
-
-static int config_tnr(struct rkispp_device *dev)
-{
-	struct rkispp_hw_dev *hw = dev->hw_dev;
-	struct rkispp_stream_vdev *vdev;
-	struct rkispp_stream *stream = NULL;
-	int ret, mult = 1;
-	u32 width, height, fmt;
-	u32 pic_size, gain_size;
-	u32 addr_offs, w, h, val;
-	u32 max_w, max_h;
-
-	vdev = &dev->stream_vdev;
-	vdev->tnr.is_end = true;
-	vdev->tnr.is_3to1 =
-		((vdev->module_ens & ISPP_MODULE_TNR_3TO1) ==
-		 ISPP_MODULE_TNR_3TO1);
-	if (!(vdev->module_ens & ISPP_MODULE_TNR))
-		return 0;
-
-	if (dev->inp == INP_DDR) {
-		vdev->tnr.is_3to1 = false;
-		stream = &vdev->stream[STREAM_II];
-		fmt = stream->out_cap_fmt.wr_fmt;
-	} else {
-		fmt = dev->isp_mode & (FMT_YUV422 | FMT_FBC);
-	}
-
-	width = dev->ispp_sdev.in_fmt.width;
-	height = dev->ispp_sdev.in_fmt.height;
-	max_w = hw->max_in.w ? hw->max_in.w : width;
-	max_h = hw->max_in.h ? hw->max_in.h : height;
-	w = (fmt & FMT_FBC) ? ALIGN(max_w, 16) : max_w;
-	h = (fmt & FMT_FBC) ? ALIGN(max_h, 16) : max_h;
-	addr_offs = (fmt & FMT_FBC) ? w * h >> 4 : w * h;
-	pic_size = (fmt & FMT_YUV422) ? w * h * 2 : w * h * 3 >> 1;
-	vdev->tnr.uv_offset = addr_offs;
-	if (fmt & FMT_FBC)
-		pic_size += w * h >> 4;
-
-	gain_size = ALIGN(width, 64) * ALIGN(height, 128) >> 4;
-	if (fmt & FMT_YUYV)
-		mult = 2;
-
-	if (vdev->module_ens & (ISPP_MODULE_NR | ISPP_MODULE_SHP)) {
-		ret = tnr_init_buf(dev, pic_size, gain_size);
-		if (ret)
-			return ret;
-		if (dev->inp == INP_ISP &&
-		    dev->isp_mode & ISP_ISPP_QUICK) {
-			rkispp_set_bits(dev, RKISPP_CTRL_QUICK,
-					GLB_QUICK_MODE_MASK,
-					GLB_QUICK_MODE(0));
-
-			val = hw->pool[0].dma[GROUP_BUF_PIC];
-			rkispp_write(dev, RKISPP_TNR_CUR_Y_BASE, val);
-			rkispp_write(dev, RKISPP_TNR_CUR_UV_BASE, val + addr_offs);
-
-			val = hw->pool[0].dma[GROUP_BUF_GAIN];
-			rkispp_write(dev, RKISPP_TNR_GAIN_CUR_Y_BASE, val);
-
-			if (vdev->tnr.is_3to1) {
-				val = hw->pool[1].dma[GROUP_BUF_PIC];
-				rkispp_write(dev, RKISPP_TNR_NXT_Y_BASE, val);
-				rkispp_write(dev, RKISPP_TNR_NXT_UV_BASE, val + addr_offs);
-				val = hw->pool[1].dma[GROUP_BUF_GAIN];
-				rkispp_write(dev, RKISPP_TNR_GAIN_NXT_Y_BASE, val);
-			}
-		}
-
-		val = vdev->tnr.buf.gain_kg.dma_addr;
-		rkispp_write(dev, RKISPP_TNR_GAIN_KG_Y_BASE, val);
-
-		val = vdev->tnr.buf.wr[0][GROUP_BUF_PIC].dma_addr;
-		rkispp_write(dev, RKISPP_TNR_WR_Y_BASE, val);
-		rkispp_write(dev, RKISPP_TNR_WR_UV_BASE, val + addr_offs);
-		if (vdev->tnr.buf.iir.mem_priv)
-			val = vdev->tnr.buf.iir.dma_addr;
-		rkispp_write(dev, RKISPP_TNR_IIR_Y_BASE, val);
-		rkispp_write(dev, RKISPP_TNR_IIR_UV_BASE, val + addr_offs);
-
-		val = vdev->tnr.buf.wr[0][GROUP_BUF_GAIN].dma_addr;
-		rkispp_write(dev, RKISPP_TNR_GAIN_WR_Y_BASE, val);
-
-		rkispp_write(dev, RKISPP_TNR_WR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-		rkispp_set_bits(dev, RKISPP_TNR_CTRL, FMT_WR_MASK, fmt << 4 | SW_TNR_1ST_FRM);
-	}
-
-	if (stream) {
-		stream->config->frame_end_id = TNR_INT;
-		stream->config->reg.cur_y_base = RKISPP_TNR_CUR_Y_BASE;
-		stream->config->reg.cur_uv_base = RKISPP_TNR_CUR_UV_BASE;
-		stream->config->reg.cur_y_base_shd = RKISPP_TNR_CUR_Y_BASE_SHD;
-		stream->config->reg.cur_uv_base_shd = RKISPP_TNR_CUR_UV_BASE_SHD;
-	}
-
-	rkispp_set_bits(dev, RKISPP_TNR_CTRL, FMT_RD_MASK, fmt);
-	if (fmt & FMT_FBC) {
-		rkispp_write(dev, RKISPP_TNR_CUR_VIR_STRIDE, 0);
-		rkispp_write(dev, RKISPP_TNR_IIR_VIR_STRIDE, 0);
-		rkispp_write(dev, RKISPP_TNR_NXT_VIR_STRIDE, 0);
-	} else {
-		rkispp_write(dev, RKISPP_TNR_CUR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-		rkispp_write(dev, RKISPP_TNR_IIR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-		rkispp_write(dev, RKISPP_TNR_NXT_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-	}
-	rkispp_set_bits(dev, RKISPP_TNR_CORE_CTRL, SW_TNR_MODE,
-			vdev->tnr.is_3to1 ? SW_TNR_MODE : 0);
-	rkispp_write(dev, RKISPP_TNR_GAIN_CUR_VIR_STRIDE, ALIGN(width, 64) >> 4);
-	rkispp_write(dev, RKISPP_TNR_GAIN_NXT_VIR_STRIDE, ALIGN(width, 64) >> 4);
-	rkispp_write(dev, RKISPP_TNR_GAIN_KG_VIR_STRIDE, ALIGN(width, 16) * 6);
-	rkispp_write(dev, RKISPP_TNR_GAIN_WR_VIR_STRIDE, ALIGN(width, 64) >> 4);
-	rkispp_write(dev, RKISPP_CTRL_TNR_SIZE, height << 16 | width);
-
-	if (vdev->monitor.is_en) {
-		init_completion(&vdev->monitor.tnr.cmpl);
-		schedule_work(&vdev->monitor.tnr.work);
-	}
-	v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-		 "%s size:%dx%d ctrl:0x%x core_ctrl:0x%x\n",
-		 __func__, width, height,
-		 rkispp_read(dev, RKISPP_TNR_CTRL),
-		 rkispp_read(dev, RKISPP_TNR_CORE_CTRL));
-	return 0;
-}
-
-static void nr_free_buf(struct rkispp_device *dev)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkisp_ispp_buf *dbufs;
-	struct list_head *list;
-	int i;
-
-	list = &vdev->nr.list_rd;
-	if (vdev->nr.cur_rd) {
-		list_add_tail(&vdev->nr.cur_rd->list, list);
-		vdev->nr.cur_rd = NULL;
-	}
-	while (!list_empty(list)) {
-		dbufs = get_list_buf(list, true);
-		if (dbufs->is_isp)
-			v4l2_subdev_call(dev->ispp_sdev.remote_sd,
-					 video, s_rx_buffer, dbufs, NULL);
-		else
-			kfree(dbufs);
-	}
-
-	list = &vdev->nr.list_wr;
-	if (vdev->nr.cur_wr)
-		vdev->nr.cur_wr = NULL;
-	while (!list_empty(list))
-		get_list_buf(list, false);
-	list = &vdev->nr.list_rpt;
-	while (!list_empty(list))
-		get_list_buf(list, false);
-
-	for (i = 0; i < sizeof(vdev->nr.buf) /
-	     sizeof(struct rkispp_dummy_buffer); i++)
-		rkispp_free_buffer(dev, &vdev->nr.buf.tmp_yuv + i);
-
-	vdev->nr.is_buf_init = false;
-}
-
-static int nr_init_buf(struct rkispp_device *dev, u32 size)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_dummy_buffer *buf;
-	int i, ret, cnt;
-
-	switch (vdev->module_ens & ISPP_MODULE_FEC_ST) {
-	case ISPP_MODULE_FEC_ST:
-		cnt = RKISPP_FEC_BUF_MAX;
-		break;
-	case ISPP_MODULE_FEC:
-		cnt = RKISPP_BUF_MAX;
-		break;
-	default:
-		cnt = 0;
-	}
-
-	for (i = 0; i < cnt; i++) {
-		buf = &vdev->nr.buf.wr[i];
-		buf->size = size;
-		buf->index = i;
-		buf->is_need_dbuf = true;
-		buf->is_need_vaddr = true;
-		buf->is_need_dmafd = false;
-		ret = rkispp_allow_buffer(dev, buf);
-		if (ret)
-			goto err;
-		list_add_tail(&buf->list, &vdev->nr.list_wr);
-	}
-
-	buf = &vdev->nr.buf.tmp_yuv;
-	cnt = DIV_ROUND_UP(dev->ispp_sdev.in_fmt.width, 32);
-	buf->size = PAGE_ALIGN(cnt * 42 * 32);
-	ret = rkispp_allow_buffer(dev, buf);
-	if (ret)
-		goto err;
-
-	vdev->nr.is_buf_init = true;
-	return 0;
-err:
-	nr_free_buf(dev);
-	v4l2_err(&dev->v4l2_dev, "%s failed\n", __func__);
-	return ret;
-}
-
-static int config_nr_shp(struct rkispp_device *dev)
-{
-	struct rkispp_hw_dev *hw = dev->hw_dev;
-	struct rkispp_stream_vdev *vdev;
-	struct rkispp_stream *stream = NULL;
-	u32 width, height, fmt;
-	u32 pic_size, addr_offs;
-	u32 w, h, val;
-	u32 max_w, max_h;
-	int ret, mult = 1;
-
-	vdev = &dev->stream_vdev;
-	vdev->nr.is_end = true;
-	if (!(vdev->module_ens & (ISPP_MODULE_NR | ISPP_MODULE_SHP)))
-		return 0;
-
-	vdev->is_done_early = is_en_done_early(dev);
-
-	if (dev->inp == INP_DDR) {
-		stream = &vdev->stream[STREAM_II];
-		fmt = stream->out_cap_fmt.wr_fmt;
-	} else {
-		fmt = dev->isp_mode & (FMT_YUV422 | FMT_FBC);
-	}
-
-	width = dev->ispp_sdev.in_fmt.width;
-	height = dev->ispp_sdev.in_fmt.height;
-	w = width;
-	h = height;
-	max_w = hw->max_in.w ? hw->max_in.w : w;
-	max_h = hw->max_in.h ? hw->max_in.h : h;
-	if (fmt & FMT_FBC) {
-		max_w = ALIGN(max_w, 16);
-		max_h = ALIGN(max_h, 16);
-		w = ALIGN(w, 16);
-		h = ALIGN(h, 16);
-	}
-	addr_offs = (fmt & FMT_FBC) ? max_w * max_h >> 4 : max_w * max_h;
-	pic_size = (fmt & FMT_YUV422) ? w * h * 2 : w * h * 3 >> 1;
-	vdev->nr.uv_offset = addr_offs;
-
-	if (fmt & FMT_YUYV)
-		mult = 2;
-
-	ret = nr_init_buf(dev, pic_size);
-	if (ret)
-		return ret;
-
-	if (vdev->module_ens & ISPP_MODULE_TNR) {
-		rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y,
-			     rkispp_read(dev, RKISPP_TNR_WR_Y_BASE));
-		rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV,
-			     rkispp_read(dev, RKISPP_TNR_WR_UV_BASE));
-		rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN,
-			     rkispp_read(dev, RKISPP_TNR_GAIN_WR_Y_BASE));
-		rkispp_set_bits(dev, RKISPP_CTRL_QUICK, 0, GLB_NR_SD32_TNR);
-	} else {
-		/* tnr need to set same format with nr in the fbc mode */
-		rkispp_set_bits(dev, RKISPP_TNR_CTRL, FMT_RD_MASK, fmt);
-		rkispp_write(dev, RKISPP_CTRL_TNR_SIZE, height << 16 | width);
-		if (dev->inp == INP_ISP) {
-			if (dev->isp_mode & ISP_ISPP_QUICK)
-				rkispp_set_bits(dev, RKISPP_CTRL_QUICK,
-						GLB_QUICK_MODE_MASK,
-						GLB_QUICK_MODE(2));
-			else
-				rkispp_set_bits(dev, RKISPP_NR_UVNR_CTRL_PARA,
-						0, SW_UVNR_SD32_SELF_EN);
-
-			val = hw->pool[0].dma[GROUP_BUF_PIC];
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, val);
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV, val + addr_offs);
-			val = hw->pool[0].dma[GROUP_BUF_GAIN];
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN, val);
-			rkispp_clear_bits(dev, RKISPP_CTRL_QUICK, GLB_NR_SD32_TNR);
-		} else if (stream) {
-			stream->config->frame_end_id = NR_INT;
-			stream->config->reg.cur_y_base = RKISPP_NR_ADDR_BASE_Y;
-			stream->config->reg.cur_uv_base = RKISPP_NR_ADDR_BASE_UV;
-			stream->config->reg.cur_y_base_shd = RKISPP_NR_ADDR_BASE_Y_SHD;
-			stream->config->reg.cur_uv_base_shd = RKISPP_NR_ADDR_BASE_UV_SHD;
-		}
-	}
-
-	rkispp_clear_bits(dev, RKISPP_CTRL_QUICK, GLB_FEC2SCL_EN);
-	if (vdev->module_ens & ISPP_MODULE_FEC) {
-		addr_offs = width * height;
-		vdev->fec.uv_offset = addr_offs;
-		val = vdev->nr.buf.wr[0].dma_addr;
-		rkispp_write(dev, RKISPP_SHARP_WR_Y_BASE, val);
-		rkispp_write(dev, RKISPP_SHARP_WR_UV_BASE, val + addr_offs);
-		rkispp_write(dev, RKISPP_SHARP_WR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-		rkispp_set_bits(dev, RKISPP_SHARP_CTRL, SW_SHP_WR_FORMAT_MASK, fmt & (~FMT_FBC));
-
-		rkispp_write(dev, RKISPP_FEC_RD_Y_BASE, val);
-		rkispp_write(dev, RKISPP_FEC_RD_UV_BASE, val + addr_offs);
-	} else {
-		stream = &vdev->stream[STREAM_MB];
-		if (!stream->streaming) {
-			val = hw->dummy_buf.dma_addr;
-			rkispp_write(dev, RKISPP_SHARP_WR_Y_BASE, val);
-			rkispp_write(dev, RKISPP_SHARP_WR_UV_BASE, val);
-			rkispp_write(dev, RKISPP_SHARP_WR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-			if (dev->inp == INP_ISP)
-				rkispp_set_bits(dev, RKISPP_SHARP_CTRL, SW_SHP_WR_FORMAT_MASK, FMT_FBC);
-		}
-	}
-
-	val = vdev->nr.buf.tmp_yuv.dma_addr;
-	rkispp_write(dev, RKISPP_SHARP_TMP_YUV_BASE, val);
-
-	/* fix to use new nr algorithm */
-	rkispp_set_bits(dev, RKISPP_NR_CTRL, NR_NEW_ALGO, NR_NEW_ALGO);
-	rkispp_set_bits(dev, RKISPP_NR_CTRL, FMT_RD_MASK, fmt);
-	if (fmt & FMT_FBC) {
-		rkispp_write(dev, RKISPP_NR_VIR_STRIDE, 0);
-		rkispp_write(dev, RKISPP_FBC_VIR_HEIGHT, max_h);
-	} else {
-		rkispp_write(dev, RKISPP_NR_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
-	}
-	rkispp_write(dev, RKISPP_NR_VIR_STRIDE_GAIN, ALIGN(width, 64) >> 4);
-	rkispp_write(dev, RKISPP_CTRL_SIZE, height << 16 | width);
-
-	if (vdev->monitor.is_en) {
-		init_completion(&vdev->monitor.nr.cmpl);
-		schedule_work(&vdev->monitor.nr.work);
-	}
-	v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-		 "%s size:%dx%d\n"
-		 "nr ctrl:0x%x ctrl_para:0x%x\n"
-		 "shp ctrl:0x%x core_ctrl:0x%x\n",
-		 __func__, width, height,
-		 rkispp_read(dev, RKISPP_NR_CTRL),
-		 rkispp_read(dev, RKISPP_NR_UVNR_CTRL_PARA),
-		 rkispp_read(dev, RKISPP_SHARP_CTRL),
-		 rkispp_read(dev, RKISPP_SHARP_CORE_CTRL));
-	return 0;
-}
-
-static void fec_free_buf(struct rkispp_device *dev)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct list_head *list = &vdev->fec.list_rd;
-
-	if (vdev->fec.cur_rd)
-		vdev->fec.cur_rd = NULL;
-	while (!list_empty(list))
-		get_list_buf(list, false);
-}
-
-static int config_fec(struct rkispp_device *dev)
-{
-	struct rkispp_stream_vdev *vdev;
-	struct rkispp_stream *stream = NULL;
-	u32 in_width, in_height, fmt, mult = 1;
-	u32 out_width, out_height;
-
-	vdev = &dev->stream_vdev;
-	vdev->fec.is_end = true;
-	if (!(vdev->module_ens & ISPP_MODULE_FEC))
-		return 0;
-
-	if (dev->inp == INP_DDR) {
-		stream = &vdev->stream[STREAM_II];
-		fmt = stream->out_cap_fmt.wr_fmt;
-	} else {
-		fmt = dev->isp_mode & FMT_YUV422;
-	}
-
-	in_width = dev->ispp_sdev.in_fmt.width;
-	in_height = dev->ispp_sdev.in_fmt.height;
-	out_width = dev->ispp_sdev.out_fmt.width;
-	out_height = dev->ispp_sdev.out_fmt.height;
-
-	if (vdev->module_ens & (ISPP_MODULE_NR | ISPP_MODULE_SHP)) {
-		rkispp_write(dev, RKISPP_FEC_RD_Y_BASE,
-			     rkispp_read(dev, RKISPP_SHARP_WR_Y_BASE));
-		rkispp_write(dev, RKISPP_FEC_RD_UV_BASE,
-			     rkispp_read(dev, RKISPP_SHARP_WR_UV_BASE));
-	} else if (stream) {
-		stream->config->frame_end_id = FEC_INT;
-		stream->config->reg.cur_y_base = RKISPP_FEC_RD_Y_BASE;
-		stream->config->reg.cur_uv_base = RKISPP_FEC_RD_UV_BASE;
-		stream->config->reg.cur_y_base_shd = RKISPP_FEC_RD_Y_BASE_SHD;
-		stream->config->reg.cur_uv_base_shd = RKISPP_FEC_RD_UV_BASE_SHD;
-	}
-
-	if (fmt & FMT_YUYV)
-		mult = 2;
-	rkispp_set_bits(dev, RKISPP_FEC_CTRL, FMT_RD_MASK, fmt);
-	rkispp_write(dev, RKISPP_FEC_RD_VIR_STRIDE, ALIGN(in_width * mult, 16) >> 2);
-	rkispp_write(dev, RKISPP_FEC_PIC_SIZE, out_height << 16 | out_width);
-	rkispp_set_bits(dev, RKISPP_CTRL_QUICK, 0, GLB_FEC2SCL_EN);
-
-	if (vdev->monitor.is_en) {
-		init_completion(&vdev->monitor.fec.cmpl);
-		schedule_work(&vdev->monitor.fec.work);
-	}
-	v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-		 "%s size:%dx%d->%dx%d ctrl:0x%x core_ctrl:0x%x\n",
-		 __func__, in_width, in_height, out_width, out_height,
-		 rkispp_read(dev, RKISPP_FEC_CTRL),
-		 rkispp_read(dev, RKISPP_FEC_CORE_CTRL));
-	return 0;
-}
-
-static void rkispp_start_3a_run(struct rkispp_device *dev)
-{
-	struct rkispp_params_vdev *params_vdev = &dev->params_vdev[PARAM_VDEV_NR];
-	struct video_device *vdev = &params_vdev->vnode.vdev;
+	struct rkispp_params_vdev *params_vdev;
+	struct video_device *vdev;
 	struct v4l2_event ev = {
 		.type = CIFISP_V4L2_EVENT_STREAM_START,
 	};
 	int ret;
 
+	if (dev->ispp_ver == ISPP_V10)
+		params_vdev = &dev->params_vdev[PARAM_VDEV_NR];
+	else
+		params_vdev = &dev->params_vdev[PARAM_VDEV_FEC];
 	if (!params_vdev->is_subs_evt)
 		return;
-
+	vdev = &params_vdev->vnode.vdev;
 	v4l2_event_queue(vdev, &ev);
 	ret = wait_event_timeout(dev->sync_onoff,
 			params_vdev->streamon && !params_vdev->first_params,
@@ -1189,16 +512,20 @@
 
 static void rkispp_stop_3a_run(struct rkispp_device *dev)
 {
-	struct rkispp_params_vdev *params_vdev = &dev->params_vdev[PARAM_VDEV_NR];
-	struct video_device *vdev = &params_vdev->vnode.vdev;
+	struct rkispp_params_vdev *params_vdev;
+	struct video_device *vdev;
 	struct v4l2_event ev = {
 		.type = CIFISP_V4L2_EVENT_STREAM_STOP,
 	};
 	int ret;
 
+	if (dev->ispp_ver == ISPP_V10)
+		params_vdev = &dev->params_vdev[PARAM_VDEV_NR];
+	else
+		params_vdev = &dev->params_vdev[PARAM_VDEV_FEC];
 	if (!params_vdev->is_subs_evt)
 		return;
-
+	vdev = &params_vdev->vnode.vdev;
 	v4l2_event_queue(vdev, &ev);
 	ret = wait_event_timeout(dev->sync_onoff, !params_vdev->streamon,
 				 msecs_to_jiffies(1000));
@@ -1208,44 +535,6 @@
 	else
 		v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
 			 "Waiting for 3A off use %d ms\n", 1000 - ret);
-}
-
-static int config_modules(struct rkispp_device *dev)
-{
-	int ret;
-
-	v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-		 "stream module ens:0x%x\n", dev->stream_vdev.module_ens);
-	dev->stream_vdev.monitor.monitoring_module = 0;
-	dev->stream_vdev.monitor.restart_module = 0;
-	dev->stream_vdev.monitor.is_restart = false;
-	dev->stream_vdev.monitor.retry = 0;
-	dev->stream_vdev.monitor.is_en = rkispp_monitor;
-	init_completion(&dev->stream_vdev.monitor.cmpl);
-
-	ret = config_tnr(dev);
-	if (ret < 0)
-		return ret;
-
-	ret = config_nr_shp(dev);
-	if (ret < 0)
-		goto free_tnr;
-
-	ret = config_fec(dev);
-	if (ret < 0)
-		goto free_nr;
-
-	/* config default params */
-	rkispp_params_cfg(&dev->params_vdev[PARAM_VDEV_TNR], 0);
-	rkispp_params_cfg(&dev->params_vdev[PARAM_VDEV_NR], 0);
-	rkispp_params_cfg(&dev->params_vdev[PARAM_VDEV_FEC], 0);
-
-	return 0;
-free_nr:
-	nr_free_buf(dev);
-free_tnr:
-	tnr_free_buf(dev);
-	return ret;
 }
 
 static int start_ii(struct rkispp_stream *stream)
@@ -1275,9 +564,11 @@
 
 static int config_ii(struct rkispp_stream *stream)
 {
+	struct rkispp_stream_vdev *stream_vdev = &stream->isppdev->stream_vdev;
+
 	stream->is_cfg = true;
 	rkispp_start_3a_run(stream->isppdev);
-	return config_modules(stream->isppdev);
+	return stream_vdev->stream_ops->config_modules(stream->isppdev);
 }
 
 static int is_stopped_ii(struct rkispp_stream *stream)
@@ -1286,7 +577,7 @@
 	return true;
 }
 
-static void secure_config_mb(struct rkispp_stream *stream)
+void secure_config_mb(struct rkispp_stream *stream)
 {
 	struct rkispp_device *dev = stream->isppdev;
 	u32 limit_range, mult = 1;
@@ -1311,7 +602,7 @@
 			0 : SW_FEC_WR_YUV_LIMIT;
 		rkispp_set_bits(dev, RKISPP_FEC_CTRL, SW_FEC_WR_YUV_LIMIT | FMT_WR_MASK,
 				limit_range | stream->out_cap_fmt.wr_fmt << 4);
-		rkispp_write(dev, RKISPP_FEC_PIC_SIZE,
+		rkispp_write(dev, RKISPP_FEC_DST_SIZE,
 			     stream->out_fmt.height << 16 | stream->out_fmt.width);
 		rkispp_clear_bits(dev, RKISPP_FEC_CORE_CTRL, SW_FEC2DDR_DIS);
 		break;
@@ -1640,6 +931,10 @@
 				pixm->plane_fmt[i].sizeimage;
 			offset = (cap_fmt->wr_fmt & FMT_FBC) ?
 				ALIGN(size, RK_MPP_ALIGN) : size;
+			if (cap_fmt->wr_fmt & FMT_FBC && dev->ispp_ver == ISPP_V20)
+				rkispp_write(dev, RKISPP_FEC_FBCE_HEAD_OFFSET,
+					     offset | SW_OFFSET_ENABLE);
+
 			isppbuf->buff_addr[i + 1] =
 				isppbuf->buff_addr[i] + offset;
 		}
@@ -1662,20 +957,6 @@
 		rkispp_event_handle(dev, CMD_QUEUE_DMABUF, &vdev->input[i]);
 	}
 	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
-}
-
-static void rkispp_destroy_buf(struct rkispp_stream *stream)
-{
-	struct rkispp_device *dev = stream->isppdev;
-	struct rkispp_stream_vdev *vdev= &dev->stream_vdev;
-
-	if (atomic_read(&vdev->refcnt) == 1) {
-		vdev->irq_ends = 0;
-		tnr_free_buf(dev);
-		nr_free_buf(dev);
-		fec_free_buf(dev);
-		rkispp_event_handle(dev, CMD_FREE_POOL, NULL);
-	}
 }
 
 static void rkispp_stream_stop(struct rkispp_stream *stream)
@@ -1745,6 +1026,7 @@
 	struct rkispp_stream *stream = queue->drv_priv;
 	struct rkispp_device *dev = stream->isppdev;
 	struct rkispp_hw_dev *hw = dev->hw_dev;
+	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
 
 	v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
 		 "%s id:%d enter\n", __func__, stream->id);
@@ -1768,7 +1050,7 @@
 	mutex_lock(&dev->hw_dev->dev_lock);
 	rkispp_stream_stop(stream);
 	destroy_buf_queue(stream, VB2_BUF_STATE_ERROR);
-	rkispp_destroy_buf(stream);
+	vdev->stream_ops->destroy_buf(stream);
 	mutex_unlock(&dev->hw_dev->dev_lock);
 	rkispp_free_common_dummy_buf(dev);
 	atomic_dec(&dev->stream_vdev.refcnt);
@@ -1783,72 +1065,12 @@
 		 "%s id:%d exit\n", __func__, stream->id);
 }
 
-static int start_isp(struct rkispp_device *dev)
-{
-	struct rkispp_subdev *ispp_sdev = &dev->ispp_sdev;
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_stream *stream;
-	struct rkisp_ispp_mode mode;
-	int i, ret;
-
-	if (dev->inp != INP_ISP || ispp_sdev->state)
-		return 0;
-
-	if (dev->stream_sync) {
-		/* output stream enable then start isp */
-		for (i = STREAM_MB; i <= STREAM_S2; i++) {
-			stream = &vdev->stream[i];
-			if (stream->linked && !stream->streaming)
-				return 0;
-		}
-	} else if (atomic_read(&vdev->refcnt) > 1) {
-		return 0;
-	}
-
-	rkispp_start_3a_run(dev);
-
-	mutex_lock(&dev->hw_dev->dev_lock);
-
-	mode.work_mode = dev->isp_mode;
-	mode.buf_num = ((vdev->module_ens & ISPP_MODULE_TNR_3TO1) ==
-			ISPP_MODULE_TNR_3TO1) ? 2 : 1;
-	mode.buf_num += RKISP_BUF_MAX + 2 * (dev->hw_dev->dev_num - 1);
-	ret = v4l2_subdev_call(ispp_sdev->remote_sd, core, ioctl,
-			       RKISP_ISPP_CMD_SET_MODE, &mode);
-	if (ret)
-		goto err;
-
-	ret = config_modules(dev);
-	if (ret) {
-		rkispp_event_handle(dev, CMD_FREE_POOL, NULL);
-		mode.work_mode = ISP_ISPP_INIT_FAIL;
-		v4l2_subdev_call(ispp_sdev->remote_sd, core, ioctl,
-				 RKISP_ISPP_CMD_SET_MODE, &mode);
-		goto err;
-	}
-	if (dev->hw_dev->is_single)
-		writel(ALL_FORCE_UPD, dev->hw_dev->base_addr + RKISPP_CTRL_UPDATE);
-	for (i = STREAM_MB; i <= STREAM_S2; i++) {
-		stream = &vdev->stream[i];
-		if (stream->streaming)
-			stream->is_upd = true;
-	}
-	if (dev->isp_mode & ISP_ISPP_QUICK)
-		rkispp_set_bits(dev, RKISPP_CTRL_QUICK, 0, GLB_QUICK_EN);
-
-	dev->isr_cnt = 0;
-	dev->isr_err_cnt = 0;
-	ret = v4l2_subdev_call(&ispp_sdev->sd, video, s_stream, true);
-err:
-	mutex_unlock(&dev->hw_dev->dev_lock);
-	return ret;
-}
-
 static int rkispp_start_streaming(struct vb2_queue *queue,
 				  unsigned int count)
 {
 	struct rkispp_stream *stream = queue->drv_priv;
 	struct rkispp_device *dev = stream->isppdev;
+	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
 	struct rkispp_hw_dev *hw = dev->hw_dev;
 	int ret = -1;
 
@@ -1878,10 +1100,10 @@
 		return ret;
 	}
 
-	if (dev->inp == INP_DDR &&
-	    !atomic_read(&hw->refcnt) &&
+	if (!atomic_read(&hw->refcnt) &&
 	    !atomic_read(&dev->stream_vdev.refcnt) &&
-	    clk_get_rate(hw->clks[0]) <= hw->core_clk_min) {
+	    clk_get_rate(hw->clks[0]) <= hw->core_clk_min &&
+	    (dev->inp == INP_DDR || dev->ispp_ver == ISPP_V20)) {
 		dev->hw_dev->is_first = false;
 		rkispp_set_clk_rate(hw->clks[0], hw->core_clk_max);
 	}
@@ -1899,8 +1121,12 @@
 	if (ret < 0)
 		goto free_buf_queue;
 
-	if (dev->inp == INP_ISP)
-		dev->stream_vdev.module_ens |= ISPP_MODULE_NR;
+	if (dev->inp == INP_ISP) {
+		if (dev->ispp_ver == ISPP_V10)
+			dev->stream_vdev.module_ens |= ISPP_MODULE_NR;
+		else if (dev->ispp_ver == ISPP_V20)
+			dev->stream_vdev.module_ens = ISPP_MODULE_FEC;
+	}
 
 	if (stream->ops && stream->ops->config) {
 		ret = stream->ops->config(stream);
@@ -1915,7 +1141,7 @@
 	stream->streaming = true;
 
 	/* start from isp */
-	ret = start_isp(dev);
+	ret = vdev->stream_ops->start_isp(dev);
 	if (ret)
 		goto free_dummy_buf;
 
@@ -1926,7 +1152,7 @@
 	rkispp_free_common_dummy_buf(stream->isppdev);
 free_buf_queue:
 	destroy_buf_queue(stream, VB2_BUF_STATE_QUEUED);
-	rkispp_destroy_buf(stream);
+	vdev->stream_ops->destroy_buf(stream);
 	atomic_dec(&dev->stream_vdev.refcnt);
 	stream->streaming = false;
 	stream->is_upd = false;
@@ -1964,6 +1190,7 @@
 	q->lock = &stream->isppdev->apilock;
 	q->dev = stream->isppdev->hw_dev->dev;
 	q->allow_cache_hints = 1;
+	q->bidirectional = 1;
 	if (stream->isppdev->hw_dev->is_dma_contig)
 		q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
 	q->gfp_flags = GFP_DMA32;
@@ -2026,10 +1253,16 @@
 
 		plane_fmt = pixm->plane_fmt + i;
 
-		w = (fmt->wr_fmt & FMT_FBC) ?
-			ALIGN(pixm->width, 16) : pixm->width;
-		h = (fmt->wr_fmt & FMT_FBC) ?
-			ALIGN(pixm->height, 16) : pixm->height;
+		if (pixm->width == RKISPP_MAX_WIDTH_V20) {
+			w = ALIGN(pixm->width, 16);
+			h = ALIGN(pixm->height, 16);
+		} else {
+			w = (fmt->wr_fmt & FMT_FBC) ?
+				ALIGN(pixm->width, 16) : pixm->width;
+			h = (fmt->wr_fmt & FMT_FBC) ?
+				ALIGN(pixm->height, 16) : pixm->height;
+		}
+
 		width = i ? w / xsubs : w;
 		height = i ? h / ysubs : h;
 
@@ -2074,17 +1307,32 @@
 			 __func__, stream->id, pixm->width, pixm->height,
 			 stream->out_fmt.width, stream->out_fmt.height);
 
-		if (sdev->out_fmt.width > RKISPP_MAX_WIDTH ||
-		    sdev->out_fmt.height > RKISPP_MAX_HEIGHT ||
-		    sdev->out_fmt.width < RKISPP_MIN_WIDTH ||
-		    sdev->out_fmt.height < RKISPP_MIN_HEIGHT) {
-			v4l2_err(&dev->v4l2_dev,
-				 "ispp input min:%dx%d max:%dx%d\n",
-				 RKISPP_MIN_WIDTH, RKISPP_MIN_HEIGHT,
-				 RKISPP_MAX_WIDTH, RKISPP_MAX_HEIGHT);
-			stream->out_fmt.width = 0;
-			stream->out_fmt.height = 0;
-			return -EINVAL;
+		if (dev->ispp_ver == ISPP_V10) {
+			if (sdev->out_fmt.width > RKISPP_MAX_WIDTH_V10 ||
+			sdev->out_fmt.height > RKISPP_MAX_HEIGHT_V10 ||
+			sdev->out_fmt.width < RKISPP_MIN_WIDTH_V10 ||
+			sdev->out_fmt.height < RKISPP_MIN_HEIGHT_V10) {
+				v4l2_err(&dev->v4l2_dev,
+					"ispp input min:%dx%d max:%dx%d\n",
+					RKISPP_MIN_WIDTH_V10, RKISPP_MIN_HEIGHT_V10,
+					RKISPP_MAX_WIDTH_V10, RKISPP_MAX_HEIGHT_V10);
+				stream->out_fmt.width = 0;
+				stream->out_fmt.height = 0;
+				return -EINVAL;
+			}
+		} else if (dev->ispp_ver == ISPP_V20) {
+			if (sdev->out_fmt.width > RKISPP_MAX_WIDTH_V20 ||
+			sdev->out_fmt.height > RKISPP_MAX_HEIGHT_V20 ||
+			sdev->out_fmt.width < RKISPP_MIN_WIDTH_V20 ||
+			sdev->out_fmt.height < RKISPP_MIN_HEIGHT_V20) {
+				v4l2_err(&dev->v4l2_dev,
+					"ispp input min:%dx%d max:%dx%d\n",
+					RKISPP_MIN_WIDTH_V20, RKISPP_MIN_HEIGHT_V20,
+					RKISPP_MAX_WIDTH_V20, RKISPP_MAX_HEIGHT_V20);
+				stream->out_fmt.width = 0;
+				stream->out_fmt.height = 0;
+				return -EINVAL;
+			}
 		}
 	}
 
@@ -2104,7 +1352,7 @@
 
 	ret = v4l2_fh_open(filp);
 	if (!ret) {
-		ret = v4l2_pipeline_pm_use(&stream->vnode.vdev.entity, 1);
+		ret = v4l2_pipeline_pm_get(&stream->vnode.vdev.entity);
 		if (ret < 0) {
 			v4l2_err(&isppdev->v4l2_dev,
 				 "pipeline power on failed %d\n", ret);
@@ -2117,16 +1365,11 @@
 static int rkispp_fh_release(struct file *filp)
 {
 	struct rkispp_stream *stream = video_drvdata(filp);
-	struct rkispp_device *isppdev = stream->isppdev;
 	int ret;
 
 	ret = vb2_fop_release(filp);
-	if (!ret) {
-		ret = v4l2_pipeline_pm_use(&stream->vnode.vdev.entity, 0);
-		if (ret < 0)
-			v4l2_err(&isppdev->v4l2_dev,
-				 "pipeline power off failed %d\n", ret);
-	}
+	if (!ret)
+		v4l2_pipeline_pm_put(&stream->vnode.vdev.entity);
 	return ret;
 }
 
@@ -2169,7 +1412,20 @@
 
 	fmt = &stream->config->fmts[f->index];
 	f->pixelformat = fmt->fourcc;
-
+	switch (f->pixelformat) {
+	case V4L2_PIX_FMT_FBC2:
+		strscpy(f->description,
+			"Rockchip yuv422sp fbc encoder",
+			sizeof(f->description));
+		break;
+	case V4L2_PIX_FMT_FBC0:
+		strscpy(f->description,
+			"Rockchip yuv420sp fbc encoder",
+			sizeof(f->description));
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
@@ -2229,11 +1485,10 @@
 	.vidioc_streamoff = vb2_ioctl_streamoff,
 	.vidioc_enum_input = rkispp_enum_input,
 	.vidioc_try_fmt_vid_cap_mplane = rkispp_try_fmt_vid_mplane,
-	.vidioc_enum_fmt_vid_cap_mplane = rkispp_enum_fmt_vid_mplane,
+	.vidioc_enum_fmt_vid_cap = rkispp_enum_fmt_vid_mplane,
 	.vidioc_s_fmt_vid_cap_mplane = rkispp_s_fmt_vid_mplane,
 	.vidioc_g_fmt_vid_cap_mplane = rkispp_g_fmt_vid_mplane,
 	.vidioc_try_fmt_vid_out_mplane = rkispp_try_fmt_vid_mplane,
-	.vidioc_enum_fmt_vid_out_mplane = rkispp_enum_fmt_vid_mplane,
 	.vidioc_s_fmt_vid_out_mplane = rkispp_s_fmt_vid_mplane,
 	.vidioc_g_fmt_vid_out_mplane = rkispp_g_fmt_vid_mplane,
 	.vidioc_querycap = rkispp_querycap,
@@ -2280,7 +1535,7 @@
 	rkispp_init_vb2_queue(&node->buf_queue, stream, buf_type);
 	vdev->queue = &node->buf_queue;
 
-	ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
 	if (ret < 0) {
 		v4l2_err(v4l2_dev,
 			 "video register failed with error %d\n", ret);
@@ -2335,8 +1590,8 @@
 			kernel_write(fp, buf->vaddr[0], vdev->tnr.cur_rd->dbuf[0]->size, &fp->f_pos);
 			filp_close(fp, NULL);
 			v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-				 "dump tnr cur_rd dma:0x%x vaddr:%p\n",
-				 buf->dma[0], buf->vaddr[0]);
+				 "dump tnr cur_rd dma:%pad vaddr:%p\n",
+				 &buf->dma[0], buf->vaddr[0]);
 		}
 
 		if (vdev->tnr.nxt_rd && vdev->tnr.nxt_rd != vdev->tnr.cur_rd) {
@@ -2352,8 +1607,8 @@
 			kernel_write(fp, buf->vaddr[0], vdev->tnr.nxt_rd->dbuf[0]->size, &fp->f_pos);
 			filp_close(fp, NULL);
 			v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-				 "dump tnr nxt_rd dma:0x%x vaddr:%p\n",
-				 buf->dma[0], buf->vaddr[0]);
+				 "dump tnr nxt_rd dma:%pad vaddr:%p\n",
+				 &buf->dma[0], buf->vaddr[0]);
 		}
 	}
 
@@ -2373,8 +1628,8 @@
 			kernel_write(fp, dummy->vaddr, dummy->size, &fp->f_pos);
 			filp_close(fp, NULL);
 			v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
-				 "dump tnr wr dma:0x%x vaddr:%p\n",
-				 dummy->dma_addr, dummy->vaddr);
+				 "dump tnr wr dma:%pad vaddr:%p\n",
+				 &dummy->dma_addr, dummy->vaddr);
 		}
 	}
 }
@@ -2546,171 +1801,6 @@
 	monitor->is_restart = false;
 }
 
-static void fec_work_event(struct rkispp_device *dev,
-			   struct rkispp_dummy_buffer *buf_rd,
-			   bool is_isr, bool is_quick)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_monitor *monitor = &vdev->monitor;
-	struct list_head *list = &vdev->fec.list_rd;
-	void __iomem *base = dev->hw_dev->base_addr;
-	struct rkispp_dummy_buffer *dummy;
-	struct rkispp_stream *stream;
-	unsigned long lock_flags = 0, lock_flags1 = 0;
-	bool is_start = false;
-	struct rkisp_ispp_reg *reg_buf = NULL;
-	u32 val;
-
-	if (!(vdev->module_ens & ISPP_MODULE_FEC))
-		return;
-
-	spin_lock_irqsave(&vdev->fec.buf_lock, lock_flags);
-
-	/* event from fec frame end */
-	if (!buf_rd && is_isr) {
-		vdev->fec.is_end = true;
-
-		if (vdev->fec.cur_rd || vdev->is_done_early)
-			rkispp_module_work_event(dev, NULL, vdev->fec.cur_rd,
-						 ISPP_MODULE_NR, false);
-		vdev->fec.cur_rd = NULL;
-	}
-
-	spin_lock_irqsave(&monitor->lock, lock_flags1);
-	if (monitor->is_restart && buf_rd) {
-		list_add_tail(&buf_rd->list, list);
-		goto restart_unlock;
-	}
-
-	if (buf_rd && vdev->fec.is_end && list_empty(list)) {
-		/* fec read buf from nr */
-		vdev->fec.cur_rd = buf_rd;
-	} else if (vdev->fec.is_end && !list_empty(list)) {
-		/* fec read buf from list
-		 * fec processing slow than nr
-		 * new read buf from nr into list
-		 */
-		vdev->fec.cur_rd = get_list_buf(list, false);
-		if (buf_rd)
-			list_add_tail(&buf_rd->list, list);
-	} else if (!vdev->fec.is_end && buf_rd) {
-		/* fec no idle
-		 * new read buf from nr into list
-		 */
-		list_add_tail(&buf_rd->list, list);
-	}
-
-	if (vdev->fec.cur_rd && vdev->fec.is_end) {
-		dummy = vdev->fec.cur_rd;
-		val = dummy->dma_addr;
-		rkispp_write(dev, RKISPP_FEC_RD_Y_BASE, val);
-		val += vdev->fec.uv_offset;
-		rkispp_write(dev, RKISPP_FEC_RD_UV_BASE, val);
-		is_start = true;
-	}
-
-	if (is_start || is_quick) {
-		u32 seq = 0;
-
-		if (vdev->fec.cur_rd) {
-			seq = vdev->fec.cur_rd->id;
-			dev->ispp_sdev.frame_timestamp =
-				vdev->fec.cur_rd->timestamp;
-			dev->ispp_sdev.frm_sync_seq = seq;
-			rkispp_params_cfg(&dev->params_vdev[PARAM_VDEV_FEC], seq);
-		} else {
-			seq = vdev->nr.buf.wr[0].id;
-			dev->ispp_sdev.frame_timestamp =
-				vdev->nr.buf.wr[0].timestamp;
-			dev->ispp_sdev.frm_sync_seq = seq;
-		}
-
-		/* check MB config and output buf beforce start, when MB connect to FEC
-		 * MB update by FEC_FORCE_UPD
-		 */
-		stream = &vdev->stream[STREAM_MB];
-		if (stream->streaming) {
-			if (!stream->is_cfg) {
-				secure_config_mb(stream);
-			} else if (!stream->curr_buf) {
-				get_stream_buf(stream);
-				if (stream->curr_buf)
-					update_mi(stream);
-			}
-		}
-
-		if (!dev->hw_dev->is_single) {
-			rkispp_update_regs(dev, RKISPP_FEC, RKISPP_FEC_CROP);
-			rkispp_update_regs(dev, RKISPP_SCL0, RKISPP_SCL2_FACTOR);
-		}
-
-		writel(FEC_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
-		if (vdev->nr.is_end) {
-			if (!dev->hw_dev->is_single)
-				rkispp_update_regs(dev, RKISPP_SCL0_CTRL, RKISPP_SCL2_FACTOR);
-			writel(OTHER_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
-			/* check scale stream stop state */
-			for (val = STREAM_S0; val <= STREAM_S2; val++) {
-				stream = &vdev->stream[val];
-				if (stream->streaming && stream->stopping) {
-					if (stream->ops->is_stopped(stream)) {
-						stream->stopping = false;
-						stream->streaming = false;
-						wake_up(&stream->done);
-					} else {
-						stream->ops->stop(stream);
-					}
-				}
-			}
-		}
-		v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev,
-			 "FEC start seq:%d | Y_SHD rd:0x%x\n"
-			 "\txint:0x%x xfra:0x%x yint:0x%x yfra:0x%x\n",
-			 seq, readl(base + RKISPP_FEC_RD_Y_BASE_SHD),
-			 readl(base + RKISPP_FEC_MESH_XINT_BASE_SHD),
-			 readl(base + RKISPP_FEC_MESH_XFRA_BASE_SHD),
-			 readl(base + RKISPP_FEC_MESH_YINT_BASE_SHD),
-			 readl(base + RKISPP_FEC_MESH_YFRA_BASE_SHD));
-
-		vdev->fec.dbg.id = seq;
-		vdev->fec.dbg.timestamp = ktime_get_ns();
-		if (monitor->is_en) {
-			monitor->fec.time = vdev->fec.dbg.interval / 1000 / 1000;
-			monitor->monitoring_module |= MONITOR_FEC;
-			if (!completion_done(&monitor->fec.cmpl))
-				complete(&monitor->fec.cmpl);
-		}
-
-		if (rkispp_is_reg_withstream_global())
-			rkispp_find_regbuf_by_id(dev, &reg_buf, dev->dev_id, seq);
-		if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_FEC)) {
-			u32 offset, size;
-
-			offset = reg_buf->reg_size;
-			size = 4 + RKISPP_FEC_CROP - RKISPP_FEC_CTRL;
-			reg_buf->ispp_size[ISPP_ID_FEC] = size;
-			reg_buf->ispp_offset[ISPP_ID_FEC] = offset;
-			memcpy_fromio(&reg_buf->reg[offset], base + RKISPP_FEC_CTRL, size);
-
-			offset += size;
-			reg_buf->reg_size = offset;
-		}
-
-		if (!dev->hw_dev->is_shutdown) {
-			writel(FEC_ST, base + RKISPP_CTRL_STRT);
-
-			if (vdev->is_done_early)
-				hrtimer_start(&vdev->frame_qst,
-					      ns_to_ktime(5000000),
-					      HRTIMER_MODE_REL);
-		}
-		vdev->fec.is_end = false;
-	}
-restart_unlock:
-	spin_unlock_irqrestore(&monitor->lock, lock_flags1);
-	spin_unlock_irqrestore(&vdev->fec.buf_lock, lock_flags);
-}
-
 static enum hrtimer_restart rkispp_fec_do_early(struct hrtimer *timer)
 {
 	struct rkispp_stream_vdev *vdev =
@@ -2738,752 +1828,10 @@
 		v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev,
 			 "%s seq:%d ycnt:%d time:%dus\n",
 			 __func__, vdev->nr.dbg.id, ycnt * 128, time / 1000);
-		fec_work_event(dev, NULL, false, true);
+		vdev->stream_ops->fec_work_event(dev, NULL, false, true);
 	}
 end:
 	return ret;
-}
-
-static void nr_work_event(struct rkispp_device *dev,
-			  struct rkisp_ispp_buf *buf_rd,
-			  struct rkispp_dummy_buffer *buf_wr,
-			  bool is_isr)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_stream *stream = &vdev->stream[STREAM_II];
-	struct rkispp_monitor *monitor = &vdev->monitor;
-	void __iomem *base = dev->hw_dev->base_addr;
-	struct rkispp_dummy_buffer *buf_to_fec = NULL;
-	struct rkispp_dummy_buffer *dummy;
-	struct rkispp_buffer *inbuf;
-	struct v4l2_subdev *sd = NULL;
-	struct list_head *list;
-	struct dma_buf *dbuf;
-	unsigned long lock_flags = 0, lock_flags1 = 0;
-	bool is_start = false, is_quick = false, is_fec_event = false;
-	bool is_fec_en = (vdev->module_ens & ISPP_MODULE_FEC);
-	struct rkisp_ispp_reg *reg_buf = NULL;
-	u32 val;
-
-	if (!(vdev->module_ens & (ISPP_MODULE_NR | ISPP_MODULE_SHP)))
-		return;
-
-	if (dev->inp == INP_ISP) {
-		if (dev->isp_mode & ISP_ISPP_QUICK)
-			is_quick = true;
-		else
-			sd = dev->ispp_sdev.remote_sd;
-	}
-
-	spin_lock_irqsave(&vdev->nr.buf_lock, lock_flags);
-
-	/* event from nr frame end */
-	if (!buf_rd && !buf_wr && is_isr) {
-		vdev->nr.is_end = true;
-		is_fec_event = true;
-		if (vdev->nr.cur_rd) {
-			/* nr read buf return to isp or tnr */
-			if (vdev->nr.cur_rd->is_isp && sd) {
-				v4l2_subdev_call(sd, video, s_rx_buffer, vdev->nr.cur_rd, NULL);
-			} else if (!vdev->nr.cur_rd->priv) {
-				rkispp_module_work_event(dev, NULL, vdev->nr.cur_rd,
-							 ISPP_MODULE_TNR, is_isr);
-			} else if (stream->streaming && vdev->nr.cur_rd->priv) {
-				inbuf = vdev->nr.cur_rd->priv;
-				vb2_buffer_done(&inbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-			}
-			vdev->nr.cur_rd = NULL;
-		}
-
-		if (vdev->nr.cur_wr) {
-			/* nr write buf to fec */
-			buf_to_fec = vdev->nr.cur_wr;
-			vdev->nr.cur_wr = NULL;
-
-			if (vdev->is_done_early && !dev->hw_dev->is_first)
-				buf_to_fec = NULL;
-		}
-	}
-
-	if (!vdev->fec.is_end) {
-		if (buf_rd)
-			list_add_tail(&buf_rd->list, &vdev->nr.list_rd);
-		goto end;
-	}
-
-	spin_lock_irqsave(&monitor->lock, lock_flags1);
-	if (monitor->is_restart) {
-		if (buf_rd)
-			list_add_tail(&buf_rd->list, &vdev->nr.list_rd);
-		if (buf_wr)
-			list_add_tail(&buf_wr->list, &vdev->nr.list_wr);
-		goto restart_unlock;
-	}
-
-	list = &vdev->nr.list_rd;
-	if (buf_rd && vdev->nr.is_end && list_empty(list)) {
-		/* nr read buf from isp or tnr */
-		vdev->nr.cur_rd = buf_rd;
-	} else if (vdev->nr.is_end && !list_empty(list)) {
-		/* nr read buf from list
-		 * nr processing slow than isp or tnr
-		 * new read buf from isp or tnr into list
-		 */
-		vdev->nr.cur_rd = get_list_buf(list, true);
-		if (buf_rd)
-			list_add_tail(&buf_rd->list, list);
-	} else if (!vdev->nr.is_end && buf_rd) {
-		/* nr no idle
-		 * new read buf from isp or tnr into list
-		 */
-		list_add_tail(&buf_rd->list, list);
-	}
-
-	list = &vdev->nr.list_wr;
-	if (vdev->nr.is_end && !vdev->nr.cur_wr) {
-		/* nr idle, get new write buf */
-		vdev->nr.cur_wr = buf_wr ? buf_wr :
-				get_list_buf(list, false);
-	} else if (buf_wr) {
-		/* tnr no idle, write buf from nr into list */
-		list_add_tail(&buf_wr->list, list);
-	}
-
-	if (vdev->nr.cur_rd && vdev->nr.is_end) {
-		if (vdev->nr.cur_rd->priv) {
-			inbuf = vdev->nr.cur_rd->priv;
-			val = inbuf->buff_addr[RKISPP_PLANE_Y];
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, val);
-			val = inbuf->buff_addr[RKISPP_PLANE_UV];
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV, val);
-		} else if (!vdev->nr.cur_rd->is_isp) {
-			u32 size = sizeof(vdev->tnr.buf) / sizeof(*dummy);
-
-			dbuf = vdev->nr.cur_rd->dbuf[GROUP_BUF_PIC];
-			dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
-			val = dummy->dma_addr;
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, val);
-			val += vdev->nr.uv_offset;
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV, val);
-
-			dbuf = vdev->nr.cur_rd->dbuf[GROUP_BUF_GAIN];
-			dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
-			val = dummy->dma_addr;
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN, val);
-		} else {
-			struct rkispp_isp_buf_pool *buf;
-
-			buf = get_pool_buf(dev, vdev->nr.cur_rd);
-			val = buf->dma[GROUP_BUF_PIC];
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, val);
-			val += vdev->nr.uv_offset;
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV, val);
-
-			val = buf->dma[GROUP_BUF_GAIN];
-			rkispp_write(dev, RKISPP_NR_ADDR_BASE_GAIN, val);
-		}
-		is_start = true;
-	}
-
-	if (vdev->nr.is_end && is_quick)
-		is_start = true;
-
-	if (vdev->nr.cur_wr && is_start) {
-		dummy = vdev->nr.cur_wr;
-		val = dummy->dma_addr;
-		rkispp_write(dev, RKISPP_SHARP_WR_Y_BASE, val);
-		val += vdev->fec.uv_offset;
-		rkispp_write(dev, RKISPP_SHARP_WR_UV_BASE, val);
-	}
-
-	if (is_start) {
-		u32 seq = 0;
-		u64 timestamp = 0;
-
-		if (vdev->nr.cur_rd) {
-			seq = vdev->nr.cur_rd->frame_id;
-			timestamp = vdev->nr.cur_rd->frame_timestamp;
-			if (vdev->nr.cur_wr) {
-				vdev->nr.cur_wr->id = seq;
-				vdev->nr.cur_wr->timestamp = timestamp;
-			} else {
-				vdev->nr.buf.wr[0].id = seq;
-				vdev->nr.buf.wr[0].timestamp = timestamp;
-			}
-			if (!is_fec_en && !is_quick) {
-				dev->ispp_sdev.frame_timestamp = timestamp;
-				dev->ispp_sdev.frm_sync_seq = seq;
-			}
-
-			dev->stats_vdev[STATS_VDEV_NR].frame_id = seq;
-			rkispp_params_cfg(&dev->params_vdev[PARAM_VDEV_NR], seq);
-		}
-
-		/* check MB config and output buf beforce start, when MB connect to SHARP
-		 * MB update by OTHER_FORCE_UPD
-		 */
-		stream = &vdev->stream[STREAM_MB];
-		if (!is_fec_en && stream->streaming) {
-			if (!stream->is_cfg) {
-				secure_config_mb(stream);
-			} else if (!stream->curr_buf) {
-				get_stream_buf(stream);
-				if (stream->curr_buf)
-					update_mi(stream);
-			}
-		}
-
-		/* check SCL output buf beforce start
-		 * SCL update by OTHER_FORCE_UPD
-		 */
-		for (val = STREAM_S0; val <= STREAM_S2; val++) {
-			stream = &vdev->stream[val];
-			if (!stream->streaming || !stream->is_cfg || stream->curr_buf)
-				continue;
-			get_stream_buf(stream);
-			if (stream->curr_buf) {
-				update_mi(stream);
-				rkispp_set_bits(dev, stream->config->reg.ctrl, 0, SW_SCL_ENABLE);
-			} else {
-				rkispp_clear_bits(dev, stream->config->reg.ctrl, SW_SCL_ENABLE);
-			}
-		}
-
-		if (!dev->hw_dev->is_single) {
-			if (vdev->nr.cur_rd &&
-			    (vdev->nr.cur_rd->is_isp || vdev->nr.cur_rd->priv)) {
-				rkispp_update_regs(dev, RKISPP_CTRL, RKISPP_TNR_CTRL);
-				writel(TNR_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
-			}
-			rkispp_update_regs(dev, RKISPP_NR, RKISPP_ORB_MAX_FEATURE);
-		}
-
-		writel(OTHER_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
-
-		val = readl(base + RKISPP_SHARP_CORE_CTRL);
-		if (!(val & SW_SHP_EN) && !is_fec_en && !stream->streaming)
-			writel(val | SW_SHP_DMA_DIS, base + RKISPP_SHARP_CORE_CTRL);
-		else if (val & SW_SHP_EN)
-			writel(val & ~SW_SHP_DMA_DIS, base + RKISPP_SHARP_CORE_CTRL);
-
-		v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev,
-			 "NR start seq:%d | Y_SHD rd:0x%x wr:0x%x\n",
-			 seq, readl(base + RKISPP_NR_ADDR_BASE_Y_SHD),
-			 readl(base + RKISPP_SHARP_WR_Y_BASE_SHD));
-
-		for (val = STREAM_S0; val <= STREAM_S2 && !is_fec_en; val++) {
-			stream = &vdev->stream[val];
-			/* check scale stream stop state */
-			if (stream->streaming && stream->stopping) {
-				if (stream->ops->is_stopped(stream)) {
-					stream->stopping = false;
-					stream->streaming = false;
-					wake_up(&stream->done);
-				} else {
-					stream->ops->stop(stream);
-				}
-			}
-		}
-
-		vdev->nr.dbg.id = seq;
-		vdev->nr.dbg.timestamp = ktime_get_ns();
-		if (monitor->is_en) {
-			monitor->nr.time = vdev->nr.dbg.interval / 1000 / 1000;
-			monitor->monitoring_module |= MONITOR_NR;
-			monitor->nr.is_err = false;
-			if (!completion_done(&monitor->nr.cmpl))
-				complete(&monitor->nr.cmpl);
-		}
-
-		if (rkispp_is_reg_withstream_global())
-			rkispp_find_regbuf_by_id(dev, &reg_buf, dev->dev_id, seq);
-		if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_NR)) {
-			u32 offset, size;
-
-			offset = reg_buf->reg_size;
-			size = 4 + RKISPP_NR_BUFFER_READY - RKISPP_NR_CTRL;
-			reg_buf->ispp_size[ISPP_ID_NR] = size;
-			reg_buf->ispp_offset[ISPP_ID_NR] = offset;
-			memcpy_fromio(&reg_buf->reg[offset], base + RKISPP_NR_CTRL, size);
-
-			offset += size;
-			reg_buf->reg_size = offset;
-		}
-		if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_SHP)) {
-			u32 offset, size;
-
-			offset = reg_buf->reg_size;
-			size = 4 + RKISPP_SHARP_GRAD_RATIO - RKISPP_SHARP_CTRL;
-			reg_buf->ispp_size[ISPP_ID_SHP] = size;
-			reg_buf->ispp_offset[ISPP_ID_SHP] = offset;
-			memcpy_fromio(&reg_buf->reg[offset], base + RKISPP_SHARP_CTRL, size);
-
-			offset += size;
-			reg_buf->reg_size = offset;
-		}
-		if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_ORB)) {
-			u32 offset, size;
-
-			offset = reg_buf->reg_size;
-			size = 4 + RKISPP_ORB_MAX_FEATURE - RKISPP_ORB_WR_BASE;
-			reg_buf->ispp_size[ISPP_ID_ORB] = size;
-			reg_buf->ispp_offset[ISPP_ID_ORB] = offset;
-			memcpy_fromio(&reg_buf->reg[offset], base + RKISPP_ORB_WR_BASE, size);
-
-			offset += size;
-			reg_buf->reg_size = offset;
-		}
-
-		if (!is_quick && !dev->hw_dev->is_shutdown) {
-			writel(NR_SHP_ST, base + RKISPP_CTRL_STRT);
-
-			if (!is_fec_en && vdev->is_done_early)
-				hrtimer_start(&vdev->frame_qst,
-					      ns_to_ktime(1000000),
-					      HRTIMER_MODE_REL);
-		}
-		vdev->nr.is_end = false;
-	}
-restart_unlock:
-	spin_unlock_irqrestore(&monitor->lock, lock_flags1);
-end:
-	/* nr_shp->fec->scl
-	 * fec start working should after nr
-	 * for scl will update by OTHER_FORCE_UPD
-	 */
-	if (buf_to_fec) {
-		if ((vdev->module_ens & ISPP_MODULE_FEC_ST) == ISPP_MODULE_FEC_ST) {
-			rkispp_finish_buffer(dev, buf_to_fec);
-			list_add_tail(&buf_to_fec->list, &dev->stream_vdev.nr.list_rpt);
-			buf_to_fec = NULL;
-		}
-		rkispp_module_work_event(dev, buf_to_fec, NULL, ISPP_MODULE_FEC, false);
-	} else if (!list_empty(&vdev->fec.list_rd) && is_fec_event) {
-		rkispp_module_work_event(dev, NULL, NULL, ISPP_MODULE_FEC, false);
-	}
-	spin_unlock_irqrestore(&vdev->nr.buf_lock, lock_flags);
-
-	if (is_fec_en && vdev->is_done_early &&
-	    is_start && !dev->hw_dev->is_first &&
-	    (vdev->module_ens & ISPP_MODULE_FEC_ST) != ISPP_MODULE_FEC_ST)
-		hrtimer_start(&vdev->fec_qst,
-			      ns_to_ktime(1000000),
-			      HRTIMER_MODE_REL);
-}
-
-static void tnr_work_event(struct rkispp_device *dev,
-			   struct rkisp_ispp_buf *buf_rd,
-			   struct rkisp_ispp_buf *buf_wr,
-			   bool is_isr)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_stream *stream = &vdev->stream[STREAM_II];
-	struct rkispp_monitor *monitor = &vdev->monitor;
-	void __iomem *base = dev->hw_dev->base_addr;
-	struct rkispp_dummy_buffer *dummy;
-	struct rkispp_buffer *inbuf;
-	struct v4l2_subdev *sd = NULL;
-	struct list_head *list;
-	struct dma_buf *dbuf;
-	unsigned long lock_flags = 0, lock_flags1 = 0;
-	u32 val, size = sizeof(vdev->tnr.buf) / sizeof(*dummy);
-	bool is_en, is_3to1 = vdev->tnr.is_3to1, is_start = false;
-	struct rkisp_ispp_reg *reg_buf = NULL;
-
-	if (!(vdev->module_ens & ISPP_MODULE_TNR) ||
-	    (dev->inp == INP_ISP && dev->isp_mode & ISP_ISPP_QUICK))
-		return;
-
-	if (dev->inp == INP_ISP)
-		sd = dev->ispp_sdev.remote_sd;
-
-	if (buf_rd)
-		rkispp_params_cfg(&dev->params_vdev[PARAM_VDEV_TNR], buf_rd->frame_id);
-
-	is_en = rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN;
-
-	spin_lock_irqsave(&vdev->tnr.buf_lock, lock_flags);
-
-	/* event from tnr frame end */
-	if (!buf_rd && !buf_wr && is_isr) {
-		vdev->tnr.is_end = true;
-
-		if (vdev->tnr.cur_rd) {
-			/* tnr read buf return to isp */
-			if (sd) {
-				v4l2_subdev_call(sd, video, s_rx_buffer, vdev->tnr.cur_rd, NULL);
-			} else if (stream->streaming && vdev->tnr.cur_rd->priv) {
-				inbuf = vdev->tnr.cur_rd->priv;
-				vb2_buffer_done(&inbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-			}
-			if (vdev->tnr.cur_rd == vdev->tnr.nxt_rd)
-				vdev->tnr.nxt_rd = NULL;
-			vdev->tnr.cur_rd = NULL;
-		}
-
-		if (vdev->tnr.cur_wr) {
-
-			if (!vdev->tnr.cur_wr->is_move_judge || !vdev->tnr.is_trigger) {
-				/* tnr write buf to nr */
-				rkispp_module_work_event(dev, vdev->tnr.cur_wr, NULL,
-							 ISPP_MODULE_NR, is_isr);
-			} else {
-				dbuf = vdev->tnr.cur_wr->dbuf[GROUP_BUF_GAIN];
-				dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
-				rkispp_finish_buffer(dev, dummy);
-				rkispp_finish_buffer(dev, &vdev->tnr.buf.gain_kg);
-				list_add_tail(&vdev->tnr.cur_wr->list, &vdev->tnr.list_rpt);
-			}
-			vdev->tnr.cur_wr = NULL;
-		}
-	}
-
-	if (!is_en) {
-		if (buf_wr)
-			list_add_tail(&buf_wr->list, &vdev->tnr.list_wr);
-
-		if (vdev->tnr.nxt_rd) {
-			if (sd) {
-				v4l2_subdev_call(sd, video, s_rx_buffer,
-						 vdev->tnr.nxt_rd, NULL);
-			} else if (stream->streaming && vdev->tnr.nxt_rd->priv) {
-				inbuf = vdev->tnr.nxt_rd->priv;
-				vb2_buffer_done(&inbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-			}
-			vdev->tnr.nxt_rd = NULL;
-		}
-		list = &vdev->tnr.list_rd;
-		while (!list_empty(list)) {
-			struct rkisp_ispp_buf *buf = get_list_buf(list, true);
-
-			rkispp_module_work_event(dev, buf, NULL,
-						 ISPP_MODULE_NR, is_isr);
-		}
-		if (buf_rd)
-			rkispp_module_work_event(dev, buf_rd, NULL,
-						 ISPP_MODULE_NR, is_isr);
-		goto end;
-	}
-
-	spin_lock_irqsave(&monitor->lock, lock_flags1);
-	if (monitor->is_restart) {
-		if (buf_rd)
-			list_add_tail(&buf_rd->list, &vdev->tnr.list_rd);
-		if (buf_wr)
-			list_add_tail(&buf_wr->list, &vdev->tnr.list_wr);
-		goto restart_unlock;
-	}
-
-	list = &vdev->tnr.list_rd;
-	if (buf_rd && vdev->tnr.is_end && list_empty(list)) {
-		/* tnr read buf from isp */
-		vdev->tnr.cur_rd = vdev->tnr.nxt_rd;
-		vdev->tnr.nxt_rd = buf_rd;
-		/* first buf for 3to1 using twice */
-		if (!is_3to1 ||
-		    (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM))
-			vdev->tnr.cur_rd = vdev->tnr.nxt_rd;
-	} else if (vdev->tnr.is_end && !list_empty(list)) {
-		/* tnr read buf from list
-		 * tnr processing slow than isp
-		 * new read buf from isp into list
-		 */
-		vdev->tnr.cur_rd = vdev->tnr.nxt_rd;
-		vdev->tnr.nxt_rd = get_list_buf(list, true);
-		if (!is_3to1)
-			vdev->tnr.cur_rd = vdev->tnr.nxt_rd;
-
-		if (buf_rd)
-			list_add_tail(&buf_rd->list, list);
-	} else if (!vdev->tnr.is_end && buf_rd) {
-		/* tnr no idle
-		 * new read buf from isp into list
-		 */
-		list_add_tail(&buf_rd->list, list);
-	}
-
-	list = &vdev->tnr.list_wr;
-	if (vdev->tnr.is_end && !vdev->tnr.cur_wr) {
-		/* tnr idle, get new write buf */
-		vdev->tnr.cur_wr =
-			buf_wr ? buf_wr : get_list_buf(list, true);
-	} else if (buf_wr) {
-		/* tnr no idle, write buf from nr into list */
-		list_add_tail(&buf_wr->list, list);
-	}
-
-	if (vdev->tnr.cur_rd && vdev->tnr.nxt_rd && vdev->tnr.is_end) {
-		if (vdev->tnr.cur_rd->priv) {
-			inbuf = vdev->tnr.cur_rd->priv;
-			val = inbuf->buff_addr[RKISPP_PLANE_Y];
-			rkispp_write(dev, RKISPP_TNR_CUR_Y_BASE, val);
-			val = inbuf->buff_addr[RKISPP_PLANE_UV];
-			rkispp_write(dev, RKISPP_TNR_CUR_UV_BASE, val);
-		} else {
-			struct rkispp_isp_buf_pool *buf;
-
-			buf = get_pool_buf(dev, vdev->tnr.cur_rd);
-			val = buf->dma[GROUP_BUF_PIC];
-			rkispp_write(dev, RKISPP_TNR_CUR_Y_BASE, val);
-			val += vdev->tnr.uv_offset;
-			rkispp_write(dev, RKISPP_TNR_CUR_UV_BASE, val);
-
-			val = buf->dma[GROUP_BUF_GAIN];
-			rkispp_write(dev, RKISPP_TNR_GAIN_CUR_Y_BASE, val);
-			if (is_3to1) {
-				buf = get_pool_buf(dev, vdev->tnr.nxt_rd);
-				val = buf->dma[GROUP_BUF_PIC];
-				rkispp_write(dev, RKISPP_TNR_NXT_Y_BASE, val);
-				val += vdev->tnr.uv_offset;
-				rkispp_write(dev, RKISPP_TNR_NXT_UV_BASE, val);
-
-				val = buf->dma[GROUP_BUF_GAIN];
-				rkispp_write(dev, RKISPP_TNR_GAIN_NXT_Y_BASE, val);
-
-				if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM)
-					vdev->tnr.cur_rd = NULL;
-			}
-		}
-		is_start = true;
-	}
-
-	if (vdev->tnr.cur_wr && is_start) {
-		dbuf = vdev->tnr.cur_wr->dbuf[GROUP_BUF_PIC];
-		dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
-		val = dummy->dma_addr;
-		rkispp_write(dev, RKISPP_TNR_WR_Y_BASE, val);
-		val += vdev->tnr.uv_offset;
-		rkispp_write(dev, RKISPP_TNR_WR_UV_BASE, val);
-
-		dbuf = vdev->tnr.cur_wr->dbuf[GROUP_BUF_GAIN];
-		dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size);
-		val = dummy->dma_addr;
-		rkispp_write(dev, RKISPP_TNR_GAIN_WR_Y_BASE, val);
-	}
-
-	if (is_start) {
-		u32 seq = 0;
-
-		if (vdev->tnr.nxt_rd) {
-			seq = vdev->tnr.nxt_rd->frame_id;
-			if (vdev->tnr.cur_wr) {
-				vdev->tnr.cur_wr->frame_id = seq;
-				vdev->tnr.cur_wr->frame_timestamp =
-					vdev->tnr.nxt_rd->frame_timestamp;
-				vdev->tnr.cur_wr->is_move_judge =
-					vdev->tnr.nxt_rd->is_move_judge;
-			}
-			dev->stats_vdev[STATS_VDEV_TNR].frame_id = seq;
-		}
-
-		if (!dev->hw_dev->is_single)
-			rkispp_update_regs(dev, RKISPP_CTRL, RKISPP_TNR_CORE_WEIGHT);
-		writel(TNR_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
-
-		v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev,
-			 "TNR start seq:%d | Y_SHD nxt:0x%x cur:0x%x iir:0x%x wr:0x%x\n",
-			 seq, readl(base + RKISPP_TNR_NXT_Y_BASE_SHD),
-			 readl(base + RKISPP_TNR_CUR_Y_BASE_SHD),
-			 readl(base + RKISPP_TNR_IIR_Y_BASE_SHD),
-			 readl(base + RKISPP_TNR_WR_Y_BASE_SHD));
-
-		/* iir using previous tnr write frame */
-		rkispp_write(dev, RKISPP_TNR_IIR_Y_BASE,
-			     rkispp_read(dev, RKISPP_TNR_WR_Y_BASE));
-		rkispp_write(dev, RKISPP_TNR_IIR_UV_BASE,
-			     rkispp_read(dev, RKISPP_TNR_WR_UV_BASE));
-
-		rkispp_prepare_buffer(dev, &vdev->tnr.buf.gain_kg);
-
-		vdev->tnr.dbg.id = seq;
-		vdev->tnr.dbg.timestamp = ktime_get_ns();
-		if (monitor->is_en) {
-			monitor->tnr.time = vdev->tnr.dbg.interval / 1000 / 1000;
-			monitor->monitoring_module |= MONITOR_TNR;
-			monitor->tnr.is_err = false;
-			if (!completion_done(&monitor->tnr.cmpl))
-				complete(&monitor->tnr.cmpl);
-		}
-
-		if (rkispp_is_reg_withstream_global())
-			rkispp_find_regbuf_by_id(dev, &reg_buf, dev->dev_id, seq);
-		if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_TNR)) {
-			u32 offset, size;
-
-			offset = reg_buf->reg_size;
-			size = 4 + RKISPP_TNR_STATE - RKISPP_TNR_CTRL;
-			reg_buf->ispp_size[ISPP_ID_TNR] = size;
-			reg_buf->ispp_offset[ISPP_ID_TNR] = offset;
-			memcpy_fromio(&reg_buf->reg[offset], base + RKISPP_TNR_CTRL, size);
-
-			offset += size;
-			reg_buf->reg_size = offset;
-		}
-
-		if (!dev->hw_dev->is_shutdown)
-			writel(TNR_ST, base + RKISPP_CTRL_STRT);
-		vdev->tnr.is_end = false;
-	}
-
-restart_unlock:
-	spin_unlock_irqrestore(&monitor->lock, lock_flags1);
-end:
-	spin_unlock_irqrestore(&vdev->tnr.buf_lock, lock_flags);
-}
-
-int rkispp_get_tnrbuf_fd(struct rkispp_device *dev, struct rkispp_buf_idxfd *idxfd)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkisp_ispp_buf *dbufs;
-	struct rkispp_dummy_buffer *buf;
-	unsigned long lock_flags = 0;
-	int j, buf_idx, ret = 0;
-
-	spin_lock_irqsave(&vdev->tnr.buf_lock, lock_flags);
-	if (!vdev->tnr.is_buf_init) {
-		spin_unlock_irqrestore(&vdev->tnr.buf_lock, lock_flags);
-		ret = -EAGAIN;
-		return ret;
-	}
-	spin_unlock_irqrestore(&vdev->tnr.buf_lock, lock_flags);
-
-	buf_idx = 0;
-	list_for_each_entry(dbufs, &vdev->tnr.list_wr, list) {
-		for (j = 0; j < GROUP_BUF_MAX; j++) {
-			dbufs->dfd[j] = dma_buf_fd(dbufs->dbuf[j], O_CLOEXEC);
-			get_dma_buf(dbufs->dbuf[j]);
-			idxfd->index[buf_idx] = dbufs->didx[j];
-			idxfd->dmafd[buf_idx] = dbufs->dfd[j];
-			buf_idx++;
-		}
-	}
-
-	list_for_each_entry(dbufs, &vdev->tnr.list_rpt, list) {
-		for (j = 0; j < GROUP_BUF_MAX; j++) {
-			dbufs->dfd[j] = dma_buf_fd(dbufs->dbuf[j], O_CLOEXEC);
-			get_dma_buf(dbufs->dbuf[j]);
-			idxfd->index[buf_idx] = dbufs->didx[j];
-			idxfd->dmafd[buf_idx] = dbufs->dfd[j];
-			buf_idx++;
-		}
-	}
-
-	if (vdev->tnr.cur_wr) {
-		for (j = 0; j < GROUP_BUF_MAX; j++) {
-			vdev->tnr.cur_wr->dfd[j] = dma_buf_fd(vdev->tnr.cur_wr->dbuf[j], O_CLOEXEC);
-			get_dma_buf(vdev->tnr.cur_wr->dbuf[j]);
-			idxfd->index[buf_idx] = vdev->tnr.cur_wr->didx[j];
-			idxfd->dmafd[buf_idx] = vdev->tnr.cur_wr->dfd[j];
-			buf_idx++;
-		}
-	}
-
-	buf = &vdev->tnr.buf.gain_kg;
-	buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
-	get_dma_buf(buf->dbuf);
-	idxfd->index[buf_idx] = buf->index;
-	idxfd->dmafd[buf_idx] = buf->dma_fd;
-	buf_idx++;
-
-	idxfd->buf_num = buf_idx;
-
-	return ret;
-}
-
-int rkispp_get_nrbuf_fd(struct rkispp_device *dev, struct rkispp_buf_idxfd *idxfd)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	struct rkispp_dummy_buffer *buf;
-	unsigned long lock_flags = 0;
-	int i, ret = 0;
-
-	spin_lock_irqsave(&vdev->nr.buf_lock, lock_flags);
-	if (!vdev->nr.is_buf_init) {
-		spin_unlock_irqrestore(&vdev->nr.buf_lock, lock_flags);
-		ret = -EAGAIN;
-		return ret;
-	}
-	spin_unlock_irqrestore(&vdev->nr.buf_lock, lock_flags);
-
-	for (i = 0; i < RKISPP_FEC_BUF_MAX; i++) {
-		buf = &vdev->nr.buf.wr[i];
-		if (!buf->dbuf)
-			break;
-		buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
-		get_dma_buf(buf->dbuf);
-		idxfd->index[i] = i;
-		idxfd->dmafd[i] = buf->dma_fd;
-	}
-	idxfd->buf_num = i;
-	return ret;
-}
-
-void rkispp_set_trigger_mode(struct rkispp_device *dev,
-			     struct rkispp_trigger_mode *mode)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-
-	if (mode->module & ISPP_MODULE_TNR)
-		vdev->tnr.is_trigger = mode->on;
-}
-
-void rkispp_module_work_event(struct rkispp_device *dev,
-			      void *buf_rd, void *buf_wr,
-			      u32 module, bool is_isr)
-{
-	struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
-	bool is_fec_en = !!(vdev->module_ens & ISPP_MODULE_FEC);
-	bool is_single = dev->hw_dev->is_single;
-	//bool is_early = vdev->is_done_early;
-
-	if (dev->hw_dev->is_shutdown)
-		return;
-
-	if (dev->ispp_sdev.state != ISPP_STOP) {
-		if (module & ISPP_MODULE_TNR)
-			tnr_work_event(dev, buf_rd, buf_wr, is_isr);
-		else if (module & ISPP_MODULE_NR)
-			nr_work_event(dev, buf_rd, buf_wr, is_isr);
-		else
-			fec_work_event(dev, buf_rd, is_isr, false);
-	}
-
-	/*
-	 * ispp frame done to do next conditions
-	 * mulit dev: cur frame (tnr->nr->fec) done for next frame
-	 * 1.single dev: fec async with tnr, and sync with nr:
-	 *   {    f0    }
-	 *   tnr->nr->fec->|
-	 *          |->tnr->nr->fec
-	 *             {    f1    }
-	 * 2.single dev and early mode:
-	 *   {  f0 }  {  f1 }  {  f2 }
-	 *   tnr->nr->tnr->nr->tnr->nr
-	 *        |->fec->||->fec->|
-	 *        {   f0  }{   f1  }
-	 */
-	if (is_isr && !buf_rd && !buf_wr &&
-	    ((!is_fec_en && module == ISPP_MODULE_NR) ||
-	     (is_fec_en &&
-	      ((module == ISPP_MODULE_NR && (is_single ||
-		vdev->fec.is_end)) ||
-	       (module == ISPP_MODULE_FEC && !is_single && vdev->fec.is_end))))) {
-		dev->stream_vdev.monitor.retry = 0;
-		rkispp_soft_reset(dev->hw_dev);
-		rkispp_event_handle(dev, CMD_QUEUE_DMABUF, NULL);
-	}
-
-	if (dev->ispp_sdev.state == ISPP_STOP) {
-		if ((module & (ISPP_MODULE_TNR | ISPP_MODULE_NR)) && buf_rd) {
-			struct rkisp_ispp_buf *buf = buf_rd;
-
-			if (buf->is_isp)
-				v4l2_subdev_call(dev->ispp_sdev.remote_sd,
-						 video, s_rx_buffer, buf, NULL);
-		}
-		if (!dev->hw_dev->is_idle)
-			dev->hw_dev->is_idle = true;
-	}
 }
 
 void rkispp_isr(u32 mis_val, struct rkispp_device *dev)
@@ -3573,7 +1921,7 @@
 		INIT_WORK(&dev->irq_work, irq_work);
 		schedule_work(&dev->irq_work);
 	} else {
-		check_to_force_update(dev, mis_val);
+		vdev->stream_ops->check_to_force_update(dev, mis_val);
 	}
 }
 
@@ -3601,12 +1949,20 @@
 	stream_vdev->tnr.is_buf_init = false;
 	stream_vdev->nr.is_buf_init = false;
 
-	hrtimer_init(&stream_vdev->fec_qst, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	stream_vdev->fec_qst.function = rkispp_fec_do_early;
-	hrtimer_init(&stream_vdev->frame_qst, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	stream_vdev->frame_qst.function = rkispp_frame_done_early;
-
-	for (i = 0; i < STREAM_MAX; i++) {
+	if (dev->ispp_ver == ISPP_V10) {
+		dev->stream_max = STREAM_MAX;
+		rkispp_stream_init_ops_v10(stream_vdev);
+		hrtimer_init(&stream_vdev->fec_qst, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		stream_vdev->fec_qst.function = rkispp_fec_do_early;
+		hrtimer_init(&stream_vdev->frame_qst, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		stream_vdev->frame_qst.function = stream_vdev->stream_ops->rkispp_frame_done_early;
+		dev->hw_dev->pool[0].group_buf_max = GROUP_BUF_MAX;
+	} else if (dev->ispp_ver == ISPP_V20) {
+		dev->stream_max = STREAM_VIR + 1;
+		rkispp_stream_init_ops_v20(stream_vdev);
+		dev->hw_dev->pool[0].group_buf_max = GROUP_BUF_GAIN;
+	}
+	for (i = 0; i < dev->stream_max; i++) {
 		stream = &stream_vdev->stream[i];
 		stream->id = i;
 		stream->isppdev = dev;
@@ -3677,7 +2033,7 @@
 	int i;
 
 	stream_vdev = &dev->stream_vdev;
-	for (i = 0; i < STREAM_MAX; i++) {
+	for (i = 0; i < dev->stream_max; i++) {
 		stream = &stream_vdev->stream[i];
 		rkispp_unregister_stream_video(stream);
 	}

--
Gitblit v1.6.2