[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