summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c46
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.h3
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;