summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Brown <oliver.brown@freescale.com>2012-02-21 17:48:26 -0600
committerOliver Brown <oliver.brown@freescale.com>2012-02-21 17:56:08 -0600
commitdd675f86d9b352cb89549db70d5f7e7e7d5352b1 (patch)
tree2a5ee3b1467cba500f171ad0bef1a40f9a39dd06
parent313dc5ed31f70cd3141853f9234f71ef2da5ca8f (diff)
ENGR00175042 - Add hwcomposer to ICS iMX53 build.
Add Hardware Composer to ICS for iMX53. Signed-off-by: Oliver Brown <oliver.brown@freescale.com>
-rw-r--r--drivers/mxc/ipu3/ipu_common.c21
-rw-r--r--drivers/video/mxc/mxc_edid.c22
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c65
3 files changed, 73 insertions, 35 deletions
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index b3f23afc5c30..339eb8a6fbd1 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -1270,7 +1270,7 @@ int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan)) {
unsigned reg = IDMAC_CH_LOCK_EN_1;
uint32_t value = 0;
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx53() || cpu_is_mx6q()) {
_ipu_ch_param_set_axi_id(ipu, dma_chan, 0);
switch (dma_chan) {
case 5:
@@ -2116,22 +2116,15 @@ void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buf
return;
ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
- if (bufNum == 0) {
- if (idma_is_set(ipu, IPU_CHA_BUF0_RDY, dma_ch)) {
- ipu_cm_write(ipu, idma_mask(dma_ch),
+ if (bufNum == 0)
+ ipu_cm_write(ipu, idma_mask(dma_ch),
IPU_CHA_BUF0_RDY(dma_ch));
- }
- } else if (bufNum == 1) {
- if (idma_is_set(ipu, IPU_CHA_BUF1_RDY, dma_ch)) {
- ipu_cm_write(ipu, idma_mask(dma_ch),
+ else if (bufNum == 1)
+ ipu_cm_write(ipu, idma_mask(dma_ch),
IPU_CHA_BUF1_RDY(dma_ch));
- }
- } else {
- if (idma_is_set(ipu, IPU_CHA_BUF2_RDY, dma_ch)) {
- ipu_cm_write(ipu, idma_mask(dma_ch),
+ else
+ ipu_cm_write(ipu, idma_mask(dma_ch),
IPU_CHA_BUF2_RDY(dma_ch));
- }
- }
ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
}
diff --git a/drivers/video/mxc/mxc_edid.c b/drivers/video/mxc/mxc_edid.c
index 386df9259971..f7ad32d27338 100644
--- a/drivers/video/mxc/mxc_edid.c
+++ b/drivers/video/mxc/mxc_edid.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -138,9 +138,17 @@ const struct fb_videomode mxc_cea_mode[64] = {
* pixclock, since for many CEA modes, 2 frequencies are supported
* e.g. 640x480 @ 60Hz or 59.94Hz
*/
-int mxc_edid_fb_mode_is_equal(const struct fb_videomode *mode1,
- const struct fb_videomode *mode2)
+int mxc_edid_fb_mode_is_equal(bool use_aspect,
+ const struct fb_videomode *mode1,
+ const struct fb_videomode *mode2)
{
+ u32 mask;
+
+ if (use_aspect)
+ mask = ~0;
+ else
+ mask = ~FB_VMODE_ASPECT_MASK;
+
return (mode1->xres == mode2->xres &&
mode1->yres == mode2->yres &&
mode1->hsync_len == mode2->hsync_len &&
@@ -150,7 +158,7 @@ int mxc_edid_fb_mode_is_equal(const struct fb_videomode *mode1,
mode1->upper_margin == mode2->upper_margin &&
mode1->lower_margin == mode2->lower_margin &&
mode1->sync == mode2->sync &&
- mode1->vmode == mode2->vmode);
+ (mode1->vmode & mask) == (mode2->vmode & mask));
}
static void get_detailed_timing(unsigned char *block,
@@ -450,7 +458,7 @@ int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
fb_var_to_videomode(&m, var);
- if (mxc_edid_fb_mode_is_equal(&m, &mxc_cea_mode[i]))
+ if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
break;
}
@@ -465,9 +473,11 @@ EXPORT_SYMBOL(mxc_edid_var_to_vic);
int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
{
int i;
+ bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);
for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
- if (mxc_edid_fb_mode_is_equal(mode, &mxc_cea_mode[i]))
+ if (mxc_edid_fb_mode_is_equal(use_aspect,
+ mode, &mxc_cea_mode[i]))
break;
}
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index 6c82bf04c7a5..840c40c46806 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -214,6 +214,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
int fb_stride;
unsigned long base;
+ unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
switch (bpp_to_pixfmt(fbi)) {
case IPU_PIX_FMT_YUV420P2:
@@ -228,16 +229,28 @@ static int _setup_disp_channel2(struct fb_info *fbi)
fb_stride = fbi->fix.line_length;
}
+ base = fbi->fix.smem_start;
+ fr_xoff = fbi->var.xoffset;
+ fr_w = fbi->var.xres_virtual;
+ if (!(fbi->var.vmode & FB_VMODE_YWRAP)) {
+ dev_dbg(fbi->device, "Y wrap disabled\n");
+ fr_yoff = fbi->var.yoffset % fbi->var.yres;
+ fr_h = fbi->var.yres;
+ base += fbi->fix.line_length * fbi->var.yres *
+ (fbi->var.yoffset / fbi->var.yres);
+ } else {
+ dev_dbg(fbi->device, "Y wrap enabled\n");
+ fr_yoff = fbi->var.yoffset;
+ fr_h = fbi->var.yres_virtual;
+ }
+ base += fr_yoff * fb_stride + fr_xoff;
+
mxc_fbi->cur_ipu_buf = 2;
sema_init(&mxc_fbi->flip_sem, 1);
if (mxc_fbi->alpha_chan_en) {
mxc_fbi->cur_ipu_alpha_buf = 1;
sema_init(&mxc_fbi->alpha_flip_sem, 1);
}
- fbi->var.xoffset = 0;
-
- base = (fbi->var.yoffset * fb_stride + fbi->var.xoffset);
- base += fbi->fix.smem_start;
retval = ipu_init_channel_buffer(mxc_fbi->ipu,
mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
@@ -255,6 +268,17 @@ static int _setup_disp_channel2(struct fb_info *fbi)
"ipu_init_channel_buffer error %d\n", retval);
}
+ /* update u/v offset */
+ ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER,
+ bpp_to_pixfmt(fbi),
+ fr_w,
+ fr_h,
+ fr_w,
+ 0, 0,
+ fr_yoff,
+ fr_xoff);
+
if (mxc_fbi->alpha_chan_en) {
retval = ipu_init_channel_buffer(mxc_fbi->ipu,
mxc_fbi->ipu_ch,
@@ -1193,6 +1217,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par,
*mxc_graphic_fbi = NULL;
u_int y_bottom;
+ unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
unsigned long base, active_alpha_phy_addr = 0;
bool loc_alpha_en = false;
int fb_stride;
@@ -1219,9 +1244,6 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
y_bottom = var->yoffset;
- if (!(var->vmode & FB_VMODE_YWRAP))
- y_bottom += var->yres;
-
if (y_bottom > info->var.yres_virtual)
return -EINVAL;
@@ -1238,8 +1260,21 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
fb_stride = info->fix.line_length;
}
- base = (var->yoffset * fb_stride + var->xoffset);
- base += info->fix.smem_start;
+ base = info->fix.smem_start;
+ fr_xoff = var->xoffset;
+ fr_w = info->var.xres_virtual;
+ if (!(var->vmode & FB_VMODE_YWRAP)) {
+ dev_dbg(info->device, "Y wrap disabled\n");
+ fr_yoff = var->yoffset % info->var.yres;
+ fr_h = info->var.yres;
+ base += info->fix.line_length * info->var.yres *
+ (var->yoffset / info->var.yres);
+ } else {
+ dev_dbg(info->device, "Y wrap enabled\n");
+ fr_yoff = var->yoffset;
+ fr_h = info->var.yres_virtual;
+ }
+ base += fr_yoff * fb_stride + fr_xoff;
/* Check if DP local alpha is enabled and find the graphic fb */
if (mxc_fbi->ipu_ch == MEM_BG_SYNC || mxc_fbi->ipu_ch == MEM_FG_SYNC) {
@@ -1294,12 +1329,12 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
IPU_INPUT_BUFFER,
bpp_to_pixfmt(info),
- info->var.xres_virtual,
- info->var.yres_virtual,
- info->var.xres_virtual,
+ fr_w,
+ fr_h,
+ fr_w,
0, 0,
- var->yoffset,
- var->xoffset);
+ fr_yoff,
+ fr_xoff);
ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
mxc_fbi->cur_ipu_buf);