From patchwork Mon Apr 5 21:07:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barnes X-Patchwork-Id: 90682 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o35LA0mE021235 for ; Mon, 5 Apr 2010 21:10:35 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 513339E9B1; Mon, 5 Apr 2010 14:09:59 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from outbound-mail-01.bluehost.com (outbound-mail-01.bluehost.com [69.89.21.11]) by gabe.freedesktop.org (Postfix) with SMTP id CDA4C9E937 for ; Mon, 5 Apr 2010 14:09:56 -0700 (PDT) Received: (qmail 29007 invoked by uid 0); 5 Apr 2010 21:09:56 -0000 Received: from unknown (HELO box514.bluehost.com) (74.220.219.114) by cpoproxy1.bluehost.com with SMTP; 5 Apr 2010 21:09:56 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=virtuousgeek.org; h=Received:Date:From:Cc:Subject:Message-ID:In-Reply-To:References:X-Mailer:Mime-Version:Content-Type:Content-Transfer-Encoding:X-Identified-User; b=QZAIRpQPsJk4VdTnr1T5KSUj2d44MXX3h6wrL+u8COVC0AjlzoCChXPsydJAuAFiiVkCRDzVFGoA51O/dUtKzJmFuR2oGVmq7Kl0xQQ0efFA8JW0RzqNlSMfrI65Jvb4; Received: from [75.110.194.140] (helo=jbarnes-piketon) by box514.bluehost.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.69) (envelope-from ) id 1NytYR-0004UR-KS; Mon, 05 Apr 2010 15:09:55 -0600 Date: Mon, 5 Apr 2010 14:07:49 -0700 From: Jesse Barnes Message-ID: <20100405140749.087ba72b@jbarnes-piketon> In-Reply-To: <20100326134108.597d257a@jbarnes-piketon> References: <1269626841-10852-1-git-send-email-jbarnes@virtuousgeek.org> <1269626841-10852-6-git-send-email-jbarnes@virtuousgeek.org> <20100326134108.597d257a@jbarnes-piketon> X-Mailer: Claws Mail 3.7.2 (GTK+ 2.18.3; x86_64-pc-linux-gnu) Mime-Version: 1.0 X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 75.110.194.140 authed with jbarnes@virtuousgeek.org} Cc: airlied@linux.ie, intel-gfx@lists.freedesktop.org, dri-devel@lists.sourceforge.net Subject: Re: [Intel-gfx] [PATCH 6/7] drm/i915: fix page flipping on gen3 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 05 Apr 2010 21:10:36 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9f8589..193bf16 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1475,6 +1475,10 @@ static int i915_load_modeset_init(struct drm_device *dev, if (ret) goto destroy_ringbuffer; + /* IIR "flip pending" bit means done if this bit is set */ + if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) + dev_priv->flip_pending_is_done = true; + intel_modeset_init(dev); ret = drm_irq_install(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index abf2713..4e41f0f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -608,6 +608,7 @@ typedef struct drm_i915_private { struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; wait_queue_head_t pending_flip_queue; + bool flip_pending_is_done; /* Reclocking support */ bool render_reclock_avail; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b16bb0d..79cbead 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -924,22 +924,30 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); } - if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) + if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { intel_prepare_page_flip(dev, 0); + if (dev_priv->flip_pending_is_done) + intel_finish_page_flip_plane(dev, 0); + } - if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) + if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) { intel_prepare_page_flip(dev, 1); + if (dev_priv->flip_pending_is_done) + intel_finish_page_flip_plane(dev, 1); + } if (pipea_stats & pipe_vblank_mask) { vblank++; drm_handle_vblank(dev, 0); - intel_finish_page_flip(dev, 0); + if (!dev_priv->flip_pending_is_done) + intel_finish_page_flip(dev, 0); } if (pipeb_stats & pipe_vblank_mask) { vblank++; drm_handle_vblank(dev, 1); - intel_finish_page_flip(dev, 1); + if (!dev_priv->flip_pending_is_done) + intel_finish_page_flip(dev, 1); } if ((pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index df20187..9179b38 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -178,6 +178,7 @@ #define MI_OVERLAY_OFF (0x2<<21) #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) +#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ @@ -357,6 +358,9 @@ #define CM0_RC_OP_FLUSH_DISABLE (1<<0) #define BB_ADDR 0x02140 /* 8 bytes */ #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ +#define ECOSKPD 0x021d0 +#define ECO_GATING_CX_ONLY (1<<3) +#define ECO_FLIP_DONE (1<<0) /* diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0e2c5da..6f5e7f5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4136,10 +4136,10 @@ static void intel_unpin_work_fn(struct work_struct *__work) kfree(work); } -void intel_finish_page_flip(struct drm_device *dev, int pipe) +static void do_intel_finish_page_flip(struct drm_device *dev, + struct drm_crtc *crtc) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; struct drm_i915_gem_object *obj_priv; @@ -4189,6 +4189,22 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) schedule_work(&work->work); } +void intel_finish_page_flip(struct drm_device *dev, int pipe) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + + do_intel_finish_page_flip(dev, crtc); +} + +void intel_finish_page_flip_plane(struct drm_device *dev, int plane) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; + + do_intel_finish_page_flip(dev, crtc); +} + void intel_prepare_page_flip(struct drm_device *dev, int plane) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -4270,14 +4286,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->pending_flip_obj = obj; BEGIN_LP_RING(4); - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch); if (IS_I965G(dev)) { + OUT_RING(MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch); OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); pipesrc = I915_READ(pipesrc_reg); OUT_RING(pipesrc & 0x0fff0fff); } else { + OUT_RING(MI_DISPLAY_FLIP_I915 | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch); OUT_RING(obj_priv->gtt_offset); OUT_RING(MI_NOOP); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3a467ca..8323225 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -219,6 +219,7 @@ extern int intel_framebuffer_create(struct drm_device *dev, extern void intel_prepare_page_flip(struct drm_device *dev, int plane); extern void intel_finish_page_flip(struct drm_device *dev, int pipe); +extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); extern void intel_setup_overlay(struct drm_device *dev); extern void intel_cleanup_overlay(struct drm_device *dev);