aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
diff options
context:
space:
mode:
authorWayne Lin <Wayne.Lin@amd.com>2021-03-02 11:52:20 +0800
committerAlex Deucher <alexander.deucher@amd.com>2021-03-05 15:11:47 -0500
commit86bc221918925a0bbb49043e3936e898e009b43b (patch)
tree3d3c7dcd66ed4446c37d319bd2c2ce96a6a57e76 /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
parent8e7b6fee9b03d683a5c2dff0689dc27a681562e9 (diff)
drm/amd/display: Support crc on specific region
[Why] To support feature that calculates CRTC CRC value on specific region (crc window). [How] 1. Use debugfs to specify crtc crc window 2. Use vline0 IRQ to write crtc crc window Signed-off-by: Wayne Lin <Wayne.Lin@amd.com> Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Acked-by: Eryk Brol <eryk.brol@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c93
1 files changed, 87 insertions, 6 deletions
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 15a512191cef..385aa233af4b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -581,6 +581,31 @@ static void dm_crtc_high_irq(void *interrupt_params)
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
}
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+/**
+ * dm_dcn_vertical_interrupt0_high_irq() - Handles OTG Vertical interrupt0 for
+ * DCN generation ASICs
+ * @interrupt params - interrupt parameters
+ *
+ * Used to set crc window/read out crc value at vertical line 0 position
+ */
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+static void dm_dcn_vertical_interrupt0_high_irq(void *interrupt_params)
+{
+ struct common_irq_params *irq_params = interrupt_params;
+ struct amdgpu_device *adev = irq_params->adev;
+ struct amdgpu_crtc *acrtc;
+
+ acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VLINE0);
+
+ if (!acrtc)
+ return;
+
+ amdgpu_dm_crtc_handle_crc_window_irq(&acrtc->base);
+}
+#endif
+#endif
+
static int dm_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
@@ -2957,6 +2982,34 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
adev, &int_params, dm_crtc_high_irq, c_irq_params);
}
+ /* Use otg vertical line interrupt */
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ for (i = DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL;
+ i <= DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL
+ + adev->mode_info.num_crtc - 1;
+ i++) {
+ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->vline0_irq);
+
+ if (r) {
+ DRM_ERROR("Failed to add vline0 irq id!\n");
+ return r;
+ }
+
+ int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
+ int_params.irq_source =
+ dc_interrupt_to_irq_source(dc, i, 0);
+
+ c_irq_params = &adev->dm.vline0_params[int_params.irq_source
+ - DC_IRQ_SOURCE_DC1_VLINE0];
+
+ c_irq_params->adev = adev;
+ c_irq_params->irq_src = int_params.irq_source;
+
+ amdgpu_dm_irq_register_interrupt(adev, &int_params,
+ dm_dcn_vertical_interrupt0_high_irq, c_irq_params);
+ }
+#endif
+
/* Use VUPDATE_NO_LOCK interrupt on DCN, which seems to correspond to
* the regular VUPDATE interrupt on DCE. We want DC_IRQ_SOURCE_VUPDATEx
* to trigger at end of each vblank, regardless of state of the lock,
@@ -5512,12 +5565,20 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
state->freesync_config = cur->freesync_config;
state->cm_has_degamma = cur->cm_has_degamma;
state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb;
-
/* TODO Duplicate dc_stream after objects are stream object is flattened */
return &state->base;
}
+#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
+int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
+{
+ crtc_debugfs_init(crtc);
+
+ return 0;
+}
+#endif
+
static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
{
enum dc_irq_source irq_source;
@@ -5603,6 +5664,9 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
.enable_vblank = dm_enable_vblank,
.disable_vblank = dm_disable_vblank,
.get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ .late_register = amdgpu_dm_crtc_late_register,
+#endif
};
static enum drm_connector_status
@@ -7502,8 +7566,19 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
adev,
&adev->pageflip_irq,
irq_type);
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ amdgpu_irq_get(
+ adev,
+ &adev->vline0_irq,
+ irq_type);
+#endif
} else {
-
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ amdgpu_irq_put(
+ adev,
+ &adev->vline0_irq,
+ irq_type);
+#endif
amdgpu_irq_put(
adev,
&adev->pageflip_irq,
@@ -8650,9 +8725,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
#ifdef CONFIG_DEBUG_FS
+ bool configure_crc = false;
enum amdgpu_dm_pipe_crc_source cur_crc_src;
#endif
-
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
if (new_crtc_state->active &&
@@ -8673,10 +8748,16 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
if (amdgpu_dm_is_valid_crc_source(cur_crc_src)) {
- amdgpu_dm_crtc_configure_crc_source(
- crtc, dm_new_crtc_state,
- cur_crc_src);
+ configure_crc = true;
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ if (amdgpu_dm_crc_window_is_activated(crtc))
+ configure_crc = false;
+#endif
}
+
+ if (configure_crc)
+ amdgpu_dm_crtc_configure_crc_source(
+ crtc, dm_new_crtc_state, cur_crc_src);
#endif
}
}