]> 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: add CSI_B/CSI_C 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_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
561         TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
562                         0x3f0000 | (pdata->lanes - 1));
563         if (pdata->lanes == 4)
564                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020101);
565         else
566                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020201);
567
568         if (cam->tpg_mode) {
569                 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
570                                 ((cam->tpg_mode - 1) << 2) | 0x1);
571                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
572                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x100010);
573                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
574                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x100010);
575                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
576                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x100010);
577                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
578                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
579
580                 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
581                 data_type = TEGRA_IMAGE_DT_RGB888;
582                 image_size = icd->user_width * 3;
583         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
584                    (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
585                    (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
586                    (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
587                 /* TBD */
588         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
589                    (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
590                 format = TEGRA_IMAGE_FORMAT_T_L8;
591                 data_type = TEGRA_IMAGE_DT_RAW8;
592                 image_size = icd->user_width;
593         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
594                    (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
595                 format = TEGRA_IMAGE_FORMAT_T_R16_I;
596                 data_type = TEGRA_IMAGE_DT_RAW10;
597                 image_size = (icd->user_width * 10) >> 3;
598         }
599
600         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
601                         (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
602
603         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
604
605         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
606
607         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
608                         (icd->user_height << 16) | icd->user_width);
609
610         return 0;
611 }
612
613 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
614                                      struct soc_camera_device *icd)
615 {
616         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
617         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
618         int format = 0, data_type = 0, image_size = 0;
619
620 #ifdef DEBUG
621         TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
622                         0x5 | (0x1 << 5) | (0x50 << 8));
623 #endif
624
625         if (pdata->port == TEGRA_CAMERA_PORT_CSI_B) {
626                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0x9);
627                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0x9);
628         } else if (pdata->port == TEGRA_CAMERA_PORT_CSI_C)
629                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0x9);
630
631         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
632         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
633         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
634         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
635         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x11);
636         TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x140000);
637
638         TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
639                         0x3f0000 | (pdata->lanes - 1));
640         if (pdata->lanes == 4)
641                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x21010202);
642         else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_C)
643                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x12020202);
644         else
645                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22010202);
646
647         if (cam->tpg_mode) {
648                 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
649                                 ((cam->tpg_mode - 1) << 2) | 0x1);
650                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_B, 0x0);
651                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_B, 0x100010);
652                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_B, 0x0);
653                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_B, 0x100010);
654                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_B, 0x0);
655                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_B, 0x100010);
656                 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
657                 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
658
659                 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
660                 data_type = TEGRA_IMAGE_DT_RGB888;
661                 image_size = icd->user_width * 3;
662         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
663                    (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
664                    (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
665                    (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
666                 /* TBD */
667         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
668                    (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
669                 format = TEGRA_IMAGE_FORMAT_T_L8;
670                 data_type = TEGRA_IMAGE_DT_RAW8;
671                 image_size = icd->user_width;
672         } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
673                    (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
674                 format = TEGRA_IMAGE_FORMAT_T_R16_I;
675                 data_type = TEGRA_IMAGE_DT_RAW10;
676                 image_size = icd->user_width * 10 / 8;
677         }
678
679         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
680                         (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
681
682         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
683
684         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
685
686         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
687                         (icd->user_height << 16) | icd->user_width);
688
689         return 0;
690 }
691
692 static int vi2_capture_setup(struct tegra_camera_dev *cam)
693 {
694         struct vb2_buffer *vb = cam->active;
695         struct tegra_camera_buffer *buf = to_tegra_vb(vb);
696         struct soc_camera_device *icd = buf->icd;
697         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
698         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
699         int port = pdata->port;
700
701         /* Skip VI2/CSI2 setup for second and later frame capture */
702         if (!cam->sof)
703                 return 0;
704
705         /*
706          * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
707          * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
708          */
709         TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
710
711         /* PAD_CILB_PDVCLAMP 0, PAD_CILB_PDIO_CLK 0, PAD_CILB_PDIO 0 */
712         TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x0);
713
714         /*
715          * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
716          * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
717          */
718         TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
719
720         /* PAD_CILD_PDVCLAMP 0, PAD_CILD_PDIO_CLK 0, PAD_CILD_PDIO 0 */
721         TC_VI_REG_WT(cam, TEGRA_CSI_CILD_PAD_CONFIG0, 0x0);
722
723         /* PAD_CILE_PDVCLAMP 0, PAD_CILE_PDIO_CLK 0, PAD_CILE_PDIO 0 */
724         TC_VI_REG_WT(cam, TEGRA_CSI_CILE_PAD_CONFIG0, 0x0);
725
726         /* Common programming set for any config */
727         TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x0);
728         TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
729         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK, 0x0);
730         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK, 0x0);
731         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK, 0x0);
732         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
733         TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
734
735         /* Setup registers for CSI-A and CSI-B inputs */
736         if (port == TEGRA_CAMERA_PORT_CSI_A)
737                 return vi2_capture_setup_csi_0(cam, icd);
738         else if (port == TEGRA_CAMERA_PORT_CSI_B ||
739                         port == TEGRA_CAMERA_PORT_CSI_C)
740                 return vi2_capture_setup_csi_1(cam, icd);
741         else
742                 return -ENODEV;
743 }
744
745 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
746                         struct tegra_camera_buffer *buf)
747 {
748         struct soc_camera_device *icd = buf->icd;
749         int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
750                         icd->current_fmt->host_fmt);
751         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
752         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
753         int port = pdata->port;
754
755         switch (icd->current_fmt->host_fmt->fourcc) {
756         case V4L2_PIX_FMT_YUV420:
757         case V4L2_PIX_FMT_YVU420:
758                 /* FIXME: Setup YUV buffer */
759
760         case V4L2_PIX_FMT_UYVY:
761         case V4L2_PIX_FMT_VYUY:
762         case V4L2_PIX_FMT_YUYV:
763         case V4L2_PIX_FMT_YVYU:
764         case V4L2_PIX_FMT_SBGGR8:
765         case V4L2_PIX_FMT_SGBRG8:
766         case V4L2_PIX_FMT_SBGGR10:
767         case V4L2_PIX_FMT_SRGGB10:
768         case V4L2_PIX_FMT_RGB32:
769                 if (port == TEGRA_CAMERA_PORT_CSI_A) {
770                         switch (buf->output_channel) {
771                         case 0:
772                                 TC_VI_REG_WT(cam,
773                                              TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
774                                              0x0);
775                                 TC_VI_REG_WT(cam,
776                                              TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
777                                              buf->buffer_addr);
778                                 TC_VI_REG_WT(cam,
779                                              TEGRA_VI_CSI_0_SURFACE0_STRIDE,
780                                              bytes_per_line);
781                                 break;
782                         case 1:
783                                 TC_VI_REG_WT(cam,
784                                              TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
785                                              0x0);
786                                 TC_VI_REG_WT(cam,
787                                              TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
788                                              buf->buffer_addr);
789                                 TC_VI_REG_WT(cam,
790                                              TEGRA_VI_CSI_0_SURFACE1_STRIDE,
791                                              bytes_per_line);
792                                 break;
793                         case 2:
794                                 TC_VI_REG_WT(cam,
795                                              TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
796                                              0x0);
797                                 TC_VI_REG_WT(cam,
798                                              TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
799                                              buf->buffer_addr);
800                                 TC_VI_REG_WT(cam,
801                                              TEGRA_VI_CSI_0_SURFACE2_STRIDE,
802                                              bytes_per_line);
803                                 break;
804                         }
805                 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
806                         port == TEGRA_CAMERA_PORT_CSI_C) {
807                         switch (buf->output_channel) {
808                         case 0:
809                                 TC_VI_REG_WT(cam,
810                                              TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
811                                              0x0);
812                                 TC_VI_REG_WT(cam,
813                                              TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
814                                              buf->buffer_addr);
815                                 TC_VI_REG_WT(cam,
816                                              TEGRA_VI_CSI_1_SURFACE0_STRIDE,
817                                              bytes_per_line);
818                                 break;
819                         case 1:
820                                 TC_VI_REG_WT(cam,
821                                              TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
822                                              0x0);
823                                 TC_VI_REG_WT(cam,
824                                              TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
825                                              buf->buffer_addr);
826                                 TC_VI_REG_WT(cam,
827                                              TEGRA_VI_CSI_1_SURFACE1_STRIDE,
828                                              bytes_per_line);
829                                 break;
830                         case 2:
831                                 TC_VI_REG_WT(cam,
832                                              TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
833                                              0x0);
834                                 TC_VI_REG_WT(cam,
835                                              TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
836                                              buf->buffer_addr);
837                                 TC_VI_REG_WT(cam,
838                                              TEGRA_VI_CSI_1_SURFACE2_STRIDE,
839                                              bytes_per_line);
840                                 break;
841                         }
842                 }
843                 break;
844
845         default:
846                 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
847                         icd->current_fmt->host_fmt->fourcc);
848                 return -EINVAL;
849         }
850
851         return 0;
852 }
853
854 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
855 {
856         u32 val;
857
858 #ifdef DEBUG
859         val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
860         pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
861 #endif
862         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
863         pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
864         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
865         pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
866         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
867         pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
868         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
869         pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
870         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
871         pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
872         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
873         pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
874         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
875         pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
876         val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS);
877         pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x%08x\n", val);
878         val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
879         pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
880         val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_1_ERROR_STATUS);
881         pr_err("TEGRA_VI_CSI_1_ERROR_STATUS 0x%08x\n", val);
882 }
883
884 static int vi2_capture_start(struct tegra_camera_dev *cam,
885                                       struct tegra_camera_buffer *buf)
886 {
887         struct soc_camera_device *icd = buf->icd;
888         struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
889         struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
890         int port = pdata->port;
891         int err;
892
893         err = vi2_capture_buffer_setup(cam, buf);
894         if (err < 0)
895                 return err;
896
897         /* Only wait on CSI frame end syncpt if we're using CSI. */
898         if (port == TEGRA_CAMERA_PORT_CSI_A) {
899                 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
900                                 (6 << 8) | cam->syncpt_id_csi_a);
901                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
902                                 0x0000f005);
903                 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
904                 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
905                                 cam->syncpt_id_csi_a,
906                                 cam->syncpt_csi_a,
907                                 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
908                                 NULL,
909                                 NULL);
910         } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
911                         port == TEGRA_CAMERA_PORT_CSI_C) {
912                 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
913                                 (7 << 8) | cam->syncpt_id_csi_b);
914                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
915                                 0x0000f005);
916                 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
917                 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
918                                 cam->syncpt_id_csi_b,
919                                 cam->syncpt_csi_b,
920                                 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
921                                 NULL,
922                                 NULL);
923         }
924
925         /* Mark SOF flag to Zero after we captured the FIRST frame */
926         if (cam->sof)
927                 cam->sof = 0;
928
929         /* Capture syncpt timeout err, then dump error status */
930         if (err) {
931                 if (port == TEGRA_CAMERA_PORT_CSI_A)
932                         dev_err(&cam->ndev->dev,
933                                 "CSI_A syncpt timeout, syncpt = %d, err = %d\n",
934                                 cam->syncpt_csi_a, err);
935                 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
936                                 port == TEGRA_CAMERA_PORT_CSI_C)
937                         dev_err(&cam->ndev->dev,
938                                 "CSI_B/CSI_C syncpt timeout, syncpt = %d, err = %d\n",
939                                 cam->syncpt_csi_b, err);
940                 vi2_capture_error_status(cam);
941         }
942
943         return err;
944 }
945
946 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
947 {
948         if (port == TEGRA_CAMERA_PORT_CSI_A)
949                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
950                              0x0000f002);
951         else if (port == TEGRA_CAMERA_PORT_CSI_B ||
952                         port == TEGRA_CAMERA_PORT_CSI_C)
953                 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
954                              0x0000f002);
955
956         return 0;
957 }
958
959 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving  */
960 static void vi2_sw_reset(struct tegra_camera_dev *cam)
961 {
962         /* T12_CG_2ND_LEVEL_EN */
963         TC_VI_REG_WT(cam, TEGRA_VI_CFG_CG_CTRL, 1);
964         TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SW_RESET, 0x1F);
965         TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SW_RESET, 0x1F);
966
967         udelay(10);
968 }
969
970 struct tegra_camera_ops vi2_ops = {
971         .clks_init = vi2_clks_init,
972         .clks_deinit = vi2_clks_deinit,
973         .clks_enable = vi2_clks_enable,
974         .clks_disable = vi2_clks_disable,
975
976         .capture_clean = vi2_capture_clean,
977         .capture_setup = vi2_capture_setup,
978         .capture_start = vi2_capture_start,
979         .capture_stop = vi2_capture_stop,
980
981         .activate = vi2_sw_reset,
982
983         .init_syncpts = vi2_init_syncpts,
984         .free_syncpts = vi2_free_syncpts,
985         .incr_syncpts = vi2_incr_syncpts,
986
987         .port_is_valid = vi2_port_is_valid,
988 };
989
990 int vi2_register(struct tegra_camera_dev *cam)
991 {
992         /* Init regulator */
993         cam->regulator_name = "avdd_dsi_csi";
994
995         /* Init VI2/CSI2 ops */
996         cam->ops = &vi2_ops;
997
998         return 0;
999 }