All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nils Wallménius" <nils.wallmenius@gmail.com>
To: Bindu Ramamurthy <bindu.r@amd.com>
Cc: Eryk.Brol@amd.com, Sunpeng.Li@amd.com, Bhawanpreet.Lakha@amd.com,
	Qingqing.Zhuo@amd.com, Rodrigo.Siqueira@amd.com,
	amd-gfx@lists.freedesktop.org, Anson.Jacob@amd.com,
	Vladimir Stempen <vladimir.stempen@amd.com>,
	Aurabindo.Pillai@amd.com, Harry.Wentland@amd.com
Subject: Re: [PATCH 08/13] drm/amd/display: Synchronize displays with different timings
Date: Sun, 21 Feb 2021 07:21:06 +0100	[thread overview]
Message-ID: <CA+nq7Dv1q1ncUZzSV=Art-etybyL+Ztx64=9uMYgVZiTsympHA@mail.gmail.com> (raw)
In-Reply-To: <20210219221612.1713328-9-bindu.r@amd.com>


[-- Attachment #1.1: Type: text/plain, Size: 15279 bytes --]

Hi Bindu, an inline comment below.

Den fre 19 feb. 2021 23:16Bindu Ramamurthy <bindu.r@amd.com> skrev:

> From: Vladimir Stempen <vladimir.stempen@amd.com>
>
> [why]
>  Vendor based fan noise improvement
>
> [how]
> Report timing synchronizable when DP streams time frame
> difference is less than 0.05 percent. Adjust DP  DTOs and
> sync displays using  MASTER_UPDATE_LOCK_DB_X_Y
>
> Signed-off-by: Vladimir Stempen <vladimir.stempen@amd.com>
> Acked-by: Bindu Ramamurthy <bindu.r@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  28 ++-
>  .../gpu/drm/amd/display/dc/core/dc_resource.c |  43 ++++
>  drivers/gpu/drm/amd/display/dc/dc.h           |   3 +
>  drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   1 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |   3 +
>  .../drm/amd/display/dc/dce/dce_clock_source.c |  52 +++-
>  .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 225 ++++++++++++++++++
>  .../amd/display/dc/dcn10/dcn10_hw_sequencer.h |   5 +
>  .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h |   2 +
>  .../display/dc/dcn10/dcn10_stream_encoder.c   |   1 -
>  .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c |   1 +
>  .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 123 ++++++++++
>  .../drm/amd/display/dc/dcn20/dcn20_resource.c |   8 +-
>  .../dc/dcn30/dcn30_dio_stream_encoder.c       |   1 -
>  .../gpu/drm/amd/display/dc/inc/clock_source.h |   5 +
>  .../amd/display/dc/inc/hw/timing_generator.h  |  12 +
>  .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |   3 +
>  drivers/gpu/drm/amd/display/dc/inc/resource.h |   4 +
>  18 files changed, 505 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c
> b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 2f56fa2c0bf4..39df5d2c0108 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -1102,6 +1102,7 @@ static void program_timing_sync(
>
>         for (i = 0; i < pipe_count; i++) {
>                 int group_size = 1;
> +               enum timing_synchronization_type sync_type =
> NOT_SYNCHRONIZABLE;
>                 struct pipe_ctx *pipe_set[MAX_PIPES];
>
>                 if (!unsynced_pipes[i])
> @@ -1116,10 +1117,22 @@ static void program_timing_sync(
>                 for (j = i + 1; j < pipe_count; j++) {
>                         if (!unsynced_pipes[j])
>                                 continue;
> -
> -                       if (resource_are_streams_timing_synchronizable(
> +                       if (sync_type != TIMING_SYNCHRONIZABLE &&
> +                               dc->hwss.enable_vblanks_synchronization &&
> +
>  unsynced_pipes[j]->stream_res.tg->funcs->align_vblanks &&
> +                               resource_are_vblanks_synchronizable(
> +                                       unsynced_pipes[j]->stream,
> +                                       pipe_set[0]->stream)) {
> +                               sync_type = VBLANK_SYNCHRONIZABLE;
> +                               pipe_set[group_size] = unsynced_pipes[j];
> +                               unsynced_pipes[j] = NULL;
> +                               group_size++;
> +                       } else
> +                       if (sync_type != VBLANK_SYNCHRONIZABLE &&
> +                               resource_are_streams_timing_synchronizable(
>                                         unsynced_pipes[j]->stream,
>                                         pipe_set[0]->stream)) {
> +                               sync_type = TIMING_SYNCHRONIZABLE;
>                                 pipe_set[group_size] = unsynced_pipes[j];
>                                 unsynced_pipes[j] = NULL;
>                                 group_size++;
> @@ -1145,7 +1158,6 @@ static void program_timing_sync(
>                         }
>                 }
>
> -
>                 for (k = 0; k < group_size; k++) {
>                         struct dc_stream_status *status =
> dc_stream_get_status_from_state(ctx, pipe_set[k]->stream);
>
> @@ -1175,8 +1187,14 @@ static void program_timing_sync(
>                 }
>
>                 if (group_size > 1) {
> -                       dc->hwss.enable_timing_synchronization(
> -                               dc, group_index, group_size, pipe_set);
> +                       if (sync_type == TIMING_SYNCHRONIZABLE) {
> +                               dc->hwss.enable_timing_synchronization(
> +                                       dc, group_index, group_size,
> pipe_set);
> +                       } else
> +                               if (sync_type == VBLANK_SYNCHRONIZABLE) {
> +                               dc->hwss.enable_vblanks_synchronization(
> +                                       dc, group_index, group_size,
> pipe_set);
> +                               }
>                         group_index++;
>                 }
>                 num_group++;
> 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 0c26c2ade782..0241c9d96d7a 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> @@ -417,6 +417,49 @@ int resource_get_clock_source_reference(
>         return -1;
>  }
>
> +bool resource_are_vblanks_synchronizable(
> +       struct dc_stream_state *stream1,
> +       struct dc_stream_state *stream2)
> +{
> +       uint32_t base60_refresh_rates[] = {10, 20, 5};
> +       uint8_t i;
> +       uint8_t rr_count =
> sizeof(base60_refresh_rates)/sizeof(base60_refresh_rates[0]);
> +       int64_t frame_time_diff;
> +
> +       if (stream1->ctx->dc->config.vblank_alignment_dto_params &&
> +
>  stream1->ctx->dc->config.vblank_alignment_max_frame_time_diff > 0 &&
> +               dc_is_dp_signal(stream1->signal) &&
> +               dc_is_dp_signal(stream2->signal) &&
> +               false == stream1->has_non_synchronizable_pclk &&
> +               false == stream2->has_non_synchronizable_pclk &&
> +               stream1->timing.flags.VBLANK_SYNCHRONIZABLE &&
> +               stream2->timing.flags.VBLANK_SYNCHRONIZABLE) {
> +               /* disable refresh rates higher than 60Hz for now */
> +               if
> (stream1->timing.pix_clk_100hz*100/stream1->timing.h_total/
> +                               stream1->timing.v_total > 60)
> +                       return false;
> +               if
> (stream2->timing.pix_clk_100hz*100/stream2->timing.h_total/
> +                               stream2->timing.v_total > 60)
> +                       return false;
> +               frame_time_diff = (int64_t)10000 *
> +                       stream1->timing.h_total *
> +                       stream1->timing.v_total *
> +                       stream2->timing.pix_clk_100hz /
> +                       stream1->timing.pix_clk_100hz /
> +                       stream2->timing.h_total /
> +                       stream2->timing.v_total;
> +               for (i = 0; i < rr_count; i++) {
> +                       int64_t diff = (frame_time_diff *
> base60_refresh_rates[i]) / 10 - 10000;
> +
> +                       if (diff < 0)
> +                               diff = -diff;
> +                       if (diff <
> stream1->ctx->dc->config.vblank_alignment_max_frame_time_diff)
> +                               return true;
> +               }
> +       }
> +       return false;
> +}
> +
>  bool resource_are_streams_timing_synchronizable(
>         struct dc_stream_state *stream1,
>         struct dc_stream_state *stream2)
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h
> b/drivers/gpu/drm/amd/display/dc/dc.h
> index a10daf6655f9..9e631980fa1b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -301,6 +301,8 @@ struct dc_config {
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>         bool clamp_min_dcfclk;
>  #endif
> +       uint64_t vblank_alignment_dto_params;
> +       uint8_t  vblank_alignment_max_frame_time_diff;
>  };
>
>  enum visual_confirm {
> @@ -528,6 +530,7 @@ struct dc_debug_options {
>         bool disable_dsc;
>         bool enable_dram_clock_change_one_display_vactive;
>         union mem_low_power_enable_options enable_mem_low_power;
> +       bool force_vblank_alignment;
>  };
>
>  struct dc_debug_data {
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> index b41e6367b15e..48d3ed97ead9 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> @@ -705,6 +705,7 @@ struct dc_crtc_timing_flags {
>  #ifndef TRIM_FSFT
>         uint32_t FAST_TRANSPORT: 1;
>  #endif
> +       uint32_t VBLANK_SYNCHRONIZABLE: 1;
>  };
>
>  enum dc_timing_3d_format {
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index e243c01b9672..7fa998f97e7a 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -228,6 +228,9 @@ struct dc_stream_state {
>         uint32_t stream_id;
>         bool is_dsc_enabled;
>         union stream_update_flags update_flags;
> +
> +       bool has_non_synchronizable_pclk;
> +       bool vblank_synchronized;
>  };
>
>  #define ABM_LEVEL_IMMEDIATE_DISABLE 255
> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> index dec58b3c42e4..6f47f9bab5ee 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> @@ -1002,15 +1002,27 @@ static bool get_pixel_clk_frequency_100hz(
>  {
>         struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
>         unsigned int clock_hz = 0;
> +       unsigned int modulo_hz = 0;
>
>         if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) {
>                 clock_hz = REG_READ(PHASE[inst]);
>
> -               /* NOTE: There is agreement with VBIOS here that MODULO is
> -                * programmed equal to DPREFCLK, in which case PHASE will
> be
> -                * equivalent to pixel clock.
> -                */
> -               *pixel_clk_khz = clock_hz / 100;
> +               if
> (clock_source->ctx->dc->hwss.enable_vblanks_synchronization &&
> +
>  clock_source->ctx->dc->config.vblank_alignment_max_frame_time_diff > 0) {
> +                       /* NOTE: In case VBLANK syncronization is enabled,
> MODULO may
> +                        * not be programmed equal to DPREFCLK
> +                        */
> +                       modulo_hz = REG_READ(MODULO[inst]);
> +                       *pixel_clk_khz = ((uint64_t)clock_hz*
> +
>  clock_source->ctx->dc->clk_mgr->dprefclk_khz*10)/
> +                               modulo_hz;
> +               } else {
> +                       /* NOTE: There is agreement with VBIOS here that
> MODULO is
> +                        * programmed equal to DPREFCLK, in which case
> PHASE will be
> +                        * equivalent to pixel clock.
> +                        */
> +                       *pixel_clk_khz = clock_hz / 100;
> +               }
>                 return true;
>         }
>
> @@ -1074,8 +1086,35 @@ static bool dcn20_program_pix_clk(
>                 struct pixel_clk_params *pix_clk_params,
>                 struct pll_settings *pll_settings)
>  {
> +       struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
> +       unsigned int inst = pix_clk_params->controller_id -
> CONTROLLER_ID_D0;
> +
>         dce112_program_pix_clk(clock_source, pix_clk_params, pll_settings);
>
> +       if (clock_source->ctx->dc->hwss.enable_vblanks_synchronization &&
> +
>  clock_source->ctx->dc->config.vblank_alignment_max_frame_time_diff > 0) {
> +               /* NOTE: In case VBLANK syncronization is enabled,
> +                * we need to set modulo to default DPREFCLK first
> +                * dce112_program_pix_clk does not set default DPREFCLK
> +                */
> +               REG_WRITE(MODULO[inst],
> +                       clock_source->ctx->dc->clk_mgr->dprefclk_khz*1000);
> +       }
> +       return true;
> +}
> +
> +static bool dcn20_override_dp_pix_clk(
> +               struct clock_source *clock_source,
> +               unsigned int inst,
> +               unsigned int pixel_clk,
> +               unsigned int ref_clk)
> +{
> +       struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
> +
> +       REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 0);
> +       REG_WRITE(PHASE[inst], pixel_clk);
> +       REG_WRITE(MODULO[inst], ref_clk);
> +       REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1);
>         return true;
>  }
>
> @@ -1083,7 +1122,8 @@ static const struct clock_source_funcs
> dcn20_clk_src_funcs = {
>         .cs_power_down = dce110_clock_source_power_down,
>         .program_pix_clk = dcn20_program_pix_clk,
>         .get_pix_clk_dividers = dce112_get_pix_clk_dividers,
> -       .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz
> +       .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz,
> +       .override_dp_pix_clk = dcn20_override_dp_pix_clk
>  };
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> index 89912bb5014f..669cee48b0b5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
> @@ -1851,6 +1851,225 @@ static bool wait_for_reset_trigger_to_occur(
>         return rc;
>  }
>
> +uint64_t reduceSizeAndFraction(
> +       uint64_t *numerator,
> +       uint64_t *denominator,
> +       bool checkUint32Bounary)
> +{
> +       int i;
> +       bool ret = checkUint32Bounary == false;
> +       uint64_t max_int32 = 0xffffffff;
> +       uint64_t num, denom;
> +       uint16_t prime_numbers[] = {
> +               2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
> +               47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
> +               107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
> +               167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
> +               229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
> +               283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353,
> +               359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
> +               431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487,
> +               491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
> +               571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
> +               641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
> +               709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773,
> +               787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857,
> +               859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
> +               941, 947, 953, 967, 971, 977, 983, 991, 997};
> +       int count = ARRAY_SIZE(prime_numbers)/sizeof(prime_numbers[0]);
>

ARRAY_SIZE gives the number of elements, so this will limit iteration to
the first half of the prime_numbers array. Btw, the array can be "static
const".

BR
Nils

[-- Attachment #1.2: Type: text/html, Size: 18990 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  reply	other threads:[~2021-02-21  6:21 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-19 22:15 [PATCH 00/13] DC Patches FEB 22, 2021 Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 01/13] drm/amd/display: Remove Assert from dcn10_get_dig_frontend Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 02/13] drm/amd/display: Refactor debugfs entries for all connectors Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 03/13] drm/amd/display: Add vupdate_no_lock interrupts for DCN2.1 Bindu Ramamurthy
2021-02-19 22:16   ` Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 04/13] drm/amd/display: disable seamless boot for DP MST Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 05/13] drm/amd/display: enable audio on DP seamless boot Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 06/13] drm/amd/display: Check for DSC support instead of ASIC revision Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 07/13] drm/amd/display: move trace buffer to uncached memory Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 08/13] drm/amd/display: Synchronize displays with different timings Bindu Ramamurthy
2021-02-21  6:21   ` Nils Wallménius [this message]
2021-02-22 13:43     ` R, Bindu
2021-02-22 18:04       ` R, Bindu
2021-02-19 22:16 ` [PATCH 09/13] drm/amd/display: Don't optimize bandwidth before disabling planes Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 10/13] drm/amd/display: reduce scope for local var Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 11/13] drm/amd/display: [FW Promotion] Release 0.0.53 Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 12/13] drm/amd/display: 3.2.124 Bindu Ramamurthy
2021-02-19 22:16 ` [PATCH 13/13] drm/amd/display: Fix system hang after multiple hotplugs Bindu Ramamurthy
2021-02-19 22:29 ` [PATCH 00/13] DC Patches FEB 22, 2021 Wheeler, Daniel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CA+nq7Dv1q1ncUZzSV=Art-etybyL+Ztx64=9uMYgVZiTsympHA@mail.gmail.com' \
    --to=nils.wallmenius@gmail.com \
    --cc=Anson.Jacob@amd.com \
    --cc=Aurabindo.Pillai@amd.com \
    --cc=Bhawanpreet.Lakha@amd.com \
    --cc=Eryk.Brol@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=Qingqing.Zhuo@amd.com \
    --cc=Rodrigo.Siqueira@amd.com \
    --cc=Sunpeng.Li@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=bindu.r@amd.com \
    --cc=vladimir.stempen@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.