On Mon, Dec 16, 2019 at 02:07:41PM -0800, José Roberto de Souza wrote:
> Check if fastset is allowed by external dependencies like other pipes
> and transcoders.
> 
> Right now this patch only forces a fullmodeset in MST slaves of MST
> masters that needs a fullmodeset but it will be needed for port sync
> as well.
> 
> v3:
> - moved handling to intel_atomic_check() this way is guarantee that
> all pipes will have its state computed
> 
> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Cc: Lucas De Marchi <lucas.demar...@intel.com>
> Cc: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
> Cc: Manasi Navare <manasi.d.nav...@intel.com>
> Signed-off-by: José Roberto de Souza <jose.so...@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 63 ++++++++++++++++----
>  1 file changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index f1c0687bf69b..2627a7bcb45c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -13941,19 +13941,6 @@ static void intel_crtc_check_fastset(const struct 
> intel_crtc_state *old_crtc_sta
>  
>       new_crtc_state->uapi.mode_changed = false;
>       new_crtc_state->update_pipe = true;
> -
> -     /*
> -      * If we're not doing the full modeset we want to
> -      * keep the current M/N values as they may be
> -      * sufficiently different to the computed values
> -      * to cause problems.
> -      *
> -      * FIXME: should really copy more fuzzy state here
> -      */
> -     new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n;
> -     new_crtc_state->dp_m_n = old_crtc_state->dp_m_n;
> -     new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2;
> -     new_crtc_state->has_drrs = old_crtc_state->has_drrs;
>  }
>  
>  static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
> @@ -14121,6 +14108,56 @@ static int intel_atomic_check(struct drm_device *dev,
>                       any_ms = true;
>       }
>  
> +     /**
> +      * Check if fastset is allowed by external dependencies like other
> +      * pipes and transcoders.
> +      *
> +      * Right now it only forces a fullmodeset when the MST master
> +      * transcoder did not changed but the pipe of the master transcoder
> +      * needs a fullmodeset so all slaves also needs to do a fullmodeset.
> +      */
> +     for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> +             struct intel_crtc_state *new_crtc_state_iter;
> +             struct intel_crtc *crtc_iter;
> +             int j;
> +
> +             if (!intel_dp_mst_is_slave_trans(new_crtc_state) ||
> +                 needs_modeset(new_crtc_state))

shouldn't this be
if (!mst_master || !needs_modeset)
        continue;
?

> +                     continue;
> +
> +             for_each_new_intel_crtc_in_state(state, crtc_iter,
> +                                              new_crtc_state_iter, j) {
> +                     if (new_crtc_state->mst_master_transcoder !=
> +                         new_crtc_state_iter->cpu_transcoder)
> +                             continue;
> +
> +                     if (needs_modeset(new_crtc_state_iter)) {
> +                             new_crtc_state->uapi.mode_changed = true;
> +                             new_crtc_state->update_pipe = false;
> +                     }
> +                     break;

Hmm. So I guess the break here is because we're going to keep iterating
the outer loop anyway? Don't think that works with the s/slave/master/
fix above.

I suggest moving this inner loop into a separate function entirely.
Could simply pass in the master_transcoder to that function and then
we wouldn't even have this clash with variable names for the two
crtcs/crtc_states.

Somethig like (with better funciton names ofc :)

mst_modeset_slaves(state, master_transcoder)
{
        for_each() {
                if (master_transcoder == crtc_state->master_transcoder)
                        modeset=1;
        }
}

atomic_check()
{
        for_each()
                compute();

        for_each() {
                if (master && needs_modeset()
                        mst_modeset_slaves(state, crtc_state->cpu_transcoder);
        }

        for_each() {
                if (fastset)
                        copy();
        }
}

Or do we also need to force a modeset for the master if a slave needs a
modeset? I'm trying to think if there's a way that we could end up with
a slave changing its master (thus needing modeset) without the master
being flagged for modeset...

> +             }
> +     }
> +
> +     for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +                                         new_crtc_state, i) {
> +             if (needs_modeset(new_crtc_state))
> +                     continue;
> +
> +             /*
> +              * If we're not doing the full modeset we want to
> +              * keep the current M/N values as they may be
> +              * sufficiently different to the computed values
> +              * to cause problems.
> +              *
> +              * FIXME: should really copy more fuzzy state here
> +              */
> +             new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n;
> +             new_crtc_state->dp_m_n = old_crtc_state->dp_m_n;
> +             new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2;
> +             new_crtc_state->has_drrs = old_crtc_state->has_drrs;

A separate function for this fastset state copy might also be nice so we
don't have to see these mundane details in this higher level code.

> +     }
> +
>       if (any_ms && !check_digital_port_conflicts(state)) {
>               DRM_DEBUG_KMS("rejecting conflicting digital port 
> configuration\n");
>               ret = EINVAL;
> -- 
> 2.24.1

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to