Forráskód Böngészése

disp: msm: sde: sw fence error handling

Sw fence error handling addresses following:
a. out of order handling
  - For cmd panel, signal the release fence and retire fence once
    sw fence error detected.
  - For vid panel, signal the fence error frame release fence and
    retire fence once sw fence error detected, hold the release
    fence of last good frame till next good frame.
b. avoid BW decrease vote
c. lut dma reset
d. cancel kickoff

Change-Id: Ic496c532a26d80e0ef0074624ef6ace01c4ab2f0
Signed-off-by: GG Hou <[email protected]>
GG Hou 2 éve
szülő
commit
54209fb4d0
2 módosított fájl, 53 hozzáadás és 0 törlés
  1. 44 0
      msm/sde/sde_crtc.c
  2. 9 0
      msm/sde/sde_encoder.c

+ 44 - 0
msm/sde/sde_crtc.c

@@ -3855,6 +3855,48 @@ exit:
 	return input_hw_fence;
 }
 
+/**
+ * sde_crtc_sw_fence_error_handle - sw fence error handing
+ * @crtc: Pointer to CRTC object.
+ * @err_status: true if sw input fence error
+ *
+ * return 0 if success non-zero otherwise
+ */
+int sde_crtc_sw_fence_error_handle(struct drm_crtc *crtc, int err_status)
+{
+	struct sde_crtc *sde_crtc = NULL;
+	struct drm_encoder *drm_encoder;
+	bool handle_sw_fence_error_flag;
+	int rc = 0;
+
+	if (!crtc) {
+		SDE_ERROR("invalid crtc\n");
+		return -EINVAL;
+	}
+
+	handle_sw_fence_error_flag = sde_crtc_get_property(
+		to_sde_crtc_state(crtc->state), CRTC_PROP_HANDLE_FENCE_ERROR);
+
+	if (!handle_sw_fence_error_flag || (err_status >= 0))
+		return 0;
+
+	SDE_EVT32(handle_sw_fence_error_flag, err_status);
+
+	sde_crtc = to_sde_crtc(crtc);
+	sde_crtc->input_fence_status = err_status;
+	sde_crtc->handle_fence_error_bw_update = true;
+
+	drm_for_each_encoder_mask(drm_encoder, crtc->dev, crtc->state->encoder_mask) {
+		rc = sde_encoder_handle_dma_fence_out_of_order(drm_encoder);
+		if (rc) {
+			SDE_DEBUG("Dma fence out of order failed, rc = %d\n", rc);
+			SDE_EVT32(rc, SDE_EVTLOG_ERROR);
+		}
+	}
+
+	return rc;
+}
+
 /**
  * _sde_crtc_fences_wait_list - wait for input sw-fences and return any hw-fences
  * @crtc: Pointer to CRTC object.
@@ -3937,6 +3979,8 @@ static int _sde_crtc_fences_wait_list(struct drm_crtc *crtc, bool use_hw_fences,
 		} while (wait_ms && rc == -ERESTARTSYS);
 	}
 
+	sde_crtc_sw_fence_error_handle(crtc, status);
+
 	return num_hw_fences;
 }
 

+ 9 - 0
msm/sde/sde_encoder.c

@@ -4399,6 +4399,14 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc,
 	}
 
 	sde_crtc = to_sde_crtc(sde_enc->crtc);
+
+	/* reset input fence status and skip flush for fence error case. */
+	if (sde_crtc->input_fence_status < 0) {
+		SDE_EVT32(DRMID(&sde_enc->base), sde_crtc->input_fence_status);
+		sde_crtc->input_fence_status = 0;
+		goto handle_elevated_ahb_vote;
+	}
+
 	if (sde_encoder_check_curr_mode(&sde_enc->base, MSM_DISPLAY_VIDEO_MODE))
 		is_vid_mode = true;
 
@@ -4476,6 +4484,7 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc,
 
 	_sde_encoder_trigger_start(sde_enc->cur_master);
 
+handle_elevated_ahb_vote:
 	if (sde_enc->elevated_ahb_vote) {
 		sde_kms = sde_encoder_get_kms(&sde_enc->base);
 		priv = sde_enc->base.dev->dev_private;