summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@nietzche.virtuousgeek.org>2008-05-12 15:47:19 -0700
committerJesse Barnes <jbarnes@nietzche.virtuousgeek.org>2008-05-12 15:47:19 -0700
commitd32ce7f621c0d8e42cdf88ce6f1d15638a3d34b7 (patch)
treed670f833f4bcedb57815567cf0459bf553d7adf2 /shared-core
parenta51e38548cfdece2978e9b5f0d6f0467ba7a7272 (diff)
i915: TV hotplug fixes
In order to avoid recursive ->detect->interrupt->detect->interrupt->... we need to disable TV hotplug interrupts in intel_tv.c:intel_tv_detect_type. We also need to enable the TV interrupt detection and hotplug sequence properly in i915_irq.c.
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/i915_irq.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index 0ee0c444..4aef568e 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -471,7 +471,6 @@ static void i915_hotplug_tv(struct drm_device *dev)
if (iout == 0)
goto unlock;
- /* may need to I915_WRITE(TVDAC, 1<<31) to ack the interrupt */
status = output->funcs->detect(output);
drm_hotplug_stage_two(dev, output,
status == output_status_connected ? 1 : 0);
@@ -631,7 +630,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
struct drm_i915_master_private *master_priv;
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u32 iir;
- u32 pipea_stats, pipeb_stats;
+ u32 pipea_stats = 0, pipeb_stats, tvdac;
int hotplug = 0;
int vblank = 0;
@@ -672,10 +671,17 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
}
/* This is a global event, and not a pipe A event */
- if ((pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) ||
- (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS))
+ if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS)
hotplug = 1;
+ if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) {
+ hotplug = 1;
+ /* Toggle hotplug detection to clear hotplug status */
+ tvdac = I915_READ(TV_DAC);
+ I915_WRITE(TV_DAC, tvdac & ~TVDAC_STATE_CHG_EN);
+ I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN);
+ }
+
I915_WRITE(I915REG_PIPEASTAT, pipea_stats);
}
@@ -1001,6 +1007,9 @@ void i915_enable_interrupt (struct drm_device *dev)
I915_WRITE(SDVOB, I915_READ(SDVOB) | SDVO_INTERRUPT_ENABLE);
I915_WRITE(SDVOC, I915_READ(SDVOC) | SDVO_INTERRUPT_ENABLE);
+
+ /* TV */
+ I915_WRITE(TV_DAC, I915_READ(TV_DAC) | TVDAC_STATE_CHG_EN);
} else {
/* DVO ???? */
}