[Intel-gfx] [PATCH] drm/i915: Acquire RPM wakeref for KMS atomic commit
Joonas Lahtinen
joonas.lahtinen at linux.intel.com
Thu Jan 21 03:52:09 PST 2016
On to, 2016-01-14 at 18:50 +0200, Imre Deak wrote:
> On la, 2015-12-19 at 09:58 +0000, Chris Wilson wrote:
> > Once all the preparations are complete, we are ready to write the
> > modesetting to the hardware. During this phase, we will be making
> > lots
> > of HW register access, so take a top level wakeref to prevent an
> > unwarranted rpm suspend cycle mid-commit. Lower level functions
> > should
> > be waking the individual power wells as required.
> >
> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93439
>
> I would separate here two things:
>
> The device level power flip-flopping you mention and the fix for the
> above bug. For the flip-flopping we could use what you suggest,
> perhaps
> by also avoiding waking up the device if nothing will change and
> everything will stay disabled.
>
> As for the fix I would go with what Ville suggested. By ensuring we
> keep an RPM reference we still allow for a display power domain
> reference to come and go in the middle of the HW readout. I went
> ahead
> and tried the following which got rid of the problem too, if people
> are
> ok with it I could convert the rest of the HW readout places
> accordingly and send out the patch. We can also
> get pm_runtime_get_if_in_use() into use once it's added, but it's
> not crucial for the fix.
>
Below patch looks fine. Just that I'd use s/if_enabled/if_in_use/ to
match the PM API better. We're already doing too much of a good job to
having many names for same thing.
Regards, Joonas
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 1f9a368..907377dc 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1910,13 +1910,16 @@ bool intel_ddi_connector_get_hw_state(struct
> intel_connector *intel_connector)
> enum transcoder cpu_transcoder;
> enum intel_display_power_domain power_domain;
> uint32_t tmp;
> + bool ret;
>
> power_domain =
> intel_display_port_power_domain(intel_encoder);
> - if (!intel_display_power_is_enabled(dev_priv, power_domain))
> + if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
> return false;
>
> - if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
> - return false;
> + if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) {
> + ret = false;
> + goto out;
> + }
>
> if (port == PORT_A)
> cpu_transcoder = TRANSCODER_EDP;
> @@ -1928,23 +1931,30 @@ bool intel_ddi_connector_get_hw_state(struct
> intel_connector *intel_connector)
> switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
> case TRANS_DDI_MODE_SELECT_HDMI:
> case TRANS_DDI_MODE_SELECT_DVI:
> - return (type == DRM_MODE_CONNECTOR_HDMIA);
> + ret = type == DRM_MODE_CONNECTOR_HDMIA;
> + goto out;
>
> case TRANS_DDI_MODE_SELECT_DP_SST:
> - if (type == DRM_MODE_CONNECTOR_eDP)
> - return true;
> - return (type == DRM_MODE_CONNECTOR_DisplayPort);
> + ret = type == DRM_MODE_CONNECTOR_eDP ||
> + type == DRM_MODE_CONNECTOR_DisplayPort;
> + goto out;
> case TRANS_DDI_MODE_SELECT_DP_MST:
> /* if the transcoder is in MST state then
> * connector isn't connected */
> - return false;
> + ret = false;
> + goto out;
>
> case TRANS_DDI_MODE_SELECT_FDI:
> - return (type == DRM_MODE_CONNECTOR_VGA);
> + ret = type == DRM_MODE_CONNECTOR_VGA;
> + goto out;
>
> default:
> - return false;
> + ret = false;
> }
> +out:
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return ret;
> }
>
> bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 059b46e..3c84159 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1456,6 +1456,8 @@ bool __intel_display_power_is_enabled(struct
> drm_i915_private *dev_priv,
> enum
> intel_display_power_domain domain);
> void intel_display_power_get(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain
> domain);
> +bool intel_display_power_get_if_enabled(struct drm_i915_private
> *dev_priv,
> + enum
> intel_display_power_domain domain);
> void intel_display_power_put(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain
> domain);
>
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c
> b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index bbca527..6c4f170 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -1470,6 +1470,17 @@ void intel_display_power_get(struct
> drm_i915_private *dev_priv,
> mutex_unlock(&power_domains->lock);
> }
>
> +bool intel_display_power_get_if_enabled(struct drm_i915_private
> *dev_priv,
> + enum
> intel_display_power_domain domain)
> +{
> + if (!intel_display_power_is_enabled(dev_priv, domain))
> + return false;
> +
> + intel_display_power_get(dev_priv, domain);
> +
> + return true;
> +}
> +
> /**
> * intel_display_power_put - release a power domain reference
> * @dev_priv: i915 device instance
>
> --Imre
>
> > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> > Cc: Imre Deak <imre.deak at intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_display.c | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index abd2d2944022..60451c3932db 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -13470,6 +13470,13 @@ static int intel_atomic_commit(struct
> > drm_device *dev,
> > drm_atomic_helper_swap_state(dev, state);
> > dev_priv->wm.config = to_intel_atomic_state(state)-
> > > wm_config;
> >
> > + /* Take a rpm wakeref for the duration of the commit.
> > Lower
> > level
> > + * functions should be acquiring the power wells for their
> > own use,
> > + * we take this toplevel reference to prevent rpm suspend
> > cycles
> > + * mid-commit.
> > + */
> > + intel_runtime_pm_get(dev_priv);
> > +
> > for_each_crtc_in_state(state, crtc, crtc_state, i) {
> > struct intel_crtc *intel_crtc =
> > to_intel_crtc(crtc);
> >
> > @@ -13558,6 +13565,8 @@ static int intel_atomic_commit(struct
> > drm_device *dev,
> > if (any_ms)
> > intel_modeset_check_state(dev, state);
> >
> > + intel_runtime_pm_put(dev_priv);
> > +
> > drm_atomic_state_free(state);
> >
> > return 0;
More information about the Intel-gfx
mailing list