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)
512 static void vi2_capture_clean(struct tegra_camera_dev *cam)
514 /* Clean up status */
515 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_STATUS, 0xFFFFFFFF);
516 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_STATUS, 0xFFFFFFFF);
517 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_STATUS, 0xFFFFFFFF);
518 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_STATUS, 0xFFFFFFFF);
519 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_STATUS, 0xFFFFFFFF);
520 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILA_STATUS, 0xFFFFFFFF);
521 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILB_STATUS, 0xFFFFFFFF);
522 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILC_STATUS, 0xFFFFFFFF);
523 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILD_STATUS, 0xFFFFFFFF);
524 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS, 0xFFFFFFFF);
525 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS, 0xFFFFFFFF);
526 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_ERROR_STATUS, 0xFFFFFFFF);
527 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_ERROR_STATUS, 0xFFFFFFFF);
530 static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
531 struct soc_camera_device *icd)
533 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
534 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
535 int format = 0, data_type = 0, image_size = 0;
539 * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
540 * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
542 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
544 /* PAD_CILB_PDVCLAMP 0, PAD_CILB_PDIO_CLK 0, PAD_CILB_PDIO 0 */
545 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x0);
547 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK, 0x0);
548 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK, 0x0);
551 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
552 0x3 | (0x1 << 5) | (0x40 << 8));
555 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x9);
556 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x9);
557 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
558 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK, 0x0);
559 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0, 0x280301f0);
560 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
561 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL1, 0x11);
562 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_GAP, 0x140000);
563 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME, 0x0);
565 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
566 0x3f0000 | (pdata->lanes - 1));
568 /* Shared register */
569 val = TC_VI_REG_RD(cam, TEGRA_CSI_PHY_CIL_COMMAND);
570 if (pdata->lanes == 4)
571 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
572 (val & 0xFFFF0000) | 0x0101);
574 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
575 (val & 0xFFFF0000) | 0x0201);
578 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
579 ((cam->tpg_mode - 1) << 2) | 0x1);
580 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
581 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x100010);
582 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
583 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x100010);
584 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
585 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x100010);
586 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
587 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
589 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
590 data_type = TEGRA_IMAGE_DT_RGB888;
591 image_size = icd->user_width * 3;
592 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
593 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
594 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
595 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
597 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
598 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
599 format = TEGRA_IMAGE_FORMAT_T_L8;
600 data_type = TEGRA_IMAGE_DT_RAW8;
601 image_size = icd->user_width;
602 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
603 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
604 format = TEGRA_IMAGE_FORMAT_T_R16_I;
605 data_type = TEGRA_IMAGE_DT_RAW10;
606 image_size = (icd->user_width * 10) >> 3;
609 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
610 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
612 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
614 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
616 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
617 (icd->user_height << 16) | icd->user_width);
622 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
623 struct soc_camera_device *icd)
625 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
626 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
627 int format = 0, data_type = 0, image_size = 0;
631 * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
632 * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
634 TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
636 /* PAD_CILD_PDVCLAMP 0, PAD_CILD_PDIO_CLK 0, PAD_CILD_PDIO 0 */
637 TC_VI_REG_WT(cam, TEGRA_CSI_CILD_PAD_CONFIG0, 0x0);
639 /* PAD_CILE_PDVCLAMP 0, PAD_CILE_PDIO_CLK 0, PAD_CILE_PDIO 0 */
640 TC_VI_REG_WT(cam, TEGRA_CSI_CILE_PAD_CONFIG0, 0x0);
642 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK, 0x0);
643 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
644 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
647 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
648 0x5 | (0x1 << 5) | (0x50 << 8));
651 if (pdata->port == TEGRA_CAMERA_PORT_CSI_B) {
652 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0x9);
653 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0x9);
654 } else if (pdata->port == TEGRA_CAMERA_PORT_CSI_C)
655 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0x9);
657 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
658 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
659 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
660 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
661 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x11);
662 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x140000);
663 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME, 0x0);
665 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
666 0x3f0000 | (pdata->lanes - 1));
668 /* Shared register */
669 val = TC_VI_REG_RD(cam, TEGRA_CSI_PHY_CIL_COMMAND);
670 if (pdata->lanes == 4)
671 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
672 (val & 0x0000FFFF) | 0x21010000);
673 else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_C)
674 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
675 (val & 0x0000FFFF) | 0x12020000);
677 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
678 (val & 0x0000FFFF) | 0x22010000);
681 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
682 ((cam->tpg_mode - 1) << 2) | 0x1);
683 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_B, 0x0);
684 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_B, 0x100010);
685 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_B, 0x0);
686 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_B, 0x100010);
687 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_B, 0x0);
688 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_B, 0x100010);
689 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
690 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
692 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
693 data_type = TEGRA_IMAGE_DT_RGB888;
694 image_size = icd->user_width * 3;
695 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
696 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
697 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
698 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
700 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
701 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
702 format = TEGRA_IMAGE_FORMAT_T_L8;
703 data_type = TEGRA_IMAGE_DT_RAW8;
704 image_size = icd->user_width;
705 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
706 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
707 format = TEGRA_IMAGE_FORMAT_T_R16_I;
708 data_type = TEGRA_IMAGE_DT_RAW10;
709 image_size = icd->user_width * 10 / 8;
712 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
713 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
715 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
717 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
719 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
720 (icd->user_height << 16) | icd->user_width);
725 static int vi2_capture_setup(struct tegra_camera_dev *cam)
727 struct vb2_buffer *vb = cam->active;
728 struct tegra_camera_buffer *buf = to_tegra_vb(vb);
729 struct soc_camera_device *icd = buf->icd;
730 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
731 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
732 int port = pdata->port;
734 /* Skip VI2/CSI2 setup for second and later frame capture */
738 /* Setup registers for CSI-A and CSI-B inputs */
739 if (port == TEGRA_CAMERA_PORT_CSI_A)
740 return vi2_capture_setup_csi_0(cam, icd);
741 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
742 port == TEGRA_CAMERA_PORT_CSI_C)
743 return vi2_capture_setup_csi_1(cam, icd);
748 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
749 struct tegra_camera_buffer *buf)
751 struct soc_camera_device *icd = buf->icd;
752 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
753 icd->current_fmt->host_fmt);
754 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
755 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
756 int port = pdata->port;
758 switch (icd->current_fmt->host_fmt->fourcc) {
759 case V4L2_PIX_FMT_YUV420:
760 case V4L2_PIX_FMT_YVU420:
761 /* FIXME: Setup YUV buffer */
763 case V4L2_PIX_FMT_UYVY:
764 case V4L2_PIX_FMT_VYUY:
765 case V4L2_PIX_FMT_YUYV:
766 case V4L2_PIX_FMT_YVYU:
767 case V4L2_PIX_FMT_SBGGR8:
768 case V4L2_PIX_FMT_SGBRG8:
769 case V4L2_PIX_FMT_SBGGR10:
770 case V4L2_PIX_FMT_SRGGB10:
771 case V4L2_PIX_FMT_RGB32:
772 if (port == TEGRA_CAMERA_PORT_CSI_A) {
773 switch (buf->output_channel) {
776 TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
779 TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
782 TEGRA_VI_CSI_0_SURFACE0_STRIDE,
787 TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
790 TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
793 TEGRA_VI_CSI_0_SURFACE1_STRIDE,
798 TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
801 TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
804 TEGRA_VI_CSI_0_SURFACE2_STRIDE,
808 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
809 port == TEGRA_CAMERA_PORT_CSI_C) {
810 switch (buf->output_channel) {
813 TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
816 TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
819 TEGRA_VI_CSI_1_SURFACE0_STRIDE,
824 TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
827 TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
830 TEGRA_VI_CSI_1_SURFACE1_STRIDE,
835 TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
838 TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
841 TEGRA_VI_CSI_1_SURFACE2_STRIDE,
849 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
850 icd->current_fmt->host_fmt->fourcc);
857 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
862 val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
863 pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
865 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
866 pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
867 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
868 pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
869 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
870 pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
871 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
872 pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
873 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
874 pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
875 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
876 pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
877 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
878 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
879 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS);
880 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x%08x\n", val);
881 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
882 pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
883 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_1_ERROR_STATUS);
884 pr_err("TEGRA_VI_CSI_1_ERROR_STATUS 0x%08x\n", val);
887 static int vi2_capture_start(struct tegra_camera_dev *cam,
888 struct tegra_camera_buffer *buf)
890 struct soc_camera_device *icd = buf->icd;
891 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
892 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
893 int port = pdata->port;
897 err = vi2_capture_buffer_setup(cam, buf);
901 /* Only wait on CSI frame end syncpt if we're using CSI. */
902 if (port == TEGRA_CAMERA_PORT_CSI_A) {
903 if (!nvhost_syncpt_read_ext_check(cam->ndev,
904 cam->syncpt_id_csi_a, &val))
905 cam->syncpt_csi_a = nvhost_syncpt_incr_max_ext(
907 cam->syncpt_id_csi_a, 1);
909 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
910 (6 << 8) | cam->syncpt_id_csi_a);
911 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
913 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
914 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
915 cam->syncpt_id_csi_a,
917 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
920 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
921 port == TEGRA_CAMERA_PORT_CSI_C) {
922 if (!nvhost_syncpt_read_ext_check(cam->ndev,
923 cam->syncpt_id_csi_b, &val))
924 cam->syncpt_csi_b = nvhost_syncpt_incr_max_ext(
926 cam->syncpt_id_csi_b, 1);
928 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
929 (7 << 8) | cam->syncpt_id_csi_b);
930 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
932 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
933 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
934 cam->syncpt_id_csi_b,
936 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
941 /* Mark SOF flag to Zero after we captured the FIRST frame */
945 /* Capture syncpt timeout err, then dump error status */
947 if (port == TEGRA_CAMERA_PORT_CSI_A)
948 dev_err(&cam->ndev->dev,
949 "CSI_A syncpt timeout, syncpt = %d, err = %d\n",
950 cam->syncpt_csi_a, err);
951 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
952 port == TEGRA_CAMERA_PORT_CSI_C)
953 dev_err(&cam->ndev->dev,
954 "CSI_B/CSI_C syncpt timeout, syncpt = %d, err = %d\n",
955 cam->syncpt_csi_b, err);
956 vi2_capture_error_status(cam);
962 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
964 if (port == TEGRA_CAMERA_PORT_CSI_A)
965 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
967 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
968 port == TEGRA_CAMERA_PORT_CSI_C)
969 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
975 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving */
976 static void vi2_sw_reset(struct tegra_camera_dev *cam)
978 /* T12_CG_2ND_LEVEL_EN */
979 TC_VI_REG_WT(cam, TEGRA_VI_CFG_CG_CTRL, 1);
981 TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x0);
986 struct tegra_camera_ops vi2_ops = {
987 .clks_init = vi2_clks_init,
988 .clks_deinit = vi2_clks_deinit,
989 .clks_enable = vi2_clks_enable,
990 .clks_disable = vi2_clks_disable,
992 .capture_clean = vi2_capture_clean,
993 .capture_setup = vi2_capture_setup,
994 .capture_start = vi2_capture_start,
995 .capture_stop = vi2_capture_stop,
997 .activate = vi2_sw_reset,
999 .init_syncpts = vi2_init_syncpts,
1000 .free_syncpts = vi2_free_syncpts,
1001 .incr_syncpts = vi2_incr_syncpts,
1003 .port_is_valid = vi2_port_is_valid,
1006 int vi2_register(struct tegra_camera_dev *cam)
1008 /* Init regulator */
1009 cam->regulator_name = "avdd_dsi_csi";
1011 /* Init VI2/CSI2 ops */
1012 cam->ops = &vi2_ops;