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);
560 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME, 0x0);
562 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
563 0x3f0000 | (pdata->lanes - 1));
564 if (pdata->lanes == 4)
565 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020101);
567 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020201);
570 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
571 ((cam->tpg_mode - 1) << 2) | 0x1);
572 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
573 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x100010);
574 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
575 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x100010);
576 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
577 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x100010);
578 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
579 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
581 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
582 data_type = TEGRA_IMAGE_DT_RGB888;
583 image_size = icd->user_width * 3;
584 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
585 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
586 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
587 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
589 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
590 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
591 format = TEGRA_IMAGE_FORMAT_T_L8;
592 data_type = TEGRA_IMAGE_DT_RAW8;
593 image_size = icd->user_width;
594 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
595 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
596 format = TEGRA_IMAGE_FORMAT_T_R16_I;
597 data_type = TEGRA_IMAGE_DT_RAW10;
598 image_size = (icd->user_width * 10) >> 3;
601 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
602 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
604 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
606 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
608 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
609 (icd->user_height << 16) | icd->user_width);
614 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
615 struct soc_camera_device *icd)
617 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
618 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
619 int format = 0, data_type = 0, image_size = 0;
622 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
623 0x5 | (0x1 << 5) | (0x50 << 8));
626 if (pdata->port == TEGRA_CAMERA_PORT_CSI_B) {
627 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0x9);
628 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0x9);
629 } else if (pdata->port == TEGRA_CAMERA_PORT_CSI_C)
630 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0x9);
632 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
633 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
634 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
635 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
636 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x11);
637 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x140000);
638 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME, 0x0);
640 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
641 0x3f0000 | (pdata->lanes - 1));
642 if (pdata->lanes == 4)
643 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x21010202);
644 else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_C)
645 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x12020202);
647 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
650 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
651 ((cam->tpg_mode - 1) << 2) | 0x1);
652 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_B, 0x0);
653 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_B, 0x100010);
654 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_B, 0x0);
655 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_B, 0x100010);
656 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_B, 0x0);
657 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_B, 0x100010);
658 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
659 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
661 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
662 data_type = TEGRA_IMAGE_DT_RGB888;
663 image_size = icd->user_width * 3;
664 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
665 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
666 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
667 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
669 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
670 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
671 format = TEGRA_IMAGE_FORMAT_T_L8;
672 data_type = TEGRA_IMAGE_DT_RAW8;
673 image_size = icd->user_width;
674 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
675 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
676 format = TEGRA_IMAGE_FORMAT_T_R16_I;
677 data_type = TEGRA_IMAGE_DT_RAW10;
678 image_size = icd->user_width * 10 / 8;
681 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
682 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
684 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
686 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
688 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
689 (icd->user_height << 16) | icd->user_width);
694 static int vi2_capture_setup(struct tegra_camera_dev *cam)
696 struct vb2_buffer *vb = cam->active;
697 struct tegra_camera_buffer *buf = to_tegra_vb(vb);
698 struct soc_camera_device *icd = buf->icd;
699 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
700 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
701 int port = pdata->port;
703 /* Skip VI2/CSI2 setup for second and later frame capture */
708 * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
709 * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
711 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
713 /* PAD_CILB_PDVCLAMP 0, PAD_CILB_PDIO_CLK 0, PAD_CILB_PDIO 0 */
714 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x0);
717 * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
718 * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
720 TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
722 /* PAD_CILD_PDVCLAMP 0, PAD_CILD_PDIO_CLK 0, PAD_CILD_PDIO 0 */
723 TC_VI_REG_WT(cam, TEGRA_CSI_CILD_PAD_CONFIG0, 0x0);
725 /* PAD_CILE_PDVCLAMP 0, PAD_CILE_PDIO_CLK 0, PAD_CILE_PDIO 0 */
726 TC_VI_REG_WT(cam, TEGRA_CSI_CILE_PAD_CONFIG0, 0x0);
728 /* Common programming set for any config */
729 TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x0);
730 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
731 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK, 0x0);
732 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK, 0x0);
733 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK, 0x0);
734 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
735 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
737 /* Setup registers for CSI-A and CSI-B inputs */
738 if (port == TEGRA_CAMERA_PORT_CSI_A)
739 return vi2_capture_setup_csi_0(cam, icd);
740 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
741 port == TEGRA_CAMERA_PORT_CSI_C)
742 return vi2_capture_setup_csi_1(cam, icd);
747 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
748 struct tegra_camera_buffer *buf)
750 struct soc_camera_device *icd = buf->icd;
751 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
752 icd->current_fmt->host_fmt);
753 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
754 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
755 int port = pdata->port;
757 switch (icd->current_fmt->host_fmt->fourcc) {
758 case V4L2_PIX_FMT_YUV420:
759 case V4L2_PIX_FMT_YVU420:
760 /* FIXME: Setup YUV buffer */
762 case V4L2_PIX_FMT_UYVY:
763 case V4L2_PIX_FMT_VYUY:
764 case V4L2_PIX_FMT_YUYV:
765 case V4L2_PIX_FMT_YVYU:
766 case V4L2_PIX_FMT_SBGGR8:
767 case V4L2_PIX_FMT_SGBRG8:
768 case V4L2_PIX_FMT_SBGGR10:
769 case V4L2_PIX_FMT_SRGGB10:
770 case V4L2_PIX_FMT_RGB32:
771 if (port == TEGRA_CAMERA_PORT_CSI_A) {
772 switch (buf->output_channel) {
775 TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
778 TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
781 TEGRA_VI_CSI_0_SURFACE0_STRIDE,
786 TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
789 TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
792 TEGRA_VI_CSI_0_SURFACE1_STRIDE,
797 TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
800 TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
803 TEGRA_VI_CSI_0_SURFACE2_STRIDE,
807 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
808 port == TEGRA_CAMERA_PORT_CSI_C) {
809 switch (buf->output_channel) {
812 TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
815 TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
818 TEGRA_VI_CSI_1_SURFACE0_STRIDE,
823 TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
826 TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
829 TEGRA_VI_CSI_1_SURFACE1_STRIDE,
834 TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
837 TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
840 TEGRA_VI_CSI_1_SURFACE2_STRIDE,
848 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
849 icd->current_fmt->host_fmt->fourcc);
856 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
861 val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
862 pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
864 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
865 pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
866 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
867 pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
868 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
869 pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
870 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
871 pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
872 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
873 pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
874 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
875 pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
876 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
877 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
878 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS);
879 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x%08x\n", val);
880 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
881 pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
882 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_1_ERROR_STATUS);
883 pr_err("TEGRA_VI_CSI_1_ERROR_STATUS 0x%08x\n", val);
886 static int vi2_capture_start(struct tegra_camera_dev *cam,
887 struct tegra_camera_buffer *buf)
889 struct soc_camera_device *icd = buf->icd;
890 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
891 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
892 int port = pdata->port;
895 err = vi2_capture_buffer_setup(cam, buf);
899 /* Only wait on CSI frame end syncpt if we're using CSI. */
900 if (port == TEGRA_CAMERA_PORT_CSI_A) {
901 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
902 (6 << 8) | cam->syncpt_id_csi_a);
903 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
905 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
906 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
907 cam->syncpt_id_csi_a,
909 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
912 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
913 port == TEGRA_CAMERA_PORT_CSI_C) {
914 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
915 (7 << 8) | cam->syncpt_id_csi_b);
916 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
918 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
919 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
920 cam->syncpt_id_csi_b,
922 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
927 /* Mark SOF flag to Zero after we captured the FIRST frame */
931 /* Capture syncpt timeout err, then dump error status */
933 if (port == TEGRA_CAMERA_PORT_CSI_A)
934 dev_err(&cam->ndev->dev,
935 "CSI_A syncpt timeout, syncpt = %d, err = %d\n",
936 cam->syncpt_csi_a, err);
937 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
938 port == TEGRA_CAMERA_PORT_CSI_C)
939 dev_err(&cam->ndev->dev,
940 "CSI_B/CSI_C syncpt timeout, syncpt = %d, err = %d\n",
941 cam->syncpt_csi_b, err);
942 vi2_capture_error_status(cam);
948 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
950 if (port == TEGRA_CAMERA_PORT_CSI_A)
951 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
953 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
954 port == TEGRA_CAMERA_PORT_CSI_C)
955 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
961 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving */
962 static void vi2_sw_reset(struct tegra_camera_dev *cam)
964 /* T12_CG_2ND_LEVEL_EN */
965 TC_VI_REG_WT(cam, TEGRA_VI_CFG_CG_CTRL, 1);
966 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SW_RESET, 0x1F);
967 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SW_RESET, 0x1F);
972 struct tegra_camera_ops vi2_ops = {
973 .clks_init = vi2_clks_init,
974 .clks_deinit = vi2_clks_deinit,
975 .clks_enable = vi2_clks_enable,
976 .clks_disable = vi2_clks_disable,
978 .capture_clean = vi2_capture_clean,
979 .capture_setup = vi2_capture_setup,
980 .capture_start = vi2_capture_start,
981 .capture_stop = vi2_capture_stop,
983 .activate = vi2_sw_reset,
985 .init_syncpts = vi2_init_syncpts,
986 .free_syncpts = vi2_free_syncpts,
987 .incr_syncpts = vi2_incr_syncpts,
989 .port_is_valid = vi2_port_is_valid,
992 int vi2_register(struct tegra_camera_dev *cam)
995 cam->regulator_name = "avdd_dsi_csi";
997 /* Init VI2/CSI2 ops */