[PATCH 6/7] drm/amd/display: Implement the retrieval of secure display CRC data

Alan Liu HaoPing.Liu at amd.com
Tue May 16 05:39:30 UTC 2023


Retrieve secure display's CRC data from the DC hardware in vline0 irq
handler, and store the values in secure display contexts.

Signed-off-by: Alan Liu <HaoPing.Liu at amd.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 50 ++++++++++++++++---
 1 file changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 81e9995183ad..f0ccf29af4f8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -529,6 +529,8 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
 	struct amdgpu_crtc *acrtc = NULL;
 	struct amdgpu_device *adev = NULL;
 	struct secure_display_context *secure_display_ctx = NULL;
+	bool reset_crc_frame_count = false, crc_is_updated = false;
+	uint32_t crc[3] = {0};
 	unsigned long flags1;
 
 	if (crtc == NULL)
@@ -543,15 +545,14 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
 
 	/* Early return if CRC capture is not enabled. */
 	if (!amdgpu_dm_is_valid_crc_source(cur_crc_src) ||
-		!dm_is_crc_source_crtc(cur_crc_src))
-		goto cleanup;
-
-	if (!acrtc->dm_irq_params.window_param.activated)
-		goto cleanup;
+	    !dm_is_crc_source_crtc(cur_crc_src)) {
+		spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
+		return;
+	}
 
-	if (acrtc->dm_irq_params.window_param.skip_frame_cnt) {
-		acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1;
-		goto cleanup;
+	if (!acrtc->dm_irq_params.window_param.activated) {
+		spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
+		return;
 	}
 
 	secure_display_ctx = &adev->dm.secure_display_ctxs[acrtc->crtc_id];
@@ -562,6 +563,11 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
 		secure_display_ctx->crtc = crtc;
 	}
 
+	if (acrtc->dm_irq_params.window_param.skip_frame_cnt) {
+		acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1;
+		goto cleanup;
+	}
+
 	if (acrtc->dm_irq_params.window_param.update_win) {
 		/* prepare work for dmub to update ROI */
 		secure_display_ctx->rect.x = acrtc->dm_irq_params.window_param.x_start;
@@ -572,6 +578,8 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
 								acrtc->dm_irq_params.window_param.y_start;
 		schedule_work(&secure_display_ctx->forward_roi_work);
 
+		reset_crc_frame_count = true;
+
 		acrtc->dm_irq_params.window_param.update_win = false;
 
 		/* Statically skip 1 frame, because we may need to wait below things
@@ -582,12 +590,38 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
 		acrtc->dm_irq_params.window_param.skip_frame_cnt = 1;
 
 	} else {
+		struct dc_stream_state *stream_state = to_dm_crtc_state(crtc->state)->stream;
+
+		if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
+					&crc[0], &crc[1], &crc[2]))
+			DRM_ERROR("Secure Display: fail to get crc\n");
+		else
+			crc_is_updated = true;
+
 		/* prepare work for psp to read ROI/CRC and send to I2C */
 		schedule_work(&secure_display_ctx->notify_ta_work);
 	}
 
 cleanup:
 	spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
+
+	spin_lock_irqsave(&secure_display_ctx->crc.lock, flags1);
+
+	if (reset_crc_frame_count || secure_display_ctx->crc.frame_count == UINT_MAX)
+		/* Reset the reference frame count after user update the ROI
+		 * or it reaches the maximum value.
+		 */
+		secure_display_ctx->crc.frame_count = 0;
+	else
+		secure_display_ctx->crc.frame_count += 1;
+
+	if (crc_is_updated) {
+		secure_display_ctx->crc.crc_R = crc[0];
+		secure_display_ctx->crc.crc_G = crc[1];
+		secure_display_ctx->crc.crc_B = crc[2];
+	}
+
+	spin_unlock_irqrestore(&secure_display_ctx->crc.lock, flags1);
 }
 
 struct secure_display_context *
-- 
2.34.1



More information about the dri-devel mailing list