Merge branch 'rmobile-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[pandora-kernel.git] / drivers / media / video / omap3isp / ispccdc.c
1 /*
2  * ispccdc.c
3  *
4  * TI OMAP3 ISP - CCDC module
5  *
6  * Copyright (C) 2009-2010 Nokia Corporation
7  * Copyright (C) 2009 Texas Instruments, Inc.
8  *
9  * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10  *           Sakari Ailus <sakari.ailus@iki.fi>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24  * 02110-1301 USA
25  */
26
27 #include <linux/module.h>
28 #include <linux/uaccess.h>
29 #include <linux/delay.h>
30 #include <linux/device.h>
31 #include <linux/dma-mapping.h>
32 #include <linux/mm.h>
33 #include <linux/sched.h>
34 #include <media/v4l2-event.h>
35
36 #include "isp.h"
37 #include "ispreg.h"
38 #include "ispccdc.h"
39
40 static struct v4l2_mbus_framefmt *
41 __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
42                   unsigned int pad, enum v4l2_subdev_format_whence which);
43
44 static const unsigned int ccdc_fmts[] = {
45         V4L2_MBUS_FMT_Y8_1X8,
46         V4L2_MBUS_FMT_SGRBG10_1X10,
47         V4L2_MBUS_FMT_SRGGB10_1X10,
48         V4L2_MBUS_FMT_SBGGR10_1X10,
49         V4L2_MBUS_FMT_SGBRG10_1X10,
50         V4L2_MBUS_FMT_SGRBG12_1X12,
51         V4L2_MBUS_FMT_SRGGB12_1X12,
52         V4L2_MBUS_FMT_SBGGR12_1X12,
53         V4L2_MBUS_FMT_SGBRG12_1X12,
54 };
55
56 /*
57  * ccdc_print_status - Print current CCDC Module register values.
58  * @ccdc: Pointer to ISP CCDC device.
59  *
60  * Also prints other debug information stored in the CCDC module.
61  */
62 #define CCDC_PRINT_REGISTER(isp, name)\
63         dev_dbg(isp->dev, "###CCDC " #name "=0x%08x\n", \
64                 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_##name))
65
66 static void ccdc_print_status(struct isp_ccdc_device *ccdc)
67 {
68         struct isp_device *isp = to_isp_device(ccdc);
69
70         dev_dbg(isp->dev, "-------------CCDC Register dump-------------\n");
71
72         CCDC_PRINT_REGISTER(isp, PCR);
73         CCDC_PRINT_REGISTER(isp, SYN_MODE);
74         CCDC_PRINT_REGISTER(isp, HD_VD_WID);
75         CCDC_PRINT_REGISTER(isp, PIX_LINES);
76         CCDC_PRINT_REGISTER(isp, HORZ_INFO);
77         CCDC_PRINT_REGISTER(isp, VERT_START);
78         CCDC_PRINT_REGISTER(isp, VERT_LINES);
79         CCDC_PRINT_REGISTER(isp, CULLING);
80         CCDC_PRINT_REGISTER(isp, HSIZE_OFF);
81         CCDC_PRINT_REGISTER(isp, SDOFST);
82         CCDC_PRINT_REGISTER(isp, SDR_ADDR);
83         CCDC_PRINT_REGISTER(isp, CLAMP);
84         CCDC_PRINT_REGISTER(isp, DCSUB);
85         CCDC_PRINT_REGISTER(isp, COLPTN);
86         CCDC_PRINT_REGISTER(isp, BLKCMP);
87         CCDC_PRINT_REGISTER(isp, FPC);
88         CCDC_PRINT_REGISTER(isp, FPC_ADDR);
89         CCDC_PRINT_REGISTER(isp, VDINT);
90         CCDC_PRINT_REGISTER(isp, ALAW);
91         CCDC_PRINT_REGISTER(isp, REC656IF);
92         CCDC_PRINT_REGISTER(isp, CFG);
93         CCDC_PRINT_REGISTER(isp, FMTCFG);
94         CCDC_PRINT_REGISTER(isp, FMT_HORZ);
95         CCDC_PRINT_REGISTER(isp, FMT_VERT);
96         CCDC_PRINT_REGISTER(isp, PRGEVEN0);
97         CCDC_PRINT_REGISTER(isp, PRGEVEN1);
98         CCDC_PRINT_REGISTER(isp, PRGODD0);
99         CCDC_PRINT_REGISTER(isp, PRGODD1);
100         CCDC_PRINT_REGISTER(isp, VP_OUT);
101         CCDC_PRINT_REGISTER(isp, LSC_CONFIG);
102         CCDC_PRINT_REGISTER(isp, LSC_INITIAL);
103         CCDC_PRINT_REGISTER(isp, LSC_TABLE_BASE);
104         CCDC_PRINT_REGISTER(isp, LSC_TABLE_OFFSET);
105
106         dev_dbg(isp->dev, "--------------------------------------------\n");
107 }
108
109 /*
110  * omap3isp_ccdc_busy - Get busy state of the CCDC.
111  * @ccdc: Pointer to ISP CCDC device.
112  */
113 int omap3isp_ccdc_busy(struct isp_ccdc_device *ccdc)
114 {
115         struct isp_device *isp = to_isp_device(ccdc);
116
117         return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR) &
118                 ISPCCDC_PCR_BUSY;
119 }
120
121 /* -----------------------------------------------------------------------------
122  * Lens Shading Compensation
123  */
124
125 /*
126  * ccdc_lsc_validate_config - Check that LSC configuration is valid.
127  * @ccdc: Pointer to ISP CCDC device.
128  * @lsc_cfg: the LSC configuration to check.
129  *
130  * Returns 0 if the LSC configuration is valid, or -EINVAL if invalid.
131  */
132 static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc,
133                                     struct omap3isp_ccdc_lsc_config *lsc_cfg)
134 {
135         struct isp_device *isp = to_isp_device(ccdc);
136         struct v4l2_mbus_framefmt *format;
137         unsigned int paxel_width, paxel_height;
138         unsigned int paxel_shift_x, paxel_shift_y;
139         unsigned int min_width, min_height, min_size;
140         unsigned int input_width, input_height;
141
142         paxel_shift_x = lsc_cfg->gain_mode_m;
143         paxel_shift_y = lsc_cfg->gain_mode_n;
144
145         if ((paxel_shift_x < 2) || (paxel_shift_x > 6) ||
146             (paxel_shift_y < 2) || (paxel_shift_y > 6)) {
147                 dev_dbg(isp->dev, "CCDC: LSC: Invalid paxel size\n");
148                 return -EINVAL;
149         }
150
151         if (lsc_cfg->offset & 3) {
152                 dev_dbg(isp->dev, "CCDC: LSC: Offset must be a multiple of "
153                         "4\n");
154                 return -EINVAL;
155         }
156
157         if ((lsc_cfg->initial_x & 1) || (lsc_cfg->initial_y & 1)) {
158                 dev_dbg(isp->dev, "CCDC: LSC: initial_x and y must be even\n");
159                 return -EINVAL;
160         }
161
162         format = __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
163                                    V4L2_SUBDEV_FORMAT_ACTIVE);
164         input_width = format->width;
165         input_height = format->height;
166
167         /* Calculate minimum bytesize for validation */
168         paxel_width = 1 << paxel_shift_x;
169         min_width = ((input_width + lsc_cfg->initial_x + paxel_width - 1)
170                      >> paxel_shift_x) + 1;
171
172         paxel_height = 1 << paxel_shift_y;
173         min_height = ((input_height + lsc_cfg->initial_y + paxel_height - 1)
174                      >> paxel_shift_y) + 1;
175
176         min_size = 4 * min_width * min_height;
177         if (min_size > lsc_cfg->size) {
178                 dev_dbg(isp->dev, "CCDC: LSC: too small table\n");
179                 return -EINVAL;
180         }
181         if (lsc_cfg->offset < (min_width * 4)) {
182                 dev_dbg(isp->dev, "CCDC: LSC: Offset is too small\n");
183                 return -EINVAL;
184         }
185         if ((lsc_cfg->size / lsc_cfg->offset) < min_height) {
186                 dev_dbg(isp->dev, "CCDC: LSC: Wrong size/offset combination\n");
187                 return -EINVAL;
188         }
189         return 0;
190 }
191
192 /*
193  * ccdc_lsc_program_table - Program Lens Shading Compensation table address.
194  * @ccdc: Pointer to ISP CCDC device.
195  */
196 static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, u32 addr)
197 {
198         isp_reg_writel(to_isp_device(ccdc), addr,
199                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE);
200 }
201
202 /*
203  * ccdc_lsc_setup_regs - Configures the lens shading compensation module
204  * @ccdc: Pointer to ISP CCDC device.
205  */
206 static void ccdc_lsc_setup_regs(struct isp_ccdc_device *ccdc,
207                                 struct omap3isp_ccdc_lsc_config *cfg)
208 {
209         struct isp_device *isp = to_isp_device(ccdc);
210         int reg;
211
212         isp_reg_writel(isp, cfg->offset, OMAP3_ISP_IOMEM_CCDC,
213                        ISPCCDC_LSC_TABLE_OFFSET);
214
215         reg = 0;
216         reg |= cfg->gain_mode_n << ISPCCDC_LSC_GAIN_MODE_N_SHIFT;
217         reg |= cfg->gain_mode_m << ISPCCDC_LSC_GAIN_MODE_M_SHIFT;
218         reg |= cfg->gain_format << ISPCCDC_LSC_GAIN_FORMAT_SHIFT;
219         isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG);
220
221         reg = 0;
222         reg &= ~ISPCCDC_LSC_INITIAL_X_MASK;
223         reg |= cfg->initial_x << ISPCCDC_LSC_INITIAL_X_SHIFT;
224         reg &= ~ISPCCDC_LSC_INITIAL_Y_MASK;
225         reg |= cfg->initial_y << ISPCCDC_LSC_INITIAL_Y_SHIFT;
226         isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC,
227                        ISPCCDC_LSC_INITIAL);
228 }
229
230 static int ccdc_lsc_wait_prefetch(struct isp_ccdc_device *ccdc)
231 {
232         struct isp_device *isp = to_isp_device(ccdc);
233         unsigned int wait;
234
235         isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
236                        OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
237
238         /* timeout 1 ms */
239         for (wait = 0; wait < 1000; wait++) {
240                 if (isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS) &
241                                   IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ) {
242                         isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
243                                        OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
244                         return 0;
245                 }
246
247                 rmb();
248                 udelay(1);
249         }
250
251         return -ETIMEDOUT;
252 }
253
254 /*
255  * __ccdc_lsc_enable - Enables/Disables the Lens Shading Compensation module.
256  * @ccdc: Pointer to ISP CCDC device.
257  * @enable: 0 Disables LSC, 1 Enables LSC.
258  */
259 static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
260 {
261         struct isp_device *isp = to_isp_device(ccdc);
262         const struct v4l2_mbus_framefmt *format =
263                 __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
264                                   V4L2_SUBDEV_FORMAT_ACTIVE);
265
266         if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) &&
267             (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) &&
268             (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) &&
269             (format->code != V4L2_MBUS_FMT_SGBRG10_1X10))
270                 return -EINVAL;
271
272         if (enable)
273                 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_LSC_READ);
274
275         isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
276                         ISPCCDC_LSC_ENABLE, enable ? ISPCCDC_LSC_ENABLE : 0);
277
278         if (enable) {
279                 if (ccdc_lsc_wait_prefetch(ccdc) < 0) {
280                         isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC,
281                                     ISPCCDC_LSC_CONFIG, ISPCCDC_LSC_ENABLE);
282                         ccdc->lsc.state = LSC_STATE_STOPPED;
283                         dev_warn(to_device(ccdc), "LSC prefecth timeout\n");
284                         return -ETIMEDOUT;
285                 }
286                 ccdc->lsc.state = LSC_STATE_RUNNING;
287         } else {
288                 ccdc->lsc.state = LSC_STATE_STOPPING;
289         }
290
291         return 0;
292 }
293
294 static int ccdc_lsc_busy(struct isp_ccdc_device *ccdc)
295 {
296         struct isp_device *isp = to_isp_device(ccdc);
297
298         return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG) &
299                              ISPCCDC_LSC_BUSY;
300 }
301
302 /* __ccdc_lsc_configure - Apply a new configuration to the LSC engine
303  * @ccdc: Pointer to ISP CCDC device
304  * @req: New configuration request
305  *
306  * context: in_interrupt()
307  */
308 static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc,
309                                 struct ispccdc_lsc_config_req *req)
310 {
311         if (!req->enable)
312                 return -EINVAL;
313
314         if (ccdc_lsc_validate_config(ccdc, &req->config) < 0) {
315                 dev_dbg(to_device(ccdc), "Discard LSC configuration\n");
316                 return -EINVAL;
317         }
318
319         if (ccdc_lsc_busy(ccdc))
320                 return -EBUSY;
321
322         ccdc_lsc_setup_regs(ccdc, &req->config);
323         ccdc_lsc_program_table(ccdc, req->table);
324         return 0;
325 }
326
327 /*
328  * ccdc_lsc_error_handler - Handle LSC prefetch error scenario.
329  * @ccdc: Pointer to ISP CCDC device.
330  *
331  * Disables LSC, and defers enablement to shadow registers update time.
332  */
333 static void ccdc_lsc_error_handler(struct isp_ccdc_device *ccdc)
334 {
335         struct isp_device *isp = to_isp_device(ccdc);
336         /*
337          * From OMAP3 TRM: When this event is pending, the module
338          * goes into transparent mode (output =input). Normal
339          * operation can be resumed at the start of the next frame
340          * after:
341          *  1) Clearing this event
342          *  2) Disabling the LSC module
343          *  3) Enabling it
344          */
345         isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
346                     ISPCCDC_LSC_ENABLE);
347         ccdc->lsc.state = LSC_STATE_STOPPED;
348 }
349
350 static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
351                                   struct ispccdc_lsc_config_req *req)
352 {
353         struct isp_device *isp = to_isp_device(ccdc);
354
355         if (req == NULL)
356                 return;
357
358         if (req->iovm)
359                 dma_unmap_sg(isp->dev, req->iovm->sgt->sgl,
360                              req->iovm->sgt->nents, DMA_TO_DEVICE);
361         if (req->table)
362                 iommu_vfree(isp->iommu, req->table);
363         kfree(req);
364 }
365
366 static void ccdc_lsc_free_queue(struct isp_ccdc_device *ccdc,
367                                 struct list_head *queue)
368 {
369         struct ispccdc_lsc_config_req *req, *n;
370         unsigned long flags;
371
372         spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
373         list_for_each_entry_safe(req, n, queue, list) {
374                 list_del(&req->list);
375                 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
376                 ccdc_lsc_free_request(ccdc, req);
377                 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
378         }
379         spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
380 }
381
382 static void ccdc_lsc_free_table_work(struct work_struct *work)
383 {
384         struct isp_ccdc_device *ccdc;
385         struct ispccdc_lsc *lsc;
386
387         lsc = container_of(work, struct ispccdc_lsc, table_work);
388         ccdc = container_of(lsc, struct isp_ccdc_device, lsc);
389
390         ccdc_lsc_free_queue(ccdc, &lsc->free_queue);
391 }
392
393 /*
394  * ccdc_lsc_config - Configure the LSC module from a userspace request
395  *
396  * Store the request LSC configuration in the LSC engine request pointer. The
397  * configuration will be applied to the hardware when the CCDC will be enabled,
398  * or at the next LSC interrupt if the CCDC is already running.
399  */
400 static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
401                            struct omap3isp_ccdc_update_config *config)
402 {
403         struct isp_device *isp = to_isp_device(ccdc);
404         struct ispccdc_lsc_config_req *req;
405         unsigned long flags;
406         void *table;
407         u16 update;
408         int ret;
409
410         update = config->update &
411                  (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC);
412         if (!update)
413                 return 0;
414
415         if (update != (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC)) {
416                 dev_dbg(to_device(ccdc), "%s: Both LSC configuration and table "
417                         "need to be supplied\n", __func__);
418                 return -EINVAL;
419         }
420
421         req = kzalloc(sizeof(*req), GFP_KERNEL);
422         if (req == NULL)
423                 return -ENOMEM;
424
425         if (config->flag & OMAP3ISP_CCDC_CONFIG_LSC) {
426                 if (copy_from_user(&req->config, config->lsc_cfg,
427                                    sizeof(req->config))) {
428                         ret = -EFAULT;
429                         goto done;
430                 }
431
432                 req->enable = 1;
433
434                 req->table = iommu_vmalloc(isp->iommu, 0, req->config.size,
435                                            IOMMU_FLAG);
436                 if (IS_ERR_VALUE(req->table)) {
437                         req->table = 0;
438                         ret = -ENOMEM;
439                         goto done;
440                 }
441
442                 req->iovm = find_iovm_area(isp->iommu, req->table);
443                 if (req->iovm == NULL) {
444                         ret = -ENOMEM;
445                         goto done;
446                 }
447
448                 if (!dma_map_sg(isp->dev, req->iovm->sgt->sgl,
449                                 req->iovm->sgt->nents, DMA_TO_DEVICE)) {
450                         ret = -ENOMEM;
451                         req->iovm = NULL;
452                         goto done;
453                 }
454
455                 dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl,
456                                     req->iovm->sgt->nents, DMA_TO_DEVICE);
457
458                 table = da_to_va(isp->iommu, req->table);
459                 if (copy_from_user(table, config->lsc, req->config.size)) {
460                         ret = -EFAULT;
461                         goto done;
462                 }
463
464                 dma_sync_sg_for_device(isp->dev, req->iovm->sgt->sgl,
465                                        req->iovm->sgt->nents, DMA_TO_DEVICE);
466         }
467
468         spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
469         if (ccdc->lsc.request) {
470                 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
471                 schedule_work(&ccdc->lsc.table_work);
472         }
473         ccdc->lsc.request = req;
474         spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
475
476         ret = 0;
477
478 done:
479         if (ret < 0)
480                 ccdc_lsc_free_request(ccdc, req);
481
482         return ret;
483 }
484
485 static inline int ccdc_lsc_is_configured(struct isp_ccdc_device *ccdc)
486 {
487         unsigned long flags;
488
489         spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
490         if (ccdc->lsc.active) {
491                 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
492                 return 1;
493         }
494         spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
495         return 0;
496 }
497
498 static int ccdc_lsc_enable(struct isp_ccdc_device *ccdc)
499 {
500         struct ispccdc_lsc *lsc = &ccdc->lsc;
501
502         if (lsc->state != LSC_STATE_STOPPED)
503                 return -EINVAL;
504
505         if (lsc->active) {
506                 list_add_tail(&lsc->active->list, &lsc->free_queue);
507                 lsc->active = NULL;
508         }
509
510         if (__ccdc_lsc_configure(ccdc, lsc->request) < 0) {
511                 omap3isp_sbl_disable(to_isp_device(ccdc),
512                                 OMAP3_ISP_SBL_CCDC_LSC_READ);
513                 list_add_tail(&lsc->request->list, &lsc->free_queue);
514                 lsc->request = NULL;
515                 goto done;
516         }
517
518         lsc->active = lsc->request;
519         lsc->request = NULL;
520         __ccdc_lsc_enable(ccdc, 1);
521
522 done:
523         if (!list_empty(&lsc->free_queue))
524                 schedule_work(&lsc->table_work);
525
526         return 0;
527 }
528
529 /* -----------------------------------------------------------------------------
530  * Parameters configuration
531  */
532
533 /*
534  * ccdc_configure_clamp - Configure optical-black or digital clamping
535  * @ccdc: Pointer to ISP CCDC device.
536  *
537  * The CCDC performs either optical-black or digital clamp. Configure and enable
538  * the selected clamp method.
539  */
540 static void ccdc_configure_clamp(struct isp_ccdc_device *ccdc)
541 {
542         struct isp_device *isp = to_isp_device(ccdc);
543         u32 clamp;
544
545         if (ccdc->obclamp) {
546                 clamp  = ccdc->clamp.obgain << ISPCCDC_CLAMP_OBGAIN_SHIFT;
547                 clamp |= ccdc->clamp.oblen << ISPCCDC_CLAMP_OBSLEN_SHIFT;
548                 clamp |= ccdc->clamp.oblines << ISPCCDC_CLAMP_OBSLN_SHIFT;
549                 clamp |= ccdc->clamp.obstpixel << ISPCCDC_CLAMP_OBST_SHIFT;
550                 isp_reg_writel(isp, clamp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP);
551         } else {
552                 isp_reg_writel(isp, ccdc->clamp.dcsubval,
553                                OMAP3_ISP_IOMEM_CCDC, ISPCCDC_DCSUB);
554         }
555
556         isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP,
557                         ISPCCDC_CLAMP_CLAMPEN,
558                         ccdc->obclamp ? ISPCCDC_CLAMP_CLAMPEN : 0);
559 }
560
561 /*
562  * ccdc_configure_fpc - Configure Faulty Pixel Correction
563  * @ccdc: Pointer to ISP CCDC device.
564  */
565 static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
566 {
567         struct isp_device *isp = to_isp_device(ccdc);
568
569         isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, ISPCCDC_FPC_FPCEN);
570
571         if (!ccdc->fpc_en)
572                 return;
573
574         isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC,
575                        ISPCCDC_FPC_ADDR);
576         /* The FPNUM field must be set before enabling FPC. */
577         isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
578                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
579         isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT) |
580                        ISPCCDC_FPC_FPCEN, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
581 }
582
583 /*
584  * ccdc_configure_black_comp - Configure Black Level Compensation.
585  * @ccdc: Pointer to ISP CCDC device.
586  */
587 static void ccdc_configure_black_comp(struct isp_ccdc_device *ccdc)
588 {
589         struct isp_device *isp = to_isp_device(ccdc);
590         u32 blcomp;
591
592         blcomp  = ccdc->blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT;
593         blcomp |= ccdc->blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT;
594         blcomp |= ccdc->blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT;
595         blcomp |= ccdc->blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT;
596
597         isp_reg_writel(isp, blcomp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP);
598 }
599
600 /*
601  * ccdc_configure_lpf - Configure Low-Pass Filter (LPF).
602  * @ccdc: Pointer to ISP CCDC device.
603  */
604 static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
605 {
606         struct isp_device *isp = to_isp_device(ccdc);
607
608         isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE,
609                         ISPCCDC_SYN_MODE_LPF,
610                         ccdc->lpf ? ISPCCDC_SYN_MODE_LPF : 0);
611 }
612
613 /*
614  * ccdc_configure_alaw - Configure A-law compression.
615  * @ccdc: Pointer to ISP CCDC device.
616  */
617 static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
618 {
619         struct isp_device *isp = to_isp_device(ccdc);
620         u32 alaw = 0;
621
622         switch (ccdc->syncif.datsz) {
623         case 8:
624                 return;
625
626         case 10:
627                 alaw = ISPCCDC_ALAW_GWDI_9_0;
628                 break;
629         case 11:
630                 alaw = ISPCCDC_ALAW_GWDI_10_1;
631                 break;
632         case 12:
633                 alaw = ISPCCDC_ALAW_GWDI_11_2;
634                 break;
635         case 13:
636                 alaw = ISPCCDC_ALAW_GWDI_12_3;
637                 break;
638         }
639
640         if (ccdc->alaw)
641                 alaw |= ISPCCDC_ALAW_CCDTBL;
642
643         isp_reg_writel(isp, alaw, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW);
644 }
645
646 /*
647  * ccdc_config_imgattr - Configure sensor image specific attributes.
648  * @ccdc: Pointer to ISP CCDC device.
649  * @colptn: Color pattern of the sensor.
650  */
651 static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
652 {
653         struct isp_device *isp = to_isp_device(ccdc);
654
655         isp_reg_writel(isp, colptn, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN);
656 }
657
658 /*
659  * ccdc_config - Set CCDC configuration from userspace
660  * @ccdc: Pointer to ISP CCDC device.
661  * @userspace_add: Structure containing CCDC configuration sent from userspace.
662  *
663  * Returns 0 if successful, -EINVAL if the pointer to the configuration
664  * structure is null, or the copy_from_user function fails to copy user space
665  * memory to kernel space memory.
666  */
667 static int ccdc_config(struct isp_ccdc_device *ccdc,
668                        struct omap3isp_ccdc_update_config *ccdc_struct)
669 {
670         struct isp_device *isp = to_isp_device(ccdc);
671         unsigned long flags;
672
673         spin_lock_irqsave(&ccdc->lock, flags);
674         ccdc->shadow_update = 1;
675         spin_unlock_irqrestore(&ccdc->lock, flags);
676
677         if (OMAP3ISP_CCDC_ALAW & ccdc_struct->update) {
678                 ccdc->alaw = !!(OMAP3ISP_CCDC_ALAW & ccdc_struct->flag);
679                 ccdc->update |= OMAP3ISP_CCDC_ALAW;
680         }
681
682         if (OMAP3ISP_CCDC_LPF & ccdc_struct->update) {
683                 ccdc->lpf = !!(OMAP3ISP_CCDC_LPF & ccdc_struct->flag);
684                 ccdc->update |= OMAP3ISP_CCDC_LPF;
685         }
686
687         if (OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->update) {
688                 if (copy_from_user(&ccdc->clamp, ccdc_struct->bclamp,
689                                    sizeof(ccdc->clamp))) {
690                         ccdc->shadow_update = 0;
691                         return -EFAULT;
692                 }
693
694                 ccdc->obclamp = !!(OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->flag);
695                 ccdc->update |= OMAP3ISP_CCDC_BLCLAMP;
696         }
697
698         if (OMAP3ISP_CCDC_BCOMP & ccdc_struct->update) {
699                 if (copy_from_user(&ccdc->blcomp, ccdc_struct->blcomp,
700                                    sizeof(ccdc->blcomp))) {
701                         ccdc->shadow_update = 0;
702                         return -EFAULT;
703                 }
704
705                 ccdc->update |= OMAP3ISP_CCDC_BCOMP;
706         }
707
708         ccdc->shadow_update = 0;
709
710         if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
711                 u32 table_old = 0;
712                 u32 table_new;
713                 u32 size;
714
715                 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
716                         return -EBUSY;
717
718                 ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
719
720                 if (ccdc->fpc_en) {
721                         if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc,
722                                            sizeof(ccdc->fpc)))
723                                 return -EFAULT;
724
725                         /*
726                          * table_new must be 64-bytes aligned, but it's
727                          * already done by iommu_vmalloc().
728                          */
729                         size = ccdc->fpc.fpnum * 4;
730                         table_new = iommu_vmalloc(isp->iommu, 0, size,
731                                                   IOMMU_FLAG);
732                         if (IS_ERR_VALUE(table_new))
733                                 return -ENOMEM;
734
735                         if (copy_from_user(da_to_va(isp->iommu, table_new),
736                                            (__force void __user *)
737                                            ccdc->fpc.fpcaddr, size)) {
738                                 iommu_vfree(isp->iommu, table_new);
739                                 return -EFAULT;
740                         }
741
742                         table_old = ccdc->fpc.fpcaddr;
743                         ccdc->fpc.fpcaddr = table_new;
744                 }
745
746                 ccdc_configure_fpc(ccdc);
747                 if (table_old != 0)
748                         iommu_vfree(isp->iommu, table_old);
749         }
750
751         return ccdc_lsc_config(ccdc, ccdc_struct);
752 }
753
754 static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
755 {
756         if (ccdc->update & OMAP3ISP_CCDC_ALAW) {
757                 ccdc_configure_alaw(ccdc);
758                 ccdc->update &= ~OMAP3ISP_CCDC_ALAW;
759         }
760
761         if (ccdc->update & OMAP3ISP_CCDC_LPF) {
762                 ccdc_configure_lpf(ccdc);
763                 ccdc->update &= ~OMAP3ISP_CCDC_LPF;
764         }
765
766         if (ccdc->update & OMAP3ISP_CCDC_BLCLAMP) {
767                 ccdc_configure_clamp(ccdc);
768                 ccdc->update &= ~OMAP3ISP_CCDC_BLCLAMP;
769         }
770
771         if (ccdc->update & OMAP3ISP_CCDC_BCOMP) {
772                 ccdc_configure_black_comp(ccdc);
773                 ccdc->update &= ~OMAP3ISP_CCDC_BCOMP;
774         }
775 }
776
777 /*
778  * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
779  * @dev: Pointer to ISP device
780  */
781 void omap3isp_ccdc_restore_context(struct isp_device *isp)
782 {
783         struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
784
785         isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC);
786
787         ccdc->update = OMAP3ISP_CCDC_ALAW | OMAP3ISP_CCDC_LPF
788                      | OMAP3ISP_CCDC_BLCLAMP | OMAP3ISP_CCDC_BCOMP;
789         ccdc_apply_controls(ccdc);
790         ccdc_configure_fpc(ccdc);
791 }
792
793 /* -----------------------------------------------------------------------------
794  * Format- and pipeline-related configuration helpers
795  */
796
797 /*
798  * ccdc_config_vp - Configure the Video Port.
799  * @ccdc: Pointer to ISP CCDC device.
800  */
801 static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
802 {
803         struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
804         struct isp_device *isp = to_isp_device(ccdc);
805         unsigned long l3_ick = pipe->l3_ick;
806         unsigned int max_div = isp->revision == ISP_REVISION_15_0 ? 64 : 8;
807         unsigned int div = 0;
808         u32 fmtcfg_vp;
809
810         fmtcfg_vp = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)
811                   & ~(ISPCCDC_FMTCFG_VPIN_MASK | ISPCCDC_FMTCFG_VPIF_FRQ_MASK);
812
813         switch (ccdc->syncif.datsz) {
814         case 8:
815         case 10:
816                 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0;
817                 break;
818         case 11:
819                 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_10_1;
820                 break;
821         case 12:
822                 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_11_2;
823                 break;
824         case 13:
825                 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3;
826                 break;
827         };
828
829         if (pipe->input)
830                 div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
831         else if (ccdc->vpcfg.pixelclk)
832                 div = l3_ick / ccdc->vpcfg.pixelclk;
833
834         div = clamp(div, 2U, max_div);
835         fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
836
837         isp_reg_writel(isp, fmtcfg_vp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG);
838 }
839
840 /*
841  * ccdc_enable_vp - Enable Video Port.
842  * @ccdc: Pointer to ISP CCDC device.
843  * @enable: 0 Disables VP, 1 Enables VP
844  *
845  * This is needed for outputting image to Preview, H3A and HIST ISP submodules.
846  */
847 static void ccdc_enable_vp(struct isp_ccdc_device *ccdc, u8 enable)
848 {
849         struct isp_device *isp = to_isp_device(ccdc);
850
851         isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG,
852                         ISPCCDC_FMTCFG_VPEN, enable ? ISPCCDC_FMTCFG_VPEN : 0);
853 }
854
855 /*
856  * ccdc_config_outlineoffset - Configure memory saving output line offset
857  * @ccdc: Pointer to ISP CCDC device.
858  * @offset: Address offset to start a new line. Must be twice the
859  *          Output width and aligned on 32 byte boundary
860  * @oddeven: Specifies the odd/even line pattern to be chosen to store the
861  *           output.
862  * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines.
863  *
864  * - Configures the output line offset when stored in memory
865  * - Sets the odd/even line pattern to store the output
866  *    (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4))
867  * - Configures the number of even and odd line fields in case of rearranging
868  * the lines.
869  */
870 static void ccdc_config_outlineoffset(struct isp_ccdc_device *ccdc,
871                                         u32 offset, u8 oddeven, u8 numlines)
872 {
873         struct isp_device *isp = to_isp_device(ccdc);
874
875         isp_reg_writel(isp, offset & 0xffff,
876                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF);
877
878         isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
879                     ISPCCDC_SDOFST_FINV);
880
881         isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
882                     ISPCCDC_SDOFST_FOFST_4L);
883
884         switch (oddeven) {
885         case EVENEVEN:
886                 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
887                             (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT);
888                 break;
889         case ODDEVEN:
890                 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
891                             (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT);
892                 break;
893         case EVENODD:
894                 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
895                             (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT);
896                 break;
897         case ODDODD:
898                 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
899                             (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT);
900                 break;
901         default:
902                 break;
903         }
904 }
905
906 /*
907  * ccdc_set_outaddr - Set memory address to save output image
908  * @ccdc: Pointer to ISP CCDC device.
909  * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
910  *
911  * Sets the memory address where the output will be saved.
912  */
913 static void ccdc_set_outaddr(struct isp_ccdc_device *ccdc, u32 addr)
914 {
915         struct isp_device *isp = to_isp_device(ccdc);
916
917         isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR);
918 }
919
920 /*
921  * omap3isp_ccdc_max_rate - Calculate maximum input data rate based on the input
922  * @ccdc: Pointer to ISP CCDC device.
923  * @max_rate: Maximum calculated data rate.
924  *
925  * Returns in *max_rate less value between calculated and passed
926  */
927 void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
928                             unsigned int *max_rate)
929 {
930         struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
931         unsigned int rate;
932
933         if (pipe == NULL)
934                 return;
935
936         /*
937          * TRM says that for parallel sensors the maximum data rate
938          * should be 90% form L3/2 clock, otherwise just L3/2.
939          */
940         if (ccdc->input == CCDC_INPUT_PARALLEL)
941                 rate = pipe->l3_ick / 2 * 9 / 10;
942         else
943                 rate = pipe->l3_ick / 2;
944
945         *max_rate = min(*max_rate, rate);
946 }
947
948 /*
949  * ccdc_config_sync_if - Set CCDC sync interface configuration
950  * @ccdc: Pointer to ISP CCDC device.
951  * @syncif: Structure containing the sync parameters like field state, CCDC in
952  *          master/slave mode, raw/yuv data, polarity of data, field, hs, vs
953  *          signals.
954  */
955 static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
956                                 struct ispccdc_syncif *syncif)
957 {
958         struct isp_device *isp = to_isp_device(ccdc);
959         u32 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC,
960                                      ISPCCDC_SYN_MODE);
961
962         syn_mode |= ISPCCDC_SYN_MODE_VDHDEN;
963
964         if (syncif->fldstat)
965                 syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT;
966         else
967                 syn_mode &= ~ISPCCDC_SYN_MODE_FLDSTAT;
968
969         syn_mode &= ~ISPCCDC_SYN_MODE_DATSIZ_MASK;
970         switch (syncif->datsz) {
971         case 8:
972                 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8;
973                 break;
974         case 10:
975                 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10;
976                 break;
977         case 11:
978                 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_11;
979                 break;
980         case 12:
981                 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12;
982                 break;
983         };
984
985         if (syncif->fldmode)
986                 syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
987         else
988                 syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;
989
990         if (syncif->datapol)
991                 syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
992         else
993                 syn_mode &= ~ISPCCDC_SYN_MODE_DATAPOL;
994
995         if (syncif->fldpol)
996                 syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
997         else
998                 syn_mode &= ~ISPCCDC_SYN_MODE_FLDPOL;
999
1000         if (syncif->hdpol)
1001                 syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
1002         else
1003                 syn_mode &= ~ISPCCDC_SYN_MODE_HDPOL;
1004
1005         if (syncif->vdpol)
1006                 syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
1007         else
1008                 syn_mode &= ~ISPCCDC_SYN_MODE_VDPOL;
1009
1010         if (syncif->ccdc_mastermode) {
1011                 syn_mode |= ISPCCDC_SYN_MODE_FLDOUT | ISPCCDC_SYN_MODE_VDHDOUT;
1012                 isp_reg_writel(isp,
1013                                syncif->hs_width << ISPCCDC_HD_VD_WID_HDW_SHIFT
1014                              | syncif->vs_width << ISPCCDC_HD_VD_WID_VDW_SHIFT,
1015                                OMAP3_ISP_IOMEM_CCDC,
1016                                ISPCCDC_HD_VD_WID);
1017
1018                 isp_reg_writel(isp,
1019                                syncif->ppln << ISPCCDC_PIX_LINES_PPLN_SHIFT
1020                              | syncif->hlprf << ISPCCDC_PIX_LINES_HLPRF_SHIFT,
1021                                OMAP3_ISP_IOMEM_CCDC,
1022                                ISPCCDC_PIX_LINES);
1023         } else
1024                 syn_mode &= ~(ISPCCDC_SYN_MODE_FLDOUT |
1025                               ISPCCDC_SYN_MODE_VDHDOUT);
1026
1027         isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1028
1029         if (!syncif->bt_r656_en)
1030                 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
1031                             ISPCCDC_REC656IF_R656ON);
1032 }
1033
1034 /* CCDC formats descriptions */
1035 static const u32 ccdc_sgrbg_pattern =
1036         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1037         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1038         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1039         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1040         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1041         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1042         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1043         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1044         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1045         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1046         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1047         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1048         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1049         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1050         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1051         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1052
1053 static const u32 ccdc_srggb_pattern =
1054         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1055         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1056         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1057         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1058         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1059         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1060         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1061         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1062         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1063         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1064         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1065         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1066         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1067         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1068         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1069         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1070
1071 static const u32 ccdc_sbggr_pattern =
1072         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1073         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1074         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1075         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1076         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1077         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1078         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1079         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1080         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1081         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1082         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1083         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1084         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1085         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1086         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1087         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1088
1089 static const u32 ccdc_sgbrg_pattern =
1090         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1091         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1092         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1093         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1094         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1095         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1096         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1097         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1098         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1099         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1100         ISPCCDC_COLPTN_Gb_G  << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1101         ISPCCDC_COLPTN_B_Mg  << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1102         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1103         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1104         ISPCCDC_COLPTN_R_Ye  << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1105         ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1106
1107 static void ccdc_configure(struct isp_ccdc_device *ccdc)
1108 {
1109         struct isp_device *isp = to_isp_device(ccdc);
1110         struct isp_parallel_platform_data *pdata = NULL;
1111         struct v4l2_subdev *sensor;
1112         struct v4l2_mbus_framefmt *format;
1113         struct media_pad *pad;
1114         unsigned long flags;
1115         u32 syn_mode;
1116         u32 ccdc_pattern;
1117
1118         if (ccdc->input == CCDC_INPUT_PARALLEL) {
1119                 pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
1120                 sensor = media_entity_to_v4l2_subdev(pad->entity);
1121                 pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
1122                         ->bus.parallel;
1123         }
1124
1125         omap3isp_configure_bridge(isp, ccdc->input, pdata);
1126
1127         ccdc->syncif.datsz = pdata ? pdata->width : 10;
1128         ccdc_config_sync_if(ccdc, &ccdc->syncif);
1129
1130         /* CCDC_PAD_SINK */
1131         format = &ccdc->formats[CCDC_PAD_SINK];
1132
1133         syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1134
1135         /* Use the raw, unprocessed data when writing to memory. The H3A and
1136          * histogram modules are still fed with lens shading corrected data.
1137          */
1138         syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
1139
1140         if (ccdc->output & CCDC_OUTPUT_MEMORY)
1141                 syn_mode |= ISPCCDC_SYN_MODE_WEN;
1142         else
1143                 syn_mode &= ~ISPCCDC_SYN_MODE_WEN;
1144
1145         if (ccdc->output & CCDC_OUTPUT_RESIZER)
1146                 syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ;
1147         else
1148                 syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
1149
1150         /* Use PACK8 mode for 1byte per pixel formats. */
1151         if (omap3isp_video_format_info(format->code)->bpp <= 8)
1152                 syn_mode |= ISPCCDC_SYN_MODE_PACK8;
1153         else
1154                 syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
1155
1156         isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1157
1158         /* Mosaic filter */
1159         switch (format->code) {
1160         case V4L2_MBUS_FMT_SRGGB10_1X10:
1161         case V4L2_MBUS_FMT_SRGGB12_1X12:
1162                 ccdc_pattern = ccdc_srggb_pattern;
1163                 break;
1164         case V4L2_MBUS_FMT_SBGGR10_1X10:
1165         case V4L2_MBUS_FMT_SBGGR12_1X12:
1166                 ccdc_pattern = ccdc_sbggr_pattern;
1167                 break;
1168         case V4L2_MBUS_FMT_SGBRG10_1X10:
1169         case V4L2_MBUS_FMT_SGBRG12_1X12:
1170                 ccdc_pattern = ccdc_sgbrg_pattern;
1171                 break;
1172         default:
1173                 /* Use GRBG */
1174                 ccdc_pattern = ccdc_sgrbg_pattern;
1175                 break;
1176         }
1177         ccdc_config_imgattr(ccdc, ccdc_pattern);
1178
1179         /* Generate VD0 on the last line of the image and VD1 on the
1180          * 2/3 height line.
1181          */
1182         isp_reg_writel(isp, ((format->height - 2) << ISPCCDC_VDINT_0_SHIFT) |
1183                        ((format->height * 2 / 3) << ISPCCDC_VDINT_1_SHIFT),
1184                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
1185
1186         /* CCDC_PAD_SOURCE_OF */
1187         format = &ccdc->formats[CCDC_PAD_SOURCE_OF];
1188
1189         isp_reg_writel(isp, (0 << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
1190                        ((format->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
1191                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
1192         isp_reg_writel(isp, 0 << ISPCCDC_VERT_START_SLV0_SHIFT,
1193                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
1194         isp_reg_writel(isp, (format->height - 1)
1195                         << ISPCCDC_VERT_LINES_NLV_SHIFT,
1196                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
1197
1198         ccdc_config_outlineoffset(ccdc, ccdc->video_out.bpl_value, 0, 0);
1199
1200         /* CCDC_PAD_SOURCE_VP */
1201         format = &ccdc->formats[CCDC_PAD_SOURCE_VP];
1202
1203         isp_reg_writel(isp, (0 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) |
1204                        (format->width << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT),
1205                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ);
1206         isp_reg_writel(isp, (0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) |
1207                        ((format->height + 1) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT),
1208                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT);
1209
1210         isp_reg_writel(isp, (format->width << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) |
1211                        (format->height << ISPCCDC_VP_OUT_VERT_NUM_SHIFT),
1212                        OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT);
1213
1214         spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1215         if (ccdc->lsc.request == NULL)
1216                 goto unlock;
1217
1218         WARN_ON(ccdc->lsc.active);
1219
1220         /* Get last good LSC configuration. If it is not supported for
1221          * the current active resolution discard it.
1222          */
1223         if (ccdc->lsc.active == NULL &&
1224             __ccdc_lsc_configure(ccdc, ccdc->lsc.request) == 0) {
1225                 ccdc->lsc.active = ccdc->lsc.request;
1226         } else {
1227                 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
1228                 schedule_work(&ccdc->lsc.table_work);
1229         }
1230
1231         ccdc->lsc.request = NULL;
1232
1233 unlock:
1234         spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1235
1236         ccdc_apply_controls(ccdc);
1237 }
1238
1239 static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable)
1240 {
1241         struct isp_device *isp = to_isp_device(ccdc);
1242
1243         isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,
1244                         ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);
1245 }
1246
1247 static int ccdc_disable(struct isp_ccdc_device *ccdc)
1248 {
1249         unsigned long flags;
1250         int ret = 0;
1251
1252         spin_lock_irqsave(&ccdc->lock, flags);
1253         if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1254                 ccdc->stopping = CCDC_STOP_REQUEST;
1255         spin_unlock_irqrestore(&ccdc->lock, flags);
1256
1257         ret = wait_event_timeout(ccdc->wait,
1258                                  ccdc->stopping == CCDC_STOP_FINISHED,
1259                                  msecs_to_jiffies(2000));
1260         if (ret == 0) {
1261                 ret = -ETIMEDOUT;
1262                 dev_warn(to_device(ccdc), "CCDC stop timeout!\n");
1263         }
1264
1265         omap3isp_sbl_disable(to_isp_device(ccdc), OMAP3_ISP_SBL_CCDC_LSC_READ);
1266
1267         mutex_lock(&ccdc->ioctl_lock);
1268         ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
1269         ccdc->lsc.request = ccdc->lsc.active;
1270         ccdc->lsc.active = NULL;
1271         cancel_work_sync(&ccdc->lsc.table_work);
1272         ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
1273         mutex_unlock(&ccdc->ioctl_lock);
1274
1275         ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
1276
1277         return ret > 0 ? 0 : ret;
1278 }
1279
1280 static void ccdc_enable(struct isp_ccdc_device *ccdc)
1281 {
1282         if (ccdc_lsc_is_configured(ccdc))
1283                 __ccdc_lsc_enable(ccdc, 1);
1284         __ccdc_enable(ccdc, 1);
1285 }
1286
1287 /* -----------------------------------------------------------------------------
1288  * Interrupt handling
1289  */
1290
1291 /*
1292  * ccdc_sbl_busy - Poll idle state of CCDC and related SBL memory write bits
1293  * @ccdc: Pointer to ISP CCDC device.
1294  *
1295  * Returns zero if the CCDC is idle and the image has been written to
1296  * memory, too.
1297  */
1298 static int ccdc_sbl_busy(struct isp_ccdc_device *ccdc)
1299 {
1300         struct isp_device *isp = to_isp_device(ccdc);
1301
1302         return omap3isp_ccdc_busy(ccdc)
1303                 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) &
1304                    ISPSBL_CCDC_WR_0_DATA_READY)
1305                 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) &
1306                    ISPSBL_CCDC_WR_0_DATA_READY)
1307                 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) &
1308                    ISPSBL_CCDC_WR_0_DATA_READY)
1309                 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) &
1310                    ISPSBL_CCDC_WR_0_DATA_READY);
1311 }
1312
1313 /*
1314  * ccdc_sbl_wait_idle - Wait until the CCDC and related SBL are idle
1315  * @ccdc: Pointer to ISP CCDC device.
1316  * @max_wait: Max retry count in us for wait for idle/busy transition.
1317  */
1318 static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
1319                               unsigned int max_wait)
1320 {
1321         unsigned int wait = 0;
1322
1323         if (max_wait == 0)
1324                 max_wait = 10000; /* 10 ms */
1325
1326         for (wait = 0; wait <= max_wait; wait++) {
1327                 if (!ccdc_sbl_busy(ccdc))
1328                         return 0;
1329
1330                 rmb();
1331                 udelay(1);
1332         }
1333
1334         return -EBUSY;
1335 }
1336
1337 /* __ccdc_handle_stopping - Handle CCDC and/or LSC stopping sequence
1338  * @ccdc: Pointer to ISP CCDC device.
1339  * @event: Pointing which event trigger handler
1340  *
1341  * Return 1 when the event and stopping request combination is satisfyied,
1342  * zero otherwise.
1343  */
1344 static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
1345 {
1346         int rval = 0;
1347
1348         switch ((ccdc->stopping & 3) | event) {
1349         case CCDC_STOP_REQUEST | CCDC_EVENT_VD1:
1350                 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1351                         __ccdc_lsc_enable(ccdc, 0);
1352                 __ccdc_enable(ccdc, 0);
1353                 ccdc->stopping = CCDC_STOP_EXECUTED;
1354                 return 1;
1355
1356         case CCDC_STOP_EXECUTED | CCDC_EVENT_VD0:
1357                 ccdc->stopping |= CCDC_STOP_CCDC_FINISHED;
1358                 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1359                         ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1360                 rval = 1;
1361                 break;
1362
1363         case CCDC_STOP_EXECUTED | CCDC_EVENT_LSC_DONE:
1364                 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1365                 rval = 1;
1366                 break;
1367
1368         case CCDC_STOP_EXECUTED | CCDC_EVENT_VD1:
1369                 return 1;
1370         }
1371
1372         if (ccdc->stopping == CCDC_STOP_FINISHED) {
1373                 wake_up(&ccdc->wait);
1374                 rval = 1;
1375         }
1376
1377         return rval;
1378 }
1379
1380 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
1381 {
1382         struct video_device *vdev = &ccdc->subdev.devnode;
1383         struct v4l2_event event;
1384
1385         memset(&event, 0, sizeof(event));
1386         event.type = V4L2_EVENT_OMAP3ISP_HS_VS;
1387
1388         v4l2_event_queue(vdev, &event);
1389 }
1390
1391 /*
1392  * ccdc_lsc_isr - Handle LSC events
1393  * @ccdc: Pointer to ISP CCDC device.
1394  * @events: LSC events
1395  */
1396 static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events)
1397 {
1398         unsigned long flags;
1399
1400         if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) {
1401                 ccdc_lsc_error_handler(ccdc);
1402                 ccdc->error = 1;
1403                 dev_dbg(to_device(ccdc), "lsc prefetch error\n");
1404         }
1405
1406         if (!(events & IRQ0STATUS_CCDC_LSC_DONE_IRQ))
1407                 return;
1408
1409         /* LSC_DONE interrupt occur, there are two cases
1410          * 1. stopping for reconfiguration
1411          * 2. stopping because of STREAM OFF command
1412          */
1413         spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1414
1415         if (ccdc->lsc.state == LSC_STATE_STOPPING)
1416                 ccdc->lsc.state = LSC_STATE_STOPPED;
1417
1418         if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_LSC_DONE))
1419                 goto done;
1420
1421         if (ccdc->lsc.state != LSC_STATE_RECONFIG)
1422                 goto done;
1423
1424         /* LSC is in STOPPING state, change to the new state */
1425         ccdc->lsc.state = LSC_STATE_STOPPED;
1426
1427         /* This is an exception. Start of frame and LSC_DONE interrupt
1428          * have been received on the same time. Skip this event and wait
1429          * for better times.
1430          */
1431         if (events & IRQ0STATUS_HS_VS_IRQ)
1432                 goto done;
1433
1434         /* The LSC engine is stopped at this point. Enable it if there's a
1435          * pending request.
1436          */
1437         if (ccdc->lsc.request == NULL)
1438                 goto done;
1439
1440         ccdc_lsc_enable(ccdc);
1441
1442 done:
1443         spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1444 }
1445
1446 static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
1447 {
1448         struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
1449         struct isp_device *isp = to_isp_device(ccdc);
1450         struct isp_buffer *buffer;
1451         int restart = 0;
1452
1453         /* The CCDC generates VD0 interrupts even when disabled (the datasheet
1454          * doesn't explicitly state if that's supposed to happen or not, so it
1455          * can be considered as a hardware bug or as a feature, but we have to
1456          * deal with it anyway). Disabling the CCDC when no buffer is available
1457          * would thus not be enough, we need to handle the situation explicitly.
1458          */
1459         if (list_empty(&ccdc->video_out.dmaqueue))
1460                 goto done;
1461
1462         /* We're in continuous mode, and memory writes were disabled due to a
1463          * buffer underrun. Reenable them now that we have a buffer. The buffer
1464          * address has been set in ccdc_video_queue.
1465          */
1466         if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && ccdc->underrun) {
1467                 restart = 1;
1468                 ccdc->underrun = 0;
1469                 goto done;
1470         }
1471
1472         if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1473                 dev_info(isp->dev, "CCDC won't become idle!\n");
1474                 goto done;
1475         }
1476
1477         buffer = omap3isp_video_buffer_next(&ccdc->video_out, ccdc->error);
1478         if (buffer != NULL) {
1479                 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1480                 restart = 1;
1481         }
1482
1483         pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1484
1485         if (ccdc->state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1486             isp_pipeline_ready(pipe))
1487                 omap3isp_pipeline_set_stream(pipe,
1488                                         ISP_PIPELINE_STREAM_SINGLESHOT);
1489
1490 done:
1491         ccdc->error = 0;
1492         return restart;
1493 }
1494
1495 /*
1496  * ccdc_vd0_isr - Handle VD0 event
1497  * @ccdc: Pointer to ISP CCDC device.
1498  *
1499  * Executes LSC deferred enablement before next frame starts.
1500  */
1501 static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
1502 {
1503         unsigned long flags;
1504         int restart = 0;
1505
1506         if (ccdc->output & CCDC_OUTPUT_MEMORY)
1507                 restart = ccdc_isr_buffer(ccdc);
1508
1509         spin_lock_irqsave(&ccdc->lock, flags);
1510         if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
1511                 spin_unlock_irqrestore(&ccdc->lock, flags);
1512                 return;
1513         }
1514
1515         if (!ccdc->shadow_update)
1516                 ccdc_apply_controls(ccdc);
1517         spin_unlock_irqrestore(&ccdc->lock, flags);
1518
1519         if (restart)
1520                 ccdc_enable(ccdc);
1521 }
1522
1523 /*
1524  * ccdc_vd1_isr - Handle VD1 event
1525  * @ccdc: Pointer to ISP CCDC device.
1526  */
1527 static void ccdc_vd1_isr(struct isp_ccdc_device *ccdc)
1528 {
1529         unsigned long flags;
1530
1531         spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1532
1533         /*
1534          * Depending on the CCDC pipeline state, CCDC stopping should be
1535          * handled differently. In SINGLESHOT we emulate an internal CCDC
1536          * stopping because the CCDC hw works only in continuous mode.
1537          * When CONTINUOUS pipeline state is used and the CCDC writes it's
1538          * data to memory the CCDC and LSC are stopped immediately but
1539          * without change the CCDC stopping state machine. The CCDC
1540          * stopping state machine should be used only when user request
1541          * for stopping is received (SINGLESHOT is an exeption).
1542          */
1543         switch (ccdc->state) {
1544         case ISP_PIPELINE_STREAM_SINGLESHOT:
1545                 ccdc->stopping = CCDC_STOP_REQUEST;
1546                 break;
1547
1548         case ISP_PIPELINE_STREAM_CONTINUOUS:
1549                 if (ccdc->output & CCDC_OUTPUT_MEMORY) {
1550                         if (ccdc->lsc.state != LSC_STATE_STOPPED)
1551                                 __ccdc_lsc_enable(ccdc, 0);
1552                         __ccdc_enable(ccdc, 0);
1553                 }
1554                 break;
1555
1556         case ISP_PIPELINE_STREAM_STOPPED:
1557                 break;
1558         }
1559
1560         if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD1))
1561                 goto done;
1562
1563         if (ccdc->lsc.request == NULL)
1564                 goto done;
1565
1566         /*
1567          * LSC need to be reconfigured. Stop it here and on next LSC_DONE IRQ
1568          * do the appropriate changes in registers
1569          */
1570         if (ccdc->lsc.state == LSC_STATE_RUNNING) {
1571                 __ccdc_lsc_enable(ccdc, 0);
1572                 ccdc->lsc.state = LSC_STATE_RECONFIG;
1573                 goto done;
1574         }
1575
1576         /* LSC has been in STOPPED state, enable it */
1577         if (ccdc->lsc.state == LSC_STATE_STOPPED)
1578                 ccdc_lsc_enable(ccdc);
1579
1580 done:
1581         spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1582 }
1583
1584 /*
1585  * omap3isp_ccdc_isr - Configure CCDC during interframe time.
1586  * @ccdc: Pointer to ISP CCDC device.
1587  * @events: CCDC events
1588  */
1589 int omap3isp_ccdc_isr(struct isp_ccdc_device *ccdc, u32 events)
1590 {
1591         if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED)
1592                 return 0;
1593
1594         if (events & IRQ0STATUS_CCDC_VD1_IRQ)
1595                 ccdc_vd1_isr(ccdc);
1596
1597         ccdc_lsc_isr(ccdc, events);
1598
1599         if (events & IRQ0STATUS_CCDC_VD0_IRQ)
1600                 ccdc_vd0_isr(ccdc);
1601
1602         if (events & IRQ0STATUS_HS_VS_IRQ)
1603                 ccdc_hs_vs_isr(ccdc);
1604
1605         return 0;
1606 }
1607
1608 /* -----------------------------------------------------------------------------
1609  * ISP video operations
1610  */
1611
1612 static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
1613 {
1614         struct isp_ccdc_device *ccdc = &video->isp->isp_ccdc;
1615
1616         if (!(ccdc->output & CCDC_OUTPUT_MEMORY))
1617                 return -ENODEV;
1618
1619         ccdc_set_outaddr(ccdc, buffer->isp_addr);
1620
1621         /* We now have a buffer queued on the output, restart the pipeline in
1622          * on the next CCDC interrupt if running in continuous mode (or when
1623          * starting the stream).
1624          */
1625         ccdc->underrun = 1;
1626
1627         return 0;
1628 }
1629
1630 static const struct isp_video_operations ccdc_video_ops = {
1631         .queue = ccdc_video_queue,
1632 };
1633
1634 /* -----------------------------------------------------------------------------
1635  * V4L2 subdev operations
1636  */
1637
1638 /*
1639  * ccdc_ioctl - CCDC module private ioctl's
1640  * @sd: ISP CCDC V4L2 subdevice
1641  * @cmd: ioctl command
1642  * @arg: ioctl argument
1643  *
1644  * Return 0 on success or a negative error code otherwise.
1645  */
1646 static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1647 {
1648         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1649         int ret;
1650
1651         switch (cmd) {
1652         case VIDIOC_OMAP3ISP_CCDC_CFG:
1653                 mutex_lock(&ccdc->ioctl_lock);
1654                 ret = ccdc_config(ccdc, arg);
1655                 mutex_unlock(&ccdc->ioctl_lock);
1656                 break;
1657
1658         default:
1659                 return -ENOIOCTLCMD;
1660         }
1661
1662         return ret;
1663 }
1664
1665 static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1666                                 struct v4l2_event_subscription *sub)
1667 {
1668         if (sub->type != V4L2_EVENT_OMAP3ISP_HS_VS)
1669                 return -EINVAL;
1670
1671         return v4l2_event_subscribe(fh, sub);
1672 }
1673
1674 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1675                                   struct v4l2_event_subscription *sub)
1676 {
1677         return v4l2_event_unsubscribe(fh, sub);
1678 }
1679
1680 /*
1681  * ccdc_set_stream - Enable/Disable streaming on the CCDC module
1682  * @sd: ISP CCDC V4L2 subdevice
1683  * @enable: Enable/disable stream
1684  *
1685  * When writing to memory, the CCDC hardware can't be enabled without a memory
1686  * buffer to write to. As the s_stream operation is called in response to a
1687  * STREAMON call without any buffer queued yet, just update the enabled field
1688  * and return immediately. The CCDC will be enabled in ccdc_isr_buffer().
1689  *
1690  * When not writing to memory enable the CCDC immediately.
1691  */
1692 static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
1693 {
1694         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1695         struct isp_device *isp = to_isp_device(ccdc);
1696         int ret = 0;
1697
1698         if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED) {
1699                 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1700                         return 0;
1701
1702                 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_CCDC);
1703                 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1704                             ISPCCDC_CFG_VDLC);
1705
1706                 ccdc_configure(ccdc);
1707
1708                 /* TODO: Don't configure the video port if all of its output
1709                  * links are inactive.
1710                  */
1711                 ccdc_config_vp(ccdc);
1712                 ccdc_enable_vp(ccdc, 1);
1713                 ccdc->error = 0;
1714                 ccdc_print_status(ccdc);
1715         }
1716
1717         switch (enable) {
1718         case ISP_PIPELINE_STREAM_CONTINUOUS:
1719                 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1720                         omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1721
1722                 if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY))
1723                         ccdc_enable(ccdc);
1724
1725                 ccdc->underrun = 0;
1726                 break;
1727
1728         case ISP_PIPELINE_STREAM_SINGLESHOT:
1729                 if (ccdc->output & CCDC_OUTPUT_MEMORY &&
1730                     ccdc->state != ISP_PIPELINE_STREAM_SINGLESHOT)
1731                         omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1732
1733                 ccdc_enable(ccdc);
1734                 break;
1735
1736         case ISP_PIPELINE_STREAM_STOPPED:
1737                 ret = ccdc_disable(ccdc);
1738                 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1739                         omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1740                 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_CCDC);
1741                 ccdc->underrun = 0;
1742                 break;
1743         }
1744
1745         ccdc->state = enable;
1746         return ret;
1747 }
1748
1749 static struct v4l2_mbus_framefmt *
1750 __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1751                   unsigned int pad, enum v4l2_subdev_format_whence which)
1752 {
1753         if (which == V4L2_SUBDEV_FORMAT_TRY)
1754                 return v4l2_subdev_get_try_format(fh, pad);
1755         else
1756                 return &ccdc->formats[pad];
1757 }
1758
1759 /*
1760  * ccdc_try_format - Try video format on a pad
1761  * @ccdc: ISP CCDC device
1762  * @fh : V4L2 subdev file handle
1763  * @pad: Pad number
1764  * @fmt: Format
1765  */
1766 static void
1767 ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1768                 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
1769                 enum v4l2_subdev_format_whence which)
1770 {
1771         struct v4l2_mbus_framefmt *format;
1772         const struct isp_format_info *info;
1773         unsigned int width = fmt->width;
1774         unsigned int height = fmt->height;
1775         unsigned int i;
1776
1777         switch (pad) {
1778         case CCDC_PAD_SINK:
1779                 /* TODO: If the CCDC output formatter pad is connected directly
1780                  * to the resizer, only YUV formats can be used.
1781                  */
1782                 for (i = 0; i < ARRAY_SIZE(ccdc_fmts); i++) {
1783                         if (fmt->code == ccdc_fmts[i])
1784                                 break;
1785                 }
1786
1787                 /* If not found, use SGRBG10 as default */
1788                 if (i >= ARRAY_SIZE(ccdc_fmts))
1789                         fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1790
1791                 /* Clamp the input size. */
1792                 fmt->width = clamp_t(u32, width, 32, 4096);
1793                 fmt->height = clamp_t(u32, height, 32, 4096);
1794                 break;
1795
1796         case CCDC_PAD_SOURCE_OF:
1797                 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1798                 memcpy(fmt, format, sizeof(*fmt));
1799
1800                 /* The data formatter truncates the number of horizontal output
1801                  * pixels to a multiple of 16. To avoid clipping data, allow
1802                  * callers to request an output size bigger than the input size
1803                  * up to the nearest multiple of 16.
1804                  */
1805                 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
1806                 fmt->width &= ~15;
1807                 fmt->height = clamp_t(u32, height, 32, fmt->height);
1808                 break;
1809
1810         case CCDC_PAD_SOURCE_VP:
1811                 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1812                 memcpy(fmt, format, sizeof(*fmt));
1813
1814                 /* The video port interface truncates the data to 10 bits. */
1815                 info = omap3isp_video_format_info(fmt->code);
1816                 fmt->code = info->truncated;
1817
1818                 /* The number of lines that can be clocked out from the video
1819                  * port output must be at least one line less than the number
1820                  * of input lines.
1821                  */
1822                 fmt->width = clamp_t(u32, width, 32, fmt->width);
1823                 fmt->height = clamp_t(u32, height, 32, fmt->height - 1);
1824                 break;
1825         }
1826
1827         /* Data is written to memory unpacked, each 10-bit or 12-bit pixel is
1828          * stored on 2 bytes.
1829          */
1830         fmt->colorspace = V4L2_COLORSPACE_SRGB;
1831         fmt->field = V4L2_FIELD_NONE;
1832 }
1833
1834 /*
1835  * ccdc_enum_mbus_code - Handle pixel format enumeration
1836  * @sd     : pointer to v4l2 subdev structure
1837  * @fh : V4L2 subdev file handle
1838  * @code   : pointer to v4l2_subdev_mbus_code_enum structure
1839  * return -EINVAL or zero on success
1840  */
1841 static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
1842                                struct v4l2_subdev_fh *fh,
1843                                struct v4l2_subdev_mbus_code_enum *code)
1844 {
1845         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1846         struct v4l2_mbus_framefmt *format;
1847
1848         switch (code->pad) {
1849         case CCDC_PAD_SINK:
1850                 if (code->index >= ARRAY_SIZE(ccdc_fmts))
1851                         return -EINVAL;
1852
1853                 code->code = ccdc_fmts[code->index];
1854                 break;
1855
1856         case CCDC_PAD_SOURCE_OF:
1857         case CCDC_PAD_SOURCE_VP:
1858                 /* No format conversion inside CCDC */
1859                 if (code->index != 0)
1860                         return -EINVAL;
1861
1862                 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK,
1863                                            V4L2_SUBDEV_FORMAT_TRY);
1864
1865                 code->code = format->code;
1866                 break;
1867
1868         default:
1869                 return -EINVAL;
1870         }
1871
1872         return 0;
1873 }
1874
1875 static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
1876                                 struct v4l2_subdev_fh *fh,
1877                                 struct v4l2_subdev_frame_size_enum *fse)
1878 {
1879         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1880         struct v4l2_mbus_framefmt format;
1881
1882         if (fse->index != 0)
1883                 return -EINVAL;
1884
1885         format.code = fse->code;
1886         format.width = 1;
1887         format.height = 1;
1888         ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1889         fse->min_width = format.width;
1890         fse->min_height = format.height;
1891
1892         if (format.code != fse->code)
1893                 return -EINVAL;
1894
1895         format.code = fse->code;
1896         format.width = -1;
1897         format.height = -1;
1898         ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1899         fse->max_width = format.width;
1900         fse->max_height = format.height;
1901
1902         return 0;
1903 }
1904
1905 /*
1906  * ccdc_get_format - Retrieve the video format on a pad
1907  * @sd : ISP CCDC V4L2 subdevice
1908  * @fh : V4L2 subdev file handle
1909  * @fmt: Format
1910  *
1911  * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
1912  * to the format type.
1913  */
1914 static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1915                            struct v4l2_subdev_format *fmt)
1916 {
1917         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1918         struct v4l2_mbus_framefmt *format;
1919
1920         format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1921         if (format == NULL)
1922                 return -EINVAL;
1923
1924         fmt->format = *format;
1925         return 0;
1926 }
1927
1928 /*
1929  * ccdc_set_format - Set the video format on a pad
1930  * @sd : ISP CCDC V4L2 subdevice
1931  * @fh : V4L2 subdev file handle
1932  * @fmt: Format
1933  *
1934  * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
1935  * to the format type.
1936  */
1937 static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1938                            struct v4l2_subdev_format *fmt)
1939 {
1940         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1941         struct v4l2_mbus_framefmt *format;
1942
1943         format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1944         if (format == NULL)
1945                 return -EINVAL;
1946
1947         ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which);
1948         *format = fmt->format;
1949
1950         /* Propagate the format from sink to source */
1951         if (fmt->pad == CCDC_PAD_SINK) {
1952                 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
1953                                            fmt->which);
1954                 *format = fmt->format;
1955                 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format,
1956                                 fmt->which);
1957
1958                 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP,
1959                                            fmt->which);
1960                 *format = fmt->format;
1961                 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format,
1962                                 fmt->which);
1963         }
1964
1965         return 0;
1966 }
1967
1968 /*
1969  * ccdc_init_formats - Initialize formats on all pads
1970  * @sd: ISP CCDC V4L2 subdevice
1971  * @fh: V4L2 subdev file handle
1972  *
1973  * Initialize all pad formats with default values. If fh is not NULL, try
1974  * formats are initialized on the file handle. Otherwise active formats are
1975  * initialized on the device.
1976  */
1977 static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1978 {
1979         struct v4l2_subdev_format format;
1980
1981         memset(&format, 0, sizeof(format));
1982         format.pad = CCDC_PAD_SINK;
1983         format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1984         format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1985         format.format.width = 4096;
1986         format.format.height = 4096;
1987         ccdc_set_format(sd, fh, &format);
1988
1989         return 0;
1990 }
1991
1992 /* V4L2 subdev core operations */
1993 static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
1994         .ioctl = ccdc_ioctl,
1995         .subscribe_event = ccdc_subscribe_event,
1996         .unsubscribe_event = ccdc_unsubscribe_event,
1997 };
1998
1999 /* V4L2 subdev video operations */
2000 static const struct v4l2_subdev_video_ops ccdc_v4l2_video_ops = {
2001         .s_stream = ccdc_set_stream,
2002 };
2003
2004 /* V4L2 subdev pad operations */
2005 static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
2006         .enum_mbus_code = ccdc_enum_mbus_code,
2007         .enum_frame_size = ccdc_enum_frame_size,
2008         .get_fmt = ccdc_get_format,
2009         .set_fmt = ccdc_set_format,
2010 };
2011
2012 /* V4L2 subdev operations */
2013 static const struct v4l2_subdev_ops ccdc_v4l2_ops = {
2014         .core = &ccdc_v4l2_core_ops,
2015         .video = &ccdc_v4l2_video_ops,
2016         .pad = &ccdc_v4l2_pad_ops,
2017 };
2018
2019 /* V4L2 subdev internal operations */
2020 static const struct v4l2_subdev_internal_ops ccdc_v4l2_internal_ops = {
2021         .open = ccdc_init_formats,
2022 };
2023
2024 /* -----------------------------------------------------------------------------
2025  * Media entity operations
2026  */
2027
2028 /*
2029  * ccdc_link_setup - Setup CCDC connections
2030  * @entity: CCDC media entity
2031  * @local: Pad at the local end of the link
2032  * @remote: Pad at the remote end of the link
2033  * @flags: Link flags
2034  *
2035  * return -EINVAL or zero on success
2036  */
2037 static int ccdc_link_setup(struct media_entity *entity,
2038                            const struct media_pad *local,
2039                            const struct media_pad *remote, u32 flags)
2040 {
2041         struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2042         struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2043         struct isp_device *isp = to_isp_device(ccdc);
2044
2045         switch (local->index | media_entity_type(remote->entity)) {
2046         case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
2047                 /* Read from the sensor (parallel interface), CCP2, CSI2a or
2048                  * CSI2c.
2049                  */
2050                 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
2051                         ccdc->input = CCDC_INPUT_NONE;
2052                         break;
2053                 }
2054
2055                 if (ccdc->input != CCDC_INPUT_NONE)
2056                         return -EBUSY;
2057
2058                 if (remote->entity == &isp->isp_ccp2.subdev.entity)
2059                         ccdc->input = CCDC_INPUT_CCP2B;
2060                 else if (remote->entity == &isp->isp_csi2a.subdev.entity)
2061                         ccdc->input = CCDC_INPUT_CSI2A;
2062                 else if (remote->entity == &isp->isp_csi2c.subdev.entity)
2063                         ccdc->input = CCDC_INPUT_CSI2C;
2064                 else
2065                         ccdc->input = CCDC_INPUT_PARALLEL;
2066
2067                 break;
2068
2069         /*
2070          * The ISP core doesn't support pipelines with multiple video outputs.
2071          * Revisit this when it will be implemented, and return -EBUSY for now.
2072          */
2073
2074         case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
2075                 /* Write to preview engine, histogram and H3A. When none of
2076                  * those links are active, the video port can be disabled.
2077                  */
2078                 if (flags & MEDIA_LNK_FL_ENABLED) {
2079                         if (ccdc->output & ~CCDC_OUTPUT_PREVIEW)
2080                                 return -EBUSY;
2081                         ccdc->output |= CCDC_OUTPUT_PREVIEW;
2082                 } else {
2083                         ccdc->output &= ~CCDC_OUTPUT_PREVIEW;
2084                 }
2085                 break;
2086
2087         case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
2088                 /* Write to memory */
2089                 if (flags & MEDIA_LNK_FL_ENABLED) {
2090                         if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
2091                                 return -EBUSY;
2092                         ccdc->output |= CCDC_OUTPUT_MEMORY;
2093                 } else {
2094                         ccdc->output &= ~CCDC_OUTPUT_MEMORY;
2095                 }
2096                 break;
2097
2098         case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
2099                 /* Write to resizer */
2100                 if (flags & MEDIA_LNK_FL_ENABLED) {
2101                         if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
2102                                 return -EBUSY;
2103                         ccdc->output |= CCDC_OUTPUT_RESIZER;
2104                 } else {
2105                         ccdc->output &= ~CCDC_OUTPUT_RESIZER;
2106                 }
2107                 break;
2108
2109         default:
2110                 return -EINVAL;
2111         }
2112
2113         return 0;
2114 }
2115
2116 /* media operations */
2117 static const struct media_entity_operations ccdc_media_ops = {
2118         .link_setup = ccdc_link_setup,
2119 };
2120
2121 /*
2122  * ccdc_init_entities - Initialize V4L2 subdev and media entity
2123  * @ccdc: ISP CCDC module
2124  *
2125  * Return 0 on success and a negative error code on failure.
2126  */
2127 static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2128 {
2129         struct v4l2_subdev *sd = &ccdc->subdev;
2130         struct media_pad *pads = ccdc->pads;
2131         struct media_entity *me = &sd->entity;
2132         int ret;
2133
2134         ccdc->input = CCDC_INPUT_NONE;
2135
2136         v4l2_subdev_init(sd, &ccdc_v4l2_ops);
2137         sd->internal_ops = &ccdc_v4l2_internal_ops;
2138         strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
2139         sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
2140         v4l2_set_subdevdata(sd, ccdc);
2141         sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
2142         sd->nevents = OMAP3ISP_CCDC_NEVENTS;
2143
2144         pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2145         pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
2146         pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
2147
2148         me->ops = &ccdc_media_ops;
2149         ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
2150         if (ret < 0)
2151                 return ret;
2152
2153         ccdc_init_formats(sd, NULL);
2154
2155         ccdc->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2156         ccdc->video_out.ops = &ccdc_video_ops;
2157         ccdc->video_out.isp = to_isp_device(ccdc);
2158         ccdc->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
2159         ccdc->video_out.bpl_alignment = 32;
2160
2161         ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2162         if (ret < 0)
2163                 return ret;
2164
2165         /* Connect the CCDC subdev to the video node. */
2166         ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2167                         &ccdc->video_out.video.entity, 0, 0);
2168         if (ret < 0)
2169                 return ret;
2170
2171         return 0;
2172 }
2173
2174 void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2175 {
2176         media_entity_cleanup(&ccdc->subdev.entity);
2177
2178         v4l2_device_unregister_subdev(&ccdc->subdev);
2179         omap3isp_video_unregister(&ccdc->video_out);
2180 }
2181
2182 int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2183         struct v4l2_device *vdev)
2184 {
2185         int ret;
2186
2187         /* Register the subdev and video node. */
2188         ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2189         if (ret < 0)
2190                 goto error;
2191
2192         ret = omap3isp_video_register(&ccdc->video_out, vdev);
2193         if (ret < 0)
2194                 goto error;
2195
2196         return 0;
2197
2198 error:
2199         omap3isp_ccdc_unregister_entities(ccdc);
2200         return ret;
2201 }
2202
2203 /* -----------------------------------------------------------------------------
2204  * ISP CCDC initialisation and cleanup
2205  */
2206
2207 /*
2208  * omap3isp_ccdc_init - CCDC module initialization.
2209  * @dev: Device pointer specific to the OMAP3 ISP.
2210  *
2211  * TODO: Get the initialisation values from platform data.
2212  *
2213  * Return 0 on success or a negative error code otherwise.
2214  */
2215 int omap3isp_ccdc_init(struct isp_device *isp)
2216 {
2217         struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2218
2219         spin_lock_init(&ccdc->lock);
2220         init_waitqueue_head(&ccdc->wait);
2221         mutex_init(&ccdc->ioctl_lock);
2222
2223         ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
2224
2225         INIT_WORK(&ccdc->lsc.table_work, ccdc_lsc_free_table_work);
2226         ccdc->lsc.state = LSC_STATE_STOPPED;
2227         INIT_LIST_HEAD(&ccdc->lsc.free_queue);
2228         spin_lock_init(&ccdc->lsc.req_lock);
2229
2230         ccdc->syncif.ccdc_mastermode = 0;
2231         ccdc->syncif.datapol = 0;
2232         ccdc->syncif.datsz = 0;
2233         ccdc->syncif.fldmode = 0;
2234         ccdc->syncif.fldout = 0;
2235         ccdc->syncif.fldpol = 0;
2236         ccdc->syncif.fldstat = 0;
2237         ccdc->syncif.hdpol = 0;
2238         ccdc->syncif.vdpol = 0;
2239
2240         ccdc->clamp.oblen = 0;
2241         ccdc->clamp.dcsubval = 0;
2242
2243         ccdc->vpcfg.pixelclk = 0;
2244
2245         ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2246         ccdc_apply_controls(ccdc);
2247
2248         return ccdc_init_entities(ccdc);
2249 }
2250
2251 /*
2252  * omap3isp_ccdc_cleanup - CCDC module cleanup.
2253  * @dev: Device pointer specific to the OMAP3 ISP.
2254  */
2255 void omap3isp_ccdc_cleanup(struct isp_device *isp)
2256 {
2257         struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2258
2259         /* Free LSC requests. As the CCDC is stopped there's no active request,
2260          * so only the pending request and the free queue need to be handled.
2261          */
2262         ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
2263         cancel_work_sync(&ccdc->lsc.table_work);
2264         ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
2265
2266         if (ccdc->fpc.fpcaddr != 0)
2267                 iommu_vfree(isp->iommu, ccdc->fpc.fpcaddr);
2268 }