sync minor framebuffer and overlay twiddlings to 11.01 BSP
[efikamx:linux-kernel.git] / drivers / media / video / mxc / output / mxc_v4l2_output.c
1 /*
2  * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
3  */
4
5 /*
6  * The code contained herein is licensed under the GNU General Public
7  * License. You may obtain a copy of the GNU General Public License
8  * Version 2 or later at the following locations:
9  *
10  * http://www.opensource.org/licenses/gpl-license.html
11  * http://www.gnu.org/copyleft/gpl.html
12  */
13
14 /*!
15  * @file drivers/media/video/mxc/output/mxc_v4l2_output.c
16  *
17  * @brief MXC V4L2 Video Output Driver
18  *
19  * Video4Linux2 Output Device using MXC IPU Post-processing functionality.
20  *
21  * @ingroup MXC_V4L2_OUTPUT
22  */
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/io.h>
26 #include <linux/semaphore.h>
27 #include <linux/console.h>
28 #include <linux/fs.h>
29 #include <linux/delay.h>
30 #include <linux/platform_device.h>
31 #include <linux/dma-mapping.h>
32 #include <linux/mxcfb.h>
33 #include <media/v4l2-ioctl.h>
34 #include <asm/cacheflush.h>
35 #include <mach/hardware.h>
36
37 #include "mxc_v4l2_output.h"
38
39 #define INTERLACED_CONTENT(vout) (((cpu_is_mx51_rev(CHIP_REV_2_0) >= 1) || \
40                                    cpu_is_mx53()) &&                    \
41                                   (((vout)->field_fmt == V4L2_FIELD_INTERLACED_TB) || \
42                                    ((vout)->field_fmt == V4L2_FIELD_INTERLACED_BT)))
43 #define LOAD_3FIELDS(vout) ((INTERLACED_CONTENT(vout)) && \
44                             ((vout)->motion_sel != HIGH_MOTION))
45
46 struct v4l2_output mxc_outputs[1] = {
47         {
48          .index = MXC_V4L2_OUT_2_SDC,
49          .name = "DISP3 Video Out",
50          .type = V4L2_OUTPUT_TYPE_ANALOG,       /* not really correct,
51                                                    but no other choice */
52          .audioset = 0,
53          .modulator = 0,
54          .std = V4L2_STD_UNKNOWN}
55 };
56
57 static int video_nr = 16;
58 static spinlock_t g_lock = SPIN_LOCK_UNLOCKED;
59 static int last_index_n;
60 static unsigned int ipu_ic_out_max_width_size;
61 static unsigned int ipu_ic_out_max_height_size;
62 /* debug counters */
63 uint32_t g_irq_cnt;
64 uint32_t g_buf_output_cnt;
65 uint32_t g_buf_q_cnt;
66 uint32_t g_buf_dq_cnt;
67
68 #define QUEUE_SIZE (MAX_FRAME_NUM + 1)
69 static __inline int queue_size(v4l_queue * q)
70 {
71         if (q->tail >= q->head)
72                 return (q->tail - q->head);
73         else
74                 return ((q->tail + QUEUE_SIZE) - q->head);
75 }
76
77 static __inline int queue_buf(v4l_queue * q, int idx)
78 {
79         if (((q->tail + 1) % QUEUE_SIZE) == q->head)
80                 return -1;      /* queue full */
81         q->list[q->tail] = idx;
82         q->tail = (q->tail + 1) % QUEUE_SIZE;
83         return 0;
84 }
85
86 static __inline int dequeue_buf(v4l_queue * q)
87 {
88         int ret;
89         if (q->tail == q->head)
90                 return -1;      /* queue empty */
91         ret = q->list[q->head];
92         q->head = (q->head + 1) % QUEUE_SIZE;
93         return ret;
94 }
95
96 static __inline int peek_next_buf(v4l_queue * q)
97 {
98         if (q->tail == q->head)
99                 return -1;      /* queue empty */
100         return q->list[q->head];
101 }
102
103 static __inline unsigned long get_jiffies(struct timeval *t)
104 {
105         struct timeval cur;
106
107         if (t->tv_usec >= 1000000) {
108                 t->tv_sec += t->tv_usec / 1000000;
109                 t->tv_usec = t->tv_usec % 1000000;
110         }
111
112         do_gettimeofday(&cur);
113         if ((t->tv_sec < cur.tv_sec)
114             || ((t->tv_sec == cur.tv_sec) && (t->tv_usec < cur.tv_usec)))
115                 return jiffies;
116
117         if (t->tv_usec < cur.tv_usec) {
118                 cur.tv_sec = t->tv_sec - cur.tv_sec - 1;
119                 cur.tv_usec = t->tv_usec + 1000000 - cur.tv_usec;
120         } else {
121                 cur.tv_sec = t->tv_sec - cur.tv_sec;
122                 cur.tv_usec = t->tv_usec - cur.tv_usec;
123         }
124
125         return jiffies + timeval_to_jiffies(&cur);
126 }
127
128 /*!
129  * Private function to free buffers
130  *
131  * @param bufs_paddr    Array of physical address of buffers to be freed
132  *
133  * @param bufs_vaddr    Array of virtual address of buffers to be freed
134  *
135  * @param num_buf       Number of buffers to be freed
136  *
137  * @param size          Size for each buffer to be free
138  *
139  * @return status  0 success.
140  */
141 static int mxc_free_buffers(dma_addr_t bufs_paddr[], void *bufs_vaddr[],
142                             int num_buf, int size)
143 {
144         int i;
145
146         for (i = 0; i < num_buf; i++) {
147                 if (bufs_vaddr[i] != 0) {
148                         dma_free_coherent(0, size, bufs_vaddr[i],
149                                           bufs_paddr[i]);
150                         pr_debug("freed @ paddr=0x%08X\n", (u32) bufs_paddr[i]);
151                         bufs_paddr[i] = 0;
152                         bufs_vaddr[i] = NULL;
153                 }
154         }
155         return 0;
156 }
157
158 /*!
159  * Private function to allocate buffers
160  *
161  * @param bufs_paddr    Output array of physical address of buffers allocated
162  *
163  * @param bufs_vaddr    Output array of virtual address of buffers allocated
164  *
165  * @param num_buf       Input number of buffers to allocate
166  *
167  * @param size          Input size for each buffer to allocate
168  *
169  * @return status       -0 Successfully allocated a buffer, -ENOBUFS failed.
170  */
171 static int mxc_allocate_buffers(dma_addr_t bufs_paddr[], void *bufs_vaddr[],
172                                 int num_buf, int size)
173 {
174         int i;
175
176         for (i = 0; i < num_buf; i++) {
177                 bufs_vaddr[i] = dma_alloc_coherent(0, size,
178                                                    &bufs_paddr[i],
179                                                    GFP_DMA | GFP_KERNEL);
180
181                 if (bufs_vaddr[i] == 0) {
182                         mxc_free_buffers(bufs_paddr, bufs_vaddr, i, size);
183                         printk(KERN_ERR "dma_alloc_coherent failed.\n");
184                         return -ENOBUFS;
185                 }
186                 pr_debug("allocated @ paddr=0x%08X, size=%d.\n",
187                          (u32) bufs_paddr[i], size);
188         }
189
190         return 0;
191 }
192
193 /*
194  * Returns bits per pixel for given pixel format
195  *
196  * @param pixelformat  V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
197  *
198  * @return bits per pixel of pixelformat
199  */
200 static u32 fmt_to_bpp(u32 pixelformat)
201 {
202         u32 bpp;
203
204         bpp = 8 * bytes_per_pixel(pixelformat);
205         return bpp;
206 }
207
208 static bool format_is_yuv(u32 pixelformat)
209 {
210         switch (pixelformat) {
211         case V4L2_PIX_FMT_YUV420:
212         case V4L2_PIX_FMT_UYVY:
213         case V4L2_PIX_FMT_YUYV:
214         case V4L2_PIX_FMT_YUV422P:
215         case V4L2_PIX_FMT_YVU420:
216         case V4L2_PIX_FMT_YUV444:
217         case V4L2_PIX_FMT_NV12:
218                 return true;
219                 break;
220         }
221         return false;
222 }
223
224 static u32 bpp_to_fmt(struct fb_info *fbi)
225 {
226         if (fbi->var.nonstd)
227                 return fbi->var.nonstd;
228
229         if (fbi->var.bits_per_pixel == 24)
230                 return V4L2_PIX_FMT_BGR24;
231         else if (fbi->var.bits_per_pixel == 32)
232                 return V4L2_PIX_FMT_BGR32;
233         else if (fbi->var.bits_per_pixel == 16)
234                 return V4L2_PIX_FMT_RGB565;
235
236         return 0;
237 }
238
239 /*
240  * we are using double buffer for video playback, ipu need make
241  * sure current buffer should not be the same buffer of next display
242  * one.
243  */
244 static int select_display_buffer(vout_data *vout, int next_buf)
245 {
246         int ret = 0;
247
248         vout->disp_buf_num = next_buf;
249         if (ipu_get_cur_buffer_idx(vout->display_ch, IPU_INPUT_BUFFER)
250                         != next_buf)
251                 ret = ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER,
252                                 next_buf);
253         else
254                 dev_dbg(&vout->video_dev->dev,
255                         "display buffer not ready for select\n");
256         return ret;
257 }
258
259 static void setup_next_buf_timer(vout_data *vout, int index)
260 {
261         unsigned long timeout;
262
263         /* Setup timer for next buffer */
264         /* if timestamp is 0, then default to 30fps */
265         if ((vout->v4l2_bufs[index].timestamp.tv_sec == 0)
266                         && (vout->v4l2_bufs[index].timestamp.tv_usec == 0)
267                         && vout->start_jiffies)
268                 timeout =
269                         vout->start_jiffies + vout->frame_count * HZ / 30;
270         else
271                 timeout =
272                         get_jiffies(&vout->v4l2_bufs[index].timestamp);
273
274         if (jiffies >= timeout) {
275                 dev_dbg(&vout->video_dev->dev,
276                                 "warning: timer timeout already expired.\n");
277         }
278         if (mod_timer(&vout->output_timer, timeout))
279                 dev_dbg(&vout->video_dev->dev,
280                                 "warning: timer was already set\n");
281
282         dev_dbg(&vout->video_dev->dev,
283                         "timer handler next schedule: %lu\n", timeout);
284 }
285
286 static int finish_previous_frame(vout_data *vout)
287 {
288         struct fb_info *fbi =
289                 registered_fb[vout->output_fb_num[vout->cur_disp_output]];
290         mm_segment_t old_fs;
291         int ret = 0, try = 0;
292
293         /* make sure buf[vout->disp_buf_num] in showing */
294         while (ipu_check_buffer_ready(vout->display_ch,
295                         IPU_INPUT_BUFFER, vout->disp_buf_num)) {
296                 if (fbi->fbops->fb_ioctl) {
297                         old_fs = get_fs();
298                         set_fs(KERNEL_DS);
299                         ret = fbi->fbops->fb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
300                                         (unsigned int)NULL);
301                         set_fs(old_fs);
302
303                         if ((ret < 0) || (try == 1)) {
304                                 /*
305                                  * ic_bypass need clear display buffer ready for next update.
306                                  * when fb doing blank and unblank, it has chance to go into
307                                  * dead loop: fb unblank just after buffer 1 ready selected.
308                                  */
309                                 ipu_clear_buffer_ready(vout->display_ch, IPU_INPUT_BUFFER,
310                                                 vout->disp_buf_num);
311                         }
312                 }
313                 try++;
314         }
315
316         return ret;
317 }
318
319 static int show_current_frame(vout_data *vout)
320 {
321         struct fb_info *fbi =
322                 registered_fb[vout->output_fb_num[vout->cur_disp_output]];
323         mm_segment_t old_fs;
324         int ret = 0;
325
326         /* make sure buf[vout->disp_buf_num] begin to show */
327         if (ipu_get_cur_buffer_idx(vout->display_ch, IPU_INPUT_BUFFER)
328                 != vout->disp_buf_num) {
329                 /* wait for display frame finish */
330                 if (fbi->fbops->fb_ioctl) {
331                         old_fs = get_fs();
332                         set_fs(KERNEL_DS);
333                         ret = fbi->fbops->fb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
334                                         (unsigned int)NULL);
335                         set_fs(old_fs);
336                 }
337         }
338
339         return ret;
340 }
341
342 static void icbypass_work_func(struct work_struct *work)
343 {
344         vout_data *vout =
345                 container_of(work, vout_data, icbypass_work);
346         int index, ret;
347         int last_buf;
348         unsigned long lock_flags = 0;
349
350         finish_previous_frame(vout);
351
352         spin_lock_irqsave(&g_lock, lock_flags);
353
354         index = dequeue_buf(&vout->ready_q);
355         if (index == -1) {      /* no buffers ready, should never occur */
356                 dev_err(&vout->video_dev->dev,
357                                 "mxc_v4l2out: timer - no queued buffers ready\n");
358                 goto exit;
359         }
360         g_buf_dq_cnt++;
361         vout->frame_count++;
362
363         vout->ipu_buf[vout->next_rdy_ipu_buf] = index;
364         ret = ipu_update_channel_buffer(vout->display_ch, IPU_INPUT_BUFFER,
365                         vout->next_rdy_ipu_buf,
366                         vout->v4l2_bufs[index].m.offset);
367         ret += select_display_buffer(vout, vout->next_rdy_ipu_buf);
368         if (ret < 0) {
369                 dev_err(&vout->video_dev->dev,
370                                 "unable to update buffer %d address rc=%d\n",
371                                 vout->next_rdy_ipu_buf, ret);
372                 goto exit;
373         }
374         spin_unlock_irqrestore(&g_lock, lock_flags);
375         show_current_frame(vout);
376         spin_lock_irqsave(&g_lock, lock_flags);
377         vout->next_rdy_ipu_buf = !vout->next_rdy_ipu_buf;
378
379         last_buf = vout->ipu_buf[vout->next_done_ipu_buf];
380         if (last_buf != -1) {
381                 g_buf_output_cnt++;
382                 vout->v4l2_bufs[last_buf].flags = V4L2_BUF_FLAG_DONE;
383                 queue_buf(&vout->done_q, last_buf);
384                 wake_up_interruptible(&vout->v4l_bufq);
385                 vout->ipu_buf[vout->next_done_ipu_buf] = -1;
386                 vout->next_done_ipu_buf = !vout->next_done_ipu_buf;
387         }
388
389         if (g_buf_output_cnt > 0) {
390                 /* Setup timer for next buffer */
391                 index = peek_next_buf(&vout->ready_q);
392                 if (index != -1)
393                         setup_next_buf_timer(vout, index);
394                 else
395                         vout->state = STATE_STREAM_PAUSED;
396
397                 if (vout->state == STATE_STREAM_STOPPING) {
398                         if ((vout->ipu_buf[0] == -1) && (vout->ipu_buf[1] == -1)) {
399                                 vout->state = STATE_STREAM_OFF;
400                         }
401                 }
402         }
403 exit:
404         spin_unlock_irqrestore(&g_lock, lock_flags);
405 }
406
407 static int get_cur_fb_blank(vout_data *vout)
408 {
409         struct fb_info *fbi =
410                 registered_fb[vout->output_fb_num[vout->cur_disp_output]];
411         mm_segment_t old_fs;
412         int ret = 0;
413
414         /* Check BG blank first, if BG is blank, FG should be blank too */
415         if (vout->display_ch == MEM_FG_SYNC) {
416                 int i, bg_found = 0;
417                 for (i = 0; i < num_registered_fb; i++) {
418                         struct fb_info *bg_fbi;
419                         char *idstr = registered_fb[i]->fix.id;
420                         if (strncmp(idstr, "DISP3 BG", 8) == 0) {
421                                 bg_found = 1;
422                                 bg_fbi = registered_fb[i];
423                                 if (bg_fbi->fbops->fb_ioctl) {
424                                         old_fs = get_fs();
425                                         set_fs(KERNEL_DS);
426                                         ret = bg_fbi->fbops->fb_ioctl(bg_fbi,
427                                                         MXCFB_GET_FB_BLANK,
428                                                         (unsigned int)(&vout->fb_blank));
429                                         set_fs(old_fs);
430                                 }
431                         }
432                         if (bg_found) {
433                                 if (vout->fb_blank == FB_BLANK_UNBLANK)
434                                         break;
435                                 else
436                                         return ret;
437                         }
438                 }
439         }
440
441         if (fbi->fbops->fb_ioctl) {
442                 old_fs = get_fs();
443                 set_fs(KERNEL_DS);
444                 ret = fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_BLANK,
445                                                 (unsigned int)(&vout->fb_blank));
446                 set_fs(old_fs);
447         }
448
449         return ret;
450 }
451
452 static void mxc_v4l2out_timer_handler(unsigned long arg)
453 {
454         int index, ret;
455         unsigned long lock_flags = 0;
456         vout_data *vout = (vout_data *) arg;
457         static int old_fb_blank = FB_BLANK_UNBLANK;
458
459         spin_lock_irqsave(&g_lock, lock_flags);
460
461         if ((vout->state == STATE_STREAM_STOPPING)
462             || (vout->state == STATE_STREAM_OFF))
463                 goto exit0;
464
465         /*
466          * If timer occurs before IPU h/w is ready, then set the state to
467          * paused and the timer will be set again when next buffer is queued
468          * or PP comletes
469          */
470         if (vout->ipu_buf[vout->next_rdy_ipu_buf] != -1) {
471                 dev_dbg(&vout->video_dev->dev, "IPU buffer busy\n");
472                 vout->state = STATE_STREAM_PAUSED;
473                 goto exit0;
474         }
475
476         /* VDI need both buffer done before update buffer? */
477         if (INTERLACED_CONTENT(vout) &&
478                 (vout->ipu_buf[!vout->next_rdy_ipu_buf] != -1)) {
479                 dev_dbg(&vout->video_dev->dev, "IPU buffer busy\n");
480                 vout->state = STATE_STREAM_PAUSED;
481                 goto exit0;
482         }
483
484         /* Handle ic bypass mode in work queue */
485         if (vout->ic_bypass) {
486                 if (queue_work(vout->v4l_wq, &vout->icbypass_work) == 0) {
487                         dev_err(&vout->video_dev->dev,
488                                 "ic bypass work was in queue already!\n ");
489                         vout->state = STATE_STREAM_PAUSED;
490                 }
491                 goto exit0;
492         }
493
494         get_cur_fb_blank(vout);
495         if (vout->fb_blank == FB_BLANK_UNBLANK) {
496                 /* if first come back from fb blank, recover correct stack */
497                 if (old_fb_blank != FB_BLANK_UNBLANK) {
498                         if (vout->next_disp_ipu_buf == 1)
499                                 ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER, 0);
500                         else
501                                 ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER, 1);
502                 }
503                 if (ipu_get_cur_buffer_idx(vout->display_ch, IPU_INPUT_BUFFER)
504                                 == vout->next_disp_ipu_buf) {
505                         dev_dbg(&vout->video_dev->dev, "IPU disp busy\n");
506                         index = peek_next_buf(&vout->ready_q);
507                         setup_next_buf_timer(vout, index);
508                         old_fb_blank = vout->fb_blank;
509                         goto exit0;
510                 }
511         }
512         old_fb_blank = vout->fb_blank;
513
514         /* Dequeue buffer and pass to IPU */
515         index = dequeue_buf(&vout->ready_q);
516         if (index == -1) {      /* no buffers ready, should never occur */
517                 dev_err(&vout->video_dev->dev,
518                         "mxc_v4l2out: timer - no queued buffers ready\n");
519                 goto exit0;
520         }
521         g_buf_dq_cnt++;
522         vout->frame_count++;
523
524         /* update next buffer */
525         if (LOAD_3FIELDS(vout)) {
526                 int index_n = index;
527                 int index_p = last_index_n;
528                 vout->ipu_buf_p[vout->next_rdy_ipu_buf] = last_index_n;
529                 vout->ipu_buf[vout->next_rdy_ipu_buf] = index;
530                 vout->ipu_buf_n[vout->next_rdy_ipu_buf] = index;
531                 ret = ipu_update_channel_buffer(vout->post_proc_ch,
532                                 IPU_INPUT_BUFFER,
533                                 vout->next_rdy_ipu_buf,
534                                 vout->v4l2_bufs[index].m.offset);
535                 ret += ipu_update_channel_buffer(MEM_VDI_PRP_VF_MEM_P,
536                                 IPU_INPUT_BUFFER,
537                                 vout->next_rdy_ipu_buf,
538                                 vout->v4l2_bufs[index_p].m.offset + vout->bytesperline);
539                 ret += ipu_update_channel_buffer(MEM_VDI_PRP_VF_MEM_N,
540                                 IPU_INPUT_BUFFER,
541                                 vout->next_rdy_ipu_buf,
542                                 vout->v4l2_bufs[index_n].m.offset + vout->bytesperline);
543                 last_index_n = index;
544         } else {
545                 vout->ipu_buf[vout->next_rdy_ipu_buf] = index;
546                 if (vout->pp_split) {
547                         vout->ipu_buf[!vout->next_rdy_ipu_buf] = index;
548                         /* always left stripe */
549                         ret = ipu_update_channel_buffer(vout->post_proc_ch,
550                                         IPU_INPUT_BUFFER,
551                                         0,/* vout->next_rdy_ipu_buf,*/
552                                         (vout->v4l2_bufs[index].m.offset) +
553                                         vout->pp_left_stripe.input_column +
554                                         vout->pp_up_stripe.input_column * vout->bytesperline);
555
556                         /* the U/V offset has to be updated inside of IDMAC */
557                         /* according to stripe offset */
558                         ret += ipu_update_channel_offset(vout->post_proc_ch,
559                                         IPU_INPUT_BUFFER,
560                                         vout->v2f.fmt.pix.pixelformat,
561                                         vout->v2f.fmt.pix.width,
562                                         vout->v2f.fmt.pix.height,
563                                         vout->bytesperline,
564                                         vout->offset.u_offset,
565                                         vout->offset.v_offset,
566                                         vout->pp_up_stripe.input_column,
567                                         vout->pp_left_stripe.input_column);
568                 } else
569                         ret = ipu_update_channel_buffer(vout->post_proc_ch,
570                                         IPU_INPUT_BUFFER,
571                                         vout->next_rdy_ipu_buf,
572                                         vout->v4l2_bufs[index].m.offset);
573         }
574
575         if (ret < 0) {
576                 dev_err(&vout->video_dev->dev,
577                         "unable to update buffer %d address rc=%d\n",
578                         vout->next_rdy_ipu_buf, ret);
579                 goto exit0;
580         }
581
582         /* set next buffer ready */
583         if (LOAD_3FIELDS(vout))
584                 ret = ipu_select_multi_vdi_buffer(vout->next_rdy_ipu_buf);
585         else
586                 ret = ipu_select_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER,
587                                 vout->next_rdy_ipu_buf);
588         if (ret < 0) {
589                 dev_err(&vout->video_dev->dev,
590                                 "unable to set IPU buffer ready\n");
591                 goto exit0;
592         }
593
594         /* Split mode use buf 0 only, no need to switch buf */
595         if (!vout->pp_split)
596                 vout->next_rdy_ipu_buf = !vout->next_rdy_ipu_buf;
597
598         /* Always assume display in double buffers */
599         vout->next_disp_ipu_buf = !vout->next_disp_ipu_buf;
600
601         /* Setup timer for next buffer */
602         index = peek_next_buf(&vout->ready_q);
603         if (index != -1)
604                 setup_next_buf_timer(vout, index);
605         else
606                 vout->state = STATE_STREAM_PAUSED;
607
608         if (vout->state == STATE_STREAM_STOPPING) {
609                 if ((vout->ipu_buf[0] == -1) && (vout->ipu_buf[1] == -1)) {
610                         vout->state = STATE_STREAM_OFF;
611                 }
612         }
613
614         spin_unlock_irqrestore(&g_lock, lock_flags);
615
616         return;
617
618 exit0:
619         spin_unlock_irqrestore(&g_lock, lock_flags);
620 }
621
622 static irqreturn_t mxc_v4l2out_work_irq_handler(int irq, void *dev_id)
623 {
624         int last_buf;
625         int index;
626         unsigned long lock_flags = 0;
627         vout_data *vout = dev_id;
628         int pp_out_buf_left_right = 0;
629         int disp_buf_num = 0;
630         int disp_buf_num_next = 1;
631         int local_buffer = 0;
632         int pp_out_buf_offset = 0;
633         int pp_out_buf_up_down = 0;
634         int release_buffer = 0;
635         u32 eba_offset = 0;
636         u32 vertical_offset = 0;
637         u16 x_pos;
638         u16 y_pos;
639         int ret = -1;
640
641         spin_lock_irqsave(&g_lock, lock_flags);
642
643         g_irq_cnt++;
644
645         /* Process previous buffer */
646         if (LOAD_3FIELDS(vout))
647                 last_buf = vout->ipu_buf_p[vout->next_done_ipu_buf];
648         else
649                 last_buf = vout->ipu_buf[vout->next_done_ipu_buf];
650
651         if (last_buf != -1) {
652                 /* If IC split mode on, update output buffer number */
653                 if (vout->pp_split) {
654                         pp_out_buf_up_down = vout->pp_split_buf_num & 1;/* left/right stripe */
655                         pp_out_buf_left_right = (vout->pp_split_buf_num >> 1) & 1; /* up/down */
656                         local_buffer = (vout->pp_split == 1) ? pp_out_buf_up_down :
657                                         pp_out_buf_left_right;
658                         disp_buf_num = vout->pp_split_buf_num >> 2;
659                         disp_buf_num_next =
660                                         ((vout->pp_split_buf_num + (vout->pp_split << 0x1)) & 7) >> 2;
661                         if ((!pp_out_buf_left_right) ||
662                                 ((!pp_out_buf_up_down) && (vout->pp_split == 1))) {
663                                 if (vout->pp_split == 1) {
664                                                 eba_offset = ((pp_out_buf_left_right + pp_out_buf_up_down) & 1) ?
665                                                                         vout->pp_right_stripe.input_column :
666                                                                         vout->pp_left_stripe.input_column;
667                                                 vertical_offset = pp_out_buf_up_down ?
668                                                                         vout->pp_up_stripe.input_column :
669                                                                         vout->pp_down_stripe.input_column;
670
671                                 } else {
672                                                 eba_offset = pp_out_buf_left_right ?
673                                                                         vout->pp_left_stripe.input_column :
674                                                                         vout->pp_right_stripe.input_column;
675                                                 vertical_offset = pp_out_buf_left_right ?
676                                                                         vout->pp_up_stripe.input_column :
677                                                                         vout->pp_down_stripe.input_column;
678                                 }
679
680                                 ret = ipu_update_channel_buffer(vout->post_proc_ch,
681                                                 IPU_INPUT_BUFFER,
682                                                 (1 - local_buffer),
683                                                 (vout->v4l2_bufs[vout->ipu_buf[disp_buf_num]].m.offset)
684                                                 + eba_offset + vertical_offset * vout->bytesperline);
685                                 ret += ipu_update_channel_offset(vout->post_proc_ch,
686                                                                 IPU_INPUT_BUFFER,
687                                                                 vout->v2f.fmt.pix.pixelformat,
688                                                                 vout->v2f.fmt.pix.width,
689                                                                 vout->v2f.fmt.pix.height,
690                                                                 vout->bytesperline,
691                                                                 vout->offset.u_offset,
692                                                                 vout->offset.v_offset,
693                                                                 vertical_offset,
694                                                                 eba_offset);
695
696                                 /* select right stripe */
697                                 ret += ipu_select_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER,
698                                                         (1 - local_buffer));
699                                 if (ret < 0)
700                                         dev_err(&vout->video_dev->dev,
701                                         "unable to set IPU buffer ready\n");
702                         }
703
704                         /* offset for next buffer's EBA */
705                         eba_offset = 0;
706                         if (vout->pp_split == 1) {
707                                 pp_out_buf_offset = ((vout->pp_split_buf_num >> 1) & 1) ?
708                                                                 vout->pp_left_stripe.output_column :
709                                                                 vout->pp_right_stripe.output_column;
710
711                                 eba_offset = ((vout->pp_split_buf_num & 1) ?
712                                                                 vout->pp_down_stripe.output_column :
713                                                                 vout->pp_up_stripe.output_column);
714
715                         } else {
716                                 pp_out_buf_offset = ((vout->pp_split_buf_num >> 1) & 1) ?
717                                                                         vout->pp_right_stripe.output_column :
718                                                                         vout->pp_left_stripe.output_column;
719                                 eba_offset = ((vout->pp_split_buf_num >> 1) & 1) ?
720                                                                         vout->pp_down_stripe.output_column :
721                                                                         vout->pp_up_stripe.output_column;
722                         }
723
724                         if (vout->cur_disp_output == 5) {
725                                 x_pos = (vout->crop_current.left / 8) * 8;
726                                 y_pos = vout->crop_current.top;
727                                 eba_offset += (vout->xres * y_pos + x_pos) * vout->bpp / 8;
728                         }
729
730
731                         /* next buffer update */
732                         eba_offset = vout->display_bufs[disp_buf_num_next] +
733                                                 pp_out_buf_offset + eba_offset;
734
735                         ipu_update_channel_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER,
736                                                 local_buffer, eba_offset);
737
738                         /* next buffer ready */
739                         ret = ipu_select_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER, local_buffer);
740
741                         /* next stripe_buffer index 0..7 */
742                         vout->pp_split_buf_num = (vout->pp_split_buf_num + vout->pp_split) & 0x7;
743                 } else {
744                         disp_buf_num = vout->next_done_ipu_buf;
745                         ret += ipu_select_buffer(vout->display_input_ch, IPU_OUTPUT_BUFFER,
746                                         vout->next_done_ipu_buf);
747                 }
748
749                 /* release buffer. For split mode: if second stripe is done */
750                 release_buffer = vout->pp_split ? (!(vout->pp_split_buf_num & 0x3)) : 1;
751                 if (release_buffer) {
752                         if (vout->fb_blank == FB_BLANK_UNBLANK)
753                                 select_display_buffer(vout, disp_buf_num);
754                         g_buf_output_cnt++;
755                         vout->v4l2_bufs[last_buf].flags = V4L2_BUF_FLAG_DONE;
756                         queue_buf(&vout->done_q, last_buf);
757                         wake_up_interruptible(&vout->v4l_bufq);
758                         vout->ipu_buf[vout->next_done_ipu_buf] = -1;
759                         if (LOAD_3FIELDS(vout)) {
760                                 vout->ipu_buf_p[vout->next_done_ipu_buf] = -1;
761                                 vout->ipu_buf_n[vout->next_done_ipu_buf] = -1;
762                         }
763                         /* split mode use buf 0 only, no need switch buf */
764                         if (!vout->pp_split)
765                                 vout->next_done_ipu_buf = !vout->next_done_ipu_buf;
766                 }
767         } /* end of last_buf != -1 */
768
769         index = peek_next_buf(&vout->ready_q);
770         if (vout->state == STATE_STREAM_STOPPING) {
771                 if ((vout->ipu_buf[0] == -1) && (vout->ipu_buf[1] == -1)) {
772                         vout->state = STATE_STREAM_OFF;
773                 }
774         } else if ((vout->state == STATE_STREAM_PAUSED)
775                    && (index != -1)) {
776                 /* Setup timer for next buffer, when stream has been paused */
777                 pr_debug("next index %d\n", index);
778                 setup_next_buf_timer(vout, index);
779                 vout->state = STATE_STREAM_ON;
780         }
781
782         spin_unlock_irqrestore(&g_lock, lock_flags);
783
784         return IRQ_HANDLED;
785 }
786
787 /*!
788  *  Initialize VDI channels
789  *
790  * @param voutstructure vout_data *
791  *
792  * @return status  0 Success
793  */
794 static int init_VDI_channel(vout_data *vout, ipu_channel_params_t params)
795 {
796         struct device *dev = &vout->video_dev->dev;
797
798         if (ipu_init_channel(MEM_VDI_PRP_VF_MEM, &params) != 0) {
799                 dev_dbg(dev, "Error initializing VDI current channel\n");
800                 return -EINVAL;
801         }
802         if (LOAD_3FIELDS(vout)) {
803                 if (ipu_init_channel(MEM_VDI_PRP_VF_MEM_P, &params) != 0) {
804                         dev_err(dev, "Error initializing VDI previous channel\n");
805                         return -EINVAL;
806                 }
807                 if (ipu_init_channel(MEM_VDI_PRP_VF_MEM_N, &params) != 0) {
808                         dev_err(dev, "Error initializing VDI next channel\n");
809                         return -EINVAL;
810                 }
811         }
812         return 0;
813 }
814
815 /*!
816  * Initialize VDI channel buffers
817  *
818  * @param vout      structure vout_data *
819  *
820  * @return status  0 Success
821  */
822 static int init_VDI_in_channel_buffer(vout_data *vout, uint32_t in_pixel_fmt,
823                                    uint16_t in_width, uint16_t in_height,
824                                    uint32_t stride,
825                                    uint32_t u_offset, uint32_t v_offset)
826 {
827         struct device *dev = &vout->video_dev->dev;
828
829         if (ipu_init_channel_buffer(MEM_VDI_PRP_VF_MEM, IPU_INPUT_BUFFER,
830                                     in_pixel_fmt, in_width, in_height, stride,
831                                     IPU_ROTATE_NONE,
832                                     vout->v4l2_bufs[vout->ipu_buf[0]].m.offset,
833                                     vout->v4l2_bufs[vout->ipu_buf[0]].m.offset,
834                                     u_offset, v_offset) != 0) {
835                 dev_err(dev, "Error initializing VDI current input buffer\n");
836                 return -EINVAL;
837         }
838         if (LOAD_3FIELDS(vout)) {
839                 if (ipu_init_channel_buffer(MEM_VDI_PRP_VF_MEM_P,
840                                             IPU_INPUT_BUFFER,
841                                             in_pixel_fmt, in_width, in_height,
842                                             stride, IPU_ROTATE_NONE,
843                                             vout->v4l2_bufs[vout->ipu_buf_p[0]].m.offset+vout->bytesperline,
844                                             vout->v4l2_bufs[vout->ipu_buf_p[0]].m.offset+vout->bytesperline,
845                                             u_offset, v_offset) != 0) {
846                         dev_err(dev, "Error initializing VDI previous input buffer\n");
847                         return -EINVAL;
848                 }
849                 if (ipu_init_channel_buffer(MEM_VDI_PRP_VF_MEM_N,
850                                             IPU_INPUT_BUFFER,
851                                             in_pixel_fmt, in_width, in_height,
852                                             stride, IPU_ROTATE_NONE,
853                                             vout->v4l2_bufs[vout->ipu_buf_n[0]].m.offset+vout->bytesperline,
854                                             vout->v4l2_bufs[vout->ipu_buf_n[0]].m.offset+vout->bytesperline,
855                                             u_offset, v_offset) != 0) {
856                         dev_err(dev, "Error initializing VDI next input buffer\n");
857                         return -EINVAL;
858                 }
859         }
860         return 0;
861 }
862
863 /*!
864  * Initialize VDI path
865  *
866  * @param vout      structure vout_data *
867  *
868  * @return status  0 Success
869  */
870 static int init_VDI(ipu_channel_params_t params, vout_data *vout,
871                         struct device *dev, struct fb_info *fbi,
872                         u16 out_width, u16 out_height)
873 {
874         params.mem_prp_vf_mem.in_width = vout->v2f.fmt.pix.width;
875         params.mem_prp_vf_mem.in_height = vout->v2f.fmt.pix.height;
876         params.mem_prp_vf_mem.motion_sel = vout->motion_sel;
877         params.mem_prp_vf_mem.field_fmt = vout->field_fmt;
878         params.mem_prp_vf_mem.in_pixel_fmt = vout->v2f.fmt.pix.pixelformat;
879         params.mem_prp_vf_mem.out_width = out_width;
880         params.mem_prp_vf_mem.out_height = out_height;
881         params.mem_prp_vf_mem.out_pixel_fmt = bpp_to_fmt(fbi);
882
883         if (init_VDI_channel(vout, params) != 0) {
884                 dev_err(dev, "Error init_VDI_channel channel\n");
885                 return -EINVAL;
886         }
887
888         if (init_VDI_in_channel_buffer(vout,
889                                        params.mem_prp_vf_mem.in_pixel_fmt,
890                                        params.mem_prp_vf_mem.in_width,
891                                        params.mem_prp_vf_mem.in_height,
892                                        bytes_per_pixel(params.mem_prp_vf_mem.
893                                                        in_pixel_fmt),
894                                        vout->offset.u_offset,
895                                        vout->offset.v_offset) != 0) {
896                 return -EINVAL;
897         }
898
899         if (!ipu_can_rotate_in_place(vout->rotate)) {
900                 if (vout->rot_pp_bufs[0]) {
901                         mxc_free_buffers(vout->rot_pp_bufs,
902                                          vout->rot_pp_bufs_vaddr, 2,
903                                          vout->display_buf_size);
904                 }
905                 if (mxc_allocate_buffers
906                     (vout->rot_pp_bufs, vout->rot_pp_bufs_vaddr, 2,
907                      vout->display_buf_size) < 0) {
908                         return -ENOBUFS;
909                 }
910
911                 if (ipu_init_channel_buffer(vout->post_proc_ch,
912                                             IPU_OUTPUT_BUFFER,
913                                             params.mem_prp_vf_mem.
914                                             out_pixel_fmt, out_width,
915                                             out_height, out_width,
916                                             IPU_ROTATE_NONE,
917                                             vout->rot_pp_bufs[0],
918                                             vout->rot_pp_bufs[1], 0, 0) != 0) {
919                         dev_err(dev, "Error initializing PRP output buffer\n");
920                         return -EINVAL;
921                 }
922
923                 if (ipu_init_channel(MEM_ROT_VF_MEM, NULL) != 0) {
924                         dev_err(dev, "Error initializing PP ROT channel\n");
925                         return -EINVAL;
926                 }
927                 if (ipu_init_channel_buffer(MEM_ROT_VF_MEM,
928                                             IPU_INPUT_BUFFER,
929                                             params.mem_prp_vf_mem.
930                                             out_pixel_fmt, out_width,
931                                             out_height, out_width,
932                                             vout->rotate,
933                                             vout->rot_pp_bufs[0],
934                                             vout->rot_pp_bufs[1], 0, 0) != 0) {
935                         dev_err(dev,
936                                 "Error initializing PP ROT input buffer\n");
937                         return -EINVAL;
938                 }
939
940                 /* swap width and height */
941                 if (vout->rotate >= IPU_ROTATE_90_RIGHT) {
942                         out_width = vout->crop_current.width;
943                         out_height = vout->crop_current.height;
944                 }
945
946                 if (ipu_init_channel_buffer(MEM_ROT_VF_MEM,
947                                             IPU_OUTPUT_BUFFER,
948                                             params.mem_prp_vf_mem.
949                                             out_pixel_fmt, out_width,
950                                             out_height, out_width,
951                                             IPU_ROTATE_NONE,
952                                             vout->display_bufs[0],
953                                             vout->display_bufs[1], 0, 0) != 0) {
954                         dev_err(dev,
955                                 "Error initializing PP-VDI output buffer\n");
956                         return -EINVAL;
957                 }
958
959                 if (ipu_link_channels(vout->post_proc_ch, MEM_ROT_VF_MEM) < 0)
960                         return -EINVAL;
961
962                 vout->display_input_ch = MEM_ROT_VF_MEM;
963                 ipu_enable_channel(MEM_ROT_VF_MEM);
964                 ipu_select_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, 0);
965                 ipu_select_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, 1);
966         } else {
967                 if (ipu_init_channel_buffer(vout->post_proc_ch,
968                                             IPU_OUTPUT_BUFFER,
969                                             params.mem_prp_vf_mem.
970                                             out_pixel_fmt, out_width,
971                                             out_height, out_width,
972                                             vout->rotate,
973                                             vout->display_bufs[0],
974                                             vout->display_bufs[1], 0, 0) != 0) {
975                         dev_err(dev,
976                                 "Error initializing PP-VDI output buffer\n");
977                         return -EINVAL;
978                 }
979         }
980         return 0;
981 }
982
983 /*!
984  * Initialize PP path
985  *
986  * @param params    structure ipu_channel_params_t
987  *
988  * @param vout      structure vout_data *
989  *
990  * @return status  0 Success
991  */
992 static int init_PP(ipu_channel_params_t *params, vout_data *vout,
993                    struct device *dev, struct fb_info *fbi,
994                    u16 out_width, u16 out_height)
995 {
996         u16 in_width, out_stride; /* stride of output channel */
997         u32 eba_offset;
998         u16 x_pos;
999         u16 y_pos;
1000         dma_addr_t phy_addr0;
1001         dma_addr_t phy_addr1;
1002
1003         eba_offset = 0;
1004         x_pos = 0;
1005         y_pos = 0;
1006
1007         params->mem_pp_mem.out_pixel_fmt = bpp_to_fmt(fbi);
1008
1009         if (vout->cur_disp_output == 5) {
1010                 x_pos = (vout->crop_current.left / 8) * 8;
1011                 y_pos = vout->crop_current.top;
1012                 eba_offset = (vout->xres*y_pos + x_pos) *
1013                                 bytes_per_pixel(params->mem_pp_mem.out_pixel_fmt);
1014         }
1015
1016         vout->bpp = fmt_to_bpp(params->mem_pp_mem.out_pixel_fmt);
1017         out_stride = vout->xres *
1018                                 bytes_per_pixel(params->mem_pp_mem.out_pixel_fmt);
1019         in_width = params->mem_pp_mem.in_width = vout->v2f.fmt.pix.width;
1020         params->mem_pp_mem.in_height = vout->v2f.fmt.pix.height;
1021         params->mem_pp_mem.in_pixel_fmt = vout->v2f.fmt.pix.pixelformat;
1022         params->mem_pp_mem.out_width = out_width;
1023         params->mem_pp_mem.out_height = out_height;
1024         params->mem_pp_mem.outh_resize_ratio = 0; /* 0 means unused */
1025         params->mem_pp_mem.outv_resize_ratio = 0; /* 0 means unused */
1026         /* split IC by two stripes, the by pass is impossible*/
1027         if (vout->pp_split) {
1028                 vout->pp_left_stripe.input_column = 0;
1029                 vout->pp_left_stripe.output_column = 0;
1030                 vout->pp_right_stripe.input_column = 0;
1031                 vout->pp_right_stripe.output_column = 0;
1032                 vout->pp_up_stripe.input_column = 0;
1033                 vout->pp_up_stripe.output_column = 0;
1034                 vout->pp_down_stripe.input_column = 0;
1035                 vout->pp_down_stripe.output_column = 0;
1036                 if (vout->pp_split != 3) {
1037                         ipu_calc_stripes_sizes(
1038                                 params->mem_pp_mem.in_width, /* input frame width;>1 */
1039                                 params->mem_pp_mem.out_width, /* output frame width; >1 */
1040                                 ipu_ic_out_max_width_size,
1041                                 (((unsigned long long)1) << 32), /* 32bit for fractional*/
1042                                 1,      /* equal stripes */
1043                                 params->mem_pp_mem.in_pixel_fmt,
1044                                 params->mem_pp_mem.out_pixel_fmt,
1045                                 &(vout->pp_left_stripe),
1046                                 &(vout->pp_right_stripe));
1047
1048                         vout->pp_left_stripe.input_column = vout->pp_left_stripe.input_column *
1049                                                                 fmt_to_bpp(vout->v2f.fmt.pix.pixelformat) / 8;
1050                         vout->pp_left_stripe.output_column = vout->pp_left_stripe.output_column *
1051                                                                 fmt_to_bpp(params->mem_pp_mem.out_pixel_fmt) / 8;
1052                         vout->pp_right_stripe.input_column = vout->pp_right_stripe.input_column *
1053                                                                 fmt_to_bpp(vout->v2f.fmt.pix.pixelformat) / 8;
1054                         vout->pp_right_stripe.output_column = vout->pp_right_stripe.output_column *
1055                                                                 fmt_to_bpp(params->mem_pp_mem.out_pixel_fmt) / 8;
1056
1057
1058                 /* updare parameters */
1059                 params->mem_pp_mem.in_width = vout->pp_left_stripe.input_width;
1060                 params->mem_pp_mem.out_width = vout->pp_left_stripe.output_width;
1061                 out_width = vout->pp_left_stripe.output_width;
1062                 /* for using in ic_init*/
1063                 params->mem_pp_mem.outh_resize_ratio = vout->pp_left_stripe.irr;
1064                 }
1065                 if (vout->pp_split != 2) {
1066                         ipu_calc_stripes_sizes(
1067                                 params->mem_pp_mem.in_height, /* input frame width;>1 */
1068                                 params->mem_pp_mem.out_height, /* output frame width; >1 */
1069                                 ipu_ic_out_max_height_size,
1070                                 (((unsigned long long)1) << 32),/* 32bit for fractional */
1071                                 1,      /* equal stripes */
1072                                 params->mem_pp_mem.in_pixel_fmt,
1073                                 params->mem_pp_mem.out_pixel_fmt,
1074                                 &(vout->pp_up_stripe),
1075                                 &(vout->pp_down_stripe));
1076                         vout->pp_down_stripe.output_column = vout->pp_down_stripe.output_column * out_stride;
1077                         vout->pp_up_stripe.output_column = vout->pp_up_stripe.output_column * out_stride;
1078                         params->mem_pp_mem.outv_resize_ratio = vout->pp_up_stripe.irr;
1079                         params->mem_pp_mem.in_height = vout->pp_up_stripe.input_width;/*height*/
1080                         out_height = vout->pp_up_stripe.output_width;/*height*/
1081                         if (vout->pp_split == 3)
1082                                 vout->pp_split = 2;/*2 vertical stripe as two horizontal stripes */
1083                 }
1084                 vout->pp_split_buf_num = 0;
1085         }
1086
1087         if (ipu_init_channel(vout->post_proc_ch, params) != 0) {
1088                 dev_err(dev, "Error initializing PP channel\n");
1089                 return -EINVAL;
1090         }
1091
1092         /* always enable double buffer */
1093         phy_addr0 = vout->v4l2_bufs[vout->ipu_buf[0]].m.offset;
1094         if (vout->ipu_buf[1] == -1)
1095                 phy_addr1 = phy_addr0;
1096         else
1097                 phy_addr1 = vout->v4l2_bufs[vout->ipu_buf[1]].m.offset;
1098         if (ipu_init_channel_buffer(vout->post_proc_ch,
1099                                     IPU_INPUT_BUFFER,
1100                                     params->mem_pp_mem.in_pixel_fmt,
1101                                     params->mem_pp_mem.in_width,
1102                                     params->mem_pp_mem.in_height,
1103                                     vout->v2f.fmt.pix.bytesperline /
1104                                     bytes_per_pixel(params->mem_pp_mem.
1105                                             in_pixel_fmt),
1106                                     IPU_ROTATE_NONE,
1107                                     phy_addr0,
1108                                     phy_addr1,
1109                                     vout->offset.u_offset,
1110                                     vout->offset.v_offset) != 0) {
1111                 dev_err(dev, "Error initializing PP input buffer\n");
1112                 return -EINVAL;
1113         }
1114
1115         if (!ipu_can_rotate_in_place(vout->rotate)) {
1116                 if (vout->rot_pp_bufs[0]) {
1117                         mxc_free_buffers(vout->rot_pp_bufs,
1118                                          vout->rot_pp_bufs_vaddr, 2,
1119                                          vout->display_buf_size);
1120                 }
1121                 if (mxc_allocate_buffers
1122                     (vout->rot_pp_bufs, vout->rot_pp_bufs_vaddr, 2,
1123                      vout->display_buf_size) < 0) {
1124                         return -ENOBUFS;
1125                 }
1126
1127                 if (ipu_init_channel_buffer(vout->post_proc_ch,
1128                                             IPU_OUTPUT_BUFFER,
1129                                             params->mem_pp_mem.
1130                                             out_pixel_fmt, out_width,
1131                                             out_height, out_stride,
1132                                             IPU_ROTATE_NONE,
1133                                             vout->rot_pp_bufs[0] + eba_offset,
1134                                             vout->rot_pp_bufs[1] + eba_offset, 0, 0) != 0) {
1135                         dev_err(dev, "Error initializing PP output buffer\n");
1136                         return -EINVAL;
1137                 }
1138
1139                 if (ipu_init_channel(MEM_ROT_PP_MEM, NULL) != 0) {
1140                         dev_err(dev, "Error initializing PP ROT channel\n");
1141                         return -EINVAL;
1142                 }
1143                 if (ipu_init_channel_buffer(MEM_ROT_PP_MEM,
1144                                             IPU_INPUT_BUFFER,
1145                                             params->mem_pp_mem.
1146                                             out_pixel_fmt, out_width,
1147                                             out_height, out_stride,
1148                                             vout->rotate,
1149                                             vout->rot_pp_bufs[0],
1150                                             vout->rot_pp_bufs[1], 0, 0) != 0) {
1151                         dev_err(dev,
1152                                 "Error initializing PP ROT input buffer\n");
1153                         return -EINVAL;
1154                 }
1155
1156                 /* swap width and height */
1157                 if (vout->rotate >= IPU_ROTATE_90_RIGHT) {
1158                         out_width = vout->crop_current.width;
1159                         out_height = vout->crop_current.height;
1160                 }
1161
1162                 if (ipu_init_channel_buffer(MEM_ROT_PP_MEM,
1163                                             IPU_OUTPUT_BUFFER,
1164                                             params->mem_pp_mem.
1165                                             out_pixel_fmt, out_width,
1166                                             out_height, out_stride,
1167                                             IPU_ROTATE_NONE,
1168                                             vout->display_bufs[0] + eba_offset,
1169                                             vout->display_bufs[1] + eba_offset, 0, 0) != 0) {
1170                         dev_err(dev, "Error initializing PP output buffer\n");
1171                         return -EINVAL;
1172                 }
1173
1174                 if (ipu_link_channels(vout->post_proc_ch, MEM_ROT_PP_MEM) < 0)
1175                         return -EINVAL;
1176
1177                 vout->display_input_ch = MEM_ROT_PP_MEM;
1178                 ipu_enable_channel(MEM_ROT_PP_MEM);
1179                 ipu_select_buffer(MEM_ROT_PP_MEM, IPU_OUTPUT_BUFFER, 0);
1180                 ipu_select_buffer(MEM_ROT_PP_MEM, IPU_OUTPUT_BUFFER, 1);
1181         } else {
1182                 if (ipu_init_channel_buffer(vout->post_proc_ch,
1183                                             IPU_OUTPUT_BUFFER,
1184                                             params->mem_pp_mem.
1185                                             out_pixel_fmt, out_width,
1186                                             out_height, out_stride,
1187                                             vout->rotate,
1188                                             vout->display_bufs[0] + eba_offset,
1189                                             vout->display_bufs[1] + eba_offset, 0, 0) != 0) {
1190                         dev_err(dev, "Error initializing PP output buffer\n");
1191                         return -EINVAL;
1192                 }
1193         }
1194
1195         /* fix EBAs for IDMAC channels */
1196         if (vout->pp_split) {
1197                 ipu_update_channel_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER,
1198                                                                         0,
1199                                                                         vout->v4l2_bufs[vout->ipu_buf[0]].m.offset +
1200                                                                         vout->pp_left_stripe.input_column +
1201                                                                         vout->pp_up_stripe.input_column * vout->bytesperline);
1202
1203
1204                 ipu_update_channel_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER,
1205                                                                         1,
1206                                                                         vout->v4l2_bufs[vout->ipu_buf[0]].m.offset +
1207                                                                         vout->pp_right_stripe.input_column +
1208                                                                         vout->pp_up_stripe.input_column * vout->bytesperline);
1209
1210                 ipu_update_channel_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER,
1211                                                                         0,
1212                                                                         vout->display_bufs[0] + eba_offset +
1213                                                                         vout->pp_left_stripe.output_column +
1214                                                                         vout->pp_up_stripe.output_column);
1215
1216                 ipu_update_channel_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER,
1217                                                                         1,
1218                                                                         vout->display_bufs[0] + eba_offset +
1219                                                                         vout->pp_right_stripe.output_column +
1220                                                                         vout->pp_up_stripe.output_column);
1221         }
1222
1223         return 0;
1224 }
1225
1226 /*!
1227  * Start the output stream
1228  *
1229  * @param vout      structure vout_data *
1230  *
1231  * @return status  0 Success
1232  */
1233 static int mxc_v4l2out_streamon(vout_data *vout)
1234 {
1235         struct device *dev = &vout->video_dev->dev;
1236         ipu_channel_params_t params;
1237         struct mxcfb_pos fb_pos;
1238         struct fb_var_screeninfo fbvar;
1239         struct fb_info *fbi =
1240             registered_fb[vout->output_fb_num[vout->cur_disp_output]];
1241         u16 out_width;
1242         u16 out_height;
1243         mm_segment_t old_fs;
1244         unsigned int ipu_ch = CHAN_NONE;
1245         unsigned int fb_fmt;
1246         int rc = 0;
1247
1248         dev_dbg(dev, "mxc_v4l2out_streamon: field format=%d\n",
1249                 vout->field_fmt);
1250
1251         if (!vout)
1252                 return -EINVAL;
1253
1254         if (vout->state != STATE_STREAM_OFF)
1255                 return -EBUSY;
1256
1257         if (queue_size(&vout->ready_q) < 2) {
1258                 dev_err(dev, "2 buffers not been queued yet!\n");
1259                 return -EINVAL;
1260         }
1261
1262         if ((vout->field_fmt == V4L2_FIELD_BOTTOM) || (vout->field_fmt == V4L2_FIELD_TOP)) {
1263                 dev_err(dev, "4 queued buffers need, not supported yet!\n");
1264                 return -EINVAL;
1265         }
1266
1267         /*
1268          * params init, check whether operation exceed the IC limitation:
1269          * whether split mode used ( ipu version >= ipuv3 only)
1270          */
1271         g_irq_cnt = g_buf_output_cnt = g_buf_q_cnt = g_buf_dq_cnt = 0;
1272         out_width = vout->crop_current.width;
1273         out_height = vout->crop_current.height;
1274         vout->disp_buf_num = 0;
1275         vout->next_done_ipu_buf = 0;
1276         vout->next_rdy_ipu_buf = vout->next_disp_ipu_buf = 1;
1277         vout->pp_split = 0;
1278         ipu_ic_out_max_height_size = 1024;
1279 #ifdef CONFIG_MXC_IPU_V1
1280         if (cpu_is_mx35())
1281                 ipu_ic_out_max_width_size = 800;
1282         else
1283                 ipu_ic_out_max_width_size = 720;
1284 #else
1285         ipu_ic_out_max_width_size = 1024;
1286 #endif
1287         if ((out_width > ipu_ic_out_max_width_size) ||
1288                 (out_height > ipu_ic_out_max_height_size))
1289                 vout->pp_split = 4;
1290         if (!INTERLACED_CONTENT(vout)) {
1291                 vout->ipu_buf[0] = dequeue_buf(&vout->ready_q);
1292                 /* split IC by two stripes, the by pass is impossible*/
1293                 if ((out_width != vout->v2f.fmt.pix.width ||
1294                         out_height != vout->v2f.fmt.pix.height) &&
1295                         vout->pp_split) {
1296                         vout->next_done_ipu_buf = vout->next_rdy_ipu_buf = 0;
1297                         vout->ipu_buf[1] = vout->ipu_buf[0];
1298                         vout->frame_count = 1;
1299                         if ((out_width > ipu_ic_out_max_width_size) &&
1300                                 (out_height > ipu_ic_out_max_height_size))
1301                                 vout->pp_split = 1; /*4 stripes*/
1302                         else if (!(out_height > ipu_ic_out_max_height_size))
1303                                 vout->pp_split = 2; /*two horizontal stripes */
1304                         else
1305                                 vout->pp_split = 3; /*2 vertical stripes*/
1306                 } else {
1307                         vout->ipu_buf[1] = -1;
1308                         vout->frame_count = 1;
1309                 }
1310         } else if (!LOAD_3FIELDS(vout)) {
1311                 vout->ipu_buf[0] = dequeue_buf(&vout->ready_q);
1312                 vout->ipu_buf[1] = -1;
1313                 vout->frame_count = 1;
1314         } else {
1315                 vout->ipu_buf_p[0] = dequeue_buf(&vout->ready_q);
1316                 vout->ipu_buf[0] = dequeue_buf(&vout->ready_q);
1317                 vout->ipu_buf_n[0] = vout->ipu_buf[0];
1318                 vout->ipu_buf_p[1] = -1;
1319                 vout->ipu_buf[1] = -1;
1320                 vout->ipu_buf_n[1] = -1;
1321                 last_index_n = vout->ipu_buf_n[0];
1322                 vout->frame_count = 2;
1323         }
1324
1325         /*
1326          * Bypass IC if resizing and rotation are not needed
1327          * Meanwhile, apply IC bypass to SDC only
1328          */
1329         fbvar = fbi->var;
1330         vout->xres = fbvar.xres;
1331         vout->yres = fbvar.yres;
1332
1333         if (vout->cur_disp_output == 3 || vout->cur_disp_output == 5) {
1334                 fb_fmt = vout->v2f.fmt.pix.pixelformat;
1335
1336                 /* DC channel can not use CSC */
1337                 if (vout->cur_disp_output == 5) {
1338                         if (fbi->fbops->fb_ioctl) {
1339                                 old_fs = get_fs();
1340                                 set_fs(KERNEL_DS);
1341                                 fbi->fbops->fb_ioctl(fbi, MXCFB_GET_DIFMT,
1342                                                 (unsigned long)&fb_fmt);
1343                                 set_fs(old_fs);
1344                         }
1345                 }
1346
1347                 fbvar.bits_per_pixel = 16;
1348                 if (format_is_yuv(fb_fmt))
1349                         fbvar.nonstd = IPU_PIX_FMT_UYVY;
1350                 else
1351                         fbvar.nonstd = 0;
1352                 if (vout->cur_disp_output == 3) {
1353                         fbvar.xres = out_width;
1354                         fbvar.yres = out_height;
1355                         vout->xres = fbvar.xres;
1356                         vout->yres = fbvar.yres;
1357                 }
1358
1359                 fbvar.xres_virtual = fbvar.xres;
1360                 fbvar.yres_virtual = fbvar.yres * 2;
1361         }
1362
1363         if (out_width == vout->v2f.fmt.pix.width &&
1364             out_height == vout->v2f.fmt.pix.height &&
1365             vout->xres == out_width &&
1366             vout->yres == out_height &&
1367             ipu_can_rotate_in_place(vout->rotate) &&
1368             (vout->bytesperline ==
1369              bytes_per_pixel(vout->v2f.fmt.pix.pixelformat) * out_width) &&
1370             !INTERLACED_CONTENT(vout)) {
1371                 vout->ic_bypass = 1;
1372         } else {
1373                 vout->ic_bypass = 0;
1374         }
1375
1376 #ifdef CONFIG_MXC_IPU_V1
1377         /* IPUv1 needs IC to do CSC */
1378         if (format_is_yuv(vout->v2f.fmt.pix.pixelformat) !=
1379             format_is_yuv(bpp_to_fmt(fbi)))
1380 #else
1381         /* DC channel needs IC to do CSC */
1382         if ((format_is_yuv(vout->v2f.fmt.pix.pixelformat) !=
1383                 format_is_yuv(fb_fmt)) &&
1384                         (vout->cur_disp_output == 5))
1385                 vout->ic_bypass = 0;
1386 #endif
1387
1388         if (fbi->fbops->fb_ioctl) {
1389                 old_fs = get_fs();
1390                 set_fs(KERNEL_DS);
1391                 fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
1392                                 (unsigned long)&ipu_ch);
1393                 set_fs(old_fs);
1394         }
1395
1396         if (ipu_ch == CHAN_NONE) {
1397                 dev_err(dev, "Can not get display ipu channel\n");
1398                 return -EINVAL;
1399         }
1400
1401         vout->display_ch = ipu_ch;
1402
1403         if (vout->ic_bypass) {
1404                 dev_info(dev, "Bypassing IC\n");
1405                 vout->pp_split = 0;
1406                 switch (vout->v2f.fmt.pix.pixelformat) {
1407                 case V4L2_PIX_FMT_YUV420:
1408                 case V4L2_PIX_FMT_YVU420:
1409                 case V4L2_PIX_FMT_NV12:
1410                 fbvar.bits_per_pixel = 12;
1411                         break;
1412                 case V4L2_PIX_FMT_YUV422P:
1413                         fbvar.bits_per_pixel = 16;
1414                         break;
1415                 default:
1416                         fbvar.bits_per_pixel = 8*
1417                         bytes_per_pixel(vout->v2f.fmt.pix.pixelformat);
1418                 }
1419                 fbvar.nonstd = vout->v2f.fmt.pix.pixelformat;
1420         }
1421
1422         /* Init display channel through fb API */
1423         fbvar.yoffset = 0;
1424         fbvar.activate |= FB_ACTIVATE_FORCE;
1425         acquire_console_sem();
1426         fbi->flags |= FBINFO_MISC_USEREVENT;
1427         fb_set_var(fbi, &fbvar);
1428         fbi->flags &= ~FBINFO_MISC_USEREVENT;
1429         release_console_sem();
1430
1431         if (fbi->fbops->fb_ioctl && vout->display_ch == MEM_FG_SYNC) {
1432                 fb_pos.x = vout->crop_current.left;
1433                 fb_pos.y = vout->crop_current.top;
1434                 old_fs = get_fs();
1435                 set_fs(KERNEL_DS);
1436                 fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
1437                                 (unsigned long)&fb_pos);
1438                 set_fs(old_fs);
1439         }
1440
1441         vout->display_bufs[1] = fbi->fix.smem_start;
1442         vout->display_bufs[0] = fbi->fix.smem_start +
1443                 (fbi->fix.line_length * vout->yres);
1444         vout->display_buf_size = vout->xres *
1445                 vout->yres * fbi->var.bits_per_pixel / 8;
1446
1447         /* avoid crashing if the YUV overlay was not allocated. Temporary workaround.
1448            thanks to Arnaud Patard, Mandriva. Hacked in by Matt at Genesi */
1449
1450         if (fbi && fbi->screen_base) {
1451         /* fill black color for init fb, we assume fb has double buffer*/
1452         if (format_is_yuv(vout->v2f.fmt.pix.pixelformat)) {
1453                 int i;
1454
1455                 if ((vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) ||
1456                         (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) ||
1457                         (!vout->ic_bypass)) {
1458                         short * tmp = (short *) fbi->screen_base;
1459                         short color;
1460                         if (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
1461                                 color = 0x8000;
1462                         else
1463                                 color = 0x80;
1464                         for (i = 0; i < (fbi->fix.line_length * fbi->var.yres_virtual)/2;
1465                                         i++, tmp++)
1466                                 *tmp = color;
1467                 } else if ((vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) ||
1468                                 (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) ||
1469                                 (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)) {
1470                         char * base = (char *)fbi->screen_base;
1471                         int j, screen_size = fbi->var.xres * fbi->var.yres;
1472
1473                         for (j = 0; j < 2; j++) {
1474                                 memset(base, 0, screen_size);
1475                                 base += screen_size;
1476                                 for (i = 0; i < screen_size/2; i++, base++)
1477                                         *base = 0x80;
1478                         }
1479                 } else if (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
1480                         char * base = (char *)fbi->screen_base;
1481                         int j, screen_size = fbi->var.xres * fbi->var.yres;
1482
1483                         for (j = 0; j < 2; j++) {
1484                                 memset(base, 0, screen_size);
1485                                 base += screen_size;
1486                                 for (i = 0; i < screen_size; i++, base++)
1487                                         *base = 0x80;
1488                         }
1489                 }
1490         } else
1491                 memset(fbi->screen_base, 0x0,
1492                                 fbi->fix.line_length * fbi->var.yres_virtual);
1493         } // NEKO
1494
1495         if (INTERLACED_CONTENT(vout))
1496                 vout->post_proc_ch = MEM_VDI_PRP_VF_MEM;
1497         else if (!vout->ic_bypass)
1498                 vout->post_proc_ch = MEM_PP_MEM;
1499
1500         /* Init IC channel */
1501         if (!vout->ic_bypass) {
1502                 if (vout->rotate >= IPU_ROTATE_90_RIGHT) {
1503                         out_width = vout->crop_current.height;
1504                         out_height = vout->crop_current.width;
1505                 }
1506                 vout->display_input_ch = vout->post_proc_ch;
1507                 memset(&params, 0, sizeof(params));
1508                 if (INTERLACED_CONTENT(vout)) {
1509                         if (vout->pp_split) {
1510                                 dev_err(&vout->video_dev->dev, "VDI split has not supported yet.\n");
1511                                 return -1;
1512                         } else
1513                                 rc = init_VDI(params, vout, dev, fbi, out_width, out_height);
1514                 } else {
1515                         rc = init_PP(&params, vout, dev, fbi, out_width, out_height);
1516                 }
1517                 if (rc < 0)
1518                         return rc;
1519         }
1520
1521         if (!vout->ic_bypass) {
1522                 switch (vout->display_input_ch) {
1523                 case MEM_PP_MEM:
1524                         vout->work_irq = IPU_IRQ_PP_OUT_EOF;
1525                         break;
1526                 case MEM_VDI_PRP_VF_MEM:
1527                         vout->work_irq = IPU_IRQ_PRP_VF_OUT_EOF;
1528                         break;
1529                 case MEM_ROT_VF_MEM:
1530                         vout->work_irq = IPU_IRQ_PRP_VF_ROT_OUT_EOF;
1531                         break;
1532                 case MEM_ROT_PP_MEM:
1533                         vout->work_irq = IPU_IRQ_PP_ROT_OUT_EOF;
1534                         break;
1535                 default:
1536                         dev_err(&vout->video_dev->dev,
1537                                 "not support channel, should not be here\n");
1538                 }
1539         } else
1540                 vout->work_irq = -1;
1541
1542         if (!vout->ic_bypass && (vout->work_irq > 0)) {
1543                 ipu_clear_irq(vout->work_irq);
1544                 ipu_request_irq(vout->work_irq,
1545                                 mxc_v4l2out_work_irq_handler,
1546                                 0, vout->video_dev->name, vout);
1547         }
1548
1549         vout->state = STATE_STREAM_PAUSED;
1550
1551         /* Enable display and IC channels */
1552         if (fbi) {
1553                 acquire_console_sem();
1554                 fb_blank(fbi, FB_BLANK_UNBLANK);
1555                 release_console_sem();
1556                 vout->fb_blank = FB_BLANK_UNBLANK;
1557         } else {
1558                 ipu_enable_channel(vout->display_ch);
1559         }
1560
1561         /* correct display ch buffer address */
1562         ipu_update_channel_buffer(vout->display_ch, IPU_INPUT_BUFFER,
1563                                         0, vout->display_bufs[0]);
1564         ipu_update_channel_buffer(vout->display_ch, IPU_INPUT_BUFFER,
1565                                         1, vout->display_bufs[1]);
1566
1567         if (!vout->ic_bypass) {
1568 #ifndef CONFIG_MXC_IPU_V1
1569                 ipu_enable_channel(vout->post_proc_ch);
1570 #endif
1571                 if (LOAD_3FIELDS(vout)) {
1572                         ipu_enable_channel(MEM_VDI_PRP_VF_MEM_P);
1573                         ipu_enable_channel(MEM_VDI_PRP_VF_MEM_N);
1574                         ipu_select_multi_vdi_buffer(0);
1575                 } else {
1576                         ipu_select_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER, 0);
1577                 }
1578                 ipu_select_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER, 0);
1579                 ipu_select_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER, 1);
1580 #ifdef CONFIG_MXC_IPU_V1
1581                 ipu_enable_channel(vout->post_proc_ch);
1582 #endif
1583         } else {
1584                 ipu_update_channel_buffer(vout->display_ch,
1585                                 IPU_INPUT_BUFFER,
1586                                 0, vout->v4l2_bufs[vout->ipu_buf[0]].m.offset);
1587                 if (vout->offset.u_offset || vout->offset.v_offset)
1588                         /* only update u/v offset */
1589                         ipu_update_channel_offset(vout->display_ch,
1590                                         IPU_INPUT_BUFFER,
1591                                         vout->v2f.fmt.pix.pixelformat,
1592                                         vout->v2f.fmt.pix.width,
1593                                         vout->v2f.fmt.pix.height,
1594                                         vout->bytesperline,
1595                                         vout->offset.u_offset,
1596                                         vout->offset.v_offset,
1597                                         0,
1598                                         0);
1599                 ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER, 0);
1600                 queue_work(vout->v4l_wq, &vout->icbypass_work);
1601         }
1602
1603         vout->start_jiffies = jiffies;
1604
1605         msleep(1);
1606
1607         dev_dbg(dev,
1608                 "streamon: start time = %lu jiffies\n", vout->start_jiffies);
1609
1610         return 0;
1611 }
1612
1613 /*!
1614  * Shut down the voutera
1615  *
1616  * @param vout      structure vout_data *
1617  *
1618  * @return status  0 Success
1619  */
1620 static int mxc_v4l2out_streamoff(vout_data * vout)
1621 {
1622         struct fb_info *fbi =
1623             registered_fb[vout->output_fb_num[vout->cur_disp_output]];
1624         int i, retval = 0;
1625         unsigned long lockflag = 0;
1626
1627         if (!vout)
1628                 return -EINVAL;
1629
1630         if (vout->state == STATE_STREAM_OFF) {
1631                 return 0;
1632         }
1633
1634         if (!vout->ic_bypass)
1635                 ipu_free_irq(vout->work_irq, vout);
1636
1637         if (vout->ic_bypass)
1638                 cancel_work_sync(&vout->icbypass_work);
1639
1640         /* fill black color for fb, we assume fb has double buffer*/
1641         if (format_is_yuv(vout->v2f.fmt.pix.pixelformat)) {
1642                 int i;
1643
1644                 if ((vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) ||
1645                         (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) ||
1646                         (!vout->ic_bypass)) {
1647                         short * tmp = (short *) fbi->screen_base;
1648                         short color;
1649                         if (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
1650                                 color = 0x8000;
1651                         else
1652                                 color = 0x80;
1653                         for (i = 0; i < (fbi->fix.line_length * fbi->var.yres_virtual)/2;
1654                                         i++, tmp++)
1655                                 *tmp = color;
1656                 } else if ((vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) ||
1657                                 (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) ||
1658                                 (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)) {
1659                         char * base = (char *)fbi->screen_base;
1660                         int j, screen_size = fbi->var.xres * fbi->var.yres;
1661
1662                         for (j = 0; j < 2; j++) {
1663                                 memset(base, 0, screen_size);
1664                                 base += screen_size;
1665                                 for (i = 0; i < screen_size/2; i++, base++)
1666                                         *base = 0x80;
1667                         }
1668                 } else if (vout->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
1669                         char * base = (char *)fbi->screen_base;
1670                         int j, screen_size = fbi->var.xres * fbi->var.yres;
1671
1672                         for (j = 0; j < 2; j++) {
1673                                 memset(base, 0, screen_size);
1674                                 base += screen_size;
1675                                 for (i = 0; i < screen_size; i++, base++)
1676                                         *base = 0x80;
1677                         }
1678                 }
1679         } else
1680                 memset(fbi->screen_base, 0x0,
1681                                 fbi->fix.line_length * fbi->var.yres_virtual);
1682
1683
1684
1685         spin_lock_irqsave(&g_lock, lockflag);
1686
1687         del_timer(&vout->output_timer);
1688
1689         if (vout->state == STATE_STREAM_ON) {
1690                 vout->state = STATE_STREAM_STOPPING;
1691         }
1692
1693         spin_unlock_irqrestore(&g_lock, lockflag);
1694
1695         if (vout->display_ch == MEM_FG_SYNC) {
1696                 struct mxcfb_pos fb_pos;
1697                 mm_segment_t old_fs;
1698
1699                 fb_pos.x = 0;
1700                 fb_pos.y = 0;
1701                 if (fbi->fbops->fb_ioctl) {
1702                         old_fs = get_fs();
1703                         set_fs(KERNEL_DS);
1704                         fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
1705                                         (unsigned long)&fb_pos);
1706                         set_fs(old_fs);
1707                 }
1708         }
1709
1710         if (vout->ic_bypass) {
1711                 fbi->var.activate |= FB_ACTIVATE_FORCE;
1712                 acquire_console_sem();
1713                 fbi->flags |= FBINFO_MISC_USEREVENT;
1714                 fb_set_var(fbi, &fbi->var);
1715                 fbi->flags &= ~FBINFO_MISC_USEREVENT;
1716                 release_console_sem();
1717
1718                 if (vout->display_ch == MEM_FG_SYNC) {
1719                         acquire_console_sem();
1720                         fb_blank(fbi, FB_BLANK_POWERDOWN);
1721                         release_console_sem();
1722                 }
1723
1724                 vout->display_bufs[0] = 0;
1725                 vout->display_bufs[1] = 0;
1726         } else if (vout->post_proc_ch == MEM_PP_MEM ||
1727             vout->post_proc_ch == MEM_PRP_VF_MEM) {
1728                 /* SDC with Rotation */
1729                 if (!ipu_can_rotate_in_place(vout->rotate)) {
1730                         ipu_unlink_channels(MEM_PP_MEM, MEM_ROT_PP_MEM);
1731                         ipu_disable_channel(MEM_ROT_PP_MEM, true);
1732
1733                         if (vout->rot_pp_bufs[0]) {
1734                                 mxc_free_buffers(vout->rot_pp_bufs,
1735                                                  vout->rot_pp_bufs_vaddr, 2,
1736                                                  vout->display_buf_size);
1737                         }
1738                 }
1739                 ipu_disable_channel(MEM_PP_MEM, true);
1740
1741                 fbi->var.activate |= FB_ACTIVATE_FORCE;
1742                 acquire_console_sem();
1743                 fbi->flags |= FBINFO_MISC_USEREVENT;
1744                 fb_set_var(fbi, &fbi->var);
1745                 fbi->flags &= ~FBINFO_MISC_USEREVENT;
1746                 release_console_sem();
1747
1748                 if (vout->display_ch == MEM_FG_SYNC) {
1749                         acquire_console_sem();
1750                         fb_blank(fbi, FB_BLANK_POWERDOWN);
1751                         release_console_sem();
1752                 }
1753
1754                 vout->display_bufs[0] = 0;
1755                 vout->display_bufs[1] = 0;
1756
1757                 ipu_uninit_channel(MEM_PP_MEM);
1758                 if (!ipu_can_rotate_in_place(vout->rotate))
1759                         ipu_uninit_channel(MEM_ROT_PP_MEM);
1760         } else if (INTERLACED_CONTENT(vout) &&
1761                 (vout->post_proc_ch == MEM_VDI_PRP_VF_MEM)) {
1762                 if (!ipu_can_rotate_in_place(vout->rotate)) {
1763                         ipu_unlink_channels(MEM_VDI_PRP_VF_MEM,
1764                                             MEM_ROT_VF_MEM);
1765                         ipu_disable_channel(MEM_ROT_VF_MEM, true);
1766
1767                         if (vout->rot_pp_bufs[0]) {
1768                                 mxc_free_buffers(vout->rot_pp_bufs,
1769                                                  vout->rot_pp_bufs_vaddr, 2,
1770                                                  vout->display_buf_size);
1771                         }
1772                 }
1773
1774                 ipu_disable_channel(MEM_VDI_PRP_VF_MEM, true);
1775                 if (LOAD_3FIELDS(vout)) {
1776                         ipu_disable_channel(MEM_VDI_PRP_VF_MEM_P, true);
1777                         ipu_disable_channel(MEM_VDI_PRP_VF_MEM_N, true);
1778                 }
1779
1780                 fbi->var.activate |= FB_ACTIVATE_FORCE;
1781                 acquire_console_sem();
1782                 fbi->flags |= FBINFO_MISC_USEREVENT;
1783                 fb_set_var(fbi, &fbi->var);
1784                 fbi->flags &= ~FBINFO_MISC_USEREVENT;
1785                 release_console_sem();
1786
1787                 if (vout->display_ch == MEM_FG_SYNC) {
1788                         acquire_console_sem();
1789                         fb_blank(fbi, FB_BLANK_POWERDOWN);
1790                         release_console_sem();
1791                 }
1792
1793                 vout->display_bufs[0] = 0;
1794                 vout->display_bufs[1] = 0;
1795
1796                 ipu_uninit_channel(MEM_VDI_PRP_VF_MEM);
1797                 if (LOAD_3FIELDS(vout)) {
1798                         ipu_uninit_channel(MEM_VDI_PRP_VF_MEM_P);
1799                         ipu_uninit_channel(MEM_VDI_PRP_VF_MEM_N);
1800                 }
1801                 if (!ipu_can_rotate_in_place(vout->rotate))
1802                         ipu_uninit_channel(MEM_ROT_VF_MEM);
1803         }
1804
1805         vout->ready_q.head = vout->ready_q.tail = 0;
1806         vout->done_q.head = vout->done_q.tail = 0;
1807         for (i = 0; i < vout->buffer_cnt; i++) {
1808                 vout->v4l2_bufs[i].flags = 0;
1809                 vout->v4l2_bufs[i].timestamp.tv_sec = 0;
1810                 vout->v4l2_bufs[i].timestamp.tv_usec = 0;
1811         }
1812
1813         vout->post_proc_ch = CHAN_NONE;
1814         vout->state = STATE_STREAM_OFF;
1815
1816         return retval;
1817 }
1818
1819 /*
1820  * Valid whether the palette is supported
1821  *
1822  * @param palette  V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
1823  *
1824  * @return 1 if supported, 0 if failed
1825  */
1826 static inline int valid_mode(u32 palette)
1827 {
1828         return ((palette == V4L2_PIX_FMT_RGB565) ||
1829                 (palette == V4L2_PIX_FMT_BGR24) ||
1830                 (palette == V4L2_PIX_FMT_RGB24) ||
1831                 (palette == V4L2_PIX_FMT_BGR32) ||
1832                 (palette == V4L2_PIX_FMT_RGB32) ||
1833                 (palette == V4L2_PIX_FMT_NV12) ||
1834                 (palette == V4L2_PIX_FMT_UYVY) ||
1835                 (palette == V4L2_PIX_FMT_YUYV) ||
1836                 (palette == V4L2_PIX_FMT_YUV422P) ||
1837                 (palette == V4L2_PIX_FMT_YUV444) ||
1838                 (palette == V4L2_PIX_FMT_YUV420));
1839 }
1840
1841 /*
1842  * V4L2 - Handles VIDIOC_G_FMT Ioctl
1843  *
1844  * @param vout         structure vout_data *
1845  *
1846  * @param v4l2_format structure v4l2_format *
1847  *
1848  * @return  status    0 success, EINVAL failed
1849  */
1850 static int mxc_v4l2out_g_fmt(vout_data * vout, struct v4l2_format *f)
1851 {
1852         if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1853                 return -EINVAL;
1854         }
1855         *f = vout->v2f;
1856         return 0;
1857 }
1858
1859 /*
1860  * V4L2 - Handles VIDIOC_S_FMT Ioctl
1861  *
1862  * @param vout         structure vout_data *
1863  *
1864  * @param v4l2_format structure v4l2_format *
1865  *
1866  * @return  status    0 success, EINVAL failed
1867  */
1868 static int mxc_v4l2out_s_fmt(vout_data * vout, struct v4l2_format *f)
1869 {
1870         int retval = 0;
1871         u32 size = 0;
1872         u32 bytesperline;
1873
1874         if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1875                 retval = -EINVAL;
1876                 goto err0;
1877         }
1878         if (!valid_mode(f->fmt.pix.pixelformat)) {
1879                 dev_err(&vout->video_dev->dev, "pixel format not supported\n");
1880                 retval = -EINVAL;
1881                 goto err0;
1882         }
1883
1884         bytesperline = (f->fmt.pix.width * fmt_to_bpp(f->fmt.pix.pixelformat)) /
1885             8;
1886         if (f->fmt.pix.bytesperline < bytesperline) {
1887                 f->fmt.pix.bytesperline = bytesperline;
1888         } else {
1889                 bytesperline = f->fmt.pix.bytesperline;
1890         }
1891         vout->bytesperline = bytesperline;
1892
1893         /* Based on http://v4l2spec.bytesex.org/spec/x6386.htm#V4L2-FIELD */
1894         vout->field_fmt = f->fmt.pix.field;
1895         switch (vout->field_fmt) {
1896                 /* Images are in progressive format, not interlaced */
1897         case V4L2_FIELD_NONE:
1898                 break;
1899                 /* The two fields of a frame are passed in separate buffers,
1900                    in temporal order, i. e. the older one first. */
1901         case V4L2_FIELD_ALTERNATE:
1902                 dev_err(&vout->video_dev->dev,
1903                         "V4L2_FIELD_ALTERNATE field format not supported yet!\n");
1904                 break;
1905         case V4L2_FIELD_INTERLACED_TB:
1906         case V4L2_FIELD_INTERLACED_BT:
1907                 if (cpu_is_mx51() || cpu_is_mx53())
1908                         break;
1909                 dev_err(&vout->video_dev->dev,
1910                         "De-interlacing not supported in this device!\n");
1911                 vout->field_fmt = V4L2_FIELD_NONE;
1912                 break;
1913         default:
1914                 vout->field_fmt = V4L2_FIELD_NONE;
1915                 break;
1916         }
1917
1918         switch (f->fmt.pix.pixelformat) {
1919         case V4L2_PIX_FMT_YUV422P:
1920                 /* byteperline for YUV planar formats is for
1921                    Y plane only */
1922                 size = bytesperline * f->fmt.pix.height * 2;
1923                 break;
1924         case V4L2_PIX_FMT_YUV420:
1925         case V4L2_PIX_FMT_NV12:
1926                 size = (bytesperline * f->fmt.pix.height * 3) / 2;
1927                 break;
1928         default:
1929                 size = bytesperline * f->fmt.pix.height;
1930                 break;
1931         }
1932
1933         /* Return the actual size of the image to the app */
1934         if (f->fmt.pix.sizeimage < size) {
1935                 f->fmt.pix.sizeimage = size;
1936         } else {
1937                 size = f->fmt.pix.sizeimage;
1938         }
1939
1940         vout->v2f.fmt.pix = f->fmt.pix;
1941         if (vout->v2f.fmt.pix.priv != 0) {
1942                 if (copy_from_user(&vout->offset,
1943                                    (void *)vout->v2f.fmt.pix.priv,
1944                                    sizeof(vout->offset))) {
1945                         retval = -EFAULT;
1946                         goto err0;
1947                 }
1948         } else {
1949                 vout->offset.u_offset = 0;
1950                 vout->offset.v_offset = 0;
1951         }
1952
1953         retval = 0;
1954       err0:
1955         return retval;
1956 }
1957
1958 /*
1959  * V4L2 - Handles VIDIOC_G_CTRL Ioctl
1960  *
1961  * @param vout         structure vout_data *
1962  *
1963  * @param c           structure v4l2_control *
1964  *
1965  * @return  status    0 success, EINVAL failed
1966  */
1967 static int mxc_get_v42lout_control(vout_data * vout, struct v4l2_control *c)
1968 {
1969         switch (c->id) {
1970         case V4L2_CID_HFLIP:
1971                 return (vout->rotate & IPU_ROTATE_HORIZ_FLIP) ? 1 : 0;
1972         case V4L2_CID_VFLIP:
1973                 return (vout->rotate & IPU_ROTATE_VERT_FLIP) ? 1 : 0;
1974         case (V4L2_CID_PRIVATE_BASE + 1):
1975                 return vout->rotate;
1976         default:
1977                 return -EINVAL;
1978         }
1979 }
1980
1981 /*
1982  * V4L2 - Handles VIDIOC_S_CTRL Ioctl
1983  *
1984  * @param vout         structure vout_data *
1985  *
1986  * @param c           structure v4l2_control *
1987  *
1988  * @return  status    0 success, EINVAL failed
1989  */
1990 static int mxc_set_v42lout_control(vout_data * vout, struct v4l2_control *c)
1991 {
1992         switch (c->id) {
1993         case V4L2_CID_HFLIP:
1994                 vout->rotate |= c->value ? IPU_ROTATE_HORIZ_FLIP :
1995                     IPU_ROTATE_NONE;
1996                 break;
1997         case V4L2_CID_VFLIP:
1998                 vout->rotate |= c->value ? IPU_ROTATE_VERT_FLIP :
1999                     IPU_ROTATE_NONE;
2000                 break;
2001         case V4L2_CID_MXC_ROT:
2002                 vout->rotate = c->value;
2003                 break;
2004         case V4L2_CID_MXC_MOTION:
2005                 vout->motion_sel = c->value;
2006                 break;
2007         default:
2008                 return -EINVAL;
2009         }
2010         return 0;
2011 }
2012
2013 /*!
2014  * V4L2 interface - open function
2015  *
2016  * @param file         structure file *
2017  *
2018  * @return  status    0 success, ENODEV invalid device instance,
2019  *                    ENODEV timeout, ERESTARTSYS interrupted by user
2020  */
2021 static int mxc_v4l2out_open(struct file *file)
2022 {
2023         struct video_device *dev = video_devdata(file);
2024         vout_data *vout = video_get_drvdata(dev);
2025         int err;
2026
2027         if (!vout) {
2028                 return -ENODEV;
2029         }
2030
2031         down(&vout->busy_lock);
2032
2033         err = -EINTR;
2034         if (signal_pending(current))
2035                 goto oops;
2036
2037
2038         if (vout->open_count++ == 0) {
2039                 init_waitqueue_head(&vout->v4l_bufq);
2040
2041                 init_timer(&vout->output_timer);
2042                 vout->output_timer.function = mxc_v4l2out_timer_handler;
2043                 vout->output_timer.data = (unsigned long)vout;
2044
2045                 vout->state = STATE_STREAM_OFF;
2046                 vout->rotate = IPU_ROTATE_NONE;
2047
2048                 vout->v4l_wq = create_singlethread_workqueue("v4l2q");
2049                 if (!vout->v4l_wq) {
2050                         dev_dbg(&dev->dev,
2051                                         "Could not create work queue\n");
2052                         err = -ENOMEM;
2053                         goto oops;
2054                 }
2055
2056                 INIT_WORK(&vout->icbypass_work, icbypass_work_func);
2057         }
2058
2059         file->private_data = dev;
2060
2061         up(&vout->busy_lock);
2062
2063         return 0;
2064
2065       oops:
2066         up(&vout->busy_lock);
2067         return err;
2068 }
2069
2070 /*!
2071  * V4L2 interface - close function
2072  *
2073  * @param file     struct file *
2074  *
2075  * @return         0 success
2076  */
2077 static int mxc_v4l2out_close(struct file *file)
2078 {
2079         struct video_device *dev = video_devdata(file);
2080         vout_data *vout = video_get_drvdata(dev);
2081
2082         if (--vout->open_count == 0) {
2083                 if (vout->state != STATE_STREAM_OFF)
2084                         mxc_v4l2out_streamoff(vout);
2085
2086                 file->private_data = NULL;
2087
2088                 mxc_free_buffers(vout->queue_buf_paddr, vout->queue_buf_vaddr,
2089                                  vout->buffer_cnt, vout->queue_buf_size);
2090                 vout->buffer_cnt = 0;
2091                 mxc_free_buffers(vout->rot_pp_bufs, vout->rot_pp_bufs_vaddr, 2,
2092                                  vout->display_buf_size);
2093
2094                 /* capture off */
2095                 wake_up_interruptible(&vout->v4l_bufq);
2096
2097                 flush_workqueue(vout->v4l_wq);
2098                 destroy_workqueue(vout->v4l_wq);
2099         }
2100
2101         return 0;
2102 }
2103
2104 /*!
2105  * V4L2 interface - ioctl function
2106  *
2107  * @param file       struct file *
2108  *
2109  * @param ioctlnr    unsigned int
2110  *
2111  * @param arg        void *
2112  *
2113  * @return           0 success, ENODEV for invalid device instance,
2114  *                   -1 for other errors.
2115  */
2116 static long
2117 mxc_v4l2out_do_ioctl(struct file *file,
2118                      unsigned int ioctlnr, void *arg)
2119 {
2120         struct video_device *vdev = file->private_data;
2121         vout_data *vout = video_get_drvdata(vdev);
2122         int retval = 0;
2123         int i = 0;
2124
2125         if (!vout)
2126                 return -EBADF;
2127
2128         /* make this _really_ smp-safe */
2129         if (down_interruptible(&vout->busy_lock))
2130                 return -EBUSY;
2131
2132         switch (ioctlnr) {
2133         case VIDIOC_QUERYCAP:
2134                 {
2135                         struct v4l2_capability *cap = arg;
2136                         strcpy(cap->driver, "mxc_v4l2_output");
2137                         cap->version = 0;
2138                         cap->capabilities =
2139                             V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
2140                         cap->card[0] = '\0';
2141                         cap->bus_info[0] = '\0';
2142                         retval = 0;
2143                         break;
2144                 }
2145         case VIDIOC_G_FMT:
2146                 {
2147                         struct v4l2_format *gf = arg;
2148                         retval = mxc_v4l2out_g_fmt(vout, gf);
2149                         break;
2150                 }
2151         case VIDIOC_S_FMT:
2152                 {
2153                         struct v4l2_format *sf = arg;
2154                         if (vout->state != STATE_STREAM_OFF) {
2155                                 retval = -EBUSY;
2156                                 break;
2157                         }
2158                         retval = mxc_v4l2out_s_fmt(vout, sf);
2159                         break;
2160                 }
2161         case VIDIOC_REQBUFS:
2162                 {
2163                         struct v4l2_requestbuffers *req = arg;
2164                         if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) ||
2165                             (req->memory != V4L2_MEMORY_MMAP)) {
2166                                 dev_dbg(&vdev->dev,
2167                                         "VIDIOC_REQBUFS: incorrect buffer type\n");
2168                                 retval = -EINVAL;
2169                                 break;
2170                         }
2171
2172                         if (req->count == 0)
2173                                 mxc_v4l2out_streamoff(vout);
2174
2175                         if (vout->state == STATE_STREAM_OFF) {
2176                                 if (vout->queue_buf_paddr[0] != 0) {
2177                                         mxc_free_buffers(vout->queue_buf_paddr,
2178                                                          vout->queue_buf_vaddr,
2179                                                          vout->buffer_cnt,
2180                                                          vout->queue_buf_size);
2181                                         dev_dbg(&vdev->dev,
2182                                                 "VIDIOC_REQBUFS: freed buffers\n");
2183                                 }
2184                                 vout->buffer_cnt = 0;
2185                         } else {
2186                                 dev_dbg(&vdev->dev,
2187                                         "VIDIOC_REQBUFS: Buffer is in use\n");
2188                                 retval = -EBUSY;
2189                                 break;
2190                         }
2191
2192                         if (req->count == 0)
2193                                 break;
2194
2195                         if (req->count < MIN_FRAME_NUM) {
2196                                 req->count = MIN_FRAME_NUM;
2197                         } else if (req->count > MAX_FRAME_NUM) {
2198                                 req->count = MAX_FRAME_NUM;
2199                         }
2200                         vout->buffer_cnt = req->count;
2201                         vout->queue_buf_size =
2202                             PAGE_ALIGN(vout->v2f.fmt.pix.sizeimage);
2203
2204                         retval = mxc_allocate_buffers(vout->queue_buf_paddr,
2205                                                       vout->queue_buf_vaddr,
2206                                                       vout->buffer_cnt,
2207                                                       vout->queue_buf_size);
2208                         if (retval < 0)
2209                                 break;
2210
2211                         /* Init buffer queues */
2212                         vout->done_q.head = 0;
2213                         vout->done_q.tail = 0;
2214                         vout->ready_q.head = 0;
2215                         vout->ready_q.tail = 0;
2216
2217                         for (i = 0; i < vout->buffer_cnt; i++) {
2218                                 memset(&(vout->v4l2_bufs[i]), 0,
2219                                        sizeof(vout->v4l2_bufs[i]));
2220                                 vout->v4l2_bufs[i].flags = 0;
2221                                 vout->v4l2_bufs[i].memory = V4L2_MEMORY_MMAP;
2222                                 vout->v4l2_bufs[i].index = i;
2223                                 vout->v4l2_bufs[i].type =
2224                                     V4L2_BUF_TYPE_VIDEO_OUTPUT;
2225                                 vout->v4l2_bufs[i].length =
2226                                     PAGE_ALIGN(vout->v2f.fmt.pix.sizeimage);
2227                                 vout->v4l2_bufs[i].m.offset =
2228                                     (unsigned long)vout->queue_buf_paddr[i];
2229                                 vout->v4l2_bufs[i].timestamp.tv_sec = 0;
2230                                 vout->v4l2_bufs[i].timestamp.tv_usec = 0;
2231                         }
2232                         break;
2233                 }
2234         case VIDIOC_QUERYBUF:
2235                 {
2236                         struct v4l2_buffer *buf = arg;
2237                         u32 type = buf->type;
2238                         int index = buf->index;
2239
2240                         if ((type != V4L2_BUF_TYPE_VIDEO_OUTPUT) ||
2241                             (index >= vout->buffer_cnt)) {
2242                                 dev_dbg(&vdev->dev,
2243                                         "VIDIOC_QUERYBUFS: incorrect buffer type\n");
2244                                 retval = -EINVAL;
2245                                 break;
2246                         }
2247                         down(&vout->param_lock);
2248                         memcpy(buf, &(vout->v4l2_bufs[index]), sizeof(*buf));
2249                         up(&vout->param_lock);
2250                         break;
2251                 }
2252         case VIDIOC_QBUF:
2253                 {
2254                         struct v4l2_buffer *buf = arg;
2255                         int index = buf->index;
2256                         unsigned long lock_flags;
2257                         int param[5][3];
2258
2259                         if ((buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) ||
2260                             (index >= vout->buffer_cnt)) {
2261                                 retval = -EINVAL;
2262                                 break;
2263                         }
2264
2265                         dev_dbg(&vdev->dev, "VIDIOC_QBUF: %d field = %d\n", buf->index, buf->field);
2266
2267                         /* mmapped buffers are L1 WB cached,
2268                          * so we need to clean them */
2269                         if (buf->memory & V4L2_MEMORY_MMAP) {
2270                                 flush_cache_all();
2271                         }
2272
2273                         spin_lock_irqsave(&g_lock, lock_flags);
2274
2275                         memcpy(&(vout->v4l2_bufs[index]), buf, sizeof(*buf));
2276                         vout->v4l2_bufs[index].flags |= V4L2_BUF_FLAG_QUEUED;
2277
2278                         g_buf_q_cnt++;
2279                         if (vout->v4l2_bufs[index].reserved)
2280                                 if (!copy_from_user(&param[0][0],
2281                                                     (void *)vout->
2282                                                     v4l2_bufs[index]
2283                                                     .reserved, sizeof(param)))
2284                                         ipu_set_csc_coefficients(vout->
2285                                                                  display_ch,
2286                                                                  param);
2287                         queue_buf(&vout->ready_q, index);
2288                         if (vout->state == STATE_STREAM_PAUSED) {
2289                                 index = peek_next_buf(&vout->ready_q);
2290                                 setup_next_buf_timer(vout, index);
2291                                 vout->state = STATE_STREAM_ON;
2292                         }
2293
2294                         spin_unlock_irqrestore(&g_lock, lock_flags);
2295                         break;
2296                 }
2297         case VIDIOC_DQBUF:
2298                 {
2299                         struct v4l2_buffer *buf = arg;
2300                         int idx;
2301
2302                         if ((queue_size(&vout->done_q) == 0) &&
2303                             (file->f_flags & O_NONBLOCK)) {
2304                                 retval = -EAGAIN;
2305                                 break;
2306                         }
2307
2308                         if (!wait_event_interruptible_timeout(vout->v4l_bufq,
2309                                                               queue_size(&vout->
2310                                                                          done_q)
2311                                                               != 0, 10 * HZ)) {
2312                                 dev_dbg(&vdev->dev, "VIDIOC_DQBUF: timeout\n");
2313                                 retval = -ETIME;
2314                                 break;
2315                         } else if (signal_pending(current)) {
2316                                 dev_dbg(&vdev->dev,
2317                                         "VIDIOC_DQBUF: interrupt received\n");