mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 15:58:03 +02:00
Fix and cleanup of Hotplug
This commit is contained in:
parent
e239882b1e
commit
bdbc34e297
3 changed files with 41 additions and 20 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue