[Intel-gfx] [PATCH v2 3/3] drm/i915: gmch: fix stuck primary plane due to memory self-refresh mode
Deepak S
deepak.s at linux.intel.com
Tue Jul 1 05:53:31 CEST 2014
On Friday 13 June 2014 05:24 PM, Imre Deak wrote:
> Blanking/unblanking the console in a loop on an Asus T100 sometimes
> leaves the console blank. After some digging I found that applying
>
> commit 61bc95c1fbbb6a08b55bbe161fdf1ea5493fc595
> Author: Egbert Eich <eich at suse.com>
> Date: Mon Mar 4 09:24:38 2013 -0500
>
> DRM/i915: On G45 enable cursor plane briefly after enabling the display plane.
>
> fixed VLV too.
>
> In my case the problem seemed to happen already during the previous crtc
> disabling and went away if I disabled self-refresh mode before disabling
> the primary plane.
>
> The root cause for this is that updates from the shadow to live plane
> control register are blocked at vblank time if the memory self-refresh
> mode (aka max-fifo mode on VLV) is active at that moment. The controller
> checks at frame start time if the CPU is in C0 and the self-refresh mode
> enable bit is set and if so activates self-reresh mode, otherwise
> deactivates it. So to make sure that the plane truly gets disabled before
> pipe-off we have to:
>
> 1. disable memory self-refresh mode
> 2. disable plane
> 3. wait for vblank
> 4. disable pipe
> 5. wait for pipe-off
>
> v2:
> - add explanation for the root cause from HW team (Cesar Mancini et al)
> - remove note about the CPU C7S state, in my latest tests disabling it
> alone didn't make a difference
> - add vblank between disabling plane and pipe (Ville)
> - apply the same workaround for all gmch platforms (Ville)
>
> Signed-off-by: Imre Deak <imre.deak at intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b9251c8..5eb8afe 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4799,6 +4799,16 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
> if (IS_GEN2(dev))
> intel_set_cpu_fifo_underrun_reporting(dev, pipe, false);
>
> + /*
> + * Vblank time updates from the shadow to live plane control register
> + * are blocked if the memory self-refresh mode is active at that
> + * moment. So to make sure the plane gets truly disabled, disable
> + * first the self-refresh mode. The self-refresh enable bit in turn
> + * will be checked/applied by the HW only at the next frame start
> + * event which is after the vblank start event, so we need to have a
> + * wait-for-vblank between disabling the plane and the pipe.
> + */
> + intel_set_memory_cxsr(dev_priv, false);
> intel_crtc_disable_planes(crtc);
>
> for_each_encoder_on_crtc(dev, crtc, encoder)
> @@ -4807,9 +4817,10 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
> /*
> * On gen2 planes are double buffered but the pipe isn't, so we must
> * wait for planes to fully turn off before disabling the pipe.
> + * We also need to wait on all gmch platforms because of the
> + * self-refresh mode constraint explained above.
> */
> - if (IS_GEN2(dev))
> - intel_wait_for_vblank(dev, pipe);
> + intel_wait_for_vblank(dev, pipe);
>
> intel_disable_pipe(dev_priv, pipe);
>
Reviewed-by: Deepak S<deepak.s at linux.intel.com>
More information about the Intel-gfx
mailing list