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