From 46e0dd8d8ddadb576cdf9db52d144abe144cdec5 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 11 Jan 2010 11:52:08 -0500 Subject: [PATCH] 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 --- .../media/video/mxc/capture/ipu_prp_vf_sdc.c | 46 +++++++++++++++---- .../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 369facdf29c..75574e94d27 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 #include #include +#include #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 7982b5cf430..f12be977ded 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;