The changes that we discussed on irc are turning out to be slightly more
difficult than I expected... In the meantime, I'd like to push this to
master to get things more or less working again.
One thing I discovered was that, at least on bsd, the signal handler
gets installed / uninstalled pretty often right now. Each time that
happens, we call drm_vblank_init and reset vblank_disable_allowed=0,
meaning that a modeset or dpms must occur after the handler is installed
each time to disable vblanks.
This patch reverts most of my changes to i915's irq install / uninstall
functions. It does move the drm_vblank_init and drm_vblank_cleanup
calls to the drivers respective load / unload routines. Minor
additional changes will be needed on the linux side. Mostly just remove
the drm_vblank_cleanup call from you irq_uninstall path.
I have made the driver changes to i915 and radeon so far, but I am only
able to test intel.
I'm still working to allow the irq handlers to be installed at load
time, but that is slightly more complicated surgery, at least on the bsd
side of the house...
robert.
--
Robert Noland <[EMAIL PROTECTED]>
2Hip Networks
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h
index 326b220..e65b7e0 100644
--- a/bsd-core/drmP.h
+++ b/bsd-core/drmP.h
@@ -933,6 +933,7 @@ int drm_vblank_get(struct drm_device *dev, int crtc);
void drm_vblank_put(struct drm_device *dev, int crtc);
int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
int drm_vblank_init(struct drm_device *dev, int num_crtcs);
+void drm_vblank_cleanup(struct drm_device *dev);
void drm_vbl_send_signals(struct drm_device *dev, int crtc);
int drm_modeset_ctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c
index 6e21d41..76809e6 100644
--- a/bsd-core/drm_irq.c
+++ b/bsd-core/drm_irq.c
@@ -96,7 +96,7 @@ static void vblank_disable_fn(void *arg)
}
}
-static void drm_vblank_cleanup(struct drm_device *dev)
+void drm_vblank_cleanup(struct drm_device *dev)
{
unsigned long irqflags;
@@ -295,8 +295,6 @@ int drm_irq_uninstall(struct drm_device *dev)
#elif defined(__NetBSD__) || defined(__OpenBSD__)
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
#endif
- drm_vblank_cleanup(dev);
-
return 0;
}
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index e57580f..9ab59ab 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -1027,24 +1027,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = (void *)dev_priv;
- /* Add register map (needed for suspend/resume) */
- base = drm_get_resource_start(dev, mmio_bar);
- size = drm_get_resource_len(dev, mmio_bar);
-
- ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
- _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map);
-
-#ifdef __linux__
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
- intel_init_chipset_flush_compat(dev);
-#endif
- intel_opregion_init(dev);
-#endif
-
- I915_WRITE16(HWSTAM, 0xeffe);
- I915_WRITE16(IMR, 0x0);
- I915_WRITE16(IER, 0x0);
-
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
dev_priv->swaps_pending = 0;
@@ -1060,14 +1042,19 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
- i915_enable_interrupt(dev);
- DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
+ /* Add register map (needed for suspend/resume) */
+ base = drm_get_resource_start(dev, mmio_bar);
+ size = drm_get_resource_len(dev, mmio_bar);
- /*
- * Initialize the hardware status page IRQ location.
- */
+ ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
+ _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map);
- I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
+#ifdef __linux__
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+ intel_init_chipset_flush_compat(dev);
+#endif
+ intel_opregion_init(dev);
+#endif
return ret;
}
@@ -1075,23 +1062,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
int i915_driver_unload(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 temp;
-
- if (dev_priv) {
- dev_priv->vblank_pipe = 0;
-
- dev_priv->irq_enabled = 0;
- I915_WRITE(HWSTAM, 0xffffffff);
- I915_WRITE(IMR, 0xffffffff);
- I915_WRITE(IER, 0x0);
-
- temp = I915_READ(PIPEASTAT);
- I915_WRITE(PIPEASTAT, temp);
- temp = I915_READ(PIPEBSTAT);
- I915_WRITE(PIPEBSTAT, temp);
- temp = I915_READ(IIR);
- I915_WRITE(IIR, temp);
- }
+
+ DRM_SPINUNINIT(&dev_priv->user_irq_lock);
+ DRM_SPINUNINIT(&dev_priv->swaps_lock);
+
+ drm_vblank_cleanup(dev);
if (dev_priv->mmio_map)
drm_rmmap(dev, dev_priv->mmio_map);
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index a77fcf0..421572c 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -307,7 +307,6 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(struct drm_device * dev);
extern int i915_driver_irq_postinstall(struct drm_device * dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev);
-extern void i915_enable_interrupt(struct drm_device *dev);
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index 135d615..ed72542 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -668,7 +668,7 @@ void i915_disable_vblank(struct drm_device *dev, int plane)
}
}
-void i915_enable_interrupt (struct drm_device *dev)
+static void i915_enable_interrupt (struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -876,15 +876,48 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
*/
void i915_driver_irq_preinstall(struct drm_device * dev)
{
- return;
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ I915_WRITE16(HWSTAM, 0xeffe);
+ I915_WRITE16(IMR, 0x0);
+ I915_WRITE16(IER, 0x0);
}
int i915_driver_irq_postinstall(struct drm_device * dev)
{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ i915_enable_interrupt(dev);
+ DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
+
+ /*
+ * Initialize the hardware status page IRQ location.
+ */
+
+ I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
return 0;
}
void i915_driver_irq_uninstall(struct drm_device * dev)
{
- return;
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ u32 temp;
+
+ if (!dev_priv)
+ return;
+
+ dev_priv->vblank_pipe = 0;
+
+ dev_priv->irq_enabled = 0;
+ I915_WRITE(HWSTAM, 0xffffffff);
+ I915_WRITE(IMR, 0xffffffff);
+ I915_WRITE(IER, 0x0);
+
+ temp = I915_READ(PIPEASTAT);
+ I915_WRITE(PIPEASTAT, temp);
+ temp = I915_READ(PIPEBSTAT);
+ I915_WRITE(PIPEBSTAT, temp);
+ temp = I915_READ(IIR);
+ I915_WRITE(IIR, temp);
+
}
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index ae31e96..b02c27c 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1729,6 +1729,13 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
DRM_DEBUG("%s card detected\n",
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
+
+ ret = drm_vblank_init(dev, 2);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0x001fffff;
+
return ret;
}
@@ -1764,6 +1771,7 @@ int radeon_driver_unload(struct drm_device *dev)
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
+ drm_vblank_cleanup(dev);
drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
dev->dev_private = NULL;
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index 6956996..22aca57 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -339,17 +339,10 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
- int ret;
atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
- ret = drm_vblank_init(dev, 2);
- if (ret)
- return ret;
-
- dev->max_vblank_count = 0x001fffff;
-
radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
return 0;
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel