From: Bhawanpreet Lakha Date: Mon, 24 Feb 2020 19:55:53 +0000 (-0500) Subject: drm/amd/display: add HDCP caps debugfs X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5f8693796c06ded7d88bf1d9009cdc406e31f3b1;p=uclinux-h8%2Flinux.git drm/amd/display: add HDCP caps debugfs Add debugfs to get HDCP capability. This is also useful for kms_content_protection igt test. Use: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability Signed-off-by: Bhawanpreet Lakha Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 0461fecd68db..4b695f6a80c6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -838,6 +838,44 @@ static int vrr_range_show(struct seq_file *m, void *data) return 0; } +#ifdef CONFIG_DRM_AMD_DC_HDCP +/* + * Returns the HDCP capability of the Display (1.4 for now). + * + * NOTE* Not all HDMI displays report their HDCP caps even when they are capable. + * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable. + * + * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability + * or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability + */ +static int hdcp_sink_capability_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + bool hdcp_cap, hdcp2_cap; + + if (connector->status != connector_status_connected) + return -ENODEV; + + seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id); + + hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link); + hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link); + + + if (hdcp_cap) + seq_printf(m, "%s ", "HDCP1.4"); + if (hdcp2_cap) + seq_printf(m, "%s ", "HDCP2.2"); + + if (!hdcp_cap && !hdcp2_cap) + seq_printf(m, "%s ", "None"); + + seq_puts(m, "\n"); + + return 0; +} +#endif /* function description * * generic SDP message access for testing @@ -964,6 +1002,9 @@ DEFINE_SHOW_ATTRIBUTE(dmub_fw_state); DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer); DEFINE_SHOW_ATTRIBUTE(output_bpc); DEFINE_SHOW_ATTRIBUTE(vrr_range); +#ifdef CONFIG_DRM_AMD_DC_HDCP +DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability); +#endif static const struct file_operations dp_link_settings_debugfs_fops = { .owner = THIS_MODULE, @@ -1019,12 +1060,23 @@ static const struct { {"test_pattern", &dp_phy_test_pattern_fops}, {"output_bpc", &output_bpc_fops}, {"vrr_range", &vrr_range_fops}, +#ifdef CONFIG_DRM_AMD_DC_HDCP + {"hdcp_sink_capability", &hdcp_sink_capability_fops}, +#endif {"sdp_message", &sdp_message_fops}, {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops}, {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops}, {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops} }; +#ifdef CONFIG_DRM_AMD_DC_HDCP +static const struct { + char *name; + const struct file_operations *fops; +} hdmi_debugfs_entries[] = { + {"hdcp_sink_capability", &hdcp_sink_capability_fops} +}; +#endif /* * Force YUV420 output if available from the given mode */ @@ -1093,6 +1145,15 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) connector->debugfs_dpcd_address = 0; connector->debugfs_dpcd_size = 0; +#ifdef CONFIG_DRM_AMD_DC_HDCP + if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) { + for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) { + debugfs_create_file(hdmi_debugfs_entries[i].name, + 0644, dir, connector, + hdmi_debugfs_entries[i].fops); + } + } +#endif } /* 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 75caa36ef85b..00f70e43ed76 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -516,6 +516,53 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin } #if defined(CONFIG_DRM_AMD_DC_HDCP) +bool dc_link_is_hdcp14(struct dc_link *link) +{ + bool ret = false; + + switch (link->connector_signal) { + case SIGNAL_TYPE_DISPLAY_PORT: + case SIGNAL_TYPE_DISPLAY_PORT_MST: + ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE; + break; + case SIGNAL_TYPE_DVI_SINGLE_LINK: + case SIGNAL_TYPE_DVI_DUAL_LINK: + case SIGNAL_TYPE_HDMI_TYPE_A: + /* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable, + * we can poll for bksv but some displays have an issue with this. Since its so rare + * for a display to not be 1.4 capable, this assumtion is ok + */ + ret = true; + break; + default: + break; + } + return ret; +} + +bool dc_link_is_hdcp22(struct dc_link *link) +{ + bool ret = false; + + switch (link->connector_signal) { + case SIGNAL_TYPE_DISPLAY_PORT: + case SIGNAL_TYPE_DISPLAY_PORT_MST: + ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE && + link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable && + (link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0; + break; + case SIGNAL_TYPE_DVI_SINGLE_LINK: + case SIGNAL_TYPE_DVI_DUAL_LINK: + case SIGNAL_TYPE_HDMI_TYPE_A: + ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0; + break; + default: + break; + } + + return ret; +} + static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) { struct hdcp_protection_message msg22; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 0077f9dcd07c..e131dc99f283 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -293,6 +293,10 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type); * DPCD access interfaces */ +#ifdef CONFIG_DRM_AMD_DC_HDCP +bool dc_link_is_hdcp14(struct dc_link *link); +bool dc_link_is_hdcp22(struct dc_link *link); +#endif void dc_link_set_drive_settings(struct dc *dc, struct link_training_settings *lt_settings, const struct dc_link *link);