Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Egbert Eich <eich@suse.de>
To: intel-gfx@lists.freedesktop.org
Cc: Egbert Eich <eich@suse.de>, Chris Wilson <chris.wilson@intel.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>
Subject: [PATCH v.2 03/12] DRM/i915: Convert HPD interrupts to make use of HPD pin assignment in encoders (v2)
Date: Thu, 28 Feb 2013 04:17:12 -0500	[thread overview]
Message-ID: <1362043032-20707-1-git-send-email-eich@suse.de> (raw)
In-Reply-To: <20130228001233.GC3840@cantiga.alporthouse.com>

This allows to enable HPD interrupts for individual pins to only receive
hotplug events from lines which are connected and working.

v2: Restructured initailization of const arrays following a suggstion
    by Chris Wilson <chris@chris-wilson.co.uk>

Signed-off-by: Egbert Eich <eich@suse.de>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_irq.c |  151 ++++++++++++++++++++++++---------------
 drivers/gpu/drm/i915/i915_reg.h |   32 ++++++++-
 2 files changed, 123 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5fd3267..7bdc90c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -36,6 +36,59 @@
 #include "i915_trace.h"
 #include "intel_drv.h"
 
+static const u32 hpd_ibx[] = {
+	[HPD_CRT] = SDE_CRT_HOTPLUG,
+	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
+	[HPD_PORT_B] = SDE_PORTB_HOTPLUG,
+	[HPD_PORT_C] = SDE_PORTC_HOTPLUG,
+	[HPD_PORT_D] = SDE_PORTD_HOTPLUG
+};
+
+static const u32 hpd_cpt[] = {
+	[HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
+	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
+	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
+	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
+};
+
+static const u32 hpd_mask_i915[] = {
+	[HPD_CRT] = CRT_HOTPLUG_INT_EN,
+	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
+	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
+	[HPD_PORT_B] = PORTB_HOTPLUG_INT_EN,
+	[HPD_PORT_C] = PORTC_HOTPLUG_INT_EN,
+	[HPD_PORT_D] = PORTD_HOTPLUG_INT_EN
+};
+
+static const u32 hpd_status_gen4[] = {
+	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
+	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
+	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
+	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
+	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
+	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
+};
+
+static const u32 hpd_status_i965[] = {
+	 [HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
+	 [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I965,
+	 [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I965,
+	 [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
+	 [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
+	 [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
+};
+
+static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
+	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
+	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
+	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
+	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
+	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
+	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
+};
+
+
+
 /* For display hotplug interrupt */
 static void
 ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
@@ -596,7 +649,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
 
 			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 					 hotplug_status);
-			if (hotplug_status & dev_priv->hotplug_supported_mask)
+			if (hotplug_status & HOTPLUG_INT_STATUS_I915)
 				queue_work(dev_priv->wq,
 					   &dev_priv->hotplug_work);
 
@@ -1940,17 +1993,21 @@ static void ibx_enable_hotplug(struct drm_device *dev)
 static void ibx_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-	u32 mask;
-
-	if (HAS_PCH_IBX(dev))
-		mask = SDE_HOTPLUG_MASK |
-		       SDE_GMBUS |
-		       SDE_AUX_MASK;
-	else
-		mask = SDE_HOTPLUG_MASK_CPT |
-		       SDE_GMBUS_CPT |
-		       SDE_AUX_MASK_CPT;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_encoder *intel_encoder;
+	u32 mask = I915_READ(SDEIER);
 
+	if (HAS_PCH_IBX(dev)) {
+		mask &= ~SDE_HOTPLUG_MASK;
+		list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
+			mask |= hpd_ibx[intel_encoder->hpd_pin];
+		mask |= SDE_GMBUS | SDE_AUX_MASK;
+	} else {
+		mask &= ~SDE_HOTPLUG_MASK_CPT;
+		list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
+			mask |= hpd_cpt[intel_encoder->hpd_pin];
+		mask |= SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
+	}
 	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
 	I915_WRITE(SDEIMR, ~mask);
 	I915_WRITE(SDEIER, mask);
@@ -2360,26 +2417,16 @@ static int i915_irq_postinstall(struct drm_device *dev)
 
 static void i915_hpd_irq_setup(struct drm_device *dev)
 {
-	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-	u32 hotplug_en;
-
 	if (I915_HAS_HOTPLUG(dev)) {
-		hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+		drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+		struct drm_mode_config *mode_config = &dev->mode_config;
+		struct intel_encoder *encoder;
+		u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
 
-		if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS)
-			hotplug_en |= PORTB_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS)
-			hotplug_en |= PORTC_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS)
-			hotplug_en |= PORTD_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915)
-			hotplug_en |= SDVOC_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915)
-			hotplug_en |= SDVOB_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
-			hotplug_en |= CRT_HOTPLUG_INT_EN;
-			hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
-		}
+		hotplug_en &= ~HOTPLUG_INT_EN_MASK;
+		list_for_each_entry(encoder, &mode_config->encoder_list, base.head)
+			hotplug_en |= hpd_mask_i915[encoder->hpd_pin];
+		hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
 
 		/* Ignore TV since it's buggy */
 
@@ -2443,7 +2490,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
 
 			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 				  hotplug_status);
-			if (hotplug_status & dev_priv->hotplug_supported_mask)
+			if (hotplug_status & HOTPLUG_INT_STATUS_I915)
 				queue_work(dev_priv->wq,
 					   &dev_priv->hotplug_work);
 
@@ -2596,38 +2643,22 @@ static int i965_irq_postinstall(struct drm_device *dev)
 static void i965_hpd_irq_setup(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_encoder *encoder;
 	u32 hotplug_en;
 
 	/* Note HDMI and DP share hotplug bits */
 	hotplug_en = 0;
-	if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS)
-		hotplug_en |= PORTB_HOTPLUG_INT_EN;
-	if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS)
-		hotplug_en |= PORTC_HOTPLUG_INT_EN;
-	if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS)
-		hotplug_en |= PORTD_HOTPLUG_INT_EN;
-	if (IS_G4X(dev)) {
-		if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X)
-			hotplug_en |= SDVOC_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_G4X)
-			hotplug_en |= SDVOB_HOTPLUG_INT_EN;
-	} else {
-		if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I965)
-			hotplug_en |= SDVOC_HOTPLUG_INT_EN;
-		if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I965)
-			hotplug_en |= SDVOB_HOTPLUG_INT_EN;
-	}
-	if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
-		hotplug_en |= CRT_HOTPLUG_INT_EN;
-
-		/* Programming the CRT detection parameters tends
-		   to generate a spurious hotplug event about three
-		   seconds later.  So just do it once.
-		   */
-		if (IS_G4X(dev))
-			hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
-		hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
-	}
+	list_for_each_entry(encoder, &mode_config->encoder_list, base.head)
+		/* enable bits are the same for all generations */
+		hotplug_en |= hpd_mask_i915[encoder->hpd_pin];
+	/* Programming the CRT detection parameters tends
+	   to generate a spurious hotplug event about three
+	   seconds later.  So just do it once.
+	*/
+	if (IS_G4X(dev))
+		hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
+	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
 
 	/* Ignore TV since it's buggy */
 
@@ -2690,7 +2721,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
 
 			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 				  hotplug_status);
-			if (hotplug_status & dev_priv->hotplug_supported_mask)
+			if (hotplug_status & (IS_G4X(dev) ?
+					      HOTPLUG_INT_STATUS_G4X :
+					      HOTPLUG_INT_STATUS_I965))
 				queue_work(dev_priv->wq,
 					   &dev_priv->hotplug_work);
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 527b664..c3d2c01 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1637,6 +1637,12 @@
 #define   SDVOC_HOTPLUG_INT_EN			(1 << 25)
 #define   TV_HOTPLUG_INT_EN			(1 << 18)
 #define   CRT_HOTPLUG_INT_EN			(1 << 9)
+#define HOTPLUG_INT_EN_MASK			(PORTB_HOTPLUG_INT_EN | \
+						 PORTC_HOTPLUG_INT_EN | \
+						 PORTD_HOTPLUG_INT_EN | \
+						 SDVOC_HOTPLUG_INT_EN | \
+						 SDVOB_HOTPLUG_INT_EN | \
+						 CRT_HOTPLUG_INT_EN)
 #define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
 #define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
 /* must use period 64 on GM45 according to docs */
@@ -1675,6 +1681,26 @@
 #define   SDVOB_HOTPLUG_INT_STATUS_I965		(3 << 2)
 #define   SDVOC_HOTPLUG_INT_STATUS_I915		(1 << 7)
 #define   SDVOB_HOTPLUG_INT_STATUS_I915		(1 << 6)
+#define   HOTPLUG_INT_STATUS_G4X		(CRT_HOTPLUG_INT_STATUS | \
+						 SDVOB_HOTPLUG_INT_STATUS_G4X | \
+						 SDVOC_HOTPLUG_INT_STATUS_G4X | \
+						 PORTB_HOTPLUG_INT_STATUS | \
+						 PORTC_HOTPLUG_INT_STATUS | \
+						 PORTD_HOTPLUG_INT_STATUS)
+
+#define HOTPLUG_INT_STATUS_I965			(CRT_HOTPLUG_INT_STATUS | \
+						 SDVOB_HOTPLUG_INT_STATUS_I965 | \
+						 SDVOC_HOTPLUG_INT_STATUS_I965 | \
+						 PORTB_HOTPLUG_INT_STATUS | \
+						 PORTC_HOTPLUG_INT_STATUS | \
+						 PORTD_HOTPLUG_INT_STATUS)
+
+#define HOTPLUG_INT_STATUS_I915			(CRT_HOTPLUG_INT_STATUS | \
+						 SDVOB_HOTPLUG_INT_STATUS_I915 | \
+						 SDVOC_HOTPLUG_INT_STATUS_I915 | \
+						 PORTB_HOTPLUG_INT_STATUS | \
+						 PORTC_HOTPLUG_INT_STATUS | \
+						 PORTD_HOTPLUG_INT_STATUS)
 
 /* SDVO port control */
 #define SDVOB			0x61140
@@ -3508,7 +3534,11 @@
 #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 SDE_HOTPLUG_MASK        (SDE_CRT_HOTPLUG | \
+				 SDE_SDVOB_HOTPLUG |	\
+				 SDE_PORTB_HOTPLUG |	\
+				 SDE_PORTC_HOTPLUG |	\
+				 SDE_PORTD_HOTPLUG)
 #define SDE_TRANSB_CRC_DONE	(1 << 5)
 #define SDE_TRANSB_CRC_ERR	(1 << 4)
 #define SDE_TRANSB_FIFO_UNDER	(1 << 3)
-- 
1.7.7

  reply	other threads:[~2013-02-28 10:21 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-10 15:02 [PATCH 0/8] Detect and deal with Interrupt 'Storms' from noisy Hotplug Lines Egbert Eich
2013-01-10 15:02 ` [PATCH 1/8] drm/i915: Remove pch_rq_mask from struct drm_i915_private Egbert Eich
2013-01-11 20:13   ` Daniel Vetter
2013-01-10 15:02 ` [PATCH 2/8] drm/i915: Set hotplug_supported_flag for all chipset generations Egbert Eich
2013-03-26 19:51   ` Jesse Barnes
2013-01-10 15:02 ` [PATCH 3/8] drm/i915: Add hpd status bit to struct intel_connector Egbert Eich
2013-03-26 19:53   ` Jesse Barnes
2013-01-10 15:02 ` [PATCH 4/8] drm/i915: Add Hotplug IRQ Storm detection Egbert Eich
2013-03-26 19:59   ` Jesse Barnes
2013-01-10 15:02 ` [PATCH 5/8] drm/i915: Move hotplug interrupt enable for i915/i965/valleyview into a separate function Egbert Eich
2013-03-26 20:04   ` Jesse Barnes
2013-01-10 15:02 ` [PATCH 6/8] drm/i915: Only enable hotplug irq when needed on Ironlake and later chips Egbert Eich
2013-01-10 15:02 ` [PATCH 7/8] drm/i915: When detecting a hotplug IRQ storm disable respective IRQs Egbert Eich
2013-01-10 15:02 ` [PATCH 8/8] drm/i915: Add Reenable Timer to turn Hotplug Detection back on Egbert Eich
2013-01-11 20:34 ` [PATCH 0/8] Detect and deal with Interrupt 'Storms' from noisy Hotplug Lines Daniel Vetter
2013-01-17 14:01   ` Egbert Eich
2013-01-17 14:45     ` Daniel Vetter
2013-01-22 13:22       ` Egbert Eich
2013-01-22 13:48         ` Daniel Vetter
2013-01-22 15:11           ` Egbert Eich
2013-02-25 17:06           ` [PATCH v.2 00/12] " Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 01/12] DRM/i915: Remove valleyview_hpd_irq_setup Egbert Eich
2013-03-26 20:06               ` Jesse Barnes
2013-02-25 17:06             ` [PATCH v.2 02/12] DRM/I915: Add enum hpd_pin to intel_encoder Egbert Eich
2013-03-26 20:07               ` Jesse Barnes
2013-02-25 17:06             ` [PATCH v.2 03/12] DRM/i915: Convert HPD interrupts to make use of HPD pin assignment in encoders Egbert Eich
2013-02-28  0:12               ` Chris Wilson
2013-02-28  9:17                 ` Egbert Eich [this message]
2013-03-26 20:08               ` Jesse Barnes
2013-02-25 17:06             ` [PATCH v.2 04/12] DRM/i915: Remove i965_hpd_irq_setup Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 05/12] DRM/i915: Get rid if the 'hotplug_supported_mask' in struct drm_i915_private Egbert Eich
2013-03-26 21:06               ` Daniel Vetter
2013-03-27 15:08                 ` Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 06/12] DRM/i915: Add HPD IRQ storm detection Egbert Eich
2013-02-28  0:30               ` Chris Wilson
2013-02-28  9:19                 ` [PATCH v.2 06/12] DRM/i915: Add HPD IRQ storm detection (v2) Egbert Eich
2013-03-03 18:07                   ` Daniel Vetter
2013-03-05  7:38                     ` [PATCH v.3 06/12] DRM/i915: Add HPD IRQ storm detection (v3) Egbert Eich
2013-03-05  7:48                       ` [PATCH v.2 10/12] DRM/i915: Add Reenable Timer to turn Hotplug Detection back on (v2) Egbert Eich
2013-03-05 10:28                         ` Ville Syrjälä
2013-03-05 12:26                           ` [PATCH v.3 10/12] DRM/i915: Add Reenable Timer to turn Hotplug Detection back on (v3) Egbert Eich
2013-03-05  7:55                       ` [PATCH v.2 11/12] DRM/i915: Add bit field to record which pins have received HPD events (v2) Egbert Eich
2013-03-05 13:00                         ` [PATCH v.3 11/12] DRM/i915: Add bit field to record which pins have received HPD events (v3) Egbert Eich
2013-03-05 14:52                           ` Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 07/12] DRM/i915: (re)init HPD interrupt storm statistics Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 08/12] DRM/i915: Treat hpd_irq_setup() for ironake and older generations the same way Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 09/12] DRM/i915: Disable HPD interrupt on pin when irq storm is detected Egbert Eich
2013-03-05 12:34               ` [PATCH v.2 09/12] DRM/i915: Disable HPD interrupt on pin when irq storm is detected (v2) Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 10/12] DRM/i915: Add Reenable Timer to turn Hotplug Detection back on Egbert Eich
2013-03-27 15:12               ` Daniel Vetter
2013-02-25 17:06             ` [PATCH v.2 11/12] DRM/i915: Add bit field to record which pins have received HPD events Egbert Eich
2013-02-25 17:06             ` [PATCH v.2 12/12] DRM/i915: Only reprobe display on encoder which has received an HPD event Egbert Eich
2013-03-05 14:18               ` [PATCH v.3 " Egbert Eich
2013-02-28  0:46             ` [PATCH v.2 00/12] Detect and deal with Interrupt 'Storms' from noisy Hotplug Lines Chris Wilson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1362043032-20707-1-git-send-email-eich@suse.de \
    --to=eich@suse.de \
    --cc=chris.wilson@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=rodrigo.vivi@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox