summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
diff options
context:
space:
mode:
authorBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>2019-08-28 22:10:03 +0300
committerAlex Deucher <alexander.deucher@amd.com>2019-11-19 18:12:53 +0300
commitb1abe5586ffcb15cc51668bd1a0f97adfbfb0acd (patch)
treeb791db4ca7602fb166f11e9d0f3a5ebc7bddea9f /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
parent53e108aa9916dbbdebd3d94ce63a6928fda09899 (diff)
downloadlinux-b1abe5586ffcb15cc51668bd1a0f97adfbfb0acd.tar.xz
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> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c53
1 files changed, 29 insertions, 24 deletions
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)