Commit 9124ee78 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher
Browse files

drm/amd/display: update HDCP DTM immediately after hardware programming



[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: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3744ee2c
Loading
Loading
Loading
Loading
+15 −31
Original line number Diff line number Diff line
@@ -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,
+4 −6
Original line number Diff line number Diff line
@@ -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);
+0 −4
Original line number Diff line number Diff line
@@ -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"))
+2 −4
Original line number Diff line number Diff line
@@ -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);
+2 −4
Original line number Diff line number Diff line
@@ -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"))
Loading