summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_crtc.c2
-rw-r--r--linux-core/intel_sdvo.c17
-rw-r--r--shared-core/i915_irq.c42
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);
}
}