From patchwork Fri Nov 16 14:22:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 1755271 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 5B6D2DF230 for ; Fri, 16 Nov 2012 14:27:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4812B436A3 for ; Fri, 16 Nov 2012 06:27:55 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id 4581443709; Fri, 16 Nov 2012 06:22:51 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 16 Nov 2012 06:22:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.83,265,1352102400"; d="scan'208";a="250270502" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.168]) by fmsmga002.fm.intel.com with SMTP; 16 Nov 2012 06:22:48 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 16 Nov 2012 16:22:48 +0200 From: ville.syrjala@linux.intel.com To: dri-devel@lists.freedesktop.org Subject: [PATCH 05/13] drm/i915: Make a copy of the calculated plane regs Date: Fri, 16 Nov 2012 16:22:17 +0200 Message-Id: <1353075745-30115-6-git-send-email-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 1.7.8.6 In-Reply-To: <1353075745-30115-1-git-send-email-ville.syrjala@linux.intel.com> References: <1353075745-30115-1-git-send-email-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Cc: intel-gfx@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: Ville Syrjälä The register values are computed when the flip ioctl is issued, and they're used only after we've waited for the GPU to finish rendering. The computed values are store in the intel_crtc and intel_plane structs, so issuing another flip before the previous one has been fully completed would clobber those stored registers. Fix the problem by making a copy of the calculated register values inside the intel_flip structure. The copy is then used when it's time to commit the registers to the hardware. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 4 +++- drivers/gpu/drm/i915/intel_atomic.c | 8 ++++++-- drivers/gpu/drm/i915/intel_display.c | 14 ++++++++------ drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_sprite.c | 24 ++++++++++++------------ 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8aaf0ce..91e2dc6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -247,6 +247,8 @@ struct drm_i915_error_state { struct intel_display_error_state *display; }; +struct intel_plane_regs; + struct drm_i915_display_funcs { bool (*fbc_enabled)(struct drm_device *dev); void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); @@ -278,7 +280,7 @@ struct drm_i915_display_funcs { int x, int y); int (*calc_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y); - void (*commit_plane)(struct drm_crtc *crtc); + void (*commit_plane)(struct drm_crtc *crtc, const struct intel_plane_regs *regs); /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 7a0e315..0aa8c93 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -49,6 +49,8 @@ struct intel_flip { struct intel_ring_buffer *ring; u32 seqno; unsigned int flip_seq; + /* FIXME need cursor regs too */ + struct intel_plane_regs regs; }; struct intel_plane_state { @@ -1988,11 +1990,11 @@ static bool intel_flip_flip(struct drm_flip *flip, struct drm_plane *plane = intel_flip->plane; struct intel_plane *intel_plane = to_intel_plane(plane); - intel_plane->commit(plane); + intel_plane->commit(plane, &intel_flip->regs); } else { struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->display.commit_plane(crtc); + dev_priv->display.commit_plane(crtc, &intel_flip->regs); } if (intel_flip->has_cursor) @@ -2339,6 +2341,7 @@ static void atomic_pipe_commit(struct drm_device *dev, /* should already be checked so can't fail */ /* FIXME refactor the failing parts? */ dev_priv->display.calc_plane(crtc, crtc->fb, crtc->x, crtc->y); + intel_flip->regs = intel_crtc->primary_regs; if (st->cursor_dirty) { intel_flip->has_cursor = true; @@ -2405,6 +2408,7 @@ static void atomic_pipe_commit(struct drm_device *dev, } intel_plane->calc(plane, plane->fb, &st->coords); + intel_flip->regs = intel_plane->regs; if (st->old.fb) intel_flip->old_fb_id = st->old.fb->base.id; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7537a2c..48eeed5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2030,13 +2030,13 @@ unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y, return tile_rows * pitch * 8 + tiles * 4096; } -static void intel_commit_plane(struct drm_crtc *crtc) +static void intel_commit_plane(struct drm_crtc *crtc, + const struct intel_plane_regs *regs) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane = intel_crtc->plane; - const struct intel_plane_regs *regs = &intel_crtc->primary_regs; I915_WRITE(DSPCNTR(plane), regs->cntr); I915_WRITE(DSPSTRIDE(plane), regs->stride); @@ -2153,15 +2153,16 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y) { struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int ret; ret = i9xx_calc_plane(crtc, fb, x, y); if (ret) return ret; - intel_commit_plane(crtc); + intel_commit_plane(crtc, &intel_crtc->primary_regs); - POSTING_READ(DSPCNTR(to_intel_crtc(crtc)->plane)); + POSTING_READ(DSPCNTR(intel_crtc->plane)); return 0; } @@ -2257,15 +2258,16 @@ static int ironlake_update_plane(struct drm_crtc *crtc, struct drm_framebuffer * int x, int y) { struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int ret; ret = ironlake_calc_plane(crtc, fb, x, y); if (ret) return ret; - intel_commit_plane(crtc); + intel_commit_plane(crtc, &intel_crtc->primary_regs); - POSTING_READ(DSPCNTR(to_intel_crtc(crtc)->plane)); + POSTING_READ(DSPCNTR(intel_crtc->plane)); return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 617ba4d..9771a10 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -274,7 +274,7 @@ struct intel_plane { void (*calc)(struct drm_plane *plane, struct drm_framebuffer *fb, const struct intel_plane_coords *clip); void (*prepare)(struct drm_plane *plane); - void (*commit)(struct drm_plane *plane); + void (*commit)(struct drm_plane *plane, const struct intel_plane_regs *regs); struct intel_plane_regs regs; struct drm_flip_helper flip_helper; }; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index ce3b950..d960e19 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -300,13 +300,13 @@ ivb_calc_plane(struct drm_plane *plane, } static void -ivb_commit_plane(struct drm_plane *plane) +ivb_commit_plane(struct drm_plane *plane, + const struct intel_plane_regs *regs) { struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe; - const struct intel_plane_regs *regs = &intel_plane->regs; I915_WRITE(SPRKEYVAL(pipe), regs->keyval); I915_WRITE(SPRKEYMAX(pipe), regs->keymaxval); @@ -371,7 +371,7 @@ ivb_update_plane(struct drm_plane *plane, ivb_calc_plane(plane, fb, coords); ivb_prepare_plane(plane); - ivb_commit_plane(plane); + ivb_commit_plane(plane, &intel_plane->regs); POSTING_READ(SPRSURF(pipe)); } @@ -387,7 +387,7 @@ ivb_disable_plane(struct drm_plane *plane) regs->cntr &= ~SPRITE_ENABLE; /* Can't leave the scaler enabled... */ regs->scale = 0; - ivb_commit_plane(plane); + ivb_commit_plane(plane, regs); POSTING_READ(SPRSURF(pipe)); dev_priv->sprite_scaling_enabled &= ~(1 << pipe); @@ -413,7 +413,7 @@ ivb_update_colorkey(struct drm_plane *plane, else if (key->flags & I915_SET_COLORKEY_SOURCE) regs->cntr |= SPRITE_SOURCE_KEY; - ivb_commit_plane(plane); + ivb_commit_plane(plane, regs); POSTING_READ(SPRKEYMSK(intel_plane->pipe)); return 0; @@ -546,13 +546,13 @@ ilk_prepare_plane(struct drm_plane *plane) } static void -ilk_commit_plane(struct drm_plane *plane) +ilk_commit_plane(struct drm_plane *plane, + const struct intel_plane_regs *regs) { struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe; - const struct intel_plane_regs *regs = &intel_plane->regs; I915_WRITE(DVSKEYVAL(pipe), regs->keyval); I915_WRITE(DVSKEYMAX(pipe), regs->keymaxval); @@ -579,7 +579,7 @@ ilk_update_plane(struct drm_plane *plane, ilk_calc_plane(plane, fb, coords); ilk_prepare_plane(plane); - ilk_commit_plane(plane); + ilk_commit_plane(plane, &intel_plane->regs); POSTING_READ(DVSSURF(pipe)); } @@ -595,7 +595,7 @@ ilk_disable_plane(struct drm_plane *plane) regs->cntr &= ~DVS_ENABLE; /* Disable the scaler */ regs->scale = 0; - ilk_commit_plane(plane); + ilk_commit_plane(plane, regs); POSTING_READ(DVSSURF(pipe)); } @@ -627,7 +627,7 @@ intel_enable_primary(struct drm_crtc *crtc) intel_update_fbc(dev); regs->cntr = I915_READ(reg) | DISPLAY_PLANE_ENABLE; - dev_priv->display.commit_plane(crtc); + dev_priv->display.commit_plane(crtc, regs); } void @@ -643,7 +643,7 @@ intel_disable_primary(struct drm_crtc *crtc) return; regs->cntr = I915_READ(reg) & ~DISPLAY_PLANE_ENABLE; - dev_priv->display.commit_plane(crtc); + dev_priv->display.commit_plane(crtc, regs); intel_crtc->primary_disabled = true; intel_update_fbc(dev); @@ -668,7 +668,7 @@ ilk_update_colorkey(struct drm_plane *plane, else if (key->flags & I915_SET_COLORKEY_SOURCE) regs->cntr |= DVS_SOURCE_KEY; - ilk_commit_plane(plane); + ilk_commit_plane(plane, regs); POSTING_READ(DVSKEYMSK(intel_plane->pipe)); return 0;