Check if there is a new ROI update during the atomic commit and process
it. A new function amdgpu_dm_crtc_set_secure_display_crc_source() is
implemented to control the state of CRC engine in hardware.

Signed-off-by: Alan Liu <haoping....@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 38 +++++++++++++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 57 +++++++++++++++++++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h |  3 +
 3 files changed, 98 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 14b296e1d0f6..ee016d5be7ac 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8857,6 +8857,44 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
                        }
                }
 #endif
+
+#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
+               if (new_crtc_state->active && 
dm_new_crtc_state->secure_display_state.roi_changed) {
+                       struct drm_roi *roi_data =
+                               (struct drm_roi 
*)dm_new_crtc_state->secure_display_state.roi_blob->data;
+
+                       if (roi_data->secure_display_enable) {
+                               if (!amdgpu_dm_crc_window_is_activated(crtc)) {
+                                       /* Enable secure display: set crc 
source to "crtc" */
+                                       
amdgpu_dm_crtc_set_secure_display_crc_source(crtc, "crtc");
+
+                                       /* wait 1 more frame for CRC engine to 
start */
+                                       
acrtc->dm_irq_params.window_param.skip_frame_cnt = 1;
+
+                                       
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
+                                       
acrtc->dm_irq_params.window_param.activated = true;
+                                       
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
+                               }
+
+                               /* Update ROI: copy ROI from dm_crtc_state to 
dm_irq_params */
+                               
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
+                               acrtc->dm_irq_params.window_param.x_start = 
roi_data->x_start;
+                               acrtc->dm_irq_params.window_param.y_start = 
roi_data->y_start;
+                               acrtc->dm_irq_params.window_param.x_end = 
roi_data->x_end;
+                               acrtc->dm_irq_params.window_param.y_end = 
roi_data->y_end;
+                               acrtc->dm_irq_params.window_param.update_win = 
true;
+                               
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
+
+                       } else {
+                               if (amdgpu_dm_crc_window_is_activated(crtc)) {
+                                       /* Disable secure display: set crc 
source to "none" */
+                                       
amdgpu_dm_crtc_set_secure_display_crc_source(crtc, "none");
+                               }
+                       }
+
+                       dm_new_crtc_state->secure_display_state.roi_changed = 
false;
+               }
+#endif
        }
 
        for_each_new_crtc_in_state(state, crtc, new_crtc_state, j)
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 a83cabb9b1a6..81e9995183ad 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
@@ -465,6 +465,63 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
 }
 
 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+int amdgpu_dm_crtc_set_secure_display_crc_source(struct drm_crtc *crtc, const 
char *src_name)
+{
+       enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
+       enum amdgpu_dm_pipe_crc_source cur_crc_src;
+       struct dm_crtc_state *crtc_state;
+       struct drm_device *drm_dev = crtc->dev;
+       struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+       bool enable = false;
+       bool enabled = false;
+       int ret = 0;
+       unsigned long flag;
+
+       if (source < 0) {
+               DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n",
+                                src_name, crtc->index);
+               return -EINVAL;
+       }
+
+       enable = amdgpu_dm_is_valid_crc_source(source);
+       crtc_state = to_dm_crtc_state(crtc->state);
+       spin_lock_irqsave(&drm_dev->event_lock, flag);
+       cur_crc_src = acrtc->dm_irq_params.crc_src;
+       spin_unlock_irqrestore(&drm_dev->event_lock, flag);
+
+       /* Reset secure_display when we change crc source */
+       amdgpu_dm_set_crc_window_default(crtc, crtc_state->stream);
+
+       if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source)) {
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       /*
+        * Reading the CRC requires the vblank interrupt handler to be
+        * enabled. Keep a reference until CRC capture stops.
+        */
+       enabled = amdgpu_dm_is_valid_crc_source(cur_crc_src);
+       if (!enabled && enable) {
+               ret = drm_crtc_vblank_get(crtc);
+               if (ret)
+                       goto cleanup;
+
+       } else if (enabled && !enable) {
+               drm_crtc_vblank_put(crtc);
+       }
+
+       spin_lock_irqsave(&drm_dev->event_lock, flag);
+       acrtc->dm_irq_params.crc_src = source;
+       spin_unlock_irqrestore(&drm_dev->event_lock, flag);
+
+       /* Reset crc_skipped on dm state */
+       crtc_state->crc_skip_count = 0;
+
+cleanup:
+       return ret;
+}
+
 void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
 {
        struct drm_device *drm_dev = NULL;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
index f2def8c20d83..1b85d60488b6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
@@ -110,12 +110,15 @@ struct secure_display_context 
*amdgpu_dm_crtc_secure_display_create_contexts(
 int amdgpu_dm_crtc_create_secure_display_properties(struct amdgpu_device 
*adev);
 void amdgpu_dm_crtc_attach_secure_display_properties(struct amdgpu_device 
*adev,
                                                struct drm_crtc *crtc);
+int amdgpu_dm_crtc_set_secure_display_crc_source(struct drm_crtc *crtc,
+                                               const char *src_name);
 #else
 #define amdgpu_dm_crc_window_is_activated(x)
 #define amdgpu_dm_crtc_handle_crc_window_irq(x)
 #define amdgpu_dm_crtc_secure_display_create_contexts(x)
 #define amdgpu_dm_crtc_create_secure_display_properties(x)
 #define amdgpu_dm_crtc_attach_secure_display_properties(x)
+#define amdgpu_dm_crtc_set_secure_display_crc_source(x)
 #endif
 
 #endif /* AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_ */
-- 
2.34.1

Reply via email to