]> code.ossystems Code Review - openembedded-core.git/blob
842f395388daf4d25c1a4d82e6d52f0f4cd65ade
[openembedded-core.git] /
1 From 9fbe7b786427d981cac890a7407da09232f5d1e2 Mon Sep 17 00:00:00 2001
2 From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
3 Date: Tue, 10 Mar 2009 10:49:02 +0200
4 Subject: [PATCH] omap3isp: Add CSI2 interface support
5
6 Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
7 ---
8  drivers/media/video/isp/ispcsi2.c | 2124 +++++++++++++++++++++++++++++++++++++
9  drivers/media/video/isp/ispcsi2.h |  232 ++++
10  2 files changed, 2356 insertions(+), 0 deletions(-)
11  create mode 100644 drivers/media/video/isp/ispcsi2.c
12  create mode 100644 drivers/media/video/isp/ispcsi2.h
13
14 diff --git a/drivers/media/video/isp/ispcsi2.c b/drivers/media/video/isp/ispcsi2.c
15 new file mode 100644
16 index 0000000..5141b5a
17 --- /dev/null
18 +++ b/drivers/media/video/isp/ispcsi2.c
19 @@ -0,0 +1,2124 @@
20 +/*
21 + * ispcsi2.c
22 + *
23 + * Driver Library for ISP CSI Control module in TI's OMAP3 Camera ISP
24 + * ISP CSI interface and IRQ related APIs are defined here.
25 + *
26 + * Copyright (C) 2009 Texas Instruments.
27 + *
28 + * Contributors:
29 + *     Sergio Aguirre <saaguirre@ti.com>
30 + *     Dominic Curran <dcurran@ti.com>
31 + *
32 + * This package is free software; you can redistribute it and/or modify
33 + * it under the terms of the GNU General Public License version 2 as
34 + * published by the Free Software Foundation.
35 + *
36 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
37 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
38 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
39 + */
40 +
41 +#include <linux/delay.h>
42 +#include <media/v4l2-common.h>
43 +
44 +#include "isp.h"
45 +#include "ispreg.h"
46 +#include "ispcsi2.h"
47 +
48 +static struct isp_csi2_cfg current_csi2_cfg;
49 +static struct isp_csi2_cfg_update current_csi2_cfg_update;
50 +
51 +static bool update_complexio_cfg1;
52 +static bool update_phy_cfg0;
53 +static bool update_phy_cfg1;
54 +static bool update_ctx_ctrl1[8];
55 +static bool update_ctx_ctrl2[8];
56 +static bool update_ctx_ctrl3[8];
57 +static bool update_timing;
58 +static bool update_ctrl;
59 +static bool uses_videoport;
60 +
61 +/**
62 + * isp_csi2_complexio_lanes_config - Configuration of CSI2 ComplexIO lanes.
63 + * @reqcfg: Pointer to structure containing desired lane configuration
64 + *
65 + * Validates and saves to internal driver memory the passed configuration.
66 + * Returns 0 if successful, or -EINVAL if null pointer is passed, invalid
67 + * lane position or polarity is set, and if 2 lanes try to occupy the same
68 + * position. To apply this settings, use the isp_csi2_complexio_lanes_update()
69 + * function just after calling this function.
70 + **/
71 +int isp_csi2_complexio_lanes_config(struct isp_csi2_lanes_cfg *reqcfg)
72 +{
73 +       int i;
74 +       bool pos_occupied[5] = {false, false, false, false, false};
75 +       struct isp_csi2_lanes_cfg *currlanes = &current_csi2_cfg.lanes;
76 +       struct isp_csi2_lanes_cfg_update *currlanes_u =
77 +               &current_csi2_cfg_update.lanes;
78 +
79 +       /* Validating parameters sent by driver */
80 +       if (reqcfg == NULL) {
81 +               printk(KERN_ERR "Invalid Complex IO Configuration sent by"
82 +                      " sensor\n");
83 +               goto err_einval;
84 +       }
85 +
86 +       /* Data lanes verification */
87 +       for (i = 0; i < 4; i++) {
88 +               if ((reqcfg->data[i].pol > 1) || (reqcfg->data[i].pos > 5)) {
89 +                       printk(KERN_ERR "Invalid CSI-2 Complex IO configuration"
90 +                              " parameters for data lane #%d\n", i);
91 +                       goto err_einval;
92 +               }
93 +               if (pos_occupied[reqcfg->data[i].pos - 1] &&
94 +                   reqcfg->data[i].pos > 0) {
95 +                       printk(KERN_ERR "Lane #%d already occupied\n",
96 +                              reqcfg->data[i].pos);
97 +                       goto err_einval;
98 +               } else
99 +                       pos_occupied[reqcfg->data[i].pos - 1] = true;
100 +       }
101 +
102 +       /* Clock lane verification */
103 +       if ((reqcfg->clk.pol > 1) || (reqcfg->clk.pos > 5) ||
104 +           (reqcfg->clk.pos == 0)) {
105 +               printk(KERN_ERR "Invalid CSI-2 Complex IO configuration"
106 +                      " parameters for clock lane\n");
107 +               goto err_einval;
108 +       }
109 +       if (pos_occupied[reqcfg->clk.pos - 1]) {
110 +               printk(KERN_ERR "Lane #%d already occupied",
111 +                      reqcfg->clk.pos);
112 +               goto err_einval;
113 +       } else
114 +               pos_occupied[reqcfg->clk.pos - 1] = true;
115 +
116 +       for (i = 0; i < 4; i++) {
117 +               if (currlanes->data[i].pos != reqcfg->data[i].pos) {
118 +                       currlanes->data[i].pos = reqcfg->data[i].pos;
119 +                       currlanes_u->data[i] = true;
120 +                       update_complexio_cfg1 = true;
121 +               }
122 +               if (currlanes->data[i].pol != reqcfg->data[i].pol) {
123 +                       currlanes->data[i].pol = reqcfg->data[i].pol;
124 +                       currlanes_u->data[i] = true;
125 +                       update_complexio_cfg1 = true;
126 +               }
127 +       }
128 +
129 +       if (currlanes->clk.pos != reqcfg->clk.pos) {
130 +               currlanes->clk.pos = reqcfg->clk.pos;
131 +               currlanes_u->clk = true;
132 +               update_complexio_cfg1 = true;
133 +       }
134 +       if (currlanes->clk.pol != reqcfg->clk.pol) {
135 +               currlanes->clk.pol = reqcfg->clk.pol;
136 +               currlanes_u->clk = true;
137 +               update_complexio_cfg1 = true;
138 +       }
139 +       return 0;
140 +err_einval:
141 +       return -EINVAL;
142 +}
143 +
144 +/**
145 + * isp_csi2_complexio_lanes_update - Applies CSI2 ComplexIO lanes configuration.
146 + * @force_update: Flag to force rewrite of registers, even if they haven't been
147 + *                updated with the isp_csi2_complexio_lanes_config() function.
148 + *
149 + * It only saves settings when they were previously updated using the
150 + * isp_csi2_complexio_lanes_config() function, unless the force_update flag is
151 + * set to true.
152 + * Always returns 0.
153 + **/
154 +int isp_csi2_complexio_lanes_update(bool force_update)
155 +{
156 +       struct isp_csi2_lanes_cfg *currlanes = &current_csi2_cfg.lanes;
157 +       struct isp_csi2_lanes_cfg_update *currlanes_u =
158 +               &current_csi2_cfg_update.lanes;
159 +       u32 reg;
160 +       int i;
161 +
162 +       if (!update_complexio_cfg1 && !force_update)
163 +               return 0;
164 +
165 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1);
166 +       for (i = 0; i < 4; i++) {
167 +               if (currlanes_u->data[i] || force_update) {
168 +                       reg &= ~(ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(i + 1) |
169 +                                ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(i +
170 +                                                                          1));
171 +                       reg |= (currlanes->data[i].pol <<
172 +                               ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(i + 1));
173 +                       reg |= (currlanes->data[i].pos <<
174 +                               ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(i +
175 +                                                                          1));
176 +                       currlanes_u->data[i] = false;
177 +               }
178 +       }
179 +
180 +       if (currlanes_u->clk || force_update) {
181 +               reg &= ~(ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK |
182 +                        ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK);
183 +               reg |= (currlanes->clk.pol <<
184 +                       ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT);
185 +               reg |= (currlanes->clk.pos <<
186 +                       ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT);
187 +               currlanes_u->clk = false;
188 +       }
189 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1);
190 +
191 +       update_complexio_cfg1 = false;
192 +       return 0;
193 +}
194 +
195 +/**
196 + * isp_csi2_complexio_lanes_get - Gets CSI2 ComplexIO lanes configuration.
197 + *
198 + * Gets settings from HW registers and fills in the internal driver memory
199 + * Always returns 0.
200 + **/
201 +int isp_csi2_complexio_lanes_get(void)
202 +{
203 +       struct isp_csi2_lanes_cfg *currlanes = &current_csi2_cfg.lanes;
204 +       struct isp_csi2_lanes_cfg_update *currlanes_u =
205 +               &current_csi2_cfg_update.lanes;
206 +       u32 reg;
207 +       int i;
208 +
209 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1);
210 +       for (i = 0; i < 4; i++) {
211 +               currlanes->data[i].pol = (reg &
212 +                                         ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(i + 1)) >>
213 +                       ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(i + 1);
214 +               currlanes->data[i].pos = (reg &
215 +                                         ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(i + 1)) >>
216 +                       ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(i + 1);
217 +               currlanes_u->data[i] = false;
218 +       }
219 +       currlanes->clk.pol = (reg & ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK) >>
220 +               ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT;
221 +       currlanes->clk.pos = (reg &
222 +                             ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK) >>
223 +               ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT;
224 +       currlanes_u->clk = false;
225 +
226 +       update_complexio_cfg1 = false;
227 +       return 0;
228 +}
229 +
230 +/**
231 + * isp_csi2_complexio_power_status - Gets CSI2 ComplexIO power status.
232 + *
233 + * Returns 3 possible valid states: ISP_CSI2_POWER_OFF, ISP_CSI2_POWER_ON,
234 + * and ISP_CSI2_POWER_ULPW.
235 + **/
236 +static enum isp_csi2_power_cmds isp_csi2_complexio_power_status(void)
237 +{
238 +       enum isp_csi2_power_cmds ret;
239 +       u32 reg;
240 +
241 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1) &
242 +               ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_MASK;
243 +       switch (reg) {
244 +       case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_OFF:
245 +               ret = ISP_CSI2_POWER_OFF;
246 +               break;
247 +       case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ON:
248 +               ret = ISP_CSI2_POWER_ON;
249 +               break;
250 +       case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ULPW:
251 +               ret = ISP_CSI2_POWER_ULPW;
252 +               break;
253 +       default:
254 +               return -EINVAL;
255 +       }
256 +       return ret;
257 +}
258 +
259 +/**
260 + * isp_csi2_complexio_power_autoswitch - Sets CSI2 ComplexIO power autoswitch.
261 + * @enable: Sets or clears the autoswitch function enable flag.
262 + *
263 + * Always returns 0.
264 + **/
265 +int isp_csi2_complexio_power_autoswitch(bool enable)
266 +{
267 +       u32 reg;
268 +
269 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1);
270 +       reg &= ~ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_MASK;
271 +
272 +       if (enable)
273 +               reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_ENABLE;
274 +       else
275 +               reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_DISABLE;
276 +
277 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1);
278 +       return 0;
279 +}
280 +
281 +/**
282 + * isp_csi2_complexio_power - Sets the desired power command for CSI2 ComplexIO.
283 + * @power_cmd: Power command to be set.
284 + *
285 + * Returns 0 if successful, or -EBUSY if the retry count is exceeded.
286 + **/
287 +int isp_csi2_complexio_power(enum isp_csi2_power_cmds power_cmd)
288 +{
289 +       enum isp_csi2_power_cmds current_state;
290 +       u32 reg;
291 +       u8 retry_count;
292 +
293 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1) &
294 +               ~ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_MASK;
295 +       switch (power_cmd) {
296 +       case ISP_CSI2_POWER_OFF:
297 +               reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_OFF;
298 +               break;
299 +       case ISP_CSI2_POWER_ON:
300 +               reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ON;
301 +               break;
302 +       case ISP_CSI2_POWER_ULPW:
303 +               reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ULPW;
304 +               break;
305 +       default:
306 +               printk(KERN_ERR "CSI2: ERROR - Wrong Power command!\n");
307 +               return -EINVAL;
308 +       }
309 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1);
310 +
311 +       retry_count = 0;
312 +       do {
313 +               udelay(50);
314 +               current_state = isp_csi2_complexio_power_status();
315 +
316 +               if (current_state != power_cmd) {
317 +                       printk(KERN_DEBUG "CSI2: Complex IO power command not"
318 +                              " yet taken.");
319 +                       if (++retry_count < 100) {
320 +                               printk(KERN_DEBUG " Retrying...\n");
321 +                               udelay(50);
322 +                       } else {
323 +                               printk(KERN_DEBUG " Retry count exceeded!\n");
324 +                       }
325 +               }
326 +       } while ((current_state != power_cmd) && (retry_count < 100));
327 +
328 +       if (retry_count == 100)
329 +               return -EBUSY;
330 +
331 +       return 0;
332 +}
333 +
334 +/**
335 + * isp_csi2_ctrl_config_frame_mode - Configure if_en behaviour for CSI2
336 + * @frame_mode: Desired action for IF_EN switch off. 0 - disable IF immediately
337 + *              1 - disable after all Frame end Code is received in all
338 + *              contexts.
339 + *
340 + * Validates and saves to internal driver memory the passed configuration.
341 + * Always returns 0.
342 + **/
343 +int isp_csi2_ctrl_config_frame_mode(enum isp_csi2_frame_mode frame_mode)
344 +{
345 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
346 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
347 +               &current_csi2_cfg_update.ctrl;
348 +
349 +       if (currctrl->frame_mode != frame_mode) {
350 +               currctrl->frame_mode = frame_mode;
351 +               currctrl_u->frame_mode = true;
352 +               update_ctrl = true;
353 +       }
354 +       return 0;
355 +}
356 +
357 +/**
358 + * isp_csi2_ctrl_config_vp_clk_enable - Enables/disables CSI2 Videoport clock.
359 + * @vp_clk_enable: Boolean value to specify the Videoport clock state.
360 + *
361 + * Validates and saves to internal driver memory the passed configuration.
362 + * Always returns 0.
363 + **/
364 +int isp_csi2_ctrl_config_vp_clk_enable(bool vp_clk_enable)
365 +{
366 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
367 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
368 +               &current_csi2_cfg_update.ctrl;
369 +
370 +       if (currctrl->vp_clk_enable != vp_clk_enable) {
371 +               currctrl->vp_clk_enable = vp_clk_enable;
372 +               currctrl_u->vp_clk_enable = true;
373 +               update_ctrl = true;
374 +       }
375 +       return 0;
376 +}
377 +
378 +/**
379 + * isp_csi2_ctrl_config_vp_only_enable - Sets CSI2 Videoport clock as exclusive
380 + * @vp_only_enable: Boolean value to specify if the Videoport clock is
381 + *                  exclusive, setting the OCP port as disabled.
382 + *
383 + * Validates and saves to internal driver memory the passed configuration.
384 + * Always returns 0.
385 + **/
386 +int isp_csi2_ctrl_config_vp_only_enable(bool vp_only_enable)
387 +{
388 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
389 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
390 +               &current_csi2_cfg_update.ctrl;
391 +
392 +       if (currctrl->vp_only_enable != vp_only_enable) {
393 +               currctrl->vp_only_enable = vp_only_enable;
394 +               currctrl_u->vp_only_enable = true;
395 +               update_ctrl = true;
396 +       }
397 +       return 0;
398 +}
399 +
400 +/**
401 + * isp_csi2_ctrl_config_vp_out_ctrl - Sets CSI2 Videoport clock divider
402 + * @vp_out_ctrl: Divider value for setting videoport clock frequency based on
403 + *               OCP port frequency, valid dividers are between 1 and 4.
404 + *
405 + * Validates and saves to internal driver memory the passed configuration.
406 + * Returns 0 if successful, or -EINVAL if wrong divider value is passed.
407 + **/
408 +int isp_csi2_ctrl_config_vp_out_ctrl(u8 vp_out_ctrl)
409 +{
410 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
411 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
412 +               &current_csi2_cfg_update.ctrl;
413 +
414 +       if ((vp_out_ctrl == 0) || (vp_out_ctrl > 4)) {
415 +               printk(KERN_ERR "CSI2: Wrong divisor value. Must be between"
416 +                      " 1 and 4");
417 +               return -EINVAL;
418 +       }
419 +
420 +       if (currctrl->vp_out_ctrl != vp_out_ctrl) {
421 +               currctrl->vp_out_ctrl = vp_out_ctrl;
422 +               currctrl_u->vp_out_ctrl = true;
423 +               update_ctrl = true;
424 +       }
425 +       return 0;
426 +}
427 +
428 +/**
429 + * isp_csi2_ctrl_config_debug_enable - Sets CSI2 debug
430 + * @debug_enable: Boolean for setting debug configuration on CSI2.
431 + *
432 + * Always returns 0.
433 + **/
434 +int isp_csi2_ctrl_config_debug_enable(bool debug_enable)
435 +{
436 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
437 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
438 +               &current_csi2_cfg_update.ctrl;
439 +
440 +       if (currctrl->debug_enable != debug_enable) {
441 +               currctrl->debug_enable = debug_enable;
442 +               currctrl_u->debug_enable = true;
443 +               update_ctrl = true;
444 +       }
445 +       return 0;
446 +}
447 +
448 +/**
449 + * isp_csi2_ctrl_config_burst_size - Sets CSI2 burst size.
450 + * @burst_size: Burst size of the memory saving capability of receiver.
451 + *
452 + * Returns 0 if successful, or -EINVAL if burst size is wrong.
453 + **/
454 +int isp_csi2_ctrl_config_burst_size(u8 burst_size)
455 +{
456 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
457 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
458 +               &current_csi2_cfg_update.ctrl;
459 +       if (burst_size > 3) {
460 +               printk(KERN_ERR "CSI2: Wrong burst size. Must be between"
461 +                      " 0 and 3");
462 +               return -EINVAL;
463 +       }
464 +
465 +       if (currctrl->burst_size != burst_size) {
466 +               currctrl->burst_size = burst_size;
467 +               currctrl_u->burst_size = true;
468 +               update_ctrl = true;
469 +       }
470 +       return 0;
471 +}
472 +
473 +/**
474 + * isp_csi2_ctrl_config_ecc_enable - Enables ECC on CSI2 Receiver
475 + * @ecc_enable: Boolean to enable/disable the CSI2 receiver ECC handling.
476 + *
477 + * Always returns 0.
478 + **/
479 +int isp_csi2_ctrl_config_ecc_enable(bool ecc_enable)
480 +{
481 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
482 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
483 +               &current_csi2_cfg_update.ctrl;
484 +
485 +       if (currctrl->ecc_enable != ecc_enable) {
486 +               currctrl->ecc_enable = ecc_enable;
487 +               currctrl_u->ecc_enable = true;
488 +               update_ctrl = true;
489 +       }
490 +       return 0;
491 +}
492 +
493 +/**
494 + * isp_csi2_ctrl_config_ecc_enable - Enables ECC on CSI2 Receiver
495 + * @ecc_enable: Boolean to enable/disable the CSI2 receiver ECC handling.
496 + *
497 + * Always returns 0.
498 + **/
499 +int isp_csi2_ctrl_config_secure_mode(bool secure_mode)
500 +{
501 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
502 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
503 +               &current_csi2_cfg_update.ctrl;
504 +
505 +       if (currctrl->secure_mode != secure_mode) {
506 +               currctrl->secure_mode = secure_mode;
507 +               currctrl_u->secure_mode = true;
508 +               update_ctrl = true;
509 +       }
510 +       return 0;
511 +}
512 +
513 +/**
514 + * isp_csi2_ctrl_config_if_enable - Enables CSI2 Receiver interface.
515 + * @if_enable: Boolean to enable/disable the CSI2 receiver interface.
516 + *
517 + * Always returns 0.
518 + **/
519 +int isp_csi2_ctrl_config_if_enable(bool if_enable)
520 +{
521 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
522 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
523 +               &current_csi2_cfg_update.ctrl;
524 +
525 +       if (currctrl->if_enable != if_enable) {
526 +               currctrl->if_enable = if_enable;
527 +               currctrl_u->if_enable = true;
528 +               update_ctrl = true;
529 +       }
530 +       return 0;
531 +}
532 +
533 +/**
534 + * isp_csi2_ctrl_update - Applies CSI2 control configuration.
535 + * @force_update: Flag to force rewrite of registers, even if they haven't been
536 + *                updated with the isp_csi2_ctrl_config_*() functions.
537 + *
538 + * It only saves settings when they were previously updated using the
539 + * isp_csi2_ctrl_config_*() functions, unless the force_update flag is
540 + * set to true.
541 + * Always returns 0.
542 + **/
543 +int isp_csi2_ctrl_update(bool force_update)
544 +{
545 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
546 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
547 +               &current_csi2_cfg_update.ctrl;
548 +       u32 reg;
549 +
550 +       if (update_ctrl || force_update) {
551 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL);
552 +               if (currctrl_u->frame_mode || force_update) {
553 +                       reg &= ~ISPCSI2_CTRL_FRAME_MASK;
554 +                       if (currctrl->frame_mode)
555 +                               reg |= ISPCSI2_CTRL_FRAME_DISABLE_FEC;
556 +                       else
557 +                               reg |= ISPCSI2_CTRL_FRAME_DISABLE_IMM;
558 +                       currctrl_u->frame_mode = false;
559 +               }
560 +               if (currctrl_u->vp_clk_enable || force_update) {
561 +                       reg &= ~ISPCSI2_CTRL_VP_CLK_EN_MASK;
562 +                       if (currctrl->vp_clk_enable)
563 +                               reg |= ISPCSI2_CTRL_VP_CLK_EN_ENABLE;
564 +                       else
565 +                               reg |= ISPCSI2_CTRL_VP_CLK_EN_DISABLE;
566 +                       currctrl_u->vp_clk_enable = false;
567 +               }
568 +               if (currctrl_u->vp_only_enable || force_update) {
569 +                       reg &= ~ISPCSI2_CTRL_VP_ONLY_EN_MASK;
570 +                       uses_videoport = currctrl->vp_only_enable;
571 +                       if (currctrl->vp_only_enable)
572 +                               reg |= ISPCSI2_CTRL_VP_ONLY_EN_ENABLE;
573 +                       else
574 +                               reg |= ISPCSI2_CTRL_VP_ONLY_EN_DISABLE;
575 +                       currctrl_u->vp_only_enable = false;
576 +               }
577 +               if (currctrl_u->vp_out_ctrl || force_update) {
578 +                       reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK;
579 +                       reg |= (currctrl->vp_out_ctrl - 1) <<
580 +                               ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT;
581 +                       currctrl_u->vp_out_ctrl = false;
582 +               }
583 +               if (currctrl_u->debug_enable || force_update) {
584 +                       reg &= ~ISPCSI2_CTRL_DBG_EN_MASK;
585 +                       if (currctrl->debug_enable)
586 +                               reg |= ISPCSI2_CTRL_DBG_EN_ENABLE;
587 +                       else
588 +                               reg |= ISPCSI2_CTRL_DBG_EN_DISABLE;
589 +                       currctrl_u->debug_enable = false;
590 +               }
591 +               if (currctrl_u->burst_size || force_update) {
592 +                       reg &= ~ISPCSI2_CTRL_BURST_SIZE_MASK;
593 +                       reg |= currctrl->burst_size <<
594 +                               ISPCSI2_CTRL_BURST_SIZE_SHIFT;
595 +                       currctrl_u->burst_size = false;
596 +               }
597 +               if (currctrl_u->ecc_enable || force_update) {
598 +                       reg &= ~ISPCSI2_CTRL_ECC_EN_MASK;
599 +                       if (currctrl->ecc_enable)
600 +                               reg |= ISPCSI2_CTRL_ECC_EN_ENABLE;
601 +                       else
602 +                               reg |= ISPCSI2_CTRL_ECC_EN_DISABLE;
603 +                       currctrl_u->ecc_enable = false;
604 +               }
605 +               if (currctrl_u->secure_mode || force_update) {
606 +                       reg &= ~ISPCSI2_CTRL_SECURE_MASK;
607 +                       if (currctrl->secure_mode)
608 +                               reg |= ISPCSI2_CTRL_SECURE_ENABLE;
609 +                       else
610 +                               reg |= ISPCSI2_CTRL_SECURE_DISABLE;
611 +                       currctrl_u->secure_mode = false;
612 +               }
613 +               if (currctrl_u->if_enable || force_update) {
614 +                       reg &= ~ISPCSI2_CTRL_IF_EN_MASK;
615 +                       if (currctrl->if_enable)
616 +                               reg |= ISPCSI2_CTRL_IF_EN_ENABLE;
617 +                       else
618 +                               reg |= ISPCSI2_CTRL_IF_EN_DISABLE;
619 +                       currctrl_u->if_enable = false;
620 +               }
621 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL);
622 +               update_ctrl = false;
623 +       }
624 +       return 0;
625 +}
626 +
627 +/**
628 + * isp_csi2_ctrl_get - Gets CSI2 control configuration
629 + *
630 + * Always returns 0.
631 + **/
632 +int isp_csi2_ctrl_get(void)
633 +{
634 +       struct isp_csi2_ctrl_cfg *currctrl = &current_csi2_cfg.ctrl;
635 +       struct isp_csi2_ctrl_cfg_update *currctrl_u =
636 +               &current_csi2_cfg_update.ctrl;
637 +       u32 reg;
638 +
639 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL);
640 +       currctrl->frame_mode = (reg & ISPCSI2_CTRL_FRAME_MASK) >>
641 +               ISPCSI2_CTRL_FRAME_SHIFT;
642 +       currctrl_u->frame_mode = false;
643 +
644 +       if ((reg & ISPCSI2_CTRL_VP_CLK_EN_MASK) ==
645 +           ISPCSI2_CTRL_VP_CLK_EN_ENABLE)
646 +               currctrl->vp_clk_enable = true;
647 +       else
648 +               currctrl->vp_clk_enable = false;
649 +       currctrl_u->vp_clk_enable = false;
650 +
651 +       if ((reg & ISPCSI2_CTRL_VP_ONLY_EN_MASK) ==
652 +           ISPCSI2_CTRL_VP_ONLY_EN_ENABLE)
653 +               currctrl->vp_only_enable = true;
654 +       else
655 +               currctrl->vp_only_enable = false;
656 +       uses_videoport = currctrl->vp_only_enable;
657 +       currctrl_u->vp_only_enable = false;
658 +
659 +       currctrl->vp_out_ctrl = ((reg & ISPCSI2_CTRL_VP_OUT_CTRL_MASK) >>
660 +                                ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) + 1;
661 +       currctrl_u->vp_out_ctrl = false;
662 +
663 +       if ((reg & ISPCSI2_CTRL_DBG_EN_MASK) == ISPCSI2_CTRL_DBG_EN_ENABLE)
664 +               currctrl->debug_enable = true;
665 +       else
666 +               currctrl->debug_enable = false;
667 +       currctrl_u->debug_enable = false;
668 +
669 +       currctrl->burst_size = (reg & ISPCSI2_CTRL_BURST_SIZE_MASK) >>
670 +               ISPCSI2_CTRL_BURST_SIZE_SHIFT;
671 +       currctrl_u->burst_size = false;
672 +
673 +       if ((reg & ISPCSI2_CTRL_ECC_EN_MASK) == ISPCSI2_CTRL_ECC_EN_ENABLE)
674 +               currctrl->ecc_enable = true;
675 +       else
676 +               currctrl->ecc_enable = false;
677 +       currctrl_u->ecc_enable = false;
678 +
679 +       if ((reg & ISPCSI2_CTRL_SECURE_MASK) == ISPCSI2_CTRL_SECURE_ENABLE)
680 +               currctrl->secure_mode = true;
681 +       else
682 +               currctrl->secure_mode = false;
683 +       currctrl_u->secure_mode = false;
684 +
685 +       if ((reg & ISPCSI2_CTRL_IF_EN_MASK) == ISPCSI2_CTRL_IF_EN_ENABLE)
686 +               currctrl->if_enable = true;
687 +       else
688 +               currctrl->if_enable = false;
689 +       currctrl_u->if_enable = false;
690 +
691 +       update_ctrl = false;
692 +       return 0;
693 +}
694 +
695 +/**
696 + * isp_csi2_ctx_validate - Validates the context number value
697 + * @ctxnum: Pointer to variable containing context number.
698 + *
699 + * If the value is not in range (3 bits), it is being ANDed with 0x7 to force
700 + * it to be on range.
701 + **/
702 +static void isp_csi2_ctx_validate(u8 *ctxnum)
703 +{
704 +       if (*ctxnum > 7) {
705 +               printk(KERN_ERR "Invalid context number. Forcing valid"
706 +                      " value...\n");
707 +               *ctxnum &= ~(0x7);
708 +       }
709 +}
710 +
711 +/**
712 + * isp_csi2_ctx_config_virtual_id - Maps a virtual ID with a CSI2 Rx context
713 + * @ctxnum: Context number, valid between 0 and 7 values.
714 + * @virtual_id: CSI2 Virtual ID to associate with specified context number.
715 + *
716 + * Returns 0 if successful, or -EINVAL if Virtual ID is not in range (0-3).
717 + **/
718 +int isp_csi2_ctx_config_virtual_id(u8 ctxnum, u8 virtual_id)
719 +{
720 +       struct isp_csi2_ctx_cfg *selected_ctx;
721 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
722 +
723 +       isp_csi2_ctx_validate(&ctxnum);
724 +
725 +       if (virtual_id > 3) {
726 +               printk(KERN_ERR "Wrong requested virtual_id\n");
727 +               return -EINVAL;
728 +       }
729 +
730 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
731 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
732 +
733 +       if (selected_ctx->virtual_id != virtual_id) {
734 +               selected_ctx->virtual_id = virtual_id;
735 +               selected_ctx_u->virtual_id = true;
736 +               update_ctx_ctrl2[ctxnum] = true;
737 +       }
738 +
739 +       return 0;
740 +}
741 +
742 +/**
743 + * isp_csi2_ctx_config_frame_count - Sets frame count to be received in CSI2 Rx.
744 + * @ctxnum: Context number, valid between 0 and 7 values.
745 + * @frame_count: Number of frames to acquire.
746 + *
747 + * Always returns 0.
748 + **/
749 +int isp_csi2_ctx_config_frame_count(u8 ctxnum, u8 frame_count)
750 +{
751 +       struct isp_csi2_ctx_cfg *selected_ctx;
752 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
753 +
754 +       isp_csi2_ctx_validate(&ctxnum);
755 +
756 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
757 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
758 +
759 +       if (selected_ctx->frame_count != frame_count) {
760 +               selected_ctx->frame_count = frame_count;
761 +               selected_ctx_u->frame_count = true;
762 +               update_ctx_ctrl1[ctxnum] = true;
763 +       }
764 +
765 +       return 0;
766 +}
767 +
768 +/**
769 + * isp_csi2_ctx_config_format - Maps a pixel format to a specified context.
770 + * @ctxnum: Context number, valid between 0 and 7 values.
771 + * @pixformat: V4L2 structure for pixel format.
772 + *
773 + * Returns 0 if successful, or -EINVAL if the format is not supported by the
774 + * receiver.
775 + **/
776 +int isp_csi2_ctx_config_format(u8 ctxnum, u32 pixformat)
777 +{
778 +       struct isp_csi2_ctx_cfg *selected_ctx;
779 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
780 +       struct v4l2_pix_format pix;
781 +
782 +       isp_csi2_ctx_validate(&ctxnum);
783 +
784 +       pix.pixelformat = pixformat;
785 +       switch (pix.pixelformat) {
786 +       case V4L2_PIX_FMT_RGB565:
787 +       case V4L2_PIX_FMT_RGB565X:
788 +       case V4L2_PIX_FMT_YUYV:
789 +       case V4L2_PIX_FMT_UYVY:
790 +       case V4L2_PIX_FMT_RGB555:
791 +       case V4L2_PIX_FMT_RGB555X:
792 +       case V4L2_PIX_FMT_SGRBG10:
793 +               break;
794 +       default:
795 +               printk(KERN_ERR "Context config pixel format unsupported\n");
796 +               return -EINVAL;
797 +       }
798 +
799 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
800 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
801 +
802 +       selected_ctx->format = pix;
803 +       selected_ctx_u->format = true;
804 +       update_ctx_ctrl2[ctxnum] = true;
805 +
806 +       return 0;
807 +}
808 +
809 +/**
810 + * isp_csi2_ctx_config_alpha - Sets the alpha value for pixel format
811 + * @ctxnum: Context number, valid between 0 and 7 values.
812 + * @alpha: Alpha value.
813 + *
814 + * Returns 0 if successful, or -EINVAL if the alpha value is bigger than 16383.
815 + **/
816 +int isp_csi2_ctx_config_alpha(u8 ctxnum, u16 alpha)
817 +{
818 +       struct isp_csi2_ctx_cfg *selected_ctx;
819 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
820 +
821 +       isp_csi2_ctx_validate(&ctxnum);
822 +
823 +       if (alpha > 0x3FFF) {
824 +               printk(KERN_ERR "Wrong alpha value\n");
825 +               return -EINVAL;
826 +       }
827 +
828 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
829 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
830 +
831 +       if (selected_ctx->alpha != alpha) {
832 +               selected_ctx->alpha = alpha;
833 +               selected_ctx_u->alpha = true;
834 +               update_ctx_ctrl3[ctxnum] = true;
835 +       }
836 +       return 0;
837 +}
838 +
839 +/**
840 + * isp_csi2_ctx_config_data_offset - Sets the offset between received lines
841 + * @ctxnum: Context number, valid between 0 and 7 values.
842 + * @data_offset: Offset between first pixel of each 2 contiguous lines.
843 + *
844 + * Returns 0 if successful, or -EINVAL if the line offset is bigger than 1023.
845 + **/
846 +int isp_csi2_ctx_config_data_offset(u8 ctxnum, u16 data_offset)
847 +{
848 +       struct isp_csi2_ctx_cfg *selected_ctx;
849 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
850 +
851 +       isp_csi2_ctx_validate(&ctxnum);
852 +
853 +       if (data_offset > 0x3FF) {
854 +               printk(KERN_ERR "Wrong line offset\n");
855 +               return -EINVAL;
856 +       }
857 +
858 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
859 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
860 +
861 +       if (selected_ctx->data_offset != data_offset) {
862 +               selected_ctx->data_offset = data_offset;
863 +               selected_ctx_u->data_offset = true;
864 +       }
865 +       return 0;
866 +}
867 +
868 +/**
869 + * isp_csi2_ctx_config_ping_addr - Sets Ping address for CSI2 Rx. buffer saving
870 + * @ctxnum: Context number, valid between 0 and 7 values.
871 + * @ping_addr: 32 bit ISP MMU mapped address.
872 + *
873 + * Always returns 0.
874 + **/
875 +int isp_csi2_ctx_config_ping_addr(u8 ctxnum, u32 ping_addr)
876 +{
877 +       struct isp_csi2_ctx_cfg *selected_ctx;
878 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
879 +
880 +       isp_csi2_ctx_validate(&ctxnum);
881 +
882 +       ping_addr &= ~(0x1F);
883 +
884 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
885 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
886 +
887 +       if (selected_ctx->ping_addr != ping_addr) {
888 +               selected_ctx->ping_addr = ping_addr;
889 +               selected_ctx_u->ping_addr = true;
890 +       }
891 +       return 0;
892 +}
893 +
894 +/**
895 + * isp_csi2_ctx_config_pong_addr - Sets Pong address for CSI2 Rx. buffer saving
896 + * @ctxnum: Context number, valid between 0 and 7 values.
897 + * @pong_addr: 32 bit ISP MMU mapped address.
898 + *
899 + * Always returns 0.
900 + **/
901 +int isp_csi2_ctx_config_pong_addr(u8 ctxnum, u32 pong_addr)
902 +{
903 +       struct isp_csi2_ctx_cfg *selected_ctx;
904 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
905 +
906 +       isp_csi2_ctx_validate(&ctxnum);
907 +
908 +       pong_addr &= ~(0x1F);
909 +
910 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
911 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
912 +
913 +       if (selected_ctx->pong_addr != pong_addr) {
914 +               selected_ctx->pong_addr = pong_addr;
915 +               selected_ctx_u->pong_addr = true;
916 +       }
917 +       return 0;
918 +}
919 +
920 +/**
921 + * isp_csi2_ctx_config_eof_enabled - Enables EOF signal assertion
922 + * @ctxnum: Context number, valid between 0 and 7 values.
923 + * @eof_enabled: Boolean to enable/disable EOF signal assertion on received
924 + *               packets.
925 + *
926 + * Always returns 0.
927 + **/
928 +int isp_csi2_ctx_config_eof_enabled(u8 ctxnum, bool eof_enabled)
929 +{
930 +       struct isp_csi2_ctx_cfg *selected_ctx;
931 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
932 +
933 +       isp_csi2_ctx_validate(&ctxnum);
934 +
935 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
936 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
937 +
938 +       if (selected_ctx->eof_enabled != eof_enabled) {
939 +               selected_ctx->eof_enabled = eof_enabled;
940 +               selected_ctx_u->eof_enabled = true;
941 +               update_ctx_ctrl1[ctxnum] = true;
942 +       }
943 +       return 0;
944 +}
945 +
946 +/**
947 + * isp_csi2_ctx_config_eol_enabled - Enables EOL signal assertion
948 + * @ctxnum: Context number, valid between 0 and 7 values.
949 + * @eol_enabled: Boolean to enable/disable EOL signal assertion on received
950 + *               packets.
951 + *
952 + * Always returns 0.
953 + **/
954 +int isp_csi2_ctx_config_eol_enabled(u8 ctxnum, bool eol_enabled)
955 +{
956 +       struct isp_csi2_ctx_cfg *selected_ctx;
957 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
958 +
959 +       isp_csi2_ctx_validate(&ctxnum);
960 +
961 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
962 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
963 +
964 +       if (selected_ctx->eol_enabled != eol_enabled) {
965 +               selected_ctx->eol_enabled = eol_enabled;
966 +               selected_ctx_u->eol_enabled = true;
967 +               update_ctx_ctrl1[ctxnum] = true;
968 +       }
969 +       return 0;
970 +}
971 +
972 +/**
973 + * isp_csi2_ctx_config_checksum_enabled - Enables Checksum check in rcvd packets
974 + * @ctxnum: Context number, valid between 0 and 7 values.
975 + * @checksum_enabled: Boolean to enable/disable Checksum check on received
976 + *                    packets
977 + *
978 + * Always returns 0.
979 + **/
980 +int isp_csi2_ctx_config_checksum_enabled(u8 ctxnum, bool checksum_enabled)
981 +{
982 +       struct isp_csi2_ctx_cfg *selected_ctx;
983 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
984 +
985 +       isp_csi2_ctx_validate(&ctxnum);
986 +
987 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
988 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
989 +
990 +       if (selected_ctx->checksum_enabled != checksum_enabled) {
991 +               selected_ctx->checksum_enabled = checksum_enabled;
992 +               selected_ctx_u->checksum_enabled = true;
993 +               update_ctx_ctrl1[ctxnum] = true;
994 +       }
995 +       return 0;
996 +}
997 +
998 +/**
999 + * isp_csi2_ctx_config_enabled - Enables specified CSI2 context
1000 + * @ctxnum: Context number, valid between 0 and 7 values.
1001 + * @enabled: Boolean to enable/disable specified context.
1002 + *
1003 + * Always returns 0.
1004 + **/
1005 +int isp_csi2_ctx_config_enabled(u8 ctxnum, bool enabled)
1006 +{
1007 +       struct isp_csi2_ctx_cfg *selected_ctx;
1008 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
1009 +
1010 +       isp_csi2_ctx_validate(&ctxnum);
1011 +
1012 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
1013 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
1014 +
1015 +       if (selected_ctx->enabled != enabled) {
1016 +               selected_ctx->enabled = enabled;
1017 +               selected_ctx_u->enabled = true;
1018 +               update_ctx_ctrl1[ctxnum] = true;
1019 +       }
1020 +       return 0;
1021 +}
1022 +
1023 +/**
1024 + * isp_csi2_ctx_update - Applies CSI2 context configuration.
1025 + * @ctxnum: Context number, valid between 0 and 7 values.
1026 + * @force_update: Flag to force rewrite of registers, even if they haven't been
1027 + *                updated with the isp_csi2_ctx_config_*() functions.
1028 + *
1029 + * It only saves settings when they were previously updated using the
1030 + * isp_csi2_ctx_config_*() functions, unless the force_update flag is
1031 + * set to true.
1032 + * Always returns 0.
1033 + **/
1034 +int isp_csi2_ctx_update(u8 ctxnum, bool force_update)
1035 +{
1036 +       struct isp_csi2_ctx_cfg *selected_ctx;
1037 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
1038 +       u32 reg;
1039 +
1040 +       isp_csi2_ctx_validate(&ctxnum);
1041 +
1042 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
1043 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
1044 +
1045 +       if (update_ctx_ctrl1[ctxnum] || force_update) {
1046 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1047 +                                   ISPCSI2_CTX_CTRL1(ctxnum));
1048 +               if (selected_ctx_u->frame_count || force_update) {
1049 +                       reg &= ~(ISPCSI2_CTX_CTRL1_COUNT_MASK);
1050 +                       reg |= selected_ctx->frame_count <<
1051 +                               ISPCSI2_CTX_CTRL1_COUNT_SHIFT;
1052 +                       selected_ctx_u->frame_count = false;
1053 +               }
1054 +               if (selected_ctx_u->eof_enabled || force_update) {
1055 +                       reg &= ~(ISPCSI2_CTX_CTRL1_EOF_EN_MASK);
1056 +                       if (selected_ctx->eof_enabled)
1057 +                               reg |= ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE;
1058 +                       else
1059 +                               reg |= ISPCSI2_CTX_CTRL1_EOF_EN_DISABLE;
1060 +                       selected_ctx_u->eof_enabled = false;
1061 +               }
1062 +               if (selected_ctx_u->eol_enabled || force_update) {
1063 +                       reg &= ~(ISPCSI2_CTX_CTRL1_EOL_EN_MASK);
1064 +                       if (selected_ctx->eol_enabled)
1065 +                               reg |= ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE;
1066 +                       else
1067 +                               reg |= ISPCSI2_CTX_CTRL1_EOL_EN_DISABLE;
1068 +                       selected_ctx_u->eol_enabled = false;
1069 +               }
1070 +               if (selected_ctx_u->checksum_enabled || force_update) {
1071 +                       reg &= ~(ISPCSI2_CTX_CTRL1_CS_EN_MASK);
1072 +                       if (selected_ctx->checksum_enabled)
1073 +                               reg |= ISPCSI2_CTX_CTRL1_CS_EN_ENABLE;
1074 +                       else
1075 +                               reg |= ISPCSI2_CTX_CTRL1_CS_EN_DISABLE;
1076 +                       selected_ctx_u->checksum_enabled = false;
1077 +               }
1078 +               if (selected_ctx_u->enabled || force_update) {
1079 +                       reg &= ~(ISPCSI2_CTX_CTRL1_CTX_EN_MASK);
1080 +                       if (selected_ctx->enabled)
1081 +                               reg |= ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE;
1082 +                       else
1083 +                               reg |= ISPCSI2_CTX_CTRL1_CTX_EN_DISABLE;
1084 +                       selected_ctx_u->enabled = false;
1085 +               }
1086 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1087 +                              ISPCSI2_CTX_CTRL1(ctxnum));
1088 +               update_ctx_ctrl1[ctxnum] = false;
1089 +       }
1090 +
1091 +       if (update_ctx_ctrl2[ctxnum] || force_update) {
1092 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1093 +                                   ISPCSI2_CTX_CTRL2(ctxnum));
1094 +               if (selected_ctx_u->virtual_id || force_update) {
1095 +                       reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK);
1096 +                       reg |= selected_ctx->virtual_id <<
1097 +                               ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
1098 +                       selected_ctx_u->virtual_id = false;
1099 +               }
1100 +
1101 +               if (selected_ctx_u->format || force_update) {
1102 +                       struct v4l2_pix_format *pix;
1103 +                       u16 new_format = 0;
1104 +
1105 +                       reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK);
1106 +                       pix = &selected_ctx->format;
1107 +                       switch (pix->pixelformat) {
1108 +                       case V4L2_PIX_FMT_RGB565:
1109 +                       case V4L2_PIX_FMT_RGB565X:
1110 +                               new_format = 0x22;
1111 +                               break;
1112 +                       case V4L2_PIX_FMT_YUYV:
1113 +                       case V4L2_PIX_FMT_UYVY:
1114 +                               if (uses_videoport)
1115 +                                       new_format = 0x9E;
1116 +                               else
1117 +                                       new_format = 0x1E;
1118 +                               break;
1119 +                       case V4L2_PIX_FMT_RGB555:
1120 +                       case V4L2_PIX_FMT_RGB555X:
1121 +                               new_format = 0xA1;
1122 +                               break;
1123 +                       case V4L2_PIX_FMT_SGRBG10:
1124 +                               if (uses_videoport)
1125 +                                       new_format = 0x12F;
1126 +                               else
1127 +                                       new_format = 0xAB;
1128 +                               break;
1129 +                       }
1130 +                       reg |= (new_format << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT);
1131 +                       selected_ctx_u->format = false;
1132 +               }
1133 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1134 +                              ISPCSI2_CTX_CTRL2(ctxnum));
1135 +               update_ctx_ctrl2[ctxnum] = false;
1136 +       }
1137 +
1138 +       if (update_ctx_ctrl3[ctxnum] || force_update) {
1139 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1140 +                                   ISPCSI2_CTX_CTRL3(ctxnum));
1141 +               if (selected_ctx_u->alpha || force_update) {
1142 +                       reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK);
1143 +                       reg |= (selected_ctx->alpha <<
1144 +                               ISPCSI2_CTX_CTRL3_ALPHA_SHIFT);
1145 +                       selected_ctx_u->alpha = false;
1146 +               }
1147 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1148 +                              ISPCSI2_CTX_CTRL3(ctxnum));
1149 +               update_ctx_ctrl3[ctxnum] = false;
1150 +       }
1151 +
1152 +       if (selected_ctx_u->data_offset) {
1153 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1154 +                                   ISPCSI2_CTX_DAT_OFST(ctxnum));
1155 +               reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK;
1156 +               reg |= selected_ctx->data_offset <<
1157 +                       ISPCSI2_CTX_DAT_OFST_OFST_SHIFT;
1158 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1159 +                              ISPCSI2_CTX_DAT_OFST(ctxnum));
1160 +               selected_ctx_u->data_offset = false;
1161 +       }
1162 +
1163 +       if (selected_ctx_u->ping_addr) {
1164 +               reg = selected_ctx->ping_addr;
1165 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1166 +                              ISPCSI2_CTX_DAT_PING_ADDR(ctxnum));
1167 +               selected_ctx_u->ping_addr = false;
1168 +       }
1169 +
1170 +       if (selected_ctx_u->pong_addr) {
1171 +               reg = selected_ctx->pong_addr;
1172 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1173 +                              ISPCSI2_CTX_DAT_PONG_ADDR(ctxnum));
1174 +               selected_ctx_u->pong_addr = false;
1175 +       }
1176 +       return 0;
1177 +}
1178 +
1179 +/**
1180 + * isp_csi2_ctx_get - Gets specific CSI2 Context configuration
1181 + * @ctxnum: Context number, valid between 0 and 7 values.
1182 + *
1183 + * Always returns 0.
1184 + **/
1185 +int isp_csi2_ctx_get(u8 ctxnum)
1186 +{
1187 +       struct isp_csi2_ctx_cfg *selected_ctx;
1188 +       struct isp_csi2_ctx_cfg_update *selected_ctx_u;
1189 +       u32 reg;
1190 +
1191 +       isp_csi2_ctx_validate(&ctxnum);
1192 +
1193 +       selected_ctx = &current_csi2_cfg.contexts[ctxnum];
1194 +       selected_ctx_u = &current_csi2_cfg_update.contexts[ctxnum];
1195 +
1196 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTX_CTRL1(ctxnum));
1197 +       selected_ctx->frame_count = (reg & ISPCSI2_CTX_CTRL1_COUNT_MASK) >>
1198 +               ISPCSI2_CTX_CTRL1_COUNT_SHIFT;
1199 +       selected_ctx_u->frame_count = false;
1200 +
1201 +       if ((reg & ISPCSI2_CTX_CTRL1_EOF_EN_MASK) ==
1202 +           ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE)
1203 +               selected_ctx->eof_enabled = true;
1204 +       else
1205 +               selected_ctx->eof_enabled = false;
1206 +       selected_ctx_u->eof_enabled = false;
1207 +
1208 +       if ((reg & ISPCSI2_CTX_CTRL1_EOL_EN_MASK) ==
1209 +           ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE)
1210 +               selected_ctx->eol_enabled = true;
1211 +       else
1212 +               selected_ctx->eol_enabled = false;
1213 +       selected_ctx_u->eol_enabled = false;
1214 +
1215 +       if ((reg & ISPCSI2_CTX_CTRL1_CS_EN_MASK) ==
1216 +           ISPCSI2_CTX_CTRL1_CS_EN_ENABLE)
1217 +               selected_ctx->checksum_enabled = true;
1218 +       else
1219 +               selected_ctx->checksum_enabled = false;
1220 +       selected_ctx_u->checksum_enabled = false;
1221 +
1222 +       if ((reg & ISPCSI2_CTX_CTRL1_CTX_EN_MASK) ==
1223 +           ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE)
1224 +               selected_ctx->enabled = true;
1225 +       else
1226 +               selected_ctx->enabled = false;
1227 +       selected_ctx_u->enabled = false;
1228 +       update_ctx_ctrl1[ctxnum] = false;
1229 +
1230 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTX_CTRL2(ctxnum));
1231 +
1232 +       selected_ctx->virtual_id = (reg & ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK) >>
1233 +               ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
1234 +       selected_ctx_u->virtual_id = false;
1235 +
1236 +       switch ((reg & ISPCSI2_CTX_CTRL2_FORMAT_MASK) >>
1237 +               ISPCSI2_CTX_CTRL2_FORMAT_SHIFT) {
1238 +       case 0x22:
1239 +               selected_ctx->format.pixelformat = V4L2_PIX_FMT_RGB565;
1240 +               break;
1241 +       case 0x9E:
1242 +       case 0x1E:
1243 +               selected_ctx->format.pixelformat = V4L2_PIX_FMT_YUYV;
1244 +               break;
1245 +       case 0xA1:
1246 +               selected_ctx->format.pixelformat = V4L2_PIX_FMT_RGB555;
1247 +               break;
1248 +       case 0xAB:
1249 +       case 0x12F:
1250 +               selected_ctx->format.pixelformat = V4L2_PIX_FMT_SGRBG10;
1251 +               break;
1252 +       }
1253 +       selected_ctx_u->format = false;
1254 +       update_ctx_ctrl2[ctxnum] = false;
1255 +
1256 +       selected_ctx->alpha = (isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1257 +                                            ISPCSI2_CTX_CTRL3(ctxnum)) &
1258 +                              ISPCSI2_CTX_CTRL3_ALPHA_MASK) >>
1259 +               ISPCSI2_CTX_CTRL3_ALPHA_SHIFT;
1260 +       selected_ctx_u->alpha = false;
1261 +       update_ctx_ctrl3[ctxnum] = false;
1262 +
1263 +       selected_ctx->data_offset = (isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1264 +                                                  ISPCSI2_CTX_DAT_OFST(ctxnum)) &
1265 +                                    ISPCSI2_CTX_DAT_OFST_OFST_MASK) >>
1266 +               ISPCSI2_CTX_DAT_OFST_OFST_SHIFT;
1267 +       selected_ctx_u->data_offset = false;
1268 +
1269 +       selected_ctx->ping_addr = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1270 +                                               ISPCSI2_CTX_DAT_PING_ADDR(ctxnum));
1271 +       selected_ctx_u->ping_addr = false;
1272 +
1273 +       selected_ctx->pong_addr = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1274 +                                               ISPCSI2_CTX_DAT_PONG_ADDR(ctxnum));
1275 +       selected_ctx_u->pong_addr = false;
1276 +       return 0;
1277 +}
1278 +
1279 +/**
1280 + * isp_csi2_ctx_update_all - Applies all CSI2 context configuration.
1281 + * @force_update: Flag to force rewrite of registers, even if they haven't been
1282 + *                updated with the isp_csi2_ctx_config_*() functions.
1283 + *
1284 + * It only saves settings when they were previously updated using the
1285 + * isp_csi2_ctx_config_*() functions, unless the force_update flag is
1286 + * set to true.
1287 + * Always returns 0.
1288 + **/
1289 +int isp_csi2_ctx_update_all(bool force_update)
1290 +{
1291 +       u8 ctxnum;
1292 +
1293 +       for (ctxnum = 0; ctxnum < 8; ctxnum++)
1294 +               isp_csi2_ctx_update(ctxnum, force_update);
1295 +
1296 +       return 0;
1297 +}
1298 +
1299 +/**
1300 + * isp_csi2_ctx_get_all - Gets all CSI2 Context configurations
1301 + *
1302 + * Always returns 0.
1303 + **/
1304 +int isp_csi2_ctx_get_all(void)
1305 +{
1306 +       u8 ctxnum;
1307 +
1308 +       for (ctxnum = 0; ctxnum < 8; ctxnum++)
1309 +               isp_csi2_ctx_get(ctxnum);
1310 +
1311 +       return 0;
1312 +}
1313 +
1314 +int isp_csi2_phy_config(struct isp_csi2_phy_cfg *desiredphyconfig)
1315 +{
1316 +       struct isp_csi2_phy_cfg *currphy = &current_csi2_cfg.phy;
1317 +       struct isp_csi2_phy_cfg_update *currphy_u =
1318 +                                               &current_csi2_cfg_update.phy;
1319 +
1320 +       if ((desiredphyconfig->tclk_term > 0x7f) ||
1321 +                               (desiredphyconfig->tclk_miss > 0x3)) {
1322 +               printk(KERN_ERR "Invalid PHY configuration sent by the"
1323 +                                                               " driver\n");
1324 +               return -EINVAL;
1325 +       }
1326 +
1327 +       if (currphy->ths_term != desiredphyconfig->ths_term) {
1328 +               currphy->ths_term = desiredphyconfig->ths_term;
1329 +               currphy_u->ths_term = true;
1330 +               update_phy_cfg0 = true;
1331 +       }
1332 +       if (currphy->ths_settle != desiredphyconfig->ths_settle) {
1333 +               currphy->ths_settle = desiredphyconfig->ths_settle;
1334 +               currphy_u->ths_settle = true;
1335 +               update_phy_cfg0 = true;
1336 +       }
1337 +       if (currphy->tclk_term != desiredphyconfig->tclk_term) {
1338 +               currphy->tclk_term = desiredphyconfig->tclk_term;
1339 +               currphy_u->tclk_term = true;
1340 +               update_phy_cfg1 = true;
1341 +       }
1342 +       if (currphy->tclk_miss != desiredphyconfig->tclk_miss) {
1343 +               currphy->tclk_miss = desiredphyconfig->tclk_miss;
1344 +               currphy_u->tclk_miss = true;
1345 +               update_phy_cfg1 = true;
1346 +       }
1347 +       if (currphy->tclk_settle != desiredphyconfig->tclk_settle) {
1348 +               currphy->tclk_settle = desiredphyconfig->tclk_settle;
1349 +               currphy_u->tclk_settle = true;
1350 +               update_phy_cfg1 = true;
1351 +       }
1352 +       return 0;
1353 +}
1354 +
1355 +/**
1356 + * isp_csi2_calc_phy_cfg0 - Calculates D-PHY config based on the MIPIClk speed.
1357 + * @mipiclk: MIPI clock frequency being used with CSI2 sensor.
1358 + * @lbound_hs_settle: Lower bound for CSI2 High Speed Settle transition.
1359 + * @ubound_hs_settle: Upper bound for CSI2 High Speed Settle transition.
1360 + *
1361 + * From TRM, we have the same calculation for HS Termination signal.
1362 + *  THS_TERM  = ceil( 12.5ns / DDRCLK period ) - 1
1363 + * But for Settle, we use the mid value between the two passed boundaries from
1364 + * sensor:
1365 + *  THS_SETTLE = (Upper bound + Lower bound) / 2
1366 + *
1367 + * Always returns 0.
1368 + */
1369 +int isp_csi2_calc_phy_cfg0(u32 mipiclk, u32 lbound_hs_settle,
1370 +                                                       u32 ubound_hs_settle)
1371 +{
1372 +       struct isp_csi2_phy_cfg *currphy = &current_csi2_cfg.phy;
1373 +       struct isp_csi2_phy_cfg_update *currphy_u =
1374 +                                               &current_csi2_cfg_update.phy;
1375 +       u32 tmp, ddrclk = mipiclk >> 1;
1376 +
1377 +       /* Calculate THS_TERM */
1378 +       tmp = ddrclk / 80000000;
1379 +       if ((ddrclk % 80000000) > 0)
1380 +               tmp++;
1381 +       currphy->ths_term = tmp - 1;
1382 +       currphy_u->ths_term = true;
1383 +
1384 +       /* Calculate THS_SETTLE */
1385 +       currphy->ths_settle = (ubound_hs_settle + lbound_hs_settle) / 2;
1386 +
1387 +       currphy_u->ths_settle = true;
1388 +       isp_csi2_phy_update(true);
1389 +       return 0;
1390 +}
1391 +EXPORT_SYMBOL(isp_csi2_calc_phy_cfg0);
1392 +
1393 +/**
1394 + * isp_csi2_phy_update - Applies CSI2 D-PHY configuration.
1395 + * @force_update: Flag to force rewrite of registers, even if they haven't been
1396 + *                updated with the isp_csi2_phy_config_*() functions.
1397 + *
1398 + * It only saves settings when they were previously updated using the
1399 + * isp_csi2_phy_config_*() functions, unless the force_update flag is
1400 +       * set to true.
1401 +       * Always returns 0.
1402 +       **/
1403 +int isp_csi2_phy_update(bool force_update)
1404 +{
1405 +       struct isp_csi2_phy_cfg *currphy = &current_csi2_cfg.phy;
1406 +       struct isp_csi2_phy_cfg_update *currphy_u =
1407 +               &current_csi2_cfg_update.phy;
1408 +       u32 reg;
1409 +
1410 +       if (update_phy_cfg0 || force_update) {
1411 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0);
1412 +               if (currphy_u->ths_term || force_update) {
1413 +                       reg &= ~ISPCSI2PHY_CFG0_THS_TERM_MASK;
1414 +                       reg |= (currphy->ths_term <<
1415 +                               ISPCSI2PHY_CFG0_THS_TERM_SHIFT);
1416 +                       currphy_u->ths_term = false;
1417 +               }
1418 +               if (currphy_u->ths_settle || force_update) {
1419 +                       reg &= ~ISPCSI2PHY_CFG0_THS_SETTLE_MASK;
1420 +                       reg |= (currphy->ths_settle <<
1421 +                               ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT);
1422 +                       currphy_u->ths_settle = false;
1423 +               }
1424 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0);
1425 +               update_phy_cfg0 = false;
1426 +       }
1427 +
1428 +       if (update_phy_cfg1 || force_update) {
1429 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1);
1430 +               if (currphy_u->tclk_term || force_update) {
1431 +                       reg &= ~ISPCSI2PHY_CFG1_TCLK_TERM_MASK;
1432 +                       reg |= (currphy->tclk_term <<
1433 +                               ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT);
1434 +                       currphy_u->tclk_term = false;
1435 +               }
1436 +               if (currphy_u->tclk_miss || force_update) {
1437 +                       reg &= ~ISPCSI2PHY_CFG1_TCLK_MISS_MASK;
1438 +                       reg |= (currphy->tclk_miss <<
1439 +                               ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT);
1440 +                       currphy_u->tclk_miss = false;
1441 +               }
1442 +               if (currphy_u->tclk_settle || force_update) {
1443 +                       reg &= ~ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK;
1444 +                       reg |= (currphy->tclk_settle <<
1445 +                               ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT);
1446 +                       currphy_u->tclk_settle = false;
1447 +               }
1448 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1);
1449 +               update_phy_cfg1 = false;
1450 +       }
1451 +       return 0;
1452 +}
1453 +
1454 +/**
1455 + * isp_csi2_phy_get - Gets CSI2 D-PHY configuration
1456 + *
1457 + * Gets settings from HW registers and fills in the internal driver memory
1458 + * Always returns 0.
1459 + **/
1460 +int isp_csi2_phy_get(void)
1461 +{
1462 +       struct isp_csi2_phy_cfg *currphy = &current_csi2_cfg.phy;
1463 +       struct isp_csi2_phy_cfg_update *currphy_u =
1464 +               &current_csi2_cfg_update.phy;
1465 +       u32 reg;
1466 +
1467 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0);
1468 +       currphy->ths_term = (reg & ISPCSI2PHY_CFG0_THS_TERM_MASK) >>
1469 +               ISPCSI2PHY_CFG0_THS_TERM_SHIFT;
1470 +       currphy_u->ths_term = false;
1471 +
1472 +       currphy->ths_settle = (reg & ISPCSI2PHY_CFG0_THS_SETTLE_MASK) >>
1473 +               ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT;
1474 +       currphy_u->ths_settle = false;
1475 +       update_phy_cfg0 = false;
1476 +
1477 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1);
1478 +
1479 +       currphy->tclk_term = (reg & ISPCSI2PHY_CFG1_TCLK_TERM_MASK) >>
1480 +               ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT;
1481 +       currphy_u->tclk_term = false;
1482 +
1483 +       currphy->tclk_miss = (reg & ISPCSI2PHY_CFG1_TCLK_MISS_MASK) >>
1484 +               ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT;
1485 +       currphy_u->tclk_miss = false;
1486 +
1487 +       currphy->tclk_settle = (reg & ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK) >>
1488 +               ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT;
1489 +       currphy_u->tclk_settle = false;
1490 +
1491 +       update_phy_cfg1 = false;
1492 +       return 0;
1493 +}
1494 +
1495 +/**
1496 + * isp_csi2_timings_config_forcerxmode - Sets Force Rx mode on stop state count
1497 + * @force_rx_mode: Boolean to enable/disable forcing Rx mode in CSI2 receiver
1498 + *
1499 + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected.
1500 + **/
1501 +int isp_csi2_timings_config_forcerxmode(u8 io, bool force_rx_mode)
1502 +{
1503 +       struct isp_csi2_timings_cfg *currtimings;
1504 +       struct isp_csi2_timings_cfg_update *currtimings_u;
1505 +
1506 +       if (io < 1 || io > 2) {
1507 +               printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n");
1508 +               return -EINVAL;
1509 +       }
1510 +
1511 +       currtimings = &current_csi2_cfg.timings[io - 1];
1512 +       currtimings_u = &current_csi2_cfg_update.timings[io - 1];
1513 +       if (currtimings->force_rx_mode != force_rx_mode) {
1514 +               currtimings->force_rx_mode = force_rx_mode;
1515 +               currtimings_u->force_rx_mode = true;
1516 +               update_timing = true;
1517 +       }
1518 +       return 0;
1519 +}
1520 +
1521 +/**
1522 + * isp_csi2_timings_config_stopstate_16x - Sets 16x factor for L3 cycles
1523 + * @stop_state_16x: Boolean to use or not use the 16x multiplier for stop count
1524 + *
1525 + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected.
1526 + **/
1527 +int isp_csi2_timings_config_stopstate_16x(u8 io, bool stop_state_16x)
1528 +{
1529 +       struct isp_csi2_timings_cfg *currtimings;
1530 +       struct isp_csi2_timings_cfg_update *currtimings_u;
1531 +
1532 +       if (io < 1 || io > 2) {
1533 +               printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n");
1534 +               return -EINVAL;
1535 +       }
1536 +
1537 +       currtimings = &current_csi2_cfg.timings[io - 1];
1538 +       currtimings_u = &current_csi2_cfg_update.timings[io - 1];
1539 +       if (currtimings->stop_state_16x != stop_state_16x) {
1540 +               currtimings->stop_state_16x = stop_state_16x;
1541 +               currtimings_u->stop_state_16x = true;
1542 +               update_timing = true;
1543 +       }
1544 +       return 0;
1545 +}
1546 +
1547 +/**
1548 + * isp_csi2_timings_config_stopstate_4x - Sets 4x factor for L3 cycles
1549 + * @stop_state_4x: Boolean to use or not use the 4x multiplier for stop count
1550 + *
1551 + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected.
1552 + **/
1553 +int isp_csi2_timings_config_stopstate_4x(u8 io, bool stop_state_4x)
1554 +{
1555 +       struct isp_csi2_timings_cfg *currtimings;
1556 +       struct isp_csi2_timings_cfg_update *currtimings_u;
1557 +
1558 +       if (io < 1 || io > 2) {
1559 +               printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n");
1560 +               return -EINVAL;
1561 +       }
1562 +
1563 +       currtimings = &current_csi2_cfg.timings[io - 1];
1564 +       currtimings_u = &current_csi2_cfg_update.timings[io - 1];
1565 +       if (currtimings->stop_state_4x != stop_state_4x) {
1566 +               currtimings->stop_state_4x = stop_state_4x;
1567 +               currtimings_u->stop_state_4x = true;
1568 +               update_timing = true;
1569 +       }
1570 +       return 0;
1571 +}
1572 +
1573 +/**
1574 + * isp_csi2_timings_config_stopstate_cnt - Sets L3 cycles
1575 + * @stop_state_counter: Stop state counter value for L3 cycles
1576 + *
1577 + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected.
1578 + **/
1579 +int isp_csi2_timings_config_stopstate_cnt(u8 io, u16 stop_state_counter)
1580 +{
1581 +       struct isp_csi2_timings_cfg *currtimings;
1582 +       struct isp_csi2_timings_cfg_update *currtimings_u;
1583 +
1584 +       if (io < 1 || io > 2) {
1585 +               printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n");
1586 +               return -EINVAL;
1587 +       }
1588 +
1589 +       currtimings = &current_csi2_cfg.timings[io - 1];
1590 +       currtimings_u = &current_csi2_cfg_update.timings[io - 1];
1591 +       if (currtimings->stop_state_counter != stop_state_counter) {
1592 +               currtimings->stop_state_counter = (stop_state_counter & 0x1FFF);
1593 +               currtimings_u->stop_state_counter = true;
1594 +               update_timing = true;
1595 +       }
1596 +       return 0;
1597 +}
1598 +
1599 +/**
1600 + * isp_csi2_timings_update - Applies specified CSI2 timing configuration.
1601 + * @io: IO number (1 or 2) which specifies which ComplexIO are we updating
1602 + * @force_update: Flag to force rewrite of registers, even if they haven't been
1603 + *                updated with the isp_csi2_timings_config_*() functions.
1604 + *
1605 + * It only saves settings when they were previously updated using the
1606 + * isp_csi2_timings_config_*() functions, unless the force_update flag is
1607 + * set to true.
1608 + * Returns 0 if successful, or -EINVAL if invalid IO number is passed.
1609 + **/
1610 +int isp_csi2_timings_update(u8 io, bool force_update)
1611 +{
1612 +       struct isp_csi2_timings_cfg *currtimings;
1613 +       struct isp_csi2_timings_cfg_update *currtimings_u;
1614 +       u32 reg;
1615 +
1616 +       if (io < 1 || io > 2) {
1617 +               printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n");
1618 +               return -EINVAL;
1619 +       }
1620 +
1621 +       currtimings = &current_csi2_cfg.timings[io - 1];
1622 +       currtimings_u = &current_csi2_cfg_update.timings[io - 1];
1623 +
1624 +       if (update_timing || force_update) {
1625 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING);
1626 +               if (currtimings_u->force_rx_mode || force_update) {
1627 +                       reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(io);
1628 +                       if (currtimings->force_rx_mode)
1629 +                               reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE
1630 +                                       (io);
1631 +                       else
1632 +                               reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO_DISABLE
1633 +                                       (io);
1634 +                       currtimings_u->force_rx_mode = false;
1635 +               }
1636 +               if (currtimings_u->stop_state_16x || force_update) {
1637 +                       reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(io);
1638 +                       if (currtimings->stop_state_16x)
1639 +                               reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE
1640 +                                       (io);
1641 +                       else
1642 +                               reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO_DISABLE
1643 +                                       (io);
1644 +                       currtimings_u->stop_state_16x = false;
1645 +               }
1646 +               if (currtimings_u->stop_state_4x || force_update) {
1647 +                       reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(io);
1648 +                       if (currtimings->stop_state_4x) {
1649 +                               reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE
1650 +                                       (io);
1651 +                       } else {
1652 +                               reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO_DISABLE
1653 +                                       (io);
1654 +                       }
1655 +                       currtimings_u->stop_state_4x = false;
1656 +               }
1657 +               if (currtimings_u->stop_state_counter || force_update) {
1658 +                       reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(io);
1659 +                       reg |= currtimings->stop_state_counter <<
1660 +                               ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(io);
1661 +                       currtimings_u->stop_state_counter = false;
1662 +               }
1663 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING);
1664 +               update_timing = false;
1665 +       }
1666 +       return 0;
1667 +}
1668 +
1669 +/**
1670 + * isp_csi2_timings_get - Gets specific CSI2 ComplexIO timing configuration
1671 + * @io: IO number (1 or 2) which specifies which ComplexIO are we getting
1672 + *
1673 + * Gets settings from HW registers and fills in the internal driver memory
1674 + * Returns 0 if successful, or -EINVAL if invalid IO number is passed.
1675 + **/
1676 +int isp_csi2_timings_get(u8 io)
1677 +{
1678 +       struct isp_csi2_timings_cfg *currtimings;
1679 +       struct isp_csi2_timings_cfg_update *currtimings_u;
1680 +       u32 reg;
1681 +
1682 +       if (io < 1 || io > 2) {
1683 +               printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n");
1684 +               return -EINVAL;
1685 +       }
1686 +
1687 +       currtimings = &current_csi2_cfg.timings[io - 1];
1688 +       currtimings_u = &current_csi2_cfg_update.timings[io - 1];
1689 +
1690 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING);
1691 +       if ((reg & ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(io)) ==
1692 +           ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE(io))
1693 +               currtimings->force_rx_mode = true;
1694 +       else
1695 +               currtimings->force_rx_mode = false;
1696 +       currtimings_u->force_rx_mode = false;
1697 +
1698 +       if ((reg & ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(io)) ==
1699 +           ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE(io))
1700 +               currtimings->stop_state_16x = true;
1701 +       else
1702 +               currtimings->stop_state_16x = false;
1703 +       currtimings_u->stop_state_16x = false;
1704 +
1705 +       if ((reg & ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(io)) ==
1706 +           ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE(io))
1707 +               currtimings->stop_state_4x = true;
1708 +       else
1709 +               currtimings->stop_state_4x = false;
1710 +       currtimings_u->stop_state_4x = false;
1711 +
1712 +       currtimings->stop_state_counter = (reg &
1713 +                                          ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(io)) >>
1714 +               ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(io);
1715 +       currtimings_u->stop_state_counter = false;
1716 +       update_timing = false;
1717 +       return 0;
1718 +}
1719 +
1720 +/**
1721 + * isp_csi2_timings_update_all - Applies specified CSI2 timing configuration.
1722 + * @force_update: Flag to force rewrite of registers, even if they haven't been
1723 + *                updated with the isp_csi2_timings_config_*() functions.
1724 + *
1725 + * It only saves settings when they were previously updated using the
1726 + * isp_csi2_timings_config_*() functions, unless the force_update flag is
1727 + * set to true.
1728 + * Always returns 0.
1729 + **/
1730 +int isp_csi2_timings_update_all(bool force_update)
1731 +{
1732 +       int i;
1733 +
1734 +       for (i = 1; i < 3; i++)
1735 +               isp_csi2_timings_update(i, force_update);
1736 +       return 0;
1737 +}
1738 +
1739 +/**
1740 + * isp_csi2_timings_get_all - Gets all CSI2 ComplexIO timing configurations
1741 + *
1742 + * Always returns 0.
1743 + **/
1744 +int isp_csi2_timings_get_all(void)
1745 +{
1746 +       int i;
1747 +
1748 +       for (i = 1; i < 3; i++)
1749 +               isp_csi2_timings_get(i);
1750 +       return 0;
1751 +}
1752 +
1753 +/**
1754 + * isp_csi2_isr - CSI2 interrupt handling.
1755 + **/
1756 +void isp_csi2_isr(void)
1757 +{
1758 +       u32 csi2_irqstatus, cpxio1_irqstatus, ctxirqstatus;
1759 +
1760 +       csi2_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1761 +                                      ISPCSI2_IRQSTATUS);
1762 +       isp_reg_writel(csi2_irqstatus, OMAP3_ISP_IOMEM_CSI2A,
1763 +                      ISPCSI2_IRQSTATUS);
1764 +
1765 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) {
1766 +               cpxio1_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1767 +                                                ISPCSI2_COMPLEXIO1_IRQSTATUS);
1768 +               isp_reg_writel(cpxio1_irqstatus, OMAP3_ISP_IOMEM_CSI2A,
1769 +                              ISPCSI2_COMPLEXIO1_IRQSTATUS);
1770 +               printk(KERN_ERR "CSI2: ComplexIO Error IRQ %x\n",
1771 +                      cpxio1_irqstatus);
1772 +       }
1773 +
1774 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) {
1775 +               ctxirqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1776 +                                            ISPCSI2_CTX_IRQSTATUS(0));
1777 +               isp_reg_writel(ctxirqstatus, OMAP3_ISP_IOMEM_CSI2A,
1778 +                              ISPCSI2_CTX_IRQSTATUS(0));
1779 +       }
1780 +
1781 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_OCP_ERR_IRQ)
1782 +               printk(KERN_ERR "CSI2: OCP Transmission Error\n");
1783 +
1784 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ)
1785 +               printk(KERN_ERR "CSI2: Short packet receive error\n");
1786 +
1787 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ)
1788 +               printk(KERN_DEBUG "CSI2: ECC correction done\n");
1789 +
1790 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ)
1791 +               printk(KERN_ERR "CSI2: ECC correction failed\n");
1792 +
1793 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ)
1794 +               printk(KERN_ERR "CSI2: ComplexIO #2 failed\n");
1795 +
1796 +       if (csi2_irqstatus & ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)
1797 +               printk(KERN_ERR "CSI2: FIFO overflow error\n");
1798 +
1799 +       return;
1800 +}
1801 +EXPORT_SYMBOL(isp_csi2_isr);
1802 +
1803 +/**
1804 + * isp_csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
1805 + * @enable: Enable/disable CSI2 ComplexIO #1 interrupts
1806 + **/
1807 +void isp_csi2_irq_complexio1_set(int enable)
1808 +{
1809 +       u32 reg;
1810 +       reg = ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMEXIT |
1811 +               ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMENTER |
1812 +               ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM5 |
1813 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL5 |
1814 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC5 |
1815 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS5 |
1816 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS5 |
1817 +               ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM4 |
1818 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL4 |
1819 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC4 |
1820 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS4 |
1821 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS4 |
1822 +               ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM3 |
1823 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL3 |
1824 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC3 |
1825 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS3 |
1826 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS3 |
1827 +               ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM2 |
1828 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL2 |
1829 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC2 |
1830 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS2 |
1831 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS2 |
1832 +               ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM1 |
1833 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL1 |
1834 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC1 |
1835 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS1 |
1836 +               ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS1;
1837 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1838 +                      ISPCSI2_COMPLEXIO1_IRQSTATUS);
1839 +       if (enable) {
1840 +               reg |= isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
1841 +                                    ISPCSI2_COMPLEXIO1_IRQENABLE);
1842 +       } else
1843 +               reg = 0;
1844 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1845 +                      ISPCSI2_COMPLEXIO1_IRQENABLE);
1846 +}
1847 +EXPORT_SYMBOL(isp_csi2_irq_complexio1_set);
1848 +
1849 +/**
1850 + * isp_csi2_irq_ctx_set - Enables CSI2 Context IRQs.
1851 + * @enable: Enable/disable CSI2 Context interrupts
1852 + **/
1853 +void isp_csi2_irq_ctx_set(int enable)
1854 +{
1855 +       u32 reg;
1856 +       int i;
1857 +
1858 +       reg = ISPCSI2_CTX_IRQSTATUS_FS_IRQ | ISPCSI2_CTX_IRQSTATUS_FE_IRQ;
1859 +       for (i = 0; i < 8; i++) {
1860 +               isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A,
1861 +                              ISPCSI2_CTX_IRQSTATUS(i));
1862 +               if (enable) {
1863 +                       isp_reg_or(OMAP3_ISP_IOMEM_CSI2A,
1864 +                                  ISPCSI2_CTX_IRQENABLE(i), reg);
1865 +               } else {
1866 +                       isp_reg_writel(0, OMAP3_ISP_IOMEM_CSI2A,
1867 +                                      ISPCSI2_CTX_IRQENABLE(i));
1868 +               }
1869 +       }
1870 +
1871 +}
1872 +EXPORT_SYMBOL(isp_csi2_irq_ctx_set);
1873 +
1874 +/**
1875 + * isp_csi2_irq_status_set - Enables CSI2 Status IRQs.
1876 + * @enable: Enable/disable CSI2 Status interrupts
1877 + **/
1878 +void isp_csi2_irq_status_set(int enable)
1879 +{
1880 +       u32 reg;
1881 +       reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
1882 +               ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
1883 +               ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ |
1884 +               ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
1885 +               ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
1886 +               ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ |
1887 +               ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ |
1888 +               ISPCSI2_IRQSTATUS_CONTEXT(0);
1889 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQSTATUS);
1890 +       if (enable)
1891 +               reg |= isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQENABLE);
1892 +       else
1893 +               reg = 0;
1894 +
1895 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQENABLE);
1896 +}
1897 +EXPORT_SYMBOL(isp_csi2_irq_status_set);
1898 +
1899 +/**
1900 + * isp_csi2_irq_status_set - Enables main CSI2 IRQ.
1901 + * @enable: Enable/disable main CSI2 interrupt
1902 + **/
1903 +void isp_csi2_irq_set(int enable)
1904 +{
1905 +       isp_reg_writel(IRQ0STATUS_CSIA_IRQ, OMAP3_ISP_IOMEM_MAIN,
1906 +                      ISP_IRQ0STATUS);
1907 +       isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE,
1908 +                      ~IRQ0ENABLE_CSIA_IRQ,
1909 +                      (enable ? IRQ0ENABLE_CSIA_IRQ : 0));
1910 +}
1911 +EXPORT_SYMBOL(isp_csi2_irq_set);
1912 +
1913 +/**
1914 + * isp_csi2_irq_all_set - Enable/disable CSI2 interrupts.
1915 + * @enable: 0-Disable, 1-Enable.
1916 + **/
1917 +void isp_csi2_irq_all_set(int enable)
1918 +{
1919 +       if (enable) {
1920 +               isp_csi2_irq_complexio1_set(enable);
1921 +               isp_csi2_irq_ctx_set(enable);
1922 +               isp_csi2_irq_status_set(enable);
1923 +               isp_csi2_irq_set(enable);
1924 +       } else {
1925 +               isp_csi2_irq_set(enable);
1926 +               isp_csi2_irq_status_set(enable);
1927 +               isp_csi2_irq_ctx_set(enable);
1928 +               isp_csi2_irq_complexio1_set(enable);
1929 +       }
1930 +       return;
1931 +}
1932 +EXPORT_SYMBOL(isp_csi2_irq_all_set);
1933 +
1934 +/**
1935 + * isp_csi2_reset - Resets the CSI2 module.
1936 + *
1937 + * Returns 0 if successful, or -EBUSY if power command didn't respond.
1938 + **/
1939 +int isp_csi2_reset(void)
1940 +{
1941 +       u32 reg;
1942 +       u8 soft_reset_retries = 0;
1943 +       int i;
1944 +
1945 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG);
1946 +       reg |= ISPCSI2_SYSCONFIG_SOFT_RESET_RESET;
1947 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG);
1948 +
1949 +       do {
1950 +               reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSSTATUS) &
1951 +                       ISPCSI2_SYSSTATUS_RESET_DONE_MASK;
1952 +               if (reg == ISPCSI2_SYSSTATUS_RESET_DONE_DONE)
1953 +                       break;
1954 +               soft_reset_retries++;
1955 +               if (soft_reset_retries < 5)
1956 +                       udelay(100);
1957 +       } while (soft_reset_retries < 5);
1958 +
1959 +       if (soft_reset_retries == 5) {
1960 +               printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n");
1961 +               return -EBUSY;
1962 +       }
1963 +
1964 +       reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG);
1965 +       reg &= ~ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK;
1966 +       reg |= ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO;
1967 +       reg &= ~ISPCSI2_SYSCONFIG_AUTO_IDLE_MASK;
1968 +       isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG);
1969 +
1970 +       uses_videoport = false;
1971 +       update_complexio_cfg1 = false;
1972 +       update_phy_cfg0 = false;
1973 +       update_phy_cfg1 = false;
1974 +       for (i = 0; i < 8; i++) {
1975 +               update_ctx_ctrl1[i] = false;
1976 +               update_ctx_ctrl2[i] = false;
1977 +               update_ctx_ctrl3[i] = false;
1978 +       }
1979 +       update_timing = false;
1980 +       update_ctrl = false;
1981 +
1982 +       isp_csi2_complexio_lanes_get();
1983 +       isp_csi2_ctrl_get();
1984 +       isp_csi2_ctx_get_all();
1985 +       isp_csi2_phy_get();
1986 +       isp_csi2_timings_get_all();
1987 +
1988 +       isp_csi2_complexio_power_autoswitch(true);
1989 +       isp_csi2_complexio_power(ISP_CSI2_POWER_ON);
1990 +
1991 +       isp_csi2_timings_config_forcerxmode(1, true);
1992 +       isp_csi2_timings_config_stopstate_cnt(1, 0x1FF);
1993 +       isp_csi2_timings_update_all(true);
1994 +
1995 +       return 0;
1996 +}
1997 +
1998 +/**
1999 + * isp_csi2_enable - Enables the CSI2 module.
2000 + * @enable: Enables/disables the CSI2 module.
2001 + **/
2002 +void isp_csi2_enable(int enable)
2003 +{
2004 +       if (enable) {
2005 +               isp_csi2_ctx_config_enabled(0, true);
2006 +               isp_csi2_ctx_config_eof_enabled(0, true);
2007 +               isp_csi2_ctx_config_checksum_enabled(0, true);
2008 +               isp_csi2_ctx_update(0, false);
2009 +
2010 +               isp_csi2_ctrl_config_ecc_enable(true);
2011 +               isp_csi2_ctrl_config_if_enable(true);
2012 +               isp_csi2_ctrl_update(false);
2013 +       } else {
2014 +               isp_csi2_ctx_config_enabled(0, false);
2015 +               isp_csi2_ctx_config_eof_enabled(0, false);
2016 +               isp_csi2_ctx_config_checksum_enabled(0, false);
2017 +               isp_csi2_ctx_update(0, false);
2018 +
2019 +               isp_csi2_ctrl_config_ecc_enable(false);
2020 +               isp_csi2_ctrl_config_if_enable(false);
2021 +               isp_csi2_ctrl_update(false);
2022 +       }
2023 +}
2024 +EXPORT_SYMBOL(isp_csi2_enable);
2025 +
2026 +/**
2027 + * isp_csi2_regdump - Prints CSI2 debug information.
2028 + **/
2029 +void isp_csi2_regdump(void)
2030 +{
2031 +       printk(KERN_DEBUG "-------------Register dump-------------\n");
2032 +
2033 +       printk(KERN_DEBUG "ISP_CTRL: %x\n",
2034 +              isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL));
2035 +       printk(KERN_DEBUG "ISP_TCTRL_CTRL: %x\n",
2036 +              isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL));
2037 +
2038 +       printk(KERN_DEBUG "ISPCCDC_SDR_ADDR: %x\n",
2039 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR));
2040 +       printk(KERN_DEBUG "ISPCCDC_SYN_MODE: %x\n",
2041 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE));
2042 +       printk(KERN_DEBUG "ISPCCDC_CFG: %x\n",
2043 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG));
2044 +       printk(KERN_DEBUG "ISPCCDC_FMTCFG: %x\n",
2045 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG));
2046 +       printk(KERN_DEBUG "ISPCCDC_HSIZE_OFF: %x\n",
2047 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF));
2048 +       printk(KERN_DEBUG "ISPCCDC_HORZ_INFO: %x\n",
2049 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO));
2050 +       printk(KERN_DEBUG "ISPCCDC_VERT_START: %x\n",
2051 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC,
2052 +                            ISPCCDC_VERT_START));
2053 +       printk(KERN_DEBUG "ISPCCDC_VERT_LINES: %x\n",
2054 +              isp_reg_readl(OMAP3_ISP_IOMEM_CCDC,
2055 +                            ISPCCDC_VERT_LINES));
2056 +
2057 +       printk(KERN_DEBUG "ISPCSI2_COMPLEXIO_CFG1: %x\n",
2058 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2059 +                            ISPCSI2_COMPLEXIO_CFG1));
2060 +       printk(KERN_DEBUG "ISPCSI2_SYSSTATUS: %x\n",
2061 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2062 +                            ISPCSI2_SYSSTATUS));
2063 +       printk(KERN_DEBUG "ISPCSI2_SYSCONFIG: %x\n",
2064 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2065 +                            ISPCSI2_SYSCONFIG));
2066 +       printk(KERN_DEBUG "ISPCSI2_IRQENABLE: %x\n",
2067 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2068 +                            ISPCSI2_IRQENABLE));
2069 +       printk(KERN_DEBUG "ISPCSI2_IRQSTATUS: %x\n",
2070 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2071 +                            ISPCSI2_IRQSTATUS));
2072 +
2073 +       printk(KERN_DEBUG "ISPCSI2_CTX_IRQENABLE(0): %x\n",
2074 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2075 +                            ISPCSI2_CTX_IRQENABLE(0)));
2076 +       printk(KERN_DEBUG "ISPCSI2_CTX_IRQSTATUS(0): %x\n",
2077 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2078 +                            ISPCSI2_CTX_IRQSTATUS(0)));
2079 +       printk(KERN_DEBUG "ISPCSI2_TIMING: %x\n",
2080 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING));
2081 +       printk(KERN_DEBUG "ISPCSI2PHY_CFG0: %x\n",
2082 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY,
2083 +                            ISPCSI2PHY_CFG0));
2084 +       printk(KERN_DEBUG "ISPCSI2PHY_CFG1: %x\n",
2085 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY,
2086 +                            ISPCSI2PHY_CFG1));
2087 +       printk(KERN_DEBUG "ISPCSI2_CTX_CTRL1(0): %x\n",
2088 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2089 +                            ISPCSI2_CTX_CTRL1(0)));
2090 +       printk(KERN_DEBUG "ISPCSI2_CTX_CTRL2(0): %x\n",
2091 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2092 +                            ISPCSI2_CTX_CTRL2(0)));
2093 +       printk(KERN_DEBUG "ISPCSI2_CTX_CTRL3(0): %x\n",
2094 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2095 +                            ISPCSI2_CTX_CTRL3(0)));
2096 +       printk(KERN_DEBUG "ISPCSI2_CTX_DAT_OFST(0): %x\n",
2097 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2098 +                            ISPCSI2_CTX_DAT_OFST(0)));
2099 +       printk(KERN_DEBUG "ISPCSI2_CTX_DAT_PING_ADDR(0): %x\n",
2100 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2101 +                            ISPCSI2_CTX_DAT_PING_ADDR(0)));
2102 +       printk(KERN_DEBUG "ISPCSI2_CTX_DAT_PONG_ADDR(0): %x\n",
2103 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A,
2104 +                            ISPCSI2_CTX_DAT_PONG_ADDR(0)));
2105 +       printk(KERN_DEBUG "ISPCSI2_CTRL: %x\n",
2106 +              isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL));
2107 +       printk(KERN_DEBUG "---------------------------------------\n");
2108 +}
2109 +
2110 +/**
2111 + * isp_csi2_cleanup - Routine for module driver cleanup
2112 + **/
2113 +void isp_csi2_cleanup(void)
2114 +{
2115 +       return;
2116 +}
2117 +
2118 +/**
2119 + * isp_csi2_init - Routine for module driver init
2120 + **/
2121 +int __init isp_csi2_init(void)
2122 +{
2123 +       int i;
2124 +
2125 +       update_complexio_cfg1 = false;
2126 +       update_phy_cfg0 = false;
2127 +       update_phy_cfg1 = false;
2128 +       for (i = 0; i < 8; i++) {
2129 +               update_ctx_ctrl1[i] = false;
2130 +               update_ctx_ctrl2[i] = false;
2131 +               update_ctx_ctrl3[i] = false;
2132 +       }
2133 +       update_timing = false;
2134 +       update_ctrl = false;
2135 +
2136 +       memset(&current_csi2_cfg, 0, sizeof(current_csi2_cfg));
2137 +       memset(&current_csi2_cfg_update, 0, sizeof(current_csi2_cfg_update));
2138 +       return 0;
2139 +}
2140 +
2141 +MODULE_AUTHOR("Texas Instruments");
2142 +MODULE_DESCRIPTION("ISP CSI2 Receiver Module");
2143 +MODULE_LICENSE("GPL");
2144 diff --git a/drivers/media/video/isp/ispcsi2.h b/drivers/media/video/isp/ispcsi2.h
2145 new file mode 100644
2146 index 0000000..4582c96
2147 --- /dev/null
2148 +++ b/drivers/media/video/isp/ispcsi2.h
2149 @@ -0,0 +1,232 @@
2150 +/*
2151 + * ispcsi2.h
2152 + *
2153 + * Copyright (C) 2009 Texas Instruments.
2154 + *
2155 + * Contributors:
2156 + *     Sergio Aguirre <saaguirre@ti.com>
2157 + *     Dominic Curran <dcurran@ti.com>
2158 + *
2159 + * This package is free software; you can redistribute it and/or modify
2160 + * it under the terms of the GNU General Public License version 2 as
2161 + * published by the Free Software Foundation.
2162 + *
2163 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2164 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2165 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2166 + */
2167 +
2168 +#ifndef OMAP_ISP_CSI2_API_H
2169 +#define OMAP_ISP_CSI2_API_H
2170 +#include <linux/videodev2.h>
2171 +
2172 +enum isp_csi2_irqevents {
2173 +       OCP_ERR_IRQ = 0x4000,
2174 +       SHORT_PACKET_IRQ = 0x2000,
2175 +       ECC_CORRECTION_IRQ = 0x1000,
2176 +       ECC_NO_CORRECTION_IRQ = 0x800,
2177 +       COMPLEXIO2_ERR_IRQ = 0x400,
2178 +       COMPLEXIO1_ERR_IRQ = 0x200,
2179 +       FIFO_OVF_IRQ = 0x100,
2180 +       CONTEXT7 = 0x80,
2181 +       CONTEXT6 = 0x40,
2182 +       CONTEXT5 = 0x20,
2183 +       CONTEXT4 = 0x10,
2184 +       CONTEXT3 = 0x8,
2185 +       CONTEXT2 = 0x4,
2186 +       CONTEXT1 = 0x2,
2187 +       CONTEXT0 = 0x1,
2188 +};
2189 +
2190 +enum isp_csi2_ctx_irqevents {
2191 +       CTX_ECC_CORRECTION = 0x100,
2192 +       CTX_LINE_NUMBER = 0x80,
2193 +       CTX_FRAME_NUMBER = 0x40,
2194 +       CTX_CS = 0x20,
2195 +       CTX_LE = 0x8,
2196 +       CTX_LS = 0x4,
2197 +       CTX_FE = 0x2,
2198 +       CTX_FS = 0x1,
2199 +};
2200 +
2201 +enum isp_csi2_power_cmds {
2202 +       ISP_CSI2_POWER_OFF,
2203 +       ISP_CSI2_POWER_ON,
2204 +       ISP_CSI2_POWER_ULPW,
2205 +};
2206 +
2207 +enum isp_csi2_frame_mode {
2208 +       ISP_CSI2_FRAME_IMMEDIATE,
2209 +       ISP_CSI2_FRAME_AFTERFEC,
2210 +};
2211 +
2212 +struct csi2_lanecfg {
2213 +       u8 pos;
2214 +       u8 pol;
2215 +};
2216 +
2217 +struct isp_csi2_lanes_cfg {
2218 +       struct csi2_lanecfg data[4];
2219 +       struct csi2_lanecfg clk;
2220 +};
2221 +
2222 +struct isp_csi2_lanes_cfg_update {
2223 +       bool data[4];
2224 +       bool clk;
2225 +};
2226 +
2227 +struct isp_csi2_phy_cfg {
2228 +       u8 ths_term;
2229 +       u8 ths_settle;
2230 +       u8 tclk_term;
2231 +       unsigned tclk_miss:1;
2232 +       u8 tclk_settle;
2233 +};
2234 +
2235 +struct isp_csi2_phy_cfg_update {
2236 +       bool ths_term;
2237 +       bool ths_settle;
2238 +       bool tclk_term;
2239 +       bool tclk_miss;
2240 +       bool tclk_settle;
2241 +};
2242 +
2243 +struct isp_csi2_ctx_cfg {
2244 +       u8 virtual_id;
2245 +       u8 frame_count;
2246 +       struct v4l2_pix_format format;
2247 +       u16 alpha;
2248 +       u16 data_offset;
2249 +       u32 ping_addr;
2250 +       u32 pong_addr;
2251 +       bool eof_enabled;
2252 +       bool eol_enabled;
2253 +       bool checksum_enabled;
2254 +       bool enabled;
2255 +};
2256 +
2257 +struct isp_csi2_ctx_cfg_update {
2258 +       bool virtual_id;
2259 +       bool frame_count;
2260 +       bool format;
2261 +       bool alpha;
2262 +       bool data_offset;
2263 +       bool ping_addr;
2264 +       bool pong_addr;
2265 +       bool eof_enabled;
2266 +       bool eol_enabled;
2267 +       bool checksum_enabled;
2268 +       bool enabled;
2269 +};
2270 +
2271 +struct isp_csi2_timings_cfg {
2272 +       bool force_rx_mode;
2273 +       bool stop_state_16x;
2274 +       bool stop_state_4x;
2275 +       u16 stop_state_counter;
2276 +};
2277 +
2278 +struct isp_csi2_timings_cfg_update {
2279 +       bool force_rx_mode;
2280 +       bool stop_state_16x;
2281 +       bool stop_state_4x;
2282 +       bool stop_state_counter;
2283 +};
2284 +
2285 +struct isp_csi2_ctrl_cfg {
2286 +       bool vp_clk_enable;
2287 +       bool vp_only_enable;
2288 +       u8 vp_out_ctrl;
2289 +       bool debug_enable;
2290 +       u8 burst_size;
2291 +       enum isp_csi2_frame_mode frame_mode;
2292 +       bool ecc_enable;
2293 +       bool secure_mode;
2294 +       bool if_enable;
2295 +};
2296 +
2297 +struct isp_csi2_ctrl_cfg_update {
2298 +       bool vp_clk_enable;
2299 +       bool vp_only_enable;
2300 +       bool vp_out_ctrl;
2301 +       bool debug_enable;
2302 +       bool burst_size;
2303 +       bool frame_mode;
2304 +       bool ecc_enable;
2305 +       bool secure_mode;
2306 +       bool if_enable;
2307 +};
2308 +
2309 +struct isp_csi2_cfg {
2310 +       struct isp_csi2_lanes_cfg lanes;
2311 +       struct isp_csi2_phy_cfg phy;
2312 +       struct isp_csi2_ctx_cfg contexts[8];
2313 +       struct isp_csi2_timings_cfg timings[2];
2314 +       struct isp_csi2_ctrl_cfg ctrl;
2315 +};
2316 +
2317 +struct isp_csi2_cfg_update {
2318 +       struct isp_csi2_lanes_cfg_update lanes;
2319 +       struct isp_csi2_phy_cfg_update phy;
2320 +       struct isp_csi2_ctx_cfg_update contexts[8];
2321 +       struct isp_csi2_timings_cfg_update timings[2];
2322 +       struct isp_csi2_ctrl_cfg_update ctrl;
2323 +};
2324 +
2325 +int isp_csi2_complexio_lanes_config(struct isp_csi2_lanes_cfg *reqcfg);
2326 +int isp_csi2_complexio_lanes_update(bool force_update);
2327 +int isp_csi2_complexio_lanes_get(void);
2328 +int isp_csi2_complexio_power_autoswitch(bool enable);
2329 +int isp_csi2_complexio_power(enum isp_csi2_power_cmds power_cmd);
2330 +int isp_csi2_ctrl_config_frame_mode(enum isp_csi2_frame_mode frame_mode);
2331 +int isp_csi2_ctrl_config_vp_clk_enable(bool vp_clk_enable);
2332 +int isp_csi2_ctrl_config_vp_only_enable(bool vp_only_enable);
2333 +int isp_csi2_ctrl_config_debug_enable(bool debug_enable);
2334 +int isp_csi2_ctrl_config_burst_size(u8 burst_size);
2335 +int isp_csi2_ctrl_config_ecc_enable(bool ecc_enable);
2336 +int isp_csi2_ctrl_config_secure_mode(bool secure_mode);
2337 +int isp_csi2_ctrl_config_if_enable(bool if_enable);
2338 +int isp_csi2_ctrl_config_vp_out_ctrl(u8 vp_out_ctrl);
2339 +int isp_csi2_ctrl_update(bool force_update);
2340 +int isp_csi2_ctrl_get(void);
2341 +int isp_csi2_ctx_config_virtual_id(u8 ctxnum, u8 virtual_id);
2342 +int isp_csi2_ctx_config_frame_count(u8 ctxnum, u8 frame_count);
2343 +int isp_csi2_ctx_config_format(u8 ctxnum, u32 pixformat);
2344 +int isp_csi2_ctx_config_alpha(u8 ctxnum, u16 alpha);
2345 +int isp_csi2_ctx_config_data_offset(u8 ctxnum, u16 data_offset);
2346 +int isp_csi2_ctx_config_ping_addr(u8 ctxnum, u32 ping_addr);
2347 +int isp_csi2_ctx_config_pong_addr(u8 ctxnum, u32 pong_addr);
2348 +int isp_csi2_ctx_config_eof_enabled(u8 ctxnum, bool eof_enabled);
2349 +int isp_csi2_ctx_config_eol_enabled(u8 ctxnum, bool eol_enabled);
2350 +int isp_csi2_ctx_config_checksum_enabled(u8 ctxnum, bool checksum_enabled);
2351 +int isp_csi2_ctx_config_enabled(u8 ctxnum, bool enabled);
2352 +int isp_csi2_ctx_update(u8 ctxnum, bool force_update);
2353 +int isp_csi2_ctx_get(u8 ctxnum);
2354 +int isp_csi2_ctx_update_all(bool force_update);
2355 +int isp_csi2_ctx_get_all(void);
2356 +int isp_csi2_phy_config(struct isp_csi2_phy_cfg *desiredphyconfig);
2357 +int isp_csi2_calc_phy_cfg0(u32 mipiclk, u32 lbound_hs_settle,
2358 +                          u32 ubound_hs_settle);
2359 +int isp_csi2_phy_update(bool force_update);
2360 +int isp_csi2_phy_get(void);
2361 +int isp_csi2_timings_config_forcerxmode(u8 io, bool force_rx_mode);
2362 +int isp_csi2_timings_config_stopstate_16x(u8 io, bool stop_state_16x);
2363 +int isp_csi2_timings_config_stopstate_4x(u8 io, bool stop_state_4x);
2364 +int isp_csi2_timings_config_stopstate_cnt(u8 io, u16 stop_state_counter);
2365 +int isp_csi2_timings_update(u8 io, bool force_update);
2366 +int isp_csi2_timings_get(u8 io);
2367 +int isp_csi2_timings_update_all(bool force_update);
2368 +int isp_csi2_timings_get_all(void);
2369 +void isp_csi2_irq_complexio1_set(int enable);
2370 +void isp_csi2_irq_ctx_set(int enable);
2371 +void isp_csi2_irq_status_set(int enable);
2372 +void isp_csi2_irq_set(int enable);
2373 +void isp_csi2_irq_all_set(int enable);
2374 +
2375 +void isp_csi2_isr(void);
2376 +int isp_csi2_reset(void);
2377 +void isp_csi2_enable(int enable);
2378 +void isp_csi2_regdump(void);
2379 +
2380 +#endif /* OMAP_ISP_CSI2_H */
2381 +
2382 -- 
2383 1.5.6.5
2384