From patchwork Tue Nov 3 18:57:21 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenyu Wang X-Patchwork-Id: 57449 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA41Vkpa021105 for ; Wed, 4 Nov 2009 01:31:46 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 940E59E9D9; Tue, 3 Nov 2009 17:31:45 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 209329E92B for ; Tue, 3 Nov 2009 17:31:43 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 03 Nov 2009 17:17:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.44,677,1249282800"; d="scan'208";a="566266709" Received: from debian-ilk.sh.intel.com (HELO localhost.localdomain) ([10.239.47.163]) by orsmga001.jf.intel.com with ESMTP; 03 Nov 2009 17:31:36 -0800 From: Zhenyu Wang To: eric@anholt.net Date: Wed, 4 Nov 2009 02:57:21 +0800 Message-Id: <1257274641-7847-1-git-send-email-zhenyuw@linux.intel.com> X-Mailer: git-send-email 1.6.3.3 Cc: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH] drm/i915: Add display hotplug event on Ironlake X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 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@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7357c29..751b1ef 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -211,6 +211,8 @@ typedef struct drm_i915_private { u32 gt_irq_mask_reg; u32 gt_irq_enable_reg; u32 de_irq_enable_reg; + u32 pch_irq_mask_reg; + u32 pch_irq_enable_reg; u32 hotplug_supported_mask; struct work_struct hotplug_work; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f1fbfdd..7489ea0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -268,19 +268,24 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = IRQ_NONE; - u32 de_iir, gt_iir; - u32 new_de_iir, new_gt_iir; + u32 de_iir, gt_iir, pch_iir; + u32 new_de_iir, new_gt_iir, new_pch_iir; struct drm_i915_master_private *master_priv; de_iir = I915_READ(DEIIR); gt_iir = I915_READ(GTIIR); + pch_iir = I915_READ(SDEIIR); for (;;) { - if (de_iir == 0 && gt_iir == 0) + if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) break; ret = IRQ_HANDLED; + /* should clear PCH hotplug event before clear CPU irq */ + I915_WRITE(SDEIIR, pch_iir); + new_pch_iir = I915_READ(SDEIIR); + I915_WRITE(DEIIR, de_iir); new_de_iir = I915_READ(DEIIR); I915_WRITE(GTIIR, gt_iir); @@ -303,8 +308,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) if (de_iir & DE_GSE) ironlake_opregion_gse_intr(dev); + /* check event from PCH */ + if ((de_iir & DE_PCH_EVENT) && + (pch_iir & SDE_HOTPLUG_MASK)) { + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } + de_iir = new_de_iir; gt_iir = new_gt_iir; + pch_iir = new_pch_iir; } return ret; @@ -1001,14 +1013,21 @@ static void igdng_irq_preinstall(struct drm_device *dev) I915_WRITE(GTIMR, 0xffffffff); I915_WRITE(GTIER, 0x0); (void) I915_READ(GTIER); + + /* south display irq */ + I915_WRITE(SDEIMR, 0xffffffff); + I915_WRITE(SDEIER, 0x0); + (void) I915_READ(SDEIER); } static int igdng_irq_postinstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; /* enable kind of interrupts always enabled */ - u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE /*| DE_PCH_EVENT */; + u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT; u32 render_mask = GT_USER_INTERRUPT; + u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | + SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; dev_priv->irq_mask_reg = ~display_mask; dev_priv->de_irq_enable_reg = display_mask; @@ -1028,6 +1047,14 @@ static int igdng_irq_postinstall(struct drm_device *dev) I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); (void) I915_READ(GTIER); + dev_priv->pch_irq_mask_reg = ~hotplug_mask; + dev_priv->pch_irq_enable_reg = hotplug_mask; + + I915_WRITE(SDEIIR, I915_READ(SDEIIR)); + I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg); + I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg); + (void) I915_READ(SDEIER); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1687edf..59e26fb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2117,6 +2117,7 @@ #define SDE_PORTC_HOTPLUG (1 << 9) #define SDE_PORTB_HOTPLUG (1 << 8) #define SDE_SDVOB_HOTPLUG (1 << 6) +#define SDE_HOTPLUG_MASK (0xf << 8) #define SDEISR 0xc4000 #define SDEIMR 0xc4004