msm_fb: display: vsync driven screen update
This patch will queue multiple surfaces and commit those
surfaces into mdp at same instance so that surfaces will
be blended and displayed at same time. Hardware vsync event
is delivered to the user space frame work via uevent. Both
queue and commit are controlled by frame work and synchonized
with vsync event. Therefore frame rate will match with vsync rate.
Change-Id: If630a6d94fd38483ee313f575b1a71ed8bd65a52
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index adf3bb9..573e317 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -409,35 +409,53 @@
goto out;
panel = mdp4_overlay_panel_list();
- if (isr & INTR_PRIMARY_VSYNC) {
- mdp4_stat.intr_vsync_p++;
+
+ if (isr & INTR_DMA_P_DONE) {
+ mdp4_stat.intr_dma_p++;
dma = &dma2_data;
- spin_lock(&mdp_spin_lock);
- mdp_intr_mask &= ~INTR_PRIMARY_VSYNC;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- dma->waiting = FALSE;
if (panel & MDP4_PANEL_LCDC)
- mdp4_primary_vsync_lcdc();
+ mdp4_dmap_done_lcdc(0);
+#ifdef CONFIG_FB_MSM_OVERLAY
#ifdef CONFIG_FB_MSM_MIPI_DSI
else if (panel & MDP4_PANEL_DSI_VIDEO)
- mdp4_primary_vsync_dsi_video();
+ mdp4_dmap_done_dsi_video(0);
+ else if (panel & MDP4_PANEL_DSI_CMD)
+ mdp4_dmap_done_dsi_cmd(0);
+#else
+ else { /* MDDI */
+ mdp4_dma_p_done_mddi(dma);
+ mdp_pipe_ctrl(MDP_DMA2_BLOCK,
+ MDP_BLOCK_POWER_OFF, TRUE);
+ complete(&dma->comp);
+ }
#endif
- spin_unlock(&mdp_spin_lock);
+#else
+ else {
+ spin_lock(&mdp_spin_lock);
+ dma->busy = FALSE;
+ spin_unlock(&mdp_spin_lock);
+ complete(&dma->comp);
+ }
+#endif
}
-#ifdef CONFIG_FB_MSM_DTV
- if (isr & INTR_EXTERNAL_VSYNC) {
- mdp4_stat.intr_vsync_e++;
- dma = &dma_e_data;
- spin_lock(&mdp_spin_lock);
- mdp_intr_mask &= ~INTR_EXTERNAL_VSYNC;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- dma->waiting = FALSE;
- if (panel & MDP4_PANEL_DTV)
- mdp4_external_vsync_dtv();
- spin_unlock(&mdp_spin_lock);
- }
+ if (isr & INTR_DMA_S_DONE) {
+ mdp4_stat.intr_dma_s++;
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
+ dma = &dma2_data;
+#else
+ dma = &dma_s_data;
#endif
+ dma->busy = FALSE;
+ mdp_pipe_ctrl(MDP_DMA_S_BLOCK,
+ MDP_BLOCK_POWER_OFF, TRUE);
+ complete(&dma->comp);
+ }
+ if (isr & INTR_DMA_E_DONE) {
+ mdp4_stat.intr_dma_e++;
+ if (panel & MDP4_PANEL_DTV)
+ mdp4_dmae_done_dtv();
+ }
#ifdef CONFIG_FB_MSM_OVERLAY
if (isr & INTR_OVERLAY0_DONE) {
mdp4_stat.intr_overlay0++;
@@ -450,15 +468,15 @@
dma->waiting = FALSE;
spin_unlock(&mdp_spin_lock);
if (panel & MDP4_PANEL_LCDC)
- mdp4_overlay0_done_lcdc(dma);
+ mdp4_overlay0_done_lcdc(0);
#ifdef CONFIG_FB_MSM_MIPI_DSI
else if (panel & MDP4_PANEL_DSI_VIDEO)
- mdp4_overlay0_done_dsi_video(dma);
+ mdp4_overlay0_done_dsi_video(0);
#endif
} else { /* MDDI, DSI_CMD */
#ifdef CONFIG_FB_MSM_MIPI_DSI
if (panel & MDP4_PANEL_DSI_CMD)
- mdp4_overlay0_done_dsi_cmd(dma);
+ mdp4_overlay0_done_dsi_cmd(0);
#else
if (panel & MDP4_PANEL_MDDI)
mdp4_overlay0_done_mddi(dma);
@@ -500,75 +518,20 @@
#endif
#endif /* OVERLAY */
- if (isr & INTR_DMA_P_DONE) {
- mdp4_stat.intr_dma_p++;
- dma = &dma2_data;
- if (panel & MDP4_PANEL_LCDC) {
- /* disable LCDC interrupt */
- spin_lock(&mdp_spin_lock);
- mdp_intr_mask &= ~INTR_DMA_P_DONE;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- dma->waiting = FALSE;
- mdp4_dma_p_done_lcdc();
- spin_unlock(&mdp_spin_lock);
- }
-#ifdef CONFIG_FB_MSM_OVERLAY
-#ifdef CONFIG_FB_MSM_MIPI_DSI
- else if (panel & MDP4_PANEL_DSI_VIDEO) {
- /* disable LCDC interrupt */
- spin_lock(&mdp_spin_lock);
- mdp_intr_mask &= ~INTR_DMA_P_DONE;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- dma->waiting = FALSE;
- mdp4_dma_p_done_dsi_video(dma);
- spin_unlock(&mdp_spin_lock);
- } else if (panel & MDP4_PANEL_DSI_CMD) {
- mdp4_dma_p_done_dsi(dma);
- }
-#else
- else { /* MDDI */
- mdp4_dma_p_done_mddi(dma);
- mdp_pipe_ctrl(MDP_DMA2_BLOCK,
- MDP_BLOCK_POWER_OFF, TRUE);
- complete(&dma->comp);
- }
-#endif
-#else
- else {
- spin_lock(&mdp_spin_lock);
- dma->busy = FALSE;
- spin_unlock(&mdp_spin_lock);
- complete(&dma->comp);
- }
-#endif
+ if (isr & INTR_PRIMARY_VSYNC) {
+ mdp4_stat.intr_vsync_p++;
+ if (panel & MDP4_PANEL_LCDC)
+ mdp4_primary_vsync_lcdc();
+ else if (panel & MDP4_PANEL_DSI_VIDEO)
+ mdp4_primary_vsync_dsi_video();
}
- if (isr & INTR_DMA_S_DONE) {
- mdp4_stat.intr_dma_s++;
-#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
- dma = &dma2_data;
-#else
- dma = &dma_s_data;
+#ifdef CONFIG_FB_MSM_DTV
+ if (isr & INTR_EXTERNAL_VSYNC) {
+ mdp4_stat.intr_vsync_e++;
+ if (panel & MDP4_PANEL_DTV)
+ mdp4_external_vsync_dtv();
+ }
#endif
-
- dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA_S_BLOCK,
- MDP_BLOCK_POWER_OFF, TRUE);
- complete(&dma->comp);
- }
- if (isr & INTR_DMA_E_DONE) {
- mdp4_stat.intr_dma_e++;
- dma = &dma_e_data;
- spin_lock(&mdp_spin_lock);
- mdp_intr_mask &= ~INTR_DMA_E_DONE;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- dma->busy = FALSE;
- mdp4_dma_e_done_dtv();
- if (dma->waiting) {
- dma->waiting = FALSE;
- complete(&dma->comp);
- }
- spin_unlock(&mdp_spin_lock);
- }
if (isr & INTR_DMA_P_HISTOGRAM) {
mdp4_stat.intr_histogram++;
ret = mdp_histogram_block2mgmt(MDP_BLOCK_DMA_P, &mgmt);
@@ -593,6 +556,10 @@
if (!ret)
mdp_histogram_handle_isr(mgmt);
}
+ if (isr & INTR_PRIMARY_RDPTR) {
+ mdp4_stat.intr_rdptr++;
+ mdp4_primary_rdptr();
+ }
out:
mdp_is_in_isr = FALSE;
@@ -2672,9 +2639,9 @@
DISPLAY_READ_DOMAIN, GEN_POOL);
}
ion_free(mfd->iclient, buf->ihdl);
- pr_debug("%s:%d free writeback imem\n", __func__,
- __LINE__);
buf->ihdl = NULL;
+ pr_info("%s:%d free ION writeback imem",
+ __func__, __LINE__);
}
} else {
if (buf->write_addr) {