[Why]
HDCP 2.2 uses type0 and type1 content type. This is passed to the receiver
to stream the proper content.

For example, in a MST case if the main
device is HDCP2.2 capable but the secondary device is only 1.4 capabale
we can use Type0

Type0 content: use HDCP 1.4 or HDCP2.2 type0
Type1 content: Only use HDCP 2.2 type1

[How]
We use the "hdcp content type" property in drm. We use the
disable_type1 flag in hdcp module to select the type based on the
properties.

For updating the property we use the same logic as 1.4, but now we
consider content_type as well and update the property if the
requirements are met

Signed-off-by: Bhawanpreet Lakha <bhawanpreet.la...@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 18 ++++++++++++++----
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 17 +++++++++++++----
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h |  4 ++--
 .../gpu/drm/amd/display/modules/hdcp/hdcp.c    |  5 ++++-
 4 files changed, 33 insertions(+), 11 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 7b0ca2e1ed8b..e9a9edac6ea7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -39,6 +39,7 @@
 #include "amdgpu_dm.h"
 #ifdef CONFIG_DRM_AMD_DC_HDCP
 #include "amdgpu_dm_hdcp.h"
+#include <drm/drm_hdcp.h>
 #endif
 #include "amdgpu_pm.h"
 
@@ -5118,7 +5119,7 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
                                adev->mode_info.freesync_capable_property, 0);
 #ifdef CONFIG_DRM_AMD_DC_HDCP
                if (adev->asic_type >= CHIP_RAVEN)
-                       
drm_connector_attach_content_protection_property(&aconnector->base, false);
+                       
drm_connector_attach_content_protection_property(&aconnector->base, true);
 #endif
        }
 }
@@ -5369,6 +5370,12 @@ static bool is_content_protection_different(struct 
drm_connector_state *state,
 {
        struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
 
+       if (old_state->hdcp_content_type != state->hdcp_content_type &&
+           state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) 
{
+               state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+               return true;
+       }
+
        /* 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) {
@@ -5401,11 +5408,14 @@ static void update_content_protection(struct 
drm_connector_state *state, const s
                                      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_add_display(hdcp_w, aconnector->dc_link->link_index, 
aconnector);
-       else if (state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+       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
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 fc775c0795d8..75f7045f04dd 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
@@ -83,7 +83,8 @@ 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)
+void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index, struct amdgpu_dm_connector *aconnector,
+                     bool disable_type1)
 {
        struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
        struct mod_hdcp_display *display = &hdcp_work[link_index].display;
@@ -92,6 +93,8 @@ void hdcp_add_display(struct hdcp_workqueue *hdcp_work, 
unsigned int link_index,
        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));
@@ -186,10 +189,16 @@ static void event_property_update(struct work_struct 
*work)
                }
        }
 
-       if (hdcp_work->encryption_status != MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF)
-               drm_hdcp_update_content_protection(&aconnector->base, 
DRM_MODE_CONTENT_PROTECTION_ENABLED);
-       else
+       if (hdcp_work->encryption_status != 
MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF) {
+               if (aconnector->base.state->hdcp_content_type == 
DRM_MODE_HDCP_CONTENT_TYPE0 &&
+                   hdcp_work->encryption_status <= 
MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON)
+                       drm_hdcp_update_content_protection(&aconnector->base, 
DRM_MODE_CONTENT_PROTECTION_ENABLED);
+               else if (aconnector->base.state->hdcp_content_type == 
DRM_MODE_HDCP_CONTENT_TYPE1 &&
+                        hdcp_work->encryption_status == 
MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON)
+                       drm_hdcp_update_content_protection(&aconnector->base, 
DRM_MODE_CONTENT_PROTECTION_ENABLED);
+       } else {
                drm_hdcp_update_content_protection(&aconnector->base, 
DRM_MODE_CONTENT_PROTECTION_DESIRED);
+       }
 
 
        mutex_unlock(&hdcp_work->mutex);
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 d3ba505d0696..098f7218f83a 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,8 +54,8 @@ 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);
+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_reset_display(struct hdcp_workqueue *work, unsigned int link_index);
 void hdcp_handle_cpirq(struct hdcp_workqueue *work, unsigned int link_index);
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
index a74812977963..0f2f242710b3 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
@@ -417,7 +417,10 @@ enum mod_hdcp_status mod_hdcp_query_display(struct 
mod_hdcp *hdcp,
        query->trace = &hdcp->connection.trace;
        query->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
 
-       mod_hdcp_hdcp1_get_link_encryption_status(hdcp, 
&query->encryption_status);
+       if (is_hdcp1(hdcp))
+               mod_hdcp_hdcp1_get_link_encryption_status(hdcp, 
&query->encryption_status);
+       else if (is_hdcp2(hdcp))
+               mod_hdcp_hdcp2_get_link_encryption_status(hdcp, 
&query->encryption_status);
 
 out:
        return status;
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to