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>
This commit is contained in:
Liu Ying
2010-01-11 11:52:08 -05:00
committed by Matt Sealey
parent af4f8336b7
commit 46e0dd8d8d
2 changed files with 38 additions and 11 deletions

View File

@@ -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]) {

View File

@@ -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;