[PATCH 2/2] drm/amd/display: Fix for otg synchronization logic

Alex Deucher alexdeucher at gmail.com
Wed Jan 12 15:53:47 UTC 2022


On Wed, Jan 12, 2022 at 9:28 AM Harry Wentland <harry.wentland at amd.com> wrote:
>
> From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram at amd.com>
>
> [Why]
> During otg sync trigger, plane states are used to decide whether the otg
> is already synchronized or not. There are scenarions when otgs are
> disabled without plane state getting disabled and in such case the otg is
> excluded from synchronization.
>
> [How]
> Introduced pipe_idx_syncd in pipe_ctx that tracks each otgs master pipe.
> When a otg is disabled/enabled, pipe_idx_syncd is reset to itself.
> On sync trigger, pipe_idx_syncd is checked to decide whether a otg is
> already synchronized and the otg is further included or excluded from
> synchronization.
>
> v2:
>   Don't drop is_blanked logic
>
> Reviewed-by: Jun Lei <Jun.Lei at amd.com>
> Reviewed-by: Mustapha Ghaddar <mustapha.ghaddar at amd.com>
> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
> Signed-off-by: meenakshikumar somasundaram <meenakshikumar.somasundaram at amd.com>
> Tested-by: Daniel Wheeler <daniel.wheeler at amd.com>
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
> Cc: torvalds at linux-foundation.org

Series is:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      | 40 +++++++++-----
>  .../gpu/drm/amd/display/dc/core/dc_resource.c | 54 +++++++++++++++++++
>  drivers/gpu/drm/amd/display/dc/dc.h           |  1 +
>  .../display/dc/dce110/dce110_hw_sequencer.c   |  8 +++
>  .../drm/amd/display/dc/dcn31/dcn31_resource.c |  3 ++
>  .../gpu/drm/amd/display/dc/inc/core_types.h   |  1 +
>  drivers/gpu/drm/amd/display/dc/inc/resource.h | 11 ++++
>  7 files changed, 105 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 01c8849b9db2..6f5528d34093 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -1404,20 +1404,34 @@ static void program_timing_sync(
>                                 status->timing_sync_info.master = false;
>
>                 }
> -               /* remove any other unblanked pipes as they have already been synced */
> -               for (j = j + 1; j < group_size; j++) {
> -                       bool is_blanked;
>
> -                       if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
> -                               is_blanked =
> -                                       pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
> -                       else
> -                               is_blanked =
> -                                       pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
> -                       if (!is_blanked) {
> -                               group_size--;
> -                               pipe_set[j] = pipe_set[group_size];
> -                               j--;
> +               /* remove any other pipes that are already been synced */
> +               if (dc->config.use_pipe_ctx_sync_logic) {
> +                       /* check pipe's syncd to decide which pipe to be removed */
> +                       for (j = 1; j < group_size; j++) {
> +                               if (pipe_set[j]->pipe_idx_syncd == pipe_set[0]->pipe_idx_syncd) {
> +                                       group_size--;
> +                                       pipe_set[j] = pipe_set[group_size];
> +                                       j--;
> +                               } else
> +                                       /* link slave pipe's syncd with master pipe */
> +                                       pipe_set[j]->pipe_idx_syncd = pipe_set[0]->pipe_idx_syncd;
> +                       }
> +               } else {
> +                       for (j = j + 1; j < group_size; j++) {
> +                               bool is_blanked;
> +
> +                               if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
> +                                       is_blanked =
> +                                               pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
> +                               else
> +                                       is_blanked =
> +                                               pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
> +                               if (!is_blanked) {
> +                                       group_size--;
> +                                       pipe_set[j] = pipe_set[group_size];
> +                                       j--;
> +                               }
>                         }
>                 }
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> index d4ff6cc6b8d9..b3912ff9dc91 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> @@ -3217,6 +3217,60 @@ struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt(
>  }
>  #endif
>
> +void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,
> +               struct dc_state *context)
> +{
> +       int i, j;
> +       struct pipe_ctx *pipe_ctx_old, *pipe_ctx, *pipe_ctx_syncd;
> +
> +       /* If pipe backend is reset, need to reset pipe syncd status */
> +       for (i = 0; i < dc->res_pool->pipe_count; i++) {
> +               pipe_ctx_old =  &dc->current_state->res_ctx.pipe_ctx[i];
> +               pipe_ctx = &context->res_ctx.pipe_ctx[i];
> +
> +               if (!pipe_ctx_old->stream)
> +                       continue;
> +
> +               if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
> +                       continue;
> +
> +               if (!pipe_ctx->stream ||
> +                               pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
> +
> +                       /* Reset all the syncd pipes from the disabled pipe */
> +                       for (j = 0; j < dc->res_pool->pipe_count; j++) {
> +                               pipe_ctx_syncd = &context->res_ctx.pipe_ctx[j];
> +                               if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_syncd) == pipe_ctx_old->pipe_idx) ||
> +                                       !IS_PIPE_SYNCD_VALID(pipe_ctx_syncd))
> +                                       SET_PIPE_SYNCD_TO_PIPE(pipe_ctx_syncd, j);
> +                       }
> +               }
> +       }
> +}
> +
> +void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
> +       struct dc_state *context,
> +       uint8_t disabled_master_pipe_idx)
> +{
> +       int i;
> +       struct pipe_ctx *pipe_ctx, *pipe_ctx_check;
> +
> +       pipe_ctx = &context->res_ctx.pipe_ctx[disabled_master_pipe_idx];
> +       if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx) != disabled_master_pipe_idx) ||
> +               !IS_PIPE_SYNCD_VALID(pipe_ctx))
> +               SET_PIPE_SYNCD_TO_PIPE(pipe_ctx, disabled_master_pipe_idx);
> +
> +       /* for the pipe disabled, check if any slave pipe exists and assert */
> +       for (i = 0; i < dc->res_pool->pipe_count; i++) {
> +               pipe_ctx_check = &context->res_ctx.pipe_ctx[i];
> +
> +               if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_check) == disabled_master_pipe_idx) &&
> +                       IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx))
> +                       DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n",
> +                               i, disabled_master_pipe_idx);
> +       }
> +}
> +
>  uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter)
>  {
>         /* TODO - get transmitter to phy idx mapping from DMUB */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
> index da2c78ce14d6..288e7b01f561 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -344,6 +344,7 @@ struct dc_config {
>         uint8_t  vblank_alignment_max_frame_time_diff;
>         bool is_asymmetric_memory;
>         bool is_single_rank_dimm;
> +       bool use_pipe_ctx_sync_logic;
>  };
>
>  enum visual_confirm {
> diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
> index 78192ecba102..f1593186e964 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
> @@ -1566,6 +1566,10 @@ static enum dc_status apply_single_controller_ctx_to_hw(
>                                 &pipe_ctx->stream->audio_info);
>         }
>
> +       /* make sure no pipes syncd to the pipe being enabled */
> +       if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic)
> +               check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx);
> +
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>         /* DCN3.1 FPGA Workaround
>          * Need to enable HPO DP Stream Encoder before setting OTG master enable.
> @@ -2297,6 +2301,10 @@ enum dc_status dce110_apply_ctx_to_hw(
>         enum dc_status status;
>         int i;
>
> +       /* reset syncd pipes from disabled pipes */
> +       if (dc->config.use_pipe_ctx_sync_logic)
> +               reset_syncd_pipes_from_disabled_pipes(dc, context);
> +
>         /* Reset old context */
>         /* look up the targets that have been removed since last commit */
>         hws->funcs.reset_hw_ctx_wrap(dc, context);
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
> index 1f1c158658ac..40778c05f9b3 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
> @@ -2254,6 +2254,9 @@ static bool dcn31_resource_construct(
>         dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
>         dc->caps.color.mpc.ocsc = 1;
>
> +       /* Use pipe context based otg sync logic */
> +       dc->config.use_pipe_ctx_sync_logic = true;
> +
>         /* read VBIOS LTTPR caps */
>         {
>                 if (ctx->dc_bios->funcs->get_lttpr_caps) {
> diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> index 890280026e69..943240e2809e 100644
> --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> @@ -382,6 +382,7 @@ struct pipe_ctx {
>         struct pll_settings pll_settings;
>
>         uint8_t pipe_idx;
> +       uint8_t pipe_idx_syncd;
>
>         struct pipe_ctx *top_pipe;
>         struct pipe_ctx *bottom_pipe;
> diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
> index 4249bf306e09..dbfe6690ded8 100644
> --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
> +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
> @@ -34,6 +34,10 @@
>  #define MEMORY_TYPE_HBM 2
>
>
> +#define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0)
> +#define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F)
> +#define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd))
> +
>  enum dce_version resource_parse_asic_id(
>                 struct hw_asic_id asic_id);
>
> @@ -208,6 +212,13 @@ struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt(
>                 const struct dc_link *link);
>  #endif
>
> +void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,
> +       struct dc_state *context);
> +
> +void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
> +       struct dc_state *context,
> +       uint8_t disabled_master_pipe_idx);
> +
>  uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter);
>
>  #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
> --
> 2.34.1
>


More information about the amd-gfx mailing list