From 5f6cce3acfb1bcbdeae73bf32f894007bd7beccf Mon Sep 17 00:00:00 2001 From: Pradeep Jilagam Date: Fri, 24 Aug 2012 16:23:06 +0530 Subject: [PATCH] msm_fb: display: Fix blend configuration for MDP4.1 MDP4.1 blend operation registers are not double buffered and take effect as soon as they are configured. Configuring these registers at any place other than between dma and vsync produce flickers as new blend values would get applied to previous mixer configurations. Configure blend operation registers just after dma is over, before vsync. Change-Id: I377c11222f7a0cd77e98e90edec6e2e1dc0c17ca Signed-off-by: Pradeep Jilagam Signed-off-by: Siddhartha Agrawal --- drivers/video/msm/mdp4.h | 1 + drivers/video/msm/mdp4_overlay.c | 31 ++++++++++++++++++++++++++- drivers/video/msm/mdp4_overlay_dtv.c | 4 ++++ drivers/video/msm/mdp4_overlay_lcdc.c | 4 ++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h index eae2246e949..7e16f3cf872 100644 --- a/drivers/video/msm/mdp4.h +++ b/drivers/video/msm/mdp4.h @@ -582,6 +582,7 @@ int mdp4_overlay_dsi_state_get(void); void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe); void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all); void mdp4_mixer_blend_setup(int mixer); +void mdp4_mixer_blend_cfg(int); struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage); void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe, int commit); void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe, int commit); diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c index 650f1f2112e..93a3b7a11d9 100644 --- a/drivers/video/msm/mdp4_overlay.c +++ b/drivers/video/msm/mdp4_overlay.c @@ -1865,6 +1865,32 @@ static void mdp4_overlay_bg_solidfill(struct blend_cfg *blend) mdp4_overlay_reg_flush(pipe, 0); } +void mdp4_mixer_blend_cfg(int mixer) +{ + int i, off; + unsigned char *overlay_base; + struct blend_cfg *blend; + + if (mixer == MDP4_MIXER2) + overlay_base = MDP_BASE + MDP4_OVERLAYPROC2_BASE; + else if (mixer == MDP4_MIXER1) + overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE; + else + overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE; + + blend = &ctrl->blend[mixer][MDP4_MIXER_STAGE_BASE]; + blend++; /* stage0 */ + + for (i = MDP4_MIXER_STAGE0; i < MDP4_MIXER_STAGE_MAX; i++) { + off = 20 * i; + off = 0x20 * (i - MDP4_MIXER_STAGE0); + if (i == MDP4_MIXER_STAGE3) + off -= 4; + outpdw(overlay_base + off + 0x104, blend->op); + blend++; + } +} + /* * D(i+1) = Ks * S + Kd * D(i) */ @@ -2011,7 +2037,10 @@ void mdp4_mixer_blend_setup(int mixer) outpdw(overlay_base + off + 0x108, blend->fg_alpha); outpdw(overlay_base + off + 0x10c, blend->bg_alpha); - outpdw(overlay_base + off + 0x104, blend->op); + + if (mdp_rev >= MDP_REV_42) + outpdw(overlay_base + off + 0x104, blend->op); + outpdw(overlay_base + (off << 5) + 0x1004, blend->co3_sel); outpdw(overlay_base + off + 0x110, blend->transp_low0);/* low */ outpdw(overlay_base + off + 0x114, blend->transp_low1);/* low */ diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c index 7e27c13bfaa..19d3481a70b 100644 --- a/drivers/video/msm/mdp4_overlay_dtv.c +++ b/drivers/video/msm/mdp4_overlay_dtv.c @@ -907,8 +907,12 @@ void mdp4_dmae_done_dtv(void) vctrl->blt_change = 0; } + if (mdp_rev <= MDP_REV_41) + mdp4_mixer_blend_cfg(MDP4_MIXER1); + complete_all(&vctrl->dmae_comp); mdp4_overlay_dma_commit(MDP4_MIXER1); + vsync_irq_disable(INTR_DMA_E_DONE, MDP_DMA_E_TERM); spin_unlock(&vctrl->spin_lock); } diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c index df75ac81611..0549c03ab74 100644 --- a/drivers/video/msm/mdp4_overlay_lcdc.c +++ b/drivers/video/msm/mdp4_overlay_lcdc.c @@ -856,6 +856,10 @@ void mdp4_dmap_done_lcdc(int cndx) } complete_all(&vctrl->dmap_comp); + + if (mdp_rev <= MDP_REV_41) + mdp4_mixer_blend_cfg(MDP4_MIXER0); + mdp4_overlay_dma_commit(cndx); spin_unlock(&vctrl->spin_lock); }