]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/amd/display: Fix HDCP SEND AKI INIT error
authorAhmad Othman <ahmad.othman@amd.com>
Fri, 4 Mar 2022 16:56:19 +0000 (11:56 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 25 Mar 2022 16:40:26 +0000 (12:40 -0400)
[why]
HDCP sends AKI INIT error in case of multiple display on dock

[how]
Add new checks and method to handle display adjustment
for multiple display cases

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Ahmad Othman <ahmad.othman@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h

index 3e81850a7ffe3a8364c521561e9275b374f5023e..5e01c6e24cbc8c0c881af655ebb1cb8ea2cd7e6e 100644 (file)
@@ -251,6 +251,33 @@ out:
        return status;
 }
 
+static enum mod_hdcp_status update_display_adjustments(struct mod_hdcp *hdcp,
+               struct mod_hdcp_display *display,
+               struct mod_hdcp_display_adjustment *adj)
+{
+       enum mod_hdcp_status status = MOD_HDCP_STATUS_NOT_IMPLEMENTED;
+
+       if (is_in_authenticated_states(hdcp) &&
+                       is_dp_mst_hdcp(hdcp) &&
+                       display->adjust.disable == true &&
+                       adj->disable == false) {
+               display->adjust.disable = false;
+               if (is_hdcp1(hdcp))
+                       status = mod_hdcp_hdcp1_enable_dp_stream_encryption(hdcp);
+               else if (is_hdcp2(hdcp))
+                       status = mod_hdcp_hdcp2_enable_dp_stream_encryption(hdcp);
+
+               if (status != MOD_HDCP_STATUS_SUCCESS)
+                       display->adjust.disable = true;
+       }
+
+       if (status == MOD_HDCP_STATUS_SUCCESS &&
+               memcmp(adj, &display->adjust,
+               sizeof(struct mod_hdcp_display_adjustment)) != 0)
+               status = MOD_HDCP_STATUS_NOT_IMPLEMENTED;
+
+       return status;
+}
 /*
  * Implementation of functions in mod_hdcp.h
  */
@@ -391,7 +418,7 @@ out:
        return status;
 }
 
-enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp,
+enum mod_hdcp_status mod_hdcp_update_display(struct mod_hdcp *hdcp,
                uint8_t index,
                struct mod_hdcp_link_adjustment *link_adjust,
                struct mod_hdcp_display_adjustment *display_adjust,
@@ -419,6 +446,15 @@ enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp,
                goto out;
        }
 
+       if (memcmp(link_adjust, &hdcp->connection.link.adjust,
+                       sizeof(struct mod_hdcp_link_adjustment)) == 0 &&
+                       memcmp(display_adjust, &display->adjust,
+                                       sizeof(struct mod_hdcp_display_adjustment)) != 0) {
+               status = update_display_adjustments(hdcp, display, display_adjust);
+               if (status != MOD_HDCP_STATUS_NOT_IMPLEMENTED)
+                       goto out;
+       }
+
        /* stop current authentication */
        status = reset_authentication(hdcp, output);
        if (status != MOD_HDCP_STATUS_SUCCESS)
index 8502263d2968d8fb089f922414e179b5d447056a..4e7021c3c8452638eb7dc9a3cc3afdf01719b1e3 100644 (file)
@@ -445,6 +445,14 @@ static inline uint8_t is_in_hdcp2_dp_states(struct mod_hdcp *hdcp)
                        current_state(hdcp) <= HDCP2_DP_STATE_END);
 }
 
+static inline uint8_t is_in_authenticated_states(struct mod_hdcp *hdcp)
+{
+       return (current_state(hdcp) == D1_A4_AUTHENTICATED ||
+       current_state(hdcp) == H1_A45_AUTHENTICATED ||
+       current_state(hdcp) == D2_A5_AUTHENTICATED ||
+       current_state(hdcp) == H2_A5_AUTHENTICATED);
+}
+
 static inline uint8_t is_hdcp1(struct mod_hdcp *hdcp)
 {
        return (is_in_hdcp1_states(hdcp) || is_in_hdcp1_dp_states(hdcp));
index f7420c3f56724352a6faa0e87e01550a68e0dd6b..3348bb97ef81aacf3ff62066913e745e7f93626a 100644 (file)
@@ -294,7 +294,7 @@ enum mod_hdcp_status mod_hdcp_remove_display(struct mod_hdcp *hdcp,
                uint8_t index, struct mod_hdcp_output *output);
 
 /* called per display to apply new authentication adjustment */
-enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp,
+enum mod_hdcp_status mod_hdcp_update_display(struct mod_hdcp *hdcp,
                uint8_t index,
                struct mod_hdcp_link_adjustment *link_adjust,
                struct mod_hdcp_display_adjustment *display_adjust,