From bdbc34e297bd7e4cb036df6244dfb0d816eed36d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 18 Dec 2007 02:09:48 +0100 Subject: Fix and cleanup of Hotplug --- linux-core/drm_crtc.c | 2 +- linux-core/intel_sdvo.c | 17 +++++++++++++++-- shared-core/i915_irq.c | 42 +++++++++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index ac2f1d42..4397b867 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1142,7 +1142,7 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output) int has_config = 0; if (output->crtc && output->crtc->desired_mode) { - DRM_DEBUG("drm thinks that output already has a config\n"); + DRM_DEBUG("drm thinks that the output already has a config\n"); has_config = 1; } diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index d2d00e2a..1d7d0b7d 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -53,6 +53,7 @@ struct intel_sdvo_priv { struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; struct intel_sdvo_dtd save_output_dtd[16]; u32 save_SDVOX; + int hotplug_enabled; }; /** @@ -71,9 +72,14 @@ void intel_sdvo_write_sdvox(struct drm_output *output, u32 val) if (sdvo_priv->output_device == SDVOB) { cval = I915_READ(SDVOC); - bval = bval | (1 << 26); + + if (sdvo_priv->hotplug_enabled) + bval = bval | (1 << 26); } else { - bval = I915_READ(SDVOB) | (1 << 26); + bval = I915_READ(SDVOB); + + if (sdvo_priv->hotplug_enabled) + cval = cval | (1 << 26); } /* * Write the registers twice for luck. Sometimes, @@ -927,6 +933,8 @@ int intel_sdvo_supports_hotplug(struct drm_output *output) void intel_sdvo_set_hotplug(struct drm_output *output, int on) { + struct intel_output *intel_output = output->driver_private; + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u8 response[2]; u8 status; @@ -934,11 +942,15 @@ void intel_sdvo_set_hotplug(struct drm_output *output, int on) intel_sdvo_read_response(output, &response, 2); if (on) { + sdvo_priv->hotplug_enabled = 1; + intel_sdvo_write_cmd(output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); status = intel_sdvo_read_response(output, &response, 2); intel_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); } else { + sdvo_priv->hotplug_enabled = 0; + response[0] = 0; response[1] = 0; intel_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); @@ -1064,6 +1076,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) } sdvo_priv->output_device = output_device; + sdvo_priv->hotplug_enabled = 0; intel_output->i2c_bus = i2cbus; intel_output->dev_priv = sdvo_priv; diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4508d146..ac5361f2 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -36,6 +36,7 @@ #define USER_INT_FLAG (1<<1) #define VSYNC_PIPEB_FLAG (1<<5) #define VSYNC_PIPEA_FLAG (1<<7) +#define HOTPLUG_FLAG (1 << 17) #define MAX_NOPID ((u32)~0) @@ -303,6 +304,10 @@ static void i915_vblank_tasklet(struct drm_device *dev) } } +#define HOTPLUG_CMD_CRT 1 +#define HOTPLUG_CMD_SDVOB 4 +#define HOTPLUG_CMD_SDVOC 8 + static struct drm_device *hotplug_dev; static int hotplug_cmd = 0; static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; @@ -359,7 +364,10 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) unlock: mutex_unlock(&dev->mode_config.mutex); } - +/* + * This code is called in a more safe envirmoent to handle the hotplugs. + * Add code here for hotplug love to userspace. + */ static void i915_hotplug_work_func(struct work_struct *work) { struct drm_device *dev = hotplug_dev; @@ -368,9 +376,9 @@ static void i915_hotplug_work_func(struct work_struct *work) int sdvoC; spin_lock(&hotplug_lock); - crt = hotplug_cmd & 1; - sdvoB = hotplug_cmd & 4; - sdvoC = hotplug_cmd & 8; + crt = hotplug_cmd & HOTPLUG_CMD_CRT; + sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB; + sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC; hotplug_cmd = 0; spin_unlock(&hotplug_lock); @@ -392,31 +400,31 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) hotplug_dev = dev; - if (stat & (1 << 11)) { + if (stat & CRT_HOTPLUG_INT_STATUS) { DRM_DEBUG("CRT event\n"); - if (stat & (1 << 9) && stat & (1 << 8)) { + if (stat & CRT_HOTPLUG_MONITOR_MASK) { spin_lock(&hotplug_lock); - hotplug_cmd |= 1; + hotplug_cmd |= HOTPLUG_CMD_CRT; spin_unlock(&hotplug_lock); } else { /* handle crt disconnects */ } } - if (stat & (1 << 6)) { + if (stat & SDVOB_HOTPLUG_INT_STATUS) { DRM_DEBUG("sDVOB event\n"); spin_lock(&hotplug_lock); - hotplug_cmd |= 4; + hotplug_cmd |= HOTPLUG_CMD_SDVOB; spin_unlock(&hotplug_lock); } - if (stat & (1 << 7)) { + if (stat & SDVOC_HOTPLUG_INT_STATUS) { DRM_DEBUG("sDVOC event\n"); spin_lock(&hotplug_lock); - hotplug_cmd |= 8; + hotplug_cmd |= HOTPLUG_CMD_SDVOC; spin_unlock(&hotplug_lock); } @@ -513,7 +521,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) /* for now lest just ack it */ if (temp & (1 << 17)) { - DRM_DEBUG("Hotplug event recived\n"); + DRM_DEBUG("Hotplug event received\n"); temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -705,24 +713,24 @@ 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 (IS_I9XX(dev) && dev->mode_config.funcs) { - dev_priv->irq_enable_reg |= (1 << 17); + if (IS_I9XX(dev) && dev->mode_config.num_output) { + dev_priv->irq_enable_reg |= HOTPLUG_FLAG; /* Activate the CRT */ - I915_WRITE(PORT_HOTPLUG_EN, (1 << 9)); + I915_WRITE(PORT_HOTPLUG_EN, CRT_HOTPLUG_INT_EN); /* SDVOB */ o = intel_sdvo_find(dev, 1); if (o && intel_sdvo_supports_hotplug(o)) { intel_sdvo_set_hotplug(o, 1); - I915_WRITE(PORT_HOTPLUG_EN, (1 << 26)); + I915_WRITE(PORT_HOTPLUG_EN, SDVOB_HOTPLUG_INT_EN); } /* SDVOC */ o = intel_sdvo_find(dev, 0); if (o && intel_sdvo_supports_hotplug(o)) { intel_sdvo_set_hotplug(o, 1); - I915_WRITE(PORT_HOTPLUG_EN, (1 << 25)); + I915_WRITE(PORT_HOTPLUG_EN, SDVOC_HOTPLUG_INT_EN); } } -- cgit v1.2.3