From patchwork Sun Apr 28 00:59:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 2497701 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 778F33FC64 for ; Sun, 28 Apr 2013 01:04:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 333D6E5CCA for ; Sat, 27 Apr 2013 18:04:08 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from shiva.localdomain (unknown [209.20.75.48]) by gabe.freedesktop.org (Postfix) with ESMTP id 23665E5C72 for ; Sat, 27 Apr 2013 17:59:39 -0700 (PDT) Received: by shiva.localdomain (Postfix, from userid 1005) id 1CD578865C; Sun, 28 Apr 2013 00:59:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on shiva.chad-versace.us X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, URIBL_BLOCKED autolearn=unavailable version=3.3.2 Received: from vandamme.jf.intel.com (jfdmzpr06-ext.jf.intel.com [134.134.137.75]) by shiva.localdomain (Postfix) with ESMTPSA id 23D418865B; Sun, 28 Apr 2013 00:59:38 +0000 (UTC) From: Ben Widawsky To: Intel-GFX Date: Sat, 27 Apr 2013 17:59:19 -0700 Message-Id: <1367110769-1306-9-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1367110769-1306-1-git-send-email-ben@bwidawsk.net> References: <1367110769-1306-1-git-send-email-ben@bwidawsk.net> Cc: Ben Widawsky Subject: [Intel-gfx] [PATCH 08/18] drm/i915: Create a more generic pm handler for hsw+ X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org HSW has some special requirements for the VEBOX. Splitting out the interrupt handler will make the code a bit nicer and less error prone when we begin to handle those. The slight functional change in this patch (queueing work while holding the spinlock) is intentional as it makes a subsequent patch a bit nicer. The change should also only effect HSW platforms. Based on patches from: CC: Haihao Xiang Signed-off-by: Ben Widawsky Reviewed-by: Damien Lespiau --- drivers/gpu/drm/i915/i915_irq.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 125b45a..98af4fe 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -843,6 +843,7 @@ static void snb_gt_irq_handler(struct drm_device *dev, ivybridge_handle_parity_error(dev); } +/* Legacy way of handling PM interrupts */ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, u32 pm_iir) { @@ -922,6 +923,31 @@ static void dp_aux_irq_handler(struct drm_device *dev) wake_up_all(&dev_priv->gmbus_wait_queue); } +/* Unlike gen6_queue_rps_work() from which this function is originally derived, + * we must be able to deal with other PM interrupts. This is complicated because + * of the way in which we use the masks to defer the RPS work (which for + * posterity is necessary because of forcewake). + */ +static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + u32 pm_iir) +{ + unsigned long flags; + + spin_lock_irqsave(&dev_priv->rps.lock, flags); + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_DEFERRED_EVENTS; + if (dev_priv->rps.pm_iir) { + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + /* We never want to mask useful interrupts. (also posting read) */ + WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_DEFERRED_EVENTS); + /* TODO: if queue_work is slow, move it out of the spinlock */ + queue_work(dev_priv->wq, &dev_priv->rps.work); + } + spin_unlock_irqrestore(&dev_priv->rps.lock, flags); + + if (pm_iir & ~GEN6_PM_DEFERRED_EVENTS) + DRM_ERROR("Unexpected PM interrupted\n"); +} + static irqreturn_t valleyview_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *) arg; @@ -1232,7 +1258,9 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) pm_iir = I915_READ(GEN6_PMIIR); if (pm_iir) { - if (pm_iir & GEN6_PM_DEFERRED_EVENTS) + if (IS_HASWELL(dev)) + hsw_pm_irq_handler(dev_priv, pm_iir); + else if (pm_iir & GEN6_PM_DEFERRED_EVENTS) gen6_queue_rps_work(dev_priv, pm_iir); I915_WRITE(GEN6_PMIIR, pm_iir); ret = IRQ_HANDLED;