From patchwork Mon Jun 12 15:24:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Manna, Animesh" X-Patchwork-Id: 9781419 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2CB8260244 for ; Mon, 12 Jun 2017 15:26:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1825D2807B for ; Mon, 12 Jun 2017 15:26:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0CDF528522; Mon, 12 Jun 2017 15:26:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 60D052807B for ; Mon, 12 Jun 2017 15:26:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3FCF6892B6; Mon, 12 Jun 2017 15:26:06 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id D10E66E14C for ; Mon, 12 Jun 2017 15:26:04 +0000 (UTC) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga104.jf.intel.com with ESMTP; 12 Jun 2017 08:26:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,334,1493708400"; d="scan'208";a="113872609" Received: from amanna-desktop.iind.intel.com ([10.223.25.34]) by fmsmga006.fm.intel.com with ESMTP; 12 Jun 2017 08:26:02 -0700 From: Animesh Manna To: intel-gfx@lists.freedesktop.org Date: Mon, 12 Jun 2017 20:54:07 +0530 Message-Id: <1497281047-25204-6-git-send-email-animesh.manna@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1497281047-25204-1-git-send-email-animesh.manna@intel.com> References: <1497281047-25204-1-git-send-email-animesh.manna@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 5/5] drm/i915: Enable HPD interrupts with master ctl interrupt X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP While suspending the device hpd related interrupts are enabled to get the interrupt when device is in suspend state. Though display is in DC9 but system can be in S0 or S0i3 state. Hot plug during S0 state will generate de_port_interrupt but if system is in S0i3 state then display driver will get hotplug interrupt as pcu_hpd_interrupt which will come via pmc. So added the interrupt handling for pcu hpd interrupt. v1: Initial version as RFC. v2: Based on review comments from Imre, Ville, - separate hpd_bxt_pcu structure added. - pcu_irq_ack/pcu_irq_handler pair added to handle pcu interrupt. - sequence for enabling pcu interrupt is modified. - Removed the definition of pcu interrupt mask bit as it is matching with enable bit. Cc: Imre Deak Cc: Ville Syrjälä Signed-off-by: Animesh Manna Signed-off-by: A.Sunil Kamath --- drivers/gpu/drm/i915/i915_irq.c | 69 +++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/i915_reg.h | 8 ++++ drivers/gpu/drm/i915/intel_runtime_pm.c | 3 +- 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4cd9ee1..1981234 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -115,6 +115,12 @@ [HPD_PORT_C] = BXT_DE_PORT_HP_DDIC }; +static const u32 hpd_bxt_pcu[HPD_NUM_PINS] = { + [HPD_PORT_A] = BXT_PCU_DC9_HP_DDIA, + [HPD_PORT_B] = BXT_PCU_DC9_HP_DDIB, + [HPD_PORT_C] = BXT_PCU_DC9_HP_DDIC +}; + /* IIR can theoretically queue up two events. Be paranoid. */ #define GEN8_IRQ_RESET_NDX(type, which) do { \ I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ @@ -2565,12 +2571,48 @@ static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv, return ret; } +static irqreturn_t +gen8_pcu_irq_ack(struct drm_i915_private *dev_priv, + u32 master_ctl, u32 *pcu_iir) +{ + irqreturn_t ret = IRQ_NONE; + + if (master_ctl & GEN8_PCU_IRQ) { + *pcu_iir = I915_READ(GEN8_PCU_IIR); + + if (*pcu_iir) { + I915_WRITE(GEN8_PCU_IIR, *pcu_iir); + ret = IRQ_HANDLED; + } else { + DRM_ERROR("The master control interrupt lied (PCU)!\n"); + } + } + + return ret; +} + +static void +gen8_pcu_irq_handler(struct drm_i915_private *dev_priv, u32 pcu_iir) +{ + bool found = false; + + if (IS_BROXTON(dev_priv) && (pcu_iir & BXT_PCU_DC9_HOTPLUG_MASK)) { + u32 tmp_mask = pcu_iir & BXT_PCU_DC9_HOTPLUG_MASK; + + bxt_hpd_irq_handler(dev_priv, tmp_mask, hpd_bxt_pcu); + found = true; + } + if ((!found) && pcu_iir) + DRM_ERROR("Unexpected PCU interrupt\n"); +} + static irqreturn_t gen8_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); u32 master_ctl; u32 gt_iir[4] = {}; + u32 pcu_iir = 0; irqreturn_t ret; if (!intel_irqs_enabled(dev_priv)) @@ -2588,7 +2630,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) /* Find, clear, then process each source of interrupt */ ret = gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir); + ret |= gen8_pcu_irq_ack(dev_priv, master_ctl, &pcu_iir); gen8_gt_irq_handler(dev_priv, gt_iir); + gen8_pcu_irq_handler(dev_priv, pcu_iir); ret |= gen8_de_irq_handler(dev_priv, master_ctl); I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); @@ -2990,9 +3034,11 @@ static void gen8_irq_reset(struct drm_device *dev) struct drm_i915_private *dev_priv = to_i915(dev); int pipe; - I915_WRITE(GEN8_MASTER_IRQ, 0); - POSTING_READ(GEN8_MASTER_IRQ); - + if (!dev_priv->vbt.hpd_wakeup_enabled) { + I915_WRITE(GEN8_MASTER_IRQ, 0); + POSTING_READ(GEN8_MASTER_IRQ); + GEN5_IRQ_RESET(GEN8_DE_PORT_); + } gen8_gt_irq_reset(dev_priv); for_each_pipe(dev_priv, pipe) @@ -3000,7 +3046,6 @@ static void gen8_irq_reset(struct drm_device *dev) POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); - GEN5_IRQ_RESET(GEN8_DE_PORT_); GEN5_IRQ_RESET(GEN8_DE_MISC_); GEN5_IRQ_RESET(GEN8_PCU_); @@ -4382,6 +4427,17 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) dev_priv->pm.irqs_enabled = false; } +static void bxt_enable_pcu_interrupt(struct drm_i915_private *dev_priv) +{ + u32 de_pcu_hpd_enable_mask, de_pcu_imr, de_pcu_ier; + + de_pcu_hpd_enable_mask = BXT_PCU_DC9_HOTPLUG_MASK; + + de_pcu_imr = (I915_READ(GEN8_PCU_IMR) & ~de_pcu_hpd_enable_mask); + de_pcu_ier = (I915_READ(GEN8_PCU_IER) | de_pcu_hpd_enable_mask); + GEN5_IRQ_INIT(GEN8_PCU_, de_pcu_imr, de_pcu_ier); +} + /** * intel_runtime_pm_disable_interrupts - runtime interrupt disabling * @dev_priv: i915 device instance @@ -4394,6 +4450,11 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) dev_priv->drm.driver->irq_uninstall(&dev_priv->drm); dev_priv->pm.irqs_enabled = false; synchronize_irq(dev_priv->drm.irq); + + if (IS_BROXTON(dev_priv) && dev_priv->vbt.hpd_wakeup_enabled) { + bxt_enable_pcu_interrupt(dev_priv); + dev_priv->pm.irqs_enabled = true; + } } /** diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b6d69e2..f8c347d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6471,6 +6471,14 @@ enum { #define GEN8_PCU_IIR _MMIO(0x444e8) #define GEN8_PCU_IER _MMIO(0x444ec) +/* BXT PCU DC9 hotplug control */ +#define BXT_PCU_DC9_HP_DDIA (1<<31) +#define BXT_PCU_DC9_HP_DDIB (1<<30) +#define BXT_PCU_DC9_HP_DDIC (1<<29) +#define BXT_PCU_DC9_HOTPLUG_MASK (BXT_PCU_DC9_HP_DDIA | \ + BXT_PCU_DC9_HP_DDIB | \ + BXT_PCU_DC9_HP_DDIC) + #define ILK_DISPLAY_CHICKEN2 _MMIO(0x42004) /* Required on all Ironlake and Sandybridge according to the B-Spec. */ #define ILK_ELPIN_409_SELECT (1 << 25) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 8a6f287..7add767 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -550,7 +550,8 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, "DC5 still not disabled to enable DC9.\n"); WARN_ONCE(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n"); - WARN_ONCE(intel_irqs_enabled(dev_priv), + if (!dev_priv->vbt.hpd_wakeup_enabled) + WARN_ONCE(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); /*