diff options
author | Zhenyu Wang <zhenyuw@linux.intel.com> | 2009-11-03 13:57:21 -0500 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-11-05 17:49:37 -0500 |
commit | c650156af34bffa3d3a62c9fe26eee595aab3fd1 (patch) | |
tree | 7b5e322e49fa39a3dd11e4dc0511188eb9ec9d91 /drivers/gpu/drm/i915 | |
parent | 01c66889c14aa163c49355b3be2ccfb214500599 (diff) |
drm/i915: Add display hotplug event on Ironlake
Enable display hotplug irqs from Ibex Peak (PCH).
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 |
3 files changed, 34 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 210d0f690dbb..835625ba7c9c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -214,6 +214,8 @@ typedef struct drm_i915_private { | |||
214 | u32 gt_irq_mask_reg; | 214 | u32 gt_irq_mask_reg; |
215 | u32 gt_irq_enable_reg; | 215 | u32 gt_irq_enable_reg; |
216 | u32 de_irq_enable_reg; | 216 | u32 de_irq_enable_reg; |
217 | u32 pch_irq_mask_reg; | ||
218 | u32 pch_irq_enable_reg; | ||
217 | 219 | ||
218 | u32 hotplug_supported_mask; | 220 | u32 hotplug_supported_mask; |
219 | struct work_struct hotplug_work; | 221 | struct work_struct hotplug_work; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ce337be4bbcd..024fb954db37 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -270,19 +270,24 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
270 | { | 270 | { |
271 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 271 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
272 | int ret = IRQ_NONE; | 272 | int ret = IRQ_NONE; |
273 | u32 de_iir, gt_iir; | 273 | u32 de_iir, gt_iir, pch_iir; |
274 | u32 new_de_iir, new_gt_iir; | 274 | u32 new_de_iir, new_gt_iir, new_pch_iir; |
275 | struct drm_i915_master_private *master_priv; | 275 | struct drm_i915_master_private *master_priv; |
276 | 276 | ||
277 | de_iir = I915_READ(DEIIR); | 277 | de_iir = I915_READ(DEIIR); |
278 | gt_iir = I915_READ(GTIIR); | 278 | gt_iir = I915_READ(GTIIR); |
279 | pch_iir = I915_READ(SDEIIR); | ||
279 | 280 | ||
280 | for (;;) { | 281 | for (;;) { |
281 | if (de_iir == 0 && gt_iir == 0) | 282 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) |
282 | break; | 283 | break; |
283 | 284 | ||
284 | ret = IRQ_HANDLED; | 285 | ret = IRQ_HANDLED; |
285 | 286 | ||
287 | /* should clear PCH hotplug event before clear CPU irq */ | ||
288 | I915_WRITE(SDEIIR, pch_iir); | ||
289 | new_pch_iir = I915_READ(SDEIIR); | ||
290 | |||
286 | I915_WRITE(DEIIR, de_iir); | 291 | I915_WRITE(DEIIR, de_iir); |
287 | new_de_iir = I915_READ(DEIIR); | 292 | new_de_iir = I915_READ(DEIIR); |
288 | I915_WRITE(GTIIR, gt_iir); | 293 | I915_WRITE(GTIIR, gt_iir); |
@@ -305,8 +310,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
305 | if (de_iir & DE_GSE) | 310 | if (de_iir & DE_GSE) |
306 | ironlake_opregion_gse_intr(dev); | 311 | ironlake_opregion_gse_intr(dev); |
307 | 312 | ||
313 | /* check event from PCH */ | ||
314 | if ((de_iir & DE_PCH_EVENT) && | ||
315 | (pch_iir & SDE_HOTPLUG_MASK)) { | ||
316 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | ||
317 | } | ||
318 | |||
308 | de_iir = new_de_iir; | 319 | de_iir = new_de_iir; |
309 | gt_iir = new_gt_iir; | 320 | gt_iir = new_gt_iir; |
321 | pch_iir = new_pch_iir; | ||
310 | } | 322 | } |
311 | 323 | ||
312 | return ret; | 324 | return ret; |
@@ -1003,14 +1015,21 @@ static void igdng_irq_preinstall(struct drm_device *dev) | |||
1003 | I915_WRITE(GTIMR, 0xffffffff); | 1015 | I915_WRITE(GTIMR, 0xffffffff); |
1004 | I915_WRITE(GTIER, 0x0); | 1016 | I915_WRITE(GTIER, 0x0); |
1005 | (void) I915_READ(GTIER); | 1017 | (void) I915_READ(GTIER); |
1018 | |||
1019 | /* south display irq */ | ||
1020 | I915_WRITE(SDEIMR, 0xffffffff); | ||
1021 | I915_WRITE(SDEIER, 0x0); | ||
1022 | (void) I915_READ(SDEIER); | ||
1006 | } | 1023 | } |
1007 | 1024 | ||
1008 | static int igdng_irq_postinstall(struct drm_device *dev) | 1025 | static int igdng_irq_postinstall(struct drm_device *dev) |
1009 | { | 1026 | { |
1010 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1027 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1011 | /* enable kind of interrupts always enabled */ | 1028 | /* enable kind of interrupts always enabled */ |
1012 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE /*| DE_PCH_EVENT */; | 1029 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT; |
1013 | u32 render_mask = GT_USER_INTERRUPT; | 1030 | u32 render_mask = GT_USER_INTERRUPT; |
1031 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | ||
1032 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | ||
1014 | 1033 | ||
1015 | dev_priv->irq_mask_reg = ~display_mask; | 1034 | dev_priv->irq_mask_reg = ~display_mask; |
1016 | dev_priv->de_irq_enable_reg = display_mask; | 1035 | dev_priv->de_irq_enable_reg = display_mask; |
@@ -1030,6 +1049,14 @@ static int igdng_irq_postinstall(struct drm_device *dev) | |||
1030 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); | 1049 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); |
1031 | (void) I915_READ(GTIER); | 1050 | (void) I915_READ(GTIER); |
1032 | 1051 | ||
1052 | dev_priv->pch_irq_mask_reg = ~hotplug_mask; | ||
1053 | dev_priv->pch_irq_enable_reg = hotplug_mask; | ||
1054 | |||
1055 | I915_WRITE(SDEIIR, I915_READ(SDEIIR)); | ||
1056 | I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg); | ||
1057 | I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg); | ||
1058 | (void) I915_READ(SDEIER); | ||
1059 | |||
1033 | return 0; | 1060 | return 0; |
1034 | } | 1061 | } |
1035 | 1062 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e8c6d00cde97..b11a682a4cff 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2126,6 +2126,7 @@ | |||
2126 | #define SDE_PORTC_HOTPLUG (1 << 9) | 2126 | #define SDE_PORTC_HOTPLUG (1 << 9) |
2127 | #define SDE_PORTB_HOTPLUG (1 << 8) | 2127 | #define SDE_PORTB_HOTPLUG (1 << 8) |
2128 | #define SDE_SDVOB_HOTPLUG (1 << 6) | 2128 | #define SDE_SDVOB_HOTPLUG (1 << 6) |
2129 | #define SDE_HOTPLUG_MASK (0xf << 8) | ||
2129 | 2130 | ||
2130 | #define SDEISR 0xc4000 | 2131 | #define SDEISR 0xc4000 |
2131 | #define SDEIMR 0xc4004 | 2132 | #define SDEIMR 0xc4004 |