From f53fe967f2b47eef16eda03f342db44a62a40693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 26 Feb 2014 12:43:39 +0200 Subject: [PATCH] drm/i915: Don't use RCS flips on gen7+ when multiple pipes are enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have some reports which suggest that using RCS flips with multiple planes simultaneosly can lead to hangs. This might have something to do with the warnings in the spec that unmasking multiple events simultaneosly in DERRMR can lead to problems. So let's just fall back to BCS flips whenever multiple pipes are active. BCS flips were in use for a long time before RCS flips were introduced, so the hope is that BCS is more resilient in this regard. We will be looking at crtc->active for all the crtcs without locking all the crtc mutexes or the mode_config.mutex. We do hold the crtc mutex for the current crtc however, and since a full modeset will grab all the crtc mutexes, we can't have a full modeset happning in parallel. That means we can safely examine crtc->active for all crtcs as long as we hold at least one crtc mutex. We can ignore load detection since it's not used for this class of hardware, and in any case load detection wouldn't be issuing page flips. v2: Rebase and use for_each_intel_crtc() Cc: Enrico Tagliavini Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8cbce75..3829fd7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9184,6 +9184,17 @@ static int intel_default_queue_flip(struct drm_device *dev, return -ENODEV; } +static int intel_num_active_pipes(struct drm_device *dev) +{ + struct intel_crtc *crtc; + int num_active_pipes = 0; + + for_each_intel_crtc(dev, crtc) + num_active_pipes += crtc->active; + + return num_active_pipes; +} + static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, @@ -9268,7 +9279,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ring = &dev_priv->ring[BCS]; } else if (INTEL_INFO(dev)->gen >= 7) { ring = obj->ring; - if (ring == NULL || ring->id != RCS) + if (ring == NULL || ring->id != RCS || + intel_num_active_pipes(dev) > 1) ring = &dev_priv->ring[BCS]; } else { ring = &dev_priv->ring[RCS]; -- 1.8.5.5