aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
diff options
context:
space:
mode:
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2021-05-19 12:37:16 -0400
committerAlex Deucher <alexander.deucher@amd.com>2021-06-04 16:39:18 -0400
commitbf62221e9d0e1e4ba50ab2b331a0008c15de97be (patch)
tree74a12b8a2ac3ee32fecede6819fb1f65651d3272 /drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
parentdrm/amd/display: Add DCN3.1 PANEL (diff)
downloadlinux-dev-bf62221e9d0e1e4ba50ab2b331a0008c15de97be.tar.xz
linux-dev-bf62221e9d0e1e4ba50ab2b331a0008c15de97be.zip
drm/amd/display: Add DCN3.1 HDCP support
New DTM interface is V3 and we need to extend our existing support to enable HDCP on DCN3.1. Version the helpers and fallback to the older versions on failure in the new interfaces. Acked-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c')
-rw-r--r--drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c135
1 files changed, 132 insertions, 3 deletions
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 06910d2fd57a..fc88fe249a50 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -44,11 +44,16 @@ static void hdcp2_message_init(struct mod_hdcp *hdcp,
in->process.msg3_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;
in->process.msg3_desc.msg_size = 0;
}
+#if defined(CONFIG_DRM_AMD_DC_DCN3_1)
+static enum mod_hdcp_status mod_hdcp_remove_display_from_topology_v2(
+ struct mod_hdcp *hdcp, uint8_t index)
+#else
enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
struct mod_hdcp *hdcp, uint8_t index)
- {
- struct psp_context *psp = hdcp->config.psp.handle;
- struct ta_dtm_shared_memory *dtm_cmd;
+#endif
+{
+ 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);
enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
@@ -79,8 +84,66 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
mutex_unlock(&psp->dtm_context.mutex);
return status;
}
+#if defined(CONFIG_DRM_AMD_DC_DCN3_1)
+static enum mod_hdcp_status mod_hdcp_remove_display_from_topology_v3(
+ struct mod_hdcp *hdcp, uint8_t index)
+{
+ 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);
+ 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_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_V3;
+ dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index;
+ dtm_cmd->dtm_in_message.topology_update_v3.is_active = 0;
+ dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
+
+ psp_dtm_invoke(psp, dtm_cmd->cmd_id);
+
+ if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
+ status = mod_hdcp_remove_display_from_topology_v2(hdcp, index);
+ if (status != MOD_HDCP_STATUS_SUCCESS)
+ display->state = MOD_HDCP_DISPLAY_INACTIVE;
+ } else {
+ display->state = MOD_HDCP_DISPLAY_ACTIVE;
+ HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
+ }
+
+ mutex_unlock(&psp->dtm_context.mutex);
+
+ return status;
+}
+
+enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
+ struct mod_hdcp *hdcp, uint8_t index)
+{
+ enum mod_hdcp_status status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
+
+ if (hdcp->config.psp.caps.dtm_v3_supported)
+ status = mod_hdcp_remove_display_from_topology_v3(hdcp, index);
+ else
+ status = mod_hdcp_remove_display_from_topology_v2(hdcp, index);
+
+ return status;
+}
+#endif
+#if defined(CONFIG_DRM_AMD_DC_DCN3_1)
+static enum mod_hdcp_status mod_hdcp_add_display_to_topology_v2(
+ struct mod_hdcp *hdcp, struct mod_hdcp_display *display)
+#else
enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
struct mod_hdcp_display *display)
+#endif
{
struct psp_context *psp = hdcp->config.psp.handle;
struct ta_dtm_shared_memory *dtm_cmd;
@@ -126,6 +189,72 @@ enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
return status;
}
+#if defined(CONFIG_DRM_AMD_DC_DCN3_1)
+static enum mod_hdcp_status mod_hdcp_add_display_to_topology_v3(
+ struct mod_hdcp *hdcp, struct mod_hdcp_display *display)
+{
+ struct psp_context *psp = hdcp->config.psp.handle;
+ struct ta_dtm_shared_memory *dtm_cmd;
+ struct mod_hdcp_link *link = &hdcp->connection.link;
+ enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+
+ if (!psp->dtm_context.dtm_initialized) {
+ DRM_INFO("Failed to add display topology, DTM TA is not initialized.");
+ display->state = MOD_HDCP_DISPLAY_INACTIVE;
+ return MOD_HDCP_STATUS_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_V3;
+ dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index;
+ dtm_cmd->dtm_in_message.topology_update_v3.is_active = 1;
+ dtm_cmd->dtm_in_message.topology_update_v3.controller = display->controller;
+ dtm_cmd->dtm_in_message.topology_update_v3.ddc_line = link->ddc_line;
+ dtm_cmd->dtm_in_message.topology_update_v3.link_enc = link->link_enc_idx;
+ dtm_cmd->dtm_in_message.topology_update_v3.stream_enc = display->stream_enc_idx;
+ if (is_dp_hdcp(hdcp))
+ dtm_cmd->dtm_in_message.topology_update_v3.is_assr = link->dp.assr_enabled;
+
+ dtm_cmd->dtm_in_message.topology_update_v3.dp_mst_vcid = display->vc_id;
+ dtm_cmd->dtm_in_message.topology_update_v3.max_hdcp_supported_version =
+ TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_3;
+ dtm_cmd->dtm_in_message.topology_update_v3.encoder_type = TA_DTM_ENCODER_TYPE__DIG;
+ dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
+ dtm_cmd->dtm_in_message.topology_update_v3.phy_id = link->phy_idx;
+ dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational;
+
+ psp_dtm_invoke(psp, dtm_cmd->cmd_id);
+
+ if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
+ status = mod_hdcp_add_display_to_topology_v2(hdcp, display);
+ if (status != MOD_HDCP_STATUS_SUCCESS)
+ display->state = MOD_HDCP_DISPLAY_INACTIVE;
+ } else {
+ HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);
+ }
+
+ mutex_unlock(&psp->dtm_context.mutex);
+
+ return status;
+}
+
+enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
+ struct mod_hdcp_display *display)
+{
+ enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+
+ if (hdcp->config.psp.caps.dtm_v3_supported)
+ status = mod_hdcp_add_display_to_topology_v3(hdcp, display);
+ else
+ status = mod_hdcp_add_display_to_topology_v2(hdcp, display);
+
+ return status;
+}
+#endif
enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)
{