• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
tegra_vi_write(struct tegra_vi_channel * chan,unsigned int addr,u32 val)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 
tegra_vi_read(struct tegra_vi_channel * chan,unsigned int addr)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 */
vi_csi_write(struct tegra_vi_channel * chan,unsigned int addr,u32 val)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 
vi_csi_read(struct tegra_vi_channel * chan,unsigned int addr)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  */
tegra_channel_capture_setup(struct tegra_vi_channel * chan)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 
tegra_channel_vi_soft_reset(struct tegra_vi_channel * chan)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 
tegra_channel_capture_error_recover(struct tegra_vi_channel * chan)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 *
dequeue_buf_done(struct tegra_vi_channel * chan)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 
release_buffer(struct tegra_vi_channel * chan,struct tegra_channel_buffer * buf,enum vb2_buffer_state state)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 
tegra_channel_capture_frame(struct tegra_vi_channel * chan,struct tegra_channel_buffer * buf)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 
tegra_channel_capture_done(struct tegra_vi_channel * chan,struct tegra_channel_buffer * buf)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 
chan_capture_kthread_start(void * data)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 
chan_capture_kthread_finish(void * data)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 
tegra210_vi_start_streaming(struct vb2_queue * vq,u32 count)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 
tegra210_vi_stop_streaming(struct vb2_queue * vq)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 */
csi_write(struct tegra_csi * csi,u8 portno,unsigned int addr,u32 val)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 */
pp_write(struct tegra_csi * csi,u8 portno,u32 addr,u32 val)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 
pp_read(struct tegra_csi * csi,u8 portno,u32 addr)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 */
cil_write(struct tegra_csi * csi,u8 portno,u32 addr,u32 val)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 
cil_read(struct tegra_csi * csi,u8 portno,u32 addr)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 */
tpg_write(struct tegra_csi * csi,u8 portno,unsigned int addr,u32 val)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  */
tegra210_csi_error_recover(struct tegra_csi_channel * csi_chan)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 
tegra210_csi_start_streaming(struct tegra_csi_channel * csi_chan)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 
tegra210_csi_stop_streaming(struct tegra_csi_channel * csi_chan)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 };
998