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