From 868fb9cb24b70e2dbb4f7395bed2aeccf41b5206 Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Fri, 13 Dec 2019 08:15:03 -0500 Subject: [PATCH] disp: msm: sde: fix frame event signal for cwb Submit a cwb frame event signal to notify the crtc that cwb is completed. Currently cwb also uses the same frame done event as primary. When a single cwb commit is completed, because cwb is on a slower path there is a race condition in which the subsequent frame done event for primary clears the refcount. This fix isolates the events and removes this situation. Change-Id: Ic3e18302eb8a497cbd7a00f271de2ab320576c83 Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_crtc.c | 3 ++- msm/sde/sde_encoder.h | 1 + msm/sde/sde_encoder_phys_wb.c | 8 ++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 85145cae209a..0cfbebbc3ef2 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2337,7 +2337,8 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) SDE_EVT32_VERBOSE(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_ENTRY); - in_clone_mode = sde_encoder_in_clone_mode(fevent->connector->encoder); + in_clone_mode = (fevent->event & SDE_ENCODER_FRAME_EVENT_CWB_DONE) ? + true : false; if (!in_clone_mode && (fevent->event & (SDE_ENCODER_FRAME_EVENT_ERROR | SDE_ENCODER_FRAME_EVENT_PANEL_DEAD diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 80f51fb2de3a..7517162015f5 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -45,6 +45,7 @@ #define SDE_ENCODER_FRAME_EVENT_PANEL_DEAD BIT(2) #define SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE BIT(3) #define SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE BIT(4) +#define SDE_ENCODER_FRAME_EVENT_CWB_DONE BIT(5) #define IDLE_POWERCOLLAPSE_DURATION (66 - 16/2) #define IDLE_POWERCOLLAPSE_IN_EARLY_WAKEUP (200 - 16/2) diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index eb5581f39a2b..1c11bdbf7a77 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -1032,7 +1032,9 @@ static void _sde_encoder_phys_wb_frame_done_helper(void *arg, bool frame_error) event |= SDE_ENCODER_FRAME_EVENT_DONE | SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE; - if (!phys_enc->in_clone_mode) + if (phys_enc->in_clone_mode) + event |= SDE_ENCODER_FRAME_EVENT_CWB_DONE; + else event |= SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE; phys_enc->parent_ops.handle_frame_done(phys_enc->parent, @@ -1187,7 +1189,9 @@ static int sde_encoder_phys_wb_frame_timeout(struct sde_encoder_phys *phys_enc) event = SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE | SDE_ENCODER_FRAME_EVENT_ERROR; - if (!phys_enc->in_clone_mode) + if (phys_enc->in_clone_mode) + event |= SDE_ENCODER_FRAME_EVENT_CWB_DONE; + else event |= SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE; phys_enc->parent_ops.handle_frame_done(