[PATCH 1/2] drm/amd/display: query hdcp capability during link detect

Rodrigo Siqueira Rodrigo.Siqueira at amd.com
Tue Apr 7 01:16:33 UTC 2020


Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira at amd.com>

On 04/01, Bhawanpreet Lakha wrote:
> [Why]
> Query the hdcp caps of a link, it is useful and can be reported to the user
> 
> [How]
> Create a query function and call it during link detect
> 
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 56 ++++++++++++
>  drivers/gpu/drm/amd/display/dc/dc.h           | 41 +++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  3 +
>  .../gpu/drm/amd/display/dc/hdcp/hdcp_msg.c    | 89 +++++++++++++++++++
>  .../gpu/drm/amd/display/include/hdcp_types.h  |  7 ++
>  5 files changed, 196 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index a93997ff0419..49c63e27dfe9 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -514,6 +514,50 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin
>  	link->local_sink = prev_sink;
>  }
>  
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
> +{
> +	struct hdcp_protection_message msg22;
> +	struct hdcp_protection_message msg14;
> +
> +	memset(&msg22, 0, sizeof(struct hdcp_protection_message));
> +	memset(&msg14, 0, sizeof(struct hdcp_protection_message));
> +	memset(link->hdcp_caps.rx_caps.raw, 0,
> +		sizeof(link->hdcp_caps.rx_caps.raw));
> +
> +	if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
> +			link->ddc->transaction_type ==
> +			DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
> +			link->connector_signal == SIGNAL_TYPE_EDP) {
> +		msg22.data = link->hdcp_caps.rx_caps.raw;
> +		msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
> +		msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
> +	} else {
> +		msg22.data = &link->hdcp_caps.rx_caps.fields.version;
> +		msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
> +		msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
> +	}
> +	msg22.version = HDCP_VERSION_22;
> +	msg22.link = HDCP_LINK_PRIMARY;
> +	msg22.max_retries = 5;
> +	dc_process_hdcp_msg(signal, link, &msg22);
> +
> +	if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
> +		enum hdcp_message_status status = HDCP_MESSAGE_UNSUPPORTED;
> +
> +		msg14.data = &link->hdcp_caps.bcaps.raw;
> +		msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
> +		msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
> +		msg14.version = HDCP_VERSION_14;
> +		msg14.link = HDCP_LINK_PRIMARY;
> +		msg14.max_retries = 5;
> +
> +		status = dc_process_hdcp_msg(signal, link, &msg14);
> +	}
> +
> +}
> +#endif
> +
>  static void read_current_link_settings_on_detect(struct dc_link *link)
>  {
>  	union lane_count_set lane_count_set = { {0} };
> @@ -606,6 +650,12 @@ static bool detect_dp(struct dc_link *link,
>  			dal_ddc_service_set_transaction_type(link->ddc,
>  							     sink_caps->transaction_type);
>  
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +			/* In case of fallback to SST when topology discovery below fails
> +			 * HDCP caps will be querried again later by the upper layer (caller
> +			 * of this function). */
> +			query_hdcp_capability(SIGNAL_TYPE_DISPLAY_PORT_MST, link);
> +#endif
>  			/*
>  			 * This call will initiate MST topology discovery. Which
>  			 * will detect MST ports and add new DRM connector DRM
> @@ -975,6 +1025,9 @@ static bool dc_link_detect_helper(struct dc_link *link,
>  			 * TODO debug why Dell 2413 doesn't like
>  			 *  two link trainings
>  			 */
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +			query_hdcp_capability(sink->sink_signal, link);
> +#endif
>  
>  			// verify link cap for SST non-seamless boot
>  			if (!perform_dp_seamless_boot)
> @@ -988,6 +1041,9 @@ static bool dc_link_detect_helper(struct dc_link *link,
>  				sink = prev_sink;
>  				prev_sink = NULL;
>  			}
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +			query_hdcp_capability(sink->sink_signal, link);
> +#endif
>  		}
>  
>  		/* HDMI-DVI Dongle */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
> index 92123b0d1196..9235d04c32dc 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -29,6 +29,9 @@
>  #include "dc_types.h"
>  #include "grph_object_defs.h"
>  #include "logger_types.h"
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +#include "hdcp_types.h"
> +#endif
>  #include "gpio_types.h"
>  #include "link_service_types.h"
>  #include "grph_object_ctrl_defs.h"
> @@ -1004,6 +1007,35 @@ union dpcd_sink_ext_caps {
>  	uint8_t raw;
>  };
>  
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +union hdcp_rx_caps {
> +	struct {
> +		uint8_t version;
> +		uint8_t reserved;
> +		struct {
> +			uint8_t repeater	: 1;
> +			uint8_t hdcp_capable	: 1;
> +			uint8_t reserved	: 6;
> +		} byte0;
> +	} fields;
> +	uint8_t raw[3];
> +};
> +
> +union hdcp_bcaps {
> +	struct {
> +		uint8_t HDCP_CAPABLE:1;
> +		uint8_t REPEATER:1;
> +		uint8_t RESERVED:6;
> +	} bits;
> +	uint8_t raw;
> +};
> +
> +struct hdcp_caps {
> +	union hdcp_rx_caps rx_caps;
> +	union hdcp_bcaps bcaps;
> +};
> +#endif
> +
>  #include "dc_link.h"
>  
>  /*******************************************************************************
> @@ -1107,6 +1139,15 @@ void dc_resume(struct dc *dc);
>  unsigned int dc_get_current_backlight_pwm(struct dc *dc);
>  unsigned int dc_get_target_backlight_pwm(struct dc *dc);
>  
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +/*
> + * HDCP Interfaces
> + */
> +enum hdcp_message_status dc_process_hdcp_msg(
> +		enum signal_type signal,
> +		struct dc_link *link,
> +		struct hdcp_protection_message *message_info);
> +#endif
>  bool dc_is_dmcu_initialized(struct dc *dc);
>  
>  enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping);
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index 00ff5e98278c..0077f9dcd07c 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -126,6 +126,9 @@ struct dc_link {
>  	uint32_t dongle_max_pix_clk;
>  	unsigned short chip_caps;
>  	unsigned int dpcd_sink_count;
> +#if defined(CONFIG_DRM_AMD_DC_HDCP)
> +	struct hdcp_caps hdcp_caps;
> +#endif
>  	enum edp_revision edp_revision;
>  	bool psr_feature_enabled;
>  	bool psr_allow_active;
> diff --git a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
> index 6f730b5bfe42..5e384a8a83dc 100644
> --- a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
> +++ b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
> @@ -322,3 +322,92 @@ static const struct protection_properties dp_11_protection = {
>  	.process_transaction = dp_11_process_transaction
>  };
>  
> +static const struct protection_properties *get_protection_properties_by_signal(
> +	struct dc_link *link,
> +	enum signal_type st,
> +	enum hdcp_version version)
> +{
> +	switch (version) {
> +	case HDCP_VERSION_14:
> +		switch (st) {
> +		case SIGNAL_TYPE_DVI_SINGLE_LINK:
> +		case SIGNAL_TYPE_DVI_DUAL_LINK:
> +		case SIGNAL_TYPE_HDMI_TYPE_A:
> +			return &hdmi_14_protection;
> +		case SIGNAL_TYPE_DISPLAY_PORT:
> +			if (link &&
> +				(link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
> +				link->dpcd_caps.dongle_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER)) {
> +				return &non_supported_protection;
> +			}
> +			return &dp_11_protection;
> +		case SIGNAL_TYPE_DISPLAY_PORT_MST:
> +		case SIGNAL_TYPE_EDP:
> +			return &dp_11_protection;
> +		default:
> +			return &non_supported_protection;
> +		}
> +		break;
> +	case HDCP_VERSION_22:
> +		switch (st) {
> +		case SIGNAL_TYPE_DVI_SINGLE_LINK:
> +		case SIGNAL_TYPE_DVI_DUAL_LINK:
> +		case SIGNAL_TYPE_HDMI_TYPE_A:
> +			return &hdmi_14_protection; //todo version2.2
> +		case SIGNAL_TYPE_DISPLAY_PORT:
> +		case SIGNAL_TYPE_DISPLAY_PORT_MST:
> +		case SIGNAL_TYPE_EDP:
> +			return &dp_11_protection;  //todo version2.2
> +		default:
> +			return &non_supported_protection;
> +		}
> +		break;
> +	default:
> +		return &non_supported_protection;
> +	}
> +}
> +
> +enum hdcp_message_status dc_process_hdcp_msg(
> +	enum signal_type signal,
> +	struct dc_link *link,
> +	struct hdcp_protection_message *message_info)
> +{
> +	enum hdcp_message_status status = HDCP_MESSAGE_FAILURE;
> +	uint32_t i = 0;
> +
> +	const struct protection_properties *protection_props;
> +
> +	if (!message_info)
> +		return HDCP_MESSAGE_UNSUPPORTED;
> +
> +	if (message_info->msg_id < HDCP_MESSAGE_ID_READ_BKSV ||
> +		message_info->msg_id >= HDCP_MESSAGE_ID_MAX)
> +		return HDCP_MESSAGE_UNSUPPORTED;
> +
> +	protection_props =
> +		get_protection_properties_by_signal(
> +			link,
> +			signal,
> +			message_info->version);
> +
> +	if (!protection_props->supported)
> +		return HDCP_MESSAGE_UNSUPPORTED;
> +
> +	if (protection_props->process_transaction(
> +		link,
> +		message_info)) {
> +		status = HDCP_MESSAGE_SUCCESS;
> +	} else {
> +		for (i = 0; i < message_info->max_retries; i++) {
> +			if (protection_props->process_transaction(
> +						link,
> +						message_info)) {
> +				status = HDCP_MESSAGE_SUCCESS;
> +				break;
> +			}
> +		}
> +	}
> +
> +	return status;
> +}
> +
> diff --git a/drivers/gpu/drm/amd/display/include/hdcp_types.h b/drivers/gpu/drm/amd/display/include/hdcp_types.h
> index f31e6befc8d6..42229b4effdc 100644
> --- a/drivers/gpu/drm/amd/display/include/hdcp_types.h
> +++ b/drivers/gpu/drm/amd/display/include/hdcp_types.h
> @@ -83,6 +83,12 @@ enum hdcp_link {
>  	HDCP_LINK_SECONDARY
>  };
>  
> +enum hdcp_message_status {
> +	HDCP_MESSAGE_SUCCESS,
> +	HDCP_MESSAGE_FAILURE,
> +	HDCP_MESSAGE_UNSUPPORTED
> +};
> +
>  struct hdcp_protection_message {
>  	enum hdcp_version version;
>  	/* relevant only for DVI */
> @@ -91,6 +97,7 @@ struct hdcp_protection_message {
>  	uint32_t length;
>  	uint8_t max_retries;
>  	uint8_t *data;
> +	enum hdcp_message_status status;
>  };
>  
>  #endif
> -- 
> 2.17.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=02%7C01%7CRodrigo.Siqueira%40amd.com%7Ce8a57ef23ebe48f69c0c08d7d67fbe52%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637213717153022133&sdata=vWM8bqK2w7d24uomK2JRZS9kbYsZPalZVdEb5HA%2F0yM%3D&reserved=0

-- 
Rodrigo Siqueira
https://siqueira.tech
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/amd-gfx/attachments/20200406/73db6ab3/attachment.sig>


More information about the amd-gfx mailing list