]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00240972-2 IPU: Add vdic double frame rate feature
authorWayne Zou <b36644@freescale.com>
Mon, 21 Jan 2013 05:36:10 +0000 (13:36 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:52 +0000 (08:35 +0200)
Add vdic double frame rate feature
It depends on the which frame(0 or 1),
and interlace field format(top or bottom) to do VDI process

Signed-off-by: Wayne Zou <b36644@freescale.com>
drivers/mxc/ipu3/ipu_device.c
drivers/mxc/ipu3/ipu_ic.c

index be1725129ce23b9f794c6d6c1b650c1f37df0916..8c58ba1c3f59b846b2007643fb552c1c934885a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -1856,6 +1856,7 @@ static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
        int out_uoff = 0, out_voff = 0, out_rot;
        int out_w = 0, out_h = 0, out_stride;
        int out_fmt;
+       u32 vdi_frame_idx = 0;
 
        memset(&params, 0, sizeof(params));
 
@@ -1908,6 +1909,19 @@ static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
                }
        }
 
+       if (t->input.deinterlace.enable) {
+               if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_FIELD_MASK)
+                       params.mem_prp_vf_mem.field_fmt =
+                               IPU_DEINTERLACE_FIELD_BOTTOM;
+               else
+                       params.mem_prp_vf_mem.field_fmt =
+                               IPU_DEINTERLACE_FIELD_TOP;
+
+               if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
+                       vdi_frame_idx = t->input.deinterlace.field_fmt &
+                                               IPU_DEINTERLACE_RATE_FRAME1;
+       }
+
        if (t->set.mode & VDOA_MODE)
                ipu->vdoa_en = 1;
 
@@ -1921,13 +1935,6 @@ static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
        }
 
        if (deinterlace_3_field(t)) {
-               if (IPU_DEINTERLACE_FIELD_TOP == t->input.deinterlace.field_fmt)
-                       params.mem_prp_vf_mem.field_fmt = V4L2_FIELD_INTERLACED_TB;
-               else if (IPU_DEINTERLACE_FIELD_BOTTOM == t->input.deinterlace.field_fmt)
-                       params.mem_prp_vf_mem.field_fmt = V4L2_FIELD_INTERLACED_BT;
-               else
-                       dev_err(t->dev, "ERR[no-0x%x]invalid field fmt:0x%x!\n",
-                               t->task_no, t->input.deinterlace.field_fmt);
                ret = ipu_init_channel(ipu, t->set.vdi_ic_p_chan, &params);
                if (ret < 0) {
                        t->state = STATE_INIT_CHAN_FAIL;
@@ -1949,13 +1956,57 @@ static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
        } else {
                if ((deinterlace_3_field(t)) &&
                        (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
-                               inbuf_p = t->input.paddr + t->set.istride +
-                                               t->set.i_off;
-                               inbuf = t->input.paddr_n + t->set.i_off;
-                               inbuf_n = t->input.paddr_n + t->set.istride +
-                                               t->set.i_off;
-               } else
-                       inbuf = t->input.paddr + t->set.i_off;
+                       if (params.mem_prp_vf_mem.field_fmt ==
+                               IPU_DEINTERLACE_FIELD_TOP) {
+                               if (vdi_frame_idx) {
+                                       inbuf_p = t->input.paddr + t->set.istride +
+                                                       t->set.i_off;
+                                       inbuf = t->input.paddr_n + t->set.i_off;
+                                       inbuf_n = t->input.paddr_n + t->set.istride +
+                                                       t->set.i_off;
+                                       params.mem_prp_vf_mem.field_fmt =
+                                               IPU_DEINTERLACE_FIELD_BOTTOM;
+                               } else {
+                                       inbuf_p = t->input.paddr + t->set.i_off;
+                                       inbuf = t->input.paddr + t->set.istride + t->set.i_off;
+                                       inbuf_n = t->input.paddr_n + t->set.i_off;
+                               }
+                       } else {
+                               if (vdi_frame_idx) {
+                                       inbuf_p = t->input.paddr + t->set.i_off;
+                                       inbuf = t->input.paddr_n + t->set.istride + t->set.i_off;
+                                       inbuf_n = t->input.paddr_n + t->set.i_off;
+                                       params.mem_prp_vf_mem.field_fmt =
+                                               IPU_DEINTERLACE_FIELD_TOP;
+                               } else {
+                                       inbuf_p = t->input.paddr + t->set.istride +
+                                                       t->set.i_off;
+                                       inbuf = t->input.paddr + t->set.i_off;
+                                       inbuf_n = t->input.paddr_n + t->set.istride +
+                                                       t->set.i_off;
+                               }
+                       }
+               } else {
+                       if (t->input.deinterlace.enable) {
+                               if (params.mem_prp_vf_mem.field_fmt ==
+                                       IPU_DEINTERLACE_FIELD_TOP) {
+                                       if (vdi_frame_idx) {
+                                               inbuf = t->input.paddr + t->set.istride + t->set.i_off;
+                                               params.mem_prp_vf_mem.field_fmt =
+                                                       IPU_DEINTERLACE_FIELD_BOTTOM;
+                                       } else
+                                               inbuf = t->input.paddr + t->set.i_off;
+                               } else {
+                                       if (vdi_frame_idx) {
+                                               inbuf = t->input.paddr + t->set.i_off;
+                                               params.mem_prp_vf_mem.field_fmt =
+                                                       IPU_DEINTERLACE_FIELD_TOP;
+                                       } else
+                                               inbuf = t->input.paddr + t->set.istride + t->set.i_off;
+                               }
+                       } else
+                               inbuf = t->input.paddr + t->set.i_off;
+               }
 
                if (t->overlay_en)
                        ovbuf = t->overlay.paddr + t->set.ov_off;
index b0b79add39a60831b48ce84f5f24f7d12c99ce98..0f528d078b3296e14f723a0794b8671b2e044b83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -69,6 +69,7 @@ void _ipu_vdi_set_motion(struct ipu_soc *ipu, ipu_motion_sel motion_sel)
                reg |= VDI_C_MOT_SEL_LOW;
 
        ipu_vdi_write(ipu, reg, VDI_C);
+       dev_dbg(ipu->dev, "VDI_C = \t0x%08X\n", reg);
 }
 
 void ic_dump_register(struct ipu_soc *ipu)
@@ -215,10 +216,10 @@ void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_param
        }
        ipu_vdi_write(ipu, reg, VDI_C);
 
-       if (params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_TB)
-               _ipu_vdi_set_top_field_man(ipu, false);
-       else if (params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_BT)
+       if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_TOP)
                _ipu_vdi_set_top_field_man(ipu, true);
+       else if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_BOTTOM)
+               _ipu_vdi_set_top_field_man(ipu, false);
 
        _ipu_vdi_set_motion(ipu, params->mem_prp_vf_mem.motion_sel);