diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules')
17 files changed, 484 insertions, 759 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index cac09d500fda..9431b48aecb4 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -1782,7 +1782,8 @@ rgb_user_alloc_fail:  	return ret;  } -bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, +bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, +		struct dc_transfer_func *input_tf,  		const struct dc_gamma *ramp, bool mapUserRamp)  {  	struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts; @@ -1801,11 +1802,29 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,  	/* we can use hardcoded curve for plain SRGB TF  	 * If linear, it's bypass if on user ramp  	 */ -	if (input_tf->type == TF_TYPE_PREDEFINED && -			(input_tf->tf == TRANSFER_FUNCTION_SRGB || -					input_tf->tf == TRANSFER_FUNCTION_LINEAR) && -					!mapUserRamp) -		return true; +	if (input_tf->type == TF_TYPE_PREDEFINED) { +		if ((input_tf->tf == TRANSFER_FUNCTION_SRGB || +				input_tf->tf == TRANSFER_FUNCTION_LINEAR) && +				!mapUserRamp) +			return true; + +		if (dc_caps != NULL && +			dc_caps->dpp.dcn_arch == 1) { + +			if (input_tf->tf == TRANSFER_FUNCTION_PQ && +					dc_caps->dpp.dgam_rom_caps.pq == 1) +				return true; + +			if (input_tf->tf == TRANSFER_FUNCTION_GAMMA22 && +					dc_caps->dpp.dgam_rom_caps.gamma2_2 == 1) +				return true; + +			// HLG OOTF not accounted for +			if (input_tf->tf == TRANSFER_FUNCTION_HLG && +					dc_caps->dpp.dgam_rom_caps.hlg == 1) +				return true; +		} +	}  	input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; @@ -1902,7 +1921,7 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, -	if (ramp->type == GAMMA_CUSTOM) +	if (ramp && ramp->type == GAMMA_CUSTOM)  		apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);  	ret = true; diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h index 9994817a9a03..7f56226ba77a 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h @@ -30,6 +30,7 @@ struct dc_transfer_func;  struct dc_gamma;  struct dc_transfer_func_distributed_points;  struct dc_rgb_fixed; +struct dc_color_caps;  enum dc_transfer_func_predefined;  /* For SetRegamma ADL interface support @@ -100,7 +101,8 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,  		const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,  		const struct freesync_hdr_tf_params *fs_params); -bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf, +bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, +		struct dc_transfer_func *output_tf,  		const struct dc_gamma *ramp, bool mapUserRamp);  bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index c33454a9e0b4..eb7421e83b86 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -443,7 +443,7 @@ static bool vrr_settings_require_update(struct core_freesync *core_freesync,  		return true;  	} else if (in_vrr->state == VRR_STATE_ACTIVE_FIXED &&  			in_vrr->fixed.target_refresh_in_uhz != -					in_config->min_refresh_in_uhz) { +					in_config->fixed_refresh_in_uhz) {  		return true;  	} else if (in_vrr->min_refresh_in_uhz != min_refresh_in_uhz) {  		return true; @@ -491,7 +491,7 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,  	return false;  } -static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr, +static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr,  		struct dc_info_packet *infopacket)  {  	/* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ @@ -523,14 +523,74 @@ static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr,  			vrr->state == VRR_STATE_ACTIVE_FIXED)  		infopacket->sb[6] |= 0x04; +	// For v1 & 2 infoframes program nominal if non-fs mode, otherwise full range  	/* PB7 = FreeSync Minimum refresh rate (Hz) */ -	infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000); +	if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || +			vrr->state == VRR_STATE_ACTIVE_FIXED) { +		infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000); +	} else { +		infopacket->sb[7] = (unsigned char)((vrr->max_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 + 500000) / 1000000); +	//FreeSync HDR +	infopacket->sb[9] = 0; +	infopacket->sb[10] = 0; +} + +static void build_vrr_infopacket_data_v3(const struct mod_vrr_params *vrr, +		struct dc_info_packet *infopacket) +{ +	/* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ +	infopacket->sb[1] = 0x1A; + +	/* PB2 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 1) */ +	infopacket->sb[2] = 0x00; + +	/* PB3 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 2) */ +	infopacket->sb[3] = 0x00; + +	/* PB4 = Reserved */ + +	/* PB5 = Reserved */ + +	/* PB6 = [Bits 7:3 = Reserved] */ + +	/* PB6 = [Bit 0 = FreeSync Supported] */ +	if (vrr->state != VRR_STATE_UNSUPPORTED) +		infopacket->sb[6] |= 0x01; + +	/* PB6 = [Bit 1 = FreeSync Enabled] */ +	if (vrr->state != VRR_STATE_DISABLED && +			vrr->state != VRR_STATE_UNSUPPORTED) +		infopacket->sb[6] |= 0x02; + +	/* PB6 = [Bit 2 = FreeSync Active] */ +	if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || +			vrr->state == VRR_STATE_ACTIVE_FIXED) +		infopacket->sb[6] |= 0x04; + +	if (vrr->state == VRR_STATE_ACTIVE_FIXED) { +		/* PB7 = FreeSync Minimum refresh rate (Hz) */ +		infopacket->sb[7] = (unsigned char)((vrr->fixed_refresh_in_uhz + 500000) / 1000000); +		/* PB8 = FreeSync Maximum refresh rate (Hz) */ +		infopacket->sb[8] = (unsigned char)((vrr->fixed_refresh_in_uhz + 500000) / 1000000); +	} else if (vrr->state == VRR_STATE_ACTIVE_VARIABLE) { +		/* PB7 = FreeSync Minimum refresh rate (Hz) */ +		infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000); +		/* PB8 = FreeSync Maximum refresh rate (Hz) */ +		infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); +	} else { +		// Non-fs case, program nominal range +		/* PB7 = FreeSync Minimum refresh rate (Hz) */ +		infopacket->sb[7] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); +		/* PB8 = FreeSync Maximum refresh rate (Hz) */ +		infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); +	}  	//FreeSync HDR  	infopacket->sb[9] = 0; @@ -678,7 +738,7 @@ static void build_vrr_infopacket_v1(enum signal_type signal,  	unsigned int payload_size = 0;  	build_vrr_infopacket_header_v1(signal, infopacket, &payload_size); -	build_vrr_infopacket_data(vrr, infopacket); +	build_vrr_infopacket_data_v1(vrr, infopacket);  	build_vrr_infopacket_checksum(&payload_size, infopacket);  	infopacket->valid = true; @@ -692,7 +752,24 @@ static void build_vrr_infopacket_v2(enum signal_type signal,  	unsigned int payload_size = 0;  	build_vrr_infopacket_header_v2(signal, infopacket, &payload_size); -	build_vrr_infopacket_data(vrr, infopacket); +	build_vrr_infopacket_data_v1(vrr, infopacket); + +	build_vrr_infopacket_fs2_data(app_tf, infopacket); + +	build_vrr_infopacket_checksum(&payload_size, infopacket); + +	infopacket->valid = true; +} + +static void build_vrr_infopacket_v3(enum signal_type signal, +		const struct mod_vrr_params *vrr, +		enum color_transfer_func app_tf, +		struct dc_info_packet *infopacket) +{ +	unsigned int payload_size = 0; + +	build_vrr_infopacket_header_v2(signal, infopacket, &payload_size); +	build_vrr_infopacket_data_v3(vrr, infopacket);  	build_vrr_infopacket_fs2_data(app_tf, infopacket); @@ -717,11 +794,14 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,  		return;  	switch (packet_type) { -	case PACKET_TYPE_FS2: +	case PACKET_TYPE_FS_V3: +		build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket); +		break; +	case PACKET_TYPE_FS_V2:  		build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket);  		break;  	case PACKET_TYPE_VRR: -	case PACKET_TYPE_FS1: +	case PACKET_TYPE_FS_V1:  	default:  		build_vrr_infopacket_v1(stream->signal, vrr, infopacket);  	} @@ -793,6 +873,11 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  				calc_duration_in_us_from_refresh_in_uhz(  						(unsigned int)max_refresh_in_uhz); +		if (in_config->state == VRR_STATE_ACTIVE_FIXED) +			in_out_vrr->fixed_refresh_in_uhz = in_config->fixed_refresh_in_uhz; +		else +			in_out_vrr->fixed_refresh_in_uhz = 0; +  		refresh_range = in_out_vrr->max_refresh_in_uhz -  				in_out_vrr->min_refresh_in_uhz; @@ -843,7 +928,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  				in_out_vrr->min_refresh_in_uhz);  	} else if (in_out_vrr->state == VRR_STATE_ACTIVE_FIXED) {  		in_out_vrr->fixed.target_refresh_in_uhz = -				in_out_vrr->min_refresh_in_uhz; +				in_out_vrr->fixed_refresh_in_uhz;  		if (in_out_vrr->fixed.ramping_active &&  				in_out_vrr->fixed.fixed_active) {  			/* Do not update vtotals if ramping is already active diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c index cc1d3f470b99..e9fbd94f8635 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c @@ -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) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h index 5cb4546be0ef..b0cefed2eb02 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h @@ -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); @@ -357,8 +357,6 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(  		struct mod_hdcp *hdcp);  enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(  		struct mod_hdcp *hdcp); -enum mod_hdcp_status mod_hdcp_hdcp2_get_link_encryption_status(struct mod_hdcp *hdcp, -							       enum mod_hdcp_encryption_status *encryption_status);  /* ddc functions */  enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp); @@ -503,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; @@ -515,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; -} - -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; +			active_count++; +	return active_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;  		} 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 37c8c05497d6..f244b72e74e0 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -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;  } 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 491c00f48026..549c113abcf7 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c @@ -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;  } 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 44956f9ba178..fb6a19d020f9 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c @@ -98,8 +98,8 @@ char *mod_hdcp_status_to_str(int32_t status)  		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_ENCRYPTION_FAILURE: +		return "MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE";  	case MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE:  		return "MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE";  	case MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE: @@ -158,8 +158,8 @@ char *mod_hdcp_status_to_str(int32_t status)  		return "MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED";  	case MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY:  		return "MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY"; -	case MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION: -		return "MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION"; +	case MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE: +		return "MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE";  	case MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING:  		return "MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING";  	case MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE: 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 c2929815c3ee..fb1161dd7ea8 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -51,12 +51,15 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(   	struct ta_dtm_shared_memory *dtm_cmd;  	struct mod_hdcp_display *display =  			get_active_display_at_index(hdcp, index); +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;  	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); +  	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));  	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; @@ -66,34 +69,33 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(  	psp_dtm_invoke(psp, dtm_cmd->cmd_id); -	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; +	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; +	} else { +		display->state = MOD_HDCP_DISPLAY_ACTIVE; +		HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); +	} -	display->state = MOD_HDCP_DISPLAY_ACTIVE; -	HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); -  - 	return MOD_HDCP_STATUS_SUCCESS; -  +	mutex_unlock(&psp->dtm_context.mutex); +	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);  	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));  	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; @@ -113,21 +115,24 @@ 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) -		return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; - -	display->state = MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED; -	HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); +	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { +		display->state = MOD_HDCP_DISPLAY_INACTIVE; +		status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; +	} else { +		HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); +	} -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->dtm_context.mutex); +	return status;  }  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;  	if (!psp->hdcp_context.hdcp_initialized) {  		DRM_ERROR("Failed to create hdcp session. HDCP TA is not initialized."); @@ -135,6 +140,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)  	}  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; + +	mutex_lock(&psp->hdcp_context.mutex);  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));  	hdcp_cmd->in_msg.hdcp1_create_session.display_handle = display->index; @@ -144,16 +151,18 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)  	hdcp->auth.id = hdcp_cmd->out_msg.hdcp1_create_session.session_handle; -	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE; - -	hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary; -	memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary, -		sizeof(hdcp->auth.msg.hdcp1.aksv)); -	memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary, -		sizeof(hdcp->auth.msg.hdcp1.an)); +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE; +	} else { +		hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary; +		memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary, +		       sizeof(hdcp->auth.msg.hdcp1.aksv)); +		memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary, +		       sizeof(hdcp->auth.msg.hdcp1.an)); +	} -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp) @@ -162,7 +171,9 @@ 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; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -171,27 +182,30 @@ enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(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_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); -		} +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE; +	} else { +		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; +				HDCP_HDCP1_DISABLED_TRACE( +					hdcp, hdcp->displays[i].index); +			} +	} -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(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; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -206,10 +220,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(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_RX_FAILURE; - -	if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status == +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE; +	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==  	    TA_HDCP_AUTHENTICATION_STATUS__HDCP1_FIRST_PART_COMPLETE) {  		/* needs second part of authentication */  		hdcp->connection.is_repeater = 1; @@ -219,20 +232,22 @@ 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_KSV_REVOKED) {  		hdcp->connection.is_hdcp1_revoked = 1; -		return MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED; +		status = MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED;  	} else -		return MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE; - +		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE; -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  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);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -241,14 +256,15 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(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_ENABLE_ENCRYPTION; - -	if (!is_dp_mst_hdcp(hdcp)) { +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE; +	} else if (!is_dp_mst_hdcp(hdcp)) {  		display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;  		HDCP_HDCP1_ENABLED_TRACE(hdcp, display->index);  	} -	return MOD_HDCP_STATUS_SUCCESS; + +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp) @@ -257,6 +273,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -287,6 +304,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)  		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE;  	} +	mutex_unlock(&psp->hdcp_context.mutex);  	return status;  } @@ -296,14 +314,15 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp  	struct psp_context *psp = hdcp->config.psp.handle;  	struct ta_hdcp_shared_memory *hdcp_cmd;  	int i = 0; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	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)); @@ -313,21 +332,26 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp  		psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); -		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -			return MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE; +		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +			status = MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE; +			break; +		}  		hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;  		HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->displays[i].index);  	} -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(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; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -339,12 +363,12 @@ enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(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_LINK_MAINTENANCE_FAILURE; +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || +			hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level != 1) +		status = MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE; -	return (hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level == 1) -		       ? MOD_HDCP_STATUS_SUCCESS -		       : MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp1_get_link_encryption_status(struct mod_hdcp *hdcp, @@ -364,19 +388,23 @@ 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; +  	if (!psp->hdcp_context.hdcp_initialized) {  		DRM_ERROR("Failed to create hdcp session, HDCP TA is not initialized");  		return MOD_HDCP_STATUS_FAILURE;  	} -	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; -	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); -  	if (!display)  		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; +	mutex_lock(&psp->hdcp_context.mutex); + +	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; +	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); +  	hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index;  	if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0) @@ -393,12 +421,14 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(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_HDCP2_CREATE_SESSION_FAILURE; -	hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle; +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) +		status = MOD_HDCP_STATUS_HDCP2_CREATE_SESSION_FAILURE; +	else +		hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle; -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp) @@ -406,7 +436,9 @@ 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; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -415,20 +447,21 @@ enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(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_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); -		} +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE; +	} else { +		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; +				HDCP_HDCP2_DISABLED_TRACE( +					hdcp, hdcp->displays[i].index); +			} +	} -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp) @@ -437,7 +470,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -452,12 +487,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(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_HDCP2_PREP_AKE_INIT_FAILURE; - -	memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0], -	       sizeof(hdcp->auth.msg.hdcp2.ake_init)); +		status = MOD_HDCP_STATUS_HDCP2_PREP_AKE_INIT_FAILURE; +	else +		memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0], +		       sizeof(hdcp->auth.msg.hdcp2.ake_init)); -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp) @@ -466,7 +502,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -488,26 +526,32 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(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_HDCP2_VALIDATE_AKE_CERT_FAILURE; - -	memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km, &msg_out->prepare.transmitter_message[0], -	       sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)); - -	memcpy(hdcp->auth.msg.hdcp2.ake_stored_km, -	       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)], -	       sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)); - -	if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) { -		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; +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE; +	} else { +		memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km, +		       &msg_out->prepare.transmitter_message[0], +		       sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)); + +		memcpy(hdcp->auth.msg.hdcp2.ake_stored_km, +		       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)], +		       sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)); + +		if (msg_out->process.msg1_status == +		    TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) { +			hdcp->connection.is_km_stored = +				msg_out->process.is_km_stored ? 1 : 0; +			hdcp->connection.is_repeater = +				msg_out->process.is_repeater ? 1 : 0; +			status = MOD_HDCP_STATUS_SUCCESS; +		} else if (msg_out->process.msg1_status == +			   TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { +			hdcp->connection.is_hdcp2_revoked = 1; +			status = MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED; +		}  	} - -	return MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp) @@ -516,7 +560,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -543,16 +589,15 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(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_HDCP2_VALIDATE_H_PRIME_FAILURE; - -	if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE; +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE; +	else if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;  	else if (!hdcp->connection.is_km_stored && -		 msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE; - +		   msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE; -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp) @@ -561,7 +606,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -577,12 +624,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(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_HDCP2_PREP_LC_INIT_FAILURE; - -	memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0], -	       sizeof(hdcp->auth.msg.hdcp2.lc_init)); +		status = MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE; +	else +		memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0], +		       sizeof(hdcp->auth.msg.hdcp2.lc_init)); -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp) @@ -591,7 +639,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -610,13 +660,12 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(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_HDCP2_VALIDATE_L_PRIME_FAILURE; - -	if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE; +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || +			msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE; -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp) @@ -625,7 +674,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -642,48 +693,55 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)  	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;  	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); -	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE; - -	memcpy(hdcp->auth.msg.hdcp2.ske_eks, &msg_out->prepare.transmitter_message[0], -	       sizeof(hdcp->auth.msg.hdcp2.ske_eks)); -	msg_out->prepare.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.ske_eks); - -	if (is_dp_hdcp(hdcp)) { -		memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp, -		       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)], -		       sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)); +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE; +	} else { +		memcpy(hdcp->auth.msg.hdcp2.ske_eks, +		       &msg_out->prepare.transmitter_message[0], +		       sizeof(hdcp->auth.msg.hdcp2.ske_eks)); +		msg_out->prepare.msg1_desc.msg_size = +			sizeof(hdcp->auth.msg.hdcp2.ske_eks); + +		if (is_dp_hdcp(hdcp)) { +			memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp, +			       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)], +			       sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)); +		}  	} +	mutex_unlock(&psp->hdcp_context.mutex); -	return MOD_HDCP_STATUS_SUCCESS; +	return status;  }  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); - -	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; -	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); +	struct mod_hdcp_display *display = get_first_active_display(hdcp); +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;  	if (!display)  		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; +	mutex_lock(&psp->hdcp_context.mutex); + +	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; +	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); +  	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); -	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE; - -	if (!is_dp_mst_hdcp(hdcp)) { +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE; +	} else if (!is_dp_mst_hdcp(hdcp)) {  		display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;  		HDCP_HDCP2_ENABLED_TRACE(hdcp, display->index);  	} -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp) @@ -692,6 +750,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; + +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -712,23 +773,26 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(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_HDCP2_VALIDATE_RX_ID_LIST_FAILURE; - -	memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack, &msg_out->prepare.transmitter_message[0], -	       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)); - -	if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) { -		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; +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE; +	} else { +		memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack, +		       &msg_out->prepare.transmitter_message[0], +		       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)); + +		if (msg_out->process.msg1_status == +		    TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) { +			hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0; +			hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0; +			status = MOD_HDCP_STATUS_SUCCESS; +		} else if (msg_out->process.msg1_status == +			   TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { +			hdcp->connection.is_hdcp2_revoked = 1; +			status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED; +		}  	} - - -	return MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp *hdcp) @@ -737,7 +801,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	uint8_t i; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -747,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; @@ -763,8 +829,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp  		HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->displays[i].index);  	} -	return (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) ? MOD_HDCP_STATUS_SUCCESS -								  : MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION; +	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) +		status = MOD_HDCP_STATUS_SUCCESS; +	else +		status = MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE; + +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *hdcp) @@ -774,7 +845,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *h  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -789,15 +862,17 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *h  	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;  	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); -	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE; - -	hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size; - -	memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage, &msg_out->prepare.transmitter_message[0], -	       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage)); +	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { +		status = MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE; +	} else { +		hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size; -	return MOD_HDCP_STATUS_SUCCESS; +		memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage, +		       &msg_out->prepare.transmitter_message[0], +		       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage)); +	} +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  }  enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp) @@ -806,7 +881,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)  	struct ta_hdcp_shared_memory *hdcp_cmd;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;  	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; +	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; +	mutex_lock(&psp->hdcp_context.mutex);  	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;  	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); @@ -825,38 +902,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)  	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;  	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); -	return (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) && -			       (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) -		       ? MOD_HDCP_STATUS_SUCCESS -		       : MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE; -} - -enum mod_hdcp_status mod_hdcp_hdcp2_get_link_encryption_status(struct mod_hdcp *hdcp, -							       enum mod_hdcp_encryption_status *encryption_status) -{ -	struct psp_context *psp = hdcp->config.psp.handle; -	struct ta_hdcp_shared_memory *hdcp_cmd; - -	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf; - -	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); - -	hdcp_cmd->in_msg.hdcp2_get_encryption_status.session_handle = hdcp->auth.id; -	hdcp_cmd->out_msg.hdcp2_get_encryption_status.protection_level = 0; -	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_GET_ENCRYPTION_STATUS; -	*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; - -	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id); - -	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) -		return MOD_HDCP_STATUS_FAILURE; - -	if (hdcp_cmd->out_msg.hdcp2_get_encryption_status.protection_level == 1) { -		if (hdcp_cmd->out_msg.hdcp2_get_encryption_status.hdcp2_type == TA_HDCP2_CONTENT_TYPE__TYPE1) -			*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON; -		else -			*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON; -	} +	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS && +	    msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) +		status = MOD_HDCP_STATUS_SUCCESS; +	else +		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE; -	return MOD_HDCP_STATUS_SUCCESS; +	mutex_unlock(&psp->hdcp_context.mutex); +	return status;  } + diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h index dbe7835aabcf..0ba3cf7f336a 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h @@ -83,6 +83,8 @@ struct mod_freesync_config {  	bool btr;  	unsigned int min_refresh_in_uhz;  	unsigned int max_refresh_in_uhz; +	unsigned int fixed_refresh_in_uhz; +  };  struct mod_vrr_params_btr { @@ -112,6 +114,7 @@ struct mod_vrr_params {  	uint32_t max_duration_in_us;  	uint32_t max_refresh_in_uhz;  	uint32_t min_duration_in_us; +	uint32_t fixed_refresh_in_uhz;  	struct dc_crtc_timing_adjust adjust; 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 c088602bc1a0..eed560eecbab 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h @@ -60,7 +60,7 @@ enum mod_hdcp_status {  	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_ENCRYPTION_FAILURE,  	MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE,  	MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE,  	MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE, @@ -90,7 +90,7 @@ enum mod_hdcp_status {  	MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY,  	MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE,  	MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED, -	MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION, +	MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE,  	MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING,  	MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE,  	MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE, @@ -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  }; diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h b/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h index fe2117904329..198c0e64d13a 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h @@ -40,8 +40,9 @@ enum color_transfer_func {  enum vrr_packet_type {  	PACKET_TYPE_VRR, -	PACKET_TYPE_FS1, -	PACKET_TYPE_FS2, +	PACKET_TYPE_FS_V1, +	PACKET_TYPE_FS_V2, +	PACKET_TYPE_FS_V3,  	PACKET_TYPE_VTEM  }; 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 cff3ab15fc0c..7cd8a43d1889 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 @@ -144,7 +144,7 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,  	}  	/*VSC packet set to 2 when DP revision >= 1.2*/ -	if (stream->psr_version != 0) +	if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)  		vsc_packet_revision = vsc_packet_rev2;  	/* Update to revision 5 for extended colorimetry support */ diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index e75a4bb94488..8c37bcc27132 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -24,6 +24,9 @@  #include "power_helpers.h"  #include "dc/inc/hw/dmcu.h" +#include "dc/inc/hw/abm.h" +#include "dc.h" +#include "core_types.h"  #define DIV_ROUNDUP(a, b) (((a)+((b)/2))/(b)) @@ -237,7 +240,7 @@ static void fill_backlight_transform_table(struct dmcu_iram_parameters params,  }  static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters params, -		struct iram_table_v_2_2 *table) +		struct iram_table_v_2_2 *table, bool big_endian)  {  	unsigned int i;  	unsigned int num_entries = NUM_BL_CURVE_SEGS; @@ -261,10 +264,12 @@ static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters par  		lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1);  		ASSERT(lut_index < params.backlight_lut_array_size); -		table->backlight_thresholds[i] = -			cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)); -		table->backlight_offsets[i] = -			cpu_to_be16(params.backlight_lut_array[lut_index]); +		table->backlight_thresholds[i] = (big_endian) ? +			cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)) : +			cpu_to_le16(DIV_ROUNDUP((i * 65536), num_entries)); +		table->backlight_offsets[i] = (big_endian) ? +			cpu_to_be16(params.backlight_lut_array[lut_index]) : +			cpu_to_le16(params.backlight_lut_array[lut_index]);  	}  } @@ -584,18 +589,18 @@ void fill_iram_v_2_2(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parame  	ram_table->crgb_slope[7]  = cpu_to_be16(0x1910);  	fill_backlight_transform_table_v_2_2( -			params, ram_table); +			params, ram_table, true);  } -void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params) +void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params, bool big_endian)  {  	unsigned int i, j;  	unsigned int set = params.set;  	ram_table->flags = 0x0; - -	ram_table->min_abm_backlight = -			cpu_to_be16(params.min_abm_backlight); +	ram_table->min_abm_backlight = (big_endian) ? +		cpu_to_be16(params.min_abm_backlight) : +		cpu_to_le16(params.min_abm_backlight);  	for (i = 0; i < NUM_AGGR_LEVEL; i++) {  		ram_table->hybrid_factor[i] = abm_settings[set][i].brightness_gain; @@ -619,33 +624,51 @@ void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parame  	ram_table->iir_curve[4] = 0x65;  	//Gamma 2.2 -	ram_table->crgb_thresh[0] = cpu_to_be16(0x127c); -	ram_table->crgb_thresh[1] = cpu_to_be16(0x151b); -	ram_table->crgb_thresh[2] = cpu_to_be16(0x17d5); -	ram_table->crgb_thresh[3] = cpu_to_be16(0x1a56); -	ram_table->crgb_thresh[4] = cpu_to_be16(0x1c83); -	ram_table->crgb_thresh[5] = cpu_to_be16(0x1e72); -	ram_table->crgb_thresh[6] = cpu_to_be16(0x20f0); -	ram_table->crgb_thresh[7] = cpu_to_be16(0x232b); -	ram_table->crgb_offset[0] = cpu_to_be16(0x2999); -	ram_table->crgb_offset[1] = cpu_to_be16(0x3999); -	ram_table->crgb_offset[2] = cpu_to_be16(0x4666); -	ram_table->crgb_offset[3] = cpu_to_be16(0x5999); -	ram_table->crgb_offset[4] = cpu_to_be16(0x6333); -	ram_table->crgb_offset[5] = cpu_to_be16(0x7800); -	ram_table->crgb_offset[6] = cpu_to_be16(0x8c00); -	ram_table->crgb_offset[7] = cpu_to_be16(0xa000); -	ram_table->crgb_slope[0]  = cpu_to_be16(0x3609); -	ram_table->crgb_slope[1]  = cpu_to_be16(0x2dfa); -	ram_table->crgb_slope[2]  = cpu_to_be16(0x27ea); -	ram_table->crgb_slope[3]  = cpu_to_be16(0x235d); -	ram_table->crgb_slope[4]  = cpu_to_be16(0x2042); -	ram_table->crgb_slope[5]  = cpu_to_be16(0x1dc3); -	ram_table->crgb_slope[6]  = cpu_to_be16(0x1b1a); -	ram_table->crgb_slope[7]  = cpu_to_be16(0x1910); +	ram_table->crgb_thresh[0] = (big_endian) ? cpu_to_be16(0x127c) : cpu_to_le16(0x127c); +	ram_table->crgb_thresh[1] = (big_endian) ? cpu_to_be16(0x151b) : cpu_to_le16(0x151b); +	ram_table->crgb_thresh[2] = (big_endian) ? cpu_to_be16(0x17d5) : cpu_to_le16(0x17d5); +	ram_table->crgb_thresh[3] = (big_endian) ? cpu_to_be16(0x1a56) : cpu_to_le16(0x1a56); +	ram_table->crgb_thresh[4] = (big_endian) ? cpu_to_be16(0x1c83) : cpu_to_le16(0x1c83); +	ram_table->crgb_thresh[5] = (big_endian) ? cpu_to_be16(0x1e72) : cpu_to_le16(0x1e72); +	ram_table->crgb_thresh[6] = (big_endian) ? cpu_to_be16(0x20f0) : cpu_to_le16(0x20f0); +	ram_table->crgb_thresh[7] = (big_endian) ? cpu_to_be16(0x232b) : cpu_to_le16(0x232b); +	ram_table->crgb_offset[0] = (big_endian) ? cpu_to_be16(0x2999) : cpu_to_le16(0x2999); +	ram_table->crgb_offset[1] = (big_endian) ? cpu_to_be16(0x3999) : cpu_to_le16(0x3999); +	ram_table->crgb_offset[2] = (big_endian) ? cpu_to_be16(0x4666) : cpu_to_le16(0x4666); +	ram_table->crgb_offset[3] = (big_endian) ? cpu_to_be16(0x5999) : cpu_to_le16(0x5999); +	ram_table->crgb_offset[4] = (big_endian) ? cpu_to_be16(0x6333) : cpu_to_le16(0x6333); +	ram_table->crgb_offset[5] = (big_endian) ? cpu_to_be16(0x7800) : cpu_to_le16(0x7800); +	ram_table->crgb_offset[6] = (big_endian) ? cpu_to_be16(0x8c00) : cpu_to_le16(0x8c00); +	ram_table->crgb_offset[7] = (big_endian) ? cpu_to_be16(0xa000) : cpu_to_le16(0xa000); +	ram_table->crgb_slope[0]  = (big_endian) ? cpu_to_be16(0x3609) : cpu_to_le16(0x3609); +	ram_table->crgb_slope[1]  = (big_endian) ? cpu_to_be16(0x2dfa) : cpu_to_le16(0x2dfa); +	ram_table->crgb_slope[2]  = (big_endian) ? cpu_to_be16(0x27ea) : cpu_to_le16(0x27ea); +	ram_table->crgb_slope[3]  = (big_endian) ? cpu_to_be16(0x235d) : cpu_to_le16(0x235d); +	ram_table->crgb_slope[4]  = (big_endian) ? cpu_to_be16(0x2042) : cpu_to_le16(0x2042); +	ram_table->crgb_slope[5]  = (big_endian) ? cpu_to_be16(0x1dc3) : cpu_to_le16(0x1dc3); +	ram_table->crgb_slope[6]  = (big_endian) ? cpu_to_be16(0x1b1a) : cpu_to_le16(0x1b1a); +	ram_table->crgb_slope[7]  = (big_endian) ? cpu_to_be16(0x1910) : cpu_to_le16(0x1910);  	fill_backlight_transform_table_v_2_2( -			params, ram_table); +			params, ram_table, big_endian); +} + +bool dmub_init_abm_config(struct abm *abm, +	struct dmcu_iram_parameters params) +{ +	unsigned char ram_table[IRAM_SIZE]; +	bool result = false; + +	if (abm == NULL) +		return false; + +	memset(&ram_table, 0, sizeof(ram_table)); + +	fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, false); +	result = abm->funcs->init_abm_config( +		abm, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); + +	return result;  }  bool dmcu_load_iram(struct dmcu *dmcu, @@ -657,17 +680,17 @@ bool dmcu_load_iram(struct dmcu *dmcu,  	if (dmcu == NULL)  		return false; -	if (!dmcu->funcs->is_dmcu_initialized(dmcu)) +	if (dmcu && !dmcu->funcs->is_dmcu_initialized(dmcu))  		return true;  	memset(&ram_table, 0, sizeof(ram_table));  	if (dmcu->dmcu_version.abm_version == 0x24) { -		fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params); -		result = dmcu->funcs->load_iram( -				dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); +		fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true); +			result = dmcu->funcs->load_iram( +					dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);  	} else if (dmcu->dmcu_version.abm_version == 0x23) { -		fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params); +		fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true);  		result = dmcu->funcs->load_iram(  				dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h index e54157026330..46fbca2e2cd1 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h @@ -26,6 +26,7 @@  #define MODULES_POWER_POWER_HELPERS_H_  #include "dc/inc/hw/dmcu.h" +#include "dc/inc/hw/abm.h"  enum abm_defines { @@ -44,5 +45,7 @@ struct dmcu_iram_parameters {  bool dmcu_load_iram(struct dmcu *dmcu,  		struct dmcu_iram_parameters params); +bool dmub_init_abm_config(struct abm *abm, +		struct dmcu_iram_parameters params);  #endif /* MODULES_POWER_POWER_HELPERS_H_ */ diff --git a/drivers/gpu/drm/amd/display/modules/stats/stats.c b/drivers/gpu/drm/amd/display/modules/stats/stats.c deleted file mode 100644 index 03121ca64fe4..000000000000 --- a/drivers/gpu/drm/amd/display/modules/stats/stats.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright 2016 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#include "mod_stats.h" -#include "dm_services.h" -#include "dc.h" -#include "core_types.h" - -#define DAL_STATS_ENABLE_REGKEY			"DalStatsEnable" -#define DAL_STATS_ENABLE_REGKEY_DEFAULT		0x00000000 -#define DAL_STATS_ENABLE_REGKEY_ENABLED		0x00000001 - -#define DAL_STATS_ENTRIES_REGKEY		"DalStatsEntries" -#define DAL_STATS_ENTRIES_REGKEY_DEFAULT	0x00350000 -#define DAL_STATS_ENTRIES_REGKEY_MAX		0x01000000 - -#define DAL_STATS_EVENT_ENTRIES_DEFAULT		0x00000100 - -#define MOD_STATS_NUM_VSYNCS			5 -#define MOD_STATS_EVENT_STRING_MAX		512 - -struct stats_time_cache { -	unsigned int entry_id; - -	unsigned long flip_timestamp_in_ns; -	unsigned long vupdate_timestamp_in_ns; - -	unsigned int render_time_in_us; -	unsigned int avg_render_time_in_us_last_ten; -	unsigned int v_sync_time_in_us[MOD_STATS_NUM_VSYNCS]; -	unsigned int num_vsync_between_flips; - -	unsigned int flip_to_vsync_time_in_us; -	unsigned int vsync_to_flip_time_in_us; - -	unsigned int min_window; -	unsigned int max_window; -	unsigned int v_total_min; -	unsigned int v_total_max; -	unsigned int event_triggers; - -	unsigned int lfc_mid_point_in_us; -	unsigned int num_frames_inserted; -	unsigned int inserted_duration_in_us; - -	unsigned int flags; -}; - -struct stats_event_cache { -	unsigned int entry_id; -	char event_string[MOD_STATS_EVENT_STRING_MAX]; -}; - -struct core_stats { -	struct mod_stats public; -	struct dc *dc; - -	bool enabled; -	unsigned int entries; -	unsigned int event_entries; -	unsigned int entry_id; - -	struct stats_time_cache *time; -	unsigned int index; - -	struct stats_event_cache *events; -	unsigned int event_index; - -}; - -#define MOD_STATS_TO_CORE(mod_stats)\ -		container_of(mod_stats, struct core_stats, public) - -bool mod_stats_init(struct mod_stats *mod_stats) -{ -	bool result = false; -	struct core_stats *core_stats = NULL; -	struct dc *dc = NULL; - -	if (mod_stats == NULL) -		return false; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); -	dc = core_stats->dc; - -	return result; -} - -struct mod_stats *mod_stats_create(struct dc *dc) -{ -	struct core_stats *core_stats = NULL; -	struct persistent_data_flag flag; -	unsigned int reg_data; -	int i = 0; - -	if (dc == NULL) -		goto fail_construct; - -	core_stats = kzalloc(sizeof(struct core_stats), GFP_KERNEL); - -	if (core_stats == NULL) -		goto fail_construct; - -	core_stats->dc = dc; - -	core_stats->enabled = DAL_STATS_ENABLE_REGKEY_DEFAULT; -	if (dm_read_persistent_data(dc->ctx, NULL, NULL, -			DAL_STATS_ENABLE_REGKEY, -			®_data, sizeof(unsigned int), &flag)) -		core_stats->enabled = reg_data; - -	if (core_stats->enabled) { -		core_stats->entries = DAL_STATS_ENTRIES_REGKEY_DEFAULT; -		if (dm_read_persistent_data(dc->ctx, NULL, NULL, -				DAL_STATS_ENTRIES_REGKEY, -				®_data, sizeof(unsigned int), &flag)) { -			if (reg_data > DAL_STATS_ENTRIES_REGKEY_MAX) -				core_stats->entries = DAL_STATS_ENTRIES_REGKEY_MAX; -			else -				core_stats->entries = reg_data; -		} -		core_stats->time = kcalloc(core_stats->entries, -						sizeof(struct stats_time_cache), -						GFP_KERNEL); - -		if (core_stats->time == NULL) -			goto fail_construct_time; - -		core_stats->event_entries = DAL_STATS_EVENT_ENTRIES_DEFAULT; -		core_stats->events = kcalloc(core_stats->event_entries, -					     sizeof(struct stats_event_cache), -					     GFP_KERNEL); - -		if (core_stats->events == NULL) -			goto fail_construct_events; - -	} else { -		core_stats->entries = 0; -	} - -	/* Purposely leave index 0 unused so we don't need special logic to -	 * handle calculation cases that depend on previous flip data. -	 */ -	core_stats->index = 1; -	core_stats->event_index = 0; - -	// Keeps track of ordering within the different stats structures -	core_stats->entry_id = 0; - -	return &core_stats->public; - -fail_construct_events: -	kfree(core_stats->time); - -fail_construct_time: -	kfree(core_stats); - -fail_construct: -	return NULL; -} - -void mod_stats_destroy(struct mod_stats *mod_stats) -{ -	if (mod_stats != NULL) { -		struct core_stats *core_stats = MOD_STATS_TO_CORE(mod_stats); - -		kfree(core_stats->time); -		kfree(core_stats->events); -		kfree(core_stats); -	} -} - -void mod_stats_dump(struct mod_stats *mod_stats) -{ -	struct dc  *dc = NULL; -	struct dal_logger *logger = NULL; -	struct core_stats *core_stats = NULL; -	struct stats_time_cache *time = NULL; -	struct stats_event_cache *events = NULL; -	unsigned int time_index = 1; -	unsigned int event_index = 0; -	unsigned int index = 0; -	struct log_entry log_entry; - -	if (mod_stats == NULL) -		return; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); -	dc = core_stats->dc; -	logger = dc->ctx->logger; -	time = core_stats->time; -	events = core_stats->events; - -	DISPLAY_STATS_BEGIN(log_entry); - -	DISPLAY_STATS("==Display Caps==\n"); - -	DISPLAY_STATS("==Display Stats==\n"); - -	DISPLAY_STATS("%10s %10s %10s %10s %10s" -			" %11s %11s %17s %10s %14s" -			" %10s %10s %10s %10s %10s" -			" %10s %10s %10s %10s\n", -		"render", "avgRender", -		"minWindow", "midPoint", "maxWindow", -		"vsyncToFlip", "flipToVsync", "vsyncsBetweenFlip", -		"numFrame", "insertDuration", -		"vTotalMin", "vTotalMax", "eventTrigs", -		"vSyncTime1", "vSyncTime2", "vSyncTime3", -		"vSyncTime4", "vSyncTime5", "flags"); - -	for (int i = 0; i < core_stats->entry_id; i++) { -		if (event_index < core_stats->event_index && -				i == events[event_index].entry_id) { -			DISPLAY_STATS("==Event==%s\n", events[event_index].event_string); -			event_index++; -		} else if (time_index < core_stats->index && -				i == time[time_index].entry_id) { -			DISPLAY_STATS("%10u %10u %10u %10u %10u" -					" %11u %11u %17u %10u %14u" -					" %10u %10u %10u %10u %10u" -					" %10u %10u %10u %10u\n", -				time[time_index].render_time_in_us, -				time[time_index].avg_render_time_in_us_last_ten, -				time[time_index].min_window, -				time[time_index].lfc_mid_point_in_us, -				time[time_index].max_window, -				time[time_index].vsync_to_flip_time_in_us, -				time[time_index].flip_to_vsync_time_in_us, -				time[time_index].num_vsync_between_flips, -				time[time_index].num_frames_inserted, -				time[time_index].inserted_duration_in_us, -				time[time_index].v_total_min, -				time[time_index].v_total_max, -				time[time_index].event_triggers, -				time[time_index].v_sync_time_in_us[0], -				time[time_index].v_sync_time_in_us[1], -				time[time_index].v_sync_time_in_us[2], -				time[time_index].v_sync_time_in_us[3], -				time[time_index].v_sync_time_in_us[4], -				time[time_index].flags); - -			time_index++; -		} -	} - -	DISPLAY_STATS_END(log_entry); -} - -void mod_stats_reset_data(struct mod_stats *mod_stats) -{ -	struct core_stats *core_stats = NULL; -	struct stats_time_cache *time = NULL; -	unsigned int index = 0; - -	if (mod_stats == NULL) -		return; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); - -	memset(core_stats->time, 0, -		sizeof(struct stats_time_cache) * core_stats->entries); - -	memset(core_stats->events, 0, -		sizeof(struct stats_event_cache) * core_stats->event_entries); - -	core_stats->index = 1; -	core_stats->event_index = 0; - -	// Keeps track of ordering within the different stats structures -	core_stats->entry_id = 0; -} - -void mod_stats_update_event(struct mod_stats *mod_stats, -		char *event_string, -		unsigned int length) -{ -	struct core_stats *core_stats = NULL; -	struct stats_event_cache *events = NULL; -	unsigned int index = 0; -	unsigned int copy_length = 0; - -	if (mod_stats == NULL) -		return; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); - -	if (core_stats->event_index >= core_stats->event_entries) -		return; - -	events = core_stats->events; -	index = core_stats->event_index; - -	copy_length = length; -	if (length > MOD_STATS_EVENT_STRING_MAX) -		copy_length = MOD_STATS_EVENT_STRING_MAX; - -	memcpy(&events[index].event_string, event_string, copy_length); -	events[index].event_string[copy_length - 1] = '\0'; - -	events[index].entry_id = core_stats->entry_id; -	core_stats->event_index++; -	core_stats->entry_id++; -} - -void mod_stats_update_flip(struct mod_stats *mod_stats, -		unsigned long timestamp_in_ns) -{ -	struct core_stats *core_stats = NULL; -	struct stats_time_cache *time = NULL; -	unsigned int index = 0; - -	if (mod_stats == NULL) -		return; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); - -	if (core_stats->index >= core_stats->entries) -		return; - -	time = core_stats->time; -	index = core_stats->index; - -	time[index].flip_timestamp_in_ns = timestamp_in_ns; -	time[index].render_time_in_us = -		(timestamp_in_ns - time[index - 1].flip_timestamp_in_ns) / 1000; - -	if (index >= 10) { -		for (unsigned int i = 0; i < 10; i++) -			time[index].avg_render_time_in_us_last_ten += -					time[index - i].render_time_in_us; -		time[index].avg_render_time_in_us_last_ten /= 10; -	} - -	if (time[index].num_vsync_between_flips > 0) -		time[index].vsync_to_flip_time_in_us = -			(timestamp_in_ns - -				time[index].vupdate_timestamp_in_ns) / 1000; -	else -		time[index].vsync_to_flip_time_in_us = -			(timestamp_in_ns - -				time[index - 1].vupdate_timestamp_in_ns) / 1000; - -	time[index].entry_id = core_stats->entry_id; -	core_stats->index++; -	core_stats->entry_id++; -} - -void mod_stats_update_vupdate(struct mod_stats *mod_stats, -		unsigned long timestamp_in_ns) -{ -	struct core_stats *core_stats = NULL; -	struct stats_time_cache *time = NULL; -	unsigned int index = 0; -	unsigned int num_vsyncs = 0; -	unsigned int prev_vsync_in_ns = 0; - -	if (mod_stats == NULL) -		return; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); - -	if (core_stats->index >= core_stats->entries) -		return; - -	time = core_stats->time; -	index = core_stats->index; -	num_vsyncs = time[index].num_vsync_between_flips; - -	if (num_vsyncs < MOD_STATS_NUM_VSYNCS) { -		if (num_vsyncs == 0) { -			prev_vsync_in_ns = -				time[index - 1].vupdate_timestamp_in_ns; - -			time[index].flip_to_vsync_time_in_us = -				(timestamp_in_ns - -					time[index - 1].flip_timestamp_in_ns) / -					1000; -		} else { -			prev_vsync_in_ns = -				time[index].vupdate_timestamp_in_ns; -		} - -		time[index].v_sync_time_in_us[num_vsyncs] = -			(timestamp_in_ns - prev_vsync_in_ns) / 1000; -	} - -	time[index].vupdate_timestamp_in_ns = timestamp_in_ns; -	time[index].num_vsync_between_flips++; -} - -void mod_stats_update_freesync(struct mod_stats *mod_stats, -		unsigned int v_total_min, -		unsigned int v_total_max, -		unsigned int event_triggers, -		unsigned int window_min, -		unsigned int window_max, -		unsigned int lfc_mid_point_in_us, -		unsigned int inserted_frames, -		unsigned int inserted_duration_in_us) -{ -	struct core_stats *core_stats = NULL; -	struct stats_time_cache *time = NULL; -	unsigned int index = 0; - -	if (mod_stats == NULL) -		return; - -	core_stats = MOD_STATS_TO_CORE(mod_stats); - -	if (core_stats->index >= core_stats->entries) -		return; - -	time = core_stats->time; -	index = core_stats->index; - -	time[index].v_total_min = v_total_min; -	time[index].v_total_max = v_total_max; -	time[index].event_triggers = event_triggers; -	time[index].min_window = window_min; -	time[index].max_window = window_max; -	time[index].lfc_mid_point_in_us = lfc_mid_point_in_us; -	time[index].num_frames_inserted = inserted_frames; -	time[index].inserted_duration_in_us = inserted_duration_in_us; -} - diff --git a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c index 00f132f8ad55..61ee4be35d27 100644 --- a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c +++ b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c @@ -112,9 +112,12 @@ uint8_t mod_vmid_get_for_ptb(struct mod_vmid *mod_vmid, uint64_t ptb)  			evict_vmids(core_vmid);  		vmid = get_next_available_vmid(core_vmid); -		add_ptb_to_table(core_vmid, vmid, ptb); +		if (vmid != -1) { +			add_ptb_to_table(core_vmid, vmid, ptb); -		dc_setup_vm_context(core_vmid->dc, &va_config, vmid); +			dc_setup_vm_context(core_vmid->dc, &va_config, vmid); +		} else +			ASSERT(0);  	}  	return vmid;  |