drm/amd/display: Handle hdcp2.2 type0/1 in dm
[Why] HDCP 2.2 uses type0 and type1 content type. This is passed to the receiver to stream the proper content. For example, in a MST case if the main device is HDCP2.2 capable but the secondary device is only 1.4 capabale we can use Type0 Type0 content: use HDCP 1.4 or HDCP2.2 type0 Type1 content: Only use HDCP 2.2 type1 [How] We use the "hdcp content type" property in drm. We use the disable_type1 flag in hdcp module to select the type based on the properties. For updating the property we use the same logic as 1.4, but now we consider content_type as well and update the property if the requirements are met Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
da283469e0
commit
53e108aa99
|
@ -43,6 +43,7 @@
|
|||
#include "amdgpu_dm.h"
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
#include "amdgpu_dm_hdcp.h"
|
||||
#include <drm/drm_hdcp.h>
|
||||
#endif
|
||||
#include "amdgpu_pm.h"
|
||||
|
||||
|
@ -5581,7 +5582,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
|
|||
&aconnector->base);
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (adev->asic_type >= CHIP_RAVEN)
|
||||
drm_connector_attach_content_protection_property(&aconnector->base, false);
|
||||
drm_connector_attach_content_protection_property(&aconnector->base, true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -5832,6 +5833,12 @@ static bool is_content_protection_different(struct drm_connector_state *state,
|
|||
{
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
||||
if (old_state->hdcp_content_type != state->hdcp_content_type &&
|
||||
state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
|
||||
state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* CP is being re enabled, ignore this */
|
||||
if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
|
||||
state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
|
@ -5864,11 +5871,14 @@ static void update_content_protection(struct drm_connector_state *state, const s
|
|||
struct hdcp_workqueue *hdcp_w)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
bool disable_type1 = state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 ? true : false;
|
||||
|
||||
if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED)
|
||||
hdcp_add_display(hdcp_w, aconnector->dc_link->link_index, aconnector);
|
||||
else if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
|
||||
if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
hdcp_reset_display(hdcp_w, aconnector->dc_link->link_index);
|
||||
hdcp_add_display(hdcp_w, aconnector->dc_link->link_index, aconnector, disable_type1);
|
||||
} else if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
|
||||
hdcp_remove_display(hdcp_w, aconnector->dc_link->link_index, aconnector->base.index);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,8 @@ static void process_output(struct hdcp_workqueue *hdcp_work)
|
|||
|
||||
}
|
||||
|
||||
void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, struct amdgpu_dm_connector *aconnector)
|
||||
void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, struct amdgpu_dm_connector *aconnector,
|
||||
bool disable_type1)
|
||||
{
|
||||
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
||||
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
|
||||
|
@ -96,6 +97,8 @@ void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index,
|
|||
mutex_lock(&hdcp_w->mutex);
|
||||
hdcp_w->aconnector = aconnector;
|
||||
|
||||
hdcp_w->link.adjust.hdcp2.disable_type1 = disable_type1;
|
||||
|
||||
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
|
||||
|
||||
schedule_delayed_work(&hdcp_w->property_validate_dwork, msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
|
||||
|
@ -190,10 +193,16 @@ static void event_property_update(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
if (hdcp_work->encryption_status != MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF)
|
||||
drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
|
||||
else
|
||||
if (hdcp_work->encryption_status != MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF) {
|
||||
if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 &&
|
||||
hdcp_work->encryption_status <= MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON)
|
||||
drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
|
||||
else if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE1 &&
|
||||
hdcp_work->encryption_status == MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON)
|
||||
drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
|
||||
} else {
|
||||
drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_DESIRED);
|
||||
}
|
||||
|
||||
|
||||
mutex_unlock(&hdcp_work->mutex);
|
||||
|
|
|
@ -54,8 +54,8 @@ struct hdcp_workqueue {
|
|||
uint8_t max_link;
|
||||
};
|
||||
|
||||
void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index,
|
||||
struct amdgpu_dm_connector *aconnector);
|
||||
void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, struct amdgpu_dm_connector *aconnector,
|
||||
bool disable_type1);
|
||||
void hdcp_remove_display(struct hdcp_workqueue *work, unsigned int link_index, unsigned int display_index);
|
||||
void hdcp_reset_display(struct hdcp_workqueue *work, unsigned int link_index);
|
||||
void hdcp_handle_cpirq(struct hdcp_workqueue *work, unsigned int link_index);
|
||||
|
|
|
@ -417,7 +417,10 @@ enum mod_hdcp_status mod_hdcp_query_display(struct mod_hdcp *hdcp,
|
|||
query->trace = &hdcp->connection.trace;
|
||||
query->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
|
||||
|
||||
mod_hdcp_hdcp1_get_link_encryption_status(hdcp, &query->encryption_status);
|
||||
if (is_hdcp1(hdcp))
|
||||
mod_hdcp_hdcp1_get_link_encryption_status(hdcp, &query->encryption_status);
|
||||
else if (is_hdcp2(hdcp))
|
||||
mod_hdcp_hdcp2_get_link_encryption_status(hdcp, &query->encryption_status);
|
||||
|
||||
out:
|
||||
return status;
|
||||
|
|
Loading…
Reference in New Issue