[Intel-gfx] [PATCH 06/31] drm/i915: Fix IPS disable sequence.
Vivi, Rodrigo
rodrigo.vivi at intel.com
Wed Nov 11 15:31:56 PST 2015
On Tue, 2015-11-10 at 16:34 +0000, Daniel Stone wrote:
> Hi,
>
> On 5 November 2015 at 18:49, Rodrigo Vivi <rodrigo.vivi at intel.com>
> wrote:
> > /**
> > + * intel_ips_disable_if_alone - Disable IPS if alone in the pipe.
> > + * @crtc: intel crtc
> > + *
> > + * This function should be called when primary plane is being
> > disabled.
> > + * It checks if there is any other plane enabled on the pipe when
> > primary is
> > + * going to be disabled. In this case IPS can continue enabled,
> > but it needs
> > + * to be disabled otherwise.
> > + */
>
> As an example of what I meant before, I would reword this to reflect
> its actual functionality, which doesn't necessarily have anything to
> do specifically with disabling the primary plane:
> 'This function examines the CRTC state to determine if IPS should
> be disabled. Currently, IPS is disabled if no planes are active on
> the
> CRTC.'
>
> Discussing its use in the context of disabling the primary plane I
> think obscures its intent, and also introduces a bug. :)
>
> > +void intel_ips_disable_if_alone(struct intel_crtc *crtc)
> > +{
> > + struct drm_device *dev = crtc->base.dev;
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + bool ips_enabled;
> > + struct intel_plane *intel_plane;
> > +
> > + mutex_lock(&dev_priv->display_ips.lock);
> > + ips_enabled = dev_priv->display_ips.enabled;
> > + mutex_unlock(&dev_priv->display_ips.lock);
> > +
> > + if (!ips_enabled)
> > + return;
> > +
> > + for_each_intel_plane_on_crtc(dev, crtc, intel_plane) {
> > + enum plane plane = intel_plane->plane;
> > +
> > + if (plane != PLANE_A &&
> > + !!(I915_READ(DSPCNTR(plane)) &
> > DISPLAY_PLANE_ENABLE))
> > + return;
> > + intel_ips_disable(crtc);
> > + }
> > +}
>
> Rather than reading the registers, this should just inspect
> plane_state->visible. Reading the registers introduces the same bug
> as
> I mentioned the last mail, but in a different way:
> - IPS is enabled
> - primary and overlay planes are both enabled
> - user commits an atomic state which disables both primary and
> overlay planes, so IPS must be disabled
> - disabling the primary plane calls this function, which sees that
> the overlay plane is still active, so IPS can remain enabled
> - the overlay plane gets disabled, with IPS still active
> - :(
You are absolutely right on this case... :/ Thanks for spotting this
case.
So I was considering your idea for the unified place but I ended up in
some concerns questions here.
First is the disable must occur on pre-update and enable on post
-update, so I would prefer to still let them spread and reactive.
But now I believe that we need to detach the atomic
->ips_{enable,disable} from primary and do for every plane on/off. So
if we are enabling any plane we just call ips_enable().
And if plane is being disabled and there is no other plane->visible in
this crtc we call intel_disable().
But I wonder how to skip the plane itself on for_each_plane_in_state...
Or should I just counter the number of state->visible and disable if <=
1 and let enable if we count more than 1 visible plane. Any better
idea?
>
> Making this work on states would eliminate this entire class of bugs,
> and also make it much easier to handle async modesets.
>
> Cheers,
> Daniel
More information about the Intel-gfx
mailing list