Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Fix HDCP SEND AKI INIT error

[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>

authored by

Ahmad Othman and committed by
Alex Deucher
4268d081 f3fa4909

+46 -2
+37 -1
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
··· 251 251 return status; 252 252 } 253 253 254 + static enum mod_hdcp_status update_display_adjustments(struct mod_hdcp *hdcp, 255 + struct mod_hdcp_display *display, 256 + struct mod_hdcp_display_adjustment *adj) 257 + { 258 + enum mod_hdcp_status status = MOD_HDCP_STATUS_NOT_IMPLEMENTED; 259 + 260 + if (is_in_authenticated_states(hdcp) && 261 + is_dp_mst_hdcp(hdcp) && 262 + display->adjust.disable == true && 263 + adj->disable == false) { 264 + display->adjust.disable = false; 265 + if (is_hdcp1(hdcp)) 266 + status = mod_hdcp_hdcp1_enable_dp_stream_encryption(hdcp); 267 + else if (is_hdcp2(hdcp)) 268 + status = mod_hdcp_hdcp2_enable_dp_stream_encryption(hdcp); 269 + 270 + if (status != MOD_HDCP_STATUS_SUCCESS) 271 + display->adjust.disable = true; 272 + } 273 + 274 + if (status == MOD_HDCP_STATUS_SUCCESS && 275 + memcmp(adj, &display->adjust, 276 + sizeof(struct mod_hdcp_display_adjustment)) != 0) 277 + status = MOD_HDCP_STATUS_NOT_IMPLEMENTED; 278 + 279 + return status; 280 + } 254 281 /* 255 282 * Implementation of functions in mod_hdcp.h 256 283 */ ··· 418 391 return status; 419 392 } 420 393 421 - enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp, 394 + enum mod_hdcp_status mod_hdcp_update_display(struct mod_hdcp *hdcp, 422 395 uint8_t index, 423 396 struct mod_hdcp_link_adjustment *link_adjust, 424 397 struct mod_hdcp_display_adjustment *display_adjust, ··· 444 417 sizeof(struct mod_hdcp_display_adjustment)) == 0) { 445 418 status = MOD_HDCP_STATUS_SUCCESS; 446 419 goto out; 420 + } 421 + 422 + if (memcmp(link_adjust, &hdcp->connection.link.adjust, 423 + sizeof(struct mod_hdcp_link_adjustment)) == 0 && 424 + memcmp(display_adjust, &display->adjust, 425 + sizeof(struct mod_hdcp_display_adjustment)) != 0) { 426 + status = update_display_adjustments(hdcp, display, display_adjust); 427 + if (status != MOD_HDCP_STATUS_NOT_IMPLEMENTED) 428 + goto out; 447 429 } 448 430 449 431 /* stop current authentication */
+8
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
··· 445 445 current_state(hdcp) <= HDCP2_DP_STATE_END); 446 446 } 447 447 448 + static inline uint8_t is_in_authenticated_states(struct mod_hdcp *hdcp) 449 + { 450 + return (current_state(hdcp) == D1_A4_AUTHENTICATED || 451 + current_state(hdcp) == H1_A45_AUTHENTICATED || 452 + current_state(hdcp) == D2_A5_AUTHENTICATED || 453 + current_state(hdcp) == H2_A5_AUTHENTICATED); 454 + } 455 + 448 456 static inline uint8_t is_hdcp1(struct mod_hdcp *hdcp) 449 457 { 450 458 return (is_in_hdcp1_states(hdcp) || is_in_hdcp1_dp_states(hdcp));
+1 -1
drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
··· 294 294 uint8_t index, struct mod_hdcp_output *output); 295 295 296 296 /* called per display to apply new authentication adjustment */ 297 - enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp, 297 + enum mod_hdcp_status mod_hdcp_update_display(struct mod_hdcp *hdcp, 298 298 uint8_t index, 299 299 struct mod_hdcp_link_adjustment *link_adjust, 300 300 struct mod_hdcp_display_adjustment *display_adjust,