[PATCH 3/3] drm/amd/display: update bw_calcs to take pipe sync into account (v2)
Alex Deucher
alexdeucher at gmail.com
Thu Aug 22 16:31:56 UTC 2019
On Thu, Aug 22, 2019 at 12:25 PM Kazlauskas, Nicholas
<Nicholas.Kazlauskas at amd.com> wrote:
>
> On 8/22/19 11:36 AM, Alex Deucher wrote:
> > Properly set all_displays_in_sync so that when the data is
> > propagated to powerplay, it's set properly and we can enable
> > mclk switching when all monitors are in sync.
> >
> > v2: fix logic, clean up
> >
> > Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> > ---
> > .../gpu/drm/amd/display/dc/calcs/dce_calcs.c | 49 ++++++++++++++++++-
> > 1 file changed, 47 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
> > index 9f12e21f8b9b..8d904647fb0f 100644
> > --- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
> > +++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
> > @@ -25,6 +25,7 @@
> >
> > #include <linux/slab.h>
> >
> > +#include "resource.h"
> > #include "dm_services.h"
> > #include "dce_calcs.h"
> > #include "dc.h"
> > @@ -2977,6 +2978,50 @@ static void populate_initial_data(
> > data->number_of_displays = num_displays;
> > }
> >
> > +static bool all_displays_in_sync(const struct pipe_ctx pipe[],
> > + int pipe_count,
> > + uint32_t number_of_displays)
> > +{
> > + const struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
> > + int group_size = 1;
> > + int i, j;
> > +
> > + for (i = 0; i < pipe_count; i++) {
> > + if (!pipe[i].stream)
>
> This bit differs from program_timing_sync, but since this is for dce and
> we don't do pipe split or MPO I think it's probably fine that you're not
> checking top_pipe here.
>
> Wouldn't hurt to have that logic here though.
>
I had checked for top_pipe here originally, but it was always NULL so
unsynced_pipes never got populated. Maybe that is not populated
properly at this point?
> > + continue;
> > +
> > + unsynced_pipes[i] = &pipe[i];
> > + }
> > +
> > + for (i = 0; i < pipe_count; i++) {
> > + const struct pipe_ctx *pipe_set[MAX_PIPES];
> > +
> > + if (!unsynced_pipes[i])
> > + continue;
> > +
> > + pipe_set[0] = unsynced_pipes[i];
> > + unsynced_pipes[i] = NULL;
> > +
> > + /* Add tg to the set, search rest of the tg's for ones with
> > + * same timing, add all tgs with same timing to the group
> > + */
> > + for (j = i + 1; j < pipe_count; j++) {
> > + if (!unsynced_pipes[j])
> > + continue;
> > +
> > + if (resource_are_streams_timing_synchronizable(
> > + unsynced_pipes[j]->stream,
> > + pipe_set[0]->stream)) {
> > + pipe_set[group_size] = unsynced_pipes[j];
> > + unsynced_pipes[j] = NULL;
> > + group_size++;
> > + }
> > + }
> > + }
> > +
> > + return (group_size == number_of_displays) ? true : false;
>
> I think this logic is functional but it looks incorrect at first glance
> because group_size doesn't get reset. What ends up happening is the
> first pipe of each group doesn't get added to group_size.
>
> I feel that this would be more clear as:
>
> static bool all_displays_in_sync(const struct pipe_ctx pipe[], int
> pipe_count)
> {
> const struct pipe_ctx *active_pipes[MAX_PIPES];
> int i, num_active_pipes = 0;
>
> for (i = 0; i < pipe_count; i++) {
> if (!pipe[i].stream || pipe[i].top_pipe)
> continue;
>
> active_pipes[num_active_pipes++] = &pipe[i];
> }
>
> if (!num_active_pipes)
> return false;
>
> for (i = 1; i < num_active_pipes; ++i)
> if (!resource_are_streams_timing_synchronizable(
> active_pipes[0]->stream, active_pipes[i]->stream))
> return false;
>
> return true;
> }
Yes, that's much cleaner. Thanks!
Alex
>
> But I haven't tested this.
>
> Nicholas Kazlauskas
>
>
> > +}
> > +
> > /**
> > * Return:
> > * true - Display(s) configuration supported.
> > @@ -2998,8 +3043,8 @@ bool bw_calcs(struct dc_context *ctx,
> >
> > populate_initial_data(pipe, pipe_count, data);
> >
> > - /*TODO: this should be taken out calcs output and assigned during timing sync for pplib use*/
> > - calcs_output->all_displays_in_sync = false;
> > + calcs_output->all_displays_in_sync = all_displays_in_sync(pipe, pipe_count,
> > + data->number_of_displays);
> >
> > if (data->number_of_displays != 0) {
> > uint8_t yclk_lvl, sclk_lvl;
> >
>
More information about the amd-gfx
mailing list