GNU Linux-libre 5.10.153-gnu1
[releases.git] / drivers / staging / media / tegra-video / tegra210.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2020 NVIDIA CORPORATION.  All rights reserved.
4  */
5
6 /*
7  * This source file contains Tegra210 supported video formats,
8  * VI and CSI SoC specific data, operations and registers accessors.
9  */
10 #include <linux/bitfield.h>
11 #include <linux/clk.h>
12 #include <linux/clk/tegra.h>
13 #include <linux/delay.h>
14 #include <linux/host1x.h>
15 #include <linux/kthread.h>
16
17 #include "csi.h"
18 #include "vi.h"
19
20 #define TEGRA_VI_SYNCPT_WAIT_TIMEOUT                    msecs_to_jiffies(200)
21
22 /* Tegra210 VI registers */
23 #define TEGRA_VI_CFG_VI_INCR_SYNCPT                     0x000
24 #define   VI_CFG_VI_INCR_SYNCPT_COND(x)                 (((x) & 0xff) << 8)
25 #define   VI_CSI_PP_FRAME_START(port)                   (5 + (port) * 4)
26 #define   VI_CSI_MW_ACK_DONE(port)                      (7 + (port) * 4)
27 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL               0x004
28 #define   VI_INCR_SYNCPT_NO_STALL                       BIT(8)
29 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR               0x008
30 #define TEGRA_VI_CFG_CG_CTRL                            0x0b8
31 #define   VI_CG_2ND_LEVEL_EN                            0x1
32
33 /* Tegra210 VI CSI registers */
34 #define TEGRA_VI_CSI_SW_RESET                           0x000
35 #define TEGRA_VI_CSI_SINGLE_SHOT                        0x004
36 #define   SINGLE_SHOT_CAPTURE                           0x1
37 #define TEGRA_VI_CSI_IMAGE_DEF                          0x00c
38 #define   BYPASS_PXL_TRANSFORM_OFFSET                   24
39 #define   IMAGE_DEF_FORMAT_OFFSET                       16
40 #define   IMAGE_DEF_DEST_MEM                            0x1
41 #define TEGRA_VI_CSI_IMAGE_SIZE                         0x018
42 #define   IMAGE_SIZE_HEIGHT_OFFSET                      16
43 #define TEGRA_VI_CSI_IMAGE_SIZE_WC                      0x01c
44 #define TEGRA_VI_CSI_IMAGE_DT                           0x020
45 #define TEGRA_VI_CSI_SURFACE0_OFFSET_MSB                0x024
46 #define TEGRA_VI_CSI_SURFACE0_OFFSET_LSB                0x028
47 #define TEGRA_VI_CSI_SURFACE1_OFFSET_MSB                0x02c
48 #define TEGRA_VI_CSI_SURFACE1_OFFSET_LSB                0x030
49 #define TEGRA_VI_CSI_SURFACE2_OFFSET_MSB                0x034
50 #define TEGRA_VI_CSI_SURFACE2_OFFSET_LSB                0x038
51 #define TEGRA_VI_CSI_SURFACE0_STRIDE                    0x054
52 #define TEGRA_VI_CSI_SURFACE1_STRIDE                    0x058
53 #define TEGRA_VI_CSI_SURFACE2_STRIDE                    0x05c
54 #define TEGRA_VI_CSI_SURFACE_HEIGHT0                    0x060
55 #define TEGRA_VI_CSI_ERROR_STATUS                       0x084
56
57 /* Tegra210 CSI Pixel Parser registers: Starts from 0x838, offset 0x0 */
58 #define TEGRA_CSI_INPUT_STREAM_CONTROL                  0x000
59 #define   CSI_SKIP_PACKET_THRESHOLD_OFFSET              16
60 #define TEGRA_CSI_PIXEL_STREAM_CONTROL0                 0x004
61 #define   CSI_PP_PACKET_HEADER_SENT                     BIT(4)
62 #define   CSI_PP_DATA_IDENTIFIER_ENABLE                 BIT(5)
63 #define   CSI_PP_WORD_COUNT_SELECT_HEADER               BIT(6)
64 #define   CSI_PP_CRC_CHECK_ENABLE                       BIT(7)
65 #define   CSI_PP_WC_CHECK                               BIT(8)
66 #define   CSI_PP_OUTPUT_FORMAT_STORE                    (0x3 << 16)
67 #define   CSI_PPA_PAD_LINE_NOPAD                        (0x2 << 24)
68 #define   CSI_PP_HEADER_EC_DISABLE                      (0x1 << 27)
69 #define   CSI_PPA_PAD_FRAME_NOPAD                       (0x2 << 28)
70 #define TEGRA_CSI_PIXEL_STREAM_CONTROL1                 0x008
71 #define   CSI_PP_TOP_FIELD_FRAME_OFFSET                 0
72 #define   CSI_PP_TOP_FIELD_FRAME_MASK_OFFSET            4
73 #define TEGRA_CSI_PIXEL_STREAM_GAP                      0x00c
74 #define   PP_FRAME_MIN_GAP_OFFSET                       16
75 #define TEGRA_CSI_PIXEL_STREAM_PP_COMMAND               0x010
76 #define   CSI_PP_ENABLE                                 0x1
77 #define   CSI_PP_DISABLE                                0x2
78 #define   CSI_PP_RST                                    0x3
79 #define   CSI_PP_SINGLE_SHOT_ENABLE                     (0x1 << 2)
80 #define   CSI_PP_START_MARKER_FRAME_MAX_OFFSET          12
81 #define TEGRA_CSI_PIXEL_STREAM_EXPECTED_FRAME           0x014
82 #define TEGRA_CSI_PIXEL_PARSER_INTERRUPT_MASK           0x018
83 #define TEGRA_CSI_PIXEL_PARSER_STATUS                   0x01c
84
85 /* Tegra210 CSI PHY registers */
86 /* CSI_PHY_CIL_COMMAND_0 offset 0x0d0 from TEGRA_CSI_PIXEL_PARSER_0_BASE */
87 #define TEGRA_CSI_PHY_CIL_COMMAND                       0x0d0
88 #define   CSI_A_PHY_CIL_NOP                             0x0
89 #define   CSI_A_PHY_CIL_ENABLE                          0x1
90 #define   CSI_A_PHY_CIL_DISABLE                         0x2
91 #define   CSI_A_PHY_CIL_ENABLE_MASK                     0x3
92 #define   CSI_B_PHY_CIL_NOP                             (0x0 << 8)
93 #define   CSI_B_PHY_CIL_ENABLE                          (0x1 << 8)
94 #define   CSI_B_PHY_CIL_DISABLE                         (0x2 << 8)
95 #define   CSI_B_PHY_CIL_ENABLE_MASK                     (0x3 << 8)
96
97 #define TEGRA_CSI_CIL_PAD_CONFIG0                       0x000
98 #define   BRICK_CLOCK_A_4X                              (0x1 << 16)
99 #define   BRICK_CLOCK_B_4X                              (0x2 << 16)
100 #define TEGRA_CSI_CIL_PAD_CONFIG1                       0x004
101 #define TEGRA_CSI_CIL_PHY_CONTROL                       0x008
102 #define   CLK_SETTLE_MASK                               GENMASK(13, 8)
103 #define   THS_SETTLE_MASK                               GENMASK(5, 0)
104 #define TEGRA_CSI_CIL_INTERRUPT_MASK                    0x00c
105 #define TEGRA_CSI_CIL_STATUS                            0x010
106 #define TEGRA_CSI_CILX_STATUS                           0x014
107 #define TEGRA_CSI_CIL_SW_SENSOR_RESET                   0x020
108
109 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL                0x000
110 #define   PG_MODE_OFFSET                                2
111 #define   PG_ENABLE                                     0x1
112 #define   PG_DISABLE                                    0x0
113 #define TEGRA_CSI_PG_BLANK                              0x004
114 #define   PG_VBLANK_OFFSET                              16
115 #define TEGRA_CSI_PG_PHASE                              0x008
116 #define TEGRA_CSI_PG_RED_FREQ                           0x00c
117 #define   PG_RED_VERT_INIT_FREQ_OFFSET                  16
118 #define   PG_RED_HOR_INIT_FREQ_OFFSET                   0
119 #define TEGRA_CSI_PG_RED_FREQ_RATE                      0x010
120 #define TEGRA_CSI_PG_GREEN_FREQ                         0x014
121 #define   PG_GREEN_VERT_INIT_FREQ_OFFSET                16
122 #define   PG_GREEN_HOR_INIT_FREQ_OFFSET                 0
123 #define TEGRA_CSI_PG_GREEN_FREQ_RATE                    0x018
124 #define TEGRA_CSI_PG_BLUE_FREQ                          0x01c
125 #define   PG_BLUE_VERT_INIT_FREQ_OFFSET                 16
126 #define   PG_BLUE_HOR_INIT_FREQ_OFFSET                  0
127 #define TEGRA_CSI_PG_BLUE_FREQ_RATE                     0x020
128 #define TEGRA_CSI_PG_AOHDR                              0x024
129 #define TEGRA_CSI_CSI_SW_STATUS_RESET                   0x214
130 #define TEGRA_CSI_CLKEN_OVERRIDE                        0x218
131
132 #define TEGRA210_CSI_PORT_OFFSET                        0x34
133 #define TEGRA210_CSI_CIL_OFFSET                         0x0f4
134 #define TEGRA210_CSI_TPG_OFFSET                         0x18c
135
136 #define CSI_PP_OFFSET(block)                            ((block) * 0x800)
137 #define TEGRA210_VI_CSI_BASE(x)                         (0x100 + (x) * 0x100)
138
139 /* Tegra210 VI registers accessors */
140 static void tegra_vi_write(struct tegra_vi_channel *chan, unsigned int addr,
141                            u32 val)
142 {
143         writel_relaxed(val, chan->vi->iomem + addr);
144 }
145
146 static u32 tegra_vi_read(struct tegra_vi_channel *chan, unsigned int addr)
147 {
148         return readl_relaxed(chan->vi->iomem + addr);
149 }
150
151 /* Tegra210 VI_CSI registers accessors */
152 static void vi_csi_write(struct tegra_vi_channel *chan, unsigned int addr,
153                          u32 val)
154 {
155         void __iomem *vi_csi_base;
156
157         vi_csi_base = chan->vi->iomem + TEGRA210_VI_CSI_BASE(chan->portno);
158
159         writel_relaxed(val, vi_csi_base + addr);
160 }
161
162 static u32 vi_csi_read(struct tegra_vi_channel *chan, unsigned int addr)
163 {
164         void __iomem *vi_csi_base;
165
166         vi_csi_base = chan->vi->iomem + TEGRA210_VI_CSI_BASE(chan->portno);
167
168         return readl_relaxed(vi_csi_base + addr);
169 }
170
171 /*
172  * Tegra210 VI channel capture operations
173  */
174 static int tegra_channel_capture_setup(struct tegra_vi_channel *chan)
175 {
176         u32 height = chan->format.height;
177         u32 width = chan->format.width;
178         u32 format = chan->fmtinfo->img_fmt;
179         u32 data_type = chan->fmtinfo->img_dt;
180         u32 word_count = (width * chan->fmtinfo->bit_width) / 8;
181
182         vi_csi_write(chan, TEGRA_VI_CSI_ERROR_STATUS, 0xffffffff);
183         vi_csi_write(chan, TEGRA_VI_CSI_IMAGE_DEF,
184                      ((chan->pg_mode ? 0 : 1) << BYPASS_PXL_TRANSFORM_OFFSET) |
185                      (format << IMAGE_DEF_FORMAT_OFFSET) |
186                      IMAGE_DEF_DEST_MEM);
187         vi_csi_write(chan, TEGRA_VI_CSI_IMAGE_DT, data_type);
188         vi_csi_write(chan, TEGRA_VI_CSI_IMAGE_SIZE_WC, word_count);
189         vi_csi_write(chan, TEGRA_VI_CSI_IMAGE_SIZE,
190                      (height << IMAGE_SIZE_HEIGHT_OFFSET) | width);
191         return 0;
192 }
193
194 static void tegra_channel_vi_soft_reset(struct tegra_vi_channel *chan)
195 {
196         /* disable clock gating to enable continuous clock */
197         tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, 0);
198         /*
199          * Soft reset memory client interface, pixel format logic, sensor
200          * control logic, and a shadow copy logic to bring VI to clean state.
201          */
202         vi_csi_write(chan, TEGRA_VI_CSI_SW_RESET, 0xf);
203         usleep_range(100, 200);
204         vi_csi_write(chan, TEGRA_VI_CSI_SW_RESET, 0x0);
205
206         /* enable back VI clock gating */
207         tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, VI_CG_2ND_LEVEL_EN);
208 }
209
210 static void tegra_channel_capture_error_recover(struct tegra_vi_channel *chan)
211 {
212         struct v4l2_subdev *subdev;
213         u32 val;
214
215         /*
216          * Recover VI and CSI hardware blocks in case of missing frame start
217          * events due to source not streaming or noisy csi inputs from the
218          * external source or many outstanding frame start or MW_ACK_DONE
219          * events which can cause CSI and VI hardware hang.
220          * This helps to have a clean capture for next frame.
221          */
222         val = vi_csi_read(chan, TEGRA_VI_CSI_ERROR_STATUS);
223         dev_dbg(&chan->video.dev, "TEGRA_VI_CSI_ERROR_STATUS 0x%08x\n", val);
224         vi_csi_write(chan, TEGRA_VI_CSI_ERROR_STATUS, val);
225
226         val = tegra_vi_read(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR);
227         dev_dbg(&chan->video.dev,
228                 "TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR 0x%08x\n", val);
229         tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR, val);
230
231         /* recover VI by issuing software reset and re-setup for capture */
232         tegra_channel_vi_soft_reset(chan);
233         tegra_channel_capture_setup(chan);
234
235         /* recover CSI block */
236         subdev = tegra_channel_get_remote_csi_subdev(chan);
237         tegra_csi_error_recover(subdev);
238 }
239
240 static struct tegra_channel_buffer *
241 dequeue_buf_done(struct tegra_vi_channel *chan)
242 {
243         struct tegra_channel_buffer *buf = NULL;
244
245         spin_lock(&chan->done_lock);
246         if (list_empty(&chan->done)) {
247                 spin_unlock(&chan->done_lock);
248                 return NULL;
249         }
250
251         buf = list_first_entry(&chan->done,
252                                struct tegra_channel_buffer, queue);
253         if (buf)
254                 list_del_init(&buf->queue);
255         spin_unlock(&chan->done_lock);
256
257         return buf;
258 }
259
260 static void release_buffer(struct tegra_vi_channel *chan,
261                            struct tegra_channel_buffer *buf,
262                            enum vb2_buffer_state state)
263 {
264         struct vb2_v4l2_buffer *vb = &buf->buf;
265
266         vb->sequence = chan->sequence++;
267         vb->field = V4L2_FIELD_NONE;
268         vb->vb2_buf.timestamp = ktime_get_ns();
269         vb2_buffer_done(&vb->vb2_buf, state);
270 }
271
272 static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
273                                        struct tegra_channel_buffer *buf)
274 {
275         u32 thresh, value, frame_start, mw_ack_done;
276         int bytes_per_line = chan->format.bytesperline;
277         int err;
278
279         /* program buffer address by using surface 0 */
280         vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_OFFSET_MSB,
281                      (u64)buf->addr >> 32);
282         vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_OFFSET_LSB, buf->addr);
283         vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_STRIDE, bytes_per_line);
284
285         /*
286          * Tegra VI block interacts with host1x syncpt for synchronizing
287          * programmed condition of capture state and hardware operation.
288          * Frame start and Memory write acknowledge syncpts has their own
289          * FIFO of depth 2.
290          *
291          * Syncpoint trigger conditions set through VI_INCR_SYNCPT register
292          * are added to HW syncpt FIFO and when the HW triggers, syncpt
293          * condition is removed from the FIFO and counter at syncpoint index
294          * will be incremented by the hardware and software can wait for
295          * counter to reach threshold to synchronize capturing frame with the
296          * hardware capture events.
297          */
298
299         /* increase channel syncpoint threshold for FRAME_START */
300         thresh = host1x_syncpt_incr_max(chan->frame_start_sp, 1);
301
302         /* Program FRAME_START trigger condition syncpt request */
303         frame_start = VI_CSI_PP_FRAME_START(chan->portno);
304         value = VI_CFG_VI_INCR_SYNCPT_COND(frame_start) |
305                 host1x_syncpt_id(chan->frame_start_sp);
306         tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
307
308         /* increase channel syncpoint threshold for MW_ACK_DONE */
309         buf->mw_ack_sp_thresh = host1x_syncpt_incr_max(chan->mw_ack_sp, 1);
310
311         /* Program MW_ACK_DONE trigger condition syncpt request */
312         mw_ack_done = VI_CSI_MW_ACK_DONE(chan->portno);
313         value = VI_CFG_VI_INCR_SYNCPT_COND(mw_ack_done) |
314                 host1x_syncpt_id(chan->mw_ack_sp);
315         tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
316
317         /* enable single shot capture */
318         vi_csi_write(chan, TEGRA_VI_CSI_SINGLE_SHOT, SINGLE_SHOT_CAPTURE);
319
320         /* wait for syncpt counter to reach frame start event threshold */
321         err = host1x_syncpt_wait(chan->frame_start_sp, thresh,
322                                  TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
323         if (err) {
324                 dev_err_ratelimited(&chan->video.dev,
325                                     "frame start syncpt timeout: %d\n", err);
326                 /* increment syncpoint counter for timedout events */
327                 host1x_syncpt_incr(chan->frame_start_sp);
328                 spin_lock(&chan->sp_incr_lock);
329                 host1x_syncpt_incr(chan->mw_ack_sp);
330                 spin_unlock(&chan->sp_incr_lock);
331                 /* clear errors and recover */
332                 tegra_channel_capture_error_recover(chan);
333                 release_buffer(chan, buf, VB2_BUF_STATE_ERROR);
334                 return err;
335         }
336
337         /* move buffer to capture done queue */
338         spin_lock(&chan->done_lock);
339         list_add_tail(&buf->queue, &chan->done);
340         spin_unlock(&chan->done_lock);
341
342         /* wait up kthread for capture done */
343         wake_up_interruptible(&chan->done_wait);
344
345         return 0;
346 }
347
348 static void tegra_channel_capture_done(struct tegra_vi_channel *chan,
349                                        struct tegra_channel_buffer *buf)
350 {
351         enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
352         u32 value;
353         int ret;
354
355         /* wait for syncpt counter to reach MW_ACK_DONE event threshold */
356         ret = host1x_syncpt_wait(chan->mw_ack_sp, buf->mw_ack_sp_thresh,
357                                  TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
358         if (ret) {
359                 dev_err_ratelimited(&chan->video.dev,
360                                     "MW_ACK_DONE syncpt timeout: %d\n", ret);
361                 state = VB2_BUF_STATE_ERROR;
362                 /* increment syncpoint counter for timedout event */
363                 spin_lock(&chan->sp_incr_lock);
364                 host1x_syncpt_incr(chan->mw_ack_sp);
365                 spin_unlock(&chan->sp_incr_lock);
366         }
367
368         release_buffer(chan, buf, state);
369 }
370
371 static int chan_capture_kthread_start(void *data)
372 {
373         struct tegra_vi_channel *chan = data;
374         struct tegra_channel_buffer *buf;
375         int err = 0;
376
377         while (1) {
378                 /*
379                  * Source is not streaming if error is non-zero.
380                  * So, do not dequeue buffers on error and let the thread sleep
381                  * till kthread stop signal is received.
382                  */
383                 wait_event_interruptible(chan->start_wait,
384                                          kthread_should_stop() ||
385                                          (!list_empty(&chan->capture) &&
386                                          !err));
387
388                 if (kthread_should_stop())
389                         break;
390
391                 /* dequeue the buffer and start capture */
392                 spin_lock(&chan->start_lock);
393                 if (list_empty(&chan->capture)) {
394                         spin_unlock(&chan->start_lock);
395                         continue;
396                 }
397
398                 buf = list_first_entry(&chan->capture,
399                                        struct tegra_channel_buffer, queue);
400                 list_del_init(&buf->queue);
401                 spin_unlock(&chan->start_lock);
402
403                 err = tegra_channel_capture_frame(chan, buf);
404                 if (err)
405                         vb2_queue_error(&chan->queue);
406         }
407
408         return 0;
409 }
410
411 static int chan_capture_kthread_finish(void *data)
412 {
413         struct tegra_vi_channel *chan = data;
414         struct tegra_channel_buffer *buf;
415
416         while (1) {
417                 wait_event_interruptible(chan->done_wait,
418                                          !list_empty(&chan->done) ||
419                                          kthread_should_stop());
420
421                 /* dequeue buffers and finish capture */
422                 buf = dequeue_buf_done(chan);
423                 while (buf) {
424                         tegra_channel_capture_done(chan, buf);
425                         buf = dequeue_buf_done(chan);
426                 }
427
428                 if (kthread_should_stop())
429                         break;
430         }
431
432         return 0;
433 }
434
435 static int tegra210_vi_start_streaming(struct vb2_queue *vq, u32 count)
436 {
437         struct tegra_vi_channel *chan = vb2_get_drv_priv(vq);
438         struct media_pipeline *pipe = &chan->video.pipe;
439         u32 val;
440         int ret;
441
442         tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, VI_CG_2ND_LEVEL_EN);
443
444         /* clear errors */
445         val = vi_csi_read(chan, TEGRA_VI_CSI_ERROR_STATUS);
446         vi_csi_write(chan, TEGRA_VI_CSI_ERROR_STATUS, val);
447
448         val = tegra_vi_read(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR);
449         tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR, val);
450
451         /*
452          * Sync point FIFO full stalls the host interface.
453          * Setting NO_STALL will drop INCR_SYNCPT methods when fifos are
454          * full and the corresponding condition bits in INCR_SYNCPT_ERROR
455          * register will be set.
456          * This allows SW to process error recovery.
457          */
458         tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL,
459                        VI_INCR_SYNCPT_NO_STALL);
460
461         /* start the pipeline */
462         ret = media_pipeline_start(&chan->video.entity, pipe);
463         if (ret < 0)
464                 goto error_pipeline_start;
465
466         tegra_channel_capture_setup(chan);
467         ret = tegra_channel_set_stream(chan, true);
468         if (ret < 0)
469                 goto error_set_stream;
470
471         chan->sequence = 0;
472
473         /* start kthreads to capture data to buffer and return them */
474         chan->kthread_start_capture = kthread_run(chan_capture_kthread_start,
475                                                   chan, "%s:0",
476                                                   chan->video.name);
477         if (IS_ERR(chan->kthread_start_capture)) {
478                 ret = PTR_ERR(chan->kthread_start_capture);
479                 chan->kthread_start_capture = NULL;
480                 dev_err(&chan->video.dev,
481                         "failed to run capture start kthread: %d\n", ret);
482                 goto error_kthread_start;
483         }
484
485         chan->kthread_finish_capture = kthread_run(chan_capture_kthread_finish,
486                                                    chan, "%s:1",
487                                                    chan->video.name);
488         if (IS_ERR(chan->kthread_finish_capture)) {
489                 ret = PTR_ERR(chan->kthread_finish_capture);
490                 chan->kthread_finish_capture = NULL;
491                 dev_err(&chan->video.dev,
492                         "failed to run capture finish kthread: %d\n", ret);
493                 goto error_kthread_done;
494         }
495
496         return 0;
497
498 error_kthread_done:
499         kthread_stop(chan->kthread_start_capture);
500 error_kthread_start:
501         tegra_channel_set_stream(chan, false);
502 error_set_stream:
503         media_pipeline_stop(&chan->video.entity);
504 error_pipeline_start:
505         tegra_channel_release_buffers(chan, VB2_BUF_STATE_QUEUED);
506         return ret;
507 }
508
509 static void tegra210_vi_stop_streaming(struct vb2_queue *vq)
510 {
511         struct tegra_vi_channel *chan = vb2_get_drv_priv(vq);
512
513         if (chan->kthread_start_capture) {
514                 kthread_stop(chan->kthread_start_capture);
515                 chan->kthread_start_capture = NULL;
516         }
517
518         if (chan->kthread_finish_capture) {
519                 kthread_stop(chan->kthread_finish_capture);
520                 chan->kthread_finish_capture = NULL;
521         }
522
523         tegra_channel_release_buffers(chan, VB2_BUF_STATE_ERROR);
524         tegra_channel_set_stream(chan, false);
525         media_pipeline_stop(&chan->video.entity);
526 }
527
528 /*
529  * Tegra210 VI Pixel memory format enum.
530  * These format enum value gets programmed into corresponding Tegra VI
531  * channel register bits.
532  */
533 enum tegra210_image_format {
534         TEGRA210_IMAGE_FORMAT_T_L8 = 16,
535
536         TEGRA210_IMAGE_FORMAT_T_R16_I = 32,
537         TEGRA210_IMAGE_FORMAT_T_B5G6R5,
538         TEGRA210_IMAGE_FORMAT_T_R5G6B5,
539         TEGRA210_IMAGE_FORMAT_T_A1B5G5R5,
540         TEGRA210_IMAGE_FORMAT_T_A1R5G5B5,
541         TEGRA210_IMAGE_FORMAT_T_B5G5R5A1,
542         TEGRA210_IMAGE_FORMAT_T_R5G5B5A1,
543         TEGRA210_IMAGE_FORMAT_T_A4B4G4R4,
544         TEGRA210_IMAGE_FORMAT_T_A4R4G4B4,
545         TEGRA210_IMAGE_FORMAT_T_B4G4R4A4,
546         TEGRA210_IMAGE_FORMAT_T_R4G4B4A4,
547
548         TEGRA210_IMAGE_FORMAT_T_A8B8G8R8 = 64,
549         TEGRA210_IMAGE_FORMAT_T_A8R8G8B8,
550         TEGRA210_IMAGE_FORMAT_T_B8G8R8A8,
551         TEGRA210_IMAGE_FORMAT_T_R8G8B8A8,
552         TEGRA210_IMAGE_FORMAT_T_A2B10G10R10,
553         TEGRA210_IMAGE_FORMAT_T_A2R10G10B10,
554         TEGRA210_IMAGE_FORMAT_T_B10G10R10A2,
555         TEGRA210_IMAGE_FORMAT_T_R10G10B10A2,
556
557         TEGRA210_IMAGE_FORMAT_T_A8Y8U8V8 = 193,
558         TEGRA210_IMAGE_FORMAT_T_V8U8Y8A8,
559
560         TEGRA210_IMAGE_FORMAT_T_A2Y10U10V10 = 197,
561         TEGRA210_IMAGE_FORMAT_T_V10U10Y10A2,
562         TEGRA210_IMAGE_FORMAT_T_Y8_U8__Y8_V8,
563         TEGRA210_IMAGE_FORMAT_T_Y8_V8__Y8_U8,
564         TEGRA210_IMAGE_FORMAT_T_U8_Y8__V8_Y8,
565         TEGRA210_IMAGE_FORMAT_T_V8_Y8__U8_Y8,
566
567         TEGRA210_IMAGE_FORMAT_T_Y8__U8__V8_N444 = 224,
568         TEGRA210_IMAGE_FORMAT_T_Y8__U8V8_N444,
569         TEGRA210_IMAGE_FORMAT_T_Y8__V8U8_N444,
570         TEGRA210_IMAGE_FORMAT_T_Y8__U8__V8_N422,
571         TEGRA210_IMAGE_FORMAT_T_Y8__U8V8_N422,
572         TEGRA210_IMAGE_FORMAT_T_Y8__V8U8_N422,
573         TEGRA210_IMAGE_FORMAT_T_Y8__U8__V8_N420,
574         TEGRA210_IMAGE_FORMAT_T_Y8__U8V8_N420,
575         TEGRA210_IMAGE_FORMAT_T_Y8__V8U8_N420,
576         TEGRA210_IMAGE_FORMAT_T_X2LC10LB10LA10,
577         TEGRA210_IMAGE_FORMAT_T_A2R6R6R6R6R6,
578 };
579
580 #define TEGRA210_VIDEO_FMT(DATA_TYPE, BIT_WIDTH, MBUS_CODE, BPP,        \
581                            FORMAT, FOURCC)                              \
582 {                                                                       \
583         TEGRA_IMAGE_DT_##DATA_TYPE,                                     \
584         BIT_WIDTH,                                                      \
585         MEDIA_BUS_FMT_##MBUS_CODE,                                      \
586         BPP,                                                            \
587         TEGRA210_IMAGE_FORMAT_##FORMAT,                                 \
588         V4L2_PIX_FMT_##FOURCC,                                          \
589 }
590
591 /* Tegra210 supported video formats */
592 static const struct tegra_video_format tegra210_video_formats[] = {
593         /* RAW 8 */
594         TEGRA210_VIDEO_FMT(RAW8, 8, SRGGB8_1X8, 1, T_L8, SRGGB8),
595         TEGRA210_VIDEO_FMT(RAW8, 8, SGRBG8_1X8, 1, T_L8, SGRBG8),
596         TEGRA210_VIDEO_FMT(RAW8, 8, SGBRG8_1X8, 1, T_L8, SGBRG8),
597         TEGRA210_VIDEO_FMT(RAW8, 8, SBGGR8_1X8, 1, T_L8, SBGGR8),
598         /* RAW 10 */
599         TEGRA210_VIDEO_FMT(RAW10, 10, SRGGB10_1X10, 2, T_R16_I, SRGGB10),
600         TEGRA210_VIDEO_FMT(RAW10, 10, SGRBG10_1X10, 2, T_R16_I, SGRBG10),
601         TEGRA210_VIDEO_FMT(RAW10, 10, SGBRG10_1X10, 2, T_R16_I, SGBRG10),
602         TEGRA210_VIDEO_FMT(RAW10, 10, SBGGR10_1X10, 2, T_R16_I, SBGGR10),
603         /* RAW 12 */
604         TEGRA210_VIDEO_FMT(RAW12, 12, SRGGB12_1X12, 2, T_R16_I, SRGGB12),
605         TEGRA210_VIDEO_FMT(RAW12, 12, SGRBG12_1X12, 2, T_R16_I, SGRBG12),
606         TEGRA210_VIDEO_FMT(RAW12, 12, SGBRG12_1X12, 2, T_R16_I, SGBRG12),
607         TEGRA210_VIDEO_FMT(RAW12, 12, SBGGR12_1X12, 2, T_R16_I, SBGGR12),
608         /* RGB888 */
609         TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, RGB24),
610         TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8,
611                            XBGR32),
612         /* YUV422 */
613         TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 2, T_U8_Y8__V8_Y8, UYVY),
614         TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_1X16, 2, T_V8_Y8__U8_Y8, VYUY),
615         TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_1X16, 2, T_Y8_U8__Y8_V8, YUYV),
616         TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_1X16, 2, T_Y8_V8__Y8_U8, YVYU),
617         TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 1, T_Y8__V8U8_N422, NV16),
618         TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_2X8, 2, T_U8_Y8__V8_Y8, UYVY),
619         TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, VYUY),
620         TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, YUYV),
621         TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, YVYU),
622 };
623
624 /* Tegra210 VI operations */
625 static const struct tegra_vi_ops tegra210_vi_ops = {
626         .vi_start_streaming = tegra210_vi_start_streaming,
627         .vi_stop_streaming = tegra210_vi_stop_streaming,
628 };
629
630 /* Tegra210 VI SoC data */
631 const struct tegra_vi_soc tegra210_vi_soc = {
632         .video_formats = tegra210_video_formats,
633         .nformats = ARRAY_SIZE(tegra210_video_formats),
634         .ops = &tegra210_vi_ops,
635         .hw_revision = 3,
636         .vi_max_channels = 6,
637 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
638         .vi_max_clk_hz = 499200000,
639 #else
640         .vi_max_clk_hz = 998400000,
641 #endif
642 };
643
644 /* Tegra210 CSI PHY registers accessors */
645 static void csi_write(struct tegra_csi *csi, u8 portno, unsigned int addr,
646                       u32 val)
647 {
648         void __iomem *csi_pp_base;
649
650         csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
651
652         writel_relaxed(val, csi_pp_base + addr);
653 }
654
655 /* Tegra210 CSI Pixel parser registers accessors */
656 static void pp_write(struct tegra_csi *csi, u8 portno, u32 addr, u32 val)
657 {
658         void __iomem *csi_pp_base;
659         unsigned int offset;
660
661         csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
662         offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
663
664         writel_relaxed(val, csi_pp_base + offset + addr);
665 }
666
667 static u32 pp_read(struct tegra_csi *csi, u8 portno, u32 addr)
668 {
669         void __iomem *csi_pp_base;
670         unsigned int offset;
671
672         csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
673         offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
674
675         return readl_relaxed(csi_pp_base + offset + addr);
676 }
677
678 /* Tegra210 CSI CIL A/B port registers accessors */
679 static void cil_write(struct tegra_csi *csi, u8 portno, u32 addr, u32 val)
680 {
681         void __iomem *csi_cil_base;
682         unsigned int offset;
683
684         csi_cil_base = csi->iomem + CSI_PP_OFFSET(portno >> 1) +
685                        TEGRA210_CSI_CIL_OFFSET;
686         offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
687
688         writel_relaxed(val, csi_cil_base + offset + addr);
689 }
690
691 static u32 cil_read(struct tegra_csi *csi, u8 portno, u32 addr)
692 {
693         void __iomem *csi_cil_base;
694         unsigned int offset;
695
696         csi_cil_base = csi->iomem + CSI_PP_OFFSET(portno >> 1) +
697                        TEGRA210_CSI_CIL_OFFSET;
698         offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
699
700         return readl_relaxed(csi_cil_base + offset + addr);
701 }
702
703 /* Tegra210 CSI Test pattern generator registers accessor */
704 static void tpg_write(struct tegra_csi *csi, u8 portno, unsigned int addr,
705                       u32 val)
706 {
707         void __iomem *csi_pp_base;
708         unsigned int offset;
709
710         csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
711         offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET +
712                  TEGRA210_CSI_TPG_OFFSET;
713
714         writel_relaxed(val, csi_pp_base + offset + addr);
715 }
716
717 /*
718  * Tegra210 CSI operations
719  */
720 static void tegra210_csi_error_recover(struct tegra_csi_channel *csi_chan)
721 {
722         struct tegra_csi *csi = csi_chan->csi;
723         unsigned int portno = csi_chan->csi_port_num;
724         u32 val;
725
726         /*
727          * Recover CSI hardware in case of capture errors by issuing
728          * software reset to CSICIL sensor, pixel parser, and clear errors
729          * to have clean capture on  next streaming.
730          */
731         val = pp_read(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS);
732         dev_dbg(csi->dev, "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n", val);
733
734         val = cil_read(csi, portno, TEGRA_CSI_CIL_STATUS);
735         dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val);
736
737         val = cil_read(csi, portno, TEGRA_CSI_CILX_STATUS);
738         dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val);
739
740         if (csi_chan->numlanes == 4) {
741                 /* reset CSI CIL sensor */
742                 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
743                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
744                 /*
745                  * SW_STATUS_RESET resets all status bits of PPA, PPB, CILA,
746                  * CILB status registers and debug counters.
747                  * So, SW_STATUS_RESET can be used only when CSI brick is in
748                  * x4 mode.
749                  */
750                 csi_write(csi, portno, TEGRA_CSI_CSI_SW_STATUS_RESET, 0x1);
751
752                 /* sleep for 20 clock cycles to drain the FIFO */
753                 usleep_range(10, 20);
754
755                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
756                 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
757                 csi_write(csi, portno, TEGRA_CSI_CSI_SW_STATUS_RESET, 0x0);
758         } else {
759                 /* reset CSICIL sensor */
760                 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
761                 usleep_range(10, 20);
762                 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
763
764                 /* clear the errors */
765                 pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS,
766                          0xffffffff);
767                 cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, 0xffffffff);
768                 cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, 0xffffffff);
769         }
770 }
771
772 static int tegra210_csi_start_streaming(struct tegra_csi_channel *csi_chan)
773 {
774         struct tegra_csi *csi = csi_chan->csi;
775         unsigned int portno = csi_chan->csi_port_num;
776         u8 clk_settle_time = 0;
777         u8 ths_settle_time = 10;
778         u32 val;
779
780         if (!csi_chan->pg_mode)
781                 tegra_csi_calc_settle_time(csi_chan, &clk_settle_time,
782                                            &ths_settle_time);
783
784         csi_write(csi, portno, TEGRA_CSI_CLKEN_OVERRIDE, 0);
785
786         /* clean up status */
787         pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS, 0xffffffff);
788         cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, 0xffffffff);
789         cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, 0xffffffff);
790         cil_write(csi, portno, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
791
792         /* CIL PHY registers setup */
793         cil_write(csi, portno, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
794         cil_write(csi, portno, TEGRA_CSI_CIL_PHY_CONTROL,
795                   FIELD_PREP(CLK_SETTLE_MASK, clk_settle_time) |
796                   FIELD_PREP(THS_SETTLE_MASK, ths_settle_time));
797
798         /*
799          * The CSI unit provides for connection of up to six cameras in
800          * the system and is organized as three identical instances of
801          * two MIPI support blocks, each with a separate 4-lane
802          * interface that can be configured as a single camera with 4
803          * lanes or as a dual camera with 2 lanes available for each
804          * camera.
805          */
806         if (csi_chan->numlanes == 4) {
807                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_STATUS, 0xffffffff);
808                 cil_write(csi, portno + 1, TEGRA_CSI_CILX_STATUS, 0xffffffff);
809                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
810
811                 cil_write(csi, portno, TEGRA_CSI_CIL_PAD_CONFIG0,
812                           BRICK_CLOCK_A_4X);
813                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
814                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
815                 cil_write(csi, portno + 1, TEGRA_CSI_CIL_PHY_CONTROL,
816                           FIELD_PREP(CLK_SETTLE_MASK, clk_settle_time) |
817                           FIELD_PREP(THS_SETTLE_MASK, ths_settle_time));
818                 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND,
819                           CSI_A_PHY_CIL_ENABLE | CSI_B_PHY_CIL_ENABLE);
820         } else {
821                 val = ((portno & 1) == PORT_A) ?
822                       CSI_A_PHY_CIL_ENABLE | CSI_B_PHY_CIL_NOP :
823                       CSI_B_PHY_CIL_ENABLE | CSI_A_PHY_CIL_NOP;
824                 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND, val);
825         }
826
827         /* CSI pixel parser registers setup */
828         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
829                  (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
830                  CSI_PP_SINGLE_SHOT_ENABLE | CSI_PP_RST);
831         pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_INTERRUPT_MASK, 0x0);
832         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_CONTROL0,
833                  CSI_PP_PACKET_HEADER_SENT |
834                  CSI_PP_DATA_IDENTIFIER_ENABLE |
835                  CSI_PP_WORD_COUNT_SELECT_HEADER |
836                  CSI_PP_CRC_CHECK_ENABLE |  CSI_PP_WC_CHECK |
837                  CSI_PP_OUTPUT_FORMAT_STORE | CSI_PPA_PAD_LINE_NOPAD |
838                  CSI_PP_HEADER_EC_DISABLE | CSI_PPA_PAD_FRAME_NOPAD |
839                  (portno & 1));
840         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_CONTROL1,
841                  (0x1 << CSI_PP_TOP_FIELD_FRAME_OFFSET) |
842                  (0x1 << CSI_PP_TOP_FIELD_FRAME_MASK_OFFSET));
843         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_GAP,
844                  0x14 << PP_FRAME_MIN_GAP_OFFSET);
845         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_EXPECTED_FRAME, 0x0);
846         pp_write(csi, portno, TEGRA_CSI_INPUT_STREAM_CONTROL,
847                  (0x3f << CSI_SKIP_PACKET_THRESHOLD_OFFSET) |
848                  (csi_chan->numlanes - 1));
849
850         /* TPG setup */
851         if (csi_chan->pg_mode) {
852                 tpg_write(csi, portno, TEGRA_CSI_PATTERN_GENERATOR_CTRL,
853                           ((csi_chan->pg_mode - 1) << PG_MODE_OFFSET) |
854                           PG_ENABLE);
855                 tpg_write(csi, portno, TEGRA_CSI_PG_BLANK,
856                           csi_chan->v_blank << PG_VBLANK_OFFSET |
857                           csi_chan->h_blank);
858                 tpg_write(csi, portno, TEGRA_CSI_PG_PHASE, 0x0);
859                 tpg_write(csi, portno, TEGRA_CSI_PG_RED_FREQ,
860                           (0x10 << PG_RED_VERT_INIT_FREQ_OFFSET) |
861                           (0x10 << PG_RED_HOR_INIT_FREQ_OFFSET));
862                 tpg_write(csi, portno, TEGRA_CSI_PG_RED_FREQ_RATE, 0x0);
863                 tpg_write(csi, portno, TEGRA_CSI_PG_GREEN_FREQ,
864                           (0x10 << PG_GREEN_VERT_INIT_FREQ_OFFSET) |
865                           (0x10 << PG_GREEN_HOR_INIT_FREQ_OFFSET));
866                 tpg_write(csi, portno, TEGRA_CSI_PG_GREEN_FREQ_RATE, 0x0);
867                 tpg_write(csi, portno, TEGRA_CSI_PG_BLUE_FREQ,
868                           (0x10 << PG_BLUE_VERT_INIT_FREQ_OFFSET) |
869                           (0x10 << PG_BLUE_HOR_INIT_FREQ_OFFSET));
870                 tpg_write(csi, portno, TEGRA_CSI_PG_BLUE_FREQ_RATE, 0x0);
871         }
872
873         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
874                  (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
875                  CSI_PP_SINGLE_SHOT_ENABLE | CSI_PP_ENABLE);
876
877         return 0;
878 }
879
880 static void tegra210_csi_stop_streaming(struct tegra_csi_channel *csi_chan)
881 {
882         struct tegra_csi *csi = csi_chan->csi;
883         unsigned int portno = csi_chan->csi_port_num;
884         u32 val;
885
886         val = pp_read(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS);
887
888         dev_dbg(csi->dev, "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n", val);
889         pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS, val);
890
891         val = cil_read(csi, portno, TEGRA_CSI_CIL_STATUS);
892         dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val);
893         cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, val);
894
895         val = cil_read(csi, portno, TEGRA_CSI_CILX_STATUS);
896         dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val);
897         cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, val);
898
899         pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
900                  (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
901                  CSI_PP_DISABLE);
902
903         if (csi_chan->pg_mode) {
904                 tpg_write(csi, portno, TEGRA_CSI_PATTERN_GENERATOR_CTRL,
905                           PG_DISABLE);
906                 return;
907         }
908
909         if (csi_chan->numlanes == 4) {
910                 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND,
911                           CSI_A_PHY_CIL_DISABLE |
912                           CSI_B_PHY_CIL_DISABLE);
913         } else {
914                 val = ((portno & 1) == PORT_A) ?
915                       CSI_A_PHY_CIL_DISABLE | CSI_B_PHY_CIL_NOP :
916                       CSI_B_PHY_CIL_DISABLE | CSI_A_PHY_CIL_NOP;
917                 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND, val);
918         }
919 }
920
921 /*
922  * Tegra210 CSI TPG frame rate table with horizontal and vertical
923  * blanking intervals for corresponding format and resolution.
924  * Blanking intervals are tuned values from design team for max TPG
925  * clock rate.
926  */
927 static const struct tpg_framerate tegra210_tpg_frmrate_table[] = {
928         {
929                 .frmsize = { 1280, 720 },
930                 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
931                 .framerate = 120,
932                 .h_blank = 512,
933                 .v_blank = 8,
934         },
935         {
936                 .frmsize = { 1920, 1080 },
937                 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
938                 .framerate = 60,
939                 .h_blank = 512,
940                 .v_blank = 8,
941         },
942         {
943                 .frmsize = { 3840, 2160 },
944                 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
945                 .framerate = 20,
946                 .h_blank = 8,
947                 .v_blank = 8,
948         },
949         {
950                 .frmsize = { 1280, 720 },
951                 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
952                 .framerate = 60,
953                 .h_blank = 512,
954                 .v_blank = 8,
955         },
956         {
957                 .frmsize = { 1920, 1080 },
958                 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
959                 .framerate = 30,
960                 .h_blank = 512,
961                 .v_blank = 8,
962         },
963         {
964                 .frmsize = { 3840, 2160 },
965                 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
966                 .framerate = 8,
967                 .h_blank = 8,
968                 .v_blank = 8,
969         },
970 };
971
972 static const char * const tegra210_csi_cil_clks[] = {
973         "csi",
974         "cilab",
975         "cilcd",
976         "cile",
977 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
978         "csi_tpg",
979 #endif
980 };
981
982 /* Tegra210 CSI operations */
983 static const struct tegra_csi_ops tegra210_csi_ops = {
984         .csi_start_streaming = tegra210_csi_start_streaming,
985         .csi_stop_streaming = tegra210_csi_stop_streaming,
986         .csi_err_recover = tegra210_csi_error_recover,
987 };
988
989 /* Tegra210 CSI SoC data */
990 const struct tegra_csi_soc tegra210_csi_soc = {
991         .ops = &tegra210_csi_ops,
992         .csi_max_channels = 6,
993         .clk_names = tegra210_csi_cil_clks,
994         .num_clks = ARRAY_SIZE(tegra210_csi_cil_clks),
995         .tpg_frmrate_table = tegra210_tpg_frmrate_table,
996         .tpg_frmrate_table_size = ARRAY_SIZE(tegra210_tpg_frmrate_table),
997 };