aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorEgbert Eich <eich@suse.de>2013-02-28 04:17:12 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-26 16:52:19 -0400
commite5868a318d1ae28f760f77bb91ce5deb751733fd (patch)
tree12e4ec4d4f18fff537105d7797f47397fe8dbfa2 /drivers/gpu/drm/i915/i915_irq.c
parent1d843f9de4e6dc6a899b6f07f106c00da09925e6 (diff)
DRM/i915: Convert HPD interrupts to make use of HPD pin assignment in encoders (v2)
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> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v1) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c155
1 files changed, 94 insertions, 61 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 1a24744f7a27..ef9fce50530d 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -36,6 +36,59 @@
36#include "i915_trace.h" 36#include "i915_trace.h"
37#include "intel_drv.h" 37#include "intel_drv.h"
38 38
39static const u32 hpd_ibx[] = {
40 [HPD_CRT] = SDE_CRT_HOTPLUG,
41 [HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
42 [HPD_PORT_B] = SDE_PORTB_HOTPLUG,
43 [HPD_PORT_C] = SDE_PORTC_HOTPLUG,
44 [HPD_PORT_D] = SDE_PORTD_HOTPLUG
45};
46
47static const u32 hpd_cpt[] = {
48 [HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
49 [HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
50 [HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
51 [HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
52};
53
54static const u32 hpd_mask_i915[] = {
55 [HPD_CRT] = CRT_HOTPLUG_INT_EN,
56 [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
57 [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
58 [HPD_PORT_B] = PORTB_HOTPLUG_INT_EN,
59 [HPD_PORT_C] = PORTC_HOTPLUG_INT_EN,
60 [HPD_PORT_D] = PORTD_HOTPLUG_INT_EN
61};
62
63static const u32 hpd_status_gen4[] = {
64 [HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
65 [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
66 [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
67 [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
68 [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
69 [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
70};
71
72static const u32 hpd_status_i965[] = {
73 [HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
74 [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I965,
75 [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I965,
76 [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
77 [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
78 [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
79};
80
81static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
82 [HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
83 [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
84 [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
85 [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
86 [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
87 [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
88};
89
90
91
39/* For display hotplug interrupt */ 92/* For display hotplug interrupt */
40static void 93static void
41ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) 94ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
@@ -599,7 +652,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
599 652
600 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", 653 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
601 hotplug_status); 654 hotplug_status);
602 if (hotplug_status & dev_priv->hotplug_supported_mask) 655 if (hotplug_status & HOTPLUG_INT_STATUS_I915)
603 queue_work(dev_priv->wq, 656 queue_work(dev_priv->wq,
604 &dev_priv->hotplug_work); 657 &dev_priv->hotplug_work);
605 658
@@ -2034,17 +2087,21 @@ static void ibx_enable_hotplug(struct drm_device *dev)
2034static void ibx_irq_postinstall(struct drm_device *dev) 2087static void ibx_irq_postinstall(struct drm_device *dev)
2035{ 2088{
2036 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 2089 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2037 u32 mask; 2090 struct drm_mode_config *mode_config = &dev->mode_config;
2038 2091 struct intel_encoder *intel_encoder;
2039 if (HAS_PCH_IBX(dev)) 2092 u32 mask = I915_READ(SDEIER);
2040 mask = SDE_HOTPLUG_MASK | 2093
2041 SDE_GMBUS | 2094 if (HAS_PCH_IBX(dev)) {
2042 SDE_AUX_MASK; 2095 mask &= ~SDE_HOTPLUG_MASK;
2043 else 2096 list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
2044 mask = SDE_HOTPLUG_MASK_CPT | 2097 mask |= hpd_ibx[intel_encoder->hpd_pin];
2045 SDE_GMBUS_CPT | 2098 mask |= SDE_GMBUS | SDE_AUX_MASK;
2046 SDE_AUX_MASK_CPT; 2099 } else {
2047 2100 mask &= ~SDE_HOTPLUG_MASK_CPT;
2101 list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
2102 mask |= hpd_cpt[intel_encoder->hpd_pin];
2103 mask |= SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
2104 }
2048 I915_WRITE(SDEIIR, I915_READ(SDEIIR)); 2105 I915_WRITE(SDEIIR, I915_READ(SDEIIR));
2049 I915_WRITE(SDEIMR, ~mask); 2106 I915_WRITE(SDEIMR, ~mask);
2050 I915_WRITE(SDEIER, mask); 2107 I915_WRITE(SDEIER, mask);
@@ -2466,26 +2523,16 @@ static int i915_irq_postinstall(struct drm_device *dev)
2466 2523
2467static void i915_hpd_irq_setup(struct drm_device *dev) 2524static void i915_hpd_irq_setup(struct drm_device *dev)
2468{ 2525{
2469 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2470 u32 hotplug_en;
2471
2472 if (I915_HAS_HOTPLUG(dev)) { 2526 if (I915_HAS_HOTPLUG(dev)) {
2473 hotplug_en = I915_READ(PORT_HOTPLUG_EN); 2527 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2474 2528 struct drm_mode_config *mode_config = &dev->mode_config;
2475 if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) 2529 struct intel_encoder *encoder;
2476 hotplug_en |= PORTB_HOTPLUG_INT_EN; 2530 u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
2477 if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) 2531
2478 hotplug_en |= PORTC_HOTPLUG_INT_EN; 2532 hotplug_en &= ~HOTPLUG_INT_EN_MASK;
2479 if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) 2533 list_for_each_entry(encoder, &mode_config->encoder_list, base.head)
2480 hotplug_en |= PORTD_HOTPLUG_INT_EN; 2534 hotplug_en |= hpd_mask_i915[encoder->hpd_pin];
2481 if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) 2535 hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
2482 hotplug_en |= SDVOC_HOTPLUG_INT_EN;
2483 if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915)
2484 hotplug_en |= SDVOB_HOTPLUG_INT_EN;
2485 if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
2486 hotplug_en |= CRT_HOTPLUG_INT_EN;
2487 hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
2488 }
2489 2536
2490 /* Ignore TV since it's buggy */ 2537 /* Ignore TV since it's buggy */
2491 2538
@@ -2576,7 +2623,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
2576 2623
2577 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", 2624 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
2578 hotplug_status); 2625 hotplug_status);
2579 if (hotplug_status & dev_priv->hotplug_supported_mask) 2626 if (hotplug_status & HOTPLUG_INT_STATUS_I915)
2580 queue_work(dev_priv->wq, 2627 queue_work(dev_priv->wq,
2581 &dev_priv->hotplug_work); 2628 &dev_priv->hotplug_work);
2582 2629
@@ -2725,38 +2772,22 @@ static int i965_irq_postinstall(struct drm_device *dev)
2725static void i965_hpd_irq_setup(struct drm_device *dev) 2772static void i965_hpd_irq_setup(struct drm_device *dev)
2726{ 2773{
2727 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 2774 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2775 struct drm_mode_config *mode_config = &dev->mode_config;
2776 struct intel_encoder *encoder;
2728 u32 hotplug_en; 2777 u32 hotplug_en;
2729 2778
2730 /* Note HDMI and DP share hotplug bits */ 2779 /* Note HDMI and DP share hotplug bits */
2731 hotplug_en = 0; 2780 hotplug_en = 0;
2732 if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) 2781 list_for_each_entry(encoder, &mode_config->encoder_list, base.head)
2733 hotplug_en |= PORTB_HOTPLUG_INT_EN; 2782 /* enable bits are the same for all generations */
2734 if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) 2783 hotplug_en |= hpd_mask_i915[encoder->hpd_pin];
2735 hotplug_en |= PORTC_HOTPLUG_INT_EN; 2784 /* Programming the CRT detection parameters tends
2736 if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) 2785 to generate a spurious hotplug event about three
2737 hotplug_en |= PORTD_HOTPLUG_INT_EN; 2786 seconds later. So just do it once.
2738 if (IS_G4X(dev)) { 2787 */
2739 if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X) 2788 if (IS_G4X(dev))
2740 hotplug_en |= SDVOC_HOTPLUG_INT_EN; 2789 hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
2741 if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_G4X) 2790 hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
2742 hotplug_en |= SDVOB_HOTPLUG_INT_EN;
2743 } else {
2744 if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I965)
2745 hotplug_en |= SDVOC_HOTPLUG_INT_EN;
2746 if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I965)
2747 hotplug_en |= SDVOB_HOTPLUG_INT_EN;
2748 }
2749 if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
2750 hotplug_en |= CRT_HOTPLUG_INT_EN;
2751
2752 /* Programming the CRT detection parameters tends
2753 to generate a spurious hotplug event about three
2754 seconds later. So just do it once.
2755 */
2756 if (IS_G4X(dev))
2757 hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
2758 hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
2759 }
2760 2791
2761 /* Ignore TV since it's buggy */ 2792 /* Ignore TV since it's buggy */
2762 2793
@@ -2822,7 +2853,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
2822 2853
2823 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", 2854 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
2824 hotplug_status); 2855 hotplug_status);
2825 if (hotplug_status & dev_priv->hotplug_supported_mask) 2856 if (hotplug_status & (IS_G4X(dev) ?
2857 HOTPLUG_INT_STATUS_G4X :
2858 HOTPLUG_INT_STATUS_I965))
2826 queue_work(dev_priv->wq, 2859 queue_work(dev_priv->wq,
2827 &dev_priv->hotplug_work); 2860 &dev_priv->hotplug_work);
2828 2861