diff options
author | Liu Ying <b17645@freescale.com> | 2010-01-11 11:52:08 -0500 |
---|---|---|
committer | Liu Ying <b17645@freescale.com> | 2010-01-11 11:52:08 -0500 |
commit | 1c0333fa91840af83c6d988df84b7a92e9f35082 (patch) | |
tree | 713e4f1111cfcac4128b3e2ac912a7ce54d34234 | |
parent | 72434b33af14bb4933359def7c9c149ead309de0 (diff) |
ENGR00119034 V4L2 overlay:Use DP to do CSC for preview on DPFG
Use DP to do CSC for preview on DPFG instead of using IC channel
so that we can get better performance. This change can make us
get rid of IC channel bandwidth limitation when using IC channel
to do upsizing from low resolution to high resolution and CSC.
This change doesn't touch V4L2 overlay for DPBG, because using DP
to do CSC will change the pixel format for DPBG(usually for GUI).
This change doesn't touch V4L2 capture, because users rarely do
upsizing with high multiple in this case.
Signed-off-by: Liu Ying <b17645@freescale.com>
-rw-r--r-- | drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c | 46 | ||||
-rw-r--r-- | drivers/media/video/mxc/capture/mxc_v4l2_capture.h | 3 |
2 files changed, 38 insertions, 11 deletions
diff --git a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c index 369facdf29c2..75574e94d272 100644 --- a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c +++ b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -23,9 +23,12 @@ #include <linux/console.h> #include <linux/ipu.h> #include <linux/mxcfb.h> +#include <mach/hardware.h> #include "mxc_v4l2_capture.h" #include "ipu_prp_sw.h" +#define OVERLAY_FB_SUPPORT_NONSTD (cpu_is_mx51_rev(CHIP_REV_2_0) >= 1) + /* * Function definitions */ @@ -42,7 +45,7 @@ static int prpvf_start(void *private) struct fb_info *fbi = NULL; cam_data *cam = (cam_data *) private; ipu_channel_params_t vf; - u32 format = IPU_PIX_FMT_RGB565; + u32 vf_out_format = 0; u32 size = 2, temp = 0; int err = 0, i = 0; @@ -58,8 +61,10 @@ static int prpvf_start(void *private) for (i = 0; i < num_registered_fb; i++) { char *idstr = registered_fb[i]->fix.id; - if (strcmp(idstr, "DISP3 FG") == 0) + if (strcmp(idstr, "DISP3 FG") == 0) { fbi = registered_fb[i]; + break; + } } if (fbi == NULL) { @@ -68,8 +73,20 @@ static int prpvf_start(void *private) } fbvar = fbi->var; + + /* Store the overlay frame buffer's original std */ + cam->fb_origin_std = fbvar.nonstd; + + if (OVERLAY_FB_SUPPORT_NONSTD) { + /* Use DP to do CSC so that we can get better performance */ + vf_out_format = IPU_PIX_FMT_UYVY; + fbvar.nonstd = vf_out_format; + } else { + vf_out_format = IPU_PIX_FMT_RGB565; + fbvar.nonstd = 0; + } + fbvar.bits_per_pixel = 16; - fbvar.nonstd = 0; fbvar.xres = fbvar.xres_virtual = cam->win.w.width; fbvar.yres = cam->win.w.height; fbvar.yres_virtual = cam->win.w.height * 2; @@ -90,7 +107,7 @@ static int prpvf_start(void *private) vf.csi_prp_vf_mem.out_width = cam->win.w.height; vf.csi_prp_vf_mem.out_height = cam->win.w.width; } - vf.csi_prp_vf_mem.out_pixel_fmt = format; + vf.csi_prp_vf_mem.out_pixel_fmt = vf_out_format; size = cam->win.w.width * cam->win.w.height * size; err = ipu_init_channel(CSI_PRP_VF_MEM, &vf); @@ -137,7 +154,7 @@ static int prpvf_start(void *private) if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) { err = ipu_init_channel_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, - format, + vf_out_format, vf.csi_prp_vf_mem.out_width, vf.csi_prp_vf_mem.out_height, vf.csi_prp_vf_mem.out_width, @@ -154,7 +171,7 @@ static int prpvf_start(void *private) } err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_INPUT_BUFFER, - format, + vf_out_format, vf.csi_prp_vf_mem.out_width, vf.csi_prp_vf_mem.out_height, vf.csi_prp_vf_mem.out_width, @@ -173,7 +190,7 @@ static int prpvf_start(void *private) } err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, - format, + vf_out_format, vf.csi_prp_vf_mem.out_height, vf.csi_prp_vf_mem.out_width, vf.csi_prp_vf_mem.out_height, @@ -211,7 +228,7 @@ static int prpvf_start(void *private) ipu_select_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, 1); } else { err = ipu_init_channel_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, - format, cam->win.w.width, + vf_out_format, cam->win.w.width, cam->win.w.height, cam->win.w.width, cam->vf_rotation, @@ -281,14 +298,17 @@ static int prpvf_stop(void *private) cam_data *cam = (cam_data *) private; int err = 0, i = 0; struct fb_info *fbi = NULL; + struct fb_var_screeninfo fbvar; if (cam->overlay_active == false) return 0; for (i = 0; i < num_registered_fb; i++) { char *idstr = registered_fb[i]->fix.id; - if (strcmp(idstr, "DISP3 FG") == 0) + if (strcmp(idstr, "DISP3 FG") == 0) { fbi = registered_fb[i]; + break; + } } if (fbi == NULL) { @@ -317,6 +337,12 @@ static int prpvf_stop(void *private) fb_blank(fbi, FB_BLANK_POWERDOWN); release_console_sem(); + /* Set the overlay frame buffer std to what it is used to be */ + fbvar = fbi->var; + fbvar.nonstd = cam->fb_origin_std; + fbvar.activate |= FB_ACTIVATE_FORCE; + fb_set_var(fbi, &fbvar); + ipu_csi_enable_mclk_if(CSI_MCLK_VF, cam->csi, false, false); if (cam->vf_bufs_vaddr[0]) { diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h index 7982b5cf4308..f12be977dedd 100644 --- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h +++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -137,6 +137,7 @@ typedef struct _cam_data { bool overlay_active; int output; struct fb_info *overlay_fb; + int fb_origin_std; /* v4l2 format */ struct v4l2_format v2f; |