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_CSI_WAIT_TIMEOUT 200
32 #define TEGRA_VI_CFG_VI_INCR_SYNCPT 0x000
33 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL 0x004
34 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR 0x008
35 #define TEGRA_VI_CFG_CTXSW 0x020
36 #define TEGRA_VI_CFG_INTSTATUS 0x024
37 #define TEGRA_VI_CFG_PWM_CONTROL 0x038
38 #define TEGRA_VI_CFG_PWM_HIGH_PULSE 0x03c
39 #define TEGRA_VI_CFG_PWM_LOW_PULSE 0x040
40 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_A 0x044
41 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_B 0x048
42 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_C 0x04c
43 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_D 0x050
44 #define TEGRA_VI_CFG_VGP1 0x064
45 #define TEGRA_VI_CFG_VGP2 0x068
46 #define TEGRA_VI_CFG_VGP3 0x06c
47 #define TEGRA_VI_CFG_VGP4 0x070
48 #define TEGRA_VI_CFG_VGP5 0x074
49 #define TEGRA_VI_CFG_VGP6 0x078
50 #define TEGRA_VI_CFG_INTERRUPT_MASK 0x08c
51 #define TEGRA_VI_CFG_INTERRUPT_TYPE_SELECT 0x090
52 #define TEGRA_VI_CFG_INTERRUPT_POLARITY_SELECT 0x094
53 #define TEGRA_VI_CFG_INTERRUPT_STATUS 0x098
54 #define TEGRA_VI_CFG_VGP_SYNCPT_CONFIG 0x0ac
55 #define TEGRA_VI_CFG_VI_SW_RESET 0x0b4
56 #define TEGRA_VI_CFG_CG_CTRL 0x0b8
57 #define TEGRA_VI_CFG_VI_MCCIF_FIFOCTRL 0x0e4
58 #define TEGRA_VI_CFG_TIMEOUT_WCOAL_VI 0x0e8
59 #define TEGRA_VI_CFG_DVFS 0x0f0
60 #define TEGRA_VI_CFG_RESERVE 0x0f4
61 #define TEGRA_VI_CFG_RESERVE_1 0x0f8
63 #define TEGRA_VI_CSI_0_SW_RESET 0x100
64 #define TEGRA_VI_CSI_0_SINGLE_SHOT 0x104
65 #define TEGRA_VI_CSI_0_SINGLE_SHOT_STATE_UPDATE 0x108
66 #define TEGRA_VI_CSI_0_IMAGE_DEF 0x10c
67 #define TEGRA_VI_CSI_0_RGB2Y_CTRL 0x110
68 #define TEGRA_VI_CSI_0_MEM_TILING 0x114
69 #define TEGRA_VI_CSI_0_CSI_IMAGE_SIZE 0x118
70 #define TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC 0x11c
71 #define TEGRA_VI_CSI_0_CSI_IMAGE_DT 0x120
72 #define TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB 0x124
73 #define TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB 0x128
74 #define TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB 0x12c
75 #define TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB 0x130
76 #define TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB 0x134
77 #define TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB 0x138
78 #define TEGRA_VI_CSI_0_SURFACE0_BF_OFFSET_MSB 0x13c
79 #define TEGRA_VI_CSI_0_SURFACE0_BF_OFFSET_LSB 0x140
80 #define TEGRA_VI_CSI_0_SURFACE1_BF_OFFSET_MSB 0x144
81 #define TEGRA_VI_CSI_0_SURFACE1_BF_OFFSET_LSB 0x148
82 #define TEGRA_VI_CSI_0_SURFACE2_BF_OFFSET_MSB 0x14c
83 #define TEGRA_VI_CSI_0_SURFACE2_BF_OFFSET_LSB 0x150
84 #define TEGRA_VI_CSI_0_SURFACE0_STRIDE 0x154
85 #define TEGRA_VI_CSI_0_SURFACE1_STRIDE 0x158
86 #define TEGRA_VI_CSI_0_SURFACE2_STRIDE 0x15c
87 #define TEGRA_VI_CSI_0_SURFACE_HEIGHT0 0x160
88 #define TEGRA_VI_CSI_0_ISPINTF_CONFIG 0x164
89 #define TEGRA_VI_CSI_0_ERROR_STATUS 0x184
90 #define TEGRA_VI_CSI_0_ERROR_INT_MASK 0x188
91 #define TEGRA_VI_CSI_0_WD_CTRL 0x18c
92 #define TEGRA_VI_CSI_0_WD_PERIOD 0x190
94 #define TEGRA_VI_CSI_1_SW_RESET 0x200
95 #define TEGRA_VI_CSI_1_SINGLE_SHOT 0x204
96 #define TEGRA_VI_CSI_1_SINGLE_SHOT_STATE_UPDATE 0x208
97 #define TEGRA_VI_CSI_1_IMAGE_DEF 0x20c
98 #define TEGRA_VI_CSI_1_RGB2Y_CTRL 0x210
99 #define TEGRA_VI_CSI_1_MEM_TILING 0x214
100 #define TEGRA_VI_CSI_1_CSI_IMAGE_SIZE 0x218
101 #define TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC 0x21c
102 #define TEGRA_VI_CSI_1_CSI_IMAGE_DT 0x220
103 #define TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB 0x224
104 #define TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB 0x228
105 #define TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB 0x22c
106 #define TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB 0x230
107 #define TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB 0x234
108 #define TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB 0x238
109 #define TEGRA_VI_CSI_1_SURFACE0_BF_OFFSET_MSB 0x23c
110 #define TEGRA_VI_CSI_1_SURFACE0_BF_OFFSET_LSB 0x240
111 #define TEGRA_VI_CSI_1_SURFACE1_BF_OFFSET_MSB 0x244
112 #define TEGRA_VI_CSI_1_SURFACE1_BF_OFFSET_LSB 0x248
113 #define TEGRA_VI_CSI_1_SURFACE2_BF_OFFSET_MSB 0x24c
114 #define TEGRA_VI_CSI_1_SURFACE2_BF_OFFSET_LSB 0x250
115 #define TEGRA_VI_CSI_1_SURFACE0_STRIDE 0x254
116 #define TEGRA_VI_CSI_1_SURFACE1_STRIDE 0x258
117 #define TEGRA_VI_CSI_1_SURFACE2_STRIDE 0x25c
118 #define TEGRA_VI_CSI_1_SURFACE_HEIGHT0 0x260
119 #define TEGRA_VI_CSI_1_ISPINTF_CONFIG 0x264
120 #define TEGRA_VI_CSI_1_ERROR_STATUS 0x284
121 #define TEGRA_VI_CSI_1_ERROR_INT_MASK 0x288
122 #define TEGRA_VI_CSI_1_WD_CTRL 0x28c
123 #define TEGRA_VI_CSI_1_WD_PERIOD 0x290
125 #define TEGRA_CSI_CSI_CAP_CIL 0x808
126 #define TEGRA_CSI_CSI_CAP_CSI 0x818
127 #define TEGRA_CSI_CSI_CAP_PP 0x828
128 #define TEGRA_CSI_INPUT_STREAM_A_CONTROL 0x838
129 #define TEGRA_CSI_PIXEL_STREAM_A_CONTROL0 0x83c
130 #define TEGRA_CSI_PIXEL_STREAM_A_CONTROL1 0x840
131 #define TEGRA_CSI_PIXEL_STREAM_A_GAP 0x844
132 #define TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND 0x848
133 #define TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME 0x84c
134 #define TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK 0x850
135 #define TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x854
136 #define TEGRA_CSI_CSI_SW_SENSOR_A_RESET 0x858
137 #define TEGRA_CSI_INPUT_STREAM_B_CONTROL 0x86c
138 #define TEGRA_CSI_PIXEL_STREAM_B_CONTROL0 0x870
139 #define TEGRA_CSI_PIXEL_STREAM_B_CONTROL1 0x874
140 #define TEGRA_CSI_PIXEL_STREAM_B_GAP 0x878
141 #define TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND 0x87c
142 #define TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME 0x880
143 #define TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK 0x884
144 #define TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x888
145 #define TEGRA_CSI_CSI_SW_SENSOR_B_RESET 0x88c
146 #define TEGRA_CSI_PHY_CIL_COMMAND 0x908
147 #define TEGRA_CSI_CIL_PAD_CONFIG0 0x90c
149 #define TEGRA_CSI_CILA_PAD_CONFIG0 0x92c
150 #define TEGRA_CSI_CILA_PAD_CONFIG1 0x930
151 #define TEGRA_CSI_PHY_CILA_CONTROL0 0x934
152 #define TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK 0x938
153 #define TEGRA_CSI_CSI_CIL_A_STATUS 0x93c
154 #define TEGRA_CSI_CSI_CILA_STATUS 0x940
155 #define TEGRA_CSI_CIL_A_ESCAPE_MODE_COMMAND 0x944
156 #define TEGRA_CSI_CIL_A_ESCAPE_MODE_DATA 0x948
157 #define TEGRA_CSI_CSICIL_SW_SENSOR_A_RESET 0x94c
159 #define TEGRA_CSI_CILB_PAD_CONFIG0 0x960
160 #define TEGRA_CSI_CILB_PAD_CONFIG1 0x964
161 #define TEGRA_CSI_PHY_CILB_CONTROL0 0x968
162 #define TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK 0x96c
163 #define TEGRA_CSI_CSI_CIL_B_STATUS 0x970
164 #define TEGRA_CSI_CSI_CILB_STATUS 0x974
165 #define TEGRA_CSI_CIL_B_ESCAPE_MODE_COMMAND 0x978
166 #define TEGRA_CSI_CIL_B_ESCAPE_MODE_DATA 0x97c
167 #define TEGRA_CSI_CSICIL_SW_SENSOR_B_RESET 0x980
169 #define TEGRA_CSI_CILC_PAD_CONFIG0 0x994
170 #define TEGRA_CSI_CILC_PAD_CONFIG1 0x998
171 #define TEGRA_CSI_PHY_CILC_CONTROL0 0x99c
172 #define TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK 0x9a0
173 #define TEGRA_CSI_CSI_CIL_C_STATUS 0x9a4
174 #define TEGRA_CSI_CSI_CILC_STATUS 0x9a8
175 #define TEGRA_CSI_CIL_C_ESCAPE_MODE_COMMAND 0x9ac
176 #define TEGRA_CSI_CIL_C_ESCAPE_MODE_DATA 0x9b0
177 #define TEGRA_CSI_CSICIL_SW_SENSOR_C_RESET 0x9b4
179 #define TEGRA_CSI_CILD_PAD_CONFIG0 0x9c8
180 #define TEGRA_CSI_CILD_PAD_CONFIG1 0x9cc
181 #define TEGRA_CSI_PHY_CILD_CONTROL0 0x9d0
182 #define TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK 0x9d4
183 #define TEGRA_CSI_CSI_CIL_D_STATUS 0x9d8
184 #define TEGRA_CSI_CSI_CILD_STATUS 0x9dc
185 #define TEGRA_CSI_CIL_D_ESCAPE_MODE_COMMAND 0x9ec
186 #define TEGRA_CSI_CIL_D_ESCAPE_MODE_DATA 0x9f0
187 #define TEGRA_CSI_CSICIL_SW_SENSOR_D_RESET 0x9f4
189 #define TEGRA_CSI_CILE_PAD_CONFIG0 0xa08
190 #define TEGRA_CSI_CILE_PAD_CONFIG1 0xa0c
191 #define TEGRA_CSI_PHY_CILE_CONTROL0 0xa10
192 #define TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK 0xa14
193 #define TEGRA_CSI_CSI_CIL_E_STATUS 0xa18
194 #define TEGRA_CSI_CIL_E_ESCAPE_MODE_COMMAND 0xa1c
195 #define TEGRA_CSI_CIL_E_ESCAPE_MODE_DATA 0xa20
196 #define TEGRA_CSI_CSICIL_SW_SENSOR_E_RESET 0xa24
198 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL_A 0xa68
199 #define TEGRA_CSI_PG_BLANK_A 0xa6c
200 #define TEGRA_CSI_PG_PHASE_A 0xa70
201 #define TEGRA_CSI_PG_RED_FREQ_A 0xa74
202 #define TEGRA_CSI_PG_RED_FREQ_RATE_A 0xa78
203 #define TEGRA_CSI_PG_GREEN_FREQ_A 0xa7c
204 #define TEGRA_CSI_PG_GREEN_FREQ_RATE_A 0xa80
205 #define TEGRA_CSI_PG_BLUE_FREQ_A 0xa84
206 #define TEGRA_CSI_PG_BLUE_FREQ_RATE_A 0xa88
208 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL_B 0xa9c
209 #define TEGRA_CSI_PG_BLANK_B 0xaa0
210 #define TEGRA_CSI_PG_PHASE_B 0xaa4
211 #define TEGRA_CSI_PG_RED_FREQ_B 0xaa8
212 #define TEGRA_CSI_PG_RED_FREQ_RATE_B 0xaac
213 #define TEGRA_CSI_PG_GREEN_FREQ_B 0xab0
214 #define TEGRA_CSI_PG_GREEN_FREQ_RATE_B 0xab4
215 #define TEGRA_CSI_PG_BLUE_FREQ_B 0xab8
216 #define TEGRA_CSI_PG_BLUE_FREQ_RATE_B 0xabc
218 #define TEGRA_CSI_DPCM_CTRL_A 0xad0
219 #define TEGRA_CSI_DPCM_CTRL_B 0xad4
220 #define TEGRA_CSI_STALL_COUNTER 0xae8
221 #define TEGRA_CSI_CSI_READONLY_STATUS 0xaec
222 #define TEGRA_CSI_CSI_SW_STATUS_RESET 0xaf0
223 #define TEGRA_CSI_CLKEN_OVERRIDE 0xaf4
224 #define TEGRA_CSI_DEBUG_CONTROL 0xaf8
225 #define TEGRA_CSI_DEBUG_COUNTER_0 0xafc
226 #define TEGRA_CSI_DEBUG_COUNTER_1 0xb00
227 #define TEGRA_CSI_DEBUG_COUNTER_2 0xb04
229 /* These go into the TEGRA_VI_CSI_n_IMAGE_DEF registers bits 23:16 */
230 #define TEGRA_IMAGE_FORMAT_T_L8 16
231 #define TEGRA_IMAGE_FORMAT_T_R16_I 32
232 #define TEGRA_IMAGE_FORMAT_T_B5G6R5 33
233 #define TEGRA_IMAGE_FORMAT_T_R5G6B5 34
234 #define TEGRA_IMAGE_FORMAT_T_A1B5G5R5 35
235 #define TEGRA_IMAGE_FORMAT_T_A1R5G5B5 36
236 #define TEGRA_IMAGE_FORMAT_T_B5G5R5A1 37
237 #define TEGRA_IMAGE_FORMAT_T_R5G5B5A1 38
238 #define TEGRA_IMAGE_FORMAT_T_A4B4G4R4 39
239 #define TEGRA_IMAGE_FORMAT_T_A4R4G4B4 40
240 #define TEGRA_IMAGE_FORMAT_T_B4G4R4A4 41
241 #define TEGRA_IMAGE_FORMAT_T_R4G4B4A4 42
242 #define TEGRA_IMAGE_FORMAT_T_A8B8G8R8 64
243 #define TEGRA_IMAGE_FORMAT_T_A8R8G8B8 65
244 #define TEGRA_IMAGE_FORMAT_T_B8G8R8A8 66
245 #define TEGRA_IMAGE_FORMAT_T_R8G8B8A8 67
246 #define TEGRA_IMAGE_FORMAT_T_A2B10G10R10 68
247 #define TEGRA_IMAGE_FORMAT_T_A2R10G10B10 69
248 #define TEGRA_IMAGE_FORMAT_T_B10G10R10A2 70
249 #define TEGRA_IMAGE_FORMAT_T_R10G10B10A2 71
250 #define TEGRA_IMAGE_FORMAT_T_A8Y8U8V8 193
251 #define TEGRA_IMAGE_FORMAT_T_V8U8Y8A8 194
252 #define TEGRA_IMAGE_FORMAT_T_A2Y10U10V10 197
253 #define TEGRA_IMAGE_FORMAT_T_V10U10Y10A2 198
254 #define TEGRA_IMAGE_FORMAT_T_Y8_U8__Y8_V8 200
255 #define TEGRA_IMAGE_FORMAT_T_Y8_V8__Y8_U8 201
256 #define TEGRA_IMAGE_FORMAT_T_U8_Y8__V8_Y8 202
257 #define TEGRA_IMAGE_FORMAT_T_T_V8_Y8__U8_Y8 203
258 #define TEGRA_IMAGE_FORMAT_T_T_Y8__U8__V8_N444 224
259 #define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N444 225
260 #define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N444 226
261 #define TEGRA_IMAGE_FORMAT_T_Y8__U8__V8_N422 227
262 #define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N422 228
263 #define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N422 229
264 #define TEGRA_IMAGE_FORMAT_T_Y8__U8__V8_N420 230
265 #define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N420 231
266 #define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N420 232
267 #define TEGRA_IMAGE_FORMAT_T_X2Lc10Lb10La10 233
268 #define TEGRA_IMAGE_FORMAT_T_A2R6R6R6R6R6 234
270 /* These go into the TEGRA_VI_CSI_n_CSI_IMAGE_DT registers bits 7:0 */
271 #define TEGRA_IMAGE_DT_YUV420_8 24
272 #define TEGRA_IMAGE_DT_YUV420_10 25
273 #define TEGRA_IMAGE_DT_YUV420CSPS_8 28
274 #define TEGRA_IMAGE_DT_YUV420CSPS_10 29
275 #define TEGRA_IMAGE_DT_YUV422_8 30
276 #define TEGRA_IMAGE_DT_YUV422_10 31
277 #define TEGRA_IMAGE_DT_RGB444 32
278 #define TEGRA_IMAGE_DT_RGB555 33
279 #define TEGRA_IMAGE_DT_RGB565 34
280 #define TEGRA_IMAGE_DT_RGB666 35
281 #define TEGRA_IMAGE_DT_RGB888 36
282 #define TEGRA_IMAGE_DT_RAW6 40
283 #define TEGRA_IMAGE_DT_RAW7 41
284 #define TEGRA_IMAGE_DT_RAW8 42
285 #define TEGRA_IMAGE_DT_RAW10 43
286 #define TEGRA_IMAGE_DT_RAW12 44
287 #define TEGRA_IMAGE_DT_RAW14 45
289 static int vi2_port_is_valid(int port)
291 return (((port) >= TEGRA_CAMERA_PORT_CSI_A) &&
292 ((port) <= TEGRA_CAMERA_PORT_CSI_C));
295 /* Clock settings for camera */
296 static struct tegra_camera_clk vi2_clks0[] = {
333 /* Always put "p11_d" at the end */
340 static struct tegra_camera_clk vi2_clks1[] = {
347 .name = "vi_sensor2",
377 /* Always put "p11_d" at the end */
384 #define MAX_DEVID_LENGTH 16
386 static int vi2_clks_init(struct tegra_camera_dev *cam, int port)
388 struct platform_device *pdev = cam->ndev;
389 struct tegra_camera_clk *clks;
393 case TEGRA_CAMERA_PORT_CSI_A:
394 cam->num_clks = ARRAY_SIZE(vi2_clks0);
395 cam->clks = vi2_clks0;
397 case TEGRA_CAMERA_PORT_CSI_B:
398 case TEGRA_CAMERA_PORT_CSI_C:
399 cam->num_clks = ARRAY_SIZE(vi2_clks1);
400 cam->clks = vi2_clks1;
403 dev_err(&pdev->dev, "Wrong port number %d\n", port);
407 for (i = 0; i < cam->num_clks; i++) {
408 clks = &cam->clks[i];
410 if (clks->use_devname) {
411 char devname[MAX_DEVID_LENGTH];
412 snprintf(devname, MAX_DEVID_LENGTH,
413 "tegra_%s", dev_name(&pdev->dev));
414 clks->clk = clk_get_sys(devname, clks->name);
416 clks->clk = clk_get(&pdev->dev, clks->name);
417 if (IS_ERR_OR_NULL(clks->clk)) {
418 dev_err(&pdev->dev, "Failed to get clock %s.\n",
420 return PTR_ERR(clks->clk);
427 static void vi2_clks_deinit(struct tegra_camera_dev *cam)
429 struct tegra_camera_clk *clks;
432 for (i = 0; i < cam->num_clks; i++) {
433 clks = &cam->clks[i];
439 static void vi2_clks_enable(struct tegra_camera_dev *cam)
441 struct tegra_camera_clk *clks;
444 for (i = 0; i < cam->num_clks - 1; i++) {
445 clks = &cam->clks[i];
447 clk_prepare_enable(clks->clk);
449 clk_set_rate(clks->clk, clks->freq);
453 clks = &cam->clks[i];
455 clk_prepare_enable(clks->clk);
457 clk_set_rate(clks->clk, clks->freq);
458 tegra_clk_cfg_ex(clks->clk,
459 TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
460 tegra_clk_cfg_ex(clks->clk,
461 TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
462 tegra_clk_cfg_ex(clks->clk,
463 TEGRA_CLK_MIPI_CSI_OUT_ENB, 0);
468 static void vi2_clks_disable(struct tegra_camera_dev *cam)
470 struct tegra_camera_clk *clks;
473 for (i = 0; i < cam->num_clks - 1; i++) {
474 clks = &cam->clks[i];
476 clk_disable_unprepare(clks->clk);
480 clks = &cam->clks[i];
482 tegra_clk_cfg_ex(clks->clk,
483 TEGRA_CLK_MIPI_CSI_OUT_ENB, 1);
484 tegra_clk_cfg_ex(clks->clk,
485 TEGRA_CLK_PLLD_CSI_OUT_ENB, 0);
486 tegra_clk_cfg_ex(clks->clk,
487 TEGRA_CLK_PLLD_DSI_OUT_ENB, 0);
488 clk_disable_unprepare(clks->clk);
493 static void vi2_init_syncpts(struct tegra_camera_dev *cam)
495 cam->syncpt_id_csi_a = nvhost_get_syncpt_client_managed("vi_csi_A");
497 cam->syncpt_id_csi_b = nvhost_get_syncpt_client_managed("vi_csi_B");
500 static void vi2_free_syncpts(struct tegra_camera_dev *cam)
502 nvhost_free_syncpt(cam->syncpt_id_csi_a);
504 nvhost_free_syncpt(cam->syncpt_id_csi_b);
507 static void vi2_incr_syncpts(struct tegra_camera_dev *cam)
511 if (!nvhost_syncpt_read_ext_check(cam->ndev,
512 cam->syncpt_id_csi_a, &val))
513 cam->syncpt_csi_a = nvhost_syncpt_incr_max_ext(cam->ndev,
514 cam->syncpt_id_csi_a, 1);
516 if (!nvhost_syncpt_read_ext_check(cam->ndev,
517 cam->syncpt_id_csi_b, &val))
518 cam->syncpt_csi_b = nvhost_syncpt_incr_max_ext(cam->ndev,
519 cam->syncpt_id_csi_b, 1);
522 static void vi2_capture_clean(struct tegra_camera_dev *cam)
524 /* Clean up status */
525 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_STATUS, 0xFFFFFFFF);
526 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_STATUS, 0xFFFFFFFF);
527 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_STATUS, 0xFFFFFFFF);
528 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_STATUS, 0xFFFFFFFF);
529 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_STATUS, 0xFFFFFFFF);
530 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILA_STATUS, 0xFFFFFFFF);
531 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILB_STATUS, 0xFFFFFFFF);
532 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILC_STATUS, 0xFFFFFFFF);
533 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILD_STATUS, 0xFFFFFFFF);
534 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS, 0xFFFFFFFF);
535 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS, 0xFFFFFFFF);
536 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_ERROR_STATUS, 0xFFFFFFFF);
537 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_ERROR_STATUS, 0xFFFFFFFF);
540 static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
541 struct soc_camera_device *icd)
543 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
544 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
545 int format = 0, data_type = 0, image_size = 0;
548 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
549 0x3 | (0x1 << 5) | (0x40 << 8));
552 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x9);
553 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x9);
554 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
555 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK, 0x0);
556 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0, 0x280301f0);
557 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
558 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL1, 0x11);
559 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_GAP, 0x140000);
561 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
562 0x3f0000 | (pdata->lanes - 1));
563 if (pdata->lanes == 4)
564 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020101);
566 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020201);
569 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
570 ((cam->tpg_mode - 1) << 2) | 0x1);
571 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
572 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x100010);
573 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
574 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x100010);
575 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
576 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x100010);
577 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
578 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
580 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
581 data_type = TEGRA_IMAGE_DT_RGB888;
582 image_size = icd->user_width * 3;
583 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
584 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
585 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
586 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
588 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
589 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
590 format = TEGRA_IMAGE_FORMAT_T_L8;
591 data_type = TEGRA_IMAGE_DT_RAW8;
592 image_size = icd->user_width;
593 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
594 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
595 format = TEGRA_IMAGE_FORMAT_T_R16_I;
596 data_type = TEGRA_IMAGE_DT_RAW10;
597 image_size = (icd->user_width * 10) >> 3;
600 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
601 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
603 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
605 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
607 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
608 (icd->user_height << 16) | icd->user_width);
613 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
614 struct soc_camera_device *icd)
616 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
617 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
618 int format = 0, data_type = 0, image_size = 0;
621 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
622 0x5 | (0x1 << 5) | (0x50 << 8));
625 if (pdata->port == TEGRA_CAMERA_PORT_CSI_B) {
626 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0x9);
627 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0x9);
628 } else if (pdata->port == TEGRA_CAMERA_PORT_CSI_C)
629 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0x9);
631 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
632 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
633 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
634 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
635 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x11);
636 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x140000);
638 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
639 0x3f0000 | (pdata->lanes - 1));
640 if (pdata->lanes == 4)
641 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x21010202);
642 else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_C)
643 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x12020202);
645 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
648 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
649 ((cam->tpg_mode - 1) << 2) | 0x1);
650 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_B, 0x0);
651 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_B, 0x100010);
652 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_B, 0x0);
653 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_B, 0x100010);
654 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_B, 0x0);
655 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_B, 0x100010);
656 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
657 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
659 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
660 data_type = TEGRA_IMAGE_DT_RGB888;
661 image_size = icd->user_width * 3;
662 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
663 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
664 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
665 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
667 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
668 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
669 format = TEGRA_IMAGE_FORMAT_T_L8;
670 data_type = TEGRA_IMAGE_DT_RAW8;
671 image_size = icd->user_width;
672 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
673 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
674 format = TEGRA_IMAGE_FORMAT_T_R16_I;
675 data_type = TEGRA_IMAGE_DT_RAW10;
676 image_size = icd->user_width * 10 / 8;
679 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
680 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
682 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
684 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
686 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
687 (icd->user_height << 16) | icd->user_width);
692 static int vi2_capture_setup(struct tegra_camera_dev *cam)
694 struct vb2_buffer *vb = cam->active;
695 struct tegra_camera_buffer *buf = to_tegra_vb(vb);
696 struct soc_camera_device *icd = buf->icd;
697 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
698 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
699 int port = pdata->port;
701 /* Skip VI2/CSI2 setup for second and later frame capture */
706 * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
707 * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
709 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
711 /* PAD_CILB_PDVCLAMP 0, PAD_CILB_PDIO_CLK 0, PAD_CILB_PDIO 0 */
712 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x0);
715 * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
716 * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
718 TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
720 /* PAD_CILD_PDVCLAMP 0, PAD_CILD_PDIO_CLK 0, PAD_CILD_PDIO 0 */
721 TC_VI_REG_WT(cam, TEGRA_CSI_CILD_PAD_CONFIG0, 0x0);
723 /* PAD_CILE_PDVCLAMP 0, PAD_CILE_PDIO_CLK 0, PAD_CILE_PDIO 0 */
724 TC_VI_REG_WT(cam, TEGRA_CSI_CILE_PAD_CONFIG0, 0x0);
726 /* Common programming set for any config */
727 TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x0);
728 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
729 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK, 0x0);
730 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK, 0x0);
731 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK, 0x0);
732 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
733 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
735 /* Setup registers for CSI-A and CSI-B inputs */
736 if (port == TEGRA_CAMERA_PORT_CSI_A)
737 return vi2_capture_setup_csi_0(cam, icd);
738 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
739 port == TEGRA_CAMERA_PORT_CSI_C)
740 return vi2_capture_setup_csi_1(cam, icd);
745 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
746 struct tegra_camera_buffer *buf)
748 struct soc_camera_device *icd = buf->icd;
749 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
750 icd->current_fmt->host_fmt);
751 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
752 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
753 int port = pdata->port;
755 switch (icd->current_fmt->host_fmt->fourcc) {
756 case V4L2_PIX_FMT_YUV420:
757 case V4L2_PIX_FMT_YVU420:
758 /* FIXME: Setup YUV buffer */
760 case V4L2_PIX_FMT_UYVY:
761 case V4L2_PIX_FMT_VYUY:
762 case V4L2_PIX_FMT_YUYV:
763 case V4L2_PIX_FMT_YVYU:
764 case V4L2_PIX_FMT_SBGGR8:
765 case V4L2_PIX_FMT_SGBRG8:
766 case V4L2_PIX_FMT_SBGGR10:
767 case V4L2_PIX_FMT_SRGGB10:
768 case V4L2_PIX_FMT_RGB32:
769 if (port == TEGRA_CAMERA_PORT_CSI_A) {
770 switch (buf->output_channel) {
773 TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
776 TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
779 TEGRA_VI_CSI_0_SURFACE0_STRIDE,
784 TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
787 TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
790 TEGRA_VI_CSI_0_SURFACE1_STRIDE,
795 TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
798 TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
801 TEGRA_VI_CSI_0_SURFACE2_STRIDE,
805 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
806 port == TEGRA_CAMERA_PORT_CSI_C) {
807 switch (buf->output_channel) {
810 TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
813 TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
816 TEGRA_VI_CSI_1_SURFACE0_STRIDE,
821 TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
824 TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
827 TEGRA_VI_CSI_1_SURFACE1_STRIDE,
832 TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
835 TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
838 TEGRA_VI_CSI_1_SURFACE2_STRIDE,
846 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
847 icd->current_fmt->host_fmt->fourcc);
854 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
859 val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
860 pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
862 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
863 pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
864 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
865 pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
866 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
867 pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
868 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
869 pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
870 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
871 pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
872 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
873 pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
874 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
875 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
876 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS);
877 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x%08x\n", val);
878 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
879 pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
880 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_1_ERROR_STATUS);
881 pr_err("TEGRA_VI_CSI_1_ERROR_STATUS 0x%08x\n", val);
884 static int vi2_capture_start(struct tegra_camera_dev *cam,
885 struct tegra_camera_buffer *buf)
887 struct soc_camera_device *icd = buf->icd;
888 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
889 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
890 int port = pdata->port;
893 err = vi2_capture_buffer_setup(cam, buf);
897 /* Only wait on CSI frame end syncpt if we're using CSI. */
898 if (port == TEGRA_CAMERA_PORT_CSI_A) {
899 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
900 (6 << 8) | cam->syncpt_id_csi_a);
901 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
903 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
904 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
905 cam->syncpt_id_csi_a,
907 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
910 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
911 port == TEGRA_CAMERA_PORT_CSI_C) {
912 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
913 (7 << 8) | cam->syncpt_id_csi_b);
914 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
916 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
917 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
918 cam->syncpt_id_csi_b,
920 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
925 /* Mark SOF flag to Zero after we captured the FIRST frame */
929 /* Capture syncpt timeout err, then dump error status */
931 if (port == TEGRA_CAMERA_PORT_CSI_A)
932 dev_err(&cam->ndev->dev,
933 "CSI_A syncpt timeout, syncpt = %d, err = %d\n",
934 cam->syncpt_csi_a, err);
935 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
936 port == TEGRA_CAMERA_PORT_CSI_C)
937 dev_err(&cam->ndev->dev,
938 "CSI_B/CSI_C syncpt timeout, syncpt = %d, err = %d\n",
939 cam->syncpt_csi_b, err);
940 vi2_capture_error_status(cam);
946 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
948 if (port == TEGRA_CAMERA_PORT_CSI_A)
949 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
951 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
952 port == TEGRA_CAMERA_PORT_CSI_C)
953 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
959 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving */
960 static void vi2_sw_reset(struct tegra_camera_dev *cam)
962 /* T12_CG_2ND_LEVEL_EN */
963 TC_VI_REG_WT(cam, TEGRA_VI_CFG_CG_CTRL, 1);
964 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SW_RESET, 0x1F);
965 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SW_RESET, 0x1F);
970 struct tegra_camera_ops vi2_ops = {
971 .clks_init = vi2_clks_init,
972 .clks_deinit = vi2_clks_deinit,
973 .clks_enable = vi2_clks_enable,
974 .clks_disable = vi2_clks_disable,
976 .capture_clean = vi2_capture_clean,
977 .capture_setup = vi2_capture_setup,
978 .capture_start = vi2_capture_start,
979 .capture_stop = vi2_capture_stop,
981 .activate = vi2_sw_reset,
983 .init_syncpts = vi2_init_syncpts,
984 .free_syncpts = vi2_free_syncpts,
985 .incr_syncpts = vi2_incr_syncpts,
987 .port_is_valid = vi2_port_is_valid,
990 int vi2_register(struct tegra_camera_dev *cam)
993 cam->regulator_name = "avdd_dsi_csi";
995 /* Init VI2/CSI2 ops */