From 34be91fe4e9f0ad73b7c4354aea0c8ce10f45f68 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 26 Apr 2007 14:50:00 +1000 Subject: i915: fix vblank pipe setup --- shared-core/i915_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4047e77e..870fe402 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -489,7 +489,7 @@ int i915_irq_wait(DRM_IOCTL_ARGS) return i915_wait_irq(dev, irqwait.irq_seq); } -static void i915_enable_interrupt (drm_device_t *dev) +void i915_enable_interrupt (drm_device_t *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; -- cgit v1.2.3 From 462d5a0dfc80dfa02da3d24d30ad90ad0387f0a2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 22 May 2007 17:49:04 -0700 Subject: Suspend/resume support (incomplete). --- shared-core/i915_irq.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4ceed3e3..2d4df76e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -438,6 +438,19 @@ static int i915_driver_vblank_do_wait(drm_device_t *dev, unsigned int *sequence, return ret; } +void i915_driver_wait_next_vblank(drm_device_t *dev, int pipe) +{ + unsigned int seq; + + seq = pipe ? atomic_read(&dev->vbl_received2) + 1 : + atomic_read(&dev->vbl_received) + 1; + + if (!pipe) + i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received); + else + i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received2); +} + int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) { return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); -- cgit v1.2.3 From e239882b1e90cba0297118ec7dc432bea06b0bd0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 4 Dec 2007 15:36:36 +0100 Subject: Modesetting Hotplug --- shared-core/i915_irq.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 225 insertions(+), 13 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4312eae2..4508d146 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -31,6 +31,8 @@ #include "i915_drm.h" #include "i915_drv.h" +#include "intel_drv.h" + #define USER_INT_FLAG (1<<1) #define VSYNC_PIPEB_FLAG (1<<5) #define VSYNC_PIPEA_FLAG (1<<7) @@ -301,27 +303,174 @@ static void i915_vblank_tasklet(struct drm_device *dev) } } +static struct drm_device *hotplug_dev; +static int hotplug_cmd = 0; +static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; + +static void i915_hotplug_crt(struct drm_device *dev) +{ + struct drm_output *output; + struct intel_output *iout; + + mutex_lock(&dev->mode_config.mutex); + + /* find the crt output */ + list_for_each_entry(output, &dev->mode_config.output_list, head) { + iout = output->driver_private; + if (iout->type == INTEL_OUTPUT_ANALOG) + break; + else + iout = 0; + } + + if (iout == 0) + goto unlock; + + drm_hotplug_stage_two(dev, output); + +unlock: + mutex_unlock(&dev->mode_config.mutex); +} + +static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) +{ + struct drm_output *output = 0; + enum drm_output_status status; + + mutex_lock(&dev->mode_config.mutex); + + output = intel_sdvo_find(dev, sdvoB); + + if (!output) { + DRM_ERROR("could not find sdvo%s output\n", sdvoB ? "B" : "C"); + goto unlock; + } + + status = output->funcs->detect(output); + + if (status != output_status_connected) + DRM_DEBUG("disconnect or unkown we don't do anything then\n"); + else + drm_hotplug_stage_two(dev, output); + + /* wierd hw bug, sdvo stop sending interupts */ + intel_sdvo_set_hotplug(output, 1); + +unlock: + mutex_unlock(&dev->mode_config.mutex); +} + +static void i915_hotplug_work_func(struct work_struct *work) +{ + struct drm_device *dev = hotplug_dev; + int crt; + int sdvoB; + int sdvoC; + + spin_lock(&hotplug_lock); + crt = hotplug_cmd & 1; + sdvoB = hotplug_cmd & 4; + sdvoC = hotplug_cmd & 8; + hotplug_cmd = 0; + spin_unlock(&hotplug_lock); + + if (crt) + i915_hotplug_crt(dev); + + if (sdvoB) + i915_hotplug_sdvo(dev, 1); + + if (sdvoC) + i915_hotplug_sdvo(dev, 0); + +} + +static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) +{ + static DECLARE_WORK(hotplug, i915_hotplug_work_func); + struct drm_i915_private *dev_priv = dev->dev_private; + + hotplug_dev = dev; + + if (stat & (1 << 11)) { + DRM_DEBUG("CRT event\n"); + + if (stat & (1 << 9) && stat & (1 << 8)) { + spin_lock(&hotplug_lock); + hotplug_cmd |= 1; + spin_unlock(&hotplug_lock); + } else { + /* handle crt disconnects */ + } + } + + if (stat & (1 << 6)) { + DRM_DEBUG("sDVOB event\n"); + + spin_lock(&hotplug_lock); + hotplug_cmd |= 4; + spin_unlock(&hotplug_lock); + } + + if (stat & (1 << 7)) { + DRM_DEBUG("sDVOC event\n"); + + spin_lock(&hotplug_lock); + hotplug_cmd |= 8; + spin_unlock(&hotplug_lock); + } + + queue_work(dev_priv->wq, &hotplug); + + return 0; +} + 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; - u16 temp; + u32 temp = 0; + u32 temp2; u32 pipea_stats, pipeb_stats; pipea_stats = I915_READ(I915REG_PIPEASTAT); pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - temp = I915_READ16(I915REG_INT_IDENTITY_R); + /* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */ + if (IS_I9XX(dev)) { + temp = I915_READ(I915REG_INT_IDENTITY_R); + } else { + temp = I915_READ16(I915REG_INT_IDENTITY_R); + } + + temp2 = temp; temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG); +#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 #if 0 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); #endif +#endif + if (temp == 0) return IRQ_NONE; - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ16(I915REG_INT_IDENTITY_R); + if (IS_I9XX(dev)) { + I915_WRITE(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ(I915REG_INT_IDENTITY_R); + } else { + I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + } + DRM_READMEMORYBARRIER(); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -362,6 +511,17 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_VBLANK_CLEAR); } + /* for now lest just ack it */ + if (temp & (1 << 17)) { + DRM_DEBUG("Hotplug event recived\n"); + + temp2 = I915_READ(PORT_HOTPLUG_STAT); + + i915_run_hotplug_tasklet(dev, temp2); + + I915_WRITE(PORT_HOTPLUG_STAT,temp2); + } + return IRQ_HANDLED; } @@ -536,6 +696,7 @@ int i915_irq_wait(struct drm_device *dev, void *data, void i915_enable_interrupt (struct drm_device *dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + struct drm_output *o; dev_priv->irq_enable_reg = USER_INT_FLAG; @@ -544,7 +705,41 @@ 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; - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && dev->mode_config.funcs) { + dev_priv->irq_enable_reg |= (1 << 17); + + /* Activate the CRT */ + I915_WRITE(PORT_HOTPLUG_EN, (1 << 9)); + + /* 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)); + } + + /* 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)); + } + + } + + if (IS_I9XX(dev)) { + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + } 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)); + DRM_DEBUG("IER %08x\n",I915_READ(I915REG_INT_ENABLE_R)); + DRM_DEBUG("SDB %08x\n",I915_READ(SDVOB)); + + I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + dev_priv->irq_enabled = 1; } @@ -749,8 +944,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_WRITE16(I915REG_INT_MASK_R, 0x0); - I915_WRITE16(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) @@ -777,16 +978,27 @@ void i915_driver_irq_postinstall(struct drm_device * dev) void i915_driver_irq_uninstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - u16 temp; + u32 temp; if (!dev_priv) return; dev_priv->irq_enabled = 0; - 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); + + 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 { + 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); + } } -- cgit v1.2.3 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 --- shared-core/i915_irq.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'shared-core/i915_irq.c') 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 From 53937a189f8dbe2dd82fb97c0e88454d29a6c7cd Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 5 Feb 2008 10:12:21 +0000 Subject: build fix for older kernels --- shared-core/i915_irq.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 9b391b75..836a8c46 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -476,7 +476,11 @@ unlock: * This code is called in a more safe envirmoent to handle the hotplugs. * Add code here for hotplug love to userspace. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void i915_hotplug_work_func(void *work) +#else static void i915_hotplug_work_func(struct work_struct *work) +#endif { struct drm_device *dev = hotplug_dev; int crt; @@ -503,7 +507,11 @@ static void i915_hotplug_work_func(struct work_struct *work) static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + static DECLARE_WORK(hotplug, i915_hotplug_work_func, NULL); +#else static DECLARE_WORK(hotplug, i915_hotplug_work_func); +#endif struct drm_i915_private *dev_priv = dev->dev_private; hotplug_dev = dev; -- cgit v1.2.3 From 0618ac8a07d834e469cb96818a1dfee6f50662b8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 7 Feb 2008 19:24:58 +0100 Subject: Added kernel part of hotplug ioctl --- shared-core/i915_irq.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 836a8c46..5f6fa56d 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -413,6 +413,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) } #define HOTPLUG_CMD_CRT 1 +#define HOTPLUG_CMD_CRT_DIS 2 #define HOTPLUG_CMD_SDVOB 4 #define HOTPLUG_CMD_SDVOC 8 @@ -420,7 +421,7 @@ static struct drm_device *hotplug_dev; static int hotplug_cmd = 0; static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; -static void i915_hotplug_crt(struct drm_device *dev) +static void i915_hotplug_crt(struct drm_device *dev, bool connected) { struct drm_output *output; struct intel_output *iout; @@ -439,7 +440,7 @@ static void i915_hotplug_crt(struct drm_device *dev) if (iout == 0) goto unlock; - drm_hotplug_stage_two(dev, output); + drm_hotplug_stage_two(dev, output, connected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -462,9 +463,9 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) status = output->funcs->detect(output); if (status != output_status_connected) - DRM_DEBUG("disconnect or unkown we don't do anything then\n"); + drm_hotplug_stage_two(dev, output, false); else - drm_hotplug_stage_two(dev, output); + drm_hotplug_stage_two(dev, output, true); /* wierd hw bug, sdvo stop sending interupts */ intel_sdvo_set_hotplug(output, 1); @@ -484,18 +485,22 @@ static void i915_hotplug_work_func(struct work_struct *work) { struct drm_device *dev = hotplug_dev; int crt; + int crtDis; int sdvoB; int sdvoC; spin_lock(&hotplug_lock); crt = hotplug_cmd & HOTPLUG_CMD_CRT; + crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS; sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB; sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC; hotplug_cmd = 0; spin_unlock(&hotplug_lock); if (crt) - i915_hotplug_crt(dev); + i915_hotplug_crt(dev, true); + if (crtDis) + i915_hotplug_crt(dev, false); if (sdvoB) i915_hotplug_sdvo(dev, 1); @@ -524,7 +529,9 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) hotplug_cmd |= HOTPLUG_CMD_CRT; spin_unlock(&hotplug_lock); } else { - /* handle crt disconnects */ + spin_lock(&hotplug_lock); + hotplug_cmd |= HOTPLUG_CMD_CRT_DIS; + spin_unlock(&hotplug_lock); } } -- cgit v1.2.3 From 8bf8cd63bb4631b57ceb27058f81d767a94edc74 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Feb 2008 07:37:34 +1000 Subject: missing bits --- shared-core/i915_irq.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 5f6fa56d..dad6ef86 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -107,8 +107,8 @@ static void i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, int plane) { - struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv; + struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + struct drm_i915_sarea *sarea_priv = master_priv->sarea_priv; u16 x1, y1, x2, y2; int pf_planes = 1 << plane; @@ -153,18 +153,18 @@ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, static void i915_vblank_tasklet(struct drm_device *dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; struct list_head *list, *tmp, hits, *hit; int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; unsigned counter[2]; struct drm_drawable_info *drw; - struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv; + struct drm_i915_sarea *sarea_priv; u32 cpp = dev_priv->cpp, offsets[3]; u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB) : XY_SRC_COPY_BLT_CMD; - u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | - (cpp << 23) | (1 << 24); + u32 pitchropcpp; RING_LOCALS; counter[0] = drm_vblank_count(dev, 0); @@ -192,6 +192,12 @@ static void i915_vblank_tasklet(struct drm_device *dev) if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) continue; + master_priv = vbl_swap->minor->master->driver_priv; + sarea_priv = master_priv->sarea_priv; + + pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); + list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, pipe); @@ -306,7 +312,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) top = upper[plane]; bottom = lower[plane]; - front = (dev_priv->sarea_priv->pf_current_page >> + front = (master_priv->sarea_priv->pf_current_page >> (2 * plane)) & 0x3; back = (front + 1) % num_pages; @@ -559,6 +565,7 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; + struct drm_i915_master_private *master_priv; struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 temp = 0; u32 temp2; @@ -627,7 +634,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + if (dev->primary->master) { + master_priv = dev->primary->master->driver_priv; + master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + } if (temp & USER_INT_FLAG) { DRM_WAKEUP(&dev_priv->irq_queue); @@ -699,6 +709,7 @@ void i915_user_irq_off(struct drm_i915_private *dev_priv) static int i915_wait_irq(struct drm_device * dev, int irq_nr) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + struct drm_i915_master_private *master_priv; int ret = 0; DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, @@ -716,8 +727,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); } + + if (dev->primary->master) { + master_priv = dev->primary->master->driver_priv; + master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + } - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); return ret; } @@ -904,6 +919,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_master_private *master_priv; struct drm_i915_vblank_swap *swap = data; struct drm_i915_vbl_swap *vbl_swap; unsigned int pipe, seqtype, curseq, plane; @@ -916,7 +932,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data, return -EINVAL; } - if (dev_priv->sarea_priv->rotation) { + if (!dev->primary->master) + return -EINVAL; + + master_priv = dev->primary->master->driver_priv; + + if (master_priv->sarea_priv->rotation) { DRM_DEBUG("Rotation not supported\n"); return -EINVAL; } @@ -1037,6 +1058,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, vbl_swap->plane = plane; vbl_swap->sequence = swap->sequence; vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); + vbl_swap->minor = file_priv->minor; if (vbl_swap->flip) swap->sequence++; -- cgit v1.2.3 From 903d9231d6f998657cc80ee6f20ded4df68e691b Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 11 Mar 2008 20:29:37 +0000 Subject: Add support for monitor hotplug signals/waits Also adjust i915 irq handling as it follows the 16bit'ism's of the i8xx series. --- shared-core/i915_irq.c | 246 +++++++++++++++++++++++++++++++------------------ 1 file changed, 158 insertions(+), 88 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index b9d137f4..4127383a 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -34,7 +34,9 @@ #include "intel_drv.h" #define USER_INT_FLAG (1<<1) +#define EVENT_PIPEB_FLAG (1<<4) #define VSYNC_PIPEB_FLAG (1<<5) +#define EVENT_PIPEA_FLAG (1<<6) #define VSYNC_PIPEA_FLAG (1<<7) #define HOTPLUG_FLAG (1 << 17) @@ -158,13 +160,14 @@ static void i915_vblank_tasklet(struct drm_device *dev) int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; unsigned counter[2]; struct drm_drawable_info *drw; - struct drm_i915_sarea *sarea_priv; + struct drm_i915_sarea *sarea_priv = master_priv->sarea_priv; u32 cpp = dev_priv->cpp, offsets[3]; u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB) : XY_SRC_COPY_BLT_CMD; - u32 pitchropcpp; + u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); RING_LOCALS; counter[0] = drm_vblank_count(dev, 0); @@ -434,7 +437,7 @@ static struct drm_device *hotplug_dev; static int hotplug_cmd = 0; static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; -static void i915_hotplug_crt(struct drm_device *dev, bool connected) +static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) { struct drm_output *output; struct intel_output *iout; @@ -453,7 +456,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool connected) if (iout == 0) goto unlock; - drm_hotplug_stage_two(dev, output, connected); + drm_hotplug_stage_two(dev, output, isconnected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -468,10 +471,8 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) output = intel_sdvo_find(dev, sdvoB); - if (!output) { - DRM_ERROR("could not find sdvo%s output\n", sdvoB ? "B" : "C"); + if (!output) goto unlock; - } status = output->funcs->detect(output); @@ -480,7 +481,6 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) else drm_hotplug_stage_two(dev, output, true); - /* wierd hw bug, sdvo stop sending interupts */ intel_sdvo_set_hotplug(output, 1); unlock: @@ -521,6 +521,7 @@ static void i915_hotplug_work_func(struct work_struct *work) if (sdvoC) i915_hotplug_sdvo(dev, 0); + drm_handle_hotplug(dev); } static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) @@ -575,45 +576,21 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_i915_master_private *master_priv; struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 temp = 0; - u32 temp2; u32 pipea_stats, pipeb_stats; - pipea_stats = I915_READ(I915REG_PIPEASTAT); - pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - - /* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */ - if (IS_I9XX(dev)) + /* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */ + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) temp = I915_READ(I915REG_INT_IDENTITY_R); else temp = I915_READ16(I915REG_INT_IDENTITY_R); - temp2 = temp; temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG); -#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 -#if 0 - DRM_DEBUG("flag=%08x\n", temp); -#endif -#endif - if (temp == 0) return IRQ_NONE; - if (IS_I9XX(dev)) { - I915_WRITE(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ(I915REG_INT_IDENTITY_R); - } else { - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ16(I915REG_INT_IDENTITY_R); - } + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); /* * Clear the PIPE(A|B)STAT regs before the IIR otherwise @@ -621,25 +598,40 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) */ if (temp & VSYNC_PIPEA_FLAG) { drm_handle_vblank(dev, i915_get_plane(dev, 0)); - I915_WRITE(I915REG_PIPEASTAT, - pipea_stats | I915_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_CLEAR); + + pipea_stats |= I915_VBLANK_INTERRUPT_ENABLE | + I915_VBLANK_CLEAR; } if (temp & VSYNC_PIPEB_FLAG) { drm_handle_vblank(dev, i915_get_plane(dev, 1)); - I915_WRITE(I915REG_PIPEBSTAT, - pipeb_stats | I915_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_CLEAR); + + pipeb_stats |= I915_VBLANK_INTERRUPT_ENABLE | + I915_VBLANK_CLEAR; } - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */ + if (temp & EVENT_PIPEA_FLAG) + pipea_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | + I915_HOTPLUG_CLEAR; - DRM_READMEMORYBARRIER(); + if (temp & EVENT_PIPEB_FLAG) + pipeb_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | + I915_HOTPLUG_CLEAR; + + I915_WRITE(I915REG_PIPEASTAT, pipea_stats); + (void) I915_READ(I915REG_PIPEASTAT); + I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); + (void) I915_READ(I915REG_PIPEBSTAT); + + /* Clear the generated interrupt */ + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + I915_WRITE(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ(I915REG_INT_IDENTITY_R); + } else { + I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + } - temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG | - VSYNC_PIPEB_FLAG); if (dev->primary->master) { master_priv = dev->primary->master->driver_priv; @@ -658,15 +650,43 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) drm_locked_tasklet(dev, i915_vblank_tasklet); } - /* for now lest just ack it */ - if (temp & (1 << 17)) { - DRM_DEBUG("Hotplug event received\n"); + if (temp & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { + u32 temp2 = 0; - temp2 = I915_READ(PORT_HOTPLUG_STAT); + DRM_INFO("Hotplug event received\n"); - i915_run_hotplug_tasklet(dev, temp2); + if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { +#if 0 + u32 b,c; + + b = I915_READ(SDVOB) & SDVO_PIPE_B_SELECT; + c = I915_READ(SDVOC) & SDVO_PIPE_B_SELECT; + + if (temp & EVENT_PIPEA_FLAG) { + if (!b) + temp2 |= SDVOB_HOTPLUG_INT_STATUS; + if (!c) + temp2 |= SDVOC_HOTPLUG_INT_STATUS; + + } + + if (temp & EVENT_PIPEB_FLAG) { + if (b) + temp2 |= SDVOB_HOTPLUG_INT_STATUS; + if (c) + temp2 |= SDVOC_HOTPLUG_INT_STATUS; + + } +#else + temp2 |= SDVOB_HOTPLUG_INT_STATUS | + SDVOC_HOTPLUG_INT_STATUS; +#endif + } else { + temp2 = I915_READ(PORT_HOTPLUG_STAT); - I915_WRITE(PORT_HOTPLUG_STAT,temp2); + I915_WRITE(PORT_HOTPLUG_STAT, temp2); + } + i915_run_hotplug_tasklet(dev, temp2); } return IRQ_HANDLED; @@ -691,23 +711,33 @@ int i915_emit_irq(struct drm_device *dev) return dev_priv->counter; } -void i915_user_irq_on(struct drm_i915_private *dev_priv) +void i915_user_irq_on(struct drm_device *dev) { + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ dev_priv->irq_enable_reg |= USER_INT_FLAG; - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + else + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } -void i915_user_irq_off(struct drm_i915_private *dev_priv) +void i915_user_irq_off(struct drm_device *dev) { + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { // dev_priv->irq_enable_reg &= ~USER_INT_FLAG; - // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + // I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // else + // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -725,10 +755,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (READ_BREADCRUMB(dev_priv) >= irq_nr) return 0; - i915_user_irq_on(dev_priv); + i915_user_irq_on(dev); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - i915_user_irq_off(dev_priv); + i915_user_irq_off(dev); if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", @@ -803,7 +833,10 @@ int i915_enable_vblank(struct drm_device *dev, int plane) break; } - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + else + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); return 0; } @@ -826,7 +859,10 @@ void i915_disable_vblank(struct drm_device *dev, int plane) break; } - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + else + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } void i915_enable_interrupt (struct drm_device *dev) @@ -836,40 +872,62 @@ void i915_enable_interrupt (struct drm_device *dev) dev_priv->irq_enable_reg |= USER_INT_FLAG; - if (IS_I9XX(dev) && dev->mode_config.num_output) { - dev_priv->irq_enable_reg |= HOTPLUG_FLAG; + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + if (dev->mode_config.num_output) + dev_priv->irq_enable_reg |= HOTPLUG_FLAG; + } else { + if (dev->mode_config.num_output) + dev_priv->irq_enable_reg |= EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG; + + I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, I915_READ(I915REG_PIPEBSTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); + } + + if (dev_priv->irq_enable_reg & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { + u32 temp = 0; - /* Activate the CRT */ - I915_WRITE(PORT_HOTPLUG_EN, CRT_HOTPLUG_INT_EN); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + temp = I915_READ(PORT_HOTPLUG_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, SDVOB_HOTPLUG_INT_EN); + /* Activate the CRT */ + temp |= CRT_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, SDVOC_HOTPLUG_INT_EN); + if (IS_I9XX(dev)) { + /* SDVOB */ + o = intel_sdvo_find(dev, 1); + if (o && intel_sdvo_supports_hotplug(o)) { + intel_sdvo_set_hotplug(o, 1); + temp |= SDVOB_HOTPLUG_INT_EN; + } + + /* SDVOC */ + o = intel_sdvo_find(dev, 0); + if (o && intel_sdvo_supports_hotplug(o)) { + intel_sdvo_set_hotplug(o, 1); + temp |= SDVOC_HOTPLUG_INT_EN; + } + + I915_WRITE(SDVOB, I915_READ(SDVOB) | SDVO_INTERRUPT_ENABLE); + I915_WRITE(SDVOC, I915_READ(SDVOC) | SDVO_INTERRUPT_ENABLE); + } else { + /* DVO ???? */ } + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + I915_WRITE(PORT_HOTPLUG_EN, temp); + + DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN)); + DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT)); + + I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + } } - if (IS_I9XX(dev)) { + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(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)); - DRM_DEBUG("IER %08x\n",I915_READ(I915REG_INT_ENABLE_R)); - DRM_DEBUG("SDB %08x\n",I915_READ(SDVOB)); - - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); dev_priv->irq_enabled = 1; } @@ -909,7 +967,11 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, return -EINVAL; } - flag = I915_READ(I915REG_INT_ENABLE_R); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + flag = I915_READ(I915REG_INT_ENABLE_R); + else + flag = I915_READ16(I915REG_INT_ENABLE_R); + pipe->pipe = 0; if (flag & VSYNC_PIPEA_FLAG) pipe->pipe |= DRM_I915_VBLANK_PIPE_A; @@ -1086,8 +1148,10 @@ void i915_driver_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + I915_WRITE(I915REG_PIPEASTAT, 0xffff); + I915_WRITE(I915REG_PIPEBSTAT, 0xffff); I915_WRITE16(I915REG_HWSTAM, 0xeffe); - if (IS_I9XX(dev)) { + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_INT_MASK_R, 0x0); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); } else { @@ -1114,6 +1178,10 @@ int i915_driver_irq_postinstall(struct drm_device * dev) if (ret) return ret; + ret = drm_hotplug_init(dev); + if (ret) + return ret; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ i915_enable_interrupt(dev); @@ -1138,7 +1206,9 @@ void i915_driver_irq_uninstall(struct drm_device * dev) dev_priv->irq_enabled = 0; - if(IS_I9XX(dev)) { + I915_WRITE(I915REG_PIPEASTAT, 0xffff); + I915_WRITE(I915REG_PIPEBSTAT, 0xffff); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_HWSTAM, 0xffffffff); I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); -- cgit v1.2.3 From cf1a2499ed9a0051bcd8627136fb53b496b6484c Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 11 Mar 2008 21:24:29 +0000 Subject: global hotplug events happen in the pipe A stat register, they are not pipe A specific. Remove pipe B code. --- shared-core/i915_irq.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4127383a..558693f1 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -577,6 +577,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 temp = 0; u32 pipea_stats, pipeb_stats; + int hotplug = 0; /* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */ if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) @@ -610,13 +611,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_VBLANK_CLEAR; } - if (temp & EVENT_PIPEA_FLAG) + /* This is a global event, and not a pipe A event */ + if (temp & EVENT_PIPEA_FLAG) { + if (pipea_stats & I915_HOTPLUG_CLEAR) + hotplug = 1; + pipea_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR; - if (temp & EVENT_PIPEB_FLAG) - pipeb_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | - I915_HOTPLUG_CLEAR; + } I915_WRITE(I915REG_PIPEASTAT, pipea_stats); (void) I915_READ(I915REG_PIPEASTAT); @@ -650,37 +653,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) drm_locked_tasklet(dev, i915_vblank_tasklet); } - if (temp & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { + if ((temp & HOTPLUG_FLAG) || hotplug) { u32 temp2 = 0; DRM_INFO("Hotplug event received\n"); if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { -#if 0 - u32 b,c; - - b = I915_READ(SDVOB) & SDVO_PIPE_B_SELECT; - c = I915_READ(SDVOC) & SDVO_PIPE_B_SELECT; - - if (temp & EVENT_PIPEA_FLAG) { - if (!b) - temp2 |= SDVOB_HOTPLUG_INT_STATUS; - if (!c) - temp2 |= SDVOC_HOTPLUG_INT_STATUS; - - } - - if (temp & EVENT_PIPEB_FLAG) { - if (b) - temp2 |= SDVOB_HOTPLUG_INT_STATUS; - if (c) - temp2 |= SDVOC_HOTPLUG_INT_STATUS; - - } -#else temp2 |= SDVOB_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS; -#endif } else { temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -879,8 +859,8 @@ void i915_enable_interrupt (struct drm_device *dev) if (dev->mode_config.num_output) dev_priv->irq_enable_reg |= EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG; + /* Enable global interrupts for hotplug - not a pipeA event */ I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); - I915_WRITE(I915REG_PIPEBSTAT, I915_READ(I915REG_PIPEBSTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); } if (dev_priv->irq_enable_reg & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { -- cgit v1.2.3 From 386ea38b8e3af9bc9166d4ab63c4beb7e0e2267b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 9 Apr 2008 14:12:56 -0700 Subject: Add TV out hotplug detection Doesn't yet work on my i915 test machine, but most of the necessary bits should be there. --- shared-core/i915_irq.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index abd8a7d3..8f136c8f 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -424,11 +424,41 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) #define HOTPLUG_CMD_CRT_DIS 2 #define HOTPLUG_CMD_SDVOB 4 #define HOTPLUG_CMD_SDVOC 8 +#define HOTPLUG_CMD_TV 16 static struct drm_device *hotplug_dev; static int hotplug_cmd = 0; static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; +static void i915_hotplug_tv(struct drm_device *dev) +{ + struct drm_output *output; + struct intel_output *iout; + enum drm_output_status status; + + mutex_lock(&dev->mode_config.mutex); + + /* find the crt output */ + list_for_each_entry(output, &dev->mode_config.output_list, head) { + iout = output->driver_private; + if (iout->type == INTEL_OUTPUT_TVOUT) + break; + else + iout = 0; + } + + if (iout == 0) + goto unlock; + + /* may need to I915_WRITE(TVDAC, 1<<31) to ack the interrupt */ + status = output->funcs->detect(output); + drm_hotplug_stage_two(dev, output, + status == output_status_connected ? 1 : 0); + +unlock: + mutex_unlock(&dev->mode_config.mutex); +} + static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) { struct drm_output *output; @@ -493,8 +523,10 @@ static void i915_hotplug_work_func(struct work_struct *work) int crtDis; int sdvoB; int sdvoC; + int tv; spin_lock(&hotplug_lock); + tv = hotplug_cmd & HOTPLUG_CMD_TV; crt = hotplug_cmd & HOTPLUG_CMD_CRT; crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS; sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB; @@ -502,6 +534,8 @@ static void i915_hotplug_work_func(struct work_struct *work) hotplug_cmd = 0; spin_unlock(&hotplug_lock); + if (tv) + i915_hotplug_tv(dev); if (crt) i915_hotplug_crt(dev, true); if (crtDis) @@ -527,6 +561,14 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) hotplug_dev = dev; + if (stat & TV_HOTPLUG_INT_STATUS) { + DRM_DEBUG("TV event\n"); + + spin_lock(&hotplug_lock); + hotplug_cmd |= HOTPLUG_CMD_TV; + spin_unlock(&hotplug_lock); + } + if (stat & CRT_HOTPLUG_INT_STATUS) { DRM_DEBUG("CRT event\n"); @@ -584,12 +626,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_DEBUG("flag=%08x\n", iir); #endif if (iir == 0) { +#if 0 DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", iir, I915_READ(I915REG_INT_MASK_R), I915_READ(I915REG_INT_ENABLE_R), I915_READ(I915REG_PIPEASTAT), I915_READ(I915REG_PIPEBSTAT)); +#endif return IRQ_NONE; } @@ -607,7 +651,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } /* This is a global event, and not a pipe A event */ - if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + if ((pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) || + (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS)) hotplug = 1; I915_WRITE(I915REG_PIPEASTAT, pipea_stats); @@ -656,8 +701,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_INFO("Hotplug event received\n"); if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { - temp2 |= SDVOB_HOTPLUG_INT_STATUS | - SDVOC_HOTPLUG_INT_STATUS; + if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + temp2 |= SDVOB_HOTPLUG_INT_STATUS | + SDVOC_HOTPLUG_INT_STATUS; + if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) + temp2 |= TV_HOTPLUG_INT_STATUS; } else { temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -898,7 +946,11 @@ void i915_enable_interrupt (struct drm_device *dev) dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; /* Enable global interrupts for hotplug - not a pipeA event */ - I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); + I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | + I915_HOTPLUG_INTERRUPT_ENABLE | + I915_HOTPLUG_TV_INTERRUPT_ENABLE | + I915_HOTPLUG_TV_CLEAR | + I915_HOTPLUG_CLEAR); } if (dev_priv->irq_enable_reg & (I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)) { -- cgit v1.2.3 From 8a390e058fcea70b0c3a912543816bdf4c3e7c4c Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Fri, 18 Apr 2008 16:49:23 +0800 Subject: clear interrupt status before install irq On my 865G machine, it seems the CPU will receive interrupt before irq_postinstall is called. This will cause kernel oops because vblank is not inited at that time. Clear interrupt status before install seems fixing this problem. Signed-off-by: Hong Liu --- shared-core/i915_irq.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 8f136c8f..422e81ed 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -1217,14 +1217,25 @@ int i915_vblank_swap(struct drm_device *dev, void *data, void i915_driver_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + u32 tmp; + + tmp = I915_READ(I915REG_PIPEASTAT); + I915_WRITE(I915REG_PIPEASTAT, tmp); + tmp = I915_READ(I915REG_PIPEBSTAT); + I915_WRITE(I915REG_PIPEBSTAT, tmp); + I915_WRITE16(I915REG_HWSTAM, 0xeffe); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_INT_MASK_R, 0x0); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); + tmp = I915_READ(I915REG_INT_IDENTITY_R); + I915_WRITE(I915REG_INT_IDENTITY_R, tmp); } else { I915_WRITE16(I915REG_INT_MASK_R, 0x0); I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); + tmp = I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(I915REG_INT_IDENTITY_R, tmp); } } -- cgit v1.2.3 From 2a78ad22647933aa8842d534bce6495ff93fbf76 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 8 May 2008 16:14:33 +1000 Subject: i915: fix vbl swap for multi-master patch from F9 tree --- shared-core/i915_irq.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 0ee0c444..ea2c88a1 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -198,9 +198,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) continue; - master_priv = vbl_swap->minor->master->driver_priv; - sarea_priv = master_priv->sarea_priv; - list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, pipe); @@ -249,16 +246,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) i915_kernel_lost_context(dev); - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->planeA_h / nhits, 1); - slice[1] = max(sarea_priv->planeB_h / nhits, 1); - lower[0] = sarea_priv->planeA_y + slice[0]; - lower[1] = sarea_priv->planeB_y + slice[0]; - - offsets[0] = sarea_priv->front_offset; - offsets[1] = sarea_priv->back_offset; - offsets[2] = sarea_priv->third_offset; - num_pages = sarea_priv->third_handle ? 3 : 2; DRM_SPINLOCK(&dev->drw_lock); @@ -272,8 +259,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) upper[1] = lower[1], lower[1] += slice[1]) { int init_drawrect = 1; - if (i == nhits) - lower[0] = lower[1] = sarea_priv->height; list_for_each(hit, &hits) { struct drm_i915_vbl_swap *swap_hit = @@ -282,6 +267,24 @@ static void i915_vblank_tasklet(struct drm_device *dev) int num_rects, plane, front, back; unsigned short top, bottom; + sarea_priv = master_priv->sarea_priv; + + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->planeA_h / nhits, 1); + slice[1] = max(sarea_priv->planeB_h / nhits, 1); + lower[0] = sarea_priv->planeA_y + slice[0]; + lower[1] = sarea_priv->planeB_y + slice[0]; + + offsets[0] = sarea_priv->front_offset; + offsets[1] = sarea_priv->back_offset; + offsets[2] = sarea_priv->third_offset; + num_pages = sarea_priv->third_handle ? 3 : 2; + if (i == nhits) + lower[0] = lower[1] = sarea_priv->height; + + pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); + drw = drm_get_drawable_info(dev, swap_hit->drw_id); if (!drw) @@ -294,6 +297,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) continue; } + master_priv = swap_hit->minor->master->driver_priv; + if (init_drawrect) { int width = sarea_priv->width; int height = sarea_priv->height; @@ -332,6 +337,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) (2 * plane)) & 0x3; back = (front + 1) % num_pages; + + for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); int y2 = min(rect->y2, bottom); -- cgit v1.2.3 From 4466fea7bab2af5c1e25947af474d0ae69df1ffd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 8 May 2008 17:12:16 +1000 Subject: Revert "i915: fix vbl swap for multi-master" This reverts commit 2a78ad22647933aa8842d534bce6495ff93fbf76. --- shared-core/i915_irq.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index ea2c88a1..0ee0c444 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -198,6 +198,9 @@ static void i915_vblank_tasklet(struct drm_device *dev) if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) continue; + master_priv = vbl_swap->minor->master->driver_priv; + sarea_priv = master_priv->sarea_priv; + list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, pipe); @@ -246,6 +249,16 @@ static void i915_vblank_tasklet(struct drm_device *dev) i915_kernel_lost_context(dev); + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->planeA_h / nhits, 1); + slice[1] = max(sarea_priv->planeB_h / nhits, 1); + lower[0] = sarea_priv->planeA_y + slice[0]; + lower[1] = sarea_priv->planeB_y + slice[0]; + + offsets[0] = sarea_priv->front_offset; + offsets[1] = sarea_priv->back_offset; + offsets[2] = sarea_priv->third_offset; + num_pages = sarea_priv->third_handle ? 3 : 2; DRM_SPINLOCK(&dev->drw_lock); @@ -259,6 +272,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) upper[1] = lower[1], lower[1] += slice[1]) { int init_drawrect = 1; + if (i == nhits) + lower[0] = lower[1] = sarea_priv->height; list_for_each(hit, &hits) { struct drm_i915_vbl_swap *swap_hit = @@ -267,24 +282,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) int num_rects, plane, front, back; unsigned short top, bottom; - sarea_priv = master_priv->sarea_priv; - - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->planeA_h / nhits, 1); - slice[1] = max(sarea_priv->planeB_h / nhits, 1); - lower[0] = sarea_priv->planeA_y + slice[0]; - lower[1] = sarea_priv->planeB_y + slice[0]; - - offsets[0] = sarea_priv->front_offset; - offsets[1] = sarea_priv->back_offset; - offsets[2] = sarea_priv->third_offset; - num_pages = sarea_priv->third_handle ? 3 : 2; - if (i == nhits) - lower[0] = lower[1] = sarea_priv->height; - - pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | - (cpp << 23) | (1 << 24); - drw = drm_get_drawable_info(dev, swap_hit->drw_id); if (!drw) @@ -297,8 +294,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) continue; } - master_priv = swap_hit->minor->master->driver_priv; - if (init_drawrect) { int width = sarea_priv->width; int height = sarea_priv->height; @@ -337,8 +332,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) (2 * plane)) & 0x3; back = (front + 1) % num_pages; - - for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); int y2 = min(rect->y2, bottom); -- cgit v1.2.3 From d32ce7f621c0d8e42cdf88ce6f1d15638a3d34b7 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 12 May 2008 15:47:19 -0700 Subject: i915: TV hotplug fixes In order to avoid recursive ->detect->interrupt->detect->interrupt->... we need to disable TV hotplug interrupts in intel_tv.c:intel_tv_detect_type. We also need to enable the TV interrupt detection and hotplug sequence properly in i915_irq.c. --- shared-core/i915_irq.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 0ee0c444..4aef568e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -471,7 +471,6 @@ static void i915_hotplug_tv(struct drm_device *dev) if (iout == 0) goto unlock; - /* may need to I915_WRITE(TVDAC, 1<<31) to ack the interrupt */ status = output->funcs->detect(output); drm_hotplug_stage_two(dev, output, status == output_status_connected ? 1 : 0); @@ -631,7 +630,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_i915_master_private *master_priv; struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 iir; - u32 pipea_stats, pipeb_stats; + u32 pipea_stats = 0, pipeb_stats, tvdac; int hotplug = 0; int vblank = 0; @@ -672,10 +671,17 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } /* This is a global event, and not a pipe A event */ - if ((pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) || - (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS)) + if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) hotplug = 1; + if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) { + hotplug = 1; + /* Toggle hotplug detection to clear hotplug status */ + tvdac = I915_READ(TV_DAC); + I915_WRITE(TV_DAC, tvdac & ~TVDAC_STATE_CHG_EN); + I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN); + } + I915_WRITE(I915REG_PIPEASTAT, pipea_stats); } @@ -1001,6 +1007,9 @@ void i915_enable_interrupt (struct drm_device *dev) I915_WRITE(SDVOB, I915_READ(SDVOB) | SDVO_INTERRUPT_ENABLE); I915_WRITE(SDVOC, I915_READ(SDVOC) | SDVO_INTERRUPT_ENABLE); + + /* TV */ + I915_WRITE(TV_DAC, I915_READ(TV_DAC) | TVDAC_STATE_CHG_EN); } else { /* DVO ???? */ } -- cgit v1.2.3 From ee631e1b8604a176b9118396998ce5bfc6475dae Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 13 May 2008 14:44:17 -0700 Subject: i915: register definition & header file cleanup It would be nice if one day the DRM driver was the canonical source for register definitions and core macros. To that end, this patch cleans things up quite a bit, removing redundant definitions (some with different names referring to the same register) and generally tidying up the header file. --- shared-core/i915_irq.c | 160 ++++++++++++++++++++++++------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4aef568e..38995421 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -636,9 +636,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) /* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */ if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - iir = I915_READ(I915REG_INT_IDENTITY_R); + iir = I915_READ(IIR); else - iir = I915_READ16(I915REG_INT_IDENTITY_R); + iir = I915_READ16(IIR); iir &= (dev_priv->irq_enable_reg | I915_USER_INTERRUPT); @@ -649,10 +649,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) #if 0 DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", iir, - I915_READ(I915REG_INT_MASK_R), - I915_READ(I915REG_INT_ENABLE_R), - I915_READ(I915REG_PIPEASTAT), - I915_READ(I915REG_PIPEBSTAT)); + I915_READ(IMR), + I915_READ(IER), + I915_READ(PIPEASTAT), + I915_READ(PIPEBSTAT)); #endif return IRQ_NONE; } @@ -662,19 +662,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) * we may get extra interrupts. */ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { - pipea_stats = I915_READ(I915REG_PIPEASTAT); - if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS| - I915_VBLANK_INTERRUPT_STATUS)) + pipea_stats = I915_READ(PIPEASTAT); + if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| + PIPE_VBLANK_INTERRUPT_STATUS)) { vblank++; drm_handle_vblank(dev, i915_get_plane(dev, 0)); } /* This is a global event, and not a pipe A event */ - if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + if (pipea_stats & PIPE_HOTPLUG_INTERRUPT_STATUS) hotplug = 1; - if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) { + if (pipea_stats & PIPE_HOTPLUG_TV_INTERRUPT_STATUS) { hotplug = 1; /* Toggle hotplug detection to clear hotplug status */ tvdac = I915_READ(TV_DAC); @@ -682,27 +682,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN); } - I915_WRITE(I915REG_PIPEASTAT, pipea_stats); + I915_WRITE(PIPEASTAT, pipea_stats); } if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { - pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS| - I915_VBLANK_INTERRUPT_STATUS)) + pipeb_stats = I915_READ(PIPEBSTAT); + if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| + PIPE_VBLANK_INTERRUPT_STATUS)) { vblank++; drm_handle_vblank(dev, i915_get_plane(dev, 1)); } - I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); + I915_WRITE(PIPEBSTAT, pipeb_stats); } /* Clear the generated interrupt */ if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - I915_WRITE(I915REG_INT_IDENTITY_R, iir); - (void) I915_READ(I915REG_INT_IDENTITY_R); + I915_WRITE(IIR, iir); + (void) I915_READ(IIR); } else { - I915_WRITE16(I915REG_INT_IDENTITY_R, iir); - (void) I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(IIR, iir); + (void) I915_READ16(IIR); } if (dev->primary->master) { @@ -728,10 +728,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_INFO("Hotplug event received\n"); if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { - if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + if (pipea_stats & PIPE_HOTPLUG_INTERRUPT_STATUS) temp2 |= SDVOB_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS; - if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) + if (pipea_stats & PIPE_HOTPLUG_TV_INTERRUPT_STATUS) temp2 |= TV_HOTPLUG_INT_STATUS; } else { temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -757,7 +757,7 @@ int i915_emit_irq(struct drm_device *dev) BEGIN_LP_RING(2); OUT_RING(0); - OUT_RING(GFX_OP_USER_INTERRUPT); + OUT_RING(MI_USER_INTERRUPT); ADVANCE_LP_RING(); return dev_priv->counter; @@ -771,9 +771,9 @@ void i915_user_irq_on(struct drm_device *dev) if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); @@ -787,9 +787,9 @@ void i915_user_irq_off(struct drm_device *dev) if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { // dev_priv->irq_enable_reg &= ~I915_USER_INTERRUPT; // if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - // I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // I915_WRITE(IER, dev_priv->irq_enable_reg); // else - // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // I915_WRITE16(IER, dev_priv->irq_enable_reg); } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -876,11 +876,11 @@ int i915_enable_vblank(struct drm_device *dev, int plane) switch (pipe) { case 0: - pipestat_reg = I915REG_PIPEASTAT; + pipestat_reg = PIPEASTAT; dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case 1: - pipestat_reg = I915REG_PIPEBSTAT; + pipestat_reg = PIPEBSTAT; dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; default: @@ -897,21 +897,21 @@ int i915_enable_vblank(struct drm_device *dev, int plane) * but */ if (IS_I965G (dev)) - pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE; + pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; else - pipestat |= I915_VBLANK_INTERRUPT_ENABLE; + pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; /* * Clear any pending status */ - pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | - I915_VBLANK_INTERRUPT_STATUS); + pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | + PIPE_VBLANK_INTERRUPT_STATUS); I915_WRITE(pipestat_reg, pipestat); } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); return 0; @@ -926,11 +926,11 @@ void i915_disable_vblank(struct drm_device *dev, int plane) switch (pipe) { case 0: - pipestat_reg = I915REG_PIPEASTAT; + pipestat_reg = PIPEASTAT; dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case 1: - pipestat_reg = I915REG_PIPEBSTAT; + pipestat_reg = PIPEBSTAT; dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; default: @@ -940,20 +940,20 @@ void i915_disable_vblank(struct drm_device *dev, int plane) } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); if (pipestat_reg) { pipestat = I915_READ (pipestat_reg); - pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_INTERRUPT_ENABLE); + pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | + PIPE_VBLANK_INTERRUPT_ENABLE); /* * Clear any pending status */ - pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | - I915_VBLANK_INTERRUPT_STATUS); + pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | + PIPE_VBLANK_INTERRUPT_STATUS); I915_WRITE(pipestat_reg, pipestat); } } @@ -973,11 +973,11 @@ void i915_enable_interrupt (struct drm_device *dev) dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; /* Enable global interrupts for hotplug - not a pipeA event */ - I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | - I915_HOTPLUG_INTERRUPT_ENABLE | - I915_HOTPLUG_TV_INTERRUPT_ENABLE | - I915_HOTPLUG_TV_CLEAR | - I915_HOTPLUG_CLEAR); + I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) | + PIPE_HOTPLUG_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_STATUS | + PIPE_HOTPLUG_INTERRUPT_STATUS); } if (dev_priv->irq_enable_reg & (I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)) { @@ -1025,9 +1025,9 @@ void i915_enable_interrupt (struct drm_device *dev) } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); dev_priv->irq_enabled = 1; } @@ -1068,9 +1068,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - flag = I915_READ(I915REG_INT_ENABLE_R); + flag = I915_READ(IER); else - flag = I915_READ16(I915REG_INT_ENABLE_R); + flag = I915_READ16(IER); pipe->pipe = 0; if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) @@ -1249,23 +1249,23 @@ void i915_driver_irq_preinstall(struct drm_device * dev) struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 tmp; - tmp = I915_READ(I915REG_PIPEASTAT); - I915_WRITE(I915REG_PIPEASTAT, tmp); - tmp = I915_READ(I915REG_PIPEBSTAT); - I915_WRITE(I915REG_PIPEBSTAT, tmp); + tmp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, tmp); + tmp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, tmp); - I915_WRITE16(I915REG_HWSTAM, 0xeffe); + I915_WRITE16(HWSTAM, 0xeffe); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - I915_WRITE(I915REG_INT_MASK_R, 0x0); - I915_WRITE(I915REG_INT_ENABLE_R, 0x0); - tmp = I915_READ(I915REG_INT_IDENTITY_R); - I915_WRITE(I915REG_INT_IDENTITY_R, tmp); + I915_WRITE(IMR, 0x0); + I915_WRITE(IER, 0x0); + tmp = I915_READ(IIR); + I915_WRITE(IIR, tmp); } else { - I915_WRITE16(I915REG_INT_MASK_R, 0x0); - I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); - tmp = I915_READ16(I915REG_INT_IDENTITY_R); - I915_WRITE16(I915REG_INT_IDENTITY_R, tmp); + I915_WRITE16(IMR, 0x0); + I915_WRITE16(IER, 0x0); + tmp = I915_READ16(IIR); + I915_WRITE16(IIR, tmp); } } @@ -1300,7 +1300,7 @@ int i915_driver_irq_postinstall(struct drm_device * dev) * Initialize the hardware status page IRQ location. */ - I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); + I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); return 0; } @@ -1314,23 +1314,23 @@ void i915_driver_irq_uninstall(struct drm_device * dev) dev_priv->irq_enabled = 0; - temp = I915_READ(I915REG_PIPEASTAT); - I915_WRITE(I915REG_PIPEASTAT, temp); - temp = I915_READ(I915REG_PIPEBSTAT); - I915_WRITE(I915REG_PIPEBSTAT, temp); + temp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, temp); + temp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, temp); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - I915_WRITE(I915REG_HWSTAM, 0xffffffff); - I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); - I915_WRITE(I915REG_INT_ENABLE_R, 0x0); + I915_WRITE(HWSTAM, 0xffffffff); + I915_WRITE(IMR, 0xffffffff); + I915_WRITE(IER, 0x0); - temp = I915_READ(I915REG_INT_IDENTITY_R); - I915_WRITE(I915REG_INT_IDENTITY_R, temp); + temp = I915_READ(IIR); + I915_WRITE(IIR, temp); } else { - I915_WRITE16(I915REG_HWSTAM, 0xffff); - I915_WRITE16(I915REG_INT_MASK_R, 0xffff); - I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); + I915_WRITE16(HWSTAM, 0xffff); + I915_WRITE16(IMR, 0xffff); + I915_WRITE16(IER, 0x0); - temp = I915_READ16(I915REG_INT_IDENTITY_R); - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + temp = I915_READ16(IIR); + I915_WRITE16(IIR, temp); } } -- cgit v1.2.3 From df8cd54286fbae5903d8ede390ec4a11cb6c4b6c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2008 14:02:14 +1000 Subject: modesetting: reorganise code into core and helper functions. This splits a lot of the core modesetting code out into a file of helper functions, that are only called from themselves and/or the driver. The driver gets called into more often or can call these functions from itself if it is a helper using driver. I've broken framebuffer resize doing this but I didn't like the API for that in any case. --- shared-core/i915_irq.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 592e881b..ccedc70e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -31,6 +31,7 @@ #include "i915_drm.h" #include "i915_drv.h" #include "intel_drv.h" +#include "drm_crtc_helper.h" #define MAX_NOPID ((u32)~0) @@ -471,8 +472,8 @@ static void i915_hotplug_tv(struct drm_device *dev) goto unlock; status = output->funcs->detect(output); - drm_hotplug_stage_two(dev, output, - status == output_status_connected ? 1 : 0); + drm_helper_hotplug_stage_two(dev, output, + status == output_status_connected ? 1 : 0); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -497,7 +498,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) if (iout == 0) goto unlock; - drm_hotplug_stage_two(dev, output, isconnected); + drm_helper_hotplug_stage_two(dev, output, isconnected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -518,9 +519,9 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) status = output->funcs->detect(output); if (status != output_status_connected) - drm_hotplug_stage_two(dev, output, false); + drm_helper_hotplug_stage_two(dev, output, false); else - drm_hotplug_stage_two(dev, output, true); + drm_helper_hotplug_stage_two(dev, output, true); intel_sdvo_set_hotplug(output, 1); -- cgit v1.2.3 From 98c5cf7f6fc51f1a8f5f90b3895009cd38dd8f22 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 11:25:41 +1000 Subject: modesetting: reorganise out crtc/outputs are allocated. Use subclassing from the drivers to allocate the objects. This saves two objects being allocated for each crtc/output and generally makes exit paths cleaner. --- shared-core/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index ccedc70e..abf916ed 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -461,7 +461,7 @@ static void i915_hotplug_tv(struct drm_device *dev) /* find the crt output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type == INTEL_OUTPUT_TVOUT) break; else @@ -488,7 +488,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) /* find the crt output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type == INTEL_OUTPUT_ANALOG) break; else -- cgit v1.2.3 From 9d38448ed33aaff324cc4bbe1e0878593e97d07d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 15:03:12 +1000 Subject: modesetting: the great renaming. Okay we have crtc, encoder and connectors. No more outputs exposed beyond driver internals I've broken intel tv connector stuff. Really for TV we should have one TV connector, with a sub property for the type of signal been driven over it --- shared-core/i915_irq.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index abf916ed..4c147a08 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -453,15 +453,15 @@ static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; static void i915_hotplug_tv(struct drm_device *dev) { - struct drm_output *output; + struct drm_connector *connector; struct intel_output *iout; - enum drm_output_status status; + enum drm_connector_status status; mutex_lock(&dev->mode_config.mutex); /* find the crt output */ - list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = to_intel_output(output); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + iout = to_intel_output(connector); if (iout->type == INTEL_OUTPUT_TVOUT) break; else @@ -471,9 +471,9 @@ static void i915_hotplug_tv(struct drm_device *dev) if (iout == 0) goto unlock; - status = output->funcs->detect(output); - drm_helper_hotplug_stage_two(dev, output, - status == output_status_connected ? 1 : 0); + status = connector->funcs->detect(connector); + drm_helper_hotplug_stage_two(dev, connector, + status == connector_status_connected ? 1 : 0); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -481,14 +481,14 @@ unlock: static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) { - struct drm_output *output; + struct drm_connector *connector; struct intel_output *iout; mutex_lock(&dev->mode_config.mutex); /* find the crt output */ - list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = to_intel_output(output); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + iout = to_intel_output(connector); if (iout->type == INTEL_OUTPUT_ANALOG) break; else @@ -498,7 +498,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) if (iout == 0) goto unlock; - drm_helper_hotplug_stage_two(dev, output, isconnected); + drm_helper_hotplug_stage_two(dev, connector, isconnected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -506,24 +506,24 @@ unlock: static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) { - struct drm_output *output = 0; - enum drm_output_status status; + struct drm_connector *connector = 0; + enum drm_connector_status status; mutex_lock(&dev->mode_config.mutex); - output = intel_sdvo_find(dev, sdvoB); + connector = intel_sdvo_find(dev, sdvoB); - if (!output) + if (!connector) goto unlock; - status = output->funcs->detect(output); + status = connector->funcs->detect(connector); - if (status != output_status_connected) - drm_helper_hotplug_stage_two(dev, output, false); + if (status != connector_status_connected) + drm_helper_hotplug_stage_two(dev, connector, false); else - drm_helper_hotplug_stage_two(dev, output, true); + drm_helper_hotplug_stage_two(dev, connector, true); - intel_sdvo_set_hotplug(output, 1); + intel_sdvo_set_hotplug(connector, 1); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -961,15 +961,15 @@ void i915_disable_vblank(struct drm_device *dev, int plane) void i915_enable_interrupt (struct drm_device *dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - struct drm_output *o; + struct drm_connector *o; dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - if (dev->mode_config.num_output) + if (dev->mode_config.num_connector) dev_priv->irq_enable_reg |= I915_DISPLAY_PORT_INTERRUPT; } else { - if (dev->mode_config.num_output) + if (dev->mode_config.num_connector) dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; /* Enable global interrupts for hotplug - not a pipeA event */ -- cgit v1.2.3 From 25c1bb334f3a32e3e635e9d5de1abf8abdcc87f0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 6 Jun 2008 10:38:35 +1000 Subject: drm/intel: make hotplug just be an event --- shared-core/i915_irq.c | 135 +------------------------------------------------ 1 file changed, 1 insertion(+), 134 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4c147a08..2d355688 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -441,93 +441,8 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) return count; } -#define HOTPLUG_CMD_CRT 1 -#define HOTPLUG_CMD_CRT_DIS 2 -#define HOTPLUG_CMD_SDVOB 4 -#define HOTPLUG_CMD_SDVOC 8 -#define HOTPLUG_CMD_TV 16 - static struct drm_device *hotplug_dev; -static int hotplug_cmd = 0; -static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; - -static void i915_hotplug_tv(struct drm_device *dev) -{ - struct drm_connector *connector; - struct intel_output *iout; - enum drm_connector_status status; - - mutex_lock(&dev->mode_config.mutex); - - /* find the crt output */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_intel_output(connector); - if (iout->type == INTEL_OUTPUT_TVOUT) - break; - else - iout = 0; - } - - if (iout == 0) - goto unlock; - - status = connector->funcs->detect(connector); - drm_helper_hotplug_stage_two(dev, connector, - status == connector_status_connected ? 1 : 0); - -unlock: - mutex_unlock(&dev->mode_config.mutex); -} - -static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) -{ - struct drm_connector *connector; - struct intel_output *iout; - - mutex_lock(&dev->mode_config.mutex); - - /* find the crt output */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_intel_output(connector); - if (iout->type == INTEL_OUTPUT_ANALOG) - break; - else - iout = 0; - } - - if (iout == 0) - goto unlock; - - drm_helper_hotplug_stage_two(dev, connector, isconnected); -unlock: - mutex_unlock(&dev->mode_config.mutex); -} - -static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) -{ - struct drm_connector *connector = 0; - enum drm_connector_status status; - - mutex_lock(&dev->mode_config.mutex); - - connector = intel_sdvo_find(dev, sdvoB); - - if (!connector) - goto unlock; - - status = connector->funcs->detect(connector); - - if (status != connector_status_connected) - drm_helper_hotplug_stage_two(dev, connector, false); - else - drm_helper_hotplug_stage_two(dev, connector, true); - - intel_sdvo_set_hotplug(connector, 1); - -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. @@ -539,34 +454,8 @@ static void i915_hotplug_work_func(struct work_struct *work) #endif { struct drm_device *dev = hotplug_dev; - int crt; - int crtDis; - int sdvoB; - int sdvoC; - int tv; - - spin_lock(&hotplug_lock); - tv = hotplug_cmd & HOTPLUG_CMD_TV; - crt = hotplug_cmd & HOTPLUG_CMD_CRT; - crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS; - sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB; - sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC; - hotplug_cmd = 0; - spin_unlock(&hotplug_lock); - - if (tv) - i915_hotplug_tv(dev); - if (crt) - i915_hotplug_crt(dev, true); - if (crtDis) - i915_hotplug_crt(dev, false); - - if (sdvoB) - i915_hotplug_sdvo(dev, 1); - - if (sdvoC) - i915_hotplug_sdvo(dev, 0); + drm_helper_hotplug_stage_two(dev); drm_handle_hotplug(dev); } @@ -583,40 +472,18 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) if (stat & TV_HOTPLUG_INT_STATUS) { DRM_DEBUG("TV event\n"); - - spin_lock(&hotplug_lock); - hotplug_cmd |= HOTPLUG_CMD_TV; - spin_unlock(&hotplug_lock); } if (stat & CRT_HOTPLUG_INT_STATUS) { DRM_DEBUG("CRT event\n"); - - if (stat & CRT_HOTPLUG_MONITOR_MASK) { - spin_lock(&hotplug_lock); - hotplug_cmd |= HOTPLUG_CMD_CRT; - spin_unlock(&hotplug_lock); - } else { - spin_lock(&hotplug_lock); - hotplug_cmd |= HOTPLUG_CMD_CRT_DIS; - spin_unlock(&hotplug_lock); - } } if (stat & SDVOB_HOTPLUG_INT_STATUS) { DRM_DEBUG("sDVOB event\n"); - - spin_lock(&hotplug_lock); - hotplug_cmd |= HOTPLUG_CMD_SDVOB; - spin_unlock(&hotplug_lock); } if (stat & SDVOC_HOTPLUG_INT_STATUS) { DRM_DEBUG("sDVOC event\n"); - - spin_lock(&hotplug_lock); - hotplug_cmd |= HOTPLUG_CMD_SDVOC; - spin_unlock(&hotplug_lock); } queue_work(dev_priv->wq, &hotplug); -- cgit v1.2.3 From a2adc696569de830c7a95722dd111bff706a0bbc Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 16 Aug 2008 12:09:24 -0700 Subject: i915: finish removing TTM bits Makes it build again. --- shared-core/i915_irq.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core/i915_irq.c') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 28fa35fd..ee83b14e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -554,9 +554,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (iir & I915_USER_INTERRUPT) { dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); DRM_WAKEUP(&dev_priv->irq_queue); -#ifdef I915_HAVE_FENCE - i915_fence_handler(dev); -#endif } if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| -- cgit v1.2.3