summaryrefslogtreecommitdiff
path: root/shared-core/i915_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core/i915_irq.c')
-rw-r--r--shared-core/i915_irq.c142
1 files changed, 42 insertions, 100 deletions
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index eac1c5e5..0d96dc57 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -307,60 +307,11 @@ static struct drm_device *hotplug_dev;
static int hotplug_cmd = 0;
static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED;
-/* TODO
- * The locking in these functions are realy messed up.
- * Currently the stage 1 functions takes both the locks.
- * But have to release it since intel_fb_probe grabs the
- * struct_mTODO utex. So to do this as cleanly as possible
- * you need to release the locks between stage 1 and 2.
- */
-
-static void i915_hotplug_stage2(struct drm_device *dev, struct drm_output *output)
-{
- int has_config = 0;
-
- mutex_lock(&dev->struct_mutex);
-
- if (output->crtc && output->crtc->desired_mode) {
- DRM_DEBUG("monkey has banana\n");
- has_config = 1;
- }
-
- drm_crtc_probe_output_modes(dev, 2048, 2048);
-
- if (!has_config)
- drm_pick_crtcs(dev);
-
- if (!output->crtc || !output->crtc->desired_mode) {
- DRM_DEBUG("no desired mode or no crtc found\n");
- goto unlock;
- }
-
- mutex_unlock(&dev->struct_mutex);
-
- DRM_DEBUG("monkey eating banana\n");
- /* We should realy check if there is a fb using this crtc */
- if (!has_config)
- dev->driver->fb_probe(dev, output->crtc);
- else {
- intelfb_resize(dev, output->crtc);
- if (!drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0))
- DRM_ERROR("setting mode failed\n");
- }
-
- drm_disable_unused_functions(dev);
-
-unlock:
- mutex_unlock(&dev->struct_mutex);
-
-}
-
static void i915_hotplug_crt(struct drm_device *dev)
{
struct drm_output *output;
struct intel_output *iout;
- mutex_lock(&dev->struct_mutex);
mutex_lock(&dev->mode_config.mutex);
/* find the crt output */
@@ -375,19 +326,10 @@ static void i915_hotplug_crt(struct drm_device *dev)
if (iout == 0)
goto unlock;
- /* TODO ugly locking */
- mutex_unlock(&dev->struct_mutex);
-
- i915_hotplug_stage2(dev, output);
-
- mutex_unlock(&dev->mode_config.mutex);
- return;
+ drm_hotplug_stage_two(dev, output);
unlock:
mutex_unlock(&dev->mode_config.mutex);
- mutex_unlock(&dev->struct_mutex);
-
- DRM_DEBUG("monkey hunt done\n");
}
static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
@@ -395,7 +337,6 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
struct drm_output *output = 0;
enum drm_output_status status;
- mutex_lock(&dev->struct_mutex);
mutex_lock(&dev->mode_config.mutex);
output = intel_sdvo_find(dev, sdvoB);
@@ -407,25 +348,16 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
status = output->funcs->detect(output);
- if (status != output_status_connected) {
+ if (status != output_status_connected)
DRM_DEBUG("disconnect or unkown we don't do anything then\n");
- intel_sdvo_set_hotplug(output, 1);
- goto unlock;
- }
-
- /* TODO ugly locking */
- mutex_unlock(&dev->struct_mutex);
-
- i915_hotplug_stage2(dev, output);
+ else
+ drm_hotplug_stage_two(dev, output);
+ /* wierd hw bug, sdvo stop sending interupts */
intel_sdvo_set_hotplug(output, 1);
- mutex_unlock(&dev->mode_config.mutex);
- return;
-
unlock:
mutex_unlock(&dev->mode_config.mutex);
- mutex_unlock(&dev->struct_mutex);
}
static void i915_hotplug_work_func(struct work_struct *work)
@@ -497,7 +429,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- u32 temp;
+ u32 temp = 0;
u32 temp2;
u32 pipea_stats, pipeb_stats;
@@ -505,39 +437,39 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
/* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */
- /* if (IS_I9XX(dev)) */ {
+ if (IS_I9XX(dev)) {
temp = I915_READ(I915REG_INT_IDENTITY_R);
- } /* else {
+ } else {
temp = I915_READ16(I915REG_INT_IDENTITY_R);
- } */
+ }
temp2 = temp;
temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
-#if 1
+#if 0
/* ugly despamification of pipeb event irq */
if (temp & (0xFFFFFFF ^ ((1 << 5) | (1 << 7)))) {
DRM_DEBUG("IIR %08x\n", temp2);
DRM_DEBUG("MSK %08x\n", dev_priv->irq_enable_reg | USER_INT_FLAG);
DRM_DEBUG("M&I %08x\n", temp);
DRM_DEBUG("HOT %08x\n", I915_READ(PORT_HOTPLUG_STAT));
- } else {
- /* DRM_DEBUG("v\n"); */
}
#else
+#if 0
DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
#endif
+#endif
if (temp == 0)
return IRQ_NONE;
- /* if (IS_I9XX(dev)) */ {
+ if (IS_I9XX(dev)) {
I915_WRITE(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ(I915REG_INT_IDENTITY_R);
- } /* else {
+ } else {
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ16(I915REG_INT_IDENTITY_R);
- } */
+ }
DRM_READMEMORYBARRIER();
@@ -762,27 +694,33 @@ void i915_enable_interrupt (struct drm_device *dev)
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
- /* if (dev_priv->mode_setting) */ {
+ if (IS_I9XX(dev) && dev->mode_config.funcs) {
dev_priv->irq_enable_reg |= (1 << 17);
- /* Activate the CRT and SDVOB hotplug detection */
- I915_WRITE(PORT_HOTPLUG_EN, (1 << 9) | (1 << 26));
+ /* Activate the CRT */
+ I915_WRITE(PORT_HOTPLUG_EN, (1 << 9));
+ /* SDVOB */
o = intel_sdvo_find(dev, 1);
- if (o) {
- intel_sdvo_supports_hotplug(o);
+ if (o && intel_sdvo_supports_hotplug(o)) {
+ intel_sdvo_set_hotplug(o, 1);
+ I915_WRITE(PORT_HOTPLUG_EN, (1 << 26));
+ }
+ /* SDVOC */
+ o = intel_sdvo_find(dev, 0);
+ if (o && intel_sdvo_supports_hotplug(o)) {
intel_sdvo_set_hotplug(o, 1);
- I915_WRITE(SDVOB, I915_READ(SDVOB) | (1 << 26));
- I915_WRITE(SDVOB, I915_READ(SDVOB) | (1 << 26));
+ I915_WRITE(PORT_HOTPLUG_EN, (1 << 25));
}
+
}
- /* if (IS_I9XX(dev_priv)) */ {
+ if (IS_I9XX(dev)) {
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
- } /* else {
+ } else {
I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
- } */
+ }
DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN));
DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT));
@@ -792,8 +730,6 @@ void i915_enable_interrupt (struct drm_device *dev)
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
dev_priv->irq_enabled = 1;
-
- DRM_DEBUG("enabled\n");
}
/* Set the vblank monitor pipe
@@ -997,8 +933,14 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
I915_WRITE16(I915REG_HWSTAM, 0xeffe);
- I915_WRITE(I915REG_INT_MASK_R, 0x0);
- I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
+ if (IS_I9XX(dev)) {
+ I915_WRITE(I915REG_INT_MASK_R, 0x0);
+ I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
+ } else {
+ I915_WRITE16(I915REG_INT_MASK_R, 0x0);
+ I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
+ }
+
}
void i915_driver_irq_postinstall(struct drm_device * dev)
@@ -1033,19 +975,19 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv->irq_enabled = 0;
- /* if(IS_I9XX(dev_priv) */ {
+ if(IS_I9XX(dev)) {
I915_WRITE(I915REG_HWSTAM, 0xffffffff);
I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
temp = I915_READ(I915REG_INT_IDENTITY_R);
I915_WRITE(I915REG_INT_IDENTITY_R, temp);
- } /* else {
+ } else {
I915_WRITE16(I915REG_HWSTAM, 0xffff);
I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
temp = I915_READ16(I915REG_INT_IDENTITY_R);
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
- } */
+ }
}