diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules')
16 files changed, 282 insertions, 220 deletions
| diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index b9992ebf77a6..c33454a9e0b4 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -524,12 +524,12 @@ static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr,  		infopacket->sb[6] |= 0x04;  	/* PB7 = FreeSync Minimum refresh rate (Hz) */ -	infopacket->sb[7] = (unsigned char)(vrr->min_refresh_in_uhz / 1000000); +	infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000);  	/* PB8 = FreeSync Maximum refresh rate (Hz)  	 * Note: We should never go above the field rate of the mode timing set.  	 */ -	infopacket->sb[8] = (unsigned char)(vrr->max_refresh_in_uhz / 1000000); +	infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000);  	//FreeSync HDR @@ -734,6 +734,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  {  	struct core_freesync *core_freesync = NULL;  	unsigned long long nominal_field_rate_in_uhz = 0; +	unsigned long long rounded_nominal_in_uhz = 0;  	unsigned int refresh_range = 0;  	unsigned long long min_refresh_in_uhz = 0;  	unsigned long long max_refresh_in_uhz = 0; @@ -747,24 +748,23 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  	nominal_field_rate_in_uhz =  			mod_freesync_calc_nominal_field_rate(stream); -	/* Rounded to the nearest Hz */ -	nominal_field_rate_in_uhz = 1000000ULL * -			div_u64(nominal_field_rate_in_uhz + 500000, 1000000); -  	min_refresh_in_uhz = in_config->min_refresh_in_uhz;  	max_refresh_in_uhz = in_config->max_refresh_in_uhz; -	// Don't allow min > max -	if (min_refresh_in_uhz > max_refresh_in_uhz) -		min_refresh_in_uhz = max_refresh_in_uhz; -  	// Full range may be larger than current video timing, so cap at nominal  	if (max_refresh_in_uhz > nominal_field_rate_in_uhz)  		max_refresh_in_uhz = nominal_field_rate_in_uhz;  	// Full range may be larger than current video timing, so cap at nominal -	if (min_refresh_in_uhz > nominal_field_rate_in_uhz) -		min_refresh_in_uhz = nominal_field_rate_in_uhz; +	if (min_refresh_in_uhz > max_refresh_in_uhz) +		min_refresh_in_uhz = max_refresh_in_uhz; + +	// If a monitor reports exactly max refresh of 2x of min, enforce it on nominal +	rounded_nominal_in_uhz = +			div_u64(nominal_field_rate_in_uhz + 50000, 100000) * 100000; +	if (in_config->max_refresh_in_uhz == (2 * in_config->min_refresh_in_uhz) && +		in_config->max_refresh_in_uhz == rounded_nominal_in_uhz) +		min_refresh_in_uhz = div_u64(nominal_field_rate_in_uhz, 2);  	if (!vrr_settings_require_update(core_freesync,  			in_config, (unsigned int)min_refresh_in_uhz, (unsigned int)max_refresh_in_uhz, @@ -796,11 +796,6 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  		refresh_range = in_out_vrr->max_refresh_in_uhz -  				in_out_vrr->min_refresh_in_uhz; -		in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us - -				2 * in_out_vrr->min_duration_in_us; -		if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN) -			in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN; -  		in_out_vrr->supported = true;  	} @@ -808,9 +803,14 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  	in_out_vrr->btr.btr_enabled = in_config->btr; -	if (in_out_vrr->max_refresh_in_uhz < -			2 * in_out_vrr->min_refresh_in_uhz) +	if (in_out_vrr->max_refresh_in_uhz < (2 * in_out_vrr->min_refresh_in_uhz))  		in_out_vrr->btr.btr_enabled = false; +	else { +		in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us - +				2 * in_out_vrr->min_duration_in_us; +		if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN) +			in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN; +	}  	in_out_vrr->btr.btr_active = false;  	in_out_vrr->btr.inserted_duration_in_us = 0; @@ -1012,8 +1012,8 @@ unsigned long long mod_freesync_calc_nominal_field_rate(  	unsigned int total = stream->timing.h_total * stream->timing.v_total;  	/* Calculate nominal field rate for stream, rounded up to nearest integer */ -	nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10; -	nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL; +	nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz; +	nominal_field_rate_in_uhz *= 100000000ULL;  	nominal_field_rate_in_uhz =	div_u64(nominal_field_rate_in_uhz, total); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c index 8aa528e874c4..cc1d3f470b99 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c @@ -52,8 +52,8 @@ static uint8_t is_cp_desired_hdcp1(struct mod_hdcp *hdcp)  	 * hdcp is not desired  	 */  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { -		if (hdcp->connection.displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && -				!hdcp->connection.displays[i].adjust.disable) { +		if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && +				!hdcp->displays[i].adjust.disable) {  			is_auth_needed = 1;  			break;  		} @@ -61,7 +61,8 @@ static uint8_t is_cp_desired_hdcp1(struct mod_hdcp *hdcp)  	return (hdcp->connection.hdcp1_retry_count < MAX_NUM_OF_ATTEMPTS) &&  			is_auth_needed && -			!hdcp->connection.link.adjust.hdcp1.disable; +			!hdcp->connection.link.adjust.hdcp1.disable && +			!hdcp->connection.is_hdcp1_revoked;  }  static uint8_t is_cp_desired_hdcp2(struct mod_hdcp *hdcp) @@ -72,8 +73,8 @@ static uint8_t is_cp_desired_hdcp2(struct mod_hdcp *hdcp)  	 * hdcp is not desired  	 */  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { -		if (hdcp->connection.displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && -				!hdcp->connection.displays[i].adjust.disable) { +		if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && +				!hdcp->displays[i].adjust.disable) {  			is_auth_needed = 1;  			break;  		} @@ -103,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)) { @@ -115,6 +114,9 @@ static enum mod_hdcp_status execution(struct mod_hdcp *hdcp,  	} else if (is_in_hdcp2_dp_states(hdcp)) {  		status = mod_hdcp_hdcp2_dp_execution(hdcp,  				event_ctx, &input->hdcp2); +	} else { +		event_ctx->unexpected_event = 1; +		goto out;  	}  out:  	return status; @@ -191,14 +193,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)); @@ -212,25 +207,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)); @@ -337,16 +319,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); @@ -379,17 +364,20 @@ 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)); -	/* request authentication for remaining displays*/ -	if (get_active_display_count(hdcp) > 0) +	/* 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 when connection is not reset */ +	if (current_state(hdcp) != HDCP_UNINITIALIZED)  		callback_in_ms(hdcp->connection.link.adjust.auth_delay * 1000,  				output);  out: @@ -496,10 +484,8 @@ enum mod_hdcp_operation_mode mod_hdcp_signal_type_to_operation_mode(  		break;  	case SIGNAL_TYPE_EDP:  	case SIGNAL_TYPE_DISPLAY_PORT: -		mode = MOD_HDCP_MODE_DP; -		break;  	case SIGNAL_TYPE_DISPLAY_PORT_MST: -		mode = MOD_HDCP_MODE_DP_MST; +		mode = MOD_HDCP_MODE_DP;  		break;  	default:  		break; diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h index af78e4f1be68..5cb4546be0ef 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; @@ -167,9 +165,9 @@ struct mod_hdcp_auth_counters {  /* contains values per connection */  struct mod_hdcp_connection {  	struct mod_hdcp_link link; -	struct mod_hdcp_display displays[MAX_NUM_OF_DISPLAYS];  	uint8_t is_repeater;  	uint8_t is_km_stored; +	uint8_t is_hdcp1_revoked;  	uint8_t is_hdcp2_revoked;  	struct mod_hdcp_trace trace;  	uint8_t hdcp1_retry_count; @@ -202,6 +200,8 @@ struct mod_hdcp {  	struct mod_hdcp_config config;  	/* per connection */  	struct mod_hdcp_connection connection; +	/* per displays */ +	struct mod_hdcp_display displays[MAX_NUM_OF_DISPLAYS];  	/* per authentication attempt */  	struct mod_hdcp_authentication auth;  	/* per state in an authentication */ @@ -327,10 +327,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); @@ -392,13 +392,13 @@ enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp);  /* hdcp version helpers */  static inline uint8_t is_dp_hdcp(struct mod_hdcp *hdcp)  { -	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP || -			hdcp->connection.link.mode == MOD_HDCP_MODE_DP_MST); +	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP);  }  static inline uint8_t is_dp_mst_hdcp(struct mod_hdcp *hdcp)  { -	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP_MST); +	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP && +			hdcp->connection.link.dp.mst_supported);  }  static inline uint8_t is_hdmi_dvi_sl_hdcp(struct mod_hdcp *hdcp) @@ -519,7 +519,7 @@ static inline uint8_t get_active_display_count(struct mod_hdcp *hdcp)  	uint8_t i;  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) -		if (is_display_active(&hdcp->connection.displays[i])) +		if (is_display_active(&hdcp->displays[i]))  			added_count++;  	return added_count;  } @@ -530,7 +530,7 @@ static inline uint8_t get_added_display_count(struct mod_hdcp *hdcp)  	uint8_t i;  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) -		if (is_display_added(&hdcp->connection.displays[i])) +		if (is_display_added(&hdcp->displays[i]))  			added_count++;  	return added_count;  } @@ -542,8 +542,8 @@ static inline struct mod_hdcp_display *get_first_added_display(  	struct mod_hdcp_display *display = NULL;  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) -		if (is_display_added(&hdcp->connection.displays[i])) { -			display = &hdcp->connection.displays[i]; +		if (is_display_added(&hdcp->displays[i])) { +			display = &hdcp->displays[i];  			break;  		}  	return display; @@ -556,9 +556,9 @@ static inline struct mod_hdcp_display *get_active_display_at_index(  	struct mod_hdcp_display *display = NULL;  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) -		if (hdcp->connection.displays[i].index == index && -				is_display_active(&hdcp->connection.displays[i])) { -			display = &hdcp->connection.displays[i]; +		if (hdcp->displays[i].index == index && +				is_display_active(&hdcp->displays[i])) { +			display = &hdcp->displays[i];  			break;  		}  	return display; @@ -571,8 +571,8 @@ static inline struct mod_hdcp_display *get_empty_display_container(  	struct mod_hdcp_display *display = NULL;  	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) -		if (!is_display_active(&hdcp->connection.displays[i])) { -			display = &hdcp->connection.displays[i]; +		if (!is_display_active(&hdcp->displays[i])) { +			display = &hdcp->displays[i];  			break;  		}  	return display; 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 76edcbe51f71..f3711914364e 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); @@ -210,7 +208,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,  			fail_and_restart_in_ms(0, &status, output);  			break;  		} else if (input->rx_validation != PASS) { -			if (hdcp->state.stay_count < 2) { +			if (hdcp->state.stay_count < 2 && +					!hdcp->connection.is_hdcp1_revoked) {  				/* allow 2 additional retries */  				callback_in_ms(0, output);  				increment_stay_counter(hdcp); @@ -231,6 +230,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,  				(!conn->is_repeater && is_dp_mst_hdcp(hdcp) && input->stream_encryption_dp != PASS)) {  			fail_and_restart_in_ms(0, &status, output);  			break; +		} else if (conn->hdcp1_retry_count < conn->link.adjust.hdcp1.min_auth_retries_wa) { +			fail_and_restart_in_ms(0, &status, output); +			break;  		}  		if (conn->is_repeater) {  			set_watchdog_in_ms(hdcp, 5000, output); @@ -290,7 +292,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,  			fail_and_restart_in_ms(0, &status, output);  			break;  		} else if (input->ksvlist_vp_validation != PASS) { -			if (hdcp->state.stay_count < 2) { +			if (hdcp->state.stay_count < 2 && +					!hdcp->connection.is_hdcp1_revoked) {  				/* allow 2 additional retries */  				callback_in_ms(0, output);  				increment_stay_counter(hdcp); 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 55246711700b..491c00f48026 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c @@ -34,7 +34,7 @@ static inline enum mod_hdcp_status check_receiver_id_list_ready(struct mod_hdcp  	if (is_dp_hdcp(hdcp))  		is_ready = HDCP_2_2_DP_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus_dp) ? 1 : 0;  	else -		is_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus[0]) && +		is_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus[1]) &&  				(HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |  						hdcp->auth.msg.hdcp2.rxstatus[0])) ? 1 : 0;  	return is_ready ? MOD_HDCP_STATUS_SUCCESS : @@ -67,7 +67,7 @@ static inline enum mod_hdcp_status check_reauthentication_request(  				MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :  				MOD_HDCP_STATUS_SUCCESS;  	else -		ret = HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus[0]) ? +		ret = HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus[1]) ?  				MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :  				MOD_HDCP_STATUS_SUCCESS;  	return ret; @@ -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_ddc.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c index ff9d54812e62..bb5130f4228d 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c @@ -65,6 +65,7 @@ enum mod_hdcp_ddc_message_id {  	MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,  	MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,  	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, +	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,  	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,  	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,  	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, @@ -101,6 +102,7 @@ static const uint8_t hdcp_i2c_offsets[] = {  	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,  	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,  	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80, +	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80,  	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,  	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,  	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80, @@ -135,6 +137,7 @@ static const uint32_t hdcp_dpcd_addrs[] = {  	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,  	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,  	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330, +	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340,  	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,  	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,  	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473, @@ -405,7 +408,7 @@ enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)  	enum mod_hdcp_status status;  	if (is_dp_hdcp(hdcp)) { -		hdcp->auth.msg.hdcp2.ake_cert[0] = 3; +		hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT;  		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,  				hdcp->auth.msg.hdcp2.ake_cert+1,  				sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1); @@ -423,7 +426,7 @@ enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)  	enum mod_hdcp_status status;  	if (is_dp_hdcp(hdcp)) { -		hdcp->auth.msg.hdcp2.ake_h_prime[0] = 7; +		hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME;  		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,  				hdcp->auth.msg.hdcp2.ake_h_prime+1,  				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1); @@ -441,7 +444,7 @@ enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)  	enum mod_hdcp_status status;  	if (is_dp_hdcp(hdcp)) { -		hdcp->auth.msg.hdcp2.ake_pairing_info[0] = 8; +		hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO;  		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,  				hdcp->auth.msg.hdcp2.ake_pairing_info+1,  				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1); @@ -459,7 +462,7 @@ enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)  	enum mod_hdcp_status status;  	if (is_dp_hdcp(hdcp)) { -		hdcp->auth.msg.hdcp2.lc_l_prime[0] = 10; +		hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME;  		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,  				hdcp->auth.msg.hdcp2.lc_l_prime+1,  				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1); @@ -474,14 +477,27 @@ enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)  enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)  { -	enum mod_hdcp_status status; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;  	if (is_dp_hdcp(hdcp)) { -		hdcp->auth.msg.hdcp2.rx_id_list[0] = 12; -		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, -				hdcp->auth.msg.hdcp2.rx_id_list+1, -				sizeof(hdcp->auth.msg.hdcp2.rx_id_list)-1); +		uint32_t device_count = 0; +		uint32_t rx_id_list_size = 0; +		uint32_t bytes_read = 0; +		hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST; +		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, +						hdcp->auth.msg.hdcp2.rx_id_list+1, +						HDCP_MAX_AUX_TRANSACTION_SIZE); +		if (status == MOD_HDCP_STATUS_SUCCESS) { +			bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE; +			device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) + +					(HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4); +			rx_id_list_size = MIN((21 + 5 * device_count), +					(sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1)); +			status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2, +					hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read, +					(rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE); +		}  	} else {  		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,  				hdcp->auth.msg.hdcp2.rx_id_list, @@ -495,7 +511,7 @@ enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)  	enum mod_hdcp_status status;  	if (is_dp_hdcp(hdcp)) { -		hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = 17; +		hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY;  		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,  				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,  				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c index 724ebcee9a19..44956f9ba178 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c @@ -90,10 +90,14 @@ char *mod_hdcp_status_to_str(int32_t status)  		return "MOD_HDCP_STATUS_HDCP1_R0_PRIME_PENDING";  	case MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE:  		return "MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE"; +	case MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED: +		return "MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED";  	case MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY:  		return "MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY";  	case MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE:  		return "MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE"; +	case MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED: +		return "MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED";  	case MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION:  		return "MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION";  	case MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE: 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..d3192b9d0c3d 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h @@ -37,10 +37,11 @@  /* default logs */  #define HDCP_ERROR_TRACE(hdcp, status) \  		HDCP_LOG_ERR(hdcp, \ -			"[Link %d] WARNING %s IN STATE %s", \ +			"[Link %d] WARNING %s IN STATE %s STAY COUNT %d", \  			hdcp->config.index, \  			mod_hdcp_status_to_str(status), \ -			mod_hdcp_state_id_to_str(hdcp->state.id)) +			mod_hdcp_state_id_to_str(hdcp->state.id), \ +			hdcp->state.stay_count)  #define HDCP_HDCP1_ENABLED_TRACE(hdcp, displayIndex) \  		HDCP_LOG_VER(hdcp, \  			"[Link %d] HDCP 1.4 enabled on display %d", \ @@ -49,6 +50,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, \ @@ -102,6 +112,9 @@  				sizeof(hdcp->auth.msg.hdcp1.bksv)); \  		HDCP_DDC_READ_TRACE(hdcp, "BCAPS", &hdcp->auth.msg.hdcp1.bcaps, \  				sizeof(hdcp->auth.msg.hdcp1.bcaps)); \ +		HDCP_DDC_READ_TRACE(hdcp, "BSTATUS", \ +				(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus, \ +				sizeof(hdcp->auth.msg.hdcp1.bstatus)); \  		HDCP_DDC_WRITE_TRACE(hdcp, "AN", hdcp->auth.msg.hdcp1.an, \  				sizeof(hdcp->auth.msg.hdcp1.an)); \  		HDCP_DDC_WRITE_TRACE(hdcp, "AKSV", hdcp->auth.msg.hdcp1.aksv, \ 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 7911dc157d5a..c2929815c3ee 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -44,83 +44,80 @@ 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)); + +	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;  } @@ -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->displays[i])) { +			hdcp->displays[i].state = +					MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; +			HDCP_HDCP1_DISABLED_TRACE(hdcp, +					hdcp->displays[i].index); +		}  	return MOD_HDCP_STATUS_SUCCESS;  } @@ -210,6 +216,10 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp)  	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==  		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) {  		hdcp->connection.is_repeater = 0; +	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status == +		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) { +		hdcp->connection.is_hdcp1_revoked = 1; +		return MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED;  	} else  		return MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE; @@ -245,6 +255,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)  {  	struct psp_context *psp = hdcp->config.psp.handle;  	struct ta_hdcp_shared_memory *hdcp_cmd; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -264,10 +275,19 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)  	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); -	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE; +	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS && +	    hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status == +		    TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) { +		status = MOD_HDCP_STATUS_SUCCESS; +	} else if (hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status == +		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) { +		hdcp->connection.is_hdcp1_revoked = 1; +		status = MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED; +	} else { +		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE; +	} -	return MOD_HDCP_STATUS_SUCCESS; +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp *hdcp) @@ -281,14 +301,14 @@ 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->connection.displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED || -		    hdcp->connection.displays[i].adjust.disable) +		if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED || +		    hdcp->displays[i].adjust.disable)  			continue;  		memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));  		hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.session_handle = hdcp->auth.id; -		hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.display_handle = hdcp->connection.displays[i].index; +		hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;  		hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_DP_STREAM_ENCRYPTION;  		psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); @@ -296,8 +316,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp  		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)  			return MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE; -		hdcp->connection.displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; -		HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->connection.displays[i].index); +		hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; +		HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->displays[i].index);  	}  	return MOD_HDCP_STATUS_SUCCESS; @@ -385,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)); @@ -398,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->displays[i])) { +			hdcp->displays[i].state = +					MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; +			HDCP_HDCP2_DISABLED_TRACE(hdcp, +					hdcp->displays[i].index); +		}  	return MOD_HDCP_STATUS_SUCCESS;  } @@ -473,9 +502,12 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)  		hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;  		hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;  		return MOD_HDCP_STATUS_SUCCESS; +	} else if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { +		hdcp->connection.is_hdcp2_revoked = 1; +		return MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED;  	} -	return MOD_HDCP_STATUS_FAILURE; +	return MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;  }  enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp) @@ -630,20 +662,15 @@ 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 ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct mod_hdcp_display *display = get_first_added_display(hdcp);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); -	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; - -	hdcp2_message_init(hdcp, msg_in); -  	if (!display)  		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; -	hdcp_cmd->in_msg.hdcp1_enable_encryption.session_handle = hdcp->auth.id; +	hdcp_cmd->in_msg.hdcp2_set_encryption.session_handle = hdcp->auth.id;  	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_SET_ENCRYPTION;  	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); @@ -695,6 +722,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)  		hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;  		hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;  		return MOD_HDCP_STATUS_SUCCESS; +	} else if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { +		hdcp->connection.is_hdcp2_revoked = 1; +		return MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED;  	} @@ -717,10 +747,10 @@ 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->connection.displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED || -		    hdcp->connection.displays[i].adjust.disable) +		if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED || +		    hdcp->displays[i].adjust.disable)  			continue; -		hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.display_handle = hdcp->connection.displays[i].index; +		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;  		hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION; @@ -729,8 +759,8 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp  		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)  			break; -		hdcp->connection.displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; -		HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->connection.displays[i].index); +		hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; +		HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->displays[i].index);  	}  	return (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) ? MOD_HDCP_STATUS_SUCCESS diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h index 82a5e997d573..1a663dbbf810 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h @@ -117,6 +117,8 @@ struct ta_dtm_shared_memory {  int psp_cmd_submit_buf(struct psp_context *psp, struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd_resp *cmd,  		uint64_t fence_mc_addr); +enum { PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE = 5120 }; +  enum ta_hdcp_command {  	TA_HDCP_COMMAND__INITIALIZE,  	TA_HDCP_COMMAND__HDCP1_CREATE_SESSION, @@ -134,7 +136,10 @@ enum ta_hdcp_command {  	TA_HDCP_COMMAND__UNUSED_3,  	TA_HDCP_COMMAND__HDCP2_CREATE_SESSION_V2,  	TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2, -	TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION +	TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION, +	TA_HDCP_COMMAND__HDCP_DESTROY_ALL_SESSIONS, +	TA_HDCP_COMMAND__HDCP_SET_SRM, +	TA_HDCP_COMMAND__HDCP_GET_SRM  };  enum ta_hdcp2_msg_id { @@ -235,7 +240,8 @@ enum ta_hdcp_authentication_status {  	TA_HDCP_AUTHENTICATION_STATUS__HDCP22_AUTHENTICATION_PENDING = 0x06,  	TA_HDCP_AUTHENTICATION_STATUS__HDCP22_AUTHENTICATION_FAILED = 0x07,  	TA_HDCP_AUTHENTICATION_STATUS__HDCP22_AUTHENTICATED = 0x08, -	TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_VALIDATION_FAILED = 0x09 +	TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_VALIDATION_FAILED = 0x09, +	TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED = 0x0A  };  enum ta_hdcp2_msg_authentication_status { @@ -253,7 +259,8 @@ enum ta_hdcp2_msg_authentication_status {  	TA_HDCP2_MSG_AUTHENTICATION_STATUS__INVALID_SEQ_NUM,  	TA_HDCP2_MSG_AUTHENTICATION_STATUS__INVALID_SIZE,  	TA_HDCP2_MSG_AUTHENTICATION_STATUS__INVALID_LENGTH, -	TA_HDCP2_MSG_AUTHENTICATION_STATUS__REAUTH_REQUEST +	TA_HDCP2_MSG_AUTHENTICATION_STATUS__REAUTH_REQUEST, +	TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED  };  enum ta_hdcp_content_type { @@ -415,6 +422,22 @@ struct ta_hdcp_cmd_hdcp2_enable_dp_stream_encryption_input {  	uint32_t display_handle;  }; +struct ta_hdcp_cmd_set_srm_input { +	uint32_t srm_buf_size; +	uint8_t srm_buf[PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE]; +}; + +struct ta_hdcp_cmd_set_srm_output { +	uint8_t valid_signature; +	uint32_t srm_version; +}; + +struct ta_hdcp_cmd_get_srm_output { +	uint32_t srm_version; +	uint32_t srm_buf_size; +	uint8_t srm_buf[PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE]; +}; +  /**********************************************************/  /* Common input structure for HDCP callbacks */  union ta_hdcp_cmd_input { @@ -432,6 +455,7 @@ union ta_hdcp_cmd_input {  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2  		hdcp2_prepare_process_authentication_message_v2;  	struct ta_hdcp_cmd_hdcp2_enable_dp_stream_encryption_input hdcp2_enable_dp_stream_encryption; +	struct ta_hdcp_cmd_set_srm_input hdcp_set_srm;  };  /* Common output structure for HDCP callbacks */ @@ -444,6 +468,8 @@ union ta_hdcp_cmd_output {  	struct ta_hdcp_cmd_hdcp2_create_session_output_v2 hdcp2_create_session_v2;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2  		hdcp2_prepare_process_authentication_message_v2; +	struct ta_hdcp_cmd_set_srm_output hdcp_set_srm; +	struct ta_hdcp_cmd_get_srm_output hdcp_get_srm;  };  /**********************************************************/ diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h index f2a0e1a064da..c088602bc1a0 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h @@ -56,8 +56,10 @@ enum mod_hdcp_status {  	MOD_HDCP_STATUS_HDCP1_NOT_CAPABLE,  	MOD_HDCP_STATUS_HDCP1_R0_PRIME_PENDING,  	MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE, +	MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED,  	MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY,  	MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE, +	MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED,  	MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION,  	MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE,  	MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE, @@ -100,6 +102,7 @@ enum mod_hdcp_status {  struct mod_hdcp_displayport {  	uint8_t rev;  	uint8_t assr_supported; +	uint8_t mst_supported;  };  struct mod_hdcp_hdmi { @@ -108,8 +111,7 @@ struct mod_hdcp_hdmi {  enum mod_hdcp_operation_mode {  	MOD_HDCP_MODE_OFF,  	MOD_HDCP_MODE_DEFAULT, -	MOD_HDCP_MODE_DP, -	MOD_HDCP_MODE_DP_MST +	MOD_HDCP_MODE_DP  };  enum mod_hdcp_display_state { @@ -155,7 +157,8 @@ struct mod_hdcp_display_adjustment {  struct mod_hdcp_link_adjustment_hdcp1 {  	uint8_t disable			: 1;  	uint8_t postpone_encryption	: 1; -	uint8_t reserved		: 6; +	uint8_t min_auth_retries_wa : 1; +	uint8_t reserved		: 5;  };  enum mod_hdcp_force_hdcp_type { diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h index 42cbeffac640..13c57ff2abdc 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h @@ -34,8 +34,7 @@ struct dc_info_packet;  struct mod_vrr_params;  void mod_build_vsc_infopacket(const struct dc_stream_state *stream, -		struct dc_info_packet *info_packet, -		bool *use_vsc_sdp_for_colorimetry); +		struct dc_info_packet *info_packet);  void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,  		struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue); diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c index 6a8a056424b8..cff3ab15fc0c 100644 --- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -130,8 +130,7 @@ enum ColorimetryYCCDP {  };  void mod_build_vsc_infopacket(const struct dc_stream_state *stream, -		struct dc_info_packet *info_packet, -		bool *use_vsc_sdp_for_colorimetry) +		struct dc_info_packet *info_packet)  {  	unsigned int vsc_packet_revision = vsc_packet_undefined;  	unsigned int i; @@ -139,11 +138,6 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,  	unsigned int colorimetryFormat = 0;  	bool stereo3dSupport = false; -	/* Initialize first, later if infopacket is valid determine if VSC SDP -	 * should be used to signal colorimetry format and pixel encoding. -	 */ -	*use_vsc_sdp_for_colorimetry = false; -  	if (stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE && stream->view_format != VIEW_3D_FORMAT_NONE) {  		vsc_packet_revision = vsc_packet_rev1;  		stereo3dSupport = true; @@ -153,9 +147,8 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,  	if (stream->psr_version != 0)  		vsc_packet_revision = vsc_packet_rev2; -	/* Update to revision 5 for extended colorimetry support for DPCD 1.4+ */ -	if (stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 && -			stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) +	/* Update to revision 5 for extended colorimetry support */ +	if (stream->use_vsc_sdp_for_colorimetry)  		vsc_packet_revision = vsc_packet_rev5;  	/* VSC packet not needed based on the features @@ -269,13 +262,6 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,  		info_packet->valid = true; -		/* If we are using VSC SDP revision 05h, use this to signal for -		 * colorimetry format and pixel encoding. HW should later be -		 * programmed to set MSA MISC1 bit 6 to indicate ignore -		 * colorimetry format and pixel encoding in the MSA. -		 */ -		*use_vsc_sdp_for_colorimetry = true; -  		/* Set VSC SDP fields for pixel encoding and colorimetry format from DP 1.3 specs  		 * Data Bytes DB 18~16  		 * Bits 3:0 (Colorimetry Format)        |  Bits 7:4 (Pixel Encoding) diff --git a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c index f0a153704f6e..00f132f8ad55 100644 --- a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c +++ b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c @@ -40,14 +40,18 @@ struct core_vmid {  static void add_ptb_to_table(struct core_vmid *core_vmid, unsigned int vmid, uint64_t ptb)  { -	core_vmid->ptb_assigned_to_vmid[vmid] = ptb; -	core_vmid->num_vmids_available--; +	if (vmid < MAX_VMID) { +		core_vmid->ptb_assigned_to_vmid[vmid] = ptb; +		core_vmid->num_vmids_available--; +	}  }  static void clear_entry_from_vmid_table(struct core_vmid *core_vmid, unsigned int vmid)  { -	core_vmid->ptb_assigned_to_vmid[vmid] = 0; -	core_vmid->num_vmids_available++; +	if (vmid < MAX_VMID) { +		core_vmid->ptb_assigned_to_vmid[vmid] = 0; +		core_vmid->num_vmids_available++; +	}  }  static void evict_vmids(struct core_vmid *core_vmid) @@ -57,7 +61,7 @@ static void evict_vmids(struct core_vmid *core_vmid)  	// At this point any positions with value 0 are unused vmids, evict them  	for (i = 1; i < core_vmid->num_vmid; i++) { -		if (ord & (1u << i)) +		if (!(ord & (1u << i)))  			clear_entry_from_vmid_table(core_vmid, i);  	}  } @@ -91,7 +95,7 @@ static int get_next_available_vmid(struct core_vmid *core_vmid)  uint8_t mod_vmid_get_for_ptb(struct mod_vmid *mod_vmid, uint64_t ptb)  {  	struct core_vmid *core_vmid = MOD_VMID_TO_CORE(mod_vmid); -	unsigned int vmid = 0; +	int vmid = 0;  	// Physical address gets vmid 0  	if (ptb == 0) |