From: Wenjing Liu <Wenjing.Liu@xxxxxxx> [why] HDCP DTM needs to be aware of the upto date display topology information in order to validate hardware consistency. [how] update HDCP DTM on update_stream_config call. Signed-off-by: Wenjing Liu <Wenjing.Liu@xxxxxxx> Reviewed-by: Jun Lei <Jun.Lei@xxxxxxx> --- .../gpu/drm/amd/display/modules/hdcp/hdcp.c | 46 ++----- .../gpu/drm/amd/display/modules/hdcp/hdcp.h | 10 +- .../display/modules/hdcp/hdcp1_execution.c | 4 - .../display/modules/hdcp/hdcp1_transition.c | 6 +- .../display/modules/hdcp/hdcp2_execution.c | 6 +- .../display/modules/hdcp/hdcp2_transition.c | 6 +- .../drm/amd/display/modules/hdcp/hdcp_log.h | 9 ++ .../drm/amd/display/modules/hdcp/hdcp_psp.c | 129 ++++++++++-------- 8 files changed, 106 insertions(+), 110 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c index a7d24734c7cd..83eaec4c6ad7 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c @@ -104,8 +104,6 @@ static enum mod_hdcp_status execution(struct mod_hdcp *hdcp, event_ctx->unexpected_event = 1; goto out; } - /* update topology event if hdcp is not desired */ - status = mod_hdcp_add_display_topology(hdcp); } else if (is_in_hdcp1_states(hdcp)) { status = mod_hdcp_hdcp1_execution(hdcp, event_ctx, &input->hdcp1); } else if (is_in_hdcp1_dp_states(hdcp)) { @@ -192,14 +190,7 @@ static enum mod_hdcp_status reset_authentication(struct mod_hdcp *hdcp, mod_hdcp_hdcp1_destroy_session(hdcp); } - if (hdcp->auth.trans_input.hdcp1.add_topology == PASS) { - status = mod_hdcp_remove_display_topology(hdcp); - if (status != MOD_HDCP_STATUS_SUCCESS) { - output->callback_needed = 0; - output->watchdog_timer_needed = 0; - goto out; - } - } + HDCP_TOP_RESET_AUTH_TRACE(hdcp); memset(&hdcp->auth, 0, sizeof(struct mod_hdcp_authentication)); memset(&hdcp->state, 0, sizeof(struct mod_hdcp_state)); @@ -213,25 +204,12 @@ static enum mod_hdcp_status reset_authentication(struct mod_hdcp *hdcp, goto out; } } - if (hdcp->auth.trans_input.hdcp2.add_topology == PASS) { - status = mod_hdcp_remove_display_topology(hdcp); - if (status != MOD_HDCP_STATUS_SUCCESS) { - output->callback_needed = 0; - output->watchdog_timer_needed = 0; - goto out; - } - } + HDCP_TOP_RESET_AUTH_TRACE(hdcp); memset(&hdcp->auth, 0, sizeof(struct mod_hdcp_authentication)); memset(&hdcp->state, 0, sizeof(struct mod_hdcp_state)); set_state_id(hdcp, output, HDCP_INITIALIZED); } else if (is_in_cp_not_desired_state(hdcp)) { - status = mod_hdcp_remove_display_topology(hdcp); - if (status != MOD_HDCP_STATUS_SUCCESS) { - output->callback_needed = 0; - output->watchdog_timer_needed = 0; - goto out; - } HDCP_TOP_RESET_AUTH_TRACE(hdcp); memset(&hdcp->auth, 0, sizeof(struct mod_hdcp_authentication)); memset(&hdcp->state, 0, sizeof(struct mod_hdcp_state)); @@ -338,16 +316,19 @@ enum mod_hdcp_status mod_hdcp_add_display(struct mod_hdcp *hdcp, if (status != MOD_HDCP_STATUS_SUCCESS) goto out; - /* add display to connection */ - hdcp->connection.link = *link; - *display_container = *display; - /* reset retry counters */ reset_retry_counts(hdcp); /* reset error trace */ memset(&hdcp->connection.trace, 0, sizeof(hdcp->connection.trace)); + /* add display to connection */ + hdcp->connection.link = *link; + *display_container = *display; + status = mod_hdcp_add_display_to_topology(hdcp, display->index); + if (status != MOD_HDCP_STATUS_SUCCESS) + goto out; + /* request authentication */ if (current_state(hdcp) != HDCP_INITIALIZED) set_state_id(hdcp, output, HDCP_INITIALIZED); @@ -380,15 +361,18 @@ enum mod_hdcp_status mod_hdcp_remove_display(struct mod_hdcp *hdcp, if (status != MOD_HDCP_STATUS_SUCCESS) goto out; - /* remove display */ - display->state = MOD_HDCP_DISPLAY_INACTIVE; - /* clear retry counters */ reset_retry_counts(hdcp); /* reset error trace */ memset(&hdcp->connection.trace, 0, sizeof(hdcp->connection.trace)); + /* remove display */ + status = mod_hdcp_remove_display_from_topology(hdcp, index); + if (status != MOD_HDCP_STATUS_SUCCESS) + goto out; + display->state = MOD_HDCP_DISPLAY_INACTIVE; + /* request authentication for remaining displays*/ if (get_active_display_count(hdcp) > 0) callback_in_ms(hdcp->connection.link.adjust.auth_delay * 1000, diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h index 4d717ec8f14b..b09d2f5502b3 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h @@ -41,7 +41,6 @@ enum mod_hdcp_trans_input_result { struct mod_hdcp_transition_input_hdcp1 { uint8_t bksv_read; uint8_t bksv_validation; - uint8_t add_topology; uint8_t create_session; uint8_t an_write; uint8_t aksv_write; @@ -71,7 +70,6 @@ struct mod_hdcp_transition_input_hdcp1 { struct mod_hdcp_transition_input_hdcp2 { uint8_t hdcp2version_read; uint8_t hdcp2_capable_check; - uint8_t add_topology; uint8_t create_session; uint8_t ake_init_prepare; uint8_t ake_init_write; @@ -328,10 +326,10 @@ void mod_hdcp_dump_binary_message(uint8_t *msg, uint32_t msg_size, /* TODO: add adjustment log */ /* psp functions */ -enum mod_hdcp_status mod_hdcp_add_display_topology( - struct mod_hdcp *hdcp); -enum mod_hdcp_status mod_hdcp_remove_display_topology( - struct mod_hdcp *hdcp); +enum mod_hdcp_status mod_hdcp_add_display_to_topology( + struct mod_hdcp *hdcp, uint8_t index); +enum mod_hdcp_status mod_hdcp_remove_display_from_topology( + struct mod_hdcp *hdcp, uint8_t index); enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index 37670db64855..37c8c05497d6 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -168,10 +168,6 @@ static enum mod_hdcp_status exchange_ksvs(struct mod_hdcp *hdcp, goto out; } - if (!mod_hdcp_execute_and_set(mod_hdcp_add_display_topology, - &input->add_topology, &status, - hdcp, "add_topology")) - goto out; if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_create_session, &input->create_session, &status, hdcp, "create_session")) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c index d66a9f954ade..5bc6706d2af7 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c @@ -46,8 +46,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_transition(struct mod_hdcp *hdcp, set_state_id(hdcp, output, H1_A1_EXCHANGE_KSVS); break; case H1_A1_EXCHANGE_KSVS: - if (input->add_topology != PASS || - input->create_session != PASS) { + if (input->create_session != PASS) { /* out of sync with psp state */ adjust->hdcp1.disable = 1; fail_and_restart_in_ms(0, &status, output); @@ -173,8 +172,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp, set_state_id(hdcp, output, D1_A1_EXCHANGE_KSVS); break; case D1_A1_EXCHANGE_KSVS: - if (input->add_topology != PASS || - input->create_session != PASS) { + if (input->create_session != PASS) { /* out of sync with psp state */ adjust->hdcp1.disable = 1; fail_and_restart_in_ms(0, &status, output); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c index f730b94ac3c0..432b2a016e56 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c @@ -259,6 +259,7 @@ static enum mod_hdcp_status known_hdcp2_capable_rx(struct mod_hdcp *hdcp, event_ctx->unexpected_event = 1; goto out; } + if (!mod_hdcp_execute_and_set(mod_hdcp_read_hdcp2version, &input->hdcp2version_read, &status, hdcp, "hdcp2version_read")) @@ -281,10 +282,7 @@ static enum mod_hdcp_status send_ake_init(struct mod_hdcp *hdcp, event_ctx->unexpected_event = 1; goto out; } - if (!mod_hdcp_execute_and_set(mod_hdcp_add_display_topology, - &input->add_topology, &status, - hdcp, "add_topology")) - goto out; + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_create_session, &input->create_session, &status, hdcp, "create_session")) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c index 8cae3e3aacd5..e738c7ae66ec 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c @@ -47,8 +47,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp, } break; case H2_A1_SEND_AKE_INIT: - if (input->add_topology != PASS || - input->create_session != PASS || + if (input->create_session != PASS || input->ake_init_prepare != PASS) { /* out of sync with psp state */ adjust->hdcp2.disable = 1; @@ -389,8 +388,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp, } break; case D2_A1_SEND_AKE_INIT: - if (input->add_topology != PASS || - input->create_session != PASS || + if (input->create_session != PASS || input->ake_init_prepare != PASS) { /* out of sync with psp state */ adjust->hdcp2.disable = 1; diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h index ff91373ebada..6e844825ad23 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h @@ -49,6 +49,15 @@ HDCP_LOG_VER(hdcp, \ "[Link %d] HDCP 2.2 enabled on display %d", \ hdcp->config.index, displayIndex) +#define HDCP_HDCP1_DISABLED_TRACE(hdcp, displayIndex) \ + HDCP_LOG_VER(hdcp, \ + "[Link %d] HDCP 1.4 disabled on display %d", \ + hdcp->config.index, displayIndex) +#define HDCP_HDCP2_DISABLED_TRACE(hdcp, displayIndex) \ + HDCP_LOG_VER(hdcp, \ + "[Link %d] HDCP 2.2 disabled on display %d", \ + hdcp->config.index, displayIndex) + /* state machine logs */ #define HDCP_REMOVE_DISPLAY_TRACE(hdcp, displayIndex) \ HDCP_LOG_FSM(hdcp, \ diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c index 844454e0a5ba..acbe3e8a8eb7 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -44,85 +44,82 @@ static void hdcp2_message_init(struct mod_hdcp *hdcp, in->process.msg3_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE; in->process.msg3_desc.msg_size = 0; } -enum mod_hdcp_status mod_hdcp_remove_display_topology(struct mod_hdcp *hdcp) -{ - - struct psp_context *psp = hdcp->config.psp.handle; - struct ta_dtm_shared_memory *dtm_cmd; - struct mod_hdcp_display *display = NULL; - uint8_t i; +enum mod_hdcp_status mod_hdcp_remove_display_from_topology( + struct mod_hdcp *hdcp, uint8_t index) + { + struct psp_context *psp = hdcp->config.psp.handle; + struct ta_dtm_shared_memory *dtm_cmd; + struct mod_hdcp_display *display = + get_active_display_at_index(hdcp, index); dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.dtm_shared_buf; - for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { - if (is_display_added(&(hdcp->connection.displays[i]))) { - - memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); - - display = &hdcp->connection.displays[i]; + if (!display || !is_display_added(display)) + return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; - dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; - dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index; - dtm_cmd->dtm_in_message.topology_update_v2.is_active = 0; - dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; + memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); - psp_dtm_invoke(psp, dtm_cmd->cmd_id); + dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; + dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index; + dtm_cmd->dtm_in_message.topology_update_v2.is_active = 0; + dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; - if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) - return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; + psp_dtm_invoke(psp, dtm_cmd->cmd_id); - display->state = MOD_HDCP_DISPLAY_ACTIVE; - HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); - } - } + if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) + return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; - return MOD_HDCP_STATUS_SUCCESS; -} + display->state = MOD_HDCP_DISPLAY_ACTIVE; + HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); + + return MOD_HDCP_STATUS_SUCCESS; + } -enum mod_hdcp_status mod_hdcp_add_display_topology(struct mod_hdcp *hdcp) +enum mod_hdcp_status mod_hdcp_add_display_to_topology( + struct mod_hdcp *hdcp, uint8_t index) { struct psp_context *psp = hdcp->config.psp.handle; struct ta_dtm_shared_memory *dtm_cmd; - struct mod_hdcp_display *display = NULL; + struct mod_hdcp_display *display = + get_active_display_at_index(hdcp, index); struct mod_hdcp_link *link = &hdcp->connection.link; - uint8_t i; if (!psp->dtm_context.dtm_initialized) { DRM_ERROR("Failed to add display topology, DTM TA is not initialized."); return MOD_HDCP_STATUS_FAILURE; } + if (!display || is_display_added(display)) + return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; + dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.dtm_shared_buf; - for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { - if (hdcp->connection.displays[i].state == MOD_HDCP_DISPLAY_ACTIVE) { - display = &hdcp->connection.displays[i]; - - memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); - - dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; - dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index; - dtm_cmd->dtm_in_message.topology_update_v2.is_active = 1; - dtm_cmd->dtm_in_message.topology_update_v2.controller = display->controller; - dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = link->ddc_line; - dtm_cmd->dtm_in_message.topology_update_v2.dig_be = link->dig_be; - dtm_cmd->dtm_in_message.topology_update_v2.dig_fe = display->dig_fe; - dtm_cmd->dtm_in_message.topology_update_v2.dp_mst_vcid = display->vc_id; - dtm_cmd->dtm_in_message.topology_update_v2.max_hdcp_supported_version = - TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_2; - dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; - - psp_dtm_invoke(psp, dtm_cmd->cmd_id); - - if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) - return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; - - display->state = MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; - HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); - } - } + memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); - return MOD_HDCP_STATUS_SUCCESS; + dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; + dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index; + dtm_cmd->dtm_in_message.topology_update_v2.is_active = 1; + dtm_cmd->dtm_in_message.topology_update_v2.controller = display->controller; + dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = link->ddc_line; + dtm_cmd->dtm_in_message.topology_update_v2.dig_be = link->dig_be; + dtm_cmd->dtm_in_message.topology_update_v2.dig_fe = display->dig_fe; + if (is_dp_hdcp(hdcp)) + dtm_cmd->dtm_in_message.topology_update_v2.is_assr = link->dp.assr_supported; + + dtm_cmd->dtm_in_message.topology_update_v2.dp_mst_vcid = display->vc_id; + dtm_cmd->dtm_in_message.topology_update_v2.max_hdcp_supported_version = + TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_2; + dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; + + psp_dtm_invoke(psp, dtm_cmd->cmd_id); + + if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) + return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; + + display->state = MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; + HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); + + return MOD_HDCP_STATUS_SUCCESS; } enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp) @@ -164,6 +161,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp) struct psp_context *psp = hdcp->config.psp.handle; struct ta_hdcp_shared_memory *hdcp_cmd; + uint8_t i = 0; hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -177,6 +175,14 @@ enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp) return MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE; HDCP_TOP_HDCP1_DESTROY_SESSION_TRACE(hdcp); + for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) + if (is_display_encryption_enabled( + &hdcp->connection.displays[i])) { + hdcp->connection.displays[i].state = + MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; + HDCP_HDCP1_DISABLED_TRACE(hdcp, + hdcp->connection.displays[i].index); + } return MOD_HDCP_STATUS_SUCCESS; } @@ -399,6 +405,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp) { struct psp_context *psp = hdcp->config.psp.handle; struct ta_hdcp_shared_memory *hdcp_cmd; + uint8_t i = 0; hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -412,6 +419,14 @@ enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp) return MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE; HDCP_TOP_HDCP2_DESTROY_SESSION_TRACE(hdcp); + for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) + if (is_display_encryption_enabled( + &hdcp->connection.displays[i])) { + hdcp->connection.displays[i].state = + MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; + HDCP_HDCP2_DISABLED_TRACE(hdcp, + hdcp->connection.displays[i].index); + } return MOD_HDCP_STATUS_SUCCESS; } -- 2.17.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx