]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/media/platform/soc_camera/tegra_camera/vi2.c
media: tegra_v4l2_camera: fix format support
[sojka/nv-tegra/linux-3.10.git] / drivers / media / platform / soc_camera / tegra_camera / vi2.c
1 /*
2  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
3  *
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.
7  *
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
11  * more details.
12  *
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/>.
15  */
16
17 #include <linux/delay.h>
18 #include <linux/clk.h>
19 #include <linux/platform_device.h>
20
21 #include <media/soc_camera.h>
22 #include <media/soc_mediabus.h>
23 #include <media/tegra_v4l2_camera.h>
24
25 #include <mach/clk.h>
26
27 #include "nvhost_syncpt.h"
28 #include "common.h"
29
30 #define TEGRA_SYNCPT_CSI_WAIT_TIMEOUT                   200
31
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
62
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
93
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
124
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
148
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
158
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
168
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
178
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
188
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
197
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
207
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
217
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
228
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
269
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
288
289 static int vi2_port_is_valid(int port)
290 {
291         return (((port) >= TEGRA_CAMERA_PORT_CSI_A) &&
292                 ((port) <= TEGRA_CAMERA_PORT_CSI_E));
293 }
294
295 /* Clock settings for camera */
296 static struct tegra_camera_clk vi2_clks0[] = {
297         {
298                 .name = "vi",
299                 .freq = 408000000,
300                 .use_devname = 1,
301         },
302         {
303                 .name = "vi_sensor",
304                 .freq = 24000000,
305         },
306         {
307                 .name = "csi",
308                 .freq = 408000000,
309                 .use_devname = 1,
310         },
311         {
312                 .name = "isp",
313                 .freq = 0,
314         },
315         {
316                 .name = "csus",
317                 .freq = 0,
318                 .use_devname = 1,
319         },
320         {
321                 .name = "sclk",
322                 .freq = 80000000,
323         },
324         {
325                 .name = "emc",
326                 .freq = 300000000,
327         },
328         {
329                 .name = "cilab",
330                 .freq = 102000000,
331                 .use_devname = 1,
332         },
333         /* Always put "p11_d" at the end */
334         {
335                 .name = "pll_d",
336                 .freq = 927000000,
337         },
338 };
339
340 static struct tegra_camera_clk vi2_clks1[] = {
341         {
342                 .name = "vi",
343                 .freq = 408000000,
344                 .use_devname = 1,
345         },
346         {
347                 .name = "vi_sensor",
348                 .freq = 24000000,
349         },
350         {
351                 .name = "csi",
352                 .freq = 408000000,
353                 .use_devname = 1,
354         },
355         {
356                 .name = "isp",
357                 .freq = 0,
358         },
359         {
360                 .name = "sclk",
361                 .freq = 80000000,
362         },
363         {
364                 .name = "emc",
365                 .freq = 300000000,
366         },
367         {
368                 .name = "cilcd",
369                 .freq = 0,
370                 .use_devname = 1,
371         },
372         {
373                 .name = "cile",
374                 .freq = 0,
375                 .use_devname = 1,
376         },
377         /* Always put "p11_d" at the end */
378         {
379                 .name = "pll_d",
380                 .freq = 927000000,
381         },
382 };
383
384 #define MAX_DEVID_LENGTH        16
385
386 static int vi2_clks_init(struct tegra_camera_dev *cam)
387 {
388         struct platform_device *pdev = cam->ndev;
389         struct tegra_camera_clk *clks;
390         int i;
391
392         switch (pdev->id) {
393         case 0:
394                 cam->num_clks = ARRAY_SIZE(vi2_clks0);
395                 cam->clks = vi2_clks0;
396                 break;
397         case 1:
398                 cam->num_clks = ARRAY_SIZE(vi2_clks1);
399                 cam->clks = vi2_clks1;
400                 break;
401         default:
402                 dev_err(&pdev->dev, "Wrong device ID %d\n", pdev->id);
403                 return -ENODEV;
404         }
405
406         for (i = 0; i < cam->num_clks; i++) {
407                 clks = &cam->clks[i];
408
409                 if (clks->use_devname) {
410                         char devname[MAX_DEVID_LENGTH];
411                         snprintf(devname, MAX_DEVID_LENGTH,
412                                  "tegra_%s", dev_name(&pdev->dev));
413                         clks->clk = clk_get_sys(devname, clks->name);
414                 } else
415                         clks->clk = clk_get(&pdev->dev, clks->name);
416                 if (IS_ERR_OR_NULL(clks->clk)) {
417                         dev_err(&pdev->dev, "Failed to get clock %s.\n",
418                                 clks->name);
419                         return PTR_ERR(clks->clk);
420                 }
421         }
422
423         return 0;
424 }
425
426 static void vi2_clks_deinit(struct tegra_camera_dev *cam)
427 {
428         struct tegra_camera_clk *clks;
429         int i;
430
431         for (i = 0; i < cam->num_clks; i++) {
432                 clks = &cam->clks[i];
433                 if (clks->clk)
434                         clk_put(clks->clk);
435         }
436 }
437
438 static void vi2_clks_enable(struct tegra_camera_dev *cam)
439 {
440         struct tegra_camera_clk *clks;
441         int i;
442
443         for (i = 0; i < cam->num_clks - 1; i++) {
444                 clks = &cam->clks[i];
445                 if (clks->clk)
446                         clk_prepare_enable(clks->clk);
447                 if (clks->freq > 0)
448                         clk_set_rate(clks->clk, clks->freq);
449         }
450
451         if (cam->tpg_mode) {
452                 clks = &cam->clks[i];
453                 if (clks->clk) {
454                         clk_prepare_enable(clks->clk);
455                         if (clks->freq > 0)
456                                 clk_set_rate(clks->clk, clks->freq);
457                         tegra_clk_cfg_ex(clks->clk,
458                                          TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
459                         tegra_clk_cfg_ex(clks->clk,
460                                          TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
461                         tegra_clk_cfg_ex(clks->clk,
462                                          TEGRA_CLK_MIPI_CSI_OUT_ENB, 0);
463                 }
464         }
465 }
466
467 static void vi2_clks_disable(struct tegra_camera_dev *cam)
468 {
469         struct tegra_camera_clk *clks;
470         int i;
471
472         for (i = 0; i < cam->num_clks - 1; i++) {
473                 clks = &cam->clks[i];
474                 if (clks->clk)
475                         clk_disable_unprepare(clks->clk);
476         }
477
478         if (cam->tpg_mode) {
479                 clks = &cam->clks[i];
480                 if (clks->clk) {
481                         tegra_clk_cfg_ex(clks->clk,
482                                          TEGRA_CLK_MIPI_CSI_OUT_ENB, 1);
483                         tegra_clk_cfg_ex(clks->clk,
484                                          TEGRA_CLK_PLLD_CSI_OUT_ENB, 0);
485                         tegra_clk_cfg_ex(clks->clk,
486                                          TEGRA_CLK_PLLD_DSI_OUT_ENB, 0);
487                         clk_disable_unprepare(clks->clk);
488                 }
489         }
490 }
491
492 static void vi2_init_syncpts(struct tegra_camera_dev *cam)
493 {
494         cam->syncpt_id_csi_a = nvhost_get_syncpt_client_managed("vi_csi_A");
495
496         cam->syncpt_id_csi_b = nvhost_get_syncpt_client_managed("vi_csi_B");
497 }
498
499 static void vi2_free_syncpts(struct tegra_camera_dev *cam)
500 {
501         nvhost_free_syncpt(cam->syncpt_id_csi_a);
502
503         nvhost_free_syncpt(cam->syncpt_id_csi_b);
504 }
505
506 static void vi2_incr_syncpts(struct tegra_camera_dev *cam)
507 {
508         u32 val;
509
510         if (!nvhost_syncpt_read_ext_check(cam->ndev,
511                         cam->syncpt_id_csi_a, &val))
512                 cam->syncpt_csi_a = nvhost_syncpt_incr_max_ext(cam->ndev,
513                                                 cam->syncpt_id_csi_a, 1);
514
515         if (!nvhost_syncpt_read_ext_check(cam->ndev,
516                         cam->syncpt_id_csi_b, &val))
517                 cam->syncpt_csi_b = nvhost_syncpt_incr_max_ext(cam->ndev,
518                                                 cam->syncpt_id_csi_b, 1);
519 }
520
521 static void vi2_capture_clean(struct tegra_camera_dev *cam)
522 {
523         /* Clean up status */
524         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_STATUS, 0xFFFFFFFF);
525         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_STATUS, 0xFFFFFFFF);
526         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_STATUS, 0xFFFFFFFF);
527         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_STATUS, 0xFFFFFFFF);
528         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_STATUS, 0xFFFFFFFF);
529         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILA_STATUS, 0xFFFFFFFF);
530         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILB_STATUS, 0xFFFFFFFF);
531         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILC_STATUS, 0xFFFFFFFF);
532         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILD_STATUS, 0xFFFFFFFF);
533         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS, 0xFFFFFFFF);
534         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS, 0xFFFFFFFF);
535         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_ERROR_STATUS, 0xFFFFFFFF);
536         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_ERROR_STATUS, 0xFFFFFFFF);
537 }
538
539 static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
540                                     struct soc_camera_device *icd)
541 {
542         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
543         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
544         int format = 0, data_type = 0, image_size = 0;
545
546         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
547         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK, 0x0);
548         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0, 0x280301f0);
549         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
550         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL1, 0x11);
551         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_GAP, 0x140000);
552
553         TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
554                         0x3f0000 | (pdata->lanes - 1));
555         if (pdata->lanes == 4)
556                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020101);
557         else
558                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020201);
559
560         if (cam->tpg_mode) {
561                 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
562                                 ((cam->tpg_mode - 1) << 2) | 0x1);
563                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
564                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x100010);
565                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
566                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x100010);
567                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
568                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x100010);
569                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
570                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
571
572                 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
573                 data_type = TEGRA_IMAGE_DT_RGB888;
574                 image_size = icd->user_width * 3;
575         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
576                    (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
577                    (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
578                    (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
579                 /* TBD */
580         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
581                    (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
582                 format = TEGRA_IMAGE_FORMAT_T_L8;
583                 data_type = TEGRA_IMAGE_DT_RAW8;
584                 image_size = icd->user_width;
585         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
586                    (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
587                 format = TEGRA_IMAGE_FORMAT_T_R16_I;
588                 data_type = TEGRA_IMAGE_DT_RAW10;
589                 image_size = (icd->user_width * 10) >> 3;
590         }
591
592         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
593                         (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
594
595         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
596
597         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
598
599         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
600                         (icd->user_height << 16) | icd->user_width);
601
602         return 0;
603 }
604
605 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
606                                      struct soc_camera_device *icd)
607 {
608         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
609         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
610         int format = 0, data_type = 0, image_size = 0;
611
612         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
613         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
614         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
615         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
616         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x11);
617         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x140000);
618
619         TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
620                         0x3f0000 | (pdata->lanes - 1));
621         if (pdata->lanes == 4)
622                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x21010202);
623         else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_E)
624                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x12020202);
625         else
626                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
627
628         if (cam->tpg_mode) {
629                 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
630                                 ((cam->tpg_mode - 1) << 2) | 0x1);
631                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_B, 0x0);
632                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_B, 0x100010);
633                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_B, 0x0);
634                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_B, 0x100010);
635                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_B, 0x0);
636                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_B, 0x100010);
637                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
638                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
639
640                 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
641                 data_type = TEGRA_IMAGE_DT_RGB888;
642                 image_size = icd->user_width * 3;
643         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
644                    (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
645                    (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
646                    (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
647                 /* TBD */
648         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
649                    (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
650                 format = TEGRA_IMAGE_FORMAT_T_L8;
651                 data_type = TEGRA_IMAGE_DT_RAW8;
652                 image_size = icd->user_width;
653         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
654                    (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
655                 format = TEGRA_IMAGE_FORMAT_T_R16_I;
656                 data_type = TEGRA_IMAGE_DT_RAW10;
657                 image_size = icd->user_width * 10 / 8;
658         }
659
660         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
661                         (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
662
663         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
664
665         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
666
667         return 0;
668 }
669
670 static int vi2_capture_setup(struct tegra_camera_dev *cam)
671 {
672         struct vb2_buffer *vb = cam->active;
673         struct tegra_camera_buffer *buf = to_tegra_vb(vb);
674         struct soc_camera_device *icd = buf->icd;
675         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
676         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
677         int port = pdata->port;
678
679         /* Skip VI2/CSI2 setup for second and later frame capture */
680         if (!cam->sof)
681                 return 0;
682
683 #ifdef DEBUG
684         TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
685                         0x3 | (0x1 << 5) | (0x40 << 8));
686 #endif
687
688         /*
689          * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
690          * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
691          */
692         TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
693
694         /* PAD_CILB_PDVCLAMP 0, PAD_CILB_PDIO_CLK 0, PAD_CILB_PDIO 0 */
695         TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x0);
696
697         /*
698          * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
699          * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
700          */
701         TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
702
703         /* PAD_CILD_PDVCLAMP 0, PAD_CILD_PDIO_CLK 0, PAD_CILD_PDIO 0 */
704         TC_VI_REG_WT(cam, TEGRA_CSI_CILD_PAD_CONFIG0, 0x0);
705
706         /* PAD_CILE_PDVCLAMP 0, PAD_CILE_PDIO_CLK 0, PAD_CILE_PDIO 0 */
707         TC_VI_REG_WT(cam, TEGRA_CSI_CILE_PAD_CONFIG0, 0x0);
708
709         /* Common programming set for any config */
710         TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x0);
711         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
712         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK, 0x0);
713         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK, 0x0);
714         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK, 0x0);
715         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
716         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
717
718         /*
719          * TODO: these values should be different with different
720          * sensor connected.
721          * Hardcode THS settle value just for TPG testing
722          */
723         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x8);
724         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x8);
725         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0xa);
726         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0xa);
727         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0xa);
728
729         /* Setup registers for CSI-A and CSI-B inputs */
730         if (port == TEGRA_CAMERA_PORT_CSI_A)
731                 return vi2_capture_setup_csi_0(cam, icd);
732         else if (port == TEGRA_CAMERA_PORT_CSI_B)
733                 return vi2_capture_setup_csi_1(cam, icd);
734         else
735                 return -ENODEV;
736 }
737
738 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
739                         struct tegra_camera_buffer *buf)
740 {
741         struct soc_camera_device *icd = buf->icd;
742         int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
743                         icd->current_fmt->host_fmt);
744
745         switch (icd->current_fmt->host_fmt->fourcc) {
746         case V4L2_PIX_FMT_YUV420:
747         case V4L2_PIX_FMT_YVU420:
748                 /* FIXME: Setup YUV buffer */
749
750         case V4L2_PIX_FMT_UYVY:
751         case V4L2_PIX_FMT_VYUY:
752         case V4L2_PIX_FMT_YUYV:
753         case V4L2_PIX_FMT_YVYU:
754         case V4L2_PIX_FMT_SBGGR8:
755         case V4L2_PIX_FMT_SGBRG8:
756         case V4L2_PIX_FMT_SBGGR10:
757         case V4L2_PIX_FMT_SRGGB10:
758         case V4L2_PIX_FMT_RGB32:
759                 switch (buf->output_channel) {
760                 case 0:
761                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
762                                      0x0);
763                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
764                                      buf->buffer_addr);
765                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE0_STRIDE,
766                                      bytes_per_line);
767                         break;
768                 case 1:
769                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
770                                      0x0);
771                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
772                                      buf->buffer_addr);
773                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE1_STRIDE,
774                                      bytes_per_line);
775                         break;
776                 case 2:
777                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
778                                      0x0);
779                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
780                                      buf->buffer_addr);
781                         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SURFACE2_STRIDE,
782                                      bytes_per_line);
783                         break;
784                 }
785                 break;
786
787         default:
788                 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
789                         icd->current_fmt->host_fmt->fourcc);
790                 return -EINVAL;
791         }
792
793         return 0;
794 }
795
796 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
797 {
798         u32 val;
799
800 #ifdef DEBUG
801         val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
802         pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
803 #endif
804         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
805         pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
806         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
807         pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
808         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
809         pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
810         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
811         pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
812         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
813         pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
814         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
815         pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
816         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
817         pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
818         val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
819         pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
820 }
821
822 static int vi2_capture_start(struct tegra_camera_dev *cam,
823                                       struct tegra_camera_buffer *buf)
824 {
825         struct soc_camera_device *icd = buf->icd;
826         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
827         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
828         int port = pdata->port;
829         int err;
830
831         err = vi2_capture_buffer_setup(cam, buf);
832         if (err < 0)
833                 return err;
834
835         /* Only wait on CSI frame end syncpt if we're using CSI. */
836         if (port == TEGRA_CAMERA_PORT_CSI_A) {
837                 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
838                                 (6 << 8) | cam->syncpt_id_csi_a);
839                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
840                                 0x0000f005);
841                 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
842                 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
843                                 cam->syncpt_id_csi_a,
844                                 cam->syncpt_csi_a,
845                                 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
846                                 NULL,
847                                 NULL);
848         } else if (port == TEGRA_CAMERA_PORT_CSI_B) {
849                 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
850                                 (7 << 8) | cam->syncpt_id_csi_b);
851                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
852                                 0x0000f005);
853                 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
854                 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
855                                 cam->syncpt_id_csi_b,
856                                 cam->syncpt_csi_b,
857                                 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
858                                 NULL,
859                                 NULL);
860         }
861
862         /* Mark SOF flag to Zero after we captured the FIRST frame */
863         if (cam->sof)
864                 cam->sof = 0;
865
866         /* Capture syncpt timeout err, then dump error status */
867         if (err) {
868                 if (port == TEGRA_CAMERA_PORT_CSI_A)
869                         dev_err(&cam->ndev->dev,
870                                 "CSI_A syncpt timeout, syncpt = %d, err = %d\n",
871                                 cam->syncpt_csi_a, err);
872                 else if (port == TEGRA_CAMERA_PORT_CSI_B)
873                         dev_err(&cam->ndev->dev,
874                                 "CSI_B syncpt timeout, syncpt = %d, err = %d\n",
875                                 cam->syncpt_csi_b, err);
876                 vi2_capture_error_status(cam);
877         }
878
879         return err;
880 }
881
882 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
883 {
884         if (port == TEGRA_CAMERA_PORT_CSI_A)
885                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
886                              0x0000f002);
887         else if (port == TEGRA_CAMERA_PORT_CSI_B)
888                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
889                              0x0000f002);
890
891         return 0;
892 }
893
894 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving  */
895 static void vi2_sw_reset(struct tegra_camera_dev *cam)
896 {
897         /* T12_CG_2ND_LEVEL_EN */
898         TC_VI_REG_WT(cam, TEGRA_VI_CFG_CG_CTRL, 1);
899         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SW_RESET, 0x1F);
900         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SW_RESET, 0x1F);
901
902         udelay(10);
903 }
904
905 struct tegra_camera_ops vi2_ops = {
906         .clks_init = vi2_clks_init,
907         .clks_deinit = vi2_clks_deinit,
908         .clks_enable = vi2_clks_enable,
909         .clks_disable = vi2_clks_disable,
910
911         .capture_clean = vi2_capture_clean,
912         .capture_setup = vi2_capture_setup,
913         .capture_start = vi2_capture_start,
914         .capture_stop = vi2_capture_stop,
915
916         .activate = vi2_sw_reset,
917
918         .init_syncpts = vi2_init_syncpts,
919         .free_syncpts = vi2_free_syncpts,
920         .incr_syncpts = vi2_incr_syncpts,
921
922         .port_is_valid = vi2_port_is_valid,
923 };
924
925 int vi2_register(struct tegra_camera_dev *cam)
926 {
927         /* Init regulator */
928         cam->regulator_name = "avdd_dsi_csi";
929
930         /* Init VI2/CSI2 ops */
931         cam->ops = &vi2_ops;
932
933         return 0;
934 }