[PATCH 10/23] drm/amd/display: phase3 mst hdcp for multiple displays
Alex Deucher
alexdeucher at gmail.com
Fri Dec 9 21:32:57 UTC 2022
On Fri, Dec 9, 2022 at 11:37 AM jdhillon <jdhillon at amd.com> wrote:
>
> From: hersen wu <hersenxs.wu at amd.com>
>
> [Why]
> multiple display hdcp are enabled within event_property_validate,
> event_property_update by looping all displays on mst hub. when
> one of display on mst hub in unplugged or disabled, hdcp are
> disabled for all displays on mst hub within hdcp_reset_display
> by looping all displays of mst link. for displays still active,
> their encryption status are off. kernel driver will not run hdcp
> authentication again. therefore, hdcp are not enabled automatically.
>
> [How]
> within is_content_protection_different, check drm_crtc_state changes
> of all displays on mst hub, if need, triger hdcp_update_display to
> re-run hdcp authentication.
>
> Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
> Acked-by: Jasdeep Dhillon <jdhillon at amd.com>
> Signed-off-by: hersen wu <hersenxs.wu at amd.com>
> ---
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 118 ++++++++++++------
> 1 file changed, 81 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 7affe0899418..dc23801de071 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -7374,27 +7374,55 @@ is_scaling_state_different(const struct dm_connector_state *dm_state,
> }
>
> #ifdef CONFIG_DRM_AMD_DC_HDCP
> -static bool is_content_protection_different(struct drm_connector_state *state,
> - const struct drm_connector_state *old_state,
> - const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w)
> +static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state,
> + struct drm_crtc_state *old_crtc_state,
> + struct drm_connector_state *new_conn_state,
> + struct drm_connector_state *old_conn_state,
> + const struct drm_connector *connector,
> + struct hdcp_workqueue *hdcp_w)
> {
> struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
> struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
>
> - /* Handle: Type0/1 change */
> - 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;
> + pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n",
> + connector->index, connector->status, connector->dpms);
> + pr_debug("[HDCP_DM] state protection old: %x new: %x\n",
> + old_conn_state->content_protection, new_conn_state->content_protection);
> +
> + if (old_crtc_state)
> + pr_debug("[HDCP_DM] old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
> + old_crtc_state->enable,
> + old_crtc_state->active,
> + old_crtc_state->mode_changed,
> + old_crtc_state->active_changed,
> + old_crtc_state->connectors_changed);
> +
> + if (new_crtc_state)
> + pr_debug("[HDCP_DM] NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
> + new_crtc_state->enable,
> + new_crtc_state->active,
> + new_crtc_state->mode_changed,
> + new_crtc_state->active_changed,
> + new_crtc_state->connectors_changed);
> +
> + /* hdcp content type change */
> + if (old_conn_state->hdcp_content_type != new_conn_state->hdcp_content_type &&
> + new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> + pr_debug("[HDCP_DM] Type0/1 change %s :true\n", __func__);
> return true;
> }
>
> - /* CP is being re enabled, ignore this
> - *
> - * Handles: ENABLED -> DESIRED
> - */
> - if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> - state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
> - state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
> + /* CP is being re enabled, ignore this */
> + if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
> + if (new_crtc_state && new_crtc_state->mode_changed) {
> + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> + pr_debug("[HDCP_DM] ENABLED->DESIRED & mode_changed %s :true\n", __func__);
> + return true;
> + };
> + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
> + pr_debug("[HDCP_DM] ENABLED -> DESIRED %s :false\n", __func__);
> return false;
> }
>
> @@ -7402,9 +7430,9 @@ static bool is_content_protection_different(struct drm_connector_state *state,
> *
> * Handles: UNDESIRED -> ENABLED
> */
> - if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
> - state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
> - state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> + if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
> + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
> + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
>
> /* Stream removed and re-enabled
> *
> @@ -7414,10 +7442,12 @@ static bool is_content_protection_different(struct drm_connector_state *state,
> *
> * Handles: DESIRED -> DESIRED (Special case)
> */
> - if (!(old_state->crtc && old_state->crtc->enabled) &&
> - state->crtc && state->crtc->enabled &&
> + if (!(old_conn_state->crtc && old_conn_state->crtc->enabled) &&
> + new_conn_state->crtc && new_conn_state->crtc->enabled &&
> connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
> dm_con_state->update_hdcp = false;
> + pr_debug("[HDCP_DM] DESIRED->DESIRED (Stream removed and re-enabled) %s :true\n",
> + __func__);
> return true;
> }
>
> @@ -7429,35 +7459,42 @@ static bool is_content_protection_different(struct drm_connector_state *state,
> *
> * Handles: DESIRED -> DESIRED (Special case)
> */
> - if (dm_con_state->update_hdcp && state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
> - connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) {
> + if (dm_con_state->update_hdcp &&
> + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
> + connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) {
> dm_con_state->update_hdcp = false;
> + pr_debug("[HDCP_DM] DESIRED->DESIRED (Hot-plug, headless s3, dpms) %s :true\n",
> + __func__);
> return true;
> }
>
> - /*
> - * Handles: UNDESIRED -> UNDESIRED
> - * DESIRED -> DESIRED
> - * ENABLED -> ENABLED
> - */
> - if (old_state->content_protection == state->content_protection)
> + if (old_conn_state->content_protection == new_conn_state->content_protection) {
> + if (new_conn_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) {
> + if (new_crtc_state && new_crtc_state->mode_changed) {
> + pr_debug("[HDCP_DM] DESIRED->DESIRED or ENABLE->ENABLE mode_change %s :true\n",
> + __func__);
> + return true;
> + };
> + pr_debug("[HDCP_DM] DESIRED->DESIRED & ENABLE->ENABLE %s :false\n",
> + __func__);
> + return false;
> + };
> +
> + pr_debug("[HDCP_DM] UNDESIRED->UNDESIRED %s :false\n", __func__);
> return false;
> + }
>
> - /*
> - * Handles: UNDESIRED -> DESIRED
> - * DESIRED -> UNDESIRED
> - * ENABLED -> UNDESIRED
> - */
> - if (state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED)
> + if (new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> + pr_debug("[HDCP_DM] UNDESIRED->DESIRED or DESIRED->UNDESIRED or ENABLED->UNDESIRED %s :true\n",
> + __func__);
> return true;
> + }
>
> - /*
> - * Handles: DESIRED -> ENABLED
> - */
> + pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__);
> return false;
> }
> -
> #endif
> +
> static void remove_stream(struct amdgpu_device *adev,
> struct amdgpu_crtc *acrtc,
> struct dc_stream_state *stream)
> @@ -8322,6 +8359,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
> new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
> old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
> }
> +<<<<<<< HEAD
> +=======
> +
> +>>>>>>> 667f52144b9a (drm/amd/display: phase3 mst hdcp for multiple displays)
rebasing leftovers.
> if (old_crtc_state)
> pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
> old_crtc_state->enable,
> @@ -8384,7 +8425,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
> DRM_MODE_CONTENT_PROTECTION_DESIRED)
> enable_encryption = true;
>
> +<<<<<<< HEAD
>
> +=======
> +>>>>>>> 667f52144b9a (drm/amd/display: phase3 mst hdcp for multiple displays)
here too.
> if (aconnector->dc_link && aconnector->dc_sink &&
> aconnector->dc_link->type == dc_connection_mst_branch) {
> struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
> --
> 2.34.1
>
More information about the amd-gfx
mailing list