2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <linux/delay.h>
18 #include <linux/clk.h>
19 #include <linux/platform_device.h>
21 #include <media/soc_camera.h>
22 #include <media/soc_mediabus.h>
23 #include <media/tegra_v4l2_camera.h>
27 #include "nvhost_syncpt.h"
30 #define TEGRA_SYNCPT_VI_WAIT_TIMEOUT 200
31 #define TEGRA_SYNCPT_CSI_WAIT_TIMEOUT 200
33 #define TEGRA_VIP_H_ACTIVE_START 0x98
34 #define TEGRA_VIP_V_ACTIVE_START 0x10
36 /* Tegra CSI-MIPI registers. */
37 #define TEGRA_VI_OUT_1_INCR_SYNCPT 0x000
38 #define TEGRA_VI_OUT_1_INCR_SYNCPT_CNTRL 0x004
39 #define TEGRA_VI_OUT_1_INCR_SYNCPT_ERROR 0x008
40 #define TEGRA_VI_OUT_2_INCR_SYNCPT 0x020
41 #define TEGRA_VI_OUT_2_INCR_SYNCPT_CNTRL 0x024
42 #define TEGRA_VI_OUT_2_INCR_SYNCPT_ERROR 0x028
43 #define TEGRA_VI_MISC_INCR_SYNCPT 0x040
44 #define TEGRA_VI_MISC_INCR_SYNCPT_CNTRL 0x044
45 #define TEGRA_VI_MISC_INCR_SYNCPT_ERROR 0x048
46 #define TEGRA_VI_CONT_SYNCPT_OUT_1 0x060
47 #define TEGRA_VI_CONT_SYNCPT_OUT_2 0x064
48 #define TEGRA_VI_CONT_SYNCPT_VIP_VSYNC 0x068
49 #define TEGRA_VI_CONT_SYNCPT_VI2EPP 0x06c
50 #define TEGRA_VI_CONT_SYNCPT_CSI_PPA_FRAME_START 0x070
51 #define TEGRA_VI_CONT_SYNCPT_CSI_PPA_FRAME_END 0x074
52 #define TEGRA_VI_CONT_SYNCPT_CSI_PPB_FRAME_START 0x078
53 #define TEGRA_VI_CONT_SYNCPT_CSI_PPB_FRAME_END 0x07c
54 #define TEGRA_VI_CTXSW 0x080
55 #define TEGRA_VI_INTSTATUS 0x084
56 #define TEGRA_VI_VI_INPUT_CONTROL 0x088
57 #define TEGRA_VI_VI_CORE_CONTROL 0x08c
58 #define TEGRA_VI_VI_FIRST_OUTPUT_CONTROL 0x090
59 #define TEGRA_VI_VI_SECOND_OUTPUT_CONTROL 0x094
60 #define TEGRA_VI_HOST_INPUT_FRAME_SIZE 0x098
61 #define TEGRA_VI_HOST_H_ACTIVE 0x09c
62 #define TEGRA_VI_HOST_V_ACTIVE 0x0a0
63 #define TEGRA_VI_VIP_H_ACTIVE 0x0a4
64 #define TEGRA_VI_VIP_V_ACTIVE 0x0a8
65 #define TEGRA_VI_VI_PEER_CONTROL 0x0ac
66 #define TEGRA_VI_VI_DMA_SELECT 0x0b0
67 #define TEGRA_VI_HOST_DMA_WRITE_BUFFER 0x0b4
68 #define TEGRA_VI_HOST_DMA_BASE_ADDRESS 0x0b8
69 #define TEGRA_VI_HOST_DMA_WRITE_BUFFER_STATUS 0x0bc
70 #define TEGRA_VI_HOST_DMA_WRITE_PEND_BUFCOUNT 0x0c0
71 #define TEGRA_VI_VB0_START_ADDRESS_FIRST 0x0c4
72 #define TEGRA_VI_VB0_BASE_ADDRESS_FIRST 0x0c8
73 #define TEGRA_VI_VB0_START_ADDRESS_U 0x0cc
74 #define TEGRA_VI_VB0_BASE_ADDRESS_U 0x0d0
75 #define TEGRA_VI_VB0_START_ADDRESS_V 0x0d4
76 #define TEGRA_VI_VB0_BASE_ADDRESS_V 0x0d8
77 #define TEGRA_VI_VB_SCRATCH_ADDRESS_UV 0x0dc
78 #define TEGRA_VI_FIRST_OUTPUT_FRAME_SIZE 0x0e0
79 #define TEGRA_VI_VB0_COUNT_FIRST 0x0e4
80 #define TEGRA_VI_VB0_SIZE_FIRST 0x0e8
81 #define TEGRA_VI_VB0_BUFFER_STRIDE_FIRST 0x0ec
82 #define TEGRA_VI_VB0_START_ADDRESS_SECOND 0x0f0
83 #define TEGRA_VI_VB0_BASE_ADDRESS_SECOND 0x0f4
84 #define TEGRA_VI_SECOND_OUTPUT_FRAME_SIZE 0x0f8
85 #define TEGRA_VI_VB0_COUNT_SECOND 0x0fc
86 #define TEGRA_VI_VB0_SIZE_SECOND 0x100
87 #define TEGRA_VI_VB0_BUFFER_STRIDE_SECOND 0x104
88 #define TEGRA_VI_H_LPF_CONTROL 0x108
89 #define TEGRA_VI_H_DOWNSCALE_CONTROL 0x10c
90 #define TEGRA_VI_V_DOWNSCALE_CONTROL 0x110
91 #define TEGRA_VI_CSC_Y 0x114
92 #define TEGRA_VI_CSC_UV_R 0x118
93 #define TEGRA_VI_CSC_UV_G 0x11c
94 #define TEGRA_VI_CSC_UV_B 0x120
95 #define TEGRA_VI_CSC_ALPHA 0x124
96 #define TEGRA_VI_HOST_VSYNC 0x128
97 #define TEGRA_VI_COMMAND 0x12c
98 #define TEGRA_VI_HOST_FIFO_STATUS 0x130
99 #define TEGRA_VI_INTERRUPT_MASK 0x134
100 #define TEGRA_VI_INTERRUPT_TYPE_SELECT 0x138
101 #define TEGRA_VI_INTERRUPT_POLARITY_SELECT 0x13c
102 #define TEGRA_VI_INTERRUPT_STATUS 0x140
103 #define TEGRA_VI_VIP_INPUT_STATUS 0x144
104 #define TEGRA_VI_VIDEO_BUFFER_STATUS 0x148
105 #define TEGRA_VI_SYNC_OUTPUT 0x14c
106 #define TEGRA_VI_VVS_OUTPUT_DELAY 0x150
107 #define TEGRA_VI_PWM_CONTROL 0x154
108 #define TEGRA_VI_PWM_SELECT_PULSE_A 0x158
109 #define TEGRA_VI_PWM_SELECT_PULSE_B 0x15c
110 #define TEGRA_VI_PWM_SELECT_PULSE_C 0x160
111 #define TEGRA_VI_PWM_SELECT_PULSE_D 0x164
112 #define TEGRA_VI_VI_DATA_INPUT_CONTROL 0x168
113 #define TEGRA_VI_PIN_INPUT_ENABLE 0x16c
114 #define TEGRA_VI_PIN_OUTPUT_ENABLE 0x170
115 #define TEGRA_VI_PIN_INVERSION 0x174
116 #define TEGRA_VI_PIN_INPUT_DATA 0x178
117 #define TEGRA_VI_PIN_OUTPUT_DATA 0x17c
118 #define TEGRA_VI_PIN_OUTPUT_SELECT 0x180
119 #define TEGRA_VI_RAISE_VIP_BUFFER_FIRST_OUTPUT 0x184
120 #define TEGRA_VI_RAISE_VIP_FRAME_FIRST_OUTPUT 0x188
121 #define TEGRA_VI_RAISE_VIP_BUFFER_SECOND_OUTPUT 0x18c
122 #define TEGRA_VI_RAISE_VIP_FRAME_SECOND_OUTPUT 0x190
123 #define TEGRA_VI_RAISE_HOST_FIRST_OUTPUT 0x194
124 #define TEGRA_VI_RAISE_HOST_SECOND_OUTPUT 0x198
125 #define TEGRA_VI_RAISE_EPP 0x19c
126 #define TEGRA_VI_CAMERA_CONTROL 0x1a0
127 #define TEGRA_VI_VI_ENABLE 0x1a4
128 #define TEGRA_VI_VI_ENABLE_2 0x1a8
129 #define TEGRA_VI_VI_RAISE 0x1ac
130 #define TEGRA_VI_Y_FIFO_WRITE 0x1b0
131 #define TEGRA_VI_U_FIFO_WRITE 0x1b4
132 #define TEGRA_VI_V_FIFO_WRITE 0x1b8
133 #define TEGRA_VI_VI_MCCIF_FIFOCTRL 0x1bc
134 #define TEGRA_VI_TIMEOUT_WCOAL_VI 0x1c0
135 #define TEGRA_VI_MCCIF_VIRUV_HP 0x1c4
136 #define TEGRA_VI_MCCIF_VIWSB_HP 0x1c8
137 #define TEGRA_VI_MCCIF_VIWU_HP 0x1cc
138 #define TEGRA_VI_MCCIF_VIWV_HP 0x1d0
139 #define TEGRA_VI_MCCIF_VIWY_HP 0x1d4
140 #define TEGRA_VI_CSI_PPA_RAISE_FRAME_START 0x1d8
141 #define TEGRA_VI_CSI_PPA_RAISE_FRAME_END 0x1dc
142 #define TEGRA_VI_CSI_PPB_RAISE_FRAME_START 0x1e0
143 #define TEGRA_VI_CSI_PBB_RAISE_FRAME_END 0x1e4
144 #define TEGRA_VI_CSI_PPA_H_ACTIVE 0x1e8
145 #define TEGRA_VI_CSI_PPA_V_ACTIVE 0x1ec
146 #define TEGRA_VI_CSI_PPB_H_ACTIVE 0x1f0
147 #define TEGRA_VI_CSI_PPB_V_ACTIVE 0x1f4
148 #define TEGRA_VI_ISP_H_ACTIVE 0x1f8
149 #define TEGRA_VI_ISP_V_ACTIVE 0x1fc
150 #define TEGRA_VI_STREAM_1_RESOURCE_DEFINE 0x200
151 #define TEGRA_VI_STREAM_2_RESOURCE_DEFINE 0x204
152 #define TEGRA_VI_RAISE_STREAM_1_DONE 0x208
153 #define TEGRA_VI_RAISE_STREAM_2_DONE 0x20c
154 #define TEGRA_VI_TS_MODE 0x210
155 #define TEGRA_VI_TS_CONTROL 0x214
156 #define TEGRA_VI_TS_PACKET_COUNT 0x218
157 #define TEGRA_VI_TS_ERROR_COUNT 0x21c
158 #define TEGRA_VI_TS_CPU_FLOW_CTL 0x220
159 #define TEGRA_VI_VB0_CHROMA_BUFFER_STRIDE_FIRST 0x224
160 #define TEGRA_VI_VB0_CHROMA_LINE_STRIDE_FIRST 0x228
161 #define TEGRA_VI_EPP_LINES_PER_BUFFER 0x22c
162 #define TEGRA_VI_BUFFER_RELEASE_OUTPUT1 0x230
163 #define TEGRA_VI_BUFFER_RELEASE_OUTPUT2 0x234
164 #define TEGRA_VI_DEBUG_FLOW_CONTROL_COUNTER_OUTPUT1 0x238
165 #define TEGRA_VI_DEBUG_FLOW_CONTROL_COUNTER_OUTPUT2 0x23c
166 #define TEGRA_VI_TERMINATE_BW_FIRST 0x240
167 #define TEGRA_VI_TERMINATE_BW_SECOND 0x244
168 #define TEGRA_VI_VB0_FIRST_BUFFER_ADDR_MODE 0x248
169 #define TEGRA_VI_VB0_SECOND_BUFFER_ADDR_MODE 0x24c
170 #define TEGRA_VI_RESERVE 0x250
171 #define TEGRA_VI_RESERVE_1 0x254
172 #define TEGRA_VI_RESERVE_2 0x258
173 #define TEGRA_VI_RESERVE_3 0x25c
174 #define TEGRA_VI_RESERVE_4 0x260
175 #define TEGRA_VI_MCCIF_VIRUV_HYST 0x264
176 #define TEGRA_VI_MCCIF_VIWSB_HYST 0x268
177 #define TEGRA_VI_MCCIF_VIWU_HYST 0x26c
178 #define TEGRA_VI_MCCIF_VIWV_HYST 0x270
179 #define TEGRA_VI_MCCIF_VIWY_HYST 0x274
181 #define TEGRA_CSI_VI_INPUT_STREAM_CONTROL 0x800
182 #define TEGRA_CSI_HOST_INPUT_STREAM_CONTROL 0x808
183 #define TEGRA_CSI_INPUT_STREAM_A_CONTROL 0x810
184 #define TEGRA_CSI_PIXEL_STREAM_A_CONTROL0 0x818
185 #define TEGRA_CSI_PIXEL_STREAM_A_CONTROL1 0x81c
186 #define TEGRA_CSI_PIXEL_STREAM_A_WORD_COUNT 0x820
187 #define TEGRA_CSI_PIXEL_STREAM_A_GAP 0x824
188 #define TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND 0x828
189 #define TEGRA_CSI_INPUT_STREAM_B_CONTROL 0x83c
190 #define TEGRA_CSI_PIXEL_STREAM_B_CONTROL0 0x844
191 #define TEGRA_CSI_PIXEL_STREAM_B_CONTROL1 0x848
192 #define TEGRA_CSI_PIXEL_STREAM_B_WORD_COUNT 0x84c
193 #define TEGRA_CSI_PIXEL_STREAM_B_GAP 0x850
194 #define TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND 0x854
195 #define TEGRA_CSI_PHY_CIL_COMMAND 0x868
196 #define TEGRA_CSI_PHY_CILA_CONTROL0 0x86c
197 #define TEGRA_CSI_PHY_CILB_CONTROL0 0x870
198 #define TEGRA_CSI_CSI_PIXEL_PARSER_STATUS 0x878
199 #define TEGRA_CSI_CSI_CIL_STATUS 0x87c
200 #define TEGRA_CSI_CSI_PIXEL_PARSER_INTERRUPT_MASK 0x880
201 #define TEGRA_CSI_CSI_CIL_INTERRUPT_MASK 0x884
202 #define TEGRA_CSI_CSI_READONLY_STATUS 0x888
203 #define TEGRA_CSI_ESCAPE_MODE_COMMAND 0x88c
204 #define TEGRA_CSI_ESCAPE_MODE_DATA 0x890
205 #define TEGRA_CSI_CILA_PAD_CONFIG0 0x894
206 #define TEGRA_CSI_CILA_PAD_CONFIG1 0x898
207 #define TEGRA_CSI_CILB_PAD_CONFIG0 0x89c
208 #define TEGRA_CSI_CILB_PAD_CONFIG1 0x8a0
209 #define TEGRA_CSI_CIL_PAD_CONFIG 0x8a4
210 #define TEGRA_CSI_CILA_MIPI_CAL_CONFIG 0x8a8
211 #define TEGRA_CSI_CILB_MIPI_CAL_CONFIG 0x8ac
212 #define TEGRA_CSI_CIL_MIPI_CAL_STATUS 0x8b0
213 #define TEGRA_CSI_CLKEN_OVERRIDE 0x8b4
214 #define TEGRA_CSI_DEBUG_CONTROL 0x8b8
215 #define TEGRA_CSI_DEBUG_COUNTER 0x8bc
216 #define TEGRA_CSI_DEBUG_COUNTER_1 0x8c0
217 #define TEGRA_CSI_DEBUG_COUNTER_2 0x8c4
218 #define TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME 0x8c8
219 #define TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME 0x8cc
220 #define TEGRA_CSI_DSI_MIPI_CAL_CONFIG 0x8d0
222 /* Test Pattern Generator of CSI */
223 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL_A 0x940
224 #define TEGRA_CSI_PG_BLANK_A 0x944
225 #define TEGRA_CSI_PG_PHASE_A 0x948
226 #define TEGRA_CSI_PG_RED_FREQ_A 0x94c
227 #define TEGRA_CSI_PG_RED_FREQ_RATE_A 0x950
228 #define TEGRA_CSI_PG_GREEN_FREQ_A 0x954
229 #define TEGRA_CSI_PG_GREEN_FREQ_RATE_A 0x958
230 #define TEGRA_CSI_PG_BLUE_FREQ_A 0x95c
231 #define TEGRA_CSI_PG_BLUE_FREQ_RATE_A 0x960
232 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL_B 0x974
233 #define TEGRA_CSI_PG_BLANK_B 0x978
234 #define TEGRA_CSI_PG_PHASE_B 0x97c
235 #define TEGRA_CSI_PG_RED_FREQ_B 0x980
236 #define TEGRA_CSI_PG_RED_FREQ_RATE_B 0x984
237 #define TEGRA_CSI_PG_GREEN_FREQ_B 0x988
238 #define TEGRA_CSI_PG_GREEN_FREQ_RATE_B 0x98c
239 #define TEGRA_CSI_PG_BLUE_FREQ_B 0x990
240 #define TEGRA_CSI_PG_BLUE_FREQ_RATE_B 0x994
242 static int vi_port_is_valid(int port)
244 return (((port) >= TEGRA_CAMERA_PORT_CSI_A) &&
245 ((port) <= TEGRA_CAMERA_PORT_VIP));
248 static int vi_port_is_csi(int port)
250 return (((port) == TEGRA_CAMERA_PORT_CSI_A) ||
251 ((port) == TEGRA_CAMERA_PORT_CSI_B));
254 /* Clock settings for camera */
255 static struct tegra_camera_clk vi_clks[] = {
284 #ifdef TEGRA_11X_OR_HIGHER_CONFIG
297 /* Always put "p11_d2" at the end */
305 static int vi_clks_init(struct tegra_camera_dev *cam, int port)
307 struct platform_device *pdev = cam->ndev;
308 struct tegra_camera_clk *clks;
311 cam->num_clks = ARRAY_SIZE(vi_clks);
314 for (i = 0; i < cam->num_clks; i++) {
315 clks = &cam->clks[i];
316 clks->clk = devm_clk_get(&pdev->dev, clks->name);
317 if (IS_ERR_OR_NULL(clks->clk)) {
319 dev_err(&pdev->dev, "Failed to get clock %s.\n",
321 return PTR_ERR(clks->clk);
325 clk_set_rate(clks->clk, clks->freq);
331 static void vi_clks_deinit(struct tegra_camera_dev *cam)
333 /* We don't need cleanup for devm_clk_get() */
337 static void vi_clks_enable(struct tegra_camera_dev *cam)
339 struct tegra_camera_clk *clks;
342 for (i = 0; i < cam->num_clks - 1; i++) {
343 clks = &cam->clks[i];
345 clk_prepare_enable(clks->clk);
348 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
349 #define TEGRA_APB_MISC_BASE 0x70000000
352 void __iomem *apb_misc = IO_ADDRESS(TEGRA_APB_MISC_BASE);
354 val = readl(apb_misc + 0x42c);
355 writel(val | 0x1, apb_misc + 0x42c);
360 clks = &cam->clks[i];
362 clk_prepare_enable(clks->clk);
363 #ifdef TEGRA_11X_OR_HIGHER_CONFIG
364 tegra_clk_cfg_ex(clks->clk,
365 TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
366 tegra_clk_cfg_ex(clks->clk,
367 TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
370 * bit 25: 0 = pd2vi_Clk,
372 * bit 24: 0 = internal clock,
373 * 1 = external clock (pd2vi_clk)
375 tegra_clk_cfg_ex(clks->clk, TEGRA_CLK_VI_INP_SEL, 2);
381 static void vi_clks_disable(struct tegra_camera_dev *cam)
383 struct tegra_camera_clk *clks;
386 for (i = 0; i < cam->num_clks - 1; i++) {
387 clks = &cam->clks[i];
389 clk_disable_unprepare(clks->clk);
393 clks = &cam->clks[i];
395 #ifdef TEGRA_11X_OR_HIGHER_CONFIG
396 tegra_clk_cfg_ex(clks->clk,
397 TEGRA_CLK_PLLD_CSI_OUT_ENB, 0);
398 tegra_clk_cfg_ex(clks->clk,
399 TEGRA_CLK_PLLD_DSI_OUT_ENB, 0);
401 clk_disable_unprepare(clks->clk);
406 static void vi_init_syncpts(struct tegra_camera_dev *cam)
408 cam->syncpt_id_csi_a = nvhost_get_syncpt_client_managed("vi_csi_A");
410 cam->syncpt_id_csi_b = nvhost_get_syncpt_client_managed("vi_csi_B");
412 cam->syncpt_id_vip = nvhost_get_syncpt_client_managed("vi_vip");
415 static void vi_free_syncpts(struct tegra_camera_dev *cam)
417 nvhost_free_syncpt(cam->syncpt_id_csi_a);
419 nvhost_free_syncpt(cam->syncpt_id_csi_b);
421 nvhost_free_syncpt(cam->syncpt_id_vip);
424 static void vi_save_syncpts(struct tegra_camera_dev *cam)
428 if (!nvhost_syncpt_read_ext_check(cam->ndev,
429 cam->syncpt_id_csi_a, &val))
430 cam->syncpt_csi_a = val;
432 if (!nvhost_syncpt_read_ext_check(cam->ndev,
433 cam->syncpt_id_csi_b, &val))
434 cam->syncpt_csi_b = val;
436 if (!nvhost_syncpt_read_ext_check(cam->ndev,
437 cam->syncpt_id_vip, &val))
438 cam->syncpt_vip = val;
441 static void vi_incr_syncpts(struct tegra_camera_dev *cam)
443 nvhost_syncpt_cpu_incr_ext(cam->ndev, cam->syncpt_id_csi_a);
445 nvhost_syncpt_cpu_incr_ext(cam->ndev, cam->syncpt_id_csi_b);
447 nvhost_syncpt_cpu_incr_ext(cam->ndev, cam->syncpt_id_vip);
450 static void vi_capture_clean(struct tegra_camera_dev *cam)
452 TC_VI_REG_WT(cam, TEGRA_CSI_VI_INPUT_STREAM_CONTROL, 0x00000000);
453 TC_VI_REG_WT(cam, TEGRA_CSI_HOST_INPUT_STREAM_CONTROL, 0x00000000);
455 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_STATUS, 0x0);
456 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_STATUS, 0x0);
457 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_INTERRUPT_MASK, 0x0);
458 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_INTERRUPT_MASK, 0x0);
459 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_READONLY_STATUS, 0x0);
460 TC_VI_REG_WT(cam, TEGRA_CSI_ESCAPE_MODE_COMMAND, 0x0);
461 TC_VI_REG_WT(cam, TEGRA_CSI_ESCAPE_MODE_DATA, 0x0);
463 TC_VI_REG_WT(cam, TEGRA_CSI_CIL_PAD_CONFIG, 0x00000000);
464 TC_VI_REG_WT(cam, TEGRA_CSI_CIL_MIPI_CAL_STATUS, 0x00000000);
465 TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x00000000);
467 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL, 0x0);
468 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_COUNTER, 0x0);
469 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_COUNTER_1, 0x0);
470 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_COUNTER_2, 0x0);
473 static void vi_capture_setup_csi_a(struct tegra_camera_dev *cam,
474 struct soc_camera_device *icd,
477 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
478 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
479 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
480 icd->current_fmt->host_fmt);
482 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL, 0x00000000);
483 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0, 0x00000000);
484 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL1, 0x00000000);
485 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_WORD_COUNT, 0x00000000);
486 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_GAP, 0x00000000);
487 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0x00000000);
488 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x00000000);
489 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x00000000);
490 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG1, 0x00000000);
491 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_MIPI_CAL_CONFIG, 0x00000000);
492 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME, 0x0);
494 TC_VI_REG_WT(cam, TEGRA_VI_VI_CORE_CONTROL, 0x02000000);
496 /* CSI-A H_ACTIVE and V_ACTIVE */
497 TC_VI_REG_WT(cam, TEGRA_VI_CSI_PPA_H_ACTIVE,
498 (icd->user_width << 16));
499 TC_VI_REG_WT(cam, TEGRA_VI_CSI_PPA_V_ACTIVE,
500 (icd->user_height << 16));
502 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL1,
503 0x1); /* Frame # for top field detect for interlaced */
505 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_WORD_COUNT,
507 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_GAP, 0x00140000);
509 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME,
510 ((icd->user_height + cam->tpg_mode) << 16));
512 /* pad 0s enabled, virtual channel ID 00 */
513 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0,
514 (0x1 << 16) | /* Output 1 pixel per clock */
515 (hdr << 8) | /* If hdr shows wrong fmt, use right value */
516 (0x1 << 7) | /* Check header CRC */
517 (0x1 << 6) | /* Use word count field in the header */
518 (0x1 << 5) | /* Look at data identifier byte in hdr */
519 (0x1 << 4)); /* Expect packet header */
521 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
522 (0x3f << 16) | /* Skip packet threshold */
525 /* Use 0x00000022 for continuous clock mode. */
526 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0,
527 (pdata->continuous_clk << 5) |
528 0x5); /* Clock settle time */
530 TC_VI_REG_WT(cam, TEGRA_VI_CONT_SYNCPT_CSI_PPA_FRAME_END,
531 (0x1 << 8) | /* Enable continuous syncpt */
532 cam->syncpt_id_csi_a);
534 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x00020001);
536 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0x0000f002);
539 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
540 ((cam->tpg_mode - 1) << 2) | 0x1);
541 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
542 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x00800080);
543 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
544 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x00800080);
545 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
546 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x00800080);
547 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
548 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLANK_A, 0x0000FFFF);
553 static void vi_capture_setup_csi_b(struct tegra_camera_dev *cam,
554 struct soc_camera_device *icd,
557 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
558 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
559 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
560 icd->current_fmt->host_fmt);
562 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL, 0x00000000);
563 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x00000000);
564 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x00000000);
565 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_WORD_COUNT, 0x00000000);
566 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x00000000);
567 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0x00000000);
568 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x00000000);
569 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x00000000);
570 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG1, 0x00000000);
571 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_MIPI_CAL_CONFIG, 0x00000000);
572 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME, 0x0);
574 TC_VI_REG_WT(cam, TEGRA_VI_VI_CORE_CONTROL, 0x04000000);
576 /* CSI-B H_ACTIVE and V_ACTIVE */
577 TC_VI_REG_WT(cam, TEGRA_VI_CSI_PPB_H_ACTIVE,
578 (icd->user_width << 16));
579 TC_VI_REG_WT(cam, TEGRA_VI_CSI_PPB_V_ACTIVE,
580 (icd->user_height << 16));
582 /* pad 0s enabled, virtual channel ID 00 */
583 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0,
584 (0x1 << 16) | /* Output 1 pixel per clock */
585 (hdr << 8) | /* If hdr shows wrong fmt, use right value */
586 (0x1 << 7) | /* Check header CRC */
587 (0x1 << 6) | /* Use word count field in the header */
588 (0x1 << 5) | /* Look at data identifier byte in hdr */
589 (0x1 << 4) | /* Expect packet header */
590 0x1); /* Set PPB stream source to CSI B */
592 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1,
593 0x1); /* Frame # for top field detect for interlaced */
595 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_WORD_COUNT,
597 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x00140000);
599 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME,
600 (icd->user_height << 16) |
601 (0x100 << 4) | /* Wait 0x100 vi clks for timeout */
602 0x1); /* Enable line timeout */
604 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
605 (0x3f << 16) | /* Skip packet threshold */
608 /* Use 0x00000022 for continuous clock mode. */
609 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0,
610 (pdata->continuous_clk << 5) |
611 0x5); /* Clock settle time */
613 TC_VI_REG_WT(cam, TEGRA_VI_CONT_SYNCPT_CSI_PPB_FRAME_END,
614 (0x1 << 8) | /* Enable continuous syncpt */
615 cam->syncpt_id_csi_b);
617 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x00010002);
619 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0x0000f002);
622 static void vi_capture_setup_vip(struct tegra_camera_dev *cam,
623 struct soc_camera_device *icd,
626 TC_VI_REG_WT(cam, TEGRA_VI_VI_CORE_CONTROL, 0x00000000);
628 TC_VI_REG_WT(cam, TEGRA_VI_VI_INPUT_CONTROL,
629 (1 << 27) | /* field detect */
630 (1 << 25) | /* hsync/vsync decoded from data (BT.656) */
631 (1 << 1) | /* VIP_INPUT_ENABLE */
634 TC_VI_REG_WT(cam, TEGRA_VI_H_DOWNSCALE_CONTROL, 0x00000000);
635 TC_VI_REG_WT(cam, TEGRA_VI_V_DOWNSCALE_CONTROL, 0x00000000);
637 /* VIP H_ACTIVE and V_ACTIVE */
638 TC_VI_REG_WT(cam, TEGRA_VI_VIP_H_ACTIVE,
639 (icd->user_width << 16) |
640 TEGRA_VIP_H_ACTIVE_START);
641 TC_VI_REG_WT(cam, TEGRA_VI_VIP_V_ACTIVE,
642 (icd->user_height << 16) |
643 TEGRA_VIP_V_ACTIVE_START);
646 * For VIP, D9..D2 is mapped to the video decoder's P7..P0.
647 * Disable/mask out the other Dn wires.
649 TC_VI_REG_WT(cam, TEGRA_VI_PIN_INPUT_ENABLE, 0x000003fc);
650 TC_VI_REG_WT(cam, TEGRA_VI_VI_DATA_INPUT_CONTROL, 0x000003fc);
651 TC_VI_REG_WT(cam, TEGRA_VI_PIN_INVERSION, 0x00000000);
653 TC_VI_REG_WT(cam, TEGRA_VI_CONT_SYNCPT_VIP_VSYNC,
654 (0x1 << 8) | /* Enable continuous syncpt */
657 TC_VI_REG_WT(cam, TEGRA_VI_CAMERA_CONTROL, 0x00000004);
660 static int vi_capture_output_channel_setup(
661 struct tegra_camera_dev *cam,
662 struct soc_camera_device *icd)
664 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
665 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
666 int port = pdata->port;
667 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
668 icd->current_fmt->host_fmt);
669 const struct soc_camera_format_xlate *current_fmt = icd->current_fmt;
670 u32 output_fourcc = current_fmt->host_fmt->fourcc;
671 u32 output_format, output_control;
672 struct tegra_camera_buffer *buf = to_tegra_vb(cam->active);
674 switch (output_fourcc) {
675 case V4L2_PIX_FMT_UYVY:
676 output_format = 0x3; /* Default to YUV422 */
678 case V4L2_PIX_FMT_VYUY:
679 output_format = (0x1 << 17) | 0x3;
681 case V4L2_PIX_FMT_YUYV:
682 output_format = (0x2 << 17) | 0x3;
684 case V4L2_PIX_FMT_YVYU:
685 output_format = (0x3 << 17) | 0x3;
687 case V4L2_PIX_FMT_YUV420:
688 case V4L2_PIX_FMT_YVU420:
689 output_format = 0x6; /* YUV420 planar */
691 case V4L2_PIX_FMT_SBGGR8:
692 case V4L2_PIX_FMT_SGBRG8:
693 case V4L2_PIX_FMT_SBGGR10:
694 /* Use second output channel for RAW8/RAW10 */
695 buf->output_channel = 1;
697 if (port == TEGRA_CAMERA_PORT_CSI_A)
699 else if (port == TEGRA_CAMERA_PORT_CSI_B)
705 dev_err(&cam->ndev->dev, "Wrong output format %d\n",
710 output_control = (pdata->flip_v ? (0x1 << 20) : 0) |
711 (pdata->flip_h ? (0x1 << 19) : 0) |
714 if (buf->output_channel == 0) {
715 TC_VI_REG_WT(cam, TEGRA_VI_VI_FIRST_OUTPUT_CONTROL,
718 * Set up frame size. Bits 31:16 are the number of lines, and
719 * bits 15:0 are the number of pixels per line.
721 TC_VI_REG_WT(cam, TEGRA_VI_FIRST_OUTPUT_FRAME_SIZE,
722 (icd->user_height << 16) | icd->user_width);
724 /* First output memory enabled */
725 TC_VI_REG_WT(cam, TEGRA_VI_VI_ENABLE, 0x00000000);
727 /* Set the number of frames in the buffer. */
728 TC_VI_REG_WT(cam, TEGRA_VI_VB0_COUNT_FIRST, 0x00000001);
730 /* Set up buffer frame size. */
731 TC_VI_REG_WT(cam, TEGRA_VI_VB0_SIZE_FIRST,
732 (icd->user_height << 16) | icd->user_width);
734 TC_VI_REG_WT(cam, TEGRA_VI_VB0_BUFFER_STRIDE_FIRST,
735 (icd->user_height * bytes_per_line));
737 TC_VI_REG_WT(cam, TEGRA_VI_CONT_SYNCPT_OUT_1,
738 (0x1 << 8) | /* Enable continuous syncpt */
741 TC_VI_REG_WT(cam, TEGRA_VI_VI_ENABLE, 0x00000000);
742 } else if (buf->output_channel == 1) {
743 TC_VI_REG_WT(cam, TEGRA_VI_VI_SECOND_OUTPUT_CONTROL,
746 TC_VI_REG_WT(cam, TEGRA_VI_SECOND_OUTPUT_FRAME_SIZE,
747 (icd->user_height << 16) | icd->user_width);
749 TC_VI_REG_WT(cam, TEGRA_VI_VI_ENABLE_2, 0x00000000);
751 /* Set the number of frames in the buffer. */
752 TC_VI_REG_WT(cam, TEGRA_VI_VB0_COUNT_SECOND, 0x00000001);
754 /* Set up buffer frame size. */
755 TC_VI_REG_WT(cam, TEGRA_VI_VB0_SIZE_SECOND,
756 (icd->user_height << 16) | icd->user_width);
758 TC_VI_REG_WT(cam, TEGRA_VI_VB0_BUFFER_STRIDE_SECOND,
759 (icd->user_height * bytes_per_line));
761 TC_VI_REG_WT(cam, TEGRA_VI_CONT_SYNCPT_OUT_2,
762 (0x1 << 8) | /* Enable continuous syncpt */
765 TC_VI_REG_WT(cam, TEGRA_VI_VI_ENABLE_2, 0x00000000);
767 dev_err(&cam->ndev->dev, "Wrong output channel %d\n",
768 buf->output_channel);
776 static int vi_capture_setup(struct tegra_camera_dev *cam,
777 struct tegra_camera_buffer *buf)
779 struct soc_camera_device *icd = buf->icd;
780 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
781 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
782 int port = pdata->port;
783 const struct soc_camera_format_xlate *current_fmt = icd->current_fmt;
784 enum v4l2_mbus_pixelcode input_code = current_fmt->code;
785 u32 hdr, input_control = 0x0;
787 switch (input_code) {
788 case V4L2_MBUS_FMT_UYVY8_2X8:
789 input_control |= 0x2 << 8;
792 case V4L2_MBUS_FMT_VYUY8_2X8:
793 input_control |= 0x3 << 8;
796 case V4L2_MBUS_FMT_YUYV8_2X8:
797 input_control |= 0x0;
800 case V4L2_MBUS_FMT_YVYU8_2X8:
801 input_control |= 0x1 << 8;
804 case V4L2_MBUS_FMT_SBGGR8_1X8:
805 case V4L2_MBUS_FMT_SGBRG8_1X8:
806 input_control |= 0x2 << 2; /* Input Format = Bayer */
809 case V4L2_MBUS_FMT_SBGGR10_1X10:
810 input_control |= 0x2 << 2; /* Input Format = Bayer */
814 dev_err(&cam->ndev->dev, "Input format %d is not supported\n",
820 * Set up low pass filter. Use 0x240 for chromaticity and 0x240
821 * for luminance, which is the default and means not to touch
824 TC_VI_REG_WT(cam, TEGRA_VI_H_LPF_CONTROL, 0x02400240);
826 /* Set up raise-on-edge, so we get an interrupt on end of frame. */
827 TC_VI_REG_WT(cam, TEGRA_VI_VI_RAISE, 0x00000001);
829 /* Setup registers for CSI-A, CSI-B and VIP inputs */
830 if (port == TEGRA_CAMERA_PORT_CSI_A)
831 vi_capture_setup_csi_a(cam, icd, hdr);
832 else if (port == TEGRA_CAMERA_PORT_CSI_B)
833 vi_capture_setup_csi_b(cam, icd, hdr);
835 vi_capture_setup_vip(cam, icd, input_control);
837 /* Setup registers for output channels */
838 return vi_capture_output_channel_setup(cam, icd);
841 static int vi_capture_buffer_setup(struct tegra_camera_dev *cam,
842 struct tegra_camera_buffer *buf)
844 struct soc_camera_device *icd = buf->icd;
846 switch (icd->current_fmt->host_fmt->fourcc) {
847 case V4L2_PIX_FMT_YUV420:
848 case V4L2_PIX_FMT_YVU420:
849 TC_VI_REG_WT(cam, TEGRA_VI_VB0_BASE_ADDRESS_U,
851 TC_VI_REG_WT(cam, TEGRA_VI_VB0_START_ADDRESS_U,
854 TC_VI_REG_WT(cam, TEGRA_VI_VB0_BASE_ADDRESS_V,
856 TC_VI_REG_WT(cam, TEGRA_VI_VB0_START_ADDRESS_V,
859 case V4L2_PIX_FMT_UYVY:
860 case V4L2_PIX_FMT_VYUY:
861 case V4L2_PIX_FMT_YUYV:
862 case V4L2_PIX_FMT_YVYU:
863 case V4L2_PIX_FMT_SBGGR8:
864 case V4L2_PIX_FMT_SGBRG8:
865 case V4L2_PIX_FMT_SBGGR10:
866 case V4L2_PIX_FMT_RGB32:
868 if (buf->output_channel == 0) {
869 TC_VI_REG_WT(cam, TEGRA_VI_VB0_BASE_ADDRESS_FIRST,
871 TC_VI_REG_WT(cam, TEGRA_VI_VB0_START_ADDRESS_FIRST,
874 } else if (buf->output_channel == 1) {
875 TC_VI_REG_WT(cam, TEGRA_VI_VB0_BASE_ADDRESS_SECOND,
877 TC_VI_REG_WT(cam, TEGRA_VI_VB0_START_ADDRESS_SECOND,
880 dev_err(&cam->ndev->dev, "Wrong output channel %d\n",
881 buf->output_channel);
887 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
888 icd->current_fmt->host_fmt->fourcc);
895 static int vi_capture_start(struct tegra_camera_dev *cam,
896 struct tegra_camera_buffer *buf)
898 struct soc_camera_device *icd = buf->icd;
899 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
900 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
901 int port = pdata->port;
904 err = vi_capture_buffer_setup(cam, buf);
908 * Only wait on CSI frame end syncpt if we're using CSI. Otherwise,
909 * wait on VIP VSYNC syncpt.
911 if (port == TEGRA_CAMERA_PORT_CSI_A) {
913 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
915 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
916 cam->syncpt_id_csi_a,
918 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
921 } else if (port == TEGRA_CAMERA_PORT_CSI_B) {
923 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
925 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
926 cam->syncpt_id_csi_b,
928 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
933 TC_VI_REG_WT(cam, TEGRA_VI_CAMERA_CONTROL,
935 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
938 TEGRA_SYNCPT_VI_WAIT_TIMEOUT,
946 if (vi_port_is_csi(port)) {
951 dev_warn(&icd->vdev->dev, "Timeout on CSI syncpt\n");
952 dev_warn(&icd->vdev->dev, "buffer_addr = 0x%08x\n",
955 ppstatus = TC_VI_REG_RD(cam,
956 TEGRA_CSI_CSI_PIXEL_PARSER_STATUS);
957 cilstatus = TC_VI_REG_RD(cam,
958 TEGRA_CSI_CSI_CIL_STATUS);
959 rostatus = TC_VI_REG_RD(cam,
960 TEGRA_CSI_CSI_READONLY_STATUS);
962 dev_warn(&icd->vdev->dev,
963 "PPSTATUS = 0x%08x, "
964 "CILSTATUS = 0x%08x, "
965 "ROSTATUS = 0x%08x\n",
966 ppstatus, cilstatus, rostatus);
968 u32 vip_input_status;
970 dev_warn(&cam->ndev->dev, "Timeout on VI syncpt\n");
971 dev_warn(&cam->ndev->dev, "buffer_addr = 0x%08x\n",
974 vip_input_status = TC_VI_REG_RD(cam,
975 TEGRA_VI_VIP_INPUT_STATUS);
977 dev_warn(&cam->ndev->dev,
978 "VIP_INPUT_STATUS = 0x%08x\n",
985 static int vi_capture_stop(struct tegra_camera_dev *cam, int port)
989 if (vi_port_is_csi(port))
990 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
993 TEGRA_SYNCPT_VI_WAIT_TIMEOUT,
1002 dev_warn(&cam->ndev->dev, "Timeout on VI syncpt\n");
1004 buffer_addr = TC_VI_REG_RD(cam,
1005 TEGRA_VI_VB0_BASE_ADDRESS_FIRST);
1006 dev_warn(&cam->ndev->dev, "buffer_addr = 0x%08x\n",
1009 ppstatus = TC_VI_REG_RD(cam,
1010 TEGRA_CSI_CSI_PIXEL_PARSER_STATUS);
1011 cilstatus = TC_VI_REG_RD(cam,
1012 TEGRA_CSI_CSI_CIL_STATUS);
1013 dev_warn(&cam->ndev->dev,
1014 "PPSTATUS = 0x%08x, CILSTATUS = 0x%08x\n",
1015 ppstatus, cilstatus);
1021 static void vi_unpowergate(struct tegra_camera_dev *cam)
1024 * Powergating DIS must powergate VE partition. Camera
1025 * module needs to increase the ref-count of disa to
1026 * avoid itself powergated by DIS inadvertently.
1028 #if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
1029 tegra_unpowergate_partition(TEGRA_POWERGATE_DISA);
1033 static void vi_powergate(struct tegra_camera_dev *cam)
1035 #if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
1036 tegra_powergate_partition(TEGRA_POWERGATE_DISA);
1040 struct tegra_camera_ops vi_ops = {
1041 .clks_init = vi_clks_init,
1042 .clks_deinit = vi_clks_deinit,
1043 .clks_enable = vi_clks_enable,
1044 .clks_disable = vi_clks_disable,
1046 .capture_clean = vi_capture_clean,
1047 .capture_setup = vi_capture_setup,
1048 .capture_start = vi_capture_start,
1049 .capture_stop = vi_capture_stop,
1051 .activate = vi_unpowergate,
1052 .deactivate = vi_powergate,
1054 .init_syncpts = vi_init_syncpts,
1055 .free_syncpts = vi_free_syncpts,
1056 .save_syncpts = vi_save_syncpts,
1057 .incr_syncpts = vi_incr_syncpts,
1059 .port_is_valid = vi_port_is_valid,
1062 int vi_register(struct tegra_camera_dev *cam)
1064 /* Init regulator */
1065 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
1066 cam->regulator_name = "vcsi";
1068 cam->regulator_name = "avdd_dsi_csi";
1071 /* Init VI/CSI ops */