summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWayne Zou <b36644@freescale.com>2013-01-21 13:36:10 +0800
committerWayne Zou <b36644@freescale.com>2013-01-23 10:56:26 +0800
commit77df6b03b1e4b0dd10a231c2881d0f97e5a3490e (patch)
tree9753116302afdfbbf2755f463570d4bde6403cbe /drivers
parent34baea61b49e7e08a93bbf79fd99306af25426cf (diff)
ENGR00240972-2 IPU: Add vdic double frame rate feature
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mxc/ipu3/ipu_device.c81
-rw-r--r--drivers/mxc/ipu3/ipu_ic.c9
2 files changed, 71 insertions, 19 deletions
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index be1725129ce2..8c58ba1c3f59 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -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;
diff --git a/drivers/mxc/ipu3/ipu_ic.c b/drivers/mxc/ipu3/ipu_ic.c
index b0b79add39a6..0f528d078b32 100644
--- a/drivers/mxc/ipu3/ipu_ic.c
+++ b/drivers/mxc/ipu3/ipu_ic.c
@@ -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);