xref: /OK3568_Linux_fs/kernel/drivers/media/platform/rockchip/isp/capture.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright (c) 2020 Rockchip Electronics Co., Ltd. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/delay.h>
5*4882a593Smuzhiyun #include <linux/pm_runtime.h>
6*4882a593Smuzhiyun #include <media/v4l2-common.h>
7*4882a593Smuzhiyun #include <media/v4l2-event.h>
8*4882a593Smuzhiyun #include <media/v4l2-fh.h>
9*4882a593Smuzhiyun #include <media/v4l2-ioctl.h>
10*4882a593Smuzhiyun #include <media/v4l2-subdev.h>
11*4882a593Smuzhiyun #include <media/videobuf2-dma-contig.h>
12*4882a593Smuzhiyun #include "dev.h"
13*4882a593Smuzhiyun #include "regs.h"
14*4882a593Smuzhiyun #include "rkisp_tb_helper.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define STREAM_MAX_MP_RSZ_OUTPUT_WIDTH		4416
17*4882a593Smuzhiyun #define STREAM_MAX_MP_RSZ_OUTPUT_HEIGHT		3312
18*4882a593Smuzhiyun #define STREAM_MAX_SP_RSZ_OUTPUT_WIDTH		1920
19*4882a593Smuzhiyun #define STREAM_MAX_SP_RSZ_OUTPUT_HEIGHT		1080
20*4882a593Smuzhiyun #define STREAM_MIN_RSZ_OUTPUT_WIDTH		32
21*4882a593Smuzhiyun #define STREAM_MIN_RSZ_OUTPUT_HEIGHT		32
22*4882a593Smuzhiyun #define STREAM_OUTPUT_STEP_WISE			8
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define STREAM_MIN_MP_SP_INPUT_WIDTH		STREAM_MIN_RSZ_OUTPUT_WIDTH
25*4882a593Smuzhiyun #define STREAM_MIN_MP_SP_INPUT_HEIGHT		STREAM_MIN_RSZ_OUTPUT_HEIGHT
26*4882a593Smuzhiyun 
hdr_dma_frame(struct rkisp_device * dev)27*4882a593Smuzhiyun static int hdr_dma_frame(struct rkisp_device *dev)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	int max_dma;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	switch (dev->hdr.op_mode) {
32*4882a593Smuzhiyun 	case HDR_FRAMEX2_DDR:
33*4882a593Smuzhiyun 	case HDR_LINEX2_DDR:
34*4882a593Smuzhiyun 	case HDR_RDBK_FRAME1:
35*4882a593Smuzhiyun 		max_dma = 1;
36*4882a593Smuzhiyun 		break;
37*4882a593Smuzhiyun 	case HDR_FRAMEX3_DDR:
38*4882a593Smuzhiyun 	case HDR_LINEX3_DDR:
39*4882a593Smuzhiyun 	case HDR_RDBK_FRAME2:
40*4882a593Smuzhiyun 		max_dma = 2;
41*4882a593Smuzhiyun 		break;
42*4882a593Smuzhiyun 	case HDR_RDBK_FRAME3:
43*4882a593Smuzhiyun 		max_dma = HDR_DMA_MAX;
44*4882a593Smuzhiyun 		break;
45*4882a593Smuzhiyun 	case HDR_LINEX2_NO_DDR:
46*4882a593Smuzhiyun 	case HDR_NORMAL:
47*4882a593Smuzhiyun 	default:
48*4882a593Smuzhiyun 		max_dma = 0;
49*4882a593Smuzhiyun 	}
50*4882a593Smuzhiyun 	return max_dma;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
rkisp_create_hdr_buf(struct rkisp_device * dev)53*4882a593Smuzhiyun static int rkisp_create_hdr_buf(struct rkisp_device *dev)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	int i, j, max_dma, max_buf = 1;
56*4882a593Smuzhiyun 	struct rkisp_dummy_buffer *buf;
57*4882a593Smuzhiyun 	struct rkisp_stream *stream;
58*4882a593Smuzhiyun 	u32 size;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX0];
61*4882a593Smuzhiyun 	size = stream->out_fmt.plane_fmt[0].sizeimage;
62*4882a593Smuzhiyun 	max_dma = hdr_dma_frame(dev);
63*4882a593Smuzhiyun 	/* hdr read back mode using base and shd address
64*4882a593Smuzhiyun 	 * this support multi-buffer
65*4882a593Smuzhiyun 	 */
66*4882a593Smuzhiyun 	if (IS_HDR_RDBK(dev->hdr.op_mode)) {
67*4882a593Smuzhiyun 		if (!dev->dmarx_dev.trigger)
68*4882a593Smuzhiyun 			max_buf = HDR_MAX_DUMMY_BUF;
69*4882a593Smuzhiyun 		else
70*4882a593Smuzhiyun 			max_buf = 0;
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun 	for (i = 0; i < max_dma; i++) {
73*4882a593Smuzhiyun 		for (j = 0; j < max_buf; j++) {
74*4882a593Smuzhiyun 			buf = &dev->hdr.dummy_buf[i][j];
75*4882a593Smuzhiyun 			buf->size = size;
76*4882a593Smuzhiyun 			if (rkisp_alloc_buffer(dev, buf) < 0) {
77*4882a593Smuzhiyun 				v4l2_err(&dev->v4l2_dev,
78*4882a593Smuzhiyun 					"Failed to allocate the memory for hdr buffer\n");
79*4882a593Smuzhiyun 				return -ENOMEM;
80*4882a593Smuzhiyun 			}
81*4882a593Smuzhiyun 			hdr_qbuf(&dev->hdr.q_tx[i], buf);
82*4882a593Smuzhiyun 			v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
83*4882a593Smuzhiyun 				 "hdr buf[%d][%d]:0x%x\n",
84*4882a593Smuzhiyun 				 i, j, (u32)buf->dma_addr);
85*4882a593Smuzhiyun 		}
86*4882a593Smuzhiyun 		dev->hdr.index[i] = i;
87*4882a593Smuzhiyun 	}
88*4882a593Smuzhiyun 	/*
89*4882a593Smuzhiyun 	 * normal: q_tx[0] to dma0
90*4882a593Smuzhiyun 	 *	   q_tx[1] to dma1
91*4882a593Smuzhiyun 	 * rdbk1: using dma2
92*4882a593Smuzhiyun 		   q_tx[0] to dma2
93*4882a593Smuzhiyun 	 * rdbk2: using dma0 (as M), dma2 (as S)
94*4882a593Smuzhiyun 	 *	   q_tx[0] to dma0
95*4882a593Smuzhiyun 	 *	   q_tx[1] to dma2
96*4882a593Smuzhiyun 	 * rdbk3: using dma0 (as M), dam1 (as L), dma2 (as S)
97*4882a593Smuzhiyun 	 *	   q_tx[0] to dma0
98*4882a593Smuzhiyun 	 *	   q_tx[1] to dma1
99*4882a593Smuzhiyun 	 *	   q_tx[2] to dma2
100*4882a593Smuzhiyun 	 */
101*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_RDBK_FRAME1) {
102*4882a593Smuzhiyun 		dev->hdr.index[HDR_DMA2] = 0;
103*4882a593Smuzhiyun 		dev->hdr.index[HDR_DMA0] = 1;
104*4882a593Smuzhiyun 		dev->hdr.index[HDR_DMA1] = 2;
105*4882a593Smuzhiyun 	} else if (dev->hdr.op_mode == HDR_RDBK_FRAME2) {
106*4882a593Smuzhiyun 		dev->hdr.index[HDR_DMA0] = 0;
107*4882a593Smuzhiyun 		dev->hdr.index[HDR_DMA2] = 1;
108*4882a593Smuzhiyun 		dev->hdr.index[HDR_DMA1] = 2;
109*4882a593Smuzhiyun 	}
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
112*4882a593Smuzhiyun 		 "hdr:%d buf index dma0:%d dma1:%d dma2:%d\n",
113*4882a593Smuzhiyun 		 max_dma,
114*4882a593Smuzhiyun 		 dev->hdr.index[HDR_DMA0],
115*4882a593Smuzhiyun 		 dev->hdr.index[HDR_DMA1],
116*4882a593Smuzhiyun 		 dev->hdr.index[HDR_DMA2]);
117*4882a593Smuzhiyun 	return 0;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
hdr_destroy_buf(struct rkisp_device * dev)120*4882a593Smuzhiyun void hdr_destroy_buf(struct rkisp_device *dev)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	int i, j;
123*4882a593Smuzhiyun 	struct rkisp_dummy_buffer *buf;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	if (atomic_read(&dev->cap_dev.refcnt) > 1 ||
126*4882a593Smuzhiyun 	    !dev->active_sensor ||
127*4882a593Smuzhiyun 	    (dev->active_sensor &&
128*4882a593Smuzhiyun 	     dev->active_sensor->mbus.type != V4L2_MBUS_CSI2_DPHY) ||
129*4882a593Smuzhiyun 	    (dev->isp_inp & INP_CIF) ||
130*4882a593Smuzhiyun 	    (dev->isp_ver != ISP_V20 && dev->isp_ver != ISP_V21))
131*4882a593Smuzhiyun 		return;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	atomic_set(&dev->hdr.refcnt, 0);
134*4882a593Smuzhiyun 	for (i = 0; i < HDR_DMA_MAX; i++) {
135*4882a593Smuzhiyun 		buf = dev->hdr.rx_cur_buf[i];
136*4882a593Smuzhiyun 		if (buf) {
137*4882a593Smuzhiyun 			rkisp_free_buffer(dev, buf);
138*4882a593Smuzhiyun 			dev->hdr.rx_cur_buf[i] = NULL;
139*4882a593Smuzhiyun 		}
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 		for (j = 0; j < HDR_MAX_DUMMY_BUF; j++) {
142*4882a593Smuzhiyun 			buf = hdr_dqbuf(&dev->hdr.q_tx[i]);
143*4882a593Smuzhiyun 			if (buf)
144*4882a593Smuzhiyun 				rkisp_free_buffer(dev, buf);
145*4882a593Smuzhiyun 			buf = hdr_dqbuf(&dev->hdr.q_rx[i]);
146*4882a593Smuzhiyun 			if (buf)
147*4882a593Smuzhiyun 				rkisp_free_buffer(dev, buf);
148*4882a593Smuzhiyun 		}
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun 
hdr_update_dmatx_buf(struct rkisp_device * dev)152*4882a593Smuzhiyun int hdr_update_dmatx_buf(struct rkisp_device *dev)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	void __iomem *base = dev->base_addr;
155*4882a593Smuzhiyun 	struct rkisp_stream *dmatx;
156*4882a593Smuzhiyun 	struct rkisp_dummy_buffer *buf;
157*4882a593Smuzhiyun 	u8 i, index;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (!dev->active_sensor ||
160*4882a593Smuzhiyun 	    (dev->active_sensor &&
161*4882a593Smuzhiyun 	     dev->active_sensor->mbus.type != V4L2_MBUS_CSI2_DPHY) ||
162*4882a593Smuzhiyun 	    (dev->isp_inp & INP_CIF) ||
163*4882a593Smuzhiyun 	    (dev->isp_ver != ISP_V20 && dev->isp_ver != ISP_V21))
164*4882a593Smuzhiyun 		return 0;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	for (i = RKISP_STREAM_DMATX0; i <= RKISP_STREAM_DMATX2; i++) {
167*4882a593Smuzhiyun 		dmatx = &dev->cap_dev.stream[i];
168*4882a593Smuzhiyun 		if (dmatx->ops && dmatx->ops->frame_end)
169*4882a593Smuzhiyun 			dmatx->ops->frame_end(dmatx, FRAME_INIT);
170*4882a593Smuzhiyun 	}
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	if (dev->dmarx_dev.trigger)
173*4882a593Smuzhiyun 		goto end;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	/* for rawrd auto trigger mode, config first buf */
176*4882a593Smuzhiyun 	index = dev->hdr.index[HDR_DMA0];
177*4882a593Smuzhiyun 	buf = hdr_dqbuf(&dev->hdr.q_rx[index]);
178*4882a593Smuzhiyun 	if (buf) {
179*4882a593Smuzhiyun 		mi_raw0_rd_set_addr(base, buf->dma_addr);
180*4882a593Smuzhiyun 		dev->hdr.rx_cur_buf[index] = buf;
181*4882a593Smuzhiyun 	} else {
182*4882a593Smuzhiyun 		mi_raw0_rd_set_addr(base,
183*4882a593Smuzhiyun 			readl(base + MI_RAW0_WR_BASE_SHD));
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	index = dev->hdr.index[HDR_DMA1];
187*4882a593Smuzhiyun 	buf = hdr_dqbuf(&dev->hdr.q_rx[index]);
188*4882a593Smuzhiyun 	if (buf) {
189*4882a593Smuzhiyun 		mi_raw1_rd_set_addr(base, buf->dma_addr);
190*4882a593Smuzhiyun 		dev->hdr.rx_cur_buf[index] = buf;
191*4882a593Smuzhiyun 	} else {
192*4882a593Smuzhiyun 		mi_raw1_rd_set_addr(base,
193*4882a593Smuzhiyun 			readl(base + MI_RAW1_WR_BASE_SHD));
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	index = dev->hdr.index[HDR_DMA2];
197*4882a593Smuzhiyun 	buf = hdr_dqbuf(&dev->hdr.q_rx[index]);
198*4882a593Smuzhiyun 	if (buf) {
199*4882a593Smuzhiyun 		mi_raw2_rd_set_addr(base, buf->dma_addr);
200*4882a593Smuzhiyun 		dev->hdr.rx_cur_buf[index] = buf;
201*4882a593Smuzhiyun 	} else {
202*4882a593Smuzhiyun 		mi_raw2_rd_set_addr(base,
203*4882a593Smuzhiyun 			readl(base + MI_RAW2_WR_BASE_SHD));
204*4882a593Smuzhiyun 	}
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun end:
207*4882a593Smuzhiyun 	v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
208*4882a593Smuzhiyun 		 "CSI2RX CTRL0:0x%x CTRL1:0x%x\n"
209*4882a593Smuzhiyun 		 "WR CTRL RAW0:0x%x RAW1:0x%x RAW2:0x%x\n"
210*4882a593Smuzhiyun 		 "RD CTRL:0x%x\n",
211*4882a593Smuzhiyun 		 readl(base + CSI2RX_CTRL0),
212*4882a593Smuzhiyun 		 readl(base + CSI2RX_CTRL1),
213*4882a593Smuzhiyun 		 readl(base + CSI2RX_RAW0_WR_CTRL),
214*4882a593Smuzhiyun 		 readl(base + CSI2RX_RAW1_WR_CTRL),
215*4882a593Smuzhiyun 		 readl(base + CSI2RX_RAW2_WR_CTRL),
216*4882a593Smuzhiyun 		 readl(base + CSI2RX_RAW_RD_CTRL));
217*4882a593Smuzhiyun 	return 0;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
hdr_config_dmatx(struct rkisp_device * dev)220*4882a593Smuzhiyun int hdr_config_dmatx(struct rkisp_device *dev)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct rkisp_stream *stream;
223*4882a593Smuzhiyun 	struct v4l2_pix_format_mplane pixm;
224*4882a593Smuzhiyun 	u32 memory = 0;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	if (atomic_inc_return(&dev->hdr.refcnt) > 1 ||
227*4882a593Smuzhiyun 	    !dev->active_sensor ||
228*4882a593Smuzhiyun 	    (dev->active_sensor &&
229*4882a593Smuzhiyun 	     dev->active_sensor->mbus.type != V4L2_MBUS_CSI2_DPHY) ||
230*4882a593Smuzhiyun 	    (dev->isp_inp & INP_CIF) ||
231*4882a593Smuzhiyun 	    (dev->isp_ver != ISP_V20 && dev->isp_ver != ISP_V21))
232*4882a593Smuzhiyun 		return 0;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	rkisp_create_hdr_buf(dev);
235*4882a593Smuzhiyun 	memset(&pixm, 0, sizeof(pixm));
236*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_FRAMEX2_DDR ||
237*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_LINEX2_DDR ||
238*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_FRAMEX3_DDR ||
239*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_LINEX3_DDR ||
240*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME2 ||
241*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME3) {
242*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX0];
243*4882a593Smuzhiyun 		if (stream->ops && stream->ops->config_mi)
244*4882a593Smuzhiyun 			stream->ops->config_mi(stream);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 		if (!dev->dmarx_dev.trigger) {
247*4882a593Smuzhiyun 			pixm = stream->out_fmt;
248*4882a593Smuzhiyun 			stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0];
249*4882a593Smuzhiyun 			rkisp_dmarx_set_fmt(stream, pixm);
250*4882a593Smuzhiyun 			mi_raw_length(stream);
251*4882a593Smuzhiyun 		}
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_FRAMEX3_DDR ||
254*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_LINEX3_DDR ||
255*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME3) {
256*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX1];
257*4882a593Smuzhiyun 		if (stream->ops && stream->ops->config_mi)
258*4882a593Smuzhiyun 			stream->ops->config_mi(stream);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 		if (!dev->dmarx_dev.trigger) {
261*4882a593Smuzhiyun 			pixm = stream->out_fmt;
262*4882a593Smuzhiyun 			stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1];
263*4882a593Smuzhiyun 			rkisp_dmarx_set_fmt(stream, pixm);
264*4882a593Smuzhiyun 			mi_raw_length(stream);
265*4882a593Smuzhiyun 		}
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_RDBK_FRAME1 ||
268*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME2 ||
269*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME3) {
270*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX2];
271*4882a593Smuzhiyun 		if (stream->ops && stream->ops->config_mi)
272*4882a593Smuzhiyun 			stream->ops->config_mi(stream);
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 		if (!dev->dmarx_dev.trigger) {
275*4882a593Smuzhiyun 			memory = stream->memory;
276*4882a593Smuzhiyun 			pixm = stream->out_fmt;
277*4882a593Smuzhiyun 			stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2];
278*4882a593Smuzhiyun 			rkisp_dmarx_set_fmt(stream, pixm);
279*4882a593Smuzhiyun 			stream->ops->config_mi(stream);
280*4882a593Smuzhiyun 		}
281*4882a593Smuzhiyun 	}
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	if (dev->hdr.op_mode != HDR_NORMAL && !dev->dmarx_dev.trigger) {
284*4882a593Smuzhiyun 		raw_rd_ctrl(dev->base_addr, memory << 2);
285*4882a593Smuzhiyun 		if (pixm.width && pixm.height)
286*4882a593Smuzhiyun 			rkisp_rawrd_set_pic_size(dev, pixm.width, pixm.height);
287*4882a593Smuzhiyun 	}
288*4882a593Smuzhiyun 	return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun 
hdr_stop_dmatx(struct rkisp_device * dev)291*4882a593Smuzhiyun void hdr_stop_dmatx(struct rkisp_device *dev)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun 	struct rkisp_stream *stream;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	if (atomic_dec_return(&dev->hdr.refcnt) ||
296*4882a593Smuzhiyun 	    !dev->active_sensor ||
297*4882a593Smuzhiyun 	    (dev->active_sensor &&
298*4882a593Smuzhiyun 	     dev->active_sensor->mbus.type != V4L2_MBUS_CSI2_DPHY) ||
299*4882a593Smuzhiyun 	    (dev->isp_inp & INP_CIF) ||
300*4882a593Smuzhiyun 	    (dev->isp_ver != ISP_V20 && dev->isp_ver != ISP_V21))
301*4882a593Smuzhiyun 		return;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_FRAMEX2_DDR ||
304*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_LINEX2_DDR ||
305*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_FRAMEX3_DDR ||
306*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_LINEX3_DDR ||
307*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME2 ||
308*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME3) {
309*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX0];
310*4882a593Smuzhiyun 		stream->ops->stop_mi(stream);
311*4882a593Smuzhiyun 	}
312*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_FRAMEX3_DDR ||
313*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_LINEX3_DDR ||
314*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME3) {
315*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX1];
316*4882a593Smuzhiyun 		stream->ops->stop_mi(stream);
317*4882a593Smuzhiyun 	}
318*4882a593Smuzhiyun 	if (dev->hdr.op_mode == HDR_RDBK_FRAME1 ||
319*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME2 ||
320*4882a593Smuzhiyun 	    dev->hdr.op_mode == HDR_RDBK_FRAME3) {
321*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[RKISP_STREAM_DMATX2];
322*4882a593Smuzhiyun 		stream->ops->stop_mi(stream);
323*4882a593Smuzhiyun 	}
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
hdr_dqbuf(struct list_head * q)326*4882a593Smuzhiyun struct rkisp_dummy_buffer *hdr_dqbuf(struct list_head *q)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	struct rkisp_dummy_buffer *buf = NULL;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	if (!list_empty(q)) {
331*4882a593Smuzhiyun 		buf = list_first_entry(q,
332*4882a593Smuzhiyun 			struct rkisp_dummy_buffer, queue);
333*4882a593Smuzhiyun 		list_del(&buf->queue);
334*4882a593Smuzhiyun 	}
335*4882a593Smuzhiyun 	return buf;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
hdr_qbuf(struct list_head * q,struct rkisp_dummy_buffer * buf)338*4882a593Smuzhiyun void hdr_qbuf(struct list_head *q,
339*4882a593Smuzhiyun 	      struct rkisp_dummy_buffer *buf)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun 	if (buf)
342*4882a593Smuzhiyun 		list_add_tail(&buf->queue, q);
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun 
rkisp_config_dmatx_valid_buf(struct rkisp_device * dev)345*4882a593Smuzhiyun void rkisp_config_dmatx_valid_buf(struct rkisp_device *dev)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	struct rkisp_hw_dev *hw = dev->hw_dev;
348*4882a593Smuzhiyun 	struct rkisp_stream *stream;
349*4882a593Smuzhiyun 	struct rkisp_device *isp;
350*4882a593Smuzhiyun 	u32 i, j;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	if (!hw->dummy_buf.mem_priv ||
353*4882a593Smuzhiyun 	    !dev->active_sensor ||
354*4882a593Smuzhiyun 	    (dev->active_sensor &&
355*4882a593Smuzhiyun 	     dev->active_sensor->mbus.type != V4L2_MBUS_CSI2_DPHY) ||
356*4882a593Smuzhiyun 	    (dev->isp_inp & INP_CIF) ||
357*4882a593Smuzhiyun 	    (dev->isp_ver != ISP_V20 && dev->isp_ver != ISP_V21))
358*4882a593Smuzhiyun 		return;
359*4882a593Smuzhiyun 	/* dmatx buf update by mi force or oneself frame end,
360*4882a593Smuzhiyun 	 * for async dmatx enable need to update to valid buf first.
361*4882a593Smuzhiyun 	 */
362*4882a593Smuzhiyun 	for (i = 0; i < hw->dev_num; i++) {
363*4882a593Smuzhiyun 		isp = hw->isp[i];
364*4882a593Smuzhiyun 		if (!isp ||
365*4882a593Smuzhiyun 		    (isp && !(isp->isp_inp & INP_CSI)))
366*4882a593Smuzhiyun 			continue;
367*4882a593Smuzhiyun 		for (j = RKISP_STREAM_DMATX0; j < RKISP_MAX_STREAM; j++) {
368*4882a593Smuzhiyun 			stream = &isp->cap_dev.stream[j];
369*4882a593Smuzhiyun 			if (!stream->linked || stream->curr_buf || stream->next_buf)
370*4882a593Smuzhiyun 				continue;
371*4882a593Smuzhiyun 			mi_set_y_addr(stream, hw->dummy_buf.dma_addr);
372*4882a593Smuzhiyun 		}
373*4882a593Smuzhiyun 	}
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun /* Get xsubs and ysubs for fourcc formats
377*4882a593Smuzhiyun  *
378*4882a593Smuzhiyun  * @xsubs: horizontal color samples in a 4*4 matrix, for yuv
379*4882a593Smuzhiyun  * @ysubs: vertical color samples in a 4*4 matrix, for yuv
380*4882a593Smuzhiyun  */
rkisp_fcc_xysubs(u32 fcc,u32 * xsubs,u32 * ysubs)381*4882a593Smuzhiyun int rkisp_fcc_xysubs(u32 fcc, u32 *xsubs, u32 *ysubs)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun 	switch (fcc) {
384*4882a593Smuzhiyun 	case V4L2_PIX_FMT_GREY:
385*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV444M:
386*4882a593Smuzhiyun 		*xsubs = 1;
387*4882a593Smuzhiyun 		*ysubs = 1;
388*4882a593Smuzhiyun 		break;
389*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUYV:
390*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YVYU:
391*4882a593Smuzhiyun 	case V4L2_PIX_FMT_VYUY:
392*4882a593Smuzhiyun 	case V4L2_PIX_FMT_UYVY:
393*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV422P:
394*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV16:
395*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV61:
396*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YVU422M:
397*4882a593Smuzhiyun 	case V4L2_PIX_FMT_FBC2:
398*4882a593Smuzhiyun 		*xsubs = 2;
399*4882a593Smuzhiyun 		*ysubs = 1;
400*4882a593Smuzhiyun 		break;
401*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV21:
402*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV12:
403*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV21M:
404*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV12M:
405*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV420:
406*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YVU420:
407*4882a593Smuzhiyun 	case V4L2_PIX_FMT_FBCG:
408*4882a593Smuzhiyun 	case V4L2_PIX_FMT_FBC0:
409*4882a593Smuzhiyun 		*xsubs = 2;
410*4882a593Smuzhiyun 		*ysubs = 2;
411*4882a593Smuzhiyun 		break;
412*4882a593Smuzhiyun 	default:
413*4882a593Smuzhiyun 		return -EINVAL;
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	return 0;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
rkisp_mbus_code_xysubs(u32 code,u32 * xsubs,u32 * ysubs)419*4882a593Smuzhiyun int rkisp_mbus_code_xysubs(u32 code, u32 *xsubs, u32 *ysubs)
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun 	switch (code) {
422*4882a593Smuzhiyun 	case MEDIA_BUS_FMT_YUYV8_2X8:
423*4882a593Smuzhiyun 	case MEDIA_BUS_FMT_YUYV8_1X16:
424*4882a593Smuzhiyun 	case MEDIA_BUS_FMT_YVYU8_1X16:
425*4882a593Smuzhiyun 	case MEDIA_BUS_FMT_UYVY8_1X16:
426*4882a593Smuzhiyun 	case MEDIA_BUS_FMT_VYUY8_1X16:
427*4882a593Smuzhiyun 		*xsubs = 2;
428*4882a593Smuzhiyun 		*ysubs = 1;
429*4882a593Smuzhiyun 		break;
430*4882a593Smuzhiyun 	default:
431*4882a593Smuzhiyun 		return -EINVAL;
432*4882a593Smuzhiyun 	}
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	return 0;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun 
rkisp_stream_frame_start(struct rkisp_device * dev,u32 isp_mis)437*4882a593Smuzhiyun int rkisp_stream_frame_start(struct rkisp_device *dev, u32 isp_mis)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 	struct rkisp_stream *stream;
440*4882a593Smuzhiyun 	int i;
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	if (isp_mis)
443*4882a593Smuzhiyun 		rkisp_dvbm_event(dev, CIF_ISP_V_START);
444*4882a593Smuzhiyun 	rkisp_bridge_update_mi(dev, isp_mis);
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	for (i = 0; i < RKISP_MAX_STREAM; i++) {
447*4882a593Smuzhiyun 		if (i == RKISP_STREAM_VIR || i == RKISP_STREAM_LUMA)
448*4882a593Smuzhiyun 			continue;
449*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[i];
450*4882a593Smuzhiyun 		if (stream->streaming &&
451*4882a593Smuzhiyun 		    stream->ops && stream->ops->frame_start)
452*4882a593Smuzhiyun 			stream->ops->frame_start(stream, isp_mis);
453*4882a593Smuzhiyun 	}
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	return 0;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
rkisp_stream_buf_done_early(struct rkisp_device * dev)458*4882a593Smuzhiyun void rkisp_stream_buf_done_early(struct rkisp_device *dev)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun 	struct rkisp_stream *stream;
461*4882a593Smuzhiyun 	int i;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	if (!dev->cap_dev.is_done_early)
464*4882a593Smuzhiyun 		return;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	for (i = 0; i < RKISP_MAX_STREAM; i++) {
467*4882a593Smuzhiyun 		if (i == RKISP_STREAM_VIR || i == RKISP_STREAM_LUMA ||
468*4882a593Smuzhiyun 		    i == RKISP_STREAM_DMATX0 || i == RKISP_STREAM_DMATX1 ||
469*4882a593Smuzhiyun 		    i == RKISP_STREAM_DMATX2 || i == RKISP_STREAM_DMATX3)
470*4882a593Smuzhiyun 			continue;
471*4882a593Smuzhiyun 		stream = &dev->cap_dev.stream[i];
472*4882a593Smuzhiyun 		if (stream->streaming && !stream->stopping &&
473*4882a593Smuzhiyun 		    stream->ops && stream->ops->frame_end)
474*4882a593Smuzhiyun 			stream->ops->frame_end(stream, FRAME_WORK);
475*4882a593Smuzhiyun 	}
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun struct stream_config rkisp_mp_stream_config = {
479*4882a593Smuzhiyun 	/* constraints */
480*4882a593Smuzhiyun 	.max_rsz_width = STREAM_MAX_MP_RSZ_OUTPUT_WIDTH,
481*4882a593Smuzhiyun 	.max_rsz_height = STREAM_MAX_MP_RSZ_OUTPUT_HEIGHT,
482*4882a593Smuzhiyun 	.min_rsz_width = STREAM_MIN_RSZ_OUTPUT_WIDTH,
483*4882a593Smuzhiyun 	.min_rsz_height = STREAM_MIN_RSZ_OUTPUT_HEIGHT,
484*4882a593Smuzhiyun 	.frame_end_id = CIF_MI_MP_FRAME,
485*4882a593Smuzhiyun 	/* registers */
486*4882a593Smuzhiyun 	.rsz = {
487*4882a593Smuzhiyun 		.ctrl = CIF_MRSZ_CTRL,
488*4882a593Smuzhiyun 		.scale_hy = CIF_MRSZ_SCALE_HY,
489*4882a593Smuzhiyun 		.scale_hcr = CIF_MRSZ_SCALE_HCR,
490*4882a593Smuzhiyun 		.scale_hcb = CIF_MRSZ_SCALE_HCB,
491*4882a593Smuzhiyun 		.scale_vy = CIF_MRSZ_SCALE_VY,
492*4882a593Smuzhiyun 		.scale_vc = CIF_MRSZ_SCALE_VC,
493*4882a593Smuzhiyun 		.scale_lut = CIF_MRSZ_SCALE_LUT,
494*4882a593Smuzhiyun 		.scale_lut_addr = CIF_MRSZ_SCALE_LUT_ADDR,
495*4882a593Smuzhiyun 		.scale_hy_shd = CIF_MRSZ_SCALE_HY_SHD,
496*4882a593Smuzhiyun 		.scale_hcr_shd = CIF_MRSZ_SCALE_HCR_SHD,
497*4882a593Smuzhiyun 		.scale_hcb_shd = CIF_MRSZ_SCALE_HCB_SHD,
498*4882a593Smuzhiyun 		.scale_vy_shd = CIF_MRSZ_SCALE_VY_SHD,
499*4882a593Smuzhiyun 		.scale_vc_shd = CIF_MRSZ_SCALE_VC_SHD,
500*4882a593Smuzhiyun 		.phase_hy = CIF_MRSZ_PHASE_HY,
501*4882a593Smuzhiyun 		.phase_hc = CIF_MRSZ_PHASE_HC,
502*4882a593Smuzhiyun 		.phase_vy = CIF_MRSZ_PHASE_VY,
503*4882a593Smuzhiyun 		.phase_vc = CIF_MRSZ_PHASE_VC,
504*4882a593Smuzhiyun 		.ctrl_shd = CIF_MRSZ_CTRL_SHD,
505*4882a593Smuzhiyun 		.phase_hy_shd = CIF_MRSZ_PHASE_HY_SHD,
506*4882a593Smuzhiyun 		.phase_hc_shd = CIF_MRSZ_PHASE_HC_SHD,
507*4882a593Smuzhiyun 		.phase_vy_shd = CIF_MRSZ_PHASE_VY_SHD,
508*4882a593Smuzhiyun 		.phase_vc_shd = CIF_MRSZ_PHASE_VC_SHD,
509*4882a593Smuzhiyun 	},
510*4882a593Smuzhiyun 	.dual_crop = {
511*4882a593Smuzhiyun 		.ctrl = CIF_DUAL_CROP_CTRL,
512*4882a593Smuzhiyun 		.yuvmode_mask = CIF_DUAL_CROP_MP_MODE_YUV,
513*4882a593Smuzhiyun 		.rawmode_mask = CIF_DUAL_CROP_MP_MODE_RAW,
514*4882a593Smuzhiyun 		.h_offset = CIF_DUAL_CROP_M_H_OFFS,
515*4882a593Smuzhiyun 		.v_offset = CIF_DUAL_CROP_M_V_OFFS,
516*4882a593Smuzhiyun 		.h_size = CIF_DUAL_CROP_M_H_SIZE,
517*4882a593Smuzhiyun 		.v_size = CIF_DUAL_CROP_M_V_SIZE,
518*4882a593Smuzhiyun 	},
519*4882a593Smuzhiyun 	.mi = {
520*4882a593Smuzhiyun 		.y_size_init = CIF_MI_MP_Y_SIZE_INIT,
521*4882a593Smuzhiyun 		.cb_size_init = CIF_MI_MP_CB_SIZE_INIT,
522*4882a593Smuzhiyun 		.cr_size_init = CIF_MI_MP_CR_SIZE_INIT,
523*4882a593Smuzhiyun 		.y_base_ad_init = CIF_MI_MP_Y_BASE_AD_INIT,
524*4882a593Smuzhiyun 		.cb_base_ad_init = CIF_MI_MP_CB_BASE_AD_INIT,
525*4882a593Smuzhiyun 		.cr_base_ad_init = CIF_MI_MP_CR_BASE_AD_INIT,
526*4882a593Smuzhiyun 		.y_offs_cnt_init = CIF_MI_MP_Y_OFFS_CNT_INIT,
527*4882a593Smuzhiyun 		.cb_offs_cnt_init = CIF_MI_MP_CB_OFFS_CNT_INIT,
528*4882a593Smuzhiyun 		.cr_offs_cnt_init = CIF_MI_MP_CR_OFFS_CNT_INIT,
529*4882a593Smuzhiyun 		.y_base_ad_shd = CIF_MI_MP_Y_BASE_AD_SHD,
530*4882a593Smuzhiyun 		.y_pic_size = ISP3X_MI_MP_WR_Y_PIC_SIZE,
531*4882a593Smuzhiyun 	},
532*4882a593Smuzhiyun };
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun struct stream_config rkisp_sp_stream_config = {
535*4882a593Smuzhiyun 	/* constraints */
536*4882a593Smuzhiyun 	.max_rsz_width = STREAM_MAX_SP_RSZ_OUTPUT_WIDTH,
537*4882a593Smuzhiyun 	.max_rsz_height = STREAM_MAX_SP_RSZ_OUTPUT_HEIGHT,
538*4882a593Smuzhiyun 	.min_rsz_width = STREAM_MIN_RSZ_OUTPUT_WIDTH,
539*4882a593Smuzhiyun 	.min_rsz_height = STREAM_MIN_RSZ_OUTPUT_HEIGHT,
540*4882a593Smuzhiyun 	.frame_end_id = CIF_MI_SP_FRAME,
541*4882a593Smuzhiyun 	/* registers */
542*4882a593Smuzhiyun 	.rsz = {
543*4882a593Smuzhiyun 		.ctrl = CIF_SRSZ_CTRL,
544*4882a593Smuzhiyun 		.scale_hy = CIF_SRSZ_SCALE_HY,
545*4882a593Smuzhiyun 		.scale_hcr = CIF_SRSZ_SCALE_HCR,
546*4882a593Smuzhiyun 		.scale_hcb = CIF_SRSZ_SCALE_HCB,
547*4882a593Smuzhiyun 		.scale_vy = CIF_SRSZ_SCALE_VY,
548*4882a593Smuzhiyun 		.scale_vc = CIF_SRSZ_SCALE_VC,
549*4882a593Smuzhiyun 		.scale_lut = CIF_SRSZ_SCALE_LUT,
550*4882a593Smuzhiyun 		.scale_lut_addr = CIF_SRSZ_SCALE_LUT_ADDR,
551*4882a593Smuzhiyun 		.scale_hy_shd = CIF_SRSZ_SCALE_HY_SHD,
552*4882a593Smuzhiyun 		.scale_hcr_shd = CIF_SRSZ_SCALE_HCR_SHD,
553*4882a593Smuzhiyun 		.scale_hcb_shd = CIF_SRSZ_SCALE_HCB_SHD,
554*4882a593Smuzhiyun 		.scale_vy_shd = CIF_SRSZ_SCALE_VY_SHD,
555*4882a593Smuzhiyun 		.scale_vc_shd = CIF_SRSZ_SCALE_VC_SHD,
556*4882a593Smuzhiyun 		.phase_hy = CIF_SRSZ_PHASE_HY,
557*4882a593Smuzhiyun 		.phase_hc = CIF_SRSZ_PHASE_HC,
558*4882a593Smuzhiyun 		.phase_vy = CIF_SRSZ_PHASE_VY,
559*4882a593Smuzhiyun 		.phase_vc = CIF_SRSZ_PHASE_VC,
560*4882a593Smuzhiyun 		.ctrl_shd = CIF_SRSZ_CTRL_SHD,
561*4882a593Smuzhiyun 		.phase_hy_shd = CIF_SRSZ_PHASE_HY_SHD,
562*4882a593Smuzhiyun 		.phase_hc_shd = CIF_SRSZ_PHASE_HC_SHD,
563*4882a593Smuzhiyun 		.phase_vy_shd = CIF_SRSZ_PHASE_VY_SHD,
564*4882a593Smuzhiyun 		.phase_vc_shd = CIF_SRSZ_PHASE_VC_SHD,
565*4882a593Smuzhiyun 	},
566*4882a593Smuzhiyun 	.dual_crop = {
567*4882a593Smuzhiyun 		.ctrl = CIF_DUAL_CROP_CTRL,
568*4882a593Smuzhiyun 		.yuvmode_mask = CIF_DUAL_CROP_SP_MODE_YUV,
569*4882a593Smuzhiyun 		.rawmode_mask = CIF_DUAL_CROP_SP_MODE_RAW,
570*4882a593Smuzhiyun 		.h_offset = CIF_DUAL_CROP_S_H_OFFS,
571*4882a593Smuzhiyun 		.v_offset = CIF_DUAL_CROP_S_V_OFFS,
572*4882a593Smuzhiyun 		.h_size = CIF_DUAL_CROP_S_H_SIZE,
573*4882a593Smuzhiyun 		.v_size = CIF_DUAL_CROP_S_V_SIZE,
574*4882a593Smuzhiyun 	},
575*4882a593Smuzhiyun 	.mi = {
576*4882a593Smuzhiyun 		.y_size_init = CIF_MI_SP_Y_SIZE_INIT,
577*4882a593Smuzhiyun 		.cb_size_init = CIF_MI_SP_CB_SIZE_INIT,
578*4882a593Smuzhiyun 		.cr_size_init = CIF_MI_SP_CR_SIZE_INIT,
579*4882a593Smuzhiyun 		.y_base_ad_init = CIF_MI_SP_Y_BASE_AD_INIT,
580*4882a593Smuzhiyun 		.cb_base_ad_init = CIF_MI_SP_CB_BASE_AD_INIT,
581*4882a593Smuzhiyun 		.cr_base_ad_init = CIF_MI_SP_CR_BASE_AD_INIT,
582*4882a593Smuzhiyun 		.y_offs_cnt_init = CIF_MI_SP_Y_OFFS_CNT_INIT,
583*4882a593Smuzhiyun 		.cb_offs_cnt_init = CIF_MI_SP_CB_OFFS_CNT_INIT,
584*4882a593Smuzhiyun 		.cr_offs_cnt_init = CIF_MI_SP_CR_OFFS_CNT_INIT,
585*4882a593Smuzhiyun 		.y_base_ad_shd = CIF_MI_SP_Y_BASE_AD_SHD,
586*4882a593Smuzhiyun 		.y_pic_size = ISP3X_MI_SP_WR_Y_PIC_SIZE,
587*4882a593Smuzhiyun 	},
588*4882a593Smuzhiyun };
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun static const
find_fmt(struct rkisp_stream * stream,const u32 pixelfmt)591*4882a593Smuzhiyun struct capture_fmt *find_fmt(struct rkisp_stream *stream, const u32 pixelfmt)
592*4882a593Smuzhiyun {
593*4882a593Smuzhiyun 	const struct capture_fmt *fmt;
594*4882a593Smuzhiyun 	int i;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	for (i = 0; i < stream->config->fmt_size; i++) {
597*4882a593Smuzhiyun 		fmt = &stream->config->fmts[i];
598*4882a593Smuzhiyun 		if (fmt->fourcc == pixelfmt)
599*4882a593Smuzhiyun 			return fmt;
600*4882a593Smuzhiyun 	}
601*4882a593Smuzhiyun 	return NULL;
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun 
restrict_rsz_resolution(struct rkisp_stream * stream,const struct stream_config * cfg,struct v4l2_rect * max_rsz)604*4882a593Smuzhiyun static void restrict_rsz_resolution(struct rkisp_stream *stream,
605*4882a593Smuzhiyun 				    const struct stream_config *cfg,
606*4882a593Smuzhiyun 				    struct v4l2_rect *max_rsz)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
609*4882a593Smuzhiyun 	struct v4l2_rect *input_win = rkisp_get_isp_sd_win(&dev->isp_sdev);
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	if (stream->id == RKISP_STREAM_VIR ||
612*4882a593Smuzhiyun 	    (dev->isp_ver == ISP_V30 && stream->id == RKISP_STREAM_BP)) {
613*4882a593Smuzhiyun 		max_rsz->width = input_win->width;
614*4882a593Smuzhiyun 		max_rsz->height = input_win->height;
615*4882a593Smuzhiyun 	} else if (stream->id == RKISP_STREAM_FBC) {
616*4882a593Smuzhiyun 		max_rsz->width = stream->dcrop.width;
617*4882a593Smuzhiyun 		max_rsz->height = stream->dcrop.height;
618*4882a593Smuzhiyun 	} else if (stream->id == RKISP_STREAM_MPDS ||
619*4882a593Smuzhiyun 		   stream->id == RKISP_STREAM_BPDS) {
620*4882a593Smuzhiyun 		struct rkisp_stream *t = &dev->cap_dev.stream[stream->conn_id];
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 		max_rsz->width = t->out_fmt.width / 4;
623*4882a593Smuzhiyun 		max_rsz->height = t->out_fmt.height / 4;
624*4882a593Smuzhiyun 	} else if (stream->id == RKISP_STREAM_LUMA) {
625*4882a593Smuzhiyun 		u32 div = dev->is_bigmode ? 32 : 16;
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 		max_rsz->width = ALIGN(DIV_ROUND_UP(input_win->width, div), 4);
628*4882a593Smuzhiyun 		max_rsz->height = DIV_ROUND_UP(input_win->height, div);
629*4882a593Smuzhiyun 	} else if (dev->hw_dev->is_unite) {
630*4882a593Smuzhiyun 		/* scale down only for unite mode */
631*4882a593Smuzhiyun 		max_rsz->width = min_t(int, input_win->width, cfg->max_rsz_width);
632*4882a593Smuzhiyun 		max_rsz->height = min_t(int, input_win->height, cfg->max_rsz_height);
633*4882a593Smuzhiyun 	} else {
634*4882a593Smuzhiyun 		/* scale up/down */
635*4882a593Smuzhiyun 		max_rsz->width = cfg->max_rsz_width;
636*4882a593Smuzhiyun 		max_rsz->height = cfg->max_rsz_height;
637*4882a593Smuzhiyun 	}
638*4882a593Smuzhiyun }
639*4882a593Smuzhiyun 
rkisp_set_fmt(struct rkisp_stream * stream,struct v4l2_pix_format_mplane * pixm,bool try)640*4882a593Smuzhiyun static int rkisp_set_fmt(struct rkisp_stream *stream,
641*4882a593Smuzhiyun 			   struct v4l2_pix_format_mplane *pixm,
642*4882a593Smuzhiyun 			   bool try)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun 	const struct capture_fmt *fmt;
645*4882a593Smuzhiyun 	struct rkisp_vdev_node *node = &stream->vnode;
646*4882a593Smuzhiyun 	const struct stream_config *config = stream->config;
647*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
648*4882a593Smuzhiyun 	struct v4l2_rect max_rsz;
649*4882a593Smuzhiyun 	u32 i, planes, imagsize = 0, xsubs = 1, ysubs = 1;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	fmt = find_fmt(stream, pixm->pixelformat);
652*4882a593Smuzhiyun 	if (!fmt) {
653*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev,
654*4882a593Smuzhiyun 			 "%s nonsupport pixelformat:%c%c%c%c\n",
655*4882a593Smuzhiyun 			 node->vdev.name,
656*4882a593Smuzhiyun 			 pixm->pixelformat,
657*4882a593Smuzhiyun 			 pixm->pixelformat >> 8,
658*4882a593Smuzhiyun 			 pixm->pixelformat >> 16,
659*4882a593Smuzhiyun 			 pixm->pixelformat >> 24);
660*4882a593Smuzhiyun 		return -EINVAL;
661*4882a593Smuzhiyun 	}
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	/* do checks on resolution */
664*4882a593Smuzhiyun 	restrict_rsz_resolution(stream, config, &max_rsz);
665*4882a593Smuzhiyun 	if (stream->id == RKISP_STREAM_MP ||
666*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_SP ||
667*4882a593Smuzhiyun 	    (stream->id == RKISP_STREAM_BP && dev->isp_ver != ISP_V30)) {
668*4882a593Smuzhiyun 		pixm->width = clamp_t(u32, pixm->width, config->min_rsz_width, max_rsz.width);
669*4882a593Smuzhiyun 	} else if (pixm->width != max_rsz.width &&
670*4882a593Smuzhiyun 		   pixm->height != max_rsz.height &&
671*4882a593Smuzhiyun 		   (stream->id == RKISP_STREAM_LUMA ||
672*4882a593Smuzhiyun 		    (dev->isp_ver == ISP_V30 &&
673*4882a593Smuzhiyun 		     (stream->id == RKISP_STREAM_BP || stream->id == RKISP_STREAM_FBC)))) {
674*4882a593Smuzhiyun 		v4l2_warn(&dev->v4l2_dev,
675*4882a593Smuzhiyun 			  "%s no scale %dx%d should equal to %dx%d\n",
676*4882a593Smuzhiyun 			  node->vdev.name,
677*4882a593Smuzhiyun 			  pixm->width, pixm->height,
678*4882a593Smuzhiyun 			  max_rsz.width, max_rsz.height);
679*4882a593Smuzhiyun 		pixm->width = max_rsz.width;
680*4882a593Smuzhiyun 		pixm->height = max_rsz.height;
681*4882a593Smuzhiyun 	} else if (stream->id == RKISP_STREAM_MPDS || stream->id == RKISP_STREAM_BPDS) {
682*4882a593Smuzhiyun 		struct rkisp_stream *t = &dev->cap_dev.stream[stream->conn_id];
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 		if (pixm->pixelformat != t->out_fmt.pixelformat ||
685*4882a593Smuzhiyun 		    pixm->width != max_rsz.width || pixm->height != max_rsz.height) {
686*4882a593Smuzhiyun 			v4l2_warn(&dev->v4l2_dev,
687*4882a593Smuzhiyun 				  "%s from %s, force to %dx%d %c%c%c%c\n",
688*4882a593Smuzhiyun 				  node->vdev.name, t->vnode.vdev.name,
689*4882a593Smuzhiyun 				  max_rsz.width, max_rsz.height,
690*4882a593Smuzhiyun 				  t->out_fmt.pixelformat,
691*4882a593Smuzhiyun 				  t->out_fmt.pixelformat >> 8,
692*4882a593Smuzhiyun 				  t->out_fmt.pixelformat >> 16,
693*4882a593Smuzhiyun 				  t->out_fmt.pixelformat >> 24);
694*4882a593Smuzhiyun 			pixm->pixelformat = t->out_fmt.pixelformat;
695*4882a593Smuzhiyun 			pixm->width = max_rsz.width;
696*4882a593Smuzhiyun 			pixm->height = max_rsz.height;
697*4882a593Smuzhiyun 		}
698*4882a593Smuzhiyun 	} else if (stream->id == RKISP_STREAM_VIR) {
699*4882a593Smuzhiyun 		struct rkisp_stream *t;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 		if (stream->conn_id != -1) {
702*4882a593Smuzhiyun 			t = &dev->cap_dev.stream[stream->conn_id];
703*4882a593Smuzhiyun 			*pixm = t->out_fmt;
704*4882a593Smuzhiyun 		} else {
705*4882a593Smuzhiyun 			for (i = RKISP_STREAM_MP; i < RKISP_STREAM_VIR; i++) {
706*4882a593Smuzhiyun 				t = &dev->cap_dev.stream[i];
707*4882a593Smuzhiyun 				if (t->out_isp_fmt.fmt_type != FMT_YUV || !t->streaming)
708*4882a593Smuzhiyun 					continue;
709*4882a593Smuzhiyun 				if (t->out_fmt.plane_fmt[0].sizeimage > imagsize) {
710*4882a593Smuzhiyun 					imagsize = t->out_fmt.plane_fmt[0].sizeimage;
711*4882a593Smuzhiyun 					*pixm = t->out_fmt;
712*4882a593Smuzhiyun 					stream->conn_id = t->id;
713*4882a593Smuzhiyun 				}
714*4882a593Smuzhiyun 			}
715*4882a593Smuzhiyun 		}
716*4882a593Smuzhiyun 		if (stream->conn_id == -1) {
717*4882a593Smuzhiyun 			v4l2_err(&dev->v4l2_dev, "no output stream for iqtool\n");
718*4882a593Smuzhiyun 			return -EINVAL;
719*4882a593Smuzhiyun 		}
720*4882a593Smuzhiyun 		imagsize = 0;
721*4882a593Smuzhiyun 	}
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	pixm->num_planes = fmt->mplanes;
724*4882a593Smuzhiyun 	pixm->field = V4L2_FIELD_NONE;
725*4882a593Smuzhiyun 	/* get quantization from ispsd */
726*4882a593Smuzhiyun 	pixm->quantization = stream->ispdev->isp_sdev.quantization;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	/* calculate size */
729*4882a593Smuzhiyun 	rkisp_fcc_xysubs(fmt->fourcc, &xsubs, &ysubs);
730*4882a593Smuzhiyun 	planes = fmt->cplanes ? fmt->cplanes : fmt->mplanes;
731*4882a593Smuzhiyun 	for (i = 0; i < planes; i++) {
732*4882a593Smuzhiyun 		struct v4l2_plane_pix_format *plane_fmt;
733*4882a593Smuzhiyun 		unsigned int width, height, bytesperline, w, h;
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 		plane_fmt = pixm->plane_fmt + i;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 		w = (fmt->fmt_type == FMT_FBC) ?
738*4882a593Smuzhiyun 			ALIGN(pixm->width, 16) : pixm->width;
739*4882a593Smuzhiyun 		h = (fmt->fmt_type == FMT_FBC) ?
740*4882a593Smuzhiyun 			ALIGN(pixm->height, 16) : pixm->height;
741*4882a593Smuzhiyun 		/* mainpath for warp default */
742*4882a593Smuzhiyun 		if (dev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP)
743*4882a593Smuzhiyun 			h = dev->cap_dev.wrap_line;
744*4882a593Smuzhiyun 		width = i ? w / xsubs : w;
745*4882a593Smuzhiyun 		height = i ? h / ysubs : h;
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 		if (dev->isp_ver == ISP_V20 &&
748*4882a593Smuzhiyun 		    fmt->fmt_type == FMT_BAYER &&
749*4882a593Smuzhiyun 		    stream->id == RKISP_STREAM_DMATX2)
750*4882a593Smuzhiyun 			height += RKMODULE_EXTEND_LINE;
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 		if ((dev->isp_ver == ISP_V20 ||
753*4882a593Smuzhiyun 		     dev->isp_ver == ISP_V21) &&
754*4882a593Smuzhiyun 		    !stream->memory &&
755*4882a593Smuzhiyun 		    fmt->fmt_type == FMT_BAYER &&
756*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_MP &&
757*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_SP)
758*4882a593Smuzhiyun 			/* compact mode need bytesperline 4byte align */
759*4882a593Smuzhiyun 			bytesperline = ALIGN(width * fmt->bpp[i] / 8, 256);
760*4882a593Smuzhiyun 		else
761*4882a593Smuzhiyun 			bytesperline = width * DIV_ROUND_UP(fmt->bpp[i], 8);
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 		if (i != 0 || plane_fmt->bytesperline < bytesperline)
764*4882a593Smuzhiyun 			plane_fmt->bytesperline = bytesperline;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 		/* 128bit AXI, 16byte align for bytesperline */
767*4882a593Smuzhiyun 		if ((dev->isp_ver == ISP_V20 && stream->id == RKISP_STREAM_SP) ||
768*4882a593Smuzhiyun 		    dev->isp_ver >= ISP_V30)
769*4882a593Smuzhiyun 			plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline, 16);
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 		plane_fmt->sizeimage = plane_fmt->bytesperline * height;
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 		/* FMT_FBCGAIN: uv address is y size offset need 64 align
774*4882a593Smuzhiyun 		 * FMT_FBC: width and height need 16 align
775*4882a593Smuzhiyun 		 *          header: width * height / 16, and 4096 align for mpp
776*4882a593Smuzhiyun 		 *          payload: yuv420 or yuv422 size
777*4882a593Smuzhiyun 		 */
778*4882a593Smuzhiyun 		if (fmt->fmt_type == FMT_FBCGAIN && i == 0)
779*4882a593Smuzhiyun 			plane_fmt->sizeimage = ALIGN(plane_fmt->sizeimage, 64);
780*4882a593Smuzhiyun 		else if (fmt->fmt_type == FMT_FBC && i == 0)
781*4882a593Smuzhiyun 			plane_fmt->sizeimage = ALIGN(plane_fmt->sizeimage >> 4, RK_MPP_ALIGN);
782*4882a593Smuzhiyun 		else if (fmt->fmt_type == FMT_FBC)
783*4882a593Smuzhiyun 			plane_fmt->sizeimage += w * h;
784*4882a593Smuzhiyun 		imagsize += plane_fmt->sizeimage;
785*4882a593Smuzhiyun 	}
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun 	/* convert to non-MPLANE format.
788*4882a593Smuzhiyun 	 * it's important since we want to unify none-MPLANE
789*4882a593Smuzhiyun 	 * and MPLANE.
790*4882a593Smuzhiyun 	 */
791*4882a593Smuzhiyun 	if (fmt->mplanes == 1 || fmt->fmt_type == FMT_FBCGAIN)
792*4882a593Smuzhiyun 		pixm->plane_fmt[0].sizeimage = imagsize;
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	if (!try && !stream->start_stream && !stream->streaming) {
795*4882a593Smuzhiyun 		stream->out_isp_fmt = *fmt;
796*4882a593Smuzhiyun 		stream->out_fmt = *pixm;
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun 		if (stream->id == RKISP_STREAM_SP) {
799*4882a593Smuzhiyun 			stream->u.sp.y_stride =
800*4882a593Smuzhiyun 				pixm->plane_fmt[0].bytesperline /
801*4882a593Smuzhiyun 				DIV_ROUND_UP(fmt->bpp[0], 8);
802*4882a593Smuzhiyun 		} else if (stream->id == RKISP_STREAM_MP) {
803*4882a593Smuzhiyun 			stream->u.mp.raw_enable = (fmt->fmt_type == FMT_BAYER);
804*4882a593Smuzhiyun 		}
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 		v4l2_dbg(1, rkisp_debug, &stream->ispdev->v4l2_dev,
807*4882a593Smuzhiyun 			 "%s: %s req(%d, %d) out(%d, %d)\n", __func__,
808*4882a593Smuzhiyun 			 node->vdev.name, pixm->width, pixm->height,
809*4882a593Smuzhiyun 			 stream->out_fmt.width, stream->out_fmt.height);
810*4882a593Smuzhiyun 	}
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	return 0;
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun struct rockit_isp_ops rockit_isp_ops = {
816*4882a593Smuzhiyun 	.rkisp_set_fmt = rkisp_set_fmt,
817*4882a593Smuzhiyun };
818*4882a593Smuzhiyun 
rkisp_fh_open(struct file * filp)819*4882a593Smuzhiyun int rkisp_fh_open(struct file *filp)
820*4882a593Smuzhiyun {
821*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(filp);
822*4882a593Smuzhiyun 	int ret;
823*4882a593Smuzhiyun 
824*4882a593Smuzhiyun 	if (!stream->ispdev->is_probe_end)
825*4882a593Smuzhiyun 		return -EINVAL;
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	ret = v4l2_fh_open(filp);
828*4882a593Smuzhiyun 	if (!ret) {
829*4882a593Smuzhiyun 		ret = v4l2_pipeline_pm_get(&stream->vnode.vdev.entity);
830*4882a593Smuzhiyun 		if (ret < 0)
831*4882a593Smuzhiyun 			vb2_fop_release(filp);
832*4882a593Smuzhiyun 	}
833*4882a593Smuzhiyun 
834*4882a593Smuzhiyun 	return ret;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun 
rkisp_fop_release(struct file * file)837*4882a593Smuzhiyun int rkisp_fop_release(struct file *file)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
840*4882a593Smuzhiyun 	int ret;
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun 	ret = vb2_fop_release(file);
843*4882a593Smuzhiyun 	if (!ret)
844*4882a593Smuzhiyun 		v4l2_pipeline_pm_put(&stream->vnode.vdev.entity);
845*4882a593Smuzhiyun 	return ret;
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun 
rkisp_set_stream_def_fmt(struct rkisp_device * dev,u32 id,u32 width,u32 height,u32 pixelformat)848*4882a593Smuzhiyun void rkisp_set_stream_def_fmt(struct rkisp_device *dev, u32 id,
849*4882a593Smuzhiyun 	u32 width, u32 height, u32 pixelformat)
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun 	struct rkisp_stream *stream = &dev->cap_dev.stream[id];
852*4882a593Smuzhiyun 	struct v4l2_pix_format_mplane pixm;
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	memset(&pixm, 0, sizeof(pixm));
855*4882a593Smuzhiyun 	if (pixelformat)
856*4882a593Smuzhiyun 		pixm.pixelformat = pixelformat;
857*4882a593Smuzhiyun 	else
858*4882a593Smuzhiyun 		pixm.pixelformat = stream->out_isp_fmt.fourcc;
859*4882a593Smuzhiyun 	if (!pixm.pixelformat)
860*4882a593Smuzhiyun 		return;
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	stream->dcrop.left = 0;
863*4882a593Smuzhiyun 	stream->dcrop.top = 0;
864*4882a593Smuzhiyun 	stream->dcrop.width = width;
865*4882a593Smuzhiyun 	stream->dcrop.height = height;
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	pixm.width = width;
868*4882a593Smuzhiyun 	pixm.height = height;
869*4882a593Smuzhiyun 	rkisp_set_fmt(stream, &pixm, false);
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun /************************* v4l2_file_operations***************************/
873*4882a593Smuzhiyun static const struct v4l2_file_operations rkisp_fops = {
874*4882a593Smuzhiyun 	.open = rkisp_fh_open,
875*4882a593Smuzhiyun 	.release = rkisp_fop_release,
876*4882a593Smuzhiyun 	.unlocked_ioctl = video_ioctl2,
877*4882a593Smuzhiyun 	.poll = vb2_fop_poll,
878*4882a593Smuzhiyun 	.mmap = vb2_fop_mmap,
879*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
880*4882a593Smuzhiyun 	.compat_ioctl32 = video_ioctl2,
881*4882a593Smuzhiyun #endif
882*4882a593Smuzhiyun };
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun /*
885*4882a593Smuzhiyun  * mp and sp v4l2_ioctl_ops
886*4882a593Smuzhiyun  */
887*4882a593Smuzhiyun 
rkisp_enum_input(struct file * file,void * priv,struct v4l2_input * input)888*4882a593Smuzhiyun static int rkisp_enum_input(struct file *file, void *priv,
889*4882a593Smuzhiyun 			     struct v4l2_input *input)
890*4882a593Smuzhiyun {
891*4882a593Smuzhiyun 	if (input->index > 0)
892*4882a593Smuzhiyun 		return -EINVAL;
893*4882a593Smuzhiyun 
894*4882a593Smuzhiyun 	input->type = V4L2_INPUT_TYPE_CAMERA;
895*4882a593Smuzhiyun 	strlcpy(input->name, "Camera", sizeof(input->name));
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	return 0;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun 
rkisp_try_fmt_vid_cap_mplane(struct file * file,void * fh,struct v4l2_format * f)900*4882a593Smuzhiyun static int rkisp_try_fmt_vid_cap_mplane(struct file *file, void *fh,
901*4882a593Smuzhiyun 					 struct v4l2_format *f)
902*4882a593Smuzhiyun {
903*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun 	return rkisp_set_fmt(stream, &f->fmt.pix_mp, true);
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun 
rkisp_enum_framesizes(struct file * file,void * prov,struct v4l2_frmsizeenum * fsize)908*4882a593Smuzhiyun static int rkisp_enum_framesizes(struct file *file, void *prov,
909*4882a593Smuzhiyun 				 struct v4l2_frmsizeenum *fsize)
910*4882a593Smuzhiyun {
911*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
912*4882a593Smuzhiyun 	const struct stream_config *config = stream->config;
913*4882a593Smuzhiyun 	struct v4l2_frmsize_stepwise *s = &fsize->stepwise;
914*4882a593Smuzhiyun 	struct v4l2_frmsize_discrete *d = &fsize->discrete;
915*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
916*4882a593Smuzhiyun 	struct v4l2_rect max_rsz;
917*4882a593Smuzhiyun 	struct v4l2_rect *input_win = rkisp_get_isp_sd_win(&dev->isp_sdev);
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun 	if (fsize->index != 0)
920*4882a593Smuzhiyun 		return -EINVAL;
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 	if (!find_fmt(stream, fsize->pixel_format))
923*4882a593Smuzhiyun 		return -EINVAL;
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 	restrict_rsz_resolution(stream, config, &max_rsz);
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun 	if (stream->out_isp_fmt.fmt_type == FMT_BAYER ||
928*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_FBC ||
929*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_BPDS ||
930*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_MPDS ||
931*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_LUMA ||
932*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_VIR ||
933*4882a593Smuzhiyun 	    (stream->id == RKISP_STREAM_BP && dev->hw_dev->isp_ver == ISP_V30)) {
934*4882a593Smuzhiyun 		fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
935*4882a593Smuzhiyun 		d->width = max_rsz.width;
936*4882a593Smuzhiyun 		d->height = max_rsz.height;
937*4882a593Smuzhiyun 	} else {
938*4882a593Smuzhiyun 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
939*4882a593Smuzhiyun 		s->min_width = STREAM_MIN_RSZ_OUTPUT_WIDTH;
940*4882a593Smuzhiyun 		s->min_height = STREAM_MIN_RSZ_OUTPUT_HEIGHT;
941*4882a593Smuzhiyun 		s->max_width = min_t(u32, max_rsz.width, input_win->width);
942*4882a593Smuzhiyun 		s->max_height = input_win->height;
943*4882a593Smuzhiyun 		s->step_width = STREAM_OUTPUT_STEP_WISE;
944*4882a593Smuzhiyun 		s->step_height = STREAM_OUTPUT_STEP_WISE;
945*4882a593Smuzhiyun 	}
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 	return 0;
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun 
rkisp_get_cmsk(struct rkisp_stream * stream,struct rkisp_cmsk_cfg * cfg)950*4882a593Smuzhiyun static int rkisp_get_cmsk(struct rkisp_stream *stream, struct rkisp_cmsk_cfg *cfg)
951*4882a593Smuzhiyun {
952*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
953*4882a593Smuzhiyun 	unsigned long lock_flags = 0;
954*4882a593Smuzhiyun 	u32 i, win_en, mode;
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	if ((dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) ||
957*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_FBC ||
958*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_MPDS ||
959*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_BPDS) {
960*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "%s not support\n", __func__);
961*4882a593Smuzhiyun 		return -EINVAL;
962*4882a593Smuzhiyun 	}
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	spin_lock_irqsave(&dev->cmsk_lock, lock_flags);
965*4882a593Smuzhiyun 	*cfg = dev->cmsk_cfg;
966*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags);
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun 	switch (stream->id) {
969*4882a593Smuzhiyun 	case RKISP_STREAM_MP:
970*4882a593Smuzhiyun 		win_en = cfg->win[0].win_en;
971*4882a593Smuzhiyun 		mode = cfg->win[0].mode;
972*4882a593Smuzhiyun 		break;
973*4882a593Smuzhiyun 	case RKISP_STREAM_SP:
974*4882a593Smuzhiyun 		win_en = cfg->win[1].win_en;
975*4882a593Smuzhiyun 		mode = cfg->win[1].mode;
976*4882a593Smuzhiyun 		break;
977*4882a593Smuzhiyun 	case RKISP_STREAM_BP:
978*4882a593Smuzhiyun 	default:
979*4882a593Smuzhiyun 		win_en = cfg->win[2].win_en;
980*4882a593Smuzhiyun 		mode = cfg->win[2].mode;
981*4882a593Smuzhiyun 		break;
982*4882a593Smuzhiyun 	}
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	cfg->width_ro = dev->isp_sdev.out_crop.width;
985*4882a593Smuzhiyun 	cfg->height_ro = dev->isp_sdev.out_crop.height;
986*4882a593Smuzhiyun 	for (i = 0; i < RKISP_CMSK_WIN_MAX; i++) {
987*4882a593Smuzhiyun 		cfg->win[i].win_en = !!(win_en & BIT(i));
988*4882a593Smuzhiyun 		cfg->win[i].mode = !!(mode & BIT(i));
989*4882a593Smuzhiyun 	}
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun 	return 0;
992*4882a593Smuzhiyun }
993*4882a593Smuzhiyun 
rkisp_set_cmsk(struct rkisp_stream * stream,struct rkisp_cmsk_cfg * cfg)994*4882a593Smuzhiyun static int rkisp_set_cmsk(struct rkisp_stream *stream, struct rkisp_cmsk_cfg *cfg)
995*4882a593Smuzhiyun {
996*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
997*4882a593Smuzhiyun 	unsigned long lock_flags = 0;
998*4882a593Smuzhiyun 	u16 i, win_en = 0, mode = 0;
999*4882a593Smuzhiyun 	u16 h_offs, v_offs, h_size, v_size;
1000*4882a593Smuzhiyun 	u32 width = dev->isp_sdev.out_crop.width;
1001*4882a593Smuzhiyun 	u32 height = dev->isp_sdev.out_crop.height;
1002*4882a593Smuzhiyun 	u32 align = (dev->isp_ver == ISP_V30) ? 8 : 2;
1003*4882a593Smuzhiyun 	bool warn = false;
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun 	if ((dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) ||
1006*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_FBC ||
1007*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_MPDS ||
1008*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_BPDS) {
1009*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "%s not support\n", __func__);
1010*4882a593Smuzhiyun 		return -EINVAL;
1011*4882a593Smuzhiyun 	}
1012*4882a593Smuzhiyun 
1013*4882a593Smuzhiyun 	spin_lock_irqsave(&dev->cmsk_lock, lock_flags);
1014*4882a593Smuzhiyun 	dev->is_cmsk_upd = true;
1015*4882a593Smuzhiyun 	for (i = 0; i < RKISP_CMSK_WIN_MAX; i++) {
1016*4882a593Smuzhiyun 		win_en |= cfg->win[i].win_en ? BIT(i) : 0;
1017*4882a593Smuzhiyun 		mode |= cfg->win[i].mode ? BIT(i) : 0;
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 		if (cfg->win[i].win_en) {
1020*4882a593Smuzhiyun 			if (cfg->win[i].mode) {
1021*4882a593Smuzhiyun 				dev->cmsk_cfg.win[i].cover_color_y = cfg->win[i].cover_color_y;
1022*4882a593Smuzhiyun 				dev->cmsk_cfg.win[i].cover_color_u = cfg->win[i].cover_color_u;
1023*4882a593Smuzhiyun 				dev->cmsk_cfg.win[i].cover_color_v = cfg->win[i].cover_color_v;
1024*4882a593Smuzhiyun 			}
1025*4882a593Smuzhiyun 			h_offs = cfg->win[i].h_offs & ~0x1;
1026*4882a593Smuzhiyun 			v_offs = cfg->win[i].v_offs & ~0x1;
1027*4882a593Smuzhiyun 			h_size = ALIGN_DOWN(cfg->win[i].h_size, align);
1028*4882a593Smuzhiyun 			v_size = ALIGN_DOWN(cfg->win[i].v_size, align);
1029*4882a593Smuzhiyun 			if (h_offs != cfg->win[i].h_offs ||
1030*4882a593Smuzhiyun 			    v_offs != cfg->win[i].v_offs ||
1031*4882a593Smuzhiyun 			    h_size != cfg->win[i].h_size ||
1032*4882a593Smuzhiyun 			    v_size != cfg->win[i].v_size)
1033*4882a593Smuzhiyun 				warn = true;
1034*4882a593Smuzhiyun 			if (h_offs + h_size > width) {
1035*4882a593Smuzhiyun 				h_size = ALIGN_DOWN(width - h_offs, align);
1036*4882a593Smuzhiyun 				warn = true;
1037*4882a593Smuzhiyun 			}
1038*4882a593Smuzhiyun 			if (v_offs + v_size > height) {
1039*4882a593Smuzhiyun 				v_size = ALIGN_DOWN(height - v_offs, align);
1040*4882a593Smuzhiyun 				warn = true;
1041*4882a593Smuzhiyun 			}
1042*4882a593Smuzhiyun 			if (warn) {
1043*4882a593Smuzhiyun 				warn = false;
1044*4882a593Smuzhiyun 				v4l2_warn(&dev->v4l2_dev,
1045*4882a593Smuzhiyun 					  "%s cmsk offs 2 align, size %d align and offs + size < resolution\n"
1046*4882a593Smuzhiyun 					  "\t cmsk win%d result to offs:%d %d, size:%d %d\n",
1047*4882a593Smuzhiyun 					  stream->vnode.vdev.name, i, align, h_offs, v_offs, h_size, v_size);
1048*4882a593Smuzhiyun 			}
1049*4882a593Smuzhiyun 			dev->cmsk_cfg.win[i].h_offs = h_offs;
1050*4882a593Smuzhiyun 			dev->cmsk_cfg.win[i].v_offs = v_offs;
1051*4882a593Smuzhiyun 			dev->cmsk_cfg.win[i].h_size = h_size;
1052*4882a593Smuzhiyun 			dev->cmsk_cfg.win[i].v_size = v_size;
1053*4882a593Smuzhiyun 		}
1054*4882a593Smuzhiyun 	}
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	switch (stream->id) {
1057*4882a593Smuzhiyun 	case RKISP_STREAM_MP:
1058*4882a593Smuzhiyun 		dev->cmsk_cfg.win[0].win_en = win_en;
1059*4882a593Smuzhiyun 		dev->cmsk_cfg.win[0].mode = mode;
1060*4882a593Smuzhiyun 		break;
1061*4882a593Smuzhiyun 	case RKISP_STREAM_SP:
1062*4882a593Smuzhiyun 		dev->cmsk_cfg.win[1].win_en = win_en;
1063*4882a593Smuzhiyun 		dev->cmsk_cfg.win[1].mode = mode;
1064*4882a593Smuzhiyun 		break;
1065*4882a593Smuzhiyun 	case RKISP_STREAM_BP:
1066*4882a593Smuzhiyun 	default:
1067*4882a593Smuzhiyun 		dev->cmsk_cfg.win[2].win_en = win_en;
1068*4882a593Smuzhiyun 		dev->cmsk_cfg.win[2].mode = mode;
1069*4882a593Smuzhiyun 		break;
1070*4882a593Smuzhiyun 	}
1071*4882a593Smuzhiyun 	dev->cmsk_cfg.mosaic_block = cfg->mosaic_block;
1072*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags);
1073*4882a593Smuzhiyun 	return 0;
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun 
rkisp_get_stream_info(struct rkisp_stream * stream,struct rkisp_stream_info * info)1077*4882a593Smuzhiyun static int rkisp_get_stream_info(struct rkisp_stream *stream,
1078*4882a593Smuzhiyun 				 struct rkisp_stream_info *info)
1079*4882a593Smuzhiyun {
1080*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1081*4882a593Smuzhiyun 	u32 id = 0;
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	rkisp_dmarx_get_frame(stream->ispdev, &id, NULL, NULL, true);
1084*4882a593Smuzhiyun 	info->cur_frame_id = stream->dbg.id;
1085*4882a593Smuzhiyun 	info->input_frame_loss = dev->isp_sdev.dbg.frameloss;
1086*4882a593Smuzhiyun 	info->output_frame_loss = stream->dbg.frameloss;
1087*4882a593Smuzhiyun 	info->stream_on = stream->streaming;
1088*4882a593Smuzhiyun 	info->stream_id = stream->id;
1089*4882a593Smuzhiyun 	return 0;
1090*4882a593Smuzhiyun }
1091*4882a593Smuzhiyun 
rkisp_get_mirror_flip(struct rkisp_stream * stream,struct rkisp_mirror_flip * cfg)1092*4882a593Smuzhiyun static int rkisp_get_mirror_flip(struct rkisp_stream *stream,
1093*4882a593Smuzhiyun 				 struct rkisp_mirror_flip *cfg)
1094*4882a593Smuzhiyun {
1095*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32)
1098*4882a593Smuzhiyun 		return -EINVAL;
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 	cfg->mirror = dev->cap_dev.is_mirror;
1101*4882a593Smuzhiyun 	cfg->flip = stream->is_flip;
1102*4882a593Smuzhiyun 	return 0;
1103*4882a593Smuzhiyun }
1104*4882a593Smuzhiyun 
rkisp_set_mirror_flip(struct rkisp_stream * stream,struct rkisp_mirror_flip * cfg)1105*4882a593Smuzhiyun static int rkisp_set_mirror_flip(struct rkisp_stream *stream,
1106*4882a593Smuzhiyun 				 struct rkisp_mirror_flip *cfg)
1107*4882a593Smuzhiyun {
1108*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32)
1111*4882a593Smuzhiyun 		return -EINVAL;
1112*4882a593Smuzhiyun 
1113*4882a593Smuzhiyun 	if (dev->cap_dev.wrap_line) {
1114*4882a593Smuzhiyun 		v4l2_warn(&dev->v4l2_dev, "wrap_line mode can not set the mirror");
1115*4882a593Smuzhiyun 		dev->cap_dev.is_mirror = 0;
1116*4882a593Smuzhiyun 	} else {
1117*4882a593Smuzhiyun 		dev->cap_dev.is_mirror = cfg->mirror;
1118*4882a593Smuzhiyun 	}
1119*4882a593Smuzhiyun 
1120*4882a593Smuzhiyun 	stream->is_flip = cfg->flip;
1121*4882a593Smuzhiyun 	stream->is_mf_upd = true;
1122*4882a593Smuzhiyun 	return 0;
1123*4882a593Smuzhiyun }
1124*4882a593Smuzhiyun 
rkisp_get_wrap_line(struct rkisp_stream * stream,struct rkisp_wrap_info * arg)1125*4882a593Smuzhiyun static int rkisp_get_wrap_line(struct rkisp_stream *stream, struct rkisp_wrap_info *arg)
1126*4882a593Smuzhiyun {
1127*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32 && stream->id != RKISP_STREAM_MP)
1130*4882a593Smuzhiyun 		return -EINVAL;
1131*4882a593Smuzhiyun 
1132*4882a593Smuzhiyun 	arg->width = dev->cap_dev.wrap_width;
1133*4882a593Smuzhiyun 	arg->height = dev->cap_dev.wrap_line;
1134*4882a593Smuzhiyun 	return 0;
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun 
rkisp_set_wrap_line(struct rkisp_stream * stream,struct rkisp_wrap_info * arg)1137*4882a593Smuzhiyun static int rkisp_set_wrap_line(struct rkisp_stream *stream, struct rkisp_wrap_info *arg)
1138*4882a593Smuzhiyun {
1139*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32 ||
1142*4882a593Smuzhiyun 	    dev->hw_dev->dev_link_num > 1 ||
1143*4882a593Smuzhiyun 	    !stream->ops->set_wrap) {
1144*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev,
1145*4882a593Smuzhiyun 			 "wrap only support for single sensor and mainpath\n");
1146*4882a593Smuzhiyun 		return -EINVAL;
1147*4882a593Smuzhiyun 	}
1148*4882a593Smuzhiyun 	dev->cap_dev.wrap_width = arg->width;
1149*4882a593Smuzhiyun 	return stream->ops->set_wrap(stream, arg->height);
1150*4882a593Smuzhiyun }
1151*4882a593Smuzhiyun 
rkisp_set_fps(struct rkisp_stream * stream,int * fps)1152*4882a593Smuzhiyun static int rkisp_set_fps(struct rkisp_stream *stream, int *fps)
1153*4882a593Smuzhiyun {
1154*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32)
1157*4882a593Smuzhiyun 		return -EINVAL;
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun 	return rkisp_rockit_fps_set(fps, stream);
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun 
rkisp_get_fps(struct rkisp_stream * stream,int * fps)1162*4882a593Smuzhiyun static int rkisp_get_fps(struct rkisp_stream *stream, int *fps)
1163*4882a593Smuzhiyun {
1164*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1165*4882a593Smuzhiyun 
1166*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32)
1167*4882a593Smuzhiyun 		return -EINVAL;
1168*4882a593Smuzhiyun 
1169*4882a593Smuzhiyun 	return rkisp_rockit_fps_get(fps, stream);
1170*4882a593Smuzhiyun }
1171*4882a593Smuzhiyun 
rkisp_get_tb_stream_info(struct rkisp_stream * stream,struct rkisp_tb_stream_info * info)1172*4882a593Smuzhiyun int rkisp_get_tb_stream_info(struct rkisp_stream *stream,
1173*4882a593Smuzhiyun 			     struct rkisp_tb_stream_info *info)
1174*4882a593Smuzhiyun {
1175*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1176*4882a593Smuzhiyun 
1177*4882a593Smuzhiyun 	if (stream->id != RKISP_STREAM_MP) {
1178*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "fast only support for MP\n");
1179*4882a593Smuzhiyun 		return -EINVAL;
1180*4882a593Smuzhiyun 	}
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 	if (!dev->tb_stream_info.buf_max) {
1183*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "thunderboot no enough memory for image\n");
1184*4882a593Smuzhiyun 		return -EINVAL;
1185*4882a593Smuzhiyun 	}
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 	memcpy(info, &dev->tb_stream_info, sizeof(*info));
1188*4882a593Smuzhiyun 	return 0;
1189*4882a593Smuzhiyun }
1190*4882a593Smuzhiyun 
rkisp_free_tb_stream_buf(struct rkisp_stream * stream)1191*4882a593Smuzhiyun int rkisp_free_tb_stream_buf(struct rkisp_stream *stream)
1192*4882a593Smuzhiyun {
1193*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1194*4882a593Smuzhiyun 	struct rkisp_isp_subdev *sdev = &dev->isp_sdev;
1195*4882a593Smuzhiyun 	struct v4l2_subdev *sd = &sdev->sd;
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun 	return sd->ops->core->ioctl(sd, RKISP_CMD_FREE_SHARED_BUF, NULL);
1198*4882a593Smuzhiyun }
1199*4882a593Smuzhiyun 
rkisp_set_iqtool_connect_id(struct rkisp_stream * stream,int stream_id)1200*4882a593Smuzhiyun static int rkisp_set_iqtool_connect_id(struct rkisp_stream *stream, int stream_id)
1201*4882a593Smuzhiyun {
1202*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1203*4882a593Smuzhiyun 
1204*4882a593Smuzhiyun 	if (stream->id != RKISP_STREAM_VIR) {
1205*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "only support for iqtool video\n");
1206*4882a593Smuzhiyun 		goto err;
1207*4882a593Smuzhiyun 	}
1208*4882a593Smuzhiyun 
1209*4882a593Smuzhiyun 	if (stream_id != RKISP_STREAM_MP &&
1210*4882a593Smuzhiyun 	    stream_id != RKISP_STREAM_SP &&
1211*4882a593Smuzhiyun 	    stream_id != RKISP_STREAM_BP) {
1212*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "invalid connect stream id\n");
1213*4882a593Smuzhiyun 		goto err;
1214*4882a593Smuzhiyun 	}
1215*4882a593Smuzhiyun 
1216*4882a593Smuzhiyun 	stream->conn_id = stream_id;
1217*4882a593Smuzhiyun 	return 0;
1218*4882a593Smuzhiyun err:
1219*4882a593Smuzhiyun 	return -EINVAL;
1220*4882a593Smuzhiyun }
1221*4882a593Smuzhiyun 
rkisp_ioctl_default(struct file * file,void * fh,bool valid_prio,unsigned int cmd,void * arg)1222*4882a593Smuzhiyun static long rkisp_ioctl_default(struct file *file, void *fh,
1223*4882a593Smuzhiyun 				bool valid_prio, unsigned int cmd, void *arg)
1224*4882a593Smuzhiyun {
1225*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1226*4882a593Smuzhiyun 	long ret = 0;
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 	if (!arg && cmd != RKISP_CMD_FREE_TB_STREAM_BUF)
1229*4882a593Smuzhiyun 		return -EINVAL;
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun 	switch (cmd) {
1232*4882a593Smuzhiyun 	case RKISP_CMD_GET_CSI_MEMORY_MODE:
1233*4882a593Smuzhiyun 		if (stream->id != RKISP_STREAM_DMATX0 &&
1234*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_DMATX1 &&
1235*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_DMATX2 &&
1236*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_DMATX3)
1237*4882a593Smuzhiyun 			ret = -EINVAL;
1238*4882a593Smuzhiyun 		else if (stream->memory == 0)
1239*4882a593Smuzhiyun 			*(int *)arg = CSI_MEM_COMPACT;
1240*4882a593Smuzhiyun 		else if (stream->memory == SW_CSI_RAW_WR_SIMG_MODE)
1241*4882a593Smuzhiyun 			*(int *)arg = CSI_MEM_WORD_BIG_ALIGN;
1242*4882a593Smuzhiyun 		else
1243*4882a593Smuzhiyun 			*(int *)arg = CSI_MEM_WORD_LITTLE_ALIGN;
1244*4882a593Smuzhiyun 		break;
1245*4882a593Smuzhiyun 	case RKISP_CMD_SET_CSI_MEMORY_MODE:
1246*4882a593Smuzhiyun 		if (stream->id != RKISP_STREAM_DMATX0 &&
1247*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_DMATX1 &&
1248*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_DMATX2 &&
1249*4882a593Smuzhiyun 		    stream->id != RKISP_STREAM_DMATX3)
1250*4882a593Smuzhiyun 			ret = -EINVAL;
1251*4882a593Smuzhiyun 		else if (*(int *)arg == CSI_MEM_COMPACT)
1252*4882a593Smuzhiyun 			stream->memory = 0;
1253*4882a593Smuzhiyun 		else if (*(int *)arg == CSI_MEM_WORD_BIG_ALIGN)
1254*4882a593Smuzhiyun 			stream->memory = SW_CSI_RAW_WR_SIMG_MODE;
1255*4882a593Smuzhiyun 		else
1256*4882a593Smuzhiyun 			stream->memory =
1257*4882a593Smuzhiyun 				SW_CSI_RWA_WR_SIMG_SWP | SW_CSI_RAW_WR_SIMG_MODE;
1258*4882a593Smuzhiyun 		break;
1259*4882a593Smuzhiyun 	case RKISP_CMD_GET_CMSK:
1260*4882a593Smuzhiyun 		ret = rkisp_get_cmsk(stream, arg);
1261*4882a593Smuzhiyun 		break;
1262*4882a593Smuzhiyun 	case RKISP_CMD_SET_CMSK:
1263*4882a593Smuzhiyun 		ret = rkisp_set_cmsk(stream, arg);
1264*4882a593Smuzhiyun 		break;
1265*4882a593Smuzhiyun 	case RKISP_CMD_GET_STREAM_INFO:
1266*4882a593Smuzhiyun 		ret = rkisp_get_stream_info(stream, arg);
1267*4882a593Smuzhiyun 		break;
1268*4882a593Smuzhiyun 	case RKISP_CMD_GET_MIRROR_FLIP:
1269*4882a593Smuzhiyun 		ret = rkisp_get_mirror_flip(stream, arg);
1270*4882a593Smuzhiyun 		break;
1271*4882a593Smuzhiyun 	case RKISP_CMD_SET_MIRROR_FLIP:
1272*4882a593Smuzhiyun 		ret = rkisp_set_mirror_flip(stream, arg);
1273*4882a593Smuzhiyun 		break;
1274*4882a593Smuzhiyun 	case RKISP_CMD_GET_WRAP_LINE:
1275*4882a593Smuzhiyun 		ret = rkisp_get_wrap_line(stream, arg);
1276*4882a593Smuzhiyun 		break;
1277*4882a593Smuzhiyun 	case RKISP_CMD_SET_WRAP_LINE:
1278*4882a593Smuzhiyun 		ret = rkisp_set_wrap_line(stream, arg);
1279*4882a593Smuzhiyun 		break;
1280*4882a593Smuzhiyun 	case RKISP_CMD_SET_FPS:
1281*4882a593Smuzhiyun 		ret = rkisp_set_fps(stream, arg);
1282*4882a593Smuzhiyun 		break;
1283*4882a593Smuzhiyun 	case RKISP_CMD_GET_FPS:
1284*4882a593Smuzhiyun 		ret = rkisp_get_fps(stream, arg);
1285*4882a593Smuzhiyun 		break;
1286*4882a593Smuzhiyun 	case RKISP_CMD_GET_TB_STREAM_INFO:
1287*4882a593Smuzhiyun 		ret = rkisp_get_tb_stream_info(stream, arg);
1288*4882a593Smuzhiyun 		break;
1289*4882a593Smuzhiyun 	case RKISP_CMD_FREE_TB_STREAM_BUF:
1290*4882a593Smuzhiyun 		ret = rkisp_free_tb_stream_buf(stream);
1291*4882a593Smuzhiyun 		break;
1292*4882a593Smuzhiyun 	case RKISP_CMD_SET_IQTOOL_CONN_ID:
1293*4882a593Smuzhiyun 		ret = rkisp_set_iqtool_connect_id(stream, *(int *)arg);
1294*4882a593Smuzhiyun 		break;
1295*4882a593Smuzhiyun 	default:
1296*4882a593Smuzhiyun 		ret = -EINVAL;
1297*4882a593Smuzhiyun 	}
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun 	return ret;
1300*4882a593Smuzhiyun }
1301*4882a593Smuzhiyun 
rkisp_enum_frameintervals(struct file * file,void * fh,struct v4l2_frmivalenum * fival)1302*4882a593Smuzhiyun static int rkisp_enum_frameintervals(struct file *file, void *fh,
1303*4882a593Smuzhiyun 				     struct v4l2_frmivalenum *fival)
1304*4882a593Smuzhiyun {
1305*4882a593Smuzhiyun 	const struct rkisp_stream *stream = video_drvdata(file);
1306*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1307*4882a593Smuzhiyun 	struct rkisp_sensor_info *sensor = dev->active_sensor;
1308*4882a593Smuzhiyun 	struct v4l2_subdev_frame_interval fi;
1309*4882a593Smuzhiyun 	int ret;
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun 	if (fival->index != 0)
1312*4882a593Smuzhiyun 		return -EINVAL;
1313*4882a593Smuzhiyun 
1314*4882a593Smuzhiyun 	if (!sensor) {
1315*4882a593Smuzhiyun 		/* TODO: active_sensor is NULL if using DMARX path */
1316*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "%s Not active sensor\n", __func__);
1317*4882a593Smuzhiyun 		return -ENODEV;
1318*4882a593Smuzhiyun 	}
1319*4882a593Smuzhiyun 
1320*4882a593Smuzhiyun 	ret = v4l2_subdev_call(sensor->sd, video, g_frame_interval, &fi);
1321*4882a593Smuzhiyun 	if (ret && ret != -ENOIOCTLCMD) {
1322*4882a593Smuzhiyun 		return ret;
1323*4882a593Smuzhiyun 	} else if (ret == -ENOIOCTLCMD) {
1324*4882a593Smuzhiyun 		/* Set a default value for sensors not implements ioctl */
1325*4882a593Smuzhiyun 		fi.interval.numerator = 1;
1326*4882a593Smuzhiyun 		fi.interval.denominator = 30;
1327*4882a593Smuzhiyun 	}
1328*4882a593Smuzhiyun 
1329*4882a593Smuzhiyun 	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1330*4882a593Smuzhiyun 	fival->stepwise.step.numerator = 1;
1331*4882a593Smuzhiyun 	fival->stepwise.step.denominator = 1;
1332*4882a593Smuzhiyun 	fival->stepwise.max.numerator = 1;
1333*4882a593Smuzhiyun 	fival->stepwise.max.denominator = 1;
1334*4882a593Smuzhiyun 	fival->stepwise.min.numerator = fi.interval.numerator;
1335*4882a593Smuzhiyun 	fival->stepwise.min.denominator = fi.interval.denominator;
1336*4882a593Smuzhiyun 
1337*4882a593Smuzhiyun 	return 0;
1338*4882a593Smuzhiyun }
1339*4882a593Smuzhiyun 
rkisp_enum_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_fmtdesc * f)1340*4882a593Smuzhiyun static int rkisp_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
1341*4882a593Smuzhiyun 					  struct v4l2_fmtdesc *f)
1342*4882a593Smuzhiyun {
1343*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1344*4882a593Smuzhiyun 	const struct capture_fmt *fmt = NULL;
1345*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1346*4882a593Smuzhiyun 	struct ispsd_in_fmt *isp_in_fmt = &dev->isp_sdev.in_fmt;
1347*4882a593Smuzhiyun 	struct ispsd_out_fmt *isp_out_fmt = &dev->isp_sdev.out_fmt;
1348*4882a593Smuzhiyun 	int ret = -EINVAL;
1349*4882a593Smuzhiyun 
1350*4882a593Smuzhiyun 	/* only one output format for raw */
1351*4882a593Smuzhiyun 	if (isp_out_fmt->fmt_type == FMT_BAYER ||
1352*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX0 ||
1353*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX1 ||
1354*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX2 ||
1355*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX3) {
1356*4882a593Smuzhiyun 		u32 pixelformat = rkisp_mbus_pixelcode_to_v4l2(isp_in_fmt->mbus_code);
1357*4882a593Smuzhiyun 
1358*4882a593Smuzhiyun 		if (f->index == 0) {
1359*4882a593Smuzhiyun 			fmt = find_fmt(stream, pixelformat);
1360*4882a593Smuzhiyun 			if (fmt) {
1361*4882a593Smuzhiyun 				f->pixelformat = pixelformat;
1362*4882a593Smuzhiyun 				ret = 0;
1363*4882a593Smuzhiyun 			}
1364*4882a593Smuzhiyun 		}
1365*4882a593Smuzhiyun 		return ret;
1366*4882a593Smuzhiyun 	}
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun 	if (f->index >= stream->config->fmt_size)
1369*4882a593Smuzhiyun 		return -EINVAL;
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	fmt = &stream->config->fmts[f->index];
1372*4882a593Smuzhiyun 	/* only output yuv format */
1373*4882a593Smuzhiyun 	if (isp_out_fmt->fmt_type == FMT_YUV && fmt->fmt_type == FMT_BAYER)
1374*4882a593Smuzhiyun 		return -EINVAL;
1375*4882a593Smuzhiyun 
1376*4882a593Smuzhiyun 	f->pixelformat = fmt->fourcc;
1377*4882a593Smuzhiyun 	switch (f->pixelformat) {
1378*4882a593Smuzhiyun 	case V4L2_PIX_FMT_FBC2:
1379*4882a593Smuzhiyun 		strscpy(f->description,
1380*4882a593Smuzhiyun 			"Rockchip yuv422sp fbc encoder",
1381*4882a593Smuzhiyun 			sizeof(f->description));
1382*4882a593Smuzhiyun 		break;
1383*4882a593Smuzhiyun 	case V4L2_PIX_FMT_FBC0:
1384*4882a593Smuzhiyun 		strscpy(f->description,
1385*4882a593Smuzhiyun 			"Rockchip yuv420sp fbc encoder",
1386*4882a593Smuzhiyun 			sizeof(f->description));
1387*4882a593Smuzhiyun 		break;
1388*4882a593Smuzhiyun 	case V4L2_PIX_FMT_FBCG:
1389*4882a593Smuzhiyun 		strscpy(f->description,
1390*4882a593Smuzhiyun 			"Rockchip fbc gain",
1391*4882a593Smuzhiyun 			sizeof(f->description));
1392*4882a593Smuzhiyun 		break;
1393*4882a593Smuzhiyun 	case V4l2_PIX_FMT_EBD8:
1394*4882a593Smuzhiyun 		strscpy(f->description,
1395*4882a593Smuzhiyun 			"Embedded data 8-bit",
1396*4882a593Smuzhiyun 			sizeof(f->description));
1397*4882a593Smuzhiyun 		break;
1398*4882a593Smuzhiyun 	case V4l2_PIX_FMT_SPD16:
1399*4882a593Smuzhiyun 		strscpy(f->description,
1400*4882a593Smuzhiyun 			"Shield pix data 16-bit",
1401*4882a593Smuzhiyun 			sizeof(f->description));
1402*4882a593Smuzhiyun 		break;
1403*4882a593Smuzhiyun 	default:
1404*4882a593Smuzhiyun 		break;
1405*4882a593Smuzhiyun 	}
1406*4882a593Smuzhiyun 
1407*4882a593Smuzhiyun 	return 0;
1408*4882a593Smuzhiyun }
1409*4882a593Smuzhiyun 
rkisp_s_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)1410*4882a593Smuzhiyun static int rkisp_s_fmt_vid_cap_mplane(struct file *file,
1411*4882a593Smuzhiyun 				       void *priv, struct v4l2_format *f)
1412*4882a593Smuzhiyun {
1413*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1414*4882a593Smuzhiyun 	struct video_device *vdev = &stream->vnode.vdev;
1415*4882a593Smuzhiyun 	struct rkisp_vdev_node *node = vdev_to_node(vdev);
1416*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1417*4882a593Smuzhiyun 
1418*4882a593Smuzhiyun 	if (vb2_is_streaming(&node->buf_queue)) {
1419*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
1420*4882a593Smuzhiyun 		return -EBUSY;
1421*4882a593Smuzhiyun 	}
1422*4882a593Smuzhiyun 
1423*4882a593Smuzhiyun 	return rkisp_set_fmt(stream, &f->fmt.pix_mp, false);
1424*4882a593Smuzhiyun }
1425*4882a593Smuzhiyun 
rkisp_g_fmt_vid_cap_mplane(struct file * file,void * fh,struct v4l2_format * f)1426*4882a593Smuzhiyun static int rkisp_g_fmt_vid_cap_mplane(struct file *file, void *fh,
1427*4882a593Smuzhiyun 				       struct v4l2_format *f)
1428*4882a593Smuzhiyun {
1429*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun 	f->fmt.pix_mp = stream->out_fmt;
1432*4882a593Smuzhiyun 
1433*4882a593Smuzhiyun 	return 0;
1434*4882a593Smuzhiyun }
1435*4882a593Smuzhiyun 
rkisp_g_selection(struct file * file,void * prv,struct v4l2_selection * sel)1436*4882a593Smuzhiyun static int rkisp_g_selection(struct file *file, void *prv,
1437*4882a593Smuzhiyun 			      struct v4l2_selection *sel)
1438*4882a593Smuzhiyun {
1439*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1440*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1441*4882a593Smuzhiyun 	struct v4l2_rect *dcrop = &stream->dcrop;
1442*4882a593Smuzhiyun 	struct v4l2_rect *input_win;
1443*4882a593Smuzhiyun 
1444*4882a593Smuzhiyun 	input_win = rkisp_get_isp_sd_win(&dev->isp_sdev);
1445*4882a593Smuzhiyun 
1446*4882a593Smuzhiyun 	switch (sel->target) {
1447*4882a593Smuzhiyun 	case V4L2_SEL_TGT_CROP_BOUNDS:
1448*4882a593Smuzhiyun 		sel->r.width = input_win->width;
1449*4882a593Smuzhiyun 		sel->r.height = input_win->height;
1450*4882a593Smuzhiyun 		sel->r.left = 0;
1451*4882a593Smuzhiyun 		sel->r.top = 0;
1452*4882a593Smuzhiyun 		break;
1453*4882a593Smuzhiyun 	case V4L2_SEL_TGT_CROP:
1454*4882a593Smuzhiyun 		sel->r = *dcrop;
1455*4882a593Smuzhiyun 		break;
1456*4882a593Smuzhiyun 	default:
1457*4882a593Smuzhiyun 		return -EINVAL;
1458*4882a593Smuzhiyun 	}
1459*4882a593Smuzhiyun 
1460*4882a593Smuzhiyun 	return 0;
1461*4882a593Smuzhiyun }
1462*4882a593Smuzhiyun 
rkisp_update_crop(struct rkisp_stream * stream,struct v4l2_rect * sel,const struct v4l2_rect * in)1463*4882a593Smuzhiyun static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream,
1464*4882a593Smuzhiyun 					    struct v4l2_rect *sel,
1465*4882a593Smuzhiyun 					    const struct v4l2_rect *in)
1466*4882a593Smuzhiyun {
1467*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1468*4882a593Smuzhiyun 	bool is_unite = dev->hw_dev->is_unite;
1469*4882a593Smuzhiyun 	u32 align = is_unite ? 4 : 2;
1470*4882a593Smuzhiyun 
1471*4882a593Smuzhiyun 	/* Not crop for MP bayer raw data and dmatx path */
1472*4882a593Smuzhiyun 	if ((stream->id == RKISP_STREAM_MP &&
1473*4882a593Smuzhiyun 	     stream->out_isp_fmt.fmt_type == FMT_BAYER) ||
1474*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX0 ||
1475*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX1 ||
1476*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX2 ||
1477*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_DMATX3 ||
1478*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_MPDS ||
1479*4882a593Smuzhiyun 	    stream->id == RKISP_STREAM_BPDS) {
1480*4882a593Smuzhiyun 		sel->left = 0;
1481*4882a593Smuzhiyun 		sel->top = 0;
1482*4882a593Smuzhiyun 		sel->width = in->width;
1483*4882a593Smuzhiyun 		sel->height = in->height;
1484*4882a593Smuzhiyun 		return sel;
1485*4882a593Smuzhiyun 	}
1486*4882a593Smuzhiyun 
1487*4882a593Smuzhiyun 	sel->left = ALIGN(sel->left, 2);
1488*4882a593Smuzhiyun 	sel->width = ALIGN(sel->width, align);
1489*4882a593Smuzhiyun 	sel->left = clamp_t(u32, sel->left, 0,
1490*4882a593Smuzhiyun 			    in->width - STREAM_MIN_MP_SP_INPUT_WIDTH);
1491*4882a593Smuzhiyun 	sel->top = clamp_t(u32, sel->top, 0,
1492*4882a593Smuzhiyun 			   in->height - STREAM_MIN_MP_SP_INPUT_HEIGHT);
1493*4882a593Smuzhiyun 	sel->width = clamp_t(u32, sel->width, STREAM_MIN_MP_SP_INPUT_WIDTH,
1494*4882a593Smuzhiyun 			     in->width - sel->left);
1495*4882a593Smuzhiyun 	sel->height = clamp_t(u32, sel->height, STREAM_MIN_MP_SP_INPUT_HEIGHT,
1496*4882a593Smuzhiyun 			      in->height - sel->top);
1497*4882a593Smuzhiyun 	if (is_unite && (sel->width + 2 * sel->left) != in->width) {
1498*4882a593Smuzhiyun 		sel->left = ALIGN_DOWN((in->width - sel->width) / 2, 2);
1499*4882a593Smuzhiyun 		v4l2_warn(&dev->v4l2_dev,
1500*4882a593Smuzhiyun 			  "try horizontal center crop(%d,%d)/%dx%d for dual isp\n",
1501*4882a593Smuzhiyun 			  sel->left, sel->top, sel->width, sel->height);
1502*4882a593Smuzhiyun 	}
1503*4882a593Smuzhiyun 	stream->is_crop_upd = true;
1504*4882a593Smuzhiyun 	return sel;
1505*4882a593Smuzhiyun }
1506*4882a593Smuzhiyun 
rkisp_s_selection(struct file * file,void * prv,struct v4l2_selection * sel)1507*4882a593Smuzhiyun static int rkisp_s_selection(struct file *file, void *prv,
1508*4882a593Smuzhiyun 			      struct v4l2_selection *sel)
1509*4882a593Smuzhiyun {
1510*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1511*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1512*4882a593Smuzhiyun 	struct v4l2_rect *dcrop = &stream->dcrop;
1513*4882a593Smuzhiyun 	const struct v4l2_rect *input_win;
1514*4882a593Smuzhiyun 
1515*4882a593Smuzhiyun 	if (sel->target != V4L2_SEL_TGT_CROP)
1516*4882a593Smuzhiyun 		return -EINVAL;
1517*4882a593Smuzhiyun 
1518*4882a593Smuzhiyun 	if (sel->flags != 0)
1519*4882a593Smuzhiyun 		return -EINVAL;
1520*4882a593Smuzhiyun 
1521*4882a593Smuzhiyun 	input_win = rkisp_get_isp_sd_win(&dev->isp_sdev);
1522*4882a593Smuzhiyun 	*dcrop = *rkisp_update_crop(stream, &sel->r, input_win);
1523*4882a593Smuzhiyun 	v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
1524*4882a593Smuzhiyun 		 "stream %d crop(%d,%d)/%dx%d\n", stream->id,
1525*4882a593Smuzhiyun 		 dcrop->left, dcrop->top, dcrop->width, dcrop->height);
1526*4882a593Smuzhiyun 
1527*4882a593Smuzhiyun 	return 0;
1528*4882a593Smuzhiyun }
1529*4882a593Smuzhiyun 
rkisp_querycap(struct file * file,void * priv,struct v4l2_capability * cap)1530*4882a593Smuzhiyun static int rkisp_querycap(struct file *file, void *priv,
1531*4882a593Smuzhiyun 			   struct v4l2_capability *cap)
1532*4882a593Smuzhiyun {
1533*4882a593Smuzhiyun 	struct rkisp_stream *stream = video_drvdata(file);
1534*4882a593Smuzhiyun 	struct device *dev = stream->ispdev->dev;
1535*4882a593Smuzhiyun 	struct video_device *vdev = video_devdata(file);
1536*4882a593Smuzhiyun 
1537*4882a593Smuzhiyun 	strlcpy(cap->card, vdev->name, sizeof(cap->card));
1538*4882a593Smuzhiyun 	snprintf(cap->driver, sizeof(cap->driver),
1539*4882a593Smuzhiyun 		 "%s_v%d", dev->driver->name,
1540*4882a593Smuzhiyun 		 stream->ispdev->isp_ver >> 4);
1541*4882a593Smuzhiyun 	snprintf(cap->bus_info, sizeof(cap->bus_info),
1542*4882a593Smuzhiyun 		 "platform:%s", dev_name(dev));
1543*4882a593Smuzhiyun 	cap->version = RKISP_DRIVER_VERSION;
1544*4882a593Smuzhiyun 	return 0;
1545*4882a593Smuzhiyun }
1546*4882a593Smuzhiyun 
1547*4882a593Smuzhiyun static const struct v4l2_ioctl_ops rkisp_v4l2_ioctl_ops = {
1548*4882a593Smuzhiyun 	.vidioc_reqbufs = vb2_ioctl_reqbufs,
1549*4882a593Smuzhiyun 	.vidioc_querybuf = vb2_ioctl_querybuf,
1550*4882a593Smuzhiyun 	.vidioc_create_bufs = vb2_ioctl_create_bufs,
1551*4882a593Smuzhiyun 	.vidioc_qbuf = vb2_ioctl_qbuf,
1552*4882a593Smuzhiyun 	.vidioc_expbuf = vb2_ioctl_expbuf,
1553*4882a593Smuzhiyun 	.vidioc_dqbuf = vb2_ioctl_dqbuf,
1554*4882a593Smuzhiyun 	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1555*4882a593Smuzhiyun 	.vidioc_streamon = vb2_ioctl_streamon,
1556*4882a593Smuzhiyun 	.vidioc_streamoff = vb2_ioctl_streamoff,
1557*4882a593Smuzhiyun 	.vidioc_enum_input = rkisp_enum_input,
1558*4882a593Smuzhiyun 	.vidioc_try_fmt_vid_cap_mplane = rkisp_try_fmt_vid_cap_mplane,
1559*4882a593Smuzhiyun 	.vidioc_enum_fmt_vid_cap = rkisp_enum_fmt_vid_cap_mplane,
1560*4882a593Smuzhiyun 	.vidioc_s_fmt_vid_cap_mplane = rkisp_s_fmt_vid_cap_mplane,
1561*4882a593Smuzhiyun 	.vidioc_g_fmt_vid_cap_mplane = rkisp_g_fmt_vid_cap_mplane,
1562*4882a593Smuzhiyun 	.vidioc_s_selection = rkisp_s_selection,
1563*4882a593Smuzhiyun 	.vidioc_g_selection = rkisp_g_selection,
1564*4882a593Smuzhiyun 	.vidioc_querycap = rkisp_querycap,
1565*4882a593Smuzhiyun 	.vidioc_enum_frameintervals = rkisp_enum_frameintervals,
1566*4882a593Smuzhiyun 	.vidioc_enum_framesizes = rkisp_enum_framesizes,
1567*4882a593Smuzhiyun 	.vidioc_default = rkisp_ioctl_default,
1568*4882a593Smuzhiyun };
1569*4882a593Smuzhiyun 
rkisp_buf_done_task(unsigned long arg)1570*4882a593Smuzhiyun static void rkisp_buf_done_task(unsigned long arg)
1571*4882a593Smuzhiyun {
1572*4882a593Smuzhiyun 	struct rkisp_stream *stream = (struct rkisp_stream *)arg;
1573*4882a593Smuzhiyun 	struct rkisp_buffer *buf = NULL;
1574*4882a593Smuzhiyun 	unsigned long lock_flags = 0;
1575*4882a593Smuzhiyun 	LIST_HEAD(local_list);
1576*4882a593Smuzhiyun 
1577*4882a593Smuzhiyun 	spin_lock_irqsave(&stream->vbq_lock, lock_flags);
1578*4882a593Smuzhiyun 	list_replace_init(&stream->buf_done_list, &local_list);
1579*4882a593Smuzhiyun 	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
1580*4882a593Smuzhiyun 
1581*4882a593Smuzhiyun 	while (!list_empty(&local_list)) {
1582*4882a593Smuzhiyun 		buf = list_first_entry(&local_list,
1583*4882a593Smuzhiyun 				       struct rkisp_buffer, queue);
1584*4882a593Smuzhiyun 		list_del(&buf->queue);
1585*4882a593Smuzhiyun 
1586*4882a593Smuzhiyun 		v4l2_dbg(2, rkisp_debug, &stream->ispdev->v4l2_dev,
1587*4882a593Smuzhiyun 			 "stream:%d seq:%d buf:0x%x done\n",
1588*4882a593Smuzhiyun 			 stream->id, buf->vb.sequence, buf->buff_addr[0]);
1589*4882a593Smuzhiyun 		vb2_buffer_done(&buf->vb.vb2_buf,
1590*4882a593Smuzhiyun 				stream->streaming ? VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR);
1591*4882a593Smuzhiyun 	}
1592*4882a593Smuzhiyun }
1593*4882a593Smuzhiyun 
rkisp_stream_buf_done(struct rkisp_stream * stream,struct rkisp_buffer * buf)1594*4882a593Smuzhiyun void rkisp_stream_buf_done(struct rkisp_stream *stream,
1595*4882a593Smuzhiyun 			   struct rkisp_buffer *buf)
1596*4882a593Smuzhiyun {
1597*4882a593Smuzhiyun 	unsigned long lock_flags = 0;
1598*4882a593Smuzhiyun 
1599*4882a593Smuzhiyun 	if (!stream || !buf)
1600*4882a593Smuzhiyun 		return;
1601*4882a593Smuzhiyun 	spin_lock_irqsave(&stream->vbq_lock, lock_flags);
1602*4882a593Smuzhiyun 	list_add_tail(&buf->queue, &stream->buf_done_list);
1603*4882a593Smuzhiyun 	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
1604*4882a593Smuzhiyun 	tasklet_schedule(&stream->buf_done_tasklet);
1605*4882a593Smuzhiyun }
1606*4882a593Smuzhiyun 
rkisp_stream_fast(struct work_struct * work)1607*4882a593Smuzhiyun static void rkisp_stream_fast(struct work_struct *work)
1608*4882a593Smuzhiyun {
1609*4882a593Smuzhiyun 	struct rkisp_capture_device *cap_dev =
1610*4882a593Smuzhiyun 		container_of(work, struct rkisp_capture_device, fast_work);
1611*4882a593Smuzhiyun 	struct rkisp_stream *stream = &cap_dev->stream[0];
1612*4882a593Smuzhiyun 	struct rkisp_device *ispdev = cap_dev->ispdev;
1613*4882a593Smuzhiyun 	struct v4l2_subdev *sd = ispdev->active_sensor->sd;
1614*4882a593Smuzhiyun 	int ret;
1615*4882a593Smuzhiyun 
1616*4882a593Smuzhiyun 	if (ispdev->isp_ver != ISP_V32)
1617*4882a593Smuzhiyun 		return;
1618*4882a593Smuzhiyun 
1619*4882a593Smuzhiyun 	rkisp_chk_tb_over(ispdev);
1620*4882a593Smuzhiyun 	if (ispdev->tb_head.complete != RKISP_TB_OK)
1621*4882a593Smuzhiyun 		return;
1622*4882a593Smuzhiyun 	ret = v4l2_pipeline_pm_get(&stream->vnode.vdev.entity);
1623*4882a593Smuzhiyun 	if (ret < 0) {
1624*4882a593Smuzhiyun 		dev_err(ispdev->dev, "%s PM get fail:%d\n", __func__, ret);
1625*4882a593Smuzhiyun 		ispdev->is_thunderboot = false;
1626*4882a593Smuzhiyun 		return;
1627*4882a593Smuzhiyun 	}
1628*4882a593Smuzhiyun 
1629*4882a593Smuzhiyun 	if (ispdev->hw_dev->dev_num > 1)
1630*4882a593Smuzhiyun 		ispdev->hw_dev->is_single = false;
1631*4882a593Smuzhiyun 	ispdev->is_pre_on = true;
1632*4882a593Smuzhiyun 	ispdev->is_rdbk_auto = true;
1633*4882a593Smuzhiyun 	ispdev->pipe.open(&ispdev->pipe, &stream->vnode.vdev.entity, true);
1634*4882a593Smuzhiyun 	v4l2_subdev_call(sd, video, s_stream, true);
1635*4882a593Smuzhiyun }
1636*4882a593Smuzhiyun 
rkisp_unregister_stream_vdev(struct rkisp_stream * stream)1637*4882a593Smuzhiyun void rkisp_unregister_stream_vdev(struct rkisp_stream *stream)
1638*4882a593Smuzhiyun {
1639*4882a593Smuzhiyun 	tasklet_kill(&stream->buf_done_tasklet);
1640*4882a593Smuzhiyun 	media_entity_cleanup(&stream->vnode.vdev.entity);
1641*4882a593Smuzhiyun 	video_unregister_device(&stream->vnode.vdev);
1642*4882a593Smuzhiyun }
1643*4882a593Smuzhiyun 
rkisp_register_stream_vdev(struct rkisp_stream * stream)1644*4882a593Smuzhiyun int rkisp_register_stream_vdev(struct rkisp_stream *stream)
1645*4882a593Smuzhiyun {
1646*4882a593Smuzhiyun 	struct rkisp_device *dev = stream->ispdev;
1647*4882a593Smuzhiyun 	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
1648*4882a593Smuzhiyun 	struct video_device *vdev = &stream->vnode.vdev;
1649*4882a593Smuzhiyun 	struct rkisp_vdev_node *node;
1650*4882a593Smuzhiyun 	struct media_entity *source, *sink;
1651*4882a593Smuzhiyun 	int ret = 0, pad;
1652*4882a593Smuzhiyun 
1653*4882a593Smuzhiyun 	mutex_init(&stream->apilock);
1654*4882a593Smuzhiyun 	node = vdev_to_node(vdev);
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun 	vdev->ioctl_ops = &rkisp_v4l2_ioctl_ops;
1657*4882a593Smuzhiyun 	vdev->release = video_device_release_empty;
1658*4882a593Smuzhiyun 	vdev->fops = &rkisp_fops;
1659*4882a593Smuzhiyun 	vdev->minor = -1;
1660*4882a593Smuzhiyun 	vdev->v4l2_dev = v4l2_dev;
1661*4882a593Smuzhiyun 	vdev->lock = &stream->apilock;
1662*4882a593Smuzhiyun 	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
1663*4882a593Smuzhiyun 				V4L2_CAP_STREAMING;
1664*4882a593Smuzhiyun 	video_set_drvdata(vdev, stream);
1665*4882a593Smuzhiyun 	vdev->vfl_dir = VFL_DIR_RX;
1666*4882a593Smuzhiyun 	node->pad.flags = MEDIA_PAD_FL_SINK;
1667*4882a593Smuzhiyun 	vdev->queue = &node->buf_queue;
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1670*4882a593Smuzhiyun 	if (ret < 0) {
1671*4882a593Smuzhiyun 		v4l2_err(v4l2_dev,
1672*4882a593Smuzhiyun 			 "video_register_device failed with error %d\n", ret);
1673*4882a593Smuzhiyun 		return ret;
1674*4882a593Smuzhiyun 	}
1675*4882a593Smuzhiyun 
1676*4882a593Smuzhiyun 	ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
1677*4882a593Smuzhiyun 	if (ret < 0)
1678*4882a593Smuzhiyun 		goto unreg;
1679*4882a593Smuzhiyun 
1680*4882a593Smuzhiyun 	source = &dev->csi_dev.sd.entity;
1681*4882a593Smuzhiyun 	switch (stream->id) {
1682*4882a593Smuzhiyun 	case RKISP_STREAM_DMATX0://CSI_SRC_CH1
1683*4882a593Smuzhiyun 	case RKISP_STREAM_DMATX1://CSI_SRC_CH2
1684*4882a593Smuzhiyun 	case RKISP_STREAM_DMATX2://CSI_SRC_CH3
1685*4882a593Smuzhiyun 	case RKISP_STREAM_DMATX3://CSI_SRC_CH4
1686*4882a593Smuzhiyun 		pad = stream->id;
1687*4882a593Smuzhiyun 		dev->csi_dev.sink[pad - 1].linked = true;
1688*4882a593Smuzhiyun 		dev->csi_dev.sink[pad - 1].index = BIT(pad - 1);
1689*4882a593Smuzhiyun 		break;
1690*4882a593Smuzhiyun 	default:
1691*4882a593Smuzhiyun 		source = &dev->isp_sdev.sd.entity;
1692*4882a593Smuzhiyun 		pad = RKISP_ISP_PAD_SOURCE_PATH;
1693*4882a593Smuzhiyun 	}
1694*4882a593Smuzhiyun 	sink = &vdev->entity;
1695*4882a593Smuzhiyun 	ret = media_create_pad_link(source, pad,
1696*4882a593Smuzhiyun 		sink, 0, stream->linked);
1697*4882a593Smuzhiyun 	if (ret < 0)
1698*4882a593Smuzhiyun 		goto unreg;
1699*4882a593Smuzhiyun 	INIT_LIST_HEAD(&stream->buf_done_list);
1700*4882a593Smuzhiyun 	tasklet_init(&stream->buf_done_tasklet,
1701*4882a593Smuzhiyun 		     rkisp_buf_done_task,
1702*4882a593Smuzhiyun 		     (unsigned long)stream);
1703*4882a593Smuzhiyun 	tasklet_disable(&stream->buf_done_tasklet);
1704*4882a593Smuzhiyun 	return 0;
1705*4882a593Smuzhiyun unreg:
1706*4882a593Smuzhiyun 	video_unregister_device(vdev);
1707*4882a593Smuzhiyun 	return ret;
1708*4882a593Smuzhiyun }
1709*4882a593Smuzhiyun 
rkisp_register_stream_vdevs(struct rkisp_device * dev)1710*4882a593Smuzhiyun int rkisp_register_stream_vdevs(struct rkisp_device *dev)
1711*4882a593Smuzhiyun {
1712*4882a593Smuzhiyun 	struct rkisp_capture_device *cap_dev = &dev->cap_dev;
1713*4882a593Smuzhiyun 	struct stream_config *st_cfg = &rkisp_mp_stream_config;
1714*4882a593Smuzhiyun 	int ret = 0;
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	memset(cap_dev, 0, sizeof(*cap_dev));
1717*4882a593Smuzhiyun 	cap_dev->ispdev = dev;
1718*4882a593Smuzhiyun 	atomic_set(&cap_dev->refcnt, 0);
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun 	if (dev->isp_ver <= ISP_V13) {
1721*4882a593Smuzhiyun 		if (dev->isp_ver == ISP_V12) {
1722*4882a593Smuzhiyun 			st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V12;
1723*4882a593Smuzhiyun 			st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V12;
1724*4882a593Smuzhiyun 		} else if (dev->isp_ver == ISP_V13) {
1725*4882a593Smuzhiyun 			st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V13;
1726*4882a593Smuzhiyun 			st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V13;
1727*4882a593Smuzhiyun 		}
1728*4882a593Smuzhiyun 		ret = rkisp_register_stream_v1x(dev);
1729*4882a593Smuzhiyun 	} else if (dev->isp_ver == ISP_V20) {
1730*4882a593Smuzhiyun 		ret = rkisp_register_stream_v20(dev);
1731*4882a593Smuzhiyun 	} else if (dev->isp_ver == ISP_V21) {
1732*4882a593Smuzhiyun 		st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V21;
1733*4882a593Smuzhiyun 		st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V21;
1734*4882a593Smuzhiyun 		ret = rkisp_register_stream_v21(dev);
1735*4882a593Smuzhiyun 	} else if (dev->isp_ver == ISP_V30) {
1736*4882a593Smuzhiyun 		st_cfg->max_rsz_width = dev->hw_dev->is_unite ?
1737*4882a593Smuzhiyun 					CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30;
1738*4882a593Smuzhiyun 		st_cfg->max_rsz_height = dev->hw_dev->is_unite ?
1739*4882a593Smuzhiyun 					 CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30;
1740*4882a593Smuzhiyun 		ret = rkisp_register_stream_v30(dev);
1741*4882a593Smuzhiyun 	} else if (dev->isp_ver == ISP_V32) {
1742*4882a593Smuzhiyun 		st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32;
1743*4882a593Smuzhiyun 		st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32;
1744*4882a593Smuzhiyun 		st_cfg = &rkisp_sp_stream_config;
1745*4882a593Smuzhiyun 		st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32;
1746*4882a593Smuzhiyun 		st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32;
1747*4882a593Smuzhiyun 		ret = rkisp_register_stream_v32(dev);
1748*4882a593Smuzhiyun 	} else if (dev->isp_ver == ISP_V32_L) {
1749*4882a593Smuzhiyun 		st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L;
1750*4882a593Smuzhiyun 		st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32_L;
1751*4882a593Smuzhiyun 		st_cfg = &rkisp_sp_stream_config;
1752*4882a593Smuzhiyun 		st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L;
1753*4882a593Smuzhiyun 		st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32_L;
1754*4882a593Smuzhiyun 		ret = rkisp_register_stream_v32(dev);
1755*4882a593Smuzhiyun 	}
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun 	INIT_WORK(&cap_dev->fast_work, rkisp_stream_fast);
1758*4882a593Smuzhiyun 	return ret;
1759*4882a593Smuzhiyun }
1760*4882a593Smuzhiyun 
rkisp_unregister_stream_vdevs(struct rkisp_device * dev)1761*4882a593Smuzhiyun void rkisp_unregister_stream_vdevs(struct rkisp_device *dev)
1762*4882a593Smuzhiyun {
1763*4882a593Smuzhiyun 	if (dev->isp_ver <= ISP_V13)
1764*4882a593Smuzhiyun 		rkisp_unregister_stream_v1x(dev);
1765*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V20)
1766*4882a593Smuzhiyun 		rkisp_unregister_stream_v20(dev);
1767*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V21)
1768*4882a593Smuzhiyun 		rkisp_unregister_stream_v21(dev);
1769*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V30)
1770*4882a593Smuzhiyun 		rkisp_unregister_stream_v30(dev);
1771*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L)
1772*4882a593Smuzhiyun 		rkisp_unregister_stream_v32(dev);
1773*4882a593Smuzhiyun }
1774*4882a593Smuzhiyun 
rkisp_mi_isr(u32 mis_val,struct rkisp_device * dev)1775*4882a593Smuzhiyun void rkisp_mi_isr(u32 mis_val, struct rkisp_device *dev)
1776*4882a593Smuzhiyun {
1777*4882a593Smuzhiyun 	if (dev->isp_ver <= ISP_V13)
1778*4882a593Smuzhiyun 		rkisp_mi_v1x_isr(mis_val, dev);
1779*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V20)
1780*4882a593Smuzhiyun 		rkisp_mi_v20_isr(mis_val, dev);
1781*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V21)
1782*4882a593Smuzhiyun 		rkisp_mi_v21_isr(mis_val, dev);
1783*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V30)
1784*4882a593Smuzhiyun 		rkisp_mi_v30_isr(mis_val, dev);
1785*4882a593Smuzhiyun 	else if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L)
1786*4882a593Smuzhiyun 		rkisp_mi_v32_isr(mis_val, dev);
1787*4882a593Smuzhiyun }
1788