msm_fb: display: add options to switch blt mode for dsi video

Currently switching mdp blt mode is done in dmap done isr which could
cause mdp hang for some panels/targets. One option is added: turning
off timing generator when switching blt mode, to avoid hang issues.

Signed-off-by: Huaibin Yang <huaibiny@codeaurora.org>
This commit is contained in:
Naseer Ahmed
2012-10-15 13:07:49 -04:00
committed by Iliyan Malchev
parent ca82d7b7cd
commit ffde53dc8f
3 changed files with 46 additions and 5 deletions

View File

@@ -93,6 +93,12 @@ enum {
#define MDP4_PANEL_DSI_CMD BIT(5)
#define MDP4_PANEL_WRITEBACK BIT(6)
enum {
OVERLAY_BLT_SWITCH_TG_ON,
OVERLAY_BLT_SWITCH_TG_OFF,
OVERLAY_BLT_ALWAYS_ON
};
enum {
OVERLAY_MODE_NONE,
OVERLAY_MODE_BLT

View File

@@ -56,6 +56,7 @@ static struct vsycn_ctrl {
int wait_vsync_cnt;
int blt_change;
int blt_free;
int blt_ctrl;
int sysfs_created;
struct mutex update_lock;
struct completion ov_comp;
@@ -194,8 +195,6 @@ int mdp4_dsi_video_pipe_commit(int cndx, int wait)
}
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1);
if (vctrl->blt_change) {
pipe = vctrl->base_pipe;
spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -496,9 +495,11 @@ int mdp4_dsi_video_on(struct platform_device *pdev)
int ret = 0;
int cndx = 0;
struct vsycn_ctrl *vctrl;
struct msm_panel_info *pinfo;
vctrl = &vsync_ctrl_db[cndx];
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
pinfo = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -508,6 +509,7 @@ int mdp4_dsi_video_on(struct platform_device *pdev)
vctrl->mfd = mfd;
vctrl->dev = mfd->fbi->dev;
vctrl->blt_ctrl = pinfo->lcd.blt_ctrl;
/* mdp clock on */
mdp_clk_ctrl(1);
@@ -1053,8 +1055,41 @@ static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable)
spin_unlock_irqrestore(&vctrl->spin_lock, flag);
return;
}
spin_unlock_irqrestore(&vctrl->spin_lock, flag);
if (vctrl->blt_ctrl == OVERLAY_BLT_SWITCH_TG_OFF) {
int tg_enabled;
pr_info("%s: blt enabled by switching TG off\n", __func__);
vctrl->blt_change = 0;
tg_enabled = inpdw(MDP_BASE + DSI_VIDEO_BASE) & 0x01;
if (tg_enabled) {
mdp4_dsi_video_wait4dmap_done(0);
MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
msleep(20);
mipi_dsi_controller_cfg(0);
}
mdp4_overlayproc_cfg(pipe);
mdp4_overlay_dmap_xy(pipe);
if (tg_enabled) {
if (pipe->ov_blt_addr) {
/* preefill on frame */
spin_lock_irqsave(&vctrl->spin_lock, flag);
pipe->ov_cnt++;
vctrl->ov_koff++;
mdp4_stat.kickoff_ov0++;
INIT_COMPLETION(vctrl->ov_comp);
vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
outpdw(MDP_BASE + 0x0004, 0);
spin_unlock_irqrestore(&vctrl->spin_lock, flag);
mdp4_dsi_video_wait4ov(cndx);
}
mipi_dsi_sw_reset();
mipi_dsi_controller_cfg(1);
MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1);
}
}
}
void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
@@ -1108,7 +1143,6 @@ void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd)
mutex_lock(&mfd->dma->ov_mutex);
mdp4_dsi_video_pipe_commit(0, 0);
mutex_unlock(&mfd->dma->ov_mutex);
if (pipe->ov_blt_addr)
mdp4_dsi_video_wait4ov(0);
@@ -1116,5 +1150,5 @@ void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd)
mdp4_dsi_video_wait4dmap(0);
mdp4_overlay_mdp_perf_upd(mfd, 0);
mutex_unlock(&mfd->dma->ov_mutex);
}

View File

@@ -65,6 +65,7 @@ struct lcd_panel_info {
__u32 v_pulse_width;
__u32 hw_vsync_mode;
__u32 vsync_notifier_period;
__u32 blt_ctrl;
__u32 rev;
};