With this we know if IPS is actually enabled. It might not be activated on BDW since Hardware take the decision and do its transition. However we have the visibility of the state on our driver what we didn't had until this patch. At least on BDW. Since ips_ready means that ips will be enabled and ips_disable() checks for the state of our enabled/disabled state machine we can remove that FIXME that was there for crtc_load_lut workaround for Haswell. With this state machine and ips being disabled from different places and many times when testcases with sink_crtc for instance it is better to have it protected with its own mutex lock. Ohterwise we cannot guarantee consitent ips.enabled state with the register bit. Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_debugfs.c | 12 ++++-------- drivers/gpu/drm/i915/i915_drv.h | 9 ++++++++- drivers/gpu/drm/i915/intel_display.c | 3 ++- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_ips.c | 35 ++++++++++++++++++++++++++++++++--- 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 391861d..f741f13 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1711,14 +1711,10 @@ static int i915_ips_status(struct seq_file *m, void *unused) seq_printf(m, "Enabled by kernel parameter: %s\n", yesno(i915.enable_ips)); - if (INTEL_INFO(dev)->gen >= 8) { - seq_puts(m, "Currently: unknown\n"); - } else { - if (I915_READ(IPS_CTL) & IPS_ENABLE) - seq_puts(m, "Currently: enabled\n"); - else - seq_puts(m, "Currently: disabled\n"); - } + if (dev_priv->display_ips.enabled) + seq_puts(m, "Currently: enabled\n"); + else + seq_puts(m, "Currently: disabled\n"); intel_runtime_pm_put(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d2a546a..516c0b1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -971,6 +971,11 @@ struct i915_psr { bool aux_frame_sync; }; +struct i915_ips { + struct mutex lock; + bool enabled; +}; + enum intel_pch { PCH_NONE = 0, /* No PCH present */ PCH_IBX, /* Ibexpeak PCH */ @@ -1850,12 +1855,14 @@ struct drm_i915_private { /* ilk-only ips/rps state. Everything in here is protected by the global * mchdev_lock in intel_pm.c */ - struct intel_ilk_power_mgmt ips; + struct intel_ilk_power_mgmt ips; /* Intelligent Power Sharing */ struct i915_power_domains power_domains; struct i915_psr psr; + struct i915_ips display_ips; /* Intermediate Pixel Storage */ + struct i915_gpu_error gpu_error; struct drm_i915_gem_object *vlv_pctx; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 197c608..e5c4056 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4537,7 +4537,6 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) /* Workaround : Do not read or write the pipe palette/gamma data while * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. */ - /* FIXME: This should be ips_enabled */ if (IS_HASWELL(dev) && intel_crtc->config->ips_ready && ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) == GAMMA_MODE_MODE_SPLIT)) { @@ -14190,6 +14189,8 @@ static void intel_setup_outputs(struct drm_device *dev) intel_psr_init(dev); + intel_ips_init(dev_priv); + for_each_intel_encoder(dev, encoder) { encoder->base.possible_crtcs = encoder->crtc_mask; encoder->base.possible_clones = diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 41a88f7..cc08566 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1210,6 +1210,7 @@ bool intel_ips_ready(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); void intel_ips_enable(struct intel_crtc *crtc); void intel_ips_disable(struct intel_crtc *crtc); +void intel_ips_init(struct drm_i915_private *dev_priv); /* intel_csr.c */ void intel_csr_ucode_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_ips.c b/drivers/gpu/drm/i915/intel_ips.c index 573bc31..1d0d8ff 100644 --- a/drivers/gpu/drm/i915/intel_ips.c +++ b/drivers/gpu/drm/i915/intel_ips.c @@ -113,6 +113,11 @@ void intel_ips_enable(struct intel_crtc *crtc) if (!crtc->config->ips_ready) return; + mutex_lock(&dev_priv->display_ips.lock); + + if (dev_priv->display_ips.enabled) + goto out; + /* * We can only enable IPS after we enable a plane * and wait for a vblank. @@ -140,9 +145,15 @@ void intel_ips_enable(struct intel_crtc *crtc) * the HW state readout code will complain that the expected * IPS_CTL value is not the one we read. */ - if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) + if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) { DRM_ERROR("Timed out waiting for IPS enable\n"); + goto out; + } } + + dev_priv->display_ips.enabled = true; +out: + mutex_unlock(&dev_priv->display_ips.lock); } /** @@ -157,8 +168,10 @@ void intel_ips_disable(struct intel_crtc *crtc) struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - if (!crtc->config->ips_ready) - return; + mutex_lock(&dev_priv->display_ips.lock); + + if (!dev_priv->display_ips.enabled) + goto out; assert_plane_enabled(dev_priv, crtc->plane); if (IS_BROADWELL(dev)) { @@ -179,4 +192,20 @@ void intel_ips_disable(struct intel_crtc *crtc) /* We need to wait for a vblank before we can disable the plane. */ intel_wait_for_vblank(dev, crtc->pipe); + + dev_priv->display_ips.enabled = false; +out: + mutex_unlock(&dev_priv->display_ips.lock); +} + +/** + * intel_ips_init - Init IPS + * @dev_priv: drm i915 private. + * + * This function should be called only once to initialize what ever needed + * for IPS. + */ +void intel_ips_init(struct drm_i915_private dev_priv) +{ + mutex_init(&dev_priv->display_ips.lock); } -- 2.4.3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx