Fix and cleanup of Hotplug

This commit is contained in:
Jakob Bornecrantz 2007-12-18 02:09:48 +01:00 committed by Jakob Bornecrantz
parent e239882b1e
commit bdbc34e297
3 changed files with 41 additions and 20 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}
}