drm/amd/display: Remove hdcp display state with mst fix

[Why]
Due to previous code changes, displays transition from active to active
and added state immediately, making it redundant to have both display
states. Previous change to fix this caused HDCP to get into a bad state
when monitor is connected to MST hub, this change fixes that issue.

[How]
Change code behavior so when a device is added successfully the state
remains as active and when addition is unsuccessful change state to
inactive. This removes need for added and active state.

Signed-off-by: Isabel Zhang <isabel.zhang@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Isabel Zhang 2020-04-05 16:40:44 -04:00 committed by Alex Deucher
parent c5d5b0ecf9
commit 2deade5ede
6 changed files with 26 additions and 47 deletions

View File

@ -328,7 +328,8 @@ enum mod_hdcp_status mod_hdcp_add_display(struct mod_hdcp *hdcp,
/* add display to connection */
hdcp->connection.link = *link;
*display_container = *display;
status = mod_hdcp_add_display_to_topology(hdcp, display->index);
status = mod_hdcp_add_display_to_topology(hdcp, display_container);
if (status != MOD_HDCP_STATUS_SUCCESS)
goto out;
@ -374,7 +375,7 @@ enum mod_hdcp_status mod_hdcp_remove_display(struct mod_hdcp *hdcp,
status = mod_hdcp_remove_display_from_topology(hdcp, index);
if (status != MOD_HDCP_STATUS_SUCCESS)
goto out;
display->state = MOD_HDCP_DISPLAY_INACTIVE;
memset(display, 0, sizeof(struct mod_hdcp_display));
/* request authentication when connection is not reset */
if (current_state(hdcp) != HDCP_UNINITIALIZED)

View File

@ -328,7 +328,7 @@ void mod_hdcp_dump_binary_message(uint8_t *msg, uint32_t msg_size,
/* psp functions */
enum mod_hdcp_status mod_hdcp_add_display_to_topology(
struct mod_hdcp *hdcp, uint8_t index);
struct mod_hdcp *hdcp, struct mod_hdcp_display *display);
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);
@ -501,11 +501,6 @@ static inline uint8_t is_display_active(struct mod_hdcp_display *display)
return display->state >= MOD_HDCP_DISPLAY_ACTIVE;
}
static inline uint8_t is_display_added(struct mod_hdcp_display *display)
{
return display->state >= MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
}
static inline uint8_t is_display_encryption_enabled(struct mod_hdcp_display *display)
{
return display->state >= MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
@ -513,34 +508,23 @@ static inline uint8_t is_display_encryption_enabled(struct mod_hdcp_display *dis
static inline uint8_t get_active_display_count(struct mod_hdcp *hdcp)
{
uint8_t added_count = 0;
uint8_t active_count = 0;
uint8_t i;
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
if (is_display_active(&hdcp->displays[i]))
added_count++;
return added_count;
active_count++;
return active_count;
}
static inline uint8_t get_added_display_count(struct mod_hdcp *hdcp)
{
uint8_t added_count = 0;
uint8_t i;
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
if (is_display_added(&hdcp->displays[i]))
added_count++;
return added_count;
}
static inline struct mod_hdcp_display *get_first_added_display(
static inline struct mod_hdcp_display *get_first_active_display(
struct mod_hdcp *hdcp)
{
uint8_t i;
struct mod_hdcp_display *display = NULL;
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
if (is_display_added(&hdcp->displays[i])) {
if (is_display_active(&hdcp->displays[i])) {
display = &hdcp->displays[i];
break;
}

View File

@ -129,7 +129,7 @@ static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
static inline enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
{
/* device count must be greater than or equal to tracked hdcp displays */
return (get_device_count(hdcp) < get_added_display_count(hdcp)) ?
return (get_device_count(hdcp) < get_active_display_count(hdcp)) ?
MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE :
MOD_HDCP_STATUS_SUCCESS;
}

View File

@ -208,7 +208,7 @@ static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
static enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
{
/* device count must be greater than or equal to tracked hdcp displays */
return (get_device_count(hdcp) < get_added_display_count(hdcp)) ?
return (get_device_count(hdcp) < get_active_display_count(hdcp)) ?
MOD_HDCP_STATUS_HDCP2_DEVICE_COUNT_MISMATCH_FAILURE :
MOD_HDCP_STATUS_SUCCESS;
}

View File

@ -55,7 +55,7 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.dtm_shared_buf;
if (!display || !is_display_added(display))
if (!display || !is_display_active(display))
return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
mutex_lock(&psp->dtm_context.mutex);
@ -80,23 +80,19 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
return status;
}
enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
uint8_t index)
struct mod_hdcp_display *display)
{
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);
struct mod_hdcp_link *link = &hdcp->connection.link;
enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
if (!psp->dtm_context.dtm_initialized) {
DRM_ERROR("Failed to add display topology, DTM TA is not initialized.");
display->state = MOD_HDCP_DISPLAY_INACTIVE;
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;
mutex_lock(&psp->dtm_context.mutex);
@ -120,9 +116,9 @@ enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
psp_dtm_invoke(psp, dtm_cmd->cmd_id);
if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
display->state = MOD_HDCP_DISPLAY_INACTIVE;
status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
} else {
display->state = MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);
}
@ -134,7 +130,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)
{
struct psp_context *psp = hdcp->config.psp.handle;
struct mod_hdcp_display *display = get_first_added_display(hdcp);
struct mod_hdcp_display *display = get_first_active_display(hdcp);
struct ta_hdcp_shared_memory *hdcp_cmd;
enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
@ -193,7 +189,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp)
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
if (is_display_encryption_enabled(&hdcp->displays[i])) {
hdcp->displays[i].state =
MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
MOD_HDCP_DISPLAY_ACTIVE;
HDCP_HDCP1_DISABLED_TRACE(
hdcp, hdcp->displays[i].index);
}
@ -248,7 +244,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp)
{
struct psp_context *psp = hdcp->config.psp.handle;
struct ta_hdcp_shared_memory *hdcp_cmd;
struct mod_hdcp_display *display = get_first_added_display(hdcp);
struct mod_hdcp_display *display = get_first_active_display(hdcp);
enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
mutex_lock(&psp->hdcp_context.mutex);
@ -325,9 +321,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED ||
hdcp->displays[i].adjust.disable)
continue;
if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)
continue;
memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
@ -393,7 +388,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)
{
struct psp_context *psp = hdcp->config.psp.handle;
struct ta_hdcp_shared_memory *hdcp_cmd;
struct mod_hdcp_display *display = get_first_added_display(hdcp);
struct mod_hdcp_display *display = get_first_active_display(hdcp);
enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
@ -459,7 +454,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp)
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
if (is_display_encryption_enabled(&hdcp->displays[i])) {
hdcp->displays[i].state =
MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
MOD_HDCP_DISPLAY_ACTIVE;
HDCP_HDCP2_DISABLED_TRACE(
hdcp, hdcp->displays[i].index);
}
@ -722,7 +717,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp)
{
struct psp_context *psp = hdcp->config.psp.handle;
struct ta_hdcp_shared_memory *hdcp_cmd;
struct mod_hdcp_display *display = get_first_added_display(hdcp);
struct mod_hdcp_display *display = get_first_active_display(hdcp);
enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
if (!display)
@ -818,9 +813,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp
for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED ||
hdcp->displays[i].adjust.disable)
continue;
if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)
continue;
hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;
hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.session_handle = hdcp->auth.id;

View File

@ -117,7 +117,6 @@ enum mod_hdcp_operation_mode {
enum mod_hdcp_display_state {
MOD_HDCP_DISPLAY_INACTIVE = 0,
MOD_HDCP_DISPLAY_ACTIVE,
MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED,
MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED
};