mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm_fb: display: replace msleep with wait4vsync
vsync is controlled by frame work which means vsync irq off may happen at any instance. This patch use a reference count to control vsync irq enable/disable so that wait4vsync can replace msleep safely during suspend. Change-Id: Ief84b1b421436e1f750288eb9a9760a9cb96c555 Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
This commit is contained in:
parent
a2781e468c
commit
56a49ded66
6 changed files with 112 additions and 58 deletions
|
@ -488,7 +488,7 @@ int mdp4_overlay_dtv_set(struct msm_fb_data_type *mfd,
|
|||
int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
|
||||
struct mdp4_overlay_pipe *pipe);
|
||||
void mdp4_dmae_done_dtv(void);
|
||||
void mdp4_dtv_wait4vsync(int cndx, long long *vtime);
|
||||
void mdp4_dtv_wait4vsync(int cndx);
|
||||
void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable);
|
||||
void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
|
||||
#else
|
||||
|
@ -521,7 +521,7 @@ static inline void mdp4_dmae_done_dtv(void)
|
|||
{
|
||||
/* empty */
|
||||
}
|
||||
static inline void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
|
||||
static inline void mdp4_dtv_wait4vsync(int cndx)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ int mdp4_overlay_format2type(uint32 format);
|
|||
int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe);
|
||||
int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req);
|
||||
int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req);
|
||||
int mdp4_overlay_wait4vsync(struct fb_info *info, long long *vtime);
|
||||
int mdp4_overlay_wait4vsync(struct fb_info *info);
|
||||
int mdp4_overlay_vsync_ctrl(struct fb_info *info, int enable);
|
||||
int mdp4_overlay_unset(struct fb_info *info, int ndx);
|
||||
int mdp4_overlay_unset_mixer(int mixer);
|
||||
|
@ -628,7 +628,7 @@ void mdp4_overlay1_done_dtv(void);
|
|||
void mdp4_overlay1_done_atv(void);
|
||||
void mdp4_primary_vsync_lcdc(void);
|
||||
void mdp4_external_vsync_dtv(void);
|
||||
void mdp4_lcdc_wait4vsync(int cndx, long long *vtime);
|
||||
void mdp4_lcdc_wait4vsync(int cndx);
|
||||
void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
|
||||
struct mdp4_overlay_pipe *pipe);
|
||||
void mdp4_mddi_overlay_dmas_restore(void);
|
||||
|
@ -786,8 +786,8 @@ int mdp4_dsi_video_off(struct platform_device *pdev);
|
|||
int mdp4_dsi_video_on(struct platform_device *pdev);
|
||||
void mdp4_primary_vsync_dsi_video(void);
|
||||
void mdp4_dsi_cmd_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
|
||||
void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime);
|
||||
void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime);
|
||||
void mdp4_dsi_cmd_wait4vsync(int cndx);
|
||||
void mdp4_dsi_video_wait4vsync(int cndx);
|
||||
void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
|
||||
void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
|
||||
void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable);
|
||||
|
@ -825,10 +825,10 @@ static inline void mdp4_dsi_cmd_base_swap(int cndx,
|
|||
struct mdp4_overlay_pipe *pipe)
|
||||
{
|
||||
}
|
||||
static inline void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
|
||||
static inline void mdp4_dsi_cmd_wait4vsync(int cndx)
|
||||
{
|
||||
}
|
||||
static inline void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
|
||||
static inline void mdp4_dsi_video_wait4vsync(int cndx)
|
||||
{
|
||||
}
|
||||
static inline void mdp4_dsi_cmd_pipe_queue(int cndx,
|
||||
|
|
|
@ -3224,17 +3224,17 @@ int mdp4_overlay_unset(struct fb_info *info, int ndx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mdp4_overlay_wait4vsync(struct fb_info *info, long long *vtime)
|
||||
int mdp4_overlay_wait4vsync(struct fb_info *info)
|
||||
{
|
||||
if (!hdmi_prim_display && info->node == 0) {
|
||||
if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
|
||||
mdp4_dsi_video_wait4vsync(0, vtime);
|
||||
mdp4_dsi_video_wait4vsync(0);
|
||||
else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
|
||||
mdp4_dsi_cmd_wait4vsync(0, vtime);
|
||||
mdp4_dsi_cmd_wait4vsync(0);
|
||||
else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
|
||||
mdp4_lcdc_wait4vsync(0, vtime);
|
||||
mdp4_lcdc_wait4vsync(0);
|
||||
} else if (hdmi_prim_display || info->node == 1) {
|
||||
mdp4_dtv_wait4vsync(0, vtime);
|
||||
mdp4_dtv_wait4vsync(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -388,11 +388,8 @@ int mdp4_dsi_cmd_pipe_commit(int cndx, int wait)
|
|||
|
||||
mdp4_stat.overlay_commit[pipe->mixer_num]++;
|
||||
|
||||
if (wait) {
|
||||
long long tick;
|
||||
|
||||
mdp4_dsi_cmd_wait4vsync(0, &tick);
|
||||
}
|
||||
if (wait)
|
||||
mdp4_dsi_cmd_wait4vsync(0);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
@ -444,7 +441,7 @@ void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable)
|
|||
mutex_unlock(&vctrl->update_lock);
|
||||
}
|
||||
|
||||
void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
|
||||
void mdp4_dsi_cmd_wait4vsync(int cndx)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
struct mdp4_overlay_pipe *pipe;
|
||||
|
@ -458,10 +455,8 @@ void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
|
|||
vctrl = &vsync_ctrl_db[cndx];
|
||||
pipe = vctrl->base_pipe;
|
||||
|
||||
if (atomic_read(&vctrl->suspend) > 0) {
|
||||
*vtime = -1;
|
||||
if (atomic_read(&vctrl->suspend) > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
if (vctrl->wait_vsync_cnt == 0)
|
||||
|
@ -471,8 +466,6 @@ void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
|
|||
|
||||
wait_for_completion(&vctrl->vsync_comp);
|
||||
mdp4_stat.wait4vsync0++;
|
||||
|
||||
*vtime = ktime_to_ns(vctrl->vsync_time);
|
||||
}
|
||||
|
||||
static void mdp4_dsi_cmd_wait4dmap(int cndx)
|
||||
|
|
|
@ -265,6 +265,31 @@ int mdp4_dsi_video_pipe_commit(int cndx, int wait)
|
|||
return cnt;
|
||||
}
|
||||
|
||||
static void mdp4_video_vsync_irq_ctrl(int cndx, int enable)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
static int vsync_irq_cnt;
|
||||
|
||||
vctrl = &vsync_ctrl_db[cndx];
|
||||
|
||||
mutex_lock(&vctrl->update_lock);
|
||||
if (enable) {
|
||||
if (vsync_irq_cnt == 0)
|
||||
vsync_irq_enable(INTR_PRIMARY_VSYNC,
|
||||
MDP_PRIM_VSYNC_TERM);
|
||||
vsync_irq_cnt++;
|
||||
} else {
|
||||
if (vsync_irq_cnt) {
|
||||
vsync_irq_cnt--;
|
||||
if (vsync_irq_cnt == 0)
|
||||
vsync_irq_disable(INTR_PRIMARY_VSYNC,
|
||||
MDP_PRIM_VSYNC_TERM);
|
||||
}
|
||||
}
|
||||
pr_debug("%s: enable=%d cnt=%d\n", __func__, enable, vsync_irq_cnt);
|
||||
mutex_unlock(&vctrl->update_lock);
|
||||
}
|
||||
|
||||
void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
|
@ -279,16 +304,13 @@ void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable)
|
|||
|
||||
vctrl->vsync_irq_enabled = enable;
|
||||
|
||||
if (enable)
|
||||
vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
|
||||
else
|
||||
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
|
||||
mdp4_video_vsync_irq_ctrl(cndx, enable);
|
||||
|
||||
if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0)
|
||||
atomic_set(&vctrl->vsync_resume, 1);
|
||||
}
|
||||
|
||||
void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
|
||||
void mdp4_dsi_video_wait4vsync(int cndx)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
struct mdp4_overlay_pipe *pipe;
|
||||
|
@ -302,14 +324,14 @@ void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
|
|||
vctrl = &vsync_ctrl_db[cndx];
|
||||
pipe = vctrl->base_pipe;
|
||||
|
||||
if (atomic_read(&vctrl->suspend) > 0) {
|
||||
*vtime = -1;
|
||||
if (atomic_read(&vctrl->suspend) > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* start timing generator & mmu if they are not started yet */
|
||||
mdp4_overlay_dsi_video_start();
|
||||
|
||||
mdp4_video_vsync_irq_ctrl(cndx, 1);
|
||||
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
if (vctrl->wait_vsync_cnt == 0)
|
||||
INIT_COMPLETION(vctrl->vsync_comp);
|
||||
|
@ -318,9 +340,8 @@ void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
|
|||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
wait_for_completion(&vctrl->vsync_comp);
|
||||
mdp4_video_vsync_irq_ctrl(cndx, 0);
|
||||
mdp4_stat.wait4vsync0++;
|
||||
|
||||
*vtime = ktime_to_ns(vctrl->vsync_time);
|
||||
}
|
||||
|
||||
static void mdp4_dsi_video_wait4dmap(int cndx)
|
||||
|
@ -692,7 +713,7 @@ int mdp4_dsi_video_off(struct platform_device *pdev)
|
|||
atomic_set(&vctrl->suspend, 1);
|
||||
atomic_set(&vctrl->vsync_resume, 0);
|
||||
|
||||
msleep(20); /* >= 17 ms */
|
||||
mdp4_dsi_video_wait4vsync(cndx);
|
||||
|
||||
complete_all(&vctrl->vsync_comp);
|
||||
|
||||
|
@ -1058,13 +1079,12 @@ static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable)
|
|||
|
||||
if (vctrl->blt_ctrl == OVERLAY_BLT_SWITCH_TG_OFF) {
|
||||
int tg_enabled;
|
||||
long long vtime;
|
||||
|
||||
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_wait4vsync(0, &vtime);
|
||||
mdp4_dsi_video_wait4vsync(cndx);
|
||||
MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
|
||||
mdp4_dsi_video_wait4dmap_done(0);
|
||||
}
|
||||
|
|
|
@ -246,6 +246,31 @@ int mdp4_dtv_pipe_commit(int cndx, int wait)
|
|||
return cnt;
|
||||
}
|
||||
|
||||
static void mdp4_dtv_vsync_irq_ctrl(int cndx, int enable)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
static int vsync_irq_cnt;
|
||||
|
||||
vctrl = &vsync_ctrl_db[cndx];
|
||||
|
||||
mutex_lock(&vctrl->update_lock);
|
||||
if (enable) {
|
||||
if (vsync_irq_cnt == 0)
|
||||
vsync_irq_enable(INTR_EXTERNAL_VSYNC,
|
||||
MDP_EXTER_VSYNC_TERM);
|
||||
vsync_irq_cnt++;
|
||||
} else {
|
||||
if (vsync_irq_cnt) {
|
||||
vsync_irq_cnt--;
|
||||
if (vsync_irq_cnt == 0)
|
||||
vsync_irq_disable(INTR_EXTERNAL_VSYNC,
|
||||
MDP_EXTER_VSYNC_TERM);
|
||||
}
|
||||
}
|
||||
pr_debug("%s: enable=%d cnt=%d\n", __func__, enable, vsync_irq_cnt);
|
||||
mutex_unlock(&vctrl->update_lock);
|
||||
}
|
||||
|
||||
void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
|
@ -263,16 +288,13 @@ void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable)
|
|||
|
||||
vctrl->vsync_irq_enabled = enable;
|
||||
|
||||
if (enable)
|
||||
vsync_irq_enable(INTR_EXTERNAL_VSYNC, MDP_EXTER_VSYNC_TERM);
|
||||
else
|
||||
vsync_irq_disable(INTR_EXTERNAL_VSYNC, MDP_EXTER_VSYNC_TERM);
|
||||
mdp4_dtv_vsync_irq_ctrl(cndx, enable);
|
||||
|
||||
if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0)
|
||||
atomic_set(&vctrl->vsync_resume, 1);
|
||||
}
|
||||
|
||||
void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
|
||||
void mdp4_dtv_wait4vsync(int cndx)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
struct mdp4_overlay_pipe *pipe;
|
||||
|
@ -289,6 +311,8 @@ void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
|
|||
if (atomic_read(&vctrl->suspend) > 0)
|
||||
return;
|
||||
|
||||
mdp4_dtv_vsync_irq_ctrl(cndx, 1);
|
||||
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
|
||||
if (vctrl->wait_vsync_cnt == 0)
|
||||
|
@ -297,9 +321,8 @@ void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
|
|||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
wait_for_completion(&vctrl->vsync_comp);
|
||||
mdp4_dtv_vsync_irq_ctrl(cndx, 0);
|
||||
mdp4_stat.wait4vsync1++;
|
||||
|
||||
*vtime = ktime_to_ns(vctrl->vsync_time);
|
||||
}
|
||||
|
||||
static void mdp4_dtv_wait4dmae(int cndx)
|
||||
|
@ -608,10 +631,7 @@ int mdp4_dtv_off(struct platform_device *pdev)
|
|||
atomic_set(&vctrl->suspend, 1);
|
||||
atomic_set(&vctrl->vsync_resume, 0);
|
||||
|
||||
if (vctrl->vsync_irq_enabled) {
|
||||
while (vctrl->wait_vsync_cnt)
|
||||
msleep(20); /* >= 17 ms */
|
||||
}
|
||||
mdp4_dtv_wait4vsync(cndx);
|
||||
|
||||
complete_all(&vctrl->vsync_comp);
|
||||
|
||||
|
|
|
@ -270,6 +270,31 @@ int mdp4_lcdc_pipe_commit(int cndx, int wait)
|
|||
return cnt;
|
||||
}
|
||||
|
||||
static void mdp4_lcdc_vsync_irq_ctrl(int cndx, int enable)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
static int vsync_irq_cnt;
|
||||
|
||||
vctrl = &vsync_ctrl_db[cndx];
|
||||
|
||||
mutex_lock(&vctrl->update_lock);
|
||||
if (enable) {
|
||||
if (vsync_irq_cnt == 0)
|
||||
vsync_irq_enable(INTR_PRIMARY_VSYNC,
|
||||
MDP_PRIM_VSYNC_TERM);
|
||||
vsync_irq_cnt++;
|
||||
} else {
|
||||
if (vsync_irq_cnt) {
|
||||
vsync_irq_cnt--;
|
||||
if (vsync_irq_cnt == 0)
|
||||
vsync_irq_disable(INTR_PRIMARY_VSYNC,
|
||||
MDP_PRIM_VSYNC_TERM);
|
||||
}
|
||||
}
|
||||
pr_debug("%s: enable=%d cnt=%d\n", __func__, enable, vsync_irq_cnt);
|
||||
mutex_unlock(&vctrl->update_lock);
|
||||
}
|
||||
|
||||
void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
|
@ -284,16 +309,13 @@ void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable)
|
|||
|
||||
vctrl->vsync_irq_enabled = enable;
|
||||
|
||||
if (enable)
|
||||
vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
|
||||
else
|
||||
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
|
||||
mdp4_lcdc_vsync_irq_ctrl(cndx, enable);
|
||||
|
||||
if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0)
|
||||
atomic_set(&vctrl->vsync_resume, 1);
|
||||
}
|
||||
|
||||
void mdp4_lcdc_wait4vsync(int cndx, long long *vtime)
|
||||
void mdp4_lcdc_wait4vsync(int cndx)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
struct mdp4_overlay_pipe *pipe;
|
||||
|
@ -307,14 +329,14 @@ void mdp4_lcdc_wait4vsync(int cndx, long long *vtime)
|
|||
vctrl = &vsync_ctrl_db[cndx];
|
||||
pipe = vctrl->base_pipe;
|
||||
|
||||
if (atomic_read(&vctrl->suspend) > 0) {
|
||||
*vtime = -1;
|
||||
if (atomic_read(&vctrl->suspend) > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* start timing generator & mmu if they are not started yet */
|
||||
mdp4_overlay_lcdc_start();
|
||||
|
||||
mdp4_lcdc_vsync_irq_ctrl(cndx, 1);
|
||||
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
|
||||
if (vctrl->wait_vsync_cnt == 0)
|
||||
|
@ -323,9 +345,8 @@ void mdp4_lcdc_wait4vsync(int cndx, long long *vtime)
|
|||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
wait_for_completion(&vctrl->vsync_comp);
|
||||
mdp4_lcdc_vsync_irq_ctrl(cndx, 0);
|
||||
mdp4_stat.wait4vsync0++;
|
||||
|
||||
*vtime = vctrl->vsync_time.tv64;
|
||||
}
|
||||
|
||||
static void mdp4_lcdc_wait4dmap(int cndx)
|
||||
|
|
Loading…
Reference in a new issue