summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
diff options
context:
space:
mode:
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)
{