Pārlūkot izejas kodu

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 <[email protected]>
Nilaan Gunabalachandran 5 gadi atpakaļ
vecāks
revīzija
868fb9cb24
3 mainītis faili ar 9 papildinājumiem un 3 dzēšanām
  1. 2 1
      msm/sde/sde_crtc.c
  2. 1 0
      msm/sde/sde_encoder.h
  3. 6 2
      msm/sde/sde_encoder_phys_wb.c

+ 2 - 1
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

+ 1 - 0
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)

+ 6 - 2
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(