2 * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <linux/delay.h>
18 #include <linux/clk.h>
19 #include <linux/regmap.h>
20 #include <linux/platform_device.h>
22 #include <media/soc_camera.h>
23 #include <media/soc_mediabus.h>
24 #include <media/tegra_v4l2_camera.h>
28 #include "nvhost_syncpt.h"
31 #define TEGRA_SYNCPT_CSI_WAIT_TIMEOUT 200
33 #define TEGRA_VI_CFG_VI_INCR_SYNCPT 0x000
34 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL 0x004
35 #define TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR 0x008
36 #define TEGRA_VI_CFG_CTXSW 0x020
37 #define TEGRA_VI_CFG_INTSTATUS 0x024
38 #define TEGRA_VI_CFG_PWM_CONTROL 0x038
39 #define TEGRA_VI_CFG_PWM_HIGH_PULSE 0x03c
40 #define TEGRA_VI_CFG_PWM_LOW_PULSE 0x040
41 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_A 0x044
42 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_B 0x048
43 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_C 0x04c
44 #define TEGRA_VI_CFG_PWM_SELECT_PULSE_D 0x050
45 #define TEGRA_VI_CFG_VGP1 0x064
46 #define TEGRA_VI_CFG_VGP2 0x068
47 #define TEGRA_VI_CFG_VGP3 0x06c
48 #define TEGRA_VI_CFG_VGP4 0x070
49 #define TEGRA_VI_CFG_VGP5 0x074
50 #define TEGRA_VI_CFG_VGP6 0x078
51 #define TEGRA_VI_CFG_INTERRUPT_MASK 0x08c
52 #define TEGRA_VI_CFG_INTERRUPT_TYPE_SELECT 0x090
53 #define TEGRA_VI_CFG_INTERRUPT_POLARITY_SELECT 0x094
54 #define TEGRA_VI_CFG_INTERRUPT_STATUS 0x098
55 #define TEGRA_VI_CFG_VGP_SYNCPT_CONFIG 0x0ac
56 #define TEGRA_VI_CFG_VI_SW_RESET 0x0b4
57 #define TEGRA_VI_CFG_CG_CTRL 0x0b8
58 #define TEGRA_VI_CFG_VI_MCCIF_FIFOCTRL 0x0e4
59 #define TEGRA_VI_CFG_TIMEOUT_WCOAL_VI 0x0e8
60 #define TEGRA_VI_CFG_DVFS 0x0f0
61 #define TEGRA_VI_CFG_RESERVE 0x0f4
62 #define TEGRA_VI_CFG_RESERVE_1 0x0f8
64 #define TEGRA_VI_CSI_0_SW_RESET 0x100
65 #define TEGRA_VI_CSI_0_SINGLE_SHOT 0x104
66 #define TEGRA_VI_CSI_0_SINGLE_SHOT_STATE_UPDATE 0x108
67 #define TEGRA_VI_CSI_0_IMAGE_DEF 0x10c
68 #define TEGRA_VI_CSI_0_RGB2Y_CTRL 0x110
69 #define TEGRA_VI_CSI_0_MEM_TILING 0x114
70 #define TEGRA_VI_CSI_0_CSI_IMAGE_SIZE 0x118
71 #define TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC 0x11c
72 #define TEGRA_VI_CSI_0_CSI_IMAGE_DT 0x120
73 #define TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB 0x124
74 #define TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB 0x128
75 #define TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB 0x12c
76 #define TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB 0x130
77 #define TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB 0x134
78 #define TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB 0x138
79 #define TEGRA_VI_CSI_0_SURFACE0_BF_OFFSET_MSB 0x13c
80 #define TEGRA_VI_CSI_0_SURFACE0_BF_OFFSET_LSB 0x140
81 #define TEGRA_VI_CSI_0_SURFACE1_BF_OFFSET_MSB 0x144
82 #define TEGRA_VI_CSI_0_SURFACE1_BF_OFFSET_LSB 0x148
83 #define TEGRA_VI_CSI_0_SURFACE2_BF_OFFSET_MSB 0x14c
84 #define TEGRA_VI_CSI_0_SURFACE2_BF_OFFSET_LSB 0x150
85 #define TEGRA_VI_CSI_0_SURFACE0_STRIDE 0x154
86 #define TEGRA_VI_CSI_0_SURFACE1_STRIDE 0x158
87 #define TEGRA_VI_CSI_0_SURFACE2_STRIDE 0x15c
88 #define TEGRA_VI_CSI_0_SURFACE_HEIGHT0 0x160
89 #define TEGRA_VI_CSI_0_ISPINTF_CONFIG 0x164
90 #define TEGRA_VI_CSI_0_ERROR_STATUS 0x184
91 #define TEGRA_VI_CSI_0_ERROR_INT_MASK 0x188
92 #define TEGRA_VI_CSI_0_WD_CTRL 0x18c
93 #define TEGRA_VI_CSI_0_WD_PERIOD 0x190
95 #define TEGRA_VI_CSI_1_SW_RESET 0x200
96 #define TEGRA_VI_CSI_1_SINGLE_SHOT 0x204
97 #define TEGRA_VI_CSI_1_SINGLE_SHOT_STATE_UPDATE 0x208
98 #define TEGRA_VI_CSI_1_IMAGE_DEF 0x20c
99 #define TEGRA_VI_CSI_1_RGB2Y_CTRL 0x210
100 #define TEGRA_VI_CSI_1_MEM_TILING 0x214
101 #define TEGRA_VI_CSI_1_CSI_IMAGE_SIZE 0x218
102 #define TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC 0x21c
103 #define TEGRA_VI_CSI_1_CSI_IMAGE_DT 0x220
104 #define TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB 0x224
105 #define TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB 0x228
106 #define TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB 0x22c
107 #define TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB 0x230
108 #define TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB 0x234
109 #define TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB 0x238
110 #define TEGRA_VI_CSI_1_SURFACE0_BF_OFFSET_MSB 0x23c
111 #define TEGRA_VI_CSI_1_SURFACE0_BF_OFFSET_LSB 0x240
112 #define TEGRA_VI_CSI_1_SURFACE1_BF_OFFSET_MSB 0x244
113 #define TEGRA_VI_CSI_1_SURFACE1_BF_OFFSET_LSB 0x248
114 #define TEGRA_VI_CSI_1_SURFACE2_BF_OFFSET_MSB 0x24c
115 #define TEGRA_VI_CSI_1_SURFACE2_BF_OFFSET_LSB 0x250
116 #define TEGRA_VI_CSI_1_SURFACE0_STRIDE 0x254
117 #define TEGRA_VI_CSI_1_SURFACE1_STRIDE 0x258
118 #define TEGRA_VI_CSI_1_SURFACE2_STRIDE 0x25c
119 #define TEGRA_VI_CSI_1_SURFACE_HEIGHT0 0x260
120 #define TEGRA_VI_CSI_1_ISPINTF_CONFIG 0x264
121 #define TEGRA_VI_CSI_1_ERROR_STATUS 0x284
122 #define TEGRA_VI_CSI_1_ERROR_INT_MASK 0x288
123 #define TEGRA_VI_CSI_1_WD_CTRL 0x28c
124 #define TEGRA_VI_CSI_1_WD_PERIOD 0x290
126 #define TEGRA_CSI_CSI_CAP_CIL 0x808
127 #define TEGRA_CSI_CSI_CAP_CSI 0x818
128 #define TEGRA_CSI_CSI_CAP_PP 0x828
129 #define TEGRA_CSI_INPUT_STREAM_A_CONTROL 0x838
130 #define TEGRA_CSI_PIXEL_STREAM_A_CONTROL0 0x83c
131 #define TEGRA_CSI_PIXEL_STREAM_A_CONTROL1 0x840
132 #define TEGRA_CSI_PIXEL_STREAM_A_GAP 0x844
133 #define TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND 0x848
134 #define TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME 0x84c
135 #define TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK 0x850
136 #define TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x854
137 #define TEGRA_CSI_CSI_SW_SENSOR_A_RESET 0x858
138 #define TEGRA_CSI_INPUT_STREAM_B_CONTROL 0x86c
139 #define TEGRA_CSI_PIXEL_STREAM_B_CONTROL0 0x870
140 #define TEGRA_CSI_PIXEL_STREAM_B_CONTROL1 0x874
141 #define TEGRA_CSI_PIXEL_STREAM_B_GAP 0x878
142 #define TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND 0x87c
143 #define TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME 0x880
144 #define TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK 0x884
145 #define TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x888
146 #define TEGRA_CSI_CSI_SW_SENSOR_B_RESET 0x88c
147 #define TEGRA_CSI_PHY_CIL_COMMAND 0x908
148 #define TEGRA_CSI_CIL_PAD_CONFIG0 0x90c
150 #define TEGRA_CSI_CILA_PAD_CONFIG0 0x92c
151 #define TEGRA_CSI_CILA_PAD_CONFIG1 0x930
152 #define TEGRA_CSI_PHY_CILA_CONTROL0 0x934
153 #define TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK 0x938
154 #define TEGRA_CSI_CSI_CIL_A_STATUS 0x93c
155 #define TEGRA_CSI_CSI_CILA_STATUS 0x940
156 #define TEGRA_CSI_CIL_A_ESCAPE_MODE_COMMAND 0x944
157 #define TEGRA_CSI_CIL_A_ESCAPE_MODE_DATA 0x948
158 #define TEGRA_CSI_CSICIL_SW_SENSOR_A_RESET 0x94c
160 #define TEGRA_CSI_CILB_PAD_CONFIG0 0x960
161 #define TEGRA_CSI_CILB_PAD_CONFIG1 0x964
162 #define TEGRA_CSI_PHY_CILB_CONTROL0 0x968
163 #define TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK 0x96c
164 #define TEGRA_CSI_CSI_CIL_B_STATUS 0x970
165 #define TEGRA_CSI_CSI_CILB_STATUS 0x974
166 #define TEGRA_CSI_CIL_B_ESCAPE_MODE_COMMAND 0x978
167 #define TEGRA_CSI_CIL_B_ESCAPE_MODE_DATA 0x97c
168 #define TEGRA_CSI_CSICIL_SW_SENSOR_B_RESET 0x980
170 #define TEGRA_CSI_CILC_PAD_CONFIG0 0x994
171 #define TEGRA_CSI_CILC_PAD_CONFIG1 0x998
172 #define TEGRA_CSI_PHY_CILC_CONTROL0 0x99c
173 #define TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK 0x9a0
174 #define TEGRA_CSI_CSI_CIL_C_STATUS 0x9a4
175 #define TEGRA_CSI_CSI_CILC_STATUS 0x9a8
176 #define TEGRA_CSI_CIL_C_ESCAPE_MODE_COMMAND 0x9ac
177 #define TEGRA_CSI_CIL_C_ESCAPE_MODE_DATA 0x9b0
178 #define TEGRA_CSI_CSICIL_SW_SENSOR_C_RESET 0x9b4
180 #define TEGRA_CSI_CILD_PAD_CONFIG0 0x9c8
181 #define TEGRA_CSI_CILD_PAD_CONFIG1 0x9cc
182 #define TEGRA_CSI_PHY_CILD_CONTROL0 0x9d0
183 #define TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK 0x9d4
184 #define TEGRA_CSI_CSI_CIL_D_STATUS 0x9d8
185 #define TEGRA_CSI_CSI_CILD_STATUS 0x9dc
186 #define TEGRA_CSI_CIL_D_ESCAPE_MODE_COMMAND 0x9ec
187 #define TEGRA_CSI_CIL_D_ESCAPE_MODE_DATA 0x9f0
188 #define TEGRA_CSI_CSICIL_SW_SENSOR_D_RESET 0x9f4
190 #define TEGRA_CSI_CILE_PAD_CONFIG0 0xa08
191 #define TEGRA_CSI_CILE_PAD_CONFIG1 0xa0c
192 #define TEGRA_CSI_PHY_CILE_CONTROL0 0xa10
193 #define TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK 0xa14
194 #define TEGRA_CSI_CSI_CIL_E_STATUS 0xa18
195 #define TEGRA_CSI_CIL_E_ESCAPE_MODE_COMMAND 0xa1c
196 #define TEGRA_CSI_CIL_E_ESCAPE_MODE_DATA 0xa20
197 #define TEGRA_CSI_CSICIL_SW_SENSOR_E_RESET 0xa24
199 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL_A 0xa68
200 #define TEGRA_CSI_PG_BLANK_A 0xa6c
201 #define TEGRA_CSI_PG_PHASE_A 0xa70
202 #define TEGRA_CSI_PG_RED_FREQ_A 0xa74
203 #define TEGRA_CSI_PG_RED_FREQ_RATE_A 0xa78
204 #define TEGRA_CSI_PG_GREEN_FREQ_A 0xa7c
205 #define TEGRA_CSI_PG_GREEN_FREQ_RATE_A 0xa80
206 #define TEGRA_CSI_PG_BLUE_FREQ_A 0xa84
207 #define TEGRA_CSI_PG_BLUE_FREQ_RATE_A 0xa88
209 #define TEGRA_CSI_PATTERN_GENERATOR_CTRL_B 0xa9c
210 #define TEGRA_CSI_PG_BLANK_B 0xaa0
211 #define TEGRA_CSI_PG_PHASE_B 0xaa4
212 #define TEGRA_CSI_PG_RED_FREQ_B 0xaa8
213 #define TEGRA_CSI_PG_RED_FREQ_RATE_B 0xaac
214 #define TEGRA_CSI_PG_GREEN_FREQ_B 0xab0
215 #define TEGRA_CSI_PG_GREEN_FREQ_RATE_B 0xab4
216 #define TEGRA_CSI_PG_BLUE_FREQ_B 0xab8
217 #define TEGRA_CSI_PG_BLUE_FREQ_RATE_B 0xabc
219 #define TEGRA_CSI_DPCM_CTRL_A 0xad0
220 #define TEGRA_CSI_DPCM_CTRL_B 0xad4
221 #define TEGRA_CSI_STALL_COUNTER 0xae8
222 #define TEGRA_CSI_CSI_READONLY_STATUS 0xaec
223 #define TEGRA_CSI_CSI_SW_STATUS_RESET 0xaf0
224 #define TEGRA_CSI_CLKEN_OVERRIDE 0xaf4
225 #define TEGRA_CSI_DEBUG_CONTROL 0xaf8
226 #define TEGRA_CSI_DEBUG_COUNTER_0 0xafc
227 #define TEGRA_CSI_DEBUG_COUNTER_1 0xb00
228 #define TEGRA_CSI_DEBUG_COUNTER_2 0xb04
230 /* These go into the TEGRA_VI_CSI_n_IMAGE_DEF registers bits 23:16 */
231 #define TEGRA_IMAGE_FORMAT_T_L8 16
232 #define TEGRA_IMAGE_FORMAT_T_R16_I 32
233 #define TEGRA_IMAGE_FORMAT_T_B5G6R5 33
234 #define TEGRA_IMAGE_FORMAT_T_R5G6B5 34
235 #define TEGRA_IMAGE_FORMAT_T_A1B5G5R5 35
236 #define TEGRA_IMAGE_FORMAT_T_A1R5G5B5 36
237 #define TEGRA_IMAGE_FORMAT_T_B5G5R5A1 37
238 #define TEGRA_IMAGE_FORMAT_T_R5G5B5A1 38
239 #define TEGRA_IMAGE_FORMAT_T_A4B4G4R4 39
240 #define TEGRA_IMAGE_FORMAT_T_A4R4G4B4 40
241 #define TEGRA_IMAGE_FORMAT_T_B4G4R4A4 41
242 #define TEGRA_IMAGE_FORMAT_T_R4G4B4A4 42
243 #define TEGRA_IMAGE_FORMAT_T_A8B8G8R8 64
244 #define TEGRA_IMAGE_FORMAT_T_A8R8G8B8 65
245 #define TEGRA_IMAGE_FORMAT_T_B8G8R8A8 66
246 #define TEGRA_IMAGE_FORMAT_T_R8G8B8A8 67
247 #define TEGRA_IMAGE_FORMAT_T_A2B10G10R10 68
248 #define TEGRA_IMAGE_FORMAT_T_A2R10G10B10 69
249 #define TEGRA_IMAGE_FORMAT_T_B10G10R10A2 70
250 #define TEGRA_IMAGE_FORMAT_T_R10G10B10A2 71
251 #define TEGRA_IMAGE_FORMAT_T_A8Y8U8V8 193
252 #define TEGRA_IMAGE_FORMAT_T_V8U8Y8A8 194
253 #define TEGRA_IMAGE_FORMAT_T_A2Y10U10V10 197
254 #define TEGRA_IMAGE_FORMAT_T_V10U10Y10A2 198
255 #define TEGRA_IMAGE_FORMAT_T_Y8_U8__Y8_V8 200
256 #define TEGRA_IMAGE_FORMAT_T_Y8_V8__Y8_U8 201
257 #define TEGRA_IMAGE_FORMAT_T_U8_Y8__V8_Y8 202
258 #define TEGRA_IMAGE_FORMAT_T_T_V8_Y8__U8_Y8 203
259 #define TEGRA_IMAGE_FORMAT_T_T_Y8__U8__V8_N444 224
260 #define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N444 225
261 #define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N444 226
262 #define TEGRA_IMAGE_FORMAT_T_Y8__U8__V8_N422 227
263 #define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N422 228
264 #define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N422 229
265 #define TEGRA_IMAGE_FORMAT_T_Y8__U8__V8_N420 230
266 #define TEGRA_IMAGE_FORMAT_T_Y8__U8V8_N420 231
267 #define TEGRA_IMAGE_FORMAT_T_Y8__V8U8_N420 232
268 #define TEGRA_IMAGE_FORMAT_T_X2Lc10Lb10La10 233
269 #define TEGRA_IMAGE_FORMAT_T_A2R6R6R6R6R6 234
271 /* These go into the TEGRA_VI_CSI_n_CSI_IMAGE_DT registers bits 7:0 */
272 #define TEGRA_IMAGE_DT_YUV420_8 24
273 #define TEGRA_IMAGE_DT_YUV420_10 25
274 #define TEGRA_IMAGE_DT_YUV420CSPS_8 28
275 #define TEGRA_IMAGE_DT_YUV420CSPS_10 29
276 #define TEGRA_IMAGE_DT_YUV422_8 30
277 #define TEGRA_IMAGE_DT_YUV422_10 31
278 #define TEGRA_IMAGE_DT_RGB444 32
279 #define TEGRA_IMAGE_DT_RGB555 33
280 #define TEGRA_IMAGE_DT_RGB565 34
281 #define TEGRA_IMAGE_DT_RGB666 35
282 #define TEGRA_IMAGE_DT_RGB888 36
283 #define TEGRA_IMAGE_DT_RAW6 40
284 #define TEGRA_IMAGE_DT_RAW7 41
285 #define TEGRA_IMAGE_DT_RAW8 42
286 #define TEGRA_IMAGE_DT_RAW10 43
287 #define TEGRA_IMAGE_DT_RAW12 44
288 #define TEGRA_IMAGE_DT_RAW14 45
290 #define MIPI_CAL_CTRL 0x00
291 #define STARTCAL (1 << 0)
292 #define CLKEN_OVR (1 << 4)
293 #define MIPI_CAL_AUTOCAL_CTRL0 0x04
294 #define CIL_MIPI_CAL_STATUS 0x08
295 #define CAL_DONE (1 << 16)
296 #define CIL_MIPI_CAL_STATUS_2 0x0c
297 #define CILA_MIPI_CAL_CONFIG 0x14
298 #define SELA (1 << 21)
299 #define CILB_MIPI_CAL_CONFIG 0x18
300 #define SELB (1 << 21)
301 #define CILC_MIPI_CAL_CONFIG 0x1c
302 #define SELC (1 << 21)
303 #define CILD_MIPI_CAL_CONFIG 0x20
304 #define SELD (1 << 21)
305 #define CILE_MIPI_CAL_CONFIG 0x24
306 #define SELE (1 << 21)
307 #define DSIA_MIPI_CAL_CONFIG 0x38
308 #define SELDSIA (1 << 21)
309 #define DSIB_MIPI_CAL_CONFIG 0x3c
310 #define SELDSIB (1 << 21)
311 #define MIPI_BIAS_PAD_CFG0 0x58
312 #define E_VCLAMP_REF (1 << 0)
313 #define MIPI_BIAS_PAD_CFG1 0x5c
314 #define MIPI_BIAS_PAD_CFG2 0x60
315 #define PDVREG (1 << 1)
316 #define DSIA_MIPI_CAL_CONFIG_2 0x64
317 #define CLKSELDSIA (1 << 21)
318 #define DSIB_MIPI_CAL_CONFIG_2 0x68
319 #define CLKSELDSIB (1 << 21)
320 #define CILC_MIPI_CAL_CONFIG_2 0x6c
321 #define CLKSELC (1 << 21)
322 #define CILD_MIPI_CAL_CONFIG_2 0x70
323 #define CLKSELD (1 << 21)
324 #define CSIE_MIPI_CAL_CONFIG_2 0x74
325 #define CLKSELE (1 << 21)
327 #define MIPI_CAL_BASE 0x700e3000
329 static const struct regmap_config mipi_cal_config = {
333 .cache_type = REGCACHE_RBTREE,
336 static int vi2_port_is_valid(int port)
338 return (((port) >= TEGRA_CAMERA_PORT_CSI_A) &&
339 ((port) <= TEGRA_CAMERA_PORT_CSI_C));
342 /* Clock settings for camera */
343 static struct tegra_camera_clk vi2_clks0[] = {
380 /* Always put "p11_d" at the end */
387 static struct tegra_camera_clk vi2_clks1[] = {
394 .name = "vi_sensor2",
424 /* Always put "p11_d" at the end */
431 #define MAX_DEVID_LENGTH 16
433 static int vi2_clks_init(struct tegra_camera_dev *cam, int port)
435 struct platform_device *pdev = cam->ndev;
436 struct tegra_camera_clk *clks;
440 case TEGRA_CAMERA_PORT_CSI_A:
441 cam->num_clks = ARRAY_SIZE(vi2_clks0);
442 cam->clks = vi2_clks0;
444 case TEGRA_CAMERA_PORT_CSI_B:
445 case TEGRA_CAMERA_PORT_CSI_C:
446 cam->num_clks = ARRAY_SIZE(vi2_clks1);
447 cam->clks = vi2_clks1;
450 dev_err(&pdev->dev, "Wrong port number %d\n", port);
454 for (i = 0; i < cam->num_clks; i++) {
455 clks = &cam->clks[i];
457 if (clks->use_devname) {
458 char devname[MAX_DEVID_LENGTH];
459 snprintf(devname, MAX_DEVID_LENGTH,
460 "tegra_%s", dev_name(&pdev->dev));
461 clks->clk = clk_get_sys(devname, clks->name);
463 clks->clk = clk_get(&pdev->dev, clks->name);
464 if (IS_ERR_OR_NULL(clks->clk)) {
465 dev_err(&pdev->dev, "Failed to get clock %s.\n",
467 return PTR_ERR(clks->clk);
474 static void vi2_clks_deinit(struct tegra_camera_dev *cam)
476 struct tegra_camera_clk *clks;
479 for (i = 0; i < cam->num_clks; i++) {
480 clks = &cam->clks[i];
486 static void vi2_clks_enable(struct tegra_camera_dev *cam)
488 struct tegra_camera_clk *clks;
491 for (i = 0; i < cam->num_clks - 1; i++) {
492 clks = &cam->clks[i];
494 clk_prepare_enable(clks->clk);
496 clk_set_rate(clks->clk, clks->freq);
500 clks = &cam->clks[i];
502 clk_prepare_enable(clks->clk);
504 clk_set_rate(clks->clk, clks->freq);
505 tegra_clk_cfg_ex(clks->clk,
506 TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
507 tegra_clk_cfg_ex(clks->clk,
508 TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
509 tegra_clk_cfg_ex(clks->clk,
510 TEGRA_CLK_MIPI_CSI_OUT_ENB, 0);
515 static void vi2_clks_disable(struct tegra_camera_dev *cam)
517 struct tegra_camera_clk *clks;
520 for (i = 0; i < cam->num_clks - 1; i++) {
521 clks = &cam->clks[i];
523 clk_disable_unprepare(clks->clk);
527 clks = &cam->clks[i];
529 tegra_clk_cfg_ex(clks->clk,
530 TEGRA_CLK_MIPI_CSI_OUT_ENB, 1);
531 tegra_clk_cfg_ex(clks->clk,
532 TEGRA_CLK_PLLD_CSI_OUT_ENB, 0);
533 tegra_clk_cfg_ex(clks->clk,
534 TEGRA_CLK_PLLD_DSI_OUT_ENB, 0);
535 clk_disable_unprepare(clks->clk);
540 static void vi2_init_syncpts(struct tegra_camera_dev *cam)
542 cam->syncpt_id_csi_a = nvhost_get_syncpt_client_managed("vi_csi_A");
544 cam->syncpt_id_csi_b = nvhost_get_syncpt_client_managed("vi_csi_B");
547 static void vi2_free_syncpts(struct tegra_camera_dev *cam)
549 nvhost_free_syncpt(cam->syncpt_id_csi_a);
551 nvhost_free_syncpt(cam->syncpt_id_csi_b);
554 static void vi2_incr_syncpts(struct tegra_camera_dev *cam)
559 static void vi2_capture_clean(struct tegra_camera_dev *cam)
561 /* Clean up status */
562 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_STATUS, 0xFFFFFFFF);
563 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_STATUS, 0xFFFFFFFF);
564 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_STATUS, 0xFFFFFFFF);
565 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_STATUS, 0xFFFFFFFF);
566 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_STATUS, 0xFFFFFFFF);
567 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILA_STATUS, 0xFFFFFFFF);
568 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILB_STATUS, 0xFFFFFFFF);
569 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILC_STATUS, 0xFFFFFFFF);
570 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CILD_STATUS, 0xFFFFFFFF);
571 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS, 0xFFFFFFFF);
572 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS, 0xFFFFFFFF);
573 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_ERROR_STATUS, 0xFFFFFFFF);
574 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_ERROR_STATUS, 0xFFFFFFFF);
577 static int vi2_capture_setup_csi_0(struct tegra_camera_dev *cam,
578 struct soc_camera_device *icd)
580 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
581 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
582 int format = 0, data_type = 0, image_size = 0;
586 * PAD_CILA_PDVCLAMP 0, PAD_CILA_PDIO_CLK 0,
587 * PAD_CILA_PDIO 0, PAD_AB_BK_MODE 1
589 TC_VI_REG_WT(cam, TEGRA_CSI_CILA_PAD_CONFIG0, 0x10000);
591 /* PAD_CILB_PDVCLAMP 0, PAD_CILB_PDIO_CLK 0, PAD_CILB_PDIO 0 */
592 TC_VI_REG_WT(cam, TEGRA_CSI_CILB_PAD_CONFIG0, 0x0);
594 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_A_INTERRUPT_MASK, 0x0);
595 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_B_INTERRUPT_MASK, 0x0);
598 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
599 0x3 | (0x1 << 5) | (0x40 << 8));
602 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILA_CONTROL0, 0x9);
603 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILB_CONTROL0, 0x9);
604 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
605 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_INTERRUPT_MASK, 0x0);
606 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL0, 0x280301f0);
607 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf007);
608 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_CONTROL1, 0x11);
609 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_GAP, 0x140000);
610 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_A_EXPECTED_FRAME, 0x0);
612 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_A_CONTROL,
613 0x3f0000 | (pdata->lanes - 1));
615 /* Shared register */
616 val = TC_VI_REG_RD(cam, TEGRA_CSI_PHY_CIL_COMMAND);
617 if (pdata->lanes == 4)
618 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
619 (val & 0xFFFF0000) | 0x0101);
621 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
622 (val & 0xFFFF0000) | 0x0201);
625 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_A,
626 ((cam->tpg_mode - 1) << 2) | 0x1);
627 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_A, 0x0);
628 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_A, 0x100010);
629 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_A, 0x0);
630 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_A, 0x100010);
631 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_A, 0x0);
632 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_A, 0x100010);
633 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_A, 0x0);
634 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
636 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
637 data_type = TEGRA_IMAGE_DT_RGB888;
638 image_size = icd->user_width * 3;
639 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
640 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
641 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
642 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
644 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
645 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
646 format = TEGRA_IMAGE_FORMAT_T_L8;
647 data_type = TEGRA_IMAGE_DT_RAW8;
648 image_size = icd->user_width;
649 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
650 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
651 format = TEGRA_IMAGE_FORMAT_T_R16_I;
652 data_type = TEGRA_IMAGE_DT_RAW10;
653 image_size = (icd->user_width * 10) >> 3;
656 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_IMAGE_DEF,
657 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
659 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_DT, data_type);
661 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE_WC, image_size);
663 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_CSI_IMAGE_SIZE,
664 (icd->user_height << 16) | icd->user_width);
669 static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam,
670 struct soc_camera_device *icd)
672 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
673 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
674 int format = 0, data_type = 0, image_size = 0;
678 * PAD_CILC_PDVCLAMP 0, PAD_CILC_PDIO_CLK 0,
679 * PAD_CILC_PDIO 0, PAD_CD_BK_MODE 1
681 TC_VI_REG_WT(cam, TEGRA_CSI_CILC_PAD_CONFIG0, 0x10000);
683 /* PAD_CILD_PDVCLAMP 0, PAD_CILD_PDIO_CLK 0, PAD_CILD_PDIO 0 */
684 TC_VI_REG_WT(cam, TEGRA_CSI_CILD_PAD_CONFIG0, 0x0);
686 /* PAD_CILE_PDVCLAMP 0, PAD_CILE_PDIO_CLK 0, PAD_CILE_PDIO 0 */
687 TC_VI_REG_WT(cam, TEGRA_CSI_CILE_PAD_CONFIG0, 0x0);
689 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_C_INTERRUPT_MASK, 0x0);
690 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_D_INTERRUPT_MASK, 0x0);
691 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_CIL_E_INTERRUPT_MASK, 0x0);
694 TC_VI_REG_WT(cam, TEGRA_CSI_DEBUG_CONTROL,
695 0x5 | (0x1 << 5) | (0x50 << 8));
698 if (pdata->port == TEGRA_CAMERA_PORT_CSI_B) {
699 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILC_CONTROL0, 0x9);
700 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILD_CONTROL0, 0x9);
701 } else if (pdata->port == TEGRA_CAMERA_PORT_CSI_C)
702 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CILE_CONTROL0, 0x9);
704 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
705 TC_VI_REG_WT(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_INTERRUPT_MASK, 0x0);
706 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL0, 0x280301f1);
707 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf007);
708 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_CONTROL1, 0x11);
709 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_GAP, 0x140000);
710 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_B_EXPECTED_FRAME, 0x0);
712 TC_VI_REG_WT(cam, TEGRA_CSI_INPUT_STREAM_B_CONTROL,
713 0x3f0000 | (pdata->lanes - 1));
715 /* Shared register */
716 val = TC_VI_REG_RD(cam, TEGRA_CSI_PHY_CIL_COMMAND);
717 if (pdata->lanes == 4)
718 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
719 (val & 0x0000FFFF) | 0x21010000);
720 else if (pdata->lanes == 1 && pdata->port == TEGRA_CAMERA_PORT_CSI_C)
721 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
722 (val & 0x0000FFFF) | 0x12020000);
724 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND,
725 (val & 0x0000FFFF) | 0x22010000);
728 TC_VI_REG_WT(cam, TEGRA_CSI_PATTERN_GENERATOR_CTRL_B,
729 ((cam->tpg_mode - 1) << 2) | 0x1);
730 TC_VI_REG_WT(cam, TEGRA_CSI_PG_PHASE_B, 0x0);
731 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_B, 0x100010);
732 TC_VI_REG_WT(cam, TEGRA_CSI_PG_RED_FREQ_RATE_B, 0x0);
733 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_B, 0x100010);
734 TC_VI_REG_WT(cam, TEGRA_CSI_PG_GREEN_FREQ_RATE_B, 0x0);
735 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_B, 0x100010);
736 TC_VI_REG_WT(cam, TEGRA_CSI_PG_BLUE_FREQ_RATE_B, 0x0);
737 TC_VI_REG_WT(cam, TEGRA_CSI_PHY_CIL_COMMAND, 0x22020202);
739 format = TEGRA_IMAGE_FORMAT_T_A8B8G8R8;
740 data_type = TEGRA_IMAGE_DT_RGB888;
741 image_size = icd->user_width * 3;
742 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) ||
743 (icd->current_fmt->code == V4L2_MBUS_FMT_VYUY8_2X8) ||
744 (icd->current_fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) ||
745 (icd->current_fmt->code == V4L2_MBUS_FMT_YVYU8_2X8)) {
747 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8) ||
748 (icd->current_fmt->code == V4L2_MBUS_FMT_SGBRG8_1X8)) {
749 format = TEGRA_IMAGE_FORMAT_T_L8;
750 data_type = TEGRA_IMAGE_DT_RAW8;
751 image_size = icd->user_width;
752 } else if ((icd->current_fmt->code == V4L2_MBUS_FMT_SBGGR10_1X10) ||
753 (icd->current_fmt->code == V4L2_MBUS_FMT_SRGGB10_1X10)) {
754 format = TEGRA_IMAGE_FORMAT_T_R16_I;
755 data_type = TEGRA_IMAGE_DT_RAW10;
756 image_size = icd->user_width * 10 / 8;
759 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_IMAGE_DEF,
760 (cam->tpg_mode ? 0 : 1 << 24) | (format << 16) | 0x1);
762 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_DT, data_type);
764 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE_WC, image_size);
766 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_CSI_IMAGE_SIZE,
767 (icd->user_height << 16) | icd->user_width);
772 static int vi2_capture_setup(struct tegra_camera_dev *cam)
774 struct vb2_buffer *vb = cam->active;
775 struct tegra_camera_buffer *buf = to_tegra_vb(vb);
776 struct soc_camera_device *icd = buf->icd;
777 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
778 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
779 int port = pdata->port;
781 /* Skip VI2/CSI2 setup for second and later frame capture */
785 /* Setup registers for CSI-A and CSI-B inputs */
786 if (port == TEGRA_CAMERA_PORT_CSI_A)
787 return vi2_capture_setup_csi_0(cam, icd);
788 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
789 port == TEGRA_CAMERA_PORT_CSI_C)
790 return vi2_capture_setup_csi_1(cam, icd);
795 static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
796 struct tegra_camera_buffer *buf)
798 struct soc_camera_device *icd = buf->icd;
799 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
800 icd->current_fmt->host_fmt);
801 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
802 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
803 int port = pdata->port;
805 switch (icd->current_fmt->host_fmt->fourcc) {
806 case V4L2_PIX_FMT_YUV420:
807 case V4L2_PIX_FMT_YVU420:
808 /* FIXME: Setup YUV buffer */
810 case V4L2_PIX_FMT_UYVY:
811 case V4L2_PIX_FMT_VYUY:
812 case V4L2_PIX_FMT_YUYV:
813 case V4L2_PIX_FMT_YVYU:
814 case V4L2_PIX_FMT_SBGGR8:
815 case V4L2_PIX_FMT_SGBRG8:
816 case V4L2_PIX_FMT_SBGGR10:
817 case V4L2_PIX_FMT_SRGGB10:
818 case V4L2_PIX_FMT_RGB32:
819 if (port == TEGRA_CAMERA_PORT_CSI_A) {
820 switch (buf->output_channel) {
823 TEGRA_VI_CSI_0_SURFACE0_OFFSET_MSB,
826 TEGRA_VI_CSI_0_SURFACE0_OFFSET_LSB,
829 TEGRA_VI_CSI_0_SURFACE0_STRIDE,
834 TEGRA_VI_CSI_0_SURFACE1_OFFSET_MSB,
837 TEGRA_VI_CSI_0_SURFACE1_OFFSET_LSB,
840 TEGRA_VI_CSI_0_SURFACE1_STRIDE,
845 TEGRA_VI_CSI_0_SURFACE2_OFFSET_MSB,
848 TEGRA_VI_CSI_0_SURFACE2_OFFSET_LSB,
851 TEGRA_VI_CSI_0_SURFACE2_STRIDE,
855 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
856 port == TEGRA_CAMERA_PORT_CSI_C) {
857 switch (buf->output_channel) {
860 TEGRA_VI_CSI_1_SURFACE0_OFFSET_MSB,
863 TEGRA_VI_CSI_1_SURFACE0_OFFSET_LSB,
866 TEGRA_VI_CSI_1_SURFACE0_STRIDE,
871 TEGRA_VI_CSI_1_SURFACE1_OFFSET_MSB,
874 TEGRA_VI_CSI_1_SURFACE1_OFFSET_LSB,
877 TEGRA_VI_CSI_1_SURFACE1_STRIDE,
882 TEGRA_VI_CSI_1_SURFACE2_OFFSET_MSB,
885 TEGRA_VI_CSI_1_SURFACE2_OFFSET_LSB,
888 TEGRA_VI_CSI_1_SURFACE2_STRIDE,
896 dev_err(&cam->ndev->dev, "Wrong host format %d\n",
897 icd->current_fmt->host_fmt->fourcc);
904 static void vi2_capture_error_status(struct tegra_camera_dev *cam)
909 val = TC_VI_REG_RD(cam, TEGRA_CSI_DEBUG_COUNTER_0);
910 pr_err("TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val);
912 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_A_STATUS);
913 pr_err("TEGRA_CSI_CSI_CIL_A_STATUS 0x%08x\n", val);
914 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CILA_STATUS);
915 pr_err("TEGRA_CSI_CSI_CILA_STATUS 0x%08x\n", val);
916 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_B_STATUS);
917 pr_err("TEGRA_CSI_CSI_CIL_B_STATUS 0x%08x\n", val);
918 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_C_STATUS);
919 pr_err("TEGRA_CSI_CSI_CIL_C_STATUS 0x%08x\n", val);
920 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_D_STATUS);
921 pr_err("TEGRA_CSI_CSI_CIL_D_STATUS 0x%08x\n", val);
922 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_CIL_E_STATUS);
923 pr_err("TEGRA_CSI_CSI_CIL_E_STATUS 0x%08x\n", val);
924 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS);
925 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_A_STATUS 0x%08x\n", val);
926 val = TC_VI_REG_RD(cam, TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS);
927 pr_err("TEGRA_CSI_CSI_PIXEL_PARSER_B_STATUS 0x%08x\n", val);
928 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_0_ERROR_STATUS);
929 pr_err("TEGRA_VI_CSI_0_ERROR_STATUS 0x%08x\n", val);
930 val = TC_VI_REG_RD(cam, TEGRA_VI_CSI_1_ERROR_STATUS);
931 pr_err("TEGRA_VI_CSI_1_ERROR_STATUS 0x%08x\n", val);
934 static int vi2_capture_start(struct tegra_camera_dev *cam,
935 struct tegra_camera_buffer *buf)
937 struct soc_camera_device *icd = buf->icd;
938 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
939 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
940 int port = pdata->port;
944 err = vi2_capture_buffer_setup(cam, buf);
948 /* Only wait on CSI frame end syncpt if we're using CSI. */
949 if (port == TEGRA_CAMERA_PORT_CSI_A) {
950 if (!nvhost_syncpt_read_ext_check(cam->ndev,
951 cam->syncpt_id_csi_a, &val))
952 cam->syncpt_csi_a = nvhost_syncpt_incr_max_ext(
954 cam->syncpt_id_csi_a, 1);
956 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
957 (6 << 8) | cam->syncpt_id_csi_a);
958 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
960 TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1);
961 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
962 cam->syncpt_id_csi_a,
964 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
967 } else if (port == TEGRA_CAMERA_PORT_CSI_B ||
968 port == TEGRA_CAMERA_PORT_CSI_C) {
969 if (!nvhost_syncpt_read_ext_check(cam->ndev,
970 cam->syncpt_id_csi_b, &val))
971 cam->syncpt_csi_b = nvhost_syncpt_incr_max_ext(
973 cam->syncpt_id_csi_b, 1);
975 TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT,
976 (7 << 8) | cam->syncpt_id_csi_b);
977 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
979 TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1);
980 err = nvhost_syncpt_wait_timeout_ext(cam->ndev,
981 cam->syncpt_id_csi_b,
983 TEGRA_SYNCPT_CSI_WAIT_TIMEOUT,
988 /* Mark SOF flag to Zero after we captured the FIRST frame */
992 /* Capture syncpt timeout err, then dump error status */
994 if (port == TEGRA_CAMERA_PORT_CSI_A)
995 dev_err(&cam->ndev->dev,
996 "CSI_A syncpt timeout, syncpt = %d, err = %d\n",
997 cam->syncpt_csi_a, err);
998 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
999 port == TEGRA_CAMERA_PORT_CSI_C)
1000 dev_err(&cam->ndev->dev,
1001 "CSI_B/CSI_C syncpt timeout, syncpt = %d, err = %d\n",
1002 cam->syncpt_csi_b, err);
1003 vi2_capture_error_status(cam);
1009 static int vi2_capture_stop(struct tegra_camera_dev *cam, int port)
1011 if (port == TEGRA_CAMERA_PORT_CSI_A)
1012 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND,
1014 else if (port == TEGRA_CAMERA_PORT_CSI_B ||
1015 port == TEGRA_CAMERA_PORT_CSI_C)
1016 TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
1022 /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving */
1023 static void vi2_sw_reset(struct tegra_camera_dev *cam)
1025 /* T12_CG_2ND_LEVEL_EN */
1026 TC_VI_REG_WT(cam, TEGRA_VI_CFG_CG_CTRL, 1);
1028 TC_VI_REG_WT(cam, TEGRA_CSI_CLKEN_OVERRIDE, 0x0);
1035 static int vi2_mipi_calibration(struct tegra_camera_dev *cam)
1037 void __iomem *mipi_cal;
1038 struct regmap *regs;
1039 struct platform_device *pdev = cam->ndev;
1040 struct vb2_buffer *vb = cam->active;
1041 struct tegra_camera_buffer *buf = to_tegra_vb(vb);
1042 struct soc_camera_device *icd = buf->icd;
1043 struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
1044 struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
1045 int port = pdata->port;
1047 struct clk *clk_mipi_cal = NULL, *clk_72mhz = NULL;
1050 /* TPG mode doesn't need any calibration */
1054 /* Get clks for MIPI Calibration */
1055 clk_mipi_cal = clk_get_sys("mipi-cal", NULL);
1056 if (IS_ERR_OR_NULL(clk_mipi_cal)) {
1057 dev_err(&pdev->dev, "cannot get mipi-cal clk.\n");
1058 return PTR_ERR(clk_mipi_cal);
1061 clk_72mhz = clk_get_sys("clk72mhz", NULL);
1062 if (IS_ERR_OR_NULL(clk_72mhz)) {
1063 dev_err(&pdev->dev, "cannot get 72MHz clk.\n");
1064 return PTR_ERR(clk_72mhz);
1068 mipi_cal = ioremap(MIPI_CAL_BASE, 0x100);
1072 regs = devm_regmap_init_mmio(&pdev->dev, mipi_cal, &mipi_cal_config);
1074 dev_err(&pdev->dev, "regmap init failed\n");
1076 return PTR_ERR(regs);
1079 /* Enable MIPI Calibration clocks */
1081 clk_prepare_enable(clk_mipi_cal);
1083 clk_prepare_enable(clk_72mhz);
1085 /* MIPI_CAL_CLKEN_OVR = 1 */
1086 regmap_update_bits(regs, MIPI_CAL_CTRL, CLKEN_OVR, CLKEN_OVR);
1088 /* Clear MIPI CAL status flags */
1089 regmap_write(regs, CIL_MIPI_CAL_STATUS, 0xF1F10000);
1090 regmap_update_bits(regs, DSIA_MIPI_CAL_CONFIG, SELDSIA, 0);
1091 regmap_update_bits(regs, DSIB_MIPI_CAL_CONFIG, SELDSIB, 0);
1092 regmap_update_bits(regs, MIPI_BIAS_PAD_CFG0,
1093 E_VCLAMP_REF, E_VCLAMP_REF);
1094 regmap_update_bits(regs, MIPI_BIAS_PAD_CFG2, PDVREG, 0);
1095 regmap_update_bits(regs, CILA_MIPI_CAL_CONFIG, SELA, 0);
1096 regmap_update_bits(regs, DSIA_MIPI_CAL_CONFIG_2, CLKSELDSIA, 0);
1097 regmap_update_bits(regs, CILB_MIPI_CAL_CONFIG, SELB, 0);
1098 regmap_update_bits(regs, DSIB_MIPI_CAL_CONFIG_2, CLKSELDSIB, 0);
1099 regmap_update_bits(regs, CILC_MIPI_CAL_CONFIG, SELC, 0);
1100 regmap_update_bits(regs, CILC_MIPI_CAL_CONFIG_2, CLKSELC, 0);
1101 regmap_update_bits(regs, CILD_MIPI_CAL_CONFIG, SELD, 0);
1102 regmap_update_bits(regs, CILD_MIPI_CAL_CONFIG_2, CLKSELD, 0);
1103 regmap_update_bits(regs, CILE_MIPI_CAL_CONFIG, SELE, 0);
1104 regmap_update_bits(regs, CSIE_MIPI_CAL_CONFIG_2, CLKSELE, 0);
1106 /* Select the CIL pad for auto calibration */
1108 case TEGRA_CAMERA_PORT_CSI_A:
1109 regmap_update_bits(regs, CILA_MIPI_CAL_CONFIG, SELA, SELA);
1110 regmap_update_bits(regs, DSIA_MIPI_CAL_CONFIG_2, CLKSELDSIA, 0);
1111 if (pdata->lanes > 2) {
1112 regmap_update_bits(regs, CILB_MIPI_CAL_CONFIG,
1114 regmap_update_bits(regs, DSIB_MIPI_CAL_CONFIG_2,
1118 case TEGRA_CAMERA_PORT_CSI_B:
1119 regmap_update_bits(regs, CILC_MIPI_CAL_CONFIG, SELC, SELC);
1120 regmap_update_bits(regs, CILC_MIPI_CAL_CONFIG_2, CLKSELC, 0);
1121 if (pdata->lanes > 2) {
1122 regmap_update_bits(regs, CILD_MIPI_CAL_CONFIG,
1124 regmap_update_bits(regs, CILD_MIPI_CAL_CONFIG_2,
1128 case TEGRA_CAMERA_PORT_CSI_C:
1129 regmap_update_bits(regs, CILE_MIPI_CAL_CONFIG, SELE, SELE);
1130 regmap_update_bits(regs, CSIE_MIPI_CAL_CONFIG_2,
1134 dev_err(&pdev->dev, "wrong port %d\n", port);
1137 /* Trigger calibration */
1138 regmap_update_bits(regs, MIPI_CAL_CTRL, STARTCAL, STARTCAL);
1140 regmap_read(regs, CIL_MIPI_CAL_STATUS, &val);
1143 usleep_range(200, 300);
1146 /* Cleanup: un-select to avoid interference with DSI */
1147 regmap_update_bits(regs, CILA_MIPI_CAL_CONFIG, SELA, 0);
1148 regmap_update_bits(regs, DSIA_MIPI_CAL_CONFIG_2,
1149 CLKSELDSIA, CLKSELDSIA);
1150 regmap_update_bits(regs, CILB_MIPI_CAL_CONFIG, SELB, 0);
1151 regmap_update_bits(regs, DSIB_MIPI_CAL_CONFIG_2,
1152 CLKSELDSIB, CLKSELDSIB);
1153 regmap_update_bits(regs, CILC_MIPI_CAL_CONFIG, SELC, 0);
1154 regmap_update_bits(regs, CILC_MIPI_CAL_CONFIG_2, CLKSELC, CLKSELC);
1155 regmap_update_bits(regs, CILD_MIPI_CAL_CONFIG, SELD, 0);
1156 regmap_update_bits(regs, CILD_MIPI_CAL_CONFIG_2, CLKSELD, CLKSELD);
1157 regmap_update_bits(regs, CILE_MIPI_CAL_CONFIG, SELE, 0);
1158 regmap_update_bits(regs, CSIE_MIPI_CAL_CONFIG_2, CLKSELE, 0);
1160 /* Disable clocks */
1162 clk_disable_unprepare(clk_mipi_cal);
1164 clk_disable_unprepare(clk_72mhz);
1167 dev_err(&pdev->dev, "MIPI calibration timeout!\n");
1171 dev_info(&pdev->dev, "MIPI calibration for CSI is done\n");
1175 struct tegra_camera_ops vi2_ops = {
1176 .clks_init = vi2_clks_init,
1177 .clks_deinit = vi2_clks_deinit,
1178 .clks_enable = vi2_clks_enable,
1179 .clks_disable = vi2_clks_disable,
1181 .capture_clean = vi2_capture_clean,
1182 .capture_setup = vi2_capture_setup,
1183 .capture_start = vi2_capture_start,
1184 .capture_stop = vi2_capture_stop,
1186 .activate = vi2_sw_reset,
1188 .init_syncpts = vi2_init_syncpts,
1189 .free_syncpts = vi2_free_syncpts,
1190 .incr_syncpts = vi2_incr_syncpts,
1192 .port_is_valid = vi2_port_is_valid,
1194 .mipi_calibration = vi2_mipi_calibration,
1197 int vi2_register(struct tegra_camera_dev *cam)
1199 /* Init regulator */
1200 cam->regulator_name = "avdd_dsi_csi";
1202 /* Init VI2/CSI2 ops */
1203 cam->ops = &vi2_ops;