[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