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