aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3866-drm-amd-display-Handle-Content-protection-property-c.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3866-drm-amd-display-Handle-Content-protection-property-c.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3866-drm-amd-display-Handle-Content-protection-property-c.patch185
1 files changed, 185 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3866-drm-amd-display-Handle-Content-protection-property-c.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3866-drm-amd-display-Handle-Content-protection-property-c.patch
new file mode 100644
index 00000000..213393fc
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3866-drm-amd-display-Handle-Content-protection-property-c.patch
@@ -0,0 +1,185 @@
+From b0606e6d078d670cfca992383f5b886cf64d69a2 Mon Sep 17 00:00:00 2001
+From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Date: Mon, 16 Sep 2019 15:52:58 -0500
+Subject: [PATCH 3866/4256] drm/amd/display: Handle Content protection property
+ changes
+
+[Why]
+We need to manage the content protection property changes for
+different usecase, once cp is DESIRED we need to maintain the
+ENABLED/DESIRED status for different cases.
+
+[How]
+1. Attach the content_protection property
+
+2. HDCP enable (UNDESIRED -> DESIRED)
+ call into the module with the correct parameters to start
+ hdcp. Set cp to ENABLED
+
+3. HDCP disable (ENABLED -> UNDESIRED)
+ Call the module to disable hdcp.
+
+3. Handle Special cases (Hotplug, S3, headless S3, DPMS)
+ If already ENABLED: set to DESIRED on unplug/suspend/dpms,
+ and disable hdcp
+
+ Then on plugin/resume/dpms: enable HDCP
+
+Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++++++++++++++++++
+ 1 file changed, 96 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 f04b5798ce2c..af7f326c56bd 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -78,6 +78,7 @@
+
+ #include "soc15_common.h"
+ #endif
++#include <drm/drm_hdcp.h>
+
+ #include "modules/inc/mod_freesync.h"
+ #include "modules/power/power_helpers.h"
+@@ -1459,6 +1460,11 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
+ dc_sink_release(aconnector->dc_sink);
+ aconnector->dc_sink = NULL;
+ aconnector->edid = NULL;
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++ /* Set CP to DESIRED if it was ENABLED, so we can re-enable it again on hotplug */
++ if (connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
++ connector->state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++#endif
+ }
+
+ mutex_unlock(&dev->mode_config.mutex);
+@@ -1473,12 +1479,18 @@ static void handle_hpd_irq(void *param)
+ struct drm_connector *connector = &aconnector->base;
+ struct drm_device *dev = connector->dev;
+ enum dc_connection_type new_connection_type = dc_connection_none;
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++ struct amdgpu_device *adev = dev->dev_private;
++#endif
+
+ /* In case of failure or MST no need to update connector status or notify the OS
+ * since (for MST case) MST does this in it's own context.
+ */
+ mutex_lock(&aconnector->hpd_lock);
+
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++ hdcp_reset_display(adev->dm.hdcp_workqueue, aconnector->dc_link->link_index);
++#endif
+ if (aconnector->fake_enable)
+ aconnector->fake_enable = false;
+
+@@ -5086,6 +5098,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
+ adev->mode_info.freesync_property, 0);
+ drm_object_attach_property(&aconnector->base.base,
+ adev->mode_info.freesync_capable_property, 0);
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++ drm_connector_attach_content_protection_property(&aconnector->base, false);
++#endif
+ }
+ }
+
+@@ -5328,6 +5343,63 @@ is_scaling_state_different(const struct dm_connector_state *dm_state,
+ return false;
+ }
+
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++static bool is_content_protection_different(struct drm_connector_state *state,
++ const struct drm_connector_state *old_state,
++ const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w)
++{
++ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
++
++ /* CP is being re enabled, ignore this */
++ if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
++ state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
++ state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
++ return false;
++ }
++
++ /* S3 resume case, since old state will always be 0 (UNDESIRED) and the restored state will be ENABLED */
++ if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
++ state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
++ state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++
++ /* Check if something is connected/enabled, otherwise we start hdcp but nothing is connected/enabled
++ * hot-plug, headless s3, dpms
++ */
++ if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && connector->dpms == DRM_MODE_DPMS_ON &&
++ aconnector->dc_sink != NULL)
++ return true;
++
++ if (old_state->content_protection == state->content_protection)
++ return false;
++
++ if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
++ return true;
++
++ return false;
++}
++
++static void update_content_protection(struct drm_connector_state *state, const struct drm_connector *connector,
++ struct hdcp_workqueue *hdcp_w)
++{
++ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
++
++ if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
++ hdcp_add_display(hdcp_w, aconnector->dc_link->link_index);
++
++ /*
++ * TODO: ENABLED should be verified using psp, it is planned later.
++ * Just set this to ENABLED for now
++ */
++ state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
++
++ return;
++ }
++
++ if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
++ hdcp_remove_display(hdcp_w, aconnector->dc_link->link_index, aconnector->base.index);
++
++}
++#endif
+ static void remove_stream(struct amdgpu_device *adev,
+ struct amdgpu_crtc *acrtc,
+ struct dc_stream_state *stream)
+@@ -6247,6 +6319,30 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ acrtc->otg_inst = status->primary_otg_inst;
+ }
+ }
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
++ struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
++ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
++ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
++
++ new_crtc_state = NULL;
++
++ if (acrtc)
++ new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
++
++ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
++
++ if (dm_new_crtc_state && dm_new_crtc_state->stream == NULL &&
++ connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
++ hdcp_reset_display(adev->dm.hdcp_workqueue, aconnector->dc_link->link_index);
++ new_con_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++ continue;
++ }
++
++ if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue))
++ update_content_protection(new_con_state, connector, adev->dm.hdcp_workqueue);
++ }
++#endif
+
+ /* Handle connector state changes */
+ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
+--
+2.17.1
+