1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2020 NVIDIA CORPORATION. All rights reserved.
7 * This source file contains Tegra210 supported video formats,
8 * VI and CSI SoC specific data, operations and registers accessors.
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>
20 #define TEGRA_VI_SYNCPT_WAIT_TIMEOUT msecs_to_jiffies(200)
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
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
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
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)
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
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
132 #define TEGRA210_CSI_PORT_OFFSET 0x34
133 #define TEGRA210_CSI_CIL_OFFSET 0x0f4
134 #define TEGRA210_CSI_TPG_OFFSET 0x18c
136 #define CSI_PP_OFFSET(block) ((block) * 0x800)
137 #define TEGRA210_VI_CSI_BASE(x) (0x100 + (x) * 0x100)
139 /* Tegra210 VI registers accessors */
140 static void tegra_vi_write(struct tegra_vi_channel *chan, unsigned int addr,
143 writel_relaxed(val, chan->vi->iomem + addr);
146 static u32 tegra_vi_read(struct tegra_vi_channel *chan, unsigned int addr)
148 return readl_relaxed(chan->vi->iomem + addr);
151 /* Tegra210 VI_CSI registers accessors */
152 static void vi_csi_write(struct tegra_vi_channel *chan, unsigned int addr,
155 void __iomem *vi_csi_base;
157 vi_csi_base = chan->vi->iomem + TEGRA210_VI_CSI_BASE(chan->portno);
159 writel_relaxed(val, vi_csi_base + addr);
162 static u32 vi_csi_read(struct tegra_vi_channel *chan, unsigned int addr)
164 void __iomem *vi_csi_base;
166 vi_csi_base = chan->vi->iomem + TEGRA210_VI_CSI_BASE(chan->portno);
168 return readl_relaxed(vi_csi_base + addr);
172 * Tegra210 VI channel capture operations
174 static int tegra_channel_capture_setup(struct tegra_vi_channel *chan)
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;
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) |
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);
194 static void tegra_channel_vi_soft_reset(struct tegra_vi_channel *chan)
196 /* disable clock gating to enable continuous clock */
197 tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, 0);
199 * Soft reset memory client interface, pixel format logic, sensor
200 * control logic, and a shadow copy logic to bring VI to clean state.
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);
206 /* enable back VI clock gating */
207 tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, VI_CG_2ND_LEVEL_EN);
210 static void tegra_channel_capture_error_recover(struct tegra_vi_channel *chan)
212 struct v4l2_subdev *subdev;
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.
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);
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);
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);
235 /* recover CSI block */
236 subdev = tegra_channel_get_remote_csi_subdev(chan);
237 tegra_csi_error_recover(subdev);
240 static struct tegra_channel_buffer *
241 dequeue_buf_done(struct tegra_vi_channel *chan)
243 struct tegra_channel_buffer *buf = NULL;
245 spin_lock(&chan->done_lock);
246 if (list_empty(&chan->done)) {
247 spin_unlock(&chan->done_lock);
251 buf = list_first_entry(&chan->done,
252 struct tegra_channel_buffer, queue);
254 list_del_init(&buf->queue);
255 spin_unlock(&chan->done_lock);
260 static void release_buffer(struct tegra_vi_channel *chan,
261 struct tegra_channel_buffer *buf,
262 enum vb2_buffer_state state)
264 struct vb2_v4l2_buffer *vb = &buf->buf;
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);
272 static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
273 struct tegra_channel_buffer *buf)
275 u32 thresh, value, frame_start, mw_ack_done;
276 int bytes_per_line = chan->format.bytesperline;
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);
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
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.
299 /* increase channel syncpoint threshold for FRAME_START */
300 thresh = host1x_syncpt_incr_max(chan->frame_start_sp, 1);
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);
308 /* increase channel syncpoint threshold for MW_ACK_DONE */
309 buf->mw_ack_sp_thresh = host1x_syncpt_incr_max(chan->mw_ack_sp, 1);
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);
317 /* enable single shot capture */
318 vi_csi_write(chan, TEGRA_VI_CSI_SINGLE_SHOT, SINGLE_SHOT_CAPTURE);
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);
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);
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);
342 /* wait up kthread for capture done */
343 wake_up_interruptible(&chan->done_wait);
348 static void tegra_channel_capture_done(struct tegra_vi_channel *chan,
349 struct tegra_channel_buffer *buf)
351 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
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);
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);
368 release_buffer(chan, buf, state);
371 static int chan_capture_kthread_start(void *data)
373 struct tegra_vi_channel *chan = data;
374 struct tegra_channel_buffer *buf;
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.
383 wait_event_interruptible(chan->start_wait,
384 kthread_should_stop() ||
385 (!list_empty(&chan->capture) &&
388 if (kthread_should_stop())
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);
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);
403 err = tegra_channel_capture_frame(chan, buf);
405 vb2_queue_error(&chan->queue);
411 static int chan_capture_kthread_finish(void *data)
413 struct tegra_vi_channel *chan = data;
414 struct tegra_channel_buffer *buf;
417 wait_event_interruptible(chan->done_wait,
418 !list_empty(&chan->done) ||
419 kthread_should_stop());
421 /* dequeue buffers and finish capture */
422 buf = dequeue_buf_done(chan);
424 tegra_channel_capture_done(chan, buf);
425 buf = dequeue_buf_done(chan);
428 if (kthread_should_stop())
435 static int tegra210_vi_start_streaming(struct vb2_queue *vq, u32 count)
437 struct tegra_vi_channel *chan = vb2_get_drv_priv(vq);
438 struct media_pipeline *pipe = &chan->video.pipe;
442 tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, VI_CG_2ND_LEVEL_EN);
445 val = vi_csi_read(chan, TEGRA_VI_CSI_ERROR_STATUS);
446 vi_csi_write(chan, TEGRA_VI_CSI_ERROR_STATUS, val);
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);
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.
458 tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL,
459 VI_INCR_SYNCPT_NO_STALL);
461 /* start the pipeline */
462 ret = media_pipeline_start(&chan->video.entity, pipe);
464 goto error_pipeline_start;
466 tegra_channel_capture_setup(chan);
467 ret = tegra_channel_set_stream(chan, true);
469 goto error_set_stream;
473 /* start kthreads to capture data to buffer and return them */
474 chan->kthread_start_capture = kthread_run(chan_capture_kthread_start,
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;
485 chan->kthread_finish_capture = kthread_run(chan_capture_kthread_finish,
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;
499 kthread_stop(chan->kthread_start_capture);
501 tegra_channel_set_stream(chan, false);
503 media_pipeline_stop(&chan->video.entity);
504 error_pipeline_start:
505 tegra_channel_release_buffers(chan, VB2_BUF_STATE_QUEUED);
509 static void tegra210_vi_stop_streaming(struct vb2_queue *vq)
511 struct tegra_vi_channel *chan = vb2_get_drv_priv(vq);
513 if (chan->kthread_start_capture) {
514 kthread_stop(chan->kthread_start_capture);
515 chan->kthread_start_capture = NULL;
518 if (chan->kthread_finish_capture) {
519 kthread_stop(chan->kthread_finish_capture);
520 chan->kthread_finish_capture = NULL;
523 tegra_channel_release_buffers(chan, VB2_BUF_STATE_ERROR);
524 tegra_channel_set_stream(chan, false);
525 media_pipeline_stop(&chan->video.entity);
529 * Tegra210 VI Pixel memory format enum.
530 * These format enum value gets programmed into corresponding Tegra VI
531 * channel register bits.
533 enum tegra210_image_format {
534 TEGRA210_IMAGE_FORMAT_T_L8 = 16,
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,
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,
557 TEGRA210_IMAGE_FORMAT_T_A8Y8U8V8 = 193,
558 TEGRA210_IMAGE_FORMAT_T_V8U8Y8A8,
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,
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,
580 #define TEGRA210_VIDEO_FMT(DATA_TYPE, BIT_WIDTH, MBUS_CODE, BPP, \
583 TEGRA_IMAGE_DT_##DATA_TYPE, \
585 MEDIA_BUS_FMT_##MBUS_CODE, \
587 TEGRA210_IMAGE_FORMAT_##FORMAT, \
588 V4L2_PIX_FMT_##FOURCC, \
591 /* Tegra210 supported video formats */
592 static const struct tegra_video_format tegra210_video_formats[] = {
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),
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),
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),
609 TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, RGB24),
610 TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8,
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),
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,
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,
636 .vi_max_channels = 6,
637 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
638 .vi_max_clk_hz = 499200000,
640 .vi_max_clk_hz = 998400000,
644 /* Tegra210 CSI PHY registers accessors */
645 static void csi_write(struct tegra_csi *csi, u8 portno, unsigned int addr,
648 void __iomem *csi_pp_base;
650 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
652 writel_relaxed(val, csi_pp_base + addr);
655 /* Tegra210 CSI Pixel parser registers accessors */
656 static void pp_write(struct tegra_csi *csi, u8 portno, u32 addr, u32 val)
658 void __iomem *csi_pp_base;
661 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
662 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
664 writel_relaxed(val, csi_pp_base + offset + addr);
667 static u32 pp_read(struct tegra_csi *csi, u8 portno, u32 addr)
669 void __iomem *csi_pp_base;
672 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
673 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
675 return readl_relaxed(csi_pp_base + offset + addr);
678 /* Tegra210 CSI CIL A/B port registers accessors */
679 static void cil_write(struct tegra_csi *csi, u8 portno, u32 addr, u32 val)
681 void __iomem *csi_cil_base;
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;
688 writel_relaxed(val, csi_cil_base + offset + addr);
691 static u32 cil_read(struct tegra_csi *csi, u8 portno, u32 addr)
693 void __iomem *csi_cil_base;
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;
700 return readl_relaxed(csi_cil_base + offset + addr);
703 /* Tegra210 CSI Test pattern generator registers accessor */
704 static void tpg_write(struct tegra_csi *csi, u8 portno, unsigned int addr,
707 void __iomem *csi_pp_base;
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;
714 writel_relaxed(val, csi_pp_base + offset + addr);
718 * Tegra210 CSI operations
720 static void tegra210_csi_error_recover(struct tegra_csi_channel *csi_chan)
722 struct tegra_csi *csi = csi_chan->csi;
723 unsigned int portno = csi_chan->csi_port_num;
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.
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);
734 val = cil_read(csi, portno, TEGRA_CSI_CIL_STATUS);
735 dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val);
737 val = cil_read(csi, portno, TEGRA_CSI_CILX_STATUS);
738 dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val);
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);
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
750 csi_write(csi, portno, TEGRA_CSI_CSI_SW_STATUS_RESET, 0x1);
752 /* sleep for 20 clock cycles to drain the FIFO */
753 usleep_range(10, 20);
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);
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);
764 /* clear the errors */
765 pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS,
767 cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, 0xffffffff);
768 cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, 0xffffffff);
772 static int tegra210_csi_start_streaming(struct tegra_csi_channel *csi_chan)
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;
780 if (!csi_chan->pg_mode)
781 tegra_csi_calc_settle_time(csi_chan, &clk_settle_time,
784 csi_write(csi, portno, TEGRA_CSI_CLKEN_OVERRIDE, 0);
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);
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));
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
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);
811 cil_write(csi, portno, TEGRA_CSI_CIL_PAD_CONFIG0,
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);
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);
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 |
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));
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) |
855 tpg_write(csi, portno, TEGRA_CSI_PG_BLANK,
856 csi_chan->v_blank << PG_VBLANK_OFFSET |
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);
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);
880 static void tegra210_csi_stop_streaming(struct tegra_csi_channel *csi_chan)
882 struct tegra_csi *csi = csi_chan->csi;
883 unsigned int portno = csi_chan->csi_port_num;
886 val = pp_read(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS);
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);
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);
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);
899 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
900 (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
903 if (csi_chan->pg_mode) {
904 tpg_write(csi, portno, TEGRA_CSI_PATTERN_GENERATOR_CTRL,
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);
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);
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
927 static const struct tpg_framerate tegra210_tpg_frmrate_table[] = {
929 .frmsize = { 1280, 720 },
930 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
936 .frmsize = { 1920, 1080 },
937 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
943 .frmsize = { 3840, 2160 },
944 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
950 .frmsize = { 1280, 720 },
951 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
957 .frmsize = { 1920, 1080 },
958 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
964 .frmsize = { 3840, 2160 },
965 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
972 static const char * const tegra210_csi_cil_clks[] = {
977 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
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,
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),