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 TEGRA210_MIN_WIDTH 32U
21 #define TEGRA210_MAX_WIDTH 32768U
22 #define TEGRA210_MIN_HEIGHT 32U
23 #define TEGRA210_MAX_HEIGHT 32768U
25 #define SURFACE_ALIGN_BYTES 64
27 #define TEGRA_VI_SYNCPT_WAIT_TIMEOUT msecs_to_jiffies(200)
29 /* Tegra210 VI registers */
30 #define TEGRA_VI_CFG_VI_INCR_SYNCPT 0x000
31 #define VI_CFG_VI_INCR_SYNCPT_COND(x) (((x) & 0xff) << 8)
32 #define VI_CSI_PP_FRAME_START(port) (5 + (port) * 4)
33 #define VI_CSI_MW_ACK_DONE(port) (7 + (port) * 4)
34 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL 0x004
35 #define VI_INCR_SYNCPT_NO_STALL BIT(8)
36 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR 0x008
37 #define TEGRA_VI_CFG_CG_CTRL 0x0b8
38 #define VI_CG_2ND_LEVEL_EN 0x1
40 /* Tegra210 VI CSI registers */
41 #define TEGRA_VI_CSI_SW_RESET 0x000
42 #define TEGRA_VI_CSI_SINGLE_SHOT 0x004
43 #define SINGLE_SHOT_CAPTURE 0x1
44 #define TEGRA_VI_CSI_IMAGE_DEF 0x00c
45 #define BYPASS_PXL_TRANSFORM_OFFSET 24
46 #define IMAGE_DEF_FORMAT_OFFSET 16
47 #define IMAGE_DEF_DEST_MEM 0x1
48 #define TEGRA_VI_CSI_IMAGE_SIZE 0x018
49 #define IMAGE_SIZE_HEIGHT_OFFSET 16
50 #define TEGRA_VI_CSI_IMAGE_SIZE_WC 0x01c
51 #define TEGRA_VI_CSI_IMAGE_DT 0x020
52 #define TEGRA_VI_CSI_SURFACE0_OFFSET_MSB 0x024
53 #define TEGRA_VI_CSI_SURFACE0_OFFSET_LSB 0x028
54 #define TEGRA_VI_CSI_SURFACE1_OFFSET_MSB 0x02c
55 #define TEGRA_VI_CSI_SURFACE1_OFFSET_LSB 0x030
56 #define TEGRA_VI_CSI_SURFACE2_OFFSET_MSB 0x034
57 #define TEGRA_VI_CSI_SURFACE2_OFFSET_LSB 0x038
58 #define TEGRA_VI_CSI_SURFACE0_STRIDE 0x054
59 #define TEGRA_VI_CSI_SURFACE1_STRIDE 0x058
60 #define TEGRA_VI_CSI_SURFACE2_STRIDE 0x05c
61 #define TEGRA_VI_CSI_SURFACE_HEIGHT0 0x060
62 #define TEGRA_VI_CSI_ERROR_STATUS 0x084
64 /* Tegra210 CSI Pixel Parser registers: Starts from 0x838, offset 0x0 */
65 #define TEGRA_CSI_INPUT_STREAM_CONTROL 0x000
66 #define CSI_SKIP_PACKET_THRESHOLD_OFFSET 16
67 #define TEGRA_CSI_PIXEL_STREAM_CONTROL0 0x004
68 #define CSI_PP_PACKET_HEADER_SENT BIT(4)
69 #define CSI_PP_DATA_IDENTIFIER_ENABLE BIT(5)
70 #define CSI_PP_WORD_COUNT_SELECT_HEADER BIT(6)
71 #define CSI_PP_CRC_CHECK_ENABLE BIT(7)
72 #define CSI_PP_WC_CHECK BIT(8)
73 #define CSI_PP_OUTPUT_FORMAT_STORE (0x3 << 16)
74 #define CSI_PPA_PAD_LINE_NOPAD (0x2 << 24)
75 #define CSI_PP_HEADER_EC_DISABLE (0x1 << 27)
76 #define CSI_PPA_PAD_FRAME_NOPAD (0x2 << 28)
77 #define TEGRA_CSI_PIXEL_STREAM_CONTROL1 0x008
78 #define CSI_PP_TOP_FIELD_FRAME_OFFSET 0
79 #define CSI_PP_TOP_FIELD_FRAME_MASK_OFFSET 4
80 #define TEGRA_CSI_PIXEL_STREAM_GAP 0x00c
81 #define PP_FRAME_MIN_GAP_OFFSET 16
82 #define TEGRA_CSI_PIXEL_STREAM_PP_COMMAND 0x010
83 #define CSI_PP_ENABLE 0x1
84 #define CSI_PP_DISABLE 0x2
85 #define CSI_PP_RST 0x3
86 #define CSI_PP_SINGLE_SHOT_ENABLE (0x1 << 2)
87 #define CSI_PP_START_MARKER_FRAME_MAX_OFFSET 12
88 #define TEGRA_CSI_PIXEL_STREAM_EXPECTED_FRAME 0x014
89 #define TEGRA_CSI_PIXEL_PARSER_INTERRUPT_MASK 0x018
90 #define TEGRA_CSI_PIXEL_PARSER_STATUS 0x01c
92 /* Tegra210 CSI PHY registers */
93 /* CSI_PHY_CIL_COMMAND_0 offset 0x0d0 from TEGRA_CSI_PIXEL_PARSER_0_BASE */
94 #define TEGRA_CSI_PHY_CIL_COMMAND 0x0d0
95 #define CSI_A_PHY_CIL_NOP 0x0
96 #define CSI_A_PHY_CIL_ENABLE 0x1
97 #define CSI_A_PHY_CIL_DISABLE 0x2
98 #define CSI_A_PHY_CIL_ENABLE_MASK 0x3
99 #define CSI_B_PHY_CIL_NOP (0x0 << 8)
100 #define CSI_B_PHY_CIL_ENABLE (0x1 << 8)
101 #define CSI_B_PHY_CIL_DISABLE (0x2 << 8)
102 #define CSI_B_PHY_CIL_ENABLE_MASK (0x3 << 8)
104 #define TEGRA_CSI_CIL_PAD_CONFIG0 0x000
105 #define BRICK_CLOCK_A_4X (0x1 << 16)
106 #define BRICK_CLOCK_B_4X (0x2 << 16)
107 #define TEGRA_CSI_CIL_PAD_CONFIG1 0x004
108 #define TEGRA_CSI_CIL_PHY_CONTROL 0x008
109 #define CLK_SETTLE_MASK GENMASK(13, 8)
110 #define THS_SETTLE_MASK GENMASK(5, 0)
111 #define TEGRA_CSI_CIL_INTERRUPT_MASK 0x00c
112 #define TEGRA_CSI_CIL_STATUS 0x010
113 #define TEGRA_CSI_CILX_STATUS 0x014
114 #define TEGRA_CSI_CIL_SW_SENSOR_RESET 0x020
116 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL 0x000
117 #define PG_MODE_OFFSET 2
118 #define PG_ENABLE 0x1
119 #define PG_DISABLE 0x0
120 #define TEGRA_CSI_PG_BLANK 0x004
121 #define PG_VBLANK_OFFSET 16
122 #define TEGRA_CSI_PG_PHASE 0x008
123 #define TEGRA_CSI_PG_RED_FREQ 0x00c
124 #define PG_RED_VERT_INIT_FREQ_OFFSET 16
125 #define PG_RED_HOR_INIT_FREQ_OFFSET 0
126 #define TEGRA_CSI_PG_RED_FREQ_RATE 0x010
127 #define TEGRA_CSI_PG_GREEN_FREQ 0x014
128 #define PG_GREEN_VERT_INIT_FREQ_OFFSET 16
129 #define PG_GREEN_HOR_INIT_FREQ_OFFSET 0
130 #define TEGRA_CSI_PG_GREEN_FREQ_RATE 0x018
131 #define TEGRA_CSI_PG_BLUE_FREQ 0x01c
132 #define PG_BLUE_VERT_INIT_FREQ_OFFSET 16
133 #define PG_BLUE_HOR_INIT_FREQ_OFFSET 0
134 #define TEGRA_CSI_PG_BLUE_FREQ_RATE 0x020
135 #define TEGRA_CSI_PG_AOHDR 0x024
136 #define TEGRA_CSI_CSI_SW_STATUS_RESET 0x214
137 #define TEGRA_CSI_CLKEN_OVERRIDE 0x218
139 #define TEGRA210_CSI_PORT_OFFSET 0x34
140 #define TEGRA210_CSI_CIL_OFFSET 0x0f4
141 #define TEGRA210_CSI_TPG_OFFSET 0x18c
143 #define CSI_PP_OFFSET(block) ((block) * 0x800)
144 #define TEGRA210_VI_CSI_BASE(x) (0x100 + (x) * 0x100)
146 /* Tegra210 VI registers accessors */
147 static void tegra_vi_write(struct tegra_vi_channel *chan, unsigned int addr,
150 writel_relaxed(val, chan->vi->iomem + addr);
153 static u32 tegra_vi_read(struct tegra_vi_channel *chan, unsigned int addr)
155 return readl_relaxed(chan->vi->iomem + addr);
158 /* Tegra210 VI_CSI registers accessors */
159 static void vi_csi_write(struct tegra_vi_channel *chan, u8 portno,
160 unsigned int addr, u32 val)
162 void __iomem *vi_csi_base;
164 vi_csi_base = chan->vi->iomem + TEGRA210_VI_CSI_BASE(portno);
166 writel_relaxed(val, vi_csi_base + addr);
169 static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 portno,
172 void __iomem *vi_csi_base;
174 vi_csi_base = chan->vi->iomem + TEGRA210_VI_CSI_BASE(portno);
176 return readl_relaxed(vi_csi_base + addr);
180 * Tegra210 VI channel capture operations
183 static int tegra210_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
185 struct tegra_vi *vi = chan->vi;
186 unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
187 struct host1x_syncpt *fs_sp;
188 struct host1x_syncpt *mw_sp;
191 for (i = 0; i < chan->numgangports; i++) {
192 fs_sp = host1x_syncpt_request(&vi->client, flags);
194 dev_err(vi->dev, "failed to request frame start syncpoint\n");
199 mw_sp = host1x_syncpt_request(&vi->client, flags);
201 dev_err(vi->dev, "failed to request memory ack syncpoint\n");
202 host1x_syncpt_put(fs_sp);
207 chan->frame_start_sp[i] = fs_sp;
208 chan->mw_ack_sp[i] = mw_sp;
209 spin_lock_init(&chan->sp_incr_lock[i]);
215 for (i = 0; i < chan->numgangports; i++) {
216 host1x_syncpt_put(chan->mw_ack_sp[i]);
217 host1x_syncpt_put(chan->frame_start_sp[i]);
222 static void tegra210_channel_host1x_syncpt_free(struct tegra_vi_channel *chan)
226 for (i = 0; i < chan->numgangports; i++) {
227 host1x_syncpt_put(chan->mw_ack_sp[i]);
228 host1x_syncpt_put(chan->frame_start_sp[i]);
232 static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
234 unsigned int min_bpl;
235 unsigned int max_bpl;
239 * The transfer alignment requirements are expressed in bytes.
240 * Clamp the requested width and height to the limits.
242 pix->width = clamp(pix->width, TEGRA210_MIN_WIDTH, TEGRA210_MAX_WIDTH);
243 pix->height = clamp(pix->height, TEGRA210_MIN_HEIGHT, TEGRA210_MAX_HEIGHT);
245 /* Clamp the requested bytes per line value. If the maximum bytes per
246 * line value is zero, the module doesn't support user configurable
247 * line sizes. Override the requested value with the minimum in that
250 min_bpl = pix->width * bpp;
251 max_bpl = rounddown(TEGRA210_MAX_WIDTH, SURFACE_ALIGN_BYTES);
252 bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
254 pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
255 pix->sizeimage = pix->bytesperline * pix->height;
256 if (pix->pixelformat == V4L2_PIX_FMT_NV16)
260 static int tegra_channel_capture_setup(struct tegra_vi_channel *chan,
263 u32 height = chan->format.height;
264 u32 width = chan->format.width;
265 u32 format = chan->fmtinfo->img_fmt;
266 u32 data_type = chan->fmtinfo->img_dt;
267 u32 word_count = (width * chan->fmtinfo->bit_width) / 8;
268 u32 bypass_pixel_transform = BIT(BYPASS_PXL_TRANSFORM_OFFSET);
271 * VI Pixel transformation unit converts source pixels data format
272 * into selected destination pixel format and aligns properly while
273 * interfacing with memory packer.
274 * This pixel transformation should be enabled for YUV and RGB
275 * formats and should be bypassed for RAW formats as RAW formats
276 * only support direct to memory.
278 if (chan->pg_mode || data_type == TEGRA_IMAGE_DT_YUV422_8 ||
279 data_type == TEGRA_IMAGE_DT_RGB888)
280 bypass_pixel_transform = 0;
283 * For x8 source streaming, the source image is split onto two x4 ports
284 * with left half to first x4 port and right half to second x4 port.
285 * So, use split width and corresponding word count for each x4 port.
287 if (chan->numgangports > 1) {
289 word_count = (width * chan->fmtinfo->bit_width) / 8;
292 vi_csi_write(chan, portno, TEGRA_VI_CSI_ERROR_STATUS, 0xffffffff);
293 vi_csi_write(chan, portno, TEGRA_VI_CSI_IMAGE_DEF,
294 bypass_pixel_transform |
295 (format << IMAGE_DEF_FORMAT_OFFSET) |
297 vi_csi_write(chan, portno, TEGRA_VI_CSI_IMAGE_DT, data_type);
298 vi_csi_write(chan, portno, TEGRA_VI_CSI_IMAGE_SIZE_WC, word_count);
299 vi_csi_write(chan, portno, TEGRA_VI_CSI_IMAGE_SIZE,
300 (height << IMAGE_SIZE_HEIGHT_OFFSET) | width);
304 static void tegra_channel_vi_soft_reset(struct tegra_vi_channel *chan,
307 /* disable clock gating to enable continuous clock */
308 tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, 0);
310 * Soft reset memory client interface, pixel format logic, sensor
311 * control logic, and a shadow copy logic to bring VI to clean state.
313 vi_csi_write(chan, portno, TEGRA_VI_CSI_SW_RESET, 0xf);
314 usleep_range(100, 200);
315 vi_csi_write(chan, portno, TEGRA_VI_CSI_SW_RESET, 0x0);
317 /* enable back VI clock gating */
318 tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, VI_CG_2ND_LEVEL_EN);
321 static void tegra_channel_capture_error_recover(struct tegra_vi_channel *chan,
324 struct v4l2_subdev *subdev;
328 * Recover VI and CSI hardware blocks in case of missing frame start
329 * events due to source not streaming or noisy csi inputs from the
330 * external source or many outstanding frame start or MW_ACK_DONE
331 * events which can cause CSI and VI hardware hang.
332 * This helps to have a clean capture for next frame.
334 val = vi_csi_read(chan, portno, TEGRA_VI_CSI_ERROR_STATUS);
335 dev_dbg(&chan->video.dev, "TEGRA_VI_CSI_ERROR_STATUS 0x%08x\n", val);
336 vi_csi_write(chan, portno, TEGRA_VI_CSI_ERROR_STATUS, val);
338 val = tegra_vi_read(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR);
339 dev_dbg(&chan->video.dev,
340 "TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR 0x%08x\n", val);
341 tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR, val);
343 /* recover VI by issuing software reset and re-setup for capture */
344 tegra_channel_vi_soft_reset(chan, portno);
345 tegra_channel_capture_setup(chan, portno);
347 /* recover CSI block */
348 subdev = tegra_channel_get_remote_csi_subdev(chan);
349 tegra_csi_error_recover(subdev);
352 static struct tegra_channel_buffer *
353 dequeue_buf_done(struct tegra_vi_channel *chan)
355 struct tegra_channel_buffer *buf = NULL;
357 spin_lock(&chan->done_lock);
358 if (list_empty(&chan->done)) {
359 spin_unlock(&chan->done_lock);
363 buf = list_first_entry(&chan->done,
364 struct tegra_channel_buffer, queue);
366 list_del_init(&buf->queue);
367 spin_unlock(&chan->done_lock);
372 static void release_buffer(struct tegra_vi_channel *chan,
373 struct tegra_channel_buffer *buf,
374 enum vb2_buffer_state state)
376 struct vb2_v4l2_buffer *vb = &buf->buf;
378 vb->sequence = chan->sequence++;
379 vb->field = V4L2_FIELD_NONE;
380 vb->vb2_buf.timestamp = ktime_get_ns();
381 vb2_buffer_done(&vb->vb2_buf, state);
384 static void tegra_channel_vi_buffer_setup(struct tegra_vi_channel *chan,
385 u8 portno, u32 buf_offset,
386 struct tegra_channel_buffer *buf)
388 int bytesperline = chan->format.bytesperline;
389 u32 sizeimage = chan->format.sizeimage;
391 /* program buffer address by using surface 0 */
392 vi_csi_write(chan, portno, TEGRA_VI_CSI_SURFACE0_OFFSET_MSB,
393 ((u64)buf->addr + buf_offset) >> 32);
394 vi_csi_write(chan, portno, TEGRA_VI_CSI_SURFACE0_OFFSET_LSB,
395 buf->addr + buf_offset);
396 vi_csi_write(chan, portno, TEGRA_VI_CSI_SURFACE0_STRIDE, bytesperline);
398 if (chan->fmtinfo->fourcc != V4L2_PIX_FMT_NV16)
401 * Program surface 1 for UV plane with offset sizeimage from Y plane.
403 vi_csi_write(chan, portno, TEGRA_VI_CSI_SURFACE1_OFFSET_MSB,
404 (((u64)buf->addr + sizeimage / 2) + buf_offset) >> 32);
405 vi_csi_write(chan, portno, TEGRA_VI_CSI_SURFACE1_OFFSET_LSB,
406 buf->addr + sizeimage / 2 + buf_offset);
407 vi_csi_write(chan, portno, TEGRA_VI_CSI_SURFACE1_STRIDE, bytesperline);
410 static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
411 struct tegra_channel_buffer *buf)
413 u32 thresh, value, frame_start, mw_ack_done;
414 u32 fs_thresh[GANG_PORTS_MAX];
415 u8 *portnos = chan->portnos;
416 int gang_bpl = (chan->format.width >> 1) * chan->fmtinfo->bpp;
418 bool capture_timedout = false;
421 for (i = 0; i < chan->numgangports; i++) {
423 * Align buffers side-by-side for all consecutive x4 ports
424 * in gang ports using bytes per line based on source split
427 buf_offset = i * roundup(gang_bpl, SURFACE_ALIGN_BYTES);
428 tegra_channel_vi_buffer_setup(chan, portnos[i], buf_offset,
432 * Tegra VI block interacts with host1x syncpt to synchronize
433 * programmed condition and hardware operation for capture.
434 * Frame start and Memory write acknowledge syncpts has their
435 * own FIFO of depth 2.
437 * Syncpoint trigger conditions set through VI_INCR_SYNCPT
438 * register are added to HW syncpt FIFO and when HW triggers,
439 * syncpt condition is removed from the FIFO and counter at
440 * syncpoint index will be incremented by the hardware and
441 * software can wait for counter to reach threshold to
442 * synchronize capturing frame with hardware capture events.
445 /* increase channel syncpoint threshold for FRAME_START */
446 thresh = host1x_syncpt_incr_max(chan->frame_start_sp[i], 1);
447 fs_thresh[i] = thresh;
449 /* Program FRAME_START trigger condition syncpt request */
450 frame_start = VI_CSI_PP_FRAME_START(portnos[i]);
451 value = VI_CFG_VI_INCR_SYNCPT_COND(frame_start) |
452 host1x_syncpt_id(chan->frame_start_sp[i]);
453 tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
455 /* increase channel syncpoint threshold for MW_ACK_DONE */
456 thresh = host1x_syncpt_incr_max(chan->mw_ack_sp[i], 1);
457 buf->mw_ack_sp_thresh[i] = thresh;
459 /* Program MW_ACK_DONE trigger condition syncpt request */
460 mw_ack_done = VI_CSI_MW_ACK_DONE(portnos[i]);
461 value = VI_CFG_VI_INCR_SYNCPT_COND(mw_ack_done) |
462 host1x_syncpt_id(chan->mw_ack_sp[i]);
463 tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
466 /* enable single shot capture after all ganged ports are ready */
467 for (i = 0; i < chan->numgangports; i++)
468 vi_csi_write(chan, portnos[i], TEGRA_VI_CSI_SINGLE_SHOT,
469 SINGLE_SHOT_CAPTURE);
471 for (i = 0; i < chan->numgangports; i++) {
473 * Wait for syncpt counter to reach frame start event threshold
475 err = host1x_syncpt_wait(chan->frame_start_sp[i], fs_thresh[i],
476 TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
478 capture_timedout = true;
479 /* increment syncpoint counter for timedout events */
480 host1x_syncpt_incr(chan->frame_start_sp[i]);
481 spin_lock(&chan->sp_incr_lock[i]);
482 host1x_syncpt_incr(chan->mw_ack_sp[i]);
483 spin_unlock(&chan->sp_incr_lock[i]);
484 /* clear errors and recover */
485 tegra_channel_capture_error_recover(chan, portnos[i]);
489 if (capture_timedout) {
490 dev_err_ratelimited(&chan->video.dev,
491 "frame start syncpt timeout: %d\n", err);
492 release_buffer(chan, buf, VB2_BUF_STATE_ERROR);
496 /* move buffer to capture done queue */
497 spin_lock(&chan->done_lock);
498 list_add_tail(&buf->queue, &chan->done);
499 spin_unlock(&chan->done_lock);
501 /* wait up kthread for capture done */
502 wake_up_interruptible(&chan->done_wait);
507 static void tegra_channel_capture_done(struct tegra_vi_channel *chan,
508 struct tegra_channel_buffer *buf)
510 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
512 bool capture_timedout = false;
515 for (i = 0; i < chan->numgangports; i++) {
517 * Wait for syncpt counter to reach MW_ACK_DONE event threshold
519 ret = host1x_syncpt_wait(chan->mw_ack_sp[i],
520 buf->mw_ack_sp_thresh[i],
521 TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
523 capture_timedout = true;
524 state = VB2_BUF_STATE_ERROR;
525 /* increment syncpoint counter for timedout event */
526 spin_lock(&chan->sp_incr_lock[i]);
527 host1x_syncpt_incr(chan->mw_ack_sp[i]);
528 spin_unlock(&chan->sp_incr_lock[i]);
532 if (capture_timedout)
533 dev_err_ratelimited(&chan->video.dev,
534 "MW_ACK_DONE syncpt timeout: %d\n", ret);
535 release_buffer(chan, buf, state);
538 static int chan_capture_kthread_start(void *data)
540 struct tegra_vi_channel *chan = data;
541 struct tegra_channel_buffer *buf;
542 unsigned int retries = 0;
547 * Source is not streaming if error is non-zero.
548 * So, do not dequeue buffers on error and let the thread sleep
549 * till kthread stop signal is received.
551 wait_event_interruptible(chan->start_wait,
552 kthread_should_stop() ||
553 (!list_empty(&chan->capture) &&
556 if (kthread_should_stop())
559 /* dequeue the buffer and start capture */
560 spin_lock(&chan->start_lock);
561 if (list_empty(&chan->capture)) {
562 spin_unlock(&chan->start_lock);
566 buf = list_first_entry(&chan->capture,
567 struct tegra_channel_buffer, queue);
568 list_del_init(&buf->queue);
569 spin_unlock(&chan->start_lock);
571 err = tegra_channel_capture_frame(chan, buf);
577 if (retries++ > chan->syncpt_timeout_retry)
578 vb2_queue_error(&chan->queue);
586 static int chan_capture_kthread_finish(void *data)
588 struct tegra_vi_channel *chan = data;
589 struct tegra_channel_buffer *buf;
592 wait_event_interruptible(chan->done_wait,
593 !list_empty(&chan->done) ||
594 kthread_should_stop());
596 /* dequeue buffers and finish capture */
597 buf = dequeue_buf_done(chan);
599 tegra_channel_capture_done(chan, buf);
600 buf = dequeue_buf_done(chan);
603 if (kthread_should_stop())
610 static int tegra210_vi_start_streaming(struct vb2_queue *vq, u32 count)
612 struct tegra_vi_channel *chan = vb2_get_drv_priv(vq);
613 struct media_pipeline *pipe = &chan->video.pipe;
615 u8 *portnos = chan->portnos;
618 tegra_vi_write(chan, TEGRA_VI_CFG_CG_CTRL, VI_CG_2ND_LEVEL_EN);
620 /* clear syncpt errors */
621 val = tegra_vi_read(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR);
622 tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR, val);
625 * Sync point FIFO full stalls the host interface.
626 * Setting NO_STALL will drop INCR_SYNCPT methods when fifos are
627 * full and the corresponding condition bits in INCR_SYNCPT_ERROR
628 * register will be set.
629 * This allows SW to process error recovery.
631 tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL,
632 VI_INCR_SYNCPT_NO_STALL);
634 /* start the pipeline */
635 ret = video_device_pipeline_start(&chan->video, pipe);
637 goto error_pipeline_start;
639 /* clear csi errors and do capture setup for all ports in gang mode */
640 for (i = 0; i < chan->numgangports; i++) {
641 val = vi_csi_read(chan, portnos[i], TEGRA_VI_CSI_ERROR_STATUS);
642 vi_csi_write(chan, portnos[i], TEGRA_VI_CSI_ERROR_STATUS, val);
644 tegra_channel_capture_setup(chan, portnos[i]);
647 ret = tegra_channel_set_stream(chan, true);
649 goto error_set_stream;
653 /* start kthreads to capture data to buffer and return them */
654 chan->kthread_start_capture = kthread_run(chan_capture_kthread_start,
657 if (IS_ERR(chan->kthread_start_capture)) {
658 ret = PTR_ERR(chan->kthread_start_capture);
659 chan->kthread_start_capture = NULL;
660 dev_err(&chan->video.dev,
661 "failed to run capture start kthread: %d\n", ret);
662 goto error_kthread_start;
665 chan->kthread_finish_capture = kthread_run(chan_capture_kthread_finish,
668 if (IS_ERR(chan->kthread_finish_capture)) {
669 ret = PTR_ERR(chan->kthread_finish_capture);
670 chan->kthread_finish_capture = NULL;
671 dev_err(&chan->video.dev,
672 "failed to run capture finish kthread: %d\n", ret);
673 goto error_kthread_done;
679 kthread_stop(chan->kthread_start_capture);
681 tegra_channel_set_stream(chan, false);
683 video_device_pipeline_stop(&chan->video);
684 error_pipeline_start:
685 tegra_channel_release_buffers(chan, VB2_BUF_STATE_QUEUED);
689 static void tegra210_vi_stop_streaming(struct vb2_queue *vq)
691 struct tegra_vi_channel *chan = vb2_get_drv_priv(vq);
693 if (chan->kthread_start_capture) {
694 kthread_stop(chan->kthread_start_capture);
695 chan->kthread_start_capture = NULL;
698 if (chan->kthread_finish_capture) {
699 kthread_stop(chan->kthread_finish_capture);
700 chan->kthread_finish_capture = NULL;
703 tegra_channel_release_buffers(chan, VB2_BUF_STATE_ERROR);
704 tegra_channel_set_stream(chan, false);
705 video_device_pipeline_stop(&chan->video);
709 * Tegra210 VI Pixel memory format enum.
710 * These format enum value gets programmed into corresponding Tegra VI
711 * channel register bits.
713 enum tegra210_image_format {
714 TEGRA210_IMAGE_FORMAT_T_L8 = 16,
716 TEGRA210_IMAGE_FORMAT_T_R16_I = 32,
717 TEGRA210_IMAGE_FORMAT_T_B5G6R5,
718 TEGRA210_IMAGE_FORMAT_T_R5G6B5,
719 TEGRA210_IMAGE_FORMAT_T_A1B5G5R5,
720 TEGRA210_IMAGE_FORMAT_T_A1R5G5B5,
721 TEGRA210_IMAGE_FORMAT_T_B5G5R5A1,
722 TEGRA210_IMAGE_FORMAT_T_R5G5B5A1,
723 TEGRA210_IMAGE_FORMAT_T_A4B4G4R4,
724 TEGRA210_IMAGE_FORMAT_T_A4R4G4B4,
725 TEGRA210_IMAGE_FORMAT_T_B4G4R4A4,
726 TEGRA210_IMAGE_FORMAT_T_R4G4B4A4,
728 TEGRA210_IMAGE_FORMAT_T_A8B8G8R8 = 64,
729 TEGRA210_IMAGE_FORMAT_T_A8R8G8B8,
730 TEGRA210_IMAGE_FORMAT_T_B8G8R8A8,
731 TEGRA210_IMAGE_FORMAT_T_R8G8B8A8,
732 TEGRA210_IMAGE_FORMAT_T_A2B10G10R10,
733 TEGRA210_IMAGE_FORMAT_T_A2R10G10B10,
734 TEGRA210_IMAGE_FORMAT_T_B10G10R10A2,
735 TEGRA210_IMAGE_FORMAT_T_R10G10B10A2,
737 TEGRA210_IMAGE_FORMAT_T_A8Y8U8V8 = 193,
738 TEGRA210_IMAGE_FORMAT_T_V8U8Y8A8,
740 TEGRA210_IMAGE_FORMAT_T_A2Y10U10V10 = 197,
741 TEGRA210_IMAGE_FORMAT_T_V10U10Y10A2,
742 TEGRA210_IMAGE_FORMAT_T_Y8_U8__Y8_V8,
743 TEGRA210_IMAGE_FORMAT_T_Y8_V8__Y8_U8,
744 TEGRA210_IMAGE_FORMAT_T_U8_Y8__V8_Y8,
745 TEGRA210_IMAGE_FORMAT_T_V8_Y8__U8_Y8,
747 TEGRA210_IMAGE_FORMAT_T_Y8__U8__V8_N444 = 224,
748 TEGRA210_IMAGE_FORMAT_T_Y8__U8V8_N444,
749 TEGRA210_IMAGE_FORMAT_T_Y8__V8U8_N444,
750 TEGRA210_IMAGE_FORMAT_T_Y8__U8__V8_N422,
751 TEGRA210_IMAGE_FORMAT_T_Y8__U8V8_N422,
752 TEGRA210_IMAGE_FORMAT_T_Y8__V8U8_N422,
753 TEGRA210_IMAGE_FORMAT_T_Y8__U8__V8_N420,
754 TEGRA210_IMAGE_FORMAT_T_Y8__U8V8_N420,
755 TEGRA210_IMAGE_FORMAT_T_Y8__V8U8_N420,
756 TEGRA210_IMAGE_FORMAT_T_X2LC10LB10LA10,
757 TEGRA210_IMAGE_FORMAT_T_A2R6R6R6R6R6,
760 #define TEGRA210_VIDEO_FMT(DATA_TYPE, BIT_WIDTH, MBUS_CODE, BPP, \
763 TEGRA_IMAGE_DT_##DATA_TYPE, \
765 MEDIA_BUS_FMT_##MBUS_CODE, \
767 TEGRA210_IMAGE_FORMAT_##FORMAT, \
768 V4L2_PIX_FMT_##FOURCC, \
771 /* Tegra210 supported video formats */
772 static const struct tegra_video_format tegra210_video_formats[] = {
774 TEGRA210_VIDEO_FMT(RAW8, 8, SRGGB8_1X8, 1, T_L8, SRGGB8),
775 TEGRA210_VIDEO_FMT(RAW8, 8, SGRBG8_1X8, 1, T_L8, SGRBG8),
776 TEGRA210_VIDEO_FMT(RAW8, 8, SGBRG8_1X8, 1, T_L8, SGBRG8),
777 TEGRA210_VIDEO_FMT(RAW8, 8, SBGGR8_1X8, 1, T_L8, SBGGR8),
779 TEGRA210_VIDEO_FMT(RAW10, 10, SRGGB10_1X10, 2, T_R16_I, SRGGB10),
780 TEGRA210_VIDEO_FMT(RAW10, 10, SGRBG10_1X10, 2, T_R16_I, SGRBG10),
781 TEGRA210_VIDEO_FMT(RAW10, 10, SGBRG10_1X10, 2, T_R16_I, SGBRG10),
782 TEGRA210_VIDEO_FMT(RAW10, 10, SBGGR10_1X10, 2, T_R16_I, SBGGR10),
784 TEGRA210_VIDEO_FMT(RAW12, 12, SRGGB12_1X12, 2, T_R16_I, SRGGB12),
785 TEGRA210_VIDEO_FMT(RAW12, 12, SGRBG12_1X12, 2, T_R16_I, SGRBG12),
786 TEGRA210_VIDEO_FMT(RAW12, 12, SGBRG12_1X12, 2, T_R16_I, SGBRG12),
787 TEGRA210_VIDEO_FMT(RAW12, 12, SBGGR12_1X12, 2, T_R16_I, SBGGR12),
789 TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, XBGR32),
790 TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8,
793 TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 2, T_U8_Y8__V8_Y8, YVYU),
794 TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_1X16, 2, T_V8_Y8__U8_Y8, YUYV),
795 TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_1X16, 2, T_Y8_U8__Y8_V8, VYUY),
796 TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_1X16, 2, T_Y8_V8__Y8_U8, UYVY),
797 TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 1, T_Y8__V8U8_N422, NV16),
798 TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_2X8, 2, T_U8_Y8__V8_Y8, YVYU),
799 TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, YUYV),
800 TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, VYUY),
801 TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, UYVY),
804 /* Tegra210 VI operations */
805 static const struct tegra_vi_ops tegra210_vi_ops = {
806 .channel_host1x_syncpt_init = tegra210_channel_host1x_syncpt_init,
807 .channel_host1x_syncpt_free = tegra210_channel_host1x_syncpt_free,
808 .vi_fmt_align = tegra210_fmt_align,
809 .vi_start_streaming = tegra210_vi_start_streaming,
810 .vi_stop_streaming = tegra210_vi_stop_streaming,
813 /* Tegra210 VI SoC data */
814 const struct tegra_vi_soc tegra210_vi_soc = {
815 .video_formats = tegra210_video_formats,
816 .nformats = ARRAY_SIZE(tegra210_video_formats),
817 .ops = &tegra210_vi_ops,
819 .vi_max_channels = 6,
820 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
821 .default_video_format = &tegra210_video_formats[0],
822 .vi_max_clk_hz = 499200000,
824 .default_video_format = &tegra210_video_formats[4],
825 .vi_max_clk_hz = 998400000,
829 /* Tegra210 CSI PHY registers accessors */
830 static void csi_write(struct tegra_csi *csi, u8 portno, unsigned int addr,
833 void __iomem *csi_pp_base;
835 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
837 writel_relaxed(val, csi_pp_base + addr);
840 /* Tegra210 CSI Pixel parser registers accessors */
841 static void pp_write(struct tegra_csi *csi, u8 portno, u32 addr, u32 val)
843 void __iomem *csi_pp_base;
846 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
847 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
849 writel_relaxed(val, csi_pp_base + offset + addr);
852 static u32 pp_read(struct tegra_csi *csi, u8 portno, u32 addr)
854 void __iomem *csi_pp_base;
857 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
858 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
860 return readl_relaxed(csi_pp_base + offset + addr);
863 /* Tegra210 CSI CIL A/B port registers accessors */
864 static void cil_write(struct tegra_csi *csi, u8 portno, u32 addr, u32 val)
866 void __iomem *csi_cil_base;
869 csi_cil_base = csi->iomem + CSI_PP_OFFSET(portno >> 1) +
870 TEGRA210_CSI_CIL_OFFSET;
871 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
873 writel_relaxed(val, csi_cil_base + offset + addr);
876 static u32 cil_read(struct tegra_csi *csi, u8 portno, u32 addr)
878 void __iomem *csi_cil_base;
881 csi_cil_base = csi->iomem + CSI_PP_OFFSET(portno >> 1) +
882 TEGRA210_CSI_CIL_OFFSET;
883 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET;
885 return readl_relaxed(csi_cil_base + offset + addr);
888 /* Tegra210 CSI Test pattern generator registers accessor */
889 static void tpg_write(struct tegra_csi *csi, u8 portno, unsigned int addr,
892 void __iomem *csi_pp_base;
895 csi_pp_base = csi->iomem + CSI_PP_OFFSET(portno >> 1);
896 offset = (portno % CSI_PORTS_PER_BRICK) * TEGRA210_CSI_PORT_OFFSET +
897 TEGRA210_CSI_TPG_OFFSET;
899 writel_relaxed(val, csi_pp_base + offset + addr);
903 * Tegra210 CSI operations
905 static void tegra210_csi_port_recover(struct tegra_csi_channel *csi_chan,
908 struct tegra_csi *csi = csi_chan->csi;
912 * Recover CSI hardware in case of capture errors by issuing
913 * software reset to CSICIL sensor, pixel parser, and clear errors
914 * to have clean capture on next streaming.
916 val = pp_read(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS);
917 dev_dbg(csi->dev, "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n", val);
919 val = cil_read(csi, portno, TEGRA_CSI_CIL_STATUS);
920 dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val);
922 val = cil_read(csi, portno, TEGRA_CSI_CILX_STATUS);
923 dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val);
925 if (csi_chan->numlanes == 4) {
926 /* reset CSI CIL sensor */
927 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
928 cil_write(csi, portno + 1, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
930 * SW_STATUS_RESET resets all status bits of PPA, PPB, CILA,
931 * CILB status registers and debug counters.
932 * So, SW_STATUS_RESET can be used only when CSI brick is in
935 csi_write(csi, portno, TEGRA_CSI_CSI_SW_STATUS_RESET, 0x1);
937 /* sleep for 20 clock cycles to drain the FIFO */
938 usleep_range(10, 20);
940 cil_write(csi, portno + 1, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
941 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
942 csi_write(csi, portno, TEGRA_CSI_CSI_SW_STATUS_RESET, 0x0);
944 /* reset CSICIL sensor */
945 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
946 usleep_range(10, 20);
947 cil_write(csi, portno, TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
949 /* clear the errors */
950 pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS,
952 cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, 0xffffffff);
953 cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, 0xffffffff);
957 static void tegra210_csi_error_recover(struct tegra_csi_channel *csi_chan)
959 u8 *portnos = csi_chan->csi_port_nums;
962 for (i = 0; i < csi_chan->numgangports; i++)
963 tegra210_csi_port_recover(csi_chan, portnos[i]);
967 tegra210_csi_port_start_streaming(struct tegra_csi_channel *csi_chan,
970 struct tegra_csi *csi = csi_chan->csi;
971 u8 clk_settle_time = 0;
972 u8 ths_settle_time = 10;
975 if (!csi_chan->pg_mode)
976 tegra_csi_calc_settle_time(csi_chan, portno, &clk_settle_time,
979 csi_write(csi, portno, TEGRA_CSI_CLKEN_OVERRIDE, 0);
981 /* clean up status */
982 pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS, 0xffffffff);
983 cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, 0xffffffff);
984 cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, 0xffffffff);
985 cil_write(csi, portno, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
987 /* CIL PHY registers setup */
988 cil_write(csi, portno, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
989 cil_write(csi, portno, TEGRA_CSI_CIL_PHY_CONTROL,
990 FIELD_PREP(CLK_SETTLE_MASK, clk_settle_time) |
991 FIELD_PREP(THS_SETTLE_MASK, ths_settle_time));
994 * The CSI unit provides for connection of up to six cameras in
995 * the system and is organized as three identical instances of
996 * two MIPI support blocks, each with a separate 4-lane
997 * interface that can be configured as a single camera with 4
998 * lanes or as a dual camera with 2 lanes available for each
1001 if (csi_chan->numlanes == 4) {
1002 cil_write(csi, portno + 1, TEGRA_CSI_CIL_STATUS, 0xffffffff);
1003 cil_write(csi, portno + 1, TEGRA_CSI_CILX_STATUS, 0xffffffff);
1004 cil_write(csi, portno + 1, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
1006 cil_write(csi, portno, TEGRA_CSI_CIL_PAD_CONFIG0,
1008 cil_write(csi, portno + 1, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
1009 cil_write(csi, portno + 1, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
1010 cil_write(csi, portno + 1, TEGRA_CSI_CIL_PHY_CONTROL,
1011 FIELD_PREP(CLK_SETTLE_MASK, clk_settle_time) |
1012 FIELD_PREP(THS_SETTLE_MASK, ths_settle_time));
1013 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND,
1014 CSI_A_PHY_CIL_ENABLE | CSI_B_PHY_CIL_ENABLE);
1016 val = ((portno & 1) == PORT_A) ?
1017 CSI_A_PHY_CIL_ENABLE | CSI_B_PHY_CIL_NOP :
1018 CSI_B_PHY_CIL_ENABLE | CSI_A_PHY_CIL_NOP;
1019 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND, val);
1022 /* CSI pixel parser registers setup */
1023 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
1024 (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
1025 CSI_PP_SINGLE_SHOT_ENABLE | CSI_PP_RST);
1026 pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_INTERRUPT_MASK, 0x0);
1027 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_CONTROL0,
1028 CSI_PP_PACKET_HEADER_SENT |
1029 CSI_PP_DATA_IDENTIFIER_ENABLE |
1030 CSI_PP_WORD_COUNT_SELECT_HEADER |
1031 CSI_PP_CRC_CHECK_ENABLE | CSI_PP_WC_CHECK |
1032 CSI_PP_OUTPUT_FORMAT_STORE | CSI_PPA_PAD_LINE_NOPAD |
1033 CSI_PP_HEADER_EC_DISABLE | CSI_PPA_PAD_FRAME_NOPAD |
1035 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_CONTROL1,
1036 (0x1 << CSI_PP_TOP_FIELD_FRAME_OFFSET) |
1037 (0x1 << CSI_PP_TOP_FIELD_FRAME_MASK_OFFSET));
1038 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_GAP,
1039 0x14 << PP_FRAME_MIN_GAP_OFFSET);
1040 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_EXPECTED_FRAME, 0x0);
1041 pp_write(csi, portno, TEGRA_CSI_INPUT_STREAM_CONTROL,
1042 (0x3f << CSI_SKIP_PACKET_THRESHOLD_OFFSET) |
1043 (csi_chan->numlanes - 1));
1046 if (csi_chan->pg_mode) {
1047 tpg_write(csi, portno, TEGRA_CSI_PATTERN_GENERATOR_CTRL,
1048 ((csi_chan->pg_mode - 1) << PG_MODE_OFFSET) |
1050 tpg_write(csi, portno, TEGRA_CSI_PG_BLANK,
1051 csi_chan->v_blank << PG_VBLANK_OFFSET |
1053 tpg_write(csi, portno, TEGRA_CSI_PG_PHASE, 0x0);
1054 tpg_write(csi, portno, TEGRA_CSI_PG_RED_FREQ,
1055 (0x10 << PG_RED_VERT_INIT_FREQ_OFFSET) |
1056 (0x10 << PG_RED_HOR_INIT_FREQ_OFFSET));
1057 tpg_write(csi, portno, TEGRA_CSI_PG_RED_FREQ_RATE, 0x0);
1058 tpg_write(csi, portno, TEGRA_CSI_PG_GREEN_FREQ,
1059 (0x10 << PG_GREEN_VERT_INIT_FREQ_OFFSET) |
1060 (0x10 << PG_GREEN_HOR_INIT_FREQ_OFFSET));
1061 tpg_write(csi, portno, TEGRA_CSI_PG_GREEN_FREQ_RATE, 0x0);
1062 tpg_write(csi, portno, TEGRA_CSI_PG_BLUE_FREQ,
1063 (0x10 << PG_BLUE_VERT_INIT_FREQ_OFFSET) |
1064 (0x10 << PG_BLUE_HOR_INIT_FREQ_OFFSET));
1065 tpg_write(csi, portno, TEGRA_CSI_PG_BLUE_FREQ_RATE, 0x0);
1068 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
1069 (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
1070 CSI_PP_SINGLE_SHOT_ENABLE | CSI_PP_ENABLE);
1076 tegra210_csi_port_stop_streaming(struct tegra_csi_channel *csi_chan, u8 portno)
1078 struct tegra_csi *csi = csi_chan->csi;
1081 val = pp_read(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS);
1083 dev_dbg(csi->dev, "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n", val);
1084 pp_write(csi, portno, TEGRA_CSI_PIXEL_PARSER_STATUS, val);
1086 val = cil_read(csi, portno, TEGRA_CSI_CIL_STATUS);
1087 dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val);
1088 cil_write(csi, portno, TEGRA_CSI_CIL_STATUS, val);
1090 val = cil_read(csi, portno, TEGRA_CSI_CILX_STATUS);
1091 dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val);
1092 cil_write(csi, portno, TEGRA_CSI_CILX_STATUS, val);
1094 pp_write(csi, portno, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
1095 (0xf << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
1098 if (csi_chan->pg_mode) {
1099 tpg_write(csi, portno, TEGRA_CSI_PATTERN_GENERATOR_CTRL,
1104 if (csi_chan->numlanes == 4) {
1105 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND,
1106 CSI_A_PHY_CIL_DISABLE |
1107 CSI_B_PHY_CIL_DISABLE);
1109 val = ((portno & 1) == PORT_A) ?
1110 CSI_A_PHY_CIL_DISABLE | CSI_B_PHY_CIL_NOP :
1111 CSI_B_PHY_CIL_DISABLE | CSI_A_PHY_CIL_NOP;
1112 csi_write(csi, portno, TEGRA_CSI_PHY_CIL_COMMAND, val);
1116 static int tegra210_csi_start_streaming(struct tegra_csi_channel *csi_chan)
1118 u8 *portnos = csi_chan->csi_port_nums;
1121 for (i = 0; i < csi_chan->numgangports; i++) {
1122 ret = tegra210_csi_port_start_streaming(csi_chan, portnos[i]);
1124 goto stream_start_fail;
1130 for (i = i - 1; i >= 0; i--)
1131 tegra210_csi_port_stop_streaming(csi_chan, portnos[i]);
1136 static void tegra210_csi_stop_streaming(struct tegra_csi_channel *csi_chan)
1138 u8 *portnos = csi_chan->csi_port_nums;
1141 for (i = 0; i < csi_chan->numgangports; i++)
1142 tegra210_csi_port_stop_streaming(csi_chan, portnos[i]);
1146 * Tegra210 CSI TPG frame rate table with horizontal and vertical
1147 * blanking intervals for corresponding format and resolution.
1148 * Blanking intervals are tuned values from design team for max TPG
1151 static const struct tpg_framerate tegra210_tpg_frmrate_table[] = {
1153 .frmsize = { 1280, 720 },
1154 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
1160 .frmsize = { 1920, 1080 },
1161 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
1167 .frmsize = { 3840, 2160 },
1168 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
1174 .frmsize = { 1280, 720 },
1175 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
1181 .frmsize = { 1920, 1080 },
1182 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
1188 .frmsize = { 3840, 2160 },
1189 .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI,
1196 static const char * const tegra210_csi_cil_clks[] = {
1201 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
1206 /* Tegra210 CSI operations */
1207 static const struct tegra_csi_ops tegra210_csi_ops = {
1208 .csi_start_streaming = tegra210_csi_start_streaming,
1209 .csi_stop_streaming = tegra210_csi_stop_streaming,
1210 .csi_err_recover = tegra210_csi_error_recover,
1213 /* Tegra210 CSI SoC data */
1214 const struct tegra_csi_soc tegra210_csi_soc = {
1215 .ops = &tegra210_csi_ops,
1216 .csi_max_channels = 6,
1217 .clk_names = tegra210_csi_cil_clks,
1218 .num_clks = ARRAY_SIZE(tegra210_csi_cil_clks),
1219 .tpg_frmrate_table = tegra210_tpg_frmrate_table,
1220 .tpg_frmrate_table_size = ARRAY_SIZE(tegra210_tpg_frmrate_table),