aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4507-drm-amd-display-Refactor-HDCP-to-handle-multiple-dis.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4507-drm-amd-display-Refactor-HDCP-to-handle-multiple-dis.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4507-drm-amd-display-Refactor-HDCP-to-handle-multiple-dis.patch178
1 files changed, 178 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4507-drm-amd-display-Refactor-HDCP-to-handle-multiple-dis.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4507-drm-amd-display-Refactor-HDCP-to-handle-multiple-dis.patch
new file mode 100644
index 00000000..d1b0bdbb
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4507-drm-amd-display-Refactor-HDCP-to-handle-multiple-dis.patch
@@ -0,0 +1,178 @@
+From 99a2fd8154613cbb8cc2720f94d56d7c1a75059b Mon Sep 17 00:00:00 2001
+From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Date: Wed, 28 Aug 2019 15:10:03 -0400
+Subject: [PATCH 4507/4736] drm/amd/display: Refactor HDCP to handle multiple
+ displays per link
+
+[Why]
+We need to do this to support HDCP over MST
+
+Currently we save a display per link, in a MST case we need to save
+multiple displays per link.
+
+[How]
+We can create an array per link to cache the displays, but it
+complicates the design. Instead we can use the module to cache the
+displays.
+
+Now we will always add all the displays to the module, but we use the
+adjustment flag to disable hdcp on all of them before they are added.
+
+When we want to enable hdcp we just query the display(cache), remove
+it then add it back with different adjustments. Its the similar for
+disable.
+
+Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ++-----
+ .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 53 ++++++++++---------
+ .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 9 ++--
+ 3 files changed, 40 insertions(+), 42 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 3828a19a87bb..9ca6806f7cef 100755
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -5763,20 +5763,6 @@ static bool is_content_protection_different(struct drm_connector_state *state,
+ 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);
+- bool disable_type1 = state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 ? true : false;
+-
+- if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+- hdcp_reset_display(hdcp_w, aconnector->dc_link->link_index);
+- hdcp_add_display(hdcp_w, aconnector->dc_link->link_index, aconnector, disable_type1);
+- } else 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,
+@@ -6740,7 +6726,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ }
+
+ 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);
++ hdcp_update_display(
++ adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
++ new_con_state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 ? true : false,
++ new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED ? true
++ : false);
+ }
+ #endif
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+index a2ad1390977d..53e382bff54d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+@@ -87,43 +87,45 @@ static void process_output(struct hdcp_workqueue *hdcp_work)
+
+ }
+
+-void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, struct amdgpu_dm_connector *aconnector,
+- bool disable_type1)
++void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
++ unsigned int link_index,
++ struct amdgpu_dm_connector *aconnector,
++ bool disable_type1,
++ bool enable_encryption)
+ {
+ struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+ struct mod_hdcp_display *display = &hdcp_work[link_index].display;
+ struct mod_hdcp_link *link = &hdcp_work[link_index].link;
++ struct mod_hdcp_display_query query;
+
+ mutex_lock(&hdcp_w->mutex);
+ hdcp_w->aconnector = aconnector;
+
+- hdcp_w->link.adjust.hdcp2.disable_type1 = disable_type1;
+-
+- mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
+-
+- schedule_delayed_work(&hdcp_w->property_validate_dwork, msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
+-
+- process_output(hdcp_w);
+-
+- mutex_unlock(&hdcp_w->mutex);
+-
+-}
+-
+-void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, unsigned int display_index)
+-{
+- struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+-
+- mutex_lock(&hdcp_w->mutex);
++ query.display = NULL;
++ mod_hdcp_query_display(&hdcp_w->hdcp, aconnector->base.index, &query);
++
++ if (query.display != NULL) {
++ memcpy(display, query.display, sizeof(struct mod_hdcp_display));
++ mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
++
++ if (enable_encryption) {
++ display->adjust.disable = 0;
++ hdcp_w->link.adjust.hdcp2.disable_type1 = disable_type1;
++ schedule_delayed_work(&hdcp_w->property_validate_dwork,
++ msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
++ } else {
++ display->adjust.disable = 1;
++ hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
++ cancel_delayed_work(&hdcp_w->property_validate_dwork);
++ }
+
+- mod_hdcp_remove_display(&hdcp_w->hdcp, display_index, &hdcp_w->output);
++ display->state = MOD_HDCP_DISPLAY_ACTIVE;
++ }
+
+- cancel_delayed_work(&hdcp_w->property_validate_dwork);
+- hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
++ mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
+
+ process_output(hdcp_w);
+-
+ mutex_unlock(&hdcp_w->mutex);
+-
+ }
+
+ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
+@@ -303,7 +305,10 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
+ link->dig_be = config->link_enc_inst;
+ link->ddc_line = aconnector->dc_link->ddc_hw_inst + 1;
+ link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw;
++ display->adjust.disable = 1;
++ link->adjust.auth_delay = 2;
+
++ hdcp_update_display(hdcp_work, link_index, aconnector, false, false);
+ }
+
+ struct hdcp_workqueue *hdcp_create_workqueue(void *psp_context, struct cp_psp *cp_psp, struct dc *dc)
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
+index 098f7218f83a..71e121f037cb 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
+@@ -54,9 +54,12 @@ struct hdcp_workqueue {
+ uint8_t max_link;
+ };
+
+-void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, struct amdgpu_dm_connector *aconnector,
+- bool disable_type1);
+-void hdcp_remove_display(struct hdcp_workqueue *work, unsigned int link_index, unsigned int display_index);
++void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
++ unsigned int link_index,
++ struct amdgpu_dm_connector *aconnector,
++ bool disable_type1,
++ bool enable_encryption);
++
+ void hdcp_reset_display(struct hdcp_workqueue *work, unsigned int link_index);
+ void hdcp_handle_cpirq(struct hdcp_workqueue *work, unsigned int link_index);
+ void hdcp_destroy(struct hdcp_workqueue *work);
+--
+2.17.1
+