summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Chen <b02280@freescale.com>2010-07-26 15:43:48 +0800
committerJason Chen <b02280@freescale.com>2010-07-26 15:43:48 +0800
commitcdf7d31170182fe72bad7245b2ec9baaad496e90 (patch)
treec3aa8cebbb239b156173d65b4f29660ccb368ca2
parentd2dab9fe6b75d20156e6bcb378fc2b59f278e7eb (diff)
ENGR00125412-1 ipuv3 fb: fg should not bigger than bg
Add check in mxcfb_check_var(), if fg size is bigger than bg, then make it same size as bg. Signed-off-by: Jason Chen <b02280@freescale.com>
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c33
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c30
2 files changed, 63 insertions, 0 deletions
diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c
index a21baaf5ce49..ea64707468a0 100644
--- a/drivers/mxc/ipu3/ipu_disp.c
+++ b/drivers/mxc/ipu3/ipu_disp.c
@@ -1778,6 +1778,39 @@ int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos,
}
EXPORT_SYMBOL(ipu_disp_set_window_pos);
+int32_t ipu_disp_get_window_pos(ipu_channel_t channel, int16_t *x_pos,
+ int16_t *y_pos)
+{
+ u32 reg;
+ unsigned long lock_flags;
+ uint32_t flow = 0;
+
+ if (channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ if (!g_ipu_clk_enabled)
+ clk_enable(g_ipu_clk);
+ spin_lock_irqsave(&ipu_lock, lock_flags);
+
+ reg = __raw_readl(DP_FG_POS(flow));
+
+ *x_pos = (reg >> 16) & 0x7FF;
+ *y_pos = reg & 0x7FF;
+
+ spin_unlock_irqrestore(&ipu_lock, lock_flags);
+ if (!g_ipu_clk_enabled)
+ clk_disable(g_ipu_clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disp_get_window_pos);
+
void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset)
{
if (channel == DIRECT_ASYNC0)
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index 1cdb55d899f3..f345ff2fa972 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -565,6 +565,36 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
u32 vtotal;
u32 htotal;
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
+
+ /* fg should not bigger than bg */
+ if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
+ struct fb_info *fbi_tmp;
+ struct mxcfb_info *mxc_fbi_tmp;
+ int i, bg_xres, bg_yres;
+ int16_t pos_x, pos_y;
+
+ bg_xres = var->xres;
+ bg_yres = var->yres;
+
+ for (i = 0; i < num_registered_fb; i++) {
+ fbi_tmp = registered_fb[i];
+ mxc_fbi_tmp = (struct mxcfb_info *)
+ (fbi_tmp->par);
+ if (mxc_fbi_tmp->ipu_ch == MEM_BG_SYNC) {
+ bg_xres = fbi_tmp->var.xres;
+ bg_yres = fbi_tmp->var.yres;
+ break;
+ }
+ }
+
+ ipu_disp_get_window_pos(mxc_fbi->ipu_ch, &pos_x, &pos_y);
+
+ if ((var->xres + pos_x) > bg_xres)
+ var->xres = bg_xres - pos_x;
+ if ((var->yres + pos_y) > bg_yres)
+ var->yres = bg_yres - pos_y;
+ }
if (var->xres_virtual < var->xres)
var->xres_virtual = var->xres;