Reviewed-by: Rodrigo Siqueira <rodrigo.sique...@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.la...@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@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=02%7C01%7CRodrigo.Siqueira%40amd.com%7Ce8a57ef23ebe48f69c0c08d7d67fbe52%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637213717153022133&amp;sdata=vWM8bqK2w7d24uomK2JRZS9kbYsZPalZVdEb5HA%2F0yM%3D&amp;reserved=0

-- 
Rodrigo Siqueira
https://siqueira.tech

Attachment: signature.asc
Description: PGP signature

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to