xref: /OK3568_Linux_fs/kernel/drivers/media/platform/rockchip/isp/csi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/delay.h>
5*4882a593Smuzhiyun #include <linux/iopoll.h>
6*4882a593Smuzhiyun #include <linux/pm_runtime.h>
7*4882a593Smuzhiyun #include <linux/rk-camera-module.h>
8*4882a593Smuzhiyun #include <media/v4l2-common.h>
9*4882a593Smuzhiyun #include <media/v4l2-event.h>
10*4882a593Smuzhiyun #include <media/v4l2-fh.h>
11*4882a593Smuzhiyun #include <media/v4l2-ioctl.h>
12*4882a593Smuzhiyun #include <media/v4l2-subdev.h>
13*4882a593Smuzhiyun #include <media/videobuf2-dma-contig.h>
14*4882a593Smuzhiyun #include "dev.h"
15*4882a593Smuzhiyun #include "isp_external.h"
16*4882a593Smuzhiyun #include "regs.h"
17*4882a593Smuzhiyun 
get_remote_mipi_sensor(struct rkisp_device * dev,struct v4l2_subdev ** sensor_sd,u32 function)18*4882a593Smuzhiyun static void get_remote_mipi_sensor(struct rkisp_device *dev,
19*4882a593Smuzhiyun 				  struct v4l2_subdev **sensor_sd, u32 function)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	struct media_graph graph;
22*4882a593Smuzhiyun 	struct media_entity *entity = &dev->isp_sdev.sd.entity;
23*4882a593Smuzhiyun 	struct media_device *mdev = entity->graph_obj.mdev;
24*4882a593Smuzhiyun 	int ret;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 	/* Walk the graph to locate sensor nodes. */
27*4882a593Smuzhiyun 	mutex_lock(&mdev->graph_mutex);
28*4882a593Smuzhiyun 	ret = media_graph_walk_init(&graph, mdev);
29*4882a593Smuzhiyun 	if (ret) {
30*4882a593Smuzhiyun 		mutex_unlock(&mdev->graph_mutex);
31*4882a593Smuzhiyun 		*sensor_sd = NULL;
32*4882a593Smuzhiyun 		return;
33*4882a593Smuzhiyun 	}
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	media_graph_walk_start(&graph, entity);
36*4882a593Smuzhiyun 	while ((entity = media_graph_walk_next(&graph))) {
37*4882a593Smuzhiyun 		if (entity->function == function)
38*4882a593Smuzhiyun 			break;
39*4882a593Smuzhiyun 	}
40*4882a593Smuzhiyun 	mutex_unlock(&mdev->graph_mutex);
41*4882a593Smuzhiyun 	media_graph_walk_cleanup(&graph);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	if (entity)
44*4882a593Smuzhiyun 		*sensor_sd = media_entity_to_v4l2_subdev(entity);
45*4882a593Smuzhiyun 	else
46*4882a593Smuzhiyun 		*sensor_sd = NULL;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
get_remote_subdev(struct v4l2_subdev * sd)49*4882a593Smuzhiyun static struct v4l2_subdev *get_remote_subdev(struct v4l2_subdev *sd)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	struct media_pad *local, *remote;
52*4882a593Smuzhiyun 	struct v4l2_subdev *remote_sd = NULL;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	local = &sd->entity.pads[CSI_SINK];
55*4882a593Smuzhiyun 	if (!local)
56*4882a593Smuzhiyun 		goto end;
57*4882a593Smuzhiyun 	remote = media_entity_remote_pad(local);
58*4882a593Smuzhiyun 	if (!remote)
59*4882a593Smuzhiyun 		goto end;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	remote_sd = media_entity_to_v4l2_subdev(remote->entity);
62*4882a593Smuzhiyun end:
63*4882a593Smuzhiyun 	return remote_sd;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
rkisp_csi_link_setup(struct media_entity * entity,const struct media_pad * local,const struct media_pad * remote,u32 flags)66*4882a593Smuzhiyun static int rkisp_csi_link_setup(struct media_entity *entity,
67*4882a593Smuzhiyun 				 const struct media_pad *local,
68*4882a593Smuzhiyun 				 const struct media_pad *remote,
69*4882a593Smuzhiyun 				 u32 flags)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
72*4882a593Smuzhiyun 	struct rkisp_csi_device *csi;
73*4882a593Smuzhiyun 	struct rkisp_stream *stream = NULL;
74*4882a593Smuzhiyun 	int ret = 0;
75*4882a593Smuzhiyun 	u8 id;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	if (!sd)
78*4882a593Smuzhiyun 		return -ENODEV;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	csi = v4l2_get_subdevdata(sd);
81*4882a593Smuzhiyun 	if (local->flags & MEDIA_PAD_FL_SOURCE) {
82*4882a593Smuzhiyun 		id = local->index - 1;
83*4882a593Smuzhiyun 		if (id && id < RKISP_STREAM_DMATX3)
84*4882a593Smuzhiyun 			stream = &csi->ispdev->cap_dev.stream[id + 1];
85*4882a593Smuzhiyun 		if (flags & MEDIA_LNK_FL_ENABLED) {
86*4882a593Smuzhiyun 			if (csi->sink[id].linked) {
87*4882a593Smuzhiyun 				ret = -EBUSY;
88*4882a593Smuzhiyun 				goto out;
89*4882a593Smuzhiyun 			}
90*4882a593Smuzhiyun 			csi->sink[id].linked = true;
91*4882a593Smuzhiyun 			csi->sink[id].index = 1 << id;
92*4882a593Smuzhiyun 		} else {
93*4882a593Smuzhiyun 			csi->sink[id].linked = false;
94*4882a593Smuzhiyun 			csi->sink[id].index = 0;
95*4882a593Smuzhiyun 		}
96*4882a593Smuzhiyun 		if (stream)
97*4882a593Smuzhiyun 			stream->linked = csi->sink[id].linked;
98*4882a593Smuzhiyun 	}
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun out:
102*4882a593Smuzhiyun 	v4l2_err(sd, "pad%d is already linked\n", local->index);
103*4882a593Smuzhiyun 	return ret;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
rkisp_csi_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)106*4882a593Smuzhiyun static int rkisp_csi_g_mbus_config(struct v4l2_subdev *sd,
107*4882a593Smuzhiyun 				   unsigned int pad_id,
108*4882a593Smuzhiyun 				   struct v4l2_mbus_config *config)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun 	struct v4l2_subdev *remote_sd;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	if (!sd)
113*4882a593Smuzhiyun 		return -ENODEV;
114*4882a593Smuzhiyun 	remote_sd = get_remote_subdev(sd);
115*4882a593Smuzhiyun 	return v4l2_subdev_call(remote_sd, pad, get_mbus_config, pad_id, config);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
rkisp_csi_get_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)118*4882a593Smuzhiyun static int rkisp_csi_get_set_fmt(struct v4l2_subdev *sd,
119*4882a593Smuzhiyun 				  struct v4l2_subdev_pad_config *cfg,
120*4882a593Smuzhiyun 				  struct v4l2_subdev_format *fmt)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	struct v4l2_subdev *remote_sd;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	if (fmt->pad != CSI_SINK)
125*4882a593Smuzhiyun 		fmt->pad -= 1;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	if (!sd)
128*4882a593Smuzhiyun 		return -ENODEV;
129*4882a593Smuzhiyun 	remote_sd = get_remote_subdev(sd);
130*4882a593Smuzhiyun 	return v4l2_subdev_call(remote_sd, pad, get_fmt, NULL, fmt);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
rkisp_csi_s_stream(struct v4l2_subdev * sd,int on)133*4882a593Smuzhiyun static int rkisp_csi_s_stream(struct v4l2_subdev *sd, int on)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	struct rkisp_csi_device *csi = v4l2_get_subdevdata(sd);
136*4882a593Smuzhiyun 	struct rkisp_device *dev = csi->ispdev;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	csi->err_cnt = 0;
139*4882a593Smuzhiyun 	csi->irq_cnt = 0;
140*4882a593Smuzhiyun 	memset(csi->tx_first, 0, sizeof(csi->tx_first));
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	if (!IS_HDR_RDBK(dev->hdr.op_mode))
143*4882a593Smuzhiyun 		return 0;
144*4882a593Smuzhiyun 	if (on)
145*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_Y_STAT_CTRL, SW_Y_STAT_EN, true);
146*4882a593Smuzhiyun 	else
147*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_Y_STAT_CTRL, 0, true);
148*4882a593Smuzhiyun 	return 0;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
rkisp_csi_s_power(struct v4l2_subdev * sd,int on)151*4882a593Smuzhiyun static int rkisp_csi_s_power(struct v4l2_subdev *sd, int on)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun 	return 0;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun static const struct media_entity_operations rkisp_csi_media_ops = {
157*4882a593Smuzhiyun 	.link_setup = rkisp_csi_link_setup,
158*4882a593Smuzhiyun 	.link_validate = v4l2_subdev_link_validate,
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun static const struct v4l2_subdev_pad_ops rkisp_csi_pad_ops = {
162*4882a593Smuzhiyun 	.set_fmt = rkisp_csi_get_set_fmt,
163*4882a593Smuzhiyun 	.get_fmt = rkisp_csi_get_set_fmt,
164*4882a593Smuzhiyun 	.get_mbus_config = rkisp_csi_g_mbus_config,
165*4882a593Smuzhiyun };
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun static const struct v4l2_subdev_video_ops rkisp_csi_video_ops = {
168*4882a593Smuzhiyun 	.s_stream = rkisp_csi_s_stream,
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun static const struct v4l2_subdev_core_ops rkisp_csi_core_ops = {
172*4882a593Smuzhiyun 	.s_power = rkisp_csi_s_power,
173*4882a593Smuzhiyun };
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun static struct v4l2_subdev_ops rkisp_csi_ops = {
176*4882a593Smuzhiyun 	.core = &rkisp_csi_core_ops,
177*4882a593Smuzhiyun 	.video = &rkisp_csi_video_ops,
178*4882a593Smuzhiyun 	.pad = &rkisp_csi_pad_ops,
179*4882a593Smuzhiyun };
180*4882a593Smuzhiyun 
csi_config(struct rkisp_csi_device * csi)181*4882a593Smuzhiyun static int csi_config(struct rkisp_csi_device *csi)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	struct rkisp_device *dev = csi->ispdev;
184*4882a593Smuzhiyun 	struct rkisp_sensor_info *sensor = dev->active_sensor;
185*4882a593Smuzhiyun 	struct v4l2_subdev *mipi_sensor;
186*4882a593Smuzhiyun 	struct v4l2_ctrl *ctrl;
187*4882a593Smuzhiyun 	u32 emd_vc, emd_dt, mipi_ctrl;
188*4882a593Smuzhiyun 	int lanes, ret, i;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	/*
191*4882a593Smuzhiyun 	 * sensor->mbus is set in isp or d-phy notifier_bound function
192*4882a593Smuzhiyun 	 */
193*4882a593Smuzhiyun 	switch (sensor->mbus.flags & V4L2_MBUS_CSI2_LANES) {
194*4882a593Smuzhiyun 	case V4L2_MBUS_CSI2_4_LANE:
195*4882a593Smuzhiyun 		lanes = 4;
196*4882a593Smuzhiyun 		break;
197*4882a593Smuzhiyun 	case V4L2_MBUS_CSI2_3_LANE:
198*4882a593Smuzhiyun 		lanes = 3;
199*4882a593Smuzhiyun 		break;
200*4882a593Smuzhiyun 	case V4L2_MBUS_CSI2_2_LANE:
201*4882a593Smuzhiyun 		lanes = 2;
202*4882a593Smuzhiyun 		break;
203*4882a593Smuzhiyun 	case V4L2_MBUS_CSI2_1_LANE:
204*4882a593Smuzhiyun 		lanes = 1;
205*4882a593Smuzhiyun 		break;
206*4882a593Smuzhiyun 	default:
207*4882a593Smuzhiyun 		return -EINVAL;
208*4882a593Smuzhiyun 	}
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	emd_vc = 0xFF;
211*4882a593Smuzhiyun 	emd_dt = 0;
212*4882a593Smuzhiyun 	dev->hdr.sensor = NULL;
213*4882a593Smuzhiyun 	get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
214*4882a593Smuzhiyun 	if (mipi_sensor) {
215*4882a593Smuzhiyun 		ctrl = v4l2_ctrl_find(mipi_sensor->ctrl_handler,
216*4882a593Smuzhiyun 				      CIFISP_CID_EMB_VC);
217*4882a593Smuzhiyun 		if (ctrl)
218*4882a593Smuzhiyun 			emd_vc = v4l2_ctrl_g_ctrl(ctrl);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 		ctrl = v4l2_ctrl_find(mipi_sensor->ctrl_handler,
221*4882a593Smuzhiyun 				      CIFISP_CID_EMB_DT);
222*4882a593Smuzhiyun 		if (ctrl)
223*4882a593Smuzhiyun 			emd_dt = v4l2_ctrl_g_ctrl(ctrl);
224*4882a593Smuzhiyun 		dev->hdr.sensor = mipi_sensor;
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	dev->emd_dt = emd_dt;
228*4882a593Smuzhiyun 	dev->emd_vc = emd_vc;
229*4882a593Smuzhiyun 	dev->emd_data_idx = 0;
230*4882a593Smuzhiyun 	if (emd_vc <= CIF_ISP_ADD_DATA_VC_MAX) {
231*4882a593Smuzhiyun 		for (i = 0; i < RKISP_EMDDATA_FIFO_MAX; i++) {
232*4882a593Smuzhiyun 			ret = kfifo_alloc(&dev->emd_data_fifo[i].mipi_kfifo,
233*4882a593Smuzhiyun 					  CIFISP_ADD_DATA_FIFO_SIZE,
234*4882a593Smuzhiyun 					  GFP_ATOMIC);
235*4882a593Smuzhiyun 			if (ret) {
236*4882a593Smuzhiyun 				v4l2_err(&dev->v4l2_dev,
237*4882a593Smuzhiyun 					 "kfifo_alloc failed with error %d\n",
238*4882a593Smuzhiyun 					 ret);
239*4882a593Smuzhiyun 				return ret;
240*4882a593Smuzhiyun 			}
241*4882a593Smuzhiyun 		}
242*4882a593Smuzhiyun 	}
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	if (dev->isp_ver == ISP_V13 ||
245*4882a593Smuzhiyun 	    dev->isp_ver == ISP_V12) {
246*4882a593Smuzhiyun 		/* lanes */
247*4882a593Smuzhiyun 		rkisp_write(dev, CIF_ISP_CSI0_CTRL1, lanes - 1, true);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 		/* linecnt */
250*4882a593Smuzhiyun 		rkisp_write(dev, CIF_ISP_CSI0_CTRL2, 0x3FFF, true);
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 		/* Configure Data Type and Virtual Channel */
253*4882a593Smuzhiyun 		rkisp_write(dev, CIF_ISP_CSI0_DATA_IDS_1,
254*4882a593Smuzhiyun 			    csi->mipi_di[0] | csi->mipi_di[1] << 8, true);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 		/* clear interrupts state */
257*4882a593Smuzhiyun 		rkisp_read(dev, CIF_ISP_CSI0_ERR1, true);
258*4882a593Smuzhiyun 		rkisp_read(dev, CIF_ISP_CSI0_ERR2, true);
259*4882a593Smuzhiyun 		rkisp_read(dev, CIF_ISP_CSI0_ERR3, true);
260*4882a593Smuzhiyun 		/* set interrupts mask */
261*4882a593Smuzhiyun 		rkisp_write(dev, CIF_ISP_CSI0_MASK1, 0x1FFFFFF0, true);
262*4882a593Smuzhiyun 		rkisp_write(dev, CIF_ISP_CSI0_MASK2, 0x03FFFFFF, true);
263*4882a593Smuzhiyun 		rkisp_write(dev, CIF_ISP_CSI0_MASK3,
264*4882a593Smuzhiyun 			    CIF_ISP_CSI0_IMASK_FRAME_END(0x3F) |
265*4882a593Smuzhiyun 			    CIF_ISP_CSI0_IMASK_RAW0_OUT_V_END |
266*4882a593Smuzhiyun 			    CIF_ISP_CSI0_IMASK_RAW1_OUT_V_END |
267*4882a593Smuzhiyun 			    CIF_ISP_CSI0_IMASK_LINECNT, true);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 		v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
270*4882a593Smuzhiyun 			 "CSI0_CTRL1 0x%08x\n"
271*4882a593Smuzhiyun 			 "CSI0_IDS 0x%08x\n"
272*4882a593Smuzhiyun 			 "CSI0_MASK3 0x%08x\n",
273*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_ISP_CSI0_CTRL1, true),
274*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_ISP_CSI0_DATA_IDS_1, true),
275*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_ISP_CSI0_MASK3, true));
276*4882a593Smuzhiyun 	} else if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) {
277*4882a593Smuzhiyun 		bool is_feature_on = dev->hw_dev->is_feature_on;
278*4882a593Smuzhiyun 		u64 iq_feature = dev->hw_dev->iq_feature;
279*4882a593Smuzhiyun 		struct rkmodule_hdr_cfg hdr_cfg;
280*4882a593Smuzhiyun 		u32 val, mask;
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 		dev->hdr.op_mode = HDR_NORMAL;
283*4882a593Smuzhiyun 		dev->hdr.esp_mode = HDR_NORMAL_VC;
284*4882a593Smuzhiyun 		memset(&hdr_cfg, 0, sizeof(hdr_cfg));
285*4882a593Smuzhiyun 		if (rkisp_csi_get_hdr_cfg(dev, &hdr_cfg) == 0) {
286*4882a593Smuzhiyun 			dev->hdr.op_mode = hdr_cfg.hdr_mode;
287*4882a593Smuzhiyun 			dev->hdr.esp_mode = hdr_cfg.esp.mode;
288*4882a593Smuzhiyun 		}
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 		/* normal read back mode */
291*4882a593Smuzhiyun 		if (dev->hdr.op_mode == HDR_NORMAL &&
292*4882a593Smuzhiyun 		    (dev->isp_inp & INP_RAWRD2 || !dev->hw_dev->is_single))
293*4882a593Smuzhiyun 			dev->hdr.op_mode = HDR_RDBK_FRAME1;
294*4882a593Smuzhiyun 		/* HDR on the fly for isp21 */
295*4882a593Smuzhiyun 		if (dev->isp_ver == ISP_V21 && !(dev->isp_inp & INP_RAWRD2))
296*4882a593Smuzhiyun 			if (dev->hdr.op_mode == HDR_RDBK_FRAME2)
297*4882a593Smuzhiyun 				dev->hdr.op_mode = HDR_LINEX2_DDR;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		/* op_mode update by mi_cfg_upd */
300*4882a593Smuzhiyun 		if (!dev->hw_dev->is_mi_update)
301*4882a593Smuzhiyun 			rkisp_write(dev, CSI2RX_CTRL0,
302*4882a593Smuzhiyun 				    SW_IBUF_OP_MODE(dev->hdr.op_mode) |
303*4882a593Smuzhiyun 				    SW_HDR_ESP_MODE(dev->hdr.esp_mode), true);
304*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_CTRL1, lanes - 1, true);
305*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_CTRL2, 0x3FFF, true);
306*4882a593Smuzhiyun 		val = SW_CSI_ID1(csi->mipi_di[1]) |
307*4882a593Smuzhiyun 		      SW_CSI_ID2(csi->mipi_di[2]) |
308*4882a593Smuzhiyun 		      SW_CSI_ID3(csi->mipi_di[3]);
309*4882a593Smuzhiyun 		mask = SW_CSI_ID1(0xff) | SW_CSI_ID2(0xff) | SW_CSI_ID3(0xff);
310*4882a593Smuzhiyun 		/* CSI_ID0 is for dmarx when read back mode */
311*4882a593Smuzhiyun 		if (dev->hw_dev->is_single) {
312*4882a593Smuzhiyun 			val |= SW_CSI_ID0(csi->mipi_di[0]);
313*4882a593Smuzhiyun 			rkisp_write(dev, CSI2RX_DATA_IDS_1, val, true);
314*4882a593Smuzhiyun 		} else {
315*4882a593Smuzhiyun 			rkisp_set_bits(dev, CSI2RX_DATA_IDS_1, mask, val, true);
316*4882a593Smuzhiyun 			for (i = 0; i < dev->hw_dev->dev_num; i++) {
317*4882a593Smuzhiyun 				if (dev->hw_dev->isp[i] &&
318*4882a593Smuzhiyun 				    !dev->hw_dev->isp[i]->is_hw_link)
319*4882a593Smuzhiyun 					continue;
320*4882a593Smuzhiyun 				rkisp_set_bits(dev->hw_dev->isp[i],
321*4882a593Smuzhiyun 					CSI2RX_DATA_IDS_1, mask, val, false);
322*4882a593Smuzhiyun 			}
323*4882a593Smuzhiyun 		}
324*4882a593Smuzhiyun 		val = SW_CSI_ID4(csi->mipi_di[4]);
325*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_DATA_IDS_2, val, true);
326*4882a593Smuzhiyun 		/* clear interrupts state */
327*4882a593Smuzhiyun 		rkisp_read(dev, CSI2RX_ERR_PHY, true);
328*4882a593Smuzhiyun 		/* set interrupts mask */
329*4882a593Smuzhiyun 		val = PHY_ERR_SOTHS | PHY_ERR_SOTSYNCHS |
330*4882a593Smuzhiyun 			PHY_ERR_EOTSYNCHS | PHY_ERR_ESC | PHY_ERR_CTL;
331*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_MASK_PHY, val, true);
332*4882a593Smuzhiyun 		val = PACKET_ERR_F_BNDRY_MATCG | PACKET_ERR_F_SEQ |
333*4882a593Smuzhiyun 			PACKET_ERR_FRAME_DATA | PACKET_ERR_ECC_1BIT |
334*4882a593Smuzhiyun 			PACKET_ERR_ECC_2BIT | PACKET_ERR_CHECKSUM;
335*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_MASK_PACKET, val, true);
336*4882a593Smuzhiyun 		val = AFIFO0_OVERFLOW | AFIFO1X_OVERFLOW |
337*4882a593Smuzhiyun 			LAFIFO1X_OVERFLOW | AFIFO2X_OVERFLOW |
338*4882a593Smuzhiyun 			IBUFX3_OVERFLOW | IBUF3R_OVERFLOW |
339*4882a593Smuzhiyun 			Y_STAT_AFIFOX3_OVERFLOW;
340*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_MASK_OVERFLOW, val, true);
341*4882a593Smuzhiyun 		val = RAW0_WR_FRAME | RAW1_WR_FRAME | RAW2_WR_FRAME |
342*4882a593Smuzhiyun 			RAW_WR_SIZE_ERR | MIPI_LINECNT |
343*4882a593Smuzhiyun 			RAW_RD_SIZE_ERR | RAW0_Y_STATE |
344*4882a593Smuzhiyun 			RAW1_Y_STATE | RAW2_Y_STATE;
345*4882a593Smuzhiyun 		if (dev->isp_ver == ISP_V20)
346*4882a593Smuzhiyun 			val |= MIPI_DROP_FRM;
347*4882a593Smuzhiyun 		else
348*4882a593Smuzhiyun 			val |= ISP21_MIPI_DROP_FRM;
349*4882a593Smuzhiyun 		rkisp_write(dev, CSI2RX_MASK_STAT, val, true);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 		/* hdr merge */
352*4882a593Smuzhiyun 		switch (dev->hdr.op_mode) {
353*4882a593Smuzhiyun 		case HDR_RDBK_FRAME2:
354*4882a593Smuzhiyun 		case HDR_FRAMEX2_DDR:
355*4882a593Smuzhiyun 		case HDR_LINEX2_DDR:
356*4882a593Smuzhiyun 		case HDR_LINEX2_NO_DDR:
357*4882a593Smuzhiyun 			val = SW_HDRMGE_EN |
358*4882a593Smuzhiyun 			      SW_HDRMGE_MODE_FRAMEX2;
359*4882a593Smuzhiyun 			break;
360*4882a593Smuzhiyun 		case HDR_RDBK_FRAME3:
361*4882a593Smuzhiyun 		case HDR_FRAMEX3_DDR:
362*4882a593Smuzhiyun 		case HDR_LINEX3_DDR:
363*4882a593Smuzhiyun 			val = SW_HDRMGE_EN |
364*4882a593Smuzhiyun 			      SW_HDRMGE_MODE_FRAMEX3;
365*4882a593Smuzhiyun 			break;
366*4882a593Smuzhiyun 		default:
367*4882a593Smuzhiyun 			val = 0;
368*4882a593Smuzhiyun 		}
369*4882a593Smuzhiyun 		if (is_feature_on) {
370*4882a593Smuzhiyun 			if ((ISP2X_MODULE_HDRMGE & ~iq_feature) && (val & SW_HDRMGE_EN)) {
371*4882a593Smuzhiyun 				v4l2_err(&dev->v4l2_dev, "hdrmge is not supported\n");
372*4882a593Smuzhiyun 				return -EINVAL;
373*4882a593Smuzhiyun 			}
374*4882a593Smuzhiyun 		}
375*4882a593Smuzhiyun 		rkisp_write(dev, ISP_HDRMGE_BASE, val, false);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 		v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
378*4882a593Smuzhiyun 			 "CSI2RX_IDS 0x%08x 0x%08x\n",
379*4882a593Smuzhiyun 			 rkisp_read(dev, CSI2RX_DATA_IDS_1, true),
380*4882a593Smuzhiyun 			 rkisp_read(dev, CSI2RX_DATA_IDS_2, true));
381*4882a593Smuzhiyun 	} else {
382*4882a593Smuzhiyun 		mipi_ctrl = CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
383*4882a593Smuzhiyun 			    CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
384*4882a593Smuzhiyun 			    CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
385*4882a593Smuzhiyun 			    CIF_MIPI_CTRL_CLOCKLANE_ENA;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_CTRL, mipi_ctrl, true);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 		/* Configure Data Type and Virtual Channel */
390*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_IMG_DATA_SEL,
391*4882a593Smuzhiyun 			    csi->mipi_di[0], true);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_ADD_DATA_SEL_1,
394*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_DT(emd_dt) |
395*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_VC(emd_vc), true);
396*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_ADD_DATA_SEL_2,
397*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_DT(emd_dt) |
398*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_VC(emd_vc), true);
399*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_ADD_DATA_SEL_3,
400*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_DT(emd_dt) |
401*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_VC(emd_vc), true);
402*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_ADD_DATA_SEL_4,
403*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_DT(emd_dt) |
404*4882a593Smuzhiyun 			    CIF_MIPI_DATA_SEL_VC(emd_vc), true);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 		/* Clear MIPI interrupts */
407*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_ICR, ~0, true);
408*4882a593Smuzhiyun 		/*
409*4882a593Smuzhiyun 		 * Disable CIF_MIPI_ERR_DPHY interrupt here temporary for
410*4882a593Smuzhiyun 		 * isp bus may be dead when switch isp.
411*4882a593Smuzhiyun 		 */
412*4882a593Smuzhiyun 		rkisp_write(dev, CIF_MIPI_IMSC,
413*4882a593Smuzhiyun 			    CIF_MIPI_FRAME_END | CIF_MIPI_ERR_CSI |
414*4882a593Smuzhiyun 			    CIF_MIPI_ERR_DPHY | CIF_MIPI_SYNC_FIFO_OVFLW(0x0F) |
415*4882a593Smuzhiyun 			    CIF_MIPI_ADD_DATA_OVFLW, true);
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 		v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
418*4882a593Smuzhiyun 			 "\n  MIPI_CTRL 0x%08x\n"
419*4882a593Smuzhiyun 			 "  MIPI_IMG_DATA_SEL 0x%08x\n"
420*4882a593Smuzhiyun 			 "  MIPI_STATUS 0x%08x\n"
421*4882a593Smuzhiyun 			 "  MIPI_IMSC 0x%08x\n",
422*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_MIPI_CTRL, true),
423*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_MIPI_IMG_DATA_SEL, true),
424*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_MIPI_STATUS, true),
425*4882a593Smuzhiyun 			 rkisp_read(dev, CIF_MIPI_IMSC, true));
426*4882a593Smuzhiyun 	}
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return 0;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
rkisp_expander_config(struct rkisp_device * dev,struct rkmodule_hdr_cfg * cfg,bool on)431*4882a593Smuzhiyun int rkisp_expander_config(struct rkisp_device *dev,
432*4882a593Smuzhiyun 			  struct rkmodule_hdr_cfg *cfg, bool on)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun 	struct rkmodule_hdr_cfg hdr_cfg;
435*4882a593Smuzhiyun 	u32 i, val, num, d0, d1, drop_bit = 0;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	if (dev->isp_ver != ISP_V32)
438*4882a593Smuzhiyun 		return 0;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	if (!on) {
441*4882a593Smuzhiyun 		rkisp_write(dev, ISP32_EXPD_CTRL, 0, false);
442*4882a593Smuzhiyun 		return 0;
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	if (!cfg) {
446*4882a593Smuzhiyun 		if (rkisp_csi_get_hdr_cfg(dev, &hdr_cfg) != 0)
447*4882a593Smuzhiyun 			goto err;
448*4882a593Smuzhiyun 		cfg = &hdr_cfg;
449*4882a593Smuzhiyun 	}
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	if (cfg->hdr_mode != HDR_COMPR)
452*4882a593Smuzhiyun 		return 0;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	/* compressed data max 12bit and src data max 20bit */
455*4882a593Smuzhiyun 	if (cfg->compr.bit > 20)
456*4882a593Smuzhiyun 		drop_bit = cfg->compr.bit - 20;
457*4882a593Smuzhiyun 	dev->hdr.compr_bit = cfg->compr.bit - drop_bit;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	num = cfg->compr.segment;
460*4882a593Smuzhiyun 	for (i = 0; i < num; i++) {
461*4882a593Smuzhiyun 		val = cfg->compr.slope_k[i];
462*4882a593Smuzhiyun 		rkisp_write(dev, ISP32_EXPD_K0 + i * 4, val, false);
463*4882a593Smuzhiyun 	}
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	d0 = 0;
466*4882a593Smuzhiyun 	d1 = cfg->compr.data_compr[0];
467*4882a593Smuzhiyun 	val = ISP32_EXPD_DATA(d0, d1 > 0xfff ? 0xfff : d1);
468*4882a593Smuzhiyun 	rkisp_write(dev, ISP32_EXPD_X00_01, val, false);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	d1 = cfg->compr.data_src_shitf[0];
471*4882a593Smuzhiyun 	val = ISP32_EXPD_DATA(d0, drop_bit ? d1 >> drop_bit : d1);
472*4882a593Smuzhiyun 	rkisp_write(dev, ISP32_EXPD_Y00_01, val, false);
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	for (i = 1; i < num - 1; i += 2) {
475*4882a593Smuzhiyun 		d0 = cfg->compr.data_compr[i];
476*4882a593Smuzhiyun 		d1 = cfg->compr.data_compr[i + 1];
477*4882a593Smuzhiyun 		val = ISP32_EXPD_DATA(d0 > 0xfff ? 0xfff : d0,
478*4882a593Smuzhiyun 				      d1 > 0xfff ? 0xfff : d1);
479*4882a593Smuzhiyun 		rkisp_write(dev, ISP32_EXPD_X00_01 + (i + 1) * 2, val, false);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 		d0 = cfg->compr.data_src_shitf[i];
482*4882a593Smuzhiyun 		d1 = cfg->compr.data_src_shitf[i + 1];
483*4882a593Smuzhiyun 		if (drop_bit) {
484*4882a593Smuzhiyun 			d0 = d0 >> drop_bit;
485*4882a593Smuzhiyun 			d1 = d1 >> drop_bit;
486*4882a593Smuzhiyun 		}
487*4882a593Smuzhiyun 		val = ISP32_EXPD_DATA(d0, d1);
488*4882a593Smuzhiyun 		rkisp_write(dev, ISP32_EXPD_Y00_01 + (i + 1) * 2, val, false);
489*4882a593Smuzhiyun 	}
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	/* the last valid point */
492*4882a593Smuzhiyun 	val = cfg->compr.data_compr[i];
493*4882a593Smuzhiyun 	val = val > 0xfff ? 0xfff : val;
494*4882a593Smuzhiyun 	d0 = ISP32_EXPD_DATA(val, val);
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	val = cfg->compr.data_src_shitf[i];
497*4882a593Smuzhiyun 	val = drop_bit ? val >> drop_bit : val;
498*4882a593Smuzhiyun 	d1 = ISP32_EXPD_DATA(val, val);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	num = HDR_COMPR_SEGMENT_16;
501*4882a593Smuzhiyun 	for (; i < num - 1; i += 2) {
502*4882a593Smuzhiyun 		rkisp_write(dev, ISP32_EXPD_X00_01 + (i + 1) * 2, d0, false);
503*4882a593Smuzhiyun 		rkisp_write(dev, ISP32_EXPD_Y00_01 + (i + 1) * 2, d1, false);
504*4882a593Smuzhiyun 	}
505*4882a593Smuzhiyun 	rkisp_write(dev, ISP32_EXPD_Y16, val, false);
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	switch (cfg->compr.segment) {
508*4882a593Smuzhiyun 	case HDR_COMPR_SEGMENT_12:
509*4882a593Smuzhiyun 		num = 1;
510*4882a593Smuzhiyun 		break;
511*4882a593Smuzhiyun 	case HDR_COMPR_SEGMENT_16:
512*4882a593Smuzhiyun 		num = 2;
513*4882a593Smuzhiyun 		break;
514*4882a593Smuzhiyun 	default:
515*4882a593Smuzhiyun 		num = 0;
516*4882a593Smuzhiyun 	}
517*4882a593Smuzhiyun 	val = ISP32_EXPD_EN |
518*4882a593Smuzhiyun 	      ISP32_EXPD_MODE(num) |
519*4882a593Smuzhiyun 	      ISP32_EXPD_K_SHIFT(cfg->compr.k_shift);
520*4882a593Smuzhiyun 	rkisp_write(dev, ISP32_EXPD_CTRL, val, false);
521*4882a593Smuzhiyun 	return 0;
522*4882a593Smuzhiyun err:
523*4882a593Smuzhiyun 	return -EINVAL;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun 
rkisp_csi_get_hdr_cfg(struct rkisp_device * dev,void * arg)526*4882a593Smuzhiyun int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun 	struct rkmodule_hdr_cfg *cfg = arg;
529*4882a593Smuzhiyun 	struct v4l2_subdev *sd = NULL;
530*4882a593Smuzhiyun 	u32 type;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	if (dev->isp_inp & INP_CSI) {
533*4882a593Smuzhiyun 		type = MEDIA_ENT_F_CAM_SENSOR;
534*4882a593Smuzhiyun 	} else if (dev->isp_inp & INP_CIF) {
535*4882a593Smuzhiyun 		type = MEDIA_ENT_F_PROC_VIDEO_COMPOSER;
536*4882a593Smuzhiyun 	} else {
537*4882a593Smuzhiyun 		switch (dev->isp_inp & 0x7) {
538*4882a593Smuzhiyun 		case INP_RAWRD2 | INP_RAWRD0:
539*4882a593Smuzhiyun 			cfg->hdr_mode = HDR_RDBK_FRAME2;
540*4882a593Smuzhiyun 			break;
541*4882a593Smuzhiyun 		case INP_RAWRD2 | INP_RAWRD1 | INP_RAWRD0:
542*4882a593Smuzhiyun 			cfg->hdr_mode = HDR_RDBK_FRAME3;
543*4882a593Smuzhiyun 			break;
544*4882a593Smuzhiyun 		default: //INP_RAWRD2
545*4882a593Smuzhiyun 			cfg->hdr_mode = HDR_RDBK_FRAME1;
546*4882a593Smuzhiyun 		}
547*4882a593Smuzhiyun 		return 0;
548*4882a593Smuzhiyun 	}
549*4882a593Smuzhiyun 	get_remote_mipi_sensor(dev, &sd, type);
550*4882a593Smuzhiyun 	if (!sd) {
551*4882a593Smuzhiyun 		v4l2_err(&dev->v4l2_dev, "%s don't find subdev\n", __func__);
552*4882a593Smuzhiyun 		return -EINVAL;
553*4882a593Smuzhiyun 	}
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	return v4l2_subdev_call(sd, core, ioctl, RKMODULE_GET_HDR_CFG, cfg);
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun 
rkisp_csi_config_patch(struct rkisp_device * dev)558*4882a593Smuzhiyun int rkisp_csi_config_patch(struct rkisp_device *dev)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun 	int val = 0, ret = 0;
561*4882a593Smuzhiyun 	struct v4l2_subdev *mipi_sensor;
562*4882a593Smuzhiyun 	bool is_feature_on = dev->hw_dev->is_feature_on;
563*4882a593Smuzhiyun 	u64 iq_feature = dev->hw_dev->iq_feature;
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	if (dev->isp_inp & INP_CSI) {
566*4882a593Smuzhiyun 		dev->hw_dev->mipi_dev_id = dev->dev_id;
567*4882a593Smuzhiyun 		ret = csi_config(&dev->csi_dev);
568*4882a593Smuzhiyun 	} else {
569*4882a593Smuzhiyun 		struct rkmodule_hdr_cfg hdr_cfg;
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 		memset(&hdr_cfg, 0, sizeof(hdr_cfg));
572*4882a593Smuzhiyun 		ret = rkisp_csi_get_hdr_cfg(dev, &hdr_cfg);
573*4882a593Smuzhiyun 		if (dev->isp_inp & INP_CIF) {
574*4882a593Smuzhiyun 			struct rkisp_vicap_mode mode;
575*4882a593Smuzhiyun 			int buf_cnt;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 			memset(&mode, 0, sizeof(mode));
578*4882a593Smuzhiyun 			mode.name = dev->name;
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 			get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
581*4882a593Smuzhiyun 			if (!mipi_sensor)
582*4882a593Smuzhiyun 				return -EINVAL;
583*4882a593Smuzhiyun 			dev->hdr.op_mode = HDR_NORMAL;
584*4882a593Smuzhiyun 			dev->hdr.esp_mode = HDR_NORMAL_VC;
585*4882a593Smuzhiyun 			if (!ret) {
586*4882a593Smuzhiyun 				dev->hdr.op_mode = hdr_cfg.hdr_mode;
587*4882a593Smuzhiyun 				dev->hdr.esp_mode = hdr_cfg.esp.mode;
588*4882a593Smuzhiyun 				rkisp_expander_config(dev, &hdr_cfg, true);
589*4882a593Smuzhiyun 			}
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 			/* normal read back mode default */
592*4882a593Smuzhiyun 			if (dev->hdr.op_mode == HDR_NORMAL || dev->hdr.op_mode == HDR_COMPR)
593*4882a593Smuzhiyun 				dev->hdr.op_mode = HDR_RDBK_FRAME1;
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 			if (dev->isp_inp == INP_CIF && dev->isp_ver > ISP_V21)
596*4882a593Smuzhiyun 				mode.rdbk_mode = dev->is_rdbk_auto ? RKISP_VICAP_RDBK_AUTO : RKISP_VICAP_ONLINE;
597*4882a593Smuzhiyun 			else
598*4882a593Smuzhiyun 				mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
599*4882a593Smuzhiyun 			v4l2_subdev_call(mipi_sensor, core, ioctl, RKISP_VICAP_CMD_MODE, &mode);
600*4882a593Smuzhiyun 			dev->vicap_in = mode.input;
601*4882a593Smuzhiyun 			/* vicap direct to isp */
602*4882a593Smuzhiyun 			if (dev->isp_ver >= ISP_V30 && !mode.rdbk_mode) {
603*4882a593Smuzhiyun 				switch (dev->hdr.op_mode) {
604*4882a593Smuzhiyun 				case HDR_RDBK_FRAME3:
605*4882a593Smuzhiyun 					dev->hdr.op_mode = HDR_LINEX3_DDR;
606*4882a593Smuzhiyun 					break;
607*4882a593Smuzhiyun 				case HDR_RDBK_FRAME2:
608*4882a593Smuzhiyun 					dev->hdr.op_mode = HDR_LINEX2_DDR;
609*4882a593Smuzhiyun 					break;
610*4882a593Smuzhiyun 				default:
611*4882a593Smuzhiyun 					dev->hdr.op_mode = HDR_NORMAL;
612*4882a593Smuzhiyun 				}
613*4882a593Smuzhiyun 				if (dev->hdr.op_mode != HDR_NORMAL) {
614*4882a593Smuzhiyun 					buf_cnt = 1;
615*4882a593Smuzhiyun 					v4l2_subdev_call(mipi_sensor, core, ioctl,
616*4882a593Smuzhiyun 							 RKISP_VICAP_CMD_INIT_BUF, &buf_cnt);
617*4882a593Smuzhiyun 				}
618*4882a593Smuzhiyun 			} else if (mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
619*4882a593Smuzhiyun 				buf_cnt = RKISP_VICAP_BUF_CNT;
620*4882a593Smuzhiyun 				v4l2_subdev_call(mipi_sensor, core, ioctl,
621*4882a593Smuzhiyun 						 RKISP_VICAP_CMD_INIT_BUF, &buf_cnt);
622*4882a593Smuzhiyun 			}
623*4882a593Smuzhiyun 		} else {
624*4882a593Smuzhiyun 			dev->hdr.op_mode = hdr_cfg.hdr_mode;
625*4882a593Smuzhiyun 		}
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 		if (!dev->hw_dev->is_mi_update)
628*4882a593Smuzhiyun 			rkisp_unite_write(dev, CSI2RX_CTRL0,
629*4882a593Smuzhiyun 					  SW_IBUF_OP_MODE(dev->hdr.op_mode),
630*4882a593Smuzhiyun 					  true, dev->hw_dev->is_unite);
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 		/* hdr merge */
633*4882a593Smuzhiyun 		switch (dev->hdr.op_mode) {
634*4882a593Smuzhiyun 		case HDR_RDBK_FRAME2:
635*4882a593Smuzhiyun 		case HDR_FRAMEX2_DDR:
636*4882a593Smuzhiyun 		case HDR_LINEX2_DDR:
637*4882a593Smuzhiyun 		case HDR_LINEX2_NO_DDR:
638*4882a593Smuzhiyun 			val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX2;
639*4882a593Smuzhiyun 			break;
640*4882a593Smuzhiyun 		case HDR_RDBK_FRAME3:
641*4882a593Smuzhiyun 		case HDR_FRAMEX3_DDR:
642*4882a593Smuzhiyun 		case HDR_LINEX3_DDR:
643*4882a593Smuzhiyun 			val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX3;
644*4882a593Smuzhiyun 			break;
645*4882a593Smuzhiyun 		default:
646*4882a593Smuzhiyun 			val = 0;
647*4882a593Smuzhiyun 		}
648*4882a593Smuzhiyun 		if (is_feature_on) {
649*4882a593Smuzhiyun 			if ((ISP2X_MODULE_HDRMGE & ~iq_feature) && (val & SW_HDRMGE_EN)) {
650*4882a593Smuzhiyun 				v4l2_err(&dev->v4l2_dev, "hdrmge is not supported\n");
651*4882a593Smuzhiyun 				return -EINVAL;
652*4882a593Smuzhiyun 			}
653*4882a593Smuzhiyun 		}
654*4882a593Smuzhiyun 		rkisp_unite_write(dev, ISP_HDRMGE_BASE, val, false, dev->hw_dev->is_unite);
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 		val = RAW_RD_SIZE_ERR;
657*4882a593Smuzhiyun 		if (!IS_HDR_RDBK(dev->hdr.op_mode))
658*4882a593Smuzhiyun 			val |= ISP21_MIPI_DROP_FRM;
659*4882a593Smuzhiyun 		rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, val, true, dev->hw_dev->is_unite);
660*4882a593Smuzhiyun 	}
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	if (IS_HDR_RDBK(dev->hdr.op_mode))
663*4882a593Smuzhiyun 		rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS,
664*4882a593Smuzhiyun 				     true, dev->hw_dev->is_unite);
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	if (dev->isp_ver >= ISP_V30)
667*4882a593Smuzhiyun 		rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP3X_SW_ACK_FRM_PRO_DIS,
668*4882a593Smuzhiyun 				     true, dev->hw_dev->is_unite);
669*4882a593Smuzhiyun 	/* line counter from isp out, default from mp out */
670*4882a593Smuzhiyun 	if (dev->isp_ver == ISP_V32_L)
671*4882a593Smuzhiyun 		rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP32L_ISP2ENC_CNT_MUX,
672*4882a593Smuzhiyun 				     true, dev->hw_dev->is_unite);
673*4882a593Smuzhiyun 	dev->rdbk_cnt = -1;
674*4882a593Smuzhiyun 	dev->rdbk_cnt_x1 = -1;
675*4882a593Smuzhiyun 	dev->rdbk_cnt_x2 = -1;
676*4882a593Smuzhiyun 	dev->rdbk_cnt_x3 = -1;
677*4882a593Smuzhiyun 	dev->rd_mode = dev->hdr.op_mode;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	return ret;
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun 
rkisp_csi_sof(struct rkisp_device * dev,u8 id)682*4882a593Smuzhiyun void rkisp_csi_sof(struct rkisp_device *dev, u8 id)
683*4882a593Smuzhiyun {
684*4882a593Smuzhiyun 	/* to get long frame vc_start */
685*4882a593Smuzhiyun 	switch (dev->hdr.op_mode) {
686*4882a593Smuzhiyun 	case HDR_RDBK_FRAME1:
687*4882a593Smuzhiyun 		if (id != HDR_DMA2)
688*4882a593Smuzhiyun 			return;
689*4882a593Smuzhiyun 		break;
690*4882a593Smuzhiyun 	case HDR_RDBK_FRAME2:
691*4882a593Smuzhiyun 	case HDR_FRAMEX2_DDR:
692*4882a593Smuzhiyun 	case HDR_LINEX2_DDR:
693*4882a593Smuzhiyun 		if (id != HDR_DMA0)
694*4882a593Smuzhiyun 			return;
695*4882a593Smuzhiyun 		break;
696*4882a593Smuzhiyun 	case HDR_RDBK_FRAME3:
697*4882a593Smuzhiyun 	case HDR_FRAMEX3_DDR:
698*4882a593Smuzhiyun 	case HDR_LINEX3_DDR:
699*4882a593Smuzhiyun 		if (id != HDR_DMA1)
700*4882a593Smuzhiyun 			return;
701*4882a593Smuzhiyun 		break;
702*4882a593Smuzhiyun 	default:
703*4882a593Smuzhiyun 		return;
704*4882a593Smuzhiyun 	}
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 	rkisp_isp_queue_event_sof(&dev->isp_sdev);
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun 
rkisp_register_csi_subdev(struct rkisp_device * dev,struct v4l2_device * v4l2_dev)709*4882a593Smuzhiyun int rkisp_register_csi_subdev(struct rkisp_device *dev,
710*4882a593Smuzhiyun 			       struct v4l2_device *v4l2_dev)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun 	struct rkisp_csi_device *csi_dev = &dev->csi_dev;
713*4882a593Smuzhiyun 	struct v4l2_subdev *sd;
714*4882a593Smuzhiyun 	int ret;
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	memset(csi_dev, 0, sizeof(*csi_dev));
717*4882a593Smuzhiyun 	csi_dev->ispdev = dev;
718*4882a593Smuzhiyun 	sd = &csi_dev->sd;
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	v4l2_subdev_init(sd, &rkisp_csi_ops);
721*4882a593Smuzhiyun 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
722*4882a593Smuzhiyun 	sd->entity.ops = &rkisp_csi_media_ops;
723*4882a593Smuzhiyun 	sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
724*4882a593Smuzhiyun 	snprintf(sd->name, sizeof(sd->name), CSI_DEV_NAME);
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	csi_dev->pads[CSI_SINK].flags =
727*4882a593Smuzhiyun 		MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
728*4882a593Smuzhiyun 	csi_dev->pads[CSI_SRC_CH0].flags =
729*4882a593Smuzhiyun 		MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_MUST_CONNECT;
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	csi_dev->max_pad = CSI_SRC_CH0 + 1;
732*4882a593Smuzhiyun 	if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) {
733*4882a593Smuzhiyun 		csi_dev->max_pad = CSI_PAD_MAX;
734*4882a593Smuzhiyun 		csi_dev->pads[CSI_SRC_CH1].flags = MEDIA_PAD_FL_SOURCE;
735*4882a593Smuzhiyun 		csi_dev->pads[CSI_SRC_CH2].flags = MEDIA_PAD_FL_SOURCE;
736*4882a593Smuzhiyun 		csi_dev->pads[CSI_SRC_CH3].flags = MEDIA_PAD_FL_SOURCE;
737*4882a593Smuzhiyun 		csi_dev->pads[CSI_SRC_CH4].flags = MEDIA_PAD_FL_SOURCE;
738*4882a593Smuzhiyun 	} else if (dev->isp_ver >= ISP_V30) {
739*4882a593Smuzhiyun 		return 0;
740*4882a593Smuzhiyun 	}
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	ret = media_entity_pads_init(&sd->entity, csi_dev->max_pad,
743*4882a593Smuzhiyun 				     csi_dev->pads);
744*4882a593Smuzhiyun 	if (ret < 0)
745*4882a593Smuzhiyun 		return ret;
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	sd->owner = THIS_MODULE;
748*4882a593Smuzhiyun 	v4l2_set_subdevdata(sd, csi_dev);
749*4882a593Smuzhiyun 	sd->grp_id = GRP_ID_CSI;
750*4882a593Smuzhiyun 	ret = v4l2_device_register_subdev(v4l2_dev, sd);
751*4882a593Smuzhiyun 	if (ret < 0) {
752*4882a593Smuzhiyun 		v4l2_err(v4l2_dev, "Failed to register csi subdev\n");
753*4882a593Smuzhiyun 		goto free_media;
754*4882a593Smuzhiyun 	}
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 	return 0;
757*4882a593Smuzhiyun free_media:
758*4882a593Smuzhiyun 	media_entity_cleanup(&sd->entity);
759*4882a593Smuzhiyun 	return ret;
760*4882a593Smuzhiyun }
761*4882a593Smuzhiyun 
rkisp_unregister_csi_subdev(struct rkisp_device * dev)762*4882a593Smuzhiyun void rkisp_unregister_csi_subdev(struct rkisp_device *dev)
763*4882a593Smuzhiyun {
764*4882a593Smuzhiyun 	struct v4l2_subdev *sd = &dev->csi_dev.sd;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 	v4l2_device_unregister_subdev(sd);
767*4882a593Smuzhiyun 	media_entity_cleanup(&sd->entity);
768*4882a593Smuzhiyun }
769