]> 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: disable line timeout
[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_C));
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_sensor2",
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 = 102000000,
370                 .use_devname = 1,
371         },
372         {
373                 .name = "cile",
374                 .freq = 102000000,
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, int port)
387 {
388         struct platform_device *pdev = cam->ndev;
389         struct tegra_camera_clk *clks;
390         int i;
391
392         switch (port) {
393         case TEGRA_CAMERA_PORT_CSI_A:
394                 cam->num_clks = ARRAY_SIZE(vi2_clks0);
395                 cam->clks = vi2_clks0;
396                 break;
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;
401                 break;
402         default:
403                 dev_err(&pdev->dev, "Wrong port number %d\n", port);
404                 return -ENODEV;
405         }
406
407         for (i = 0; i < cam->num_clks; i++) {
408                 clks = &cam->clks[i];
409
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);
415                 } else
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",
419                                 clks->name);
420                         return PTR_ERR(clks->clk);
421                 }
422         }
423
424         return 0;
425 }
426
427 static void vi2_clks_deinit(struct tegra_camera_dev *cam)
428 {
429         struct tegra_camera_clk *clks;
430         int i;
431
432         for (i = 0; i < cam->num_clks; i++) {
433                 clks = &cam->clks[i];
434                 if (clks->clk)
435                         clk_put(clks->clk);
436         }
437 }
438
439 static void vi2_clks_enable(struct tegra_camera_dev *cam)
440 {
441         struct tegra_camera_clk *clks;
442         int i;
443
444         for (i = 0; i < cam->num_clks - 1; i++) {
445                 clks = &cam->clks[i];
446                 if (clks->clk)
447                         clk_prepare_enable(clks->clk);
448                 if (clks->freq > 0)
449                         clk_set_rate(clks->clk, clks->freq);
450         }
451
452         if (cam->tpg_mode) {
453                 clks = &cam->clks[i];
454                 if (clks->clk) {
455                         clk_prepare_enable(clks->clk);
456                         if (clks->freq > 0)
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);
464                 }
465         }
466 }
467
468 static void vi2_clks_disable(struct tegra_camera_dev *cam)
469 {
470         struct tegra_camera_clk *clks;
471         int i;
472
473         for (i = 0; i < cam->num_clks - 1; i++) {
474                 clks = &cam->clks[i];
475                 if (clks->clk)
476                         clk_disable_unprepare(clks->clk);
477         }
478
479         if (cam->tpg_mode) {
480                 clks = &cam->clks[i];
481                 if (clks->clk) {
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);
489                 }
490         }
491 }
492
493 static void vi2_init_syncpts(struct tegra_camera_dev *cam)
494 {
495         cam->syncpt_id_csi_a = nvhost_get_syncpt_client_managed("vi_csi_A");
496
497         cam->syncpt_id_csi_b = nvhost_get_syncpt_client_managed("vi_csi_B");
498 }
499
500 static void vi2_free_syncpts(struct tegra_camera_dev *cam)
501 {
502         nvhost_free_syncpt(cam->syncpt_id_csi_a);
503
504         nvhost_free_syncpt(cam->syncpt_id_csi_b);
505 }
506
507 static void vi2_incr_syncpts(struct tegra_camera_dev *cam)
508 {
509         u32 val;
510
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);
515
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);
520 }
521
522 static void vi2_capture_clean(struct tegra_camera_dev *cam)
523 {
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);
538 }
539
540 static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
541                                     struct soc_camera_device *icd)
542 {
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;
546
547 #ifdef DEBUG
548         TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
549                         0x3 | (0x1 << 5) | (0x40 << 8));
550 #endif
551
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);
561
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);
566         else
567                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020201);
568
569         if (cam->tpg_mode) {
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);
580
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)) {
588                 /* TBD */
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;
599         }
600
601         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
602                         (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
603
604         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
605
606         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
607
608         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
609                         (icd->user_height << 16) | icd->user_width);
610
611         return 0;
612 }
613
614 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
615                                      struct soc_camera_device *icd)
616 {
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;
620
621 #ifdef DEBUG
622         TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
623                         0x5 | (0x1 << 5) | (0x50 << 8));
624 #endif
625
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);
631
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);
639
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);
646         else
647                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
648
649         if (cam->tpg_mode) {
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);
660
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)) {
668                 /* TBD */
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;
679         }
680
681         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
682                         (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
683
684         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
685
686         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
687
688         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
689                         (icd->user_height << 16) | icd->user_width);
690
691         return 0;
692 }
693
694 static int vi2_capture_setup(struct tegra_camera_dev *cam)
695 {
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;
702
703         /* Skip VI2/CSI2 setup for second and later frame capture */
704         if (!cam->sof)
705                 return 0;
706
707         /*
708          * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
709          * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
710          */
711         TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
712
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);
715
716         /*
717          * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
718          * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
719          */
720         TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
721
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);
724
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);
727
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);
736
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);
743         else
744                 return -ENODEV;
745 }
746
747 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
748                         struct tegra_camera_buffer *buf)
749 {
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;
756
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 */
761
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) {
773                         case 0:
774                                 TC_VI_REG_WT(cam,
775                                              TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
776                                              0x0);
777                                 TC_VI_REG_WT(cam,
778                                              TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
779                                              buf->buffer_addr);
780                                 TC_VI_REG_WT(cam,
781                                              TEGRA_VI_CSI_0_SURFACE0_STRIDE,
782                                              bytes_per_line);
783                                 break;
784                         case 1:
785                                 TC_VI_REG_WT(cam,
786                                              TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
787                                              0x0);
788                                 TC_VI_REG_WT(cam,
789                                              TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
790                                              buf->buffer_addr);
791                                 TC_VI_REG_WT(cam,
792                                              TEGRA_VI_CSI_0_SURFACE1_STRIDE,
793                                              bytes_per_line);
794                                 break;
795                         case 2:
796                                 TC_VI_REG_WT(cam,
797                                              TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
798                                              0x0);
799                                 TC_VI_REG_WT(cam,
800                                              TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
801                                              buf->buffer_addr);
802                                 TC_VI_REG_WT(cam,
803                                              TEGRA_VI_CSI_0_SURFACE2_STRIDE,
804                                              bytes_per_line);
805                                 break;
806                         }
807                 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
808                         port == TEGRA_CAMERA_PORT_CSI_C) {
809                         switch (buf->output_channel) {
810                         case 0:
811                                 TC_VI_REG_WT(cam,
812                                              TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
813                                              0x0);
814                                 TC_VI_REG_WT(cam,
815                                              TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
816                                              buf->buffer_addr);
817                                 TC_VI_REG_WT(cam,
818                                              TEGRA_VI_CSI_1_SURFACE0_STRIDE,
819                                              bytes_per_line);
820                                 break;
821                         case 1:
822                                 TC_VI_REG_WT(cam,
823                                              TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
824                                              0x0);
825                                 TC_VI_REG_WT(cam,
826                                              TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
827                                              buf->buffer_addr);
828                                 TC_VI_REG_WT(cam,
829                                              TEGRA_VI_CSI_1_SURFACE1_STRIDE,
830                                              bytes_per_line);
831                                 break;
832                         case 2:
833                                 TC_VI_REG_WT(cam,
834                                              TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
835                                              0x0);
836                                 TC_VI_REG_WT(cam,
837                                              TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
838                                              buf->buffer_addr);
839                                 TC_VI_REG_WT(cam,
840                                              TEGRA_VI_CSI_1_SURFACE2_STRIDE,
841                                              bytes_per_line);
842                                 break;
843                         }
844                 }
845                 break;
846
847         default:
848                 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
849                         icd->current_fmt->host_fmt->fourcc);
850                 return -EINVAL;
851         }
852
853         return 0;
854 }
855
856 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
857 {
858         u32 val;
859
860 #ifdef DEBUG
861         val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
862         pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
863 #endif
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);
884 }
885
886 static int vi2_capture_start(struct tegra_camera_dev *cam,
887                                       struct tegra_camera_buffer *buf)
888 {
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;
893         int err;
894
895         err = vi2_capture_buffer_setup(cam, buf);
896         if (err < 0)
897                 return err;
898
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,
904                                 0x0000f005);
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,
908                                 cam->syncpt_csi_a,
909                                 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
910                                 NULL,
911                                 NULL);
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,
917                                 0x0000f005);
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,
921                                 cam->syncpt_csi_b,
922                                 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
923                                 NULL,
924                                 NULL);
925         }
926
927         /* Mark SOF flag to Zero after we captured the FIRST frame */
928         if (cam->sof)
929                 cam->sof = 0;
930
931         /* Capture syncpt timeout err, then dump error status */
932         if (err) {
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);
943         }
944
945         return err;
946 }
947
948 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
949 {
950         if (port == TEGRA_CAMERA_PORT_CSI_A)
951                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
952                              0x0000f002);
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,
956                              0x0000f002);
957
958         return 0;
959 }
960
961 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving  */
962 static void vi2_sw_reset(struct tegra_camera_dev *cam)
963 {
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);
968
969         udelay(10);
970 }
971
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,
977
978         .capture_clean = vi2_capture_clean,
979         .capture_setup = vi2_capture_setup,
980         .capture_start = vi2_capture_start,
981         .capture_stop = vi2_capture_stop,
982
983         .activate = vi2_sw_reset,
984
985         .init_syncpts = vi2_init_syncpts,
986         .free_syncpts = vi2_free_syncpts,
987         .incr_syncpts = vi2_incr_syncpts,
988
989         .port_is_valid = vi2_port_is_valid,
990 };
991
992 int vi2_register(struct tegra_camera_dev *cam)
993 {
994         /* Init regulator */
995         cam->regulator_name = "avdd_dsi_csi";
996
997         /* Init VI2/CSI2 ops */
998         cam->ops = &vi2_ops;
999
1000         return 0;
1001 }