diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-04-03 12:41:21 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-04-03 12:41:21 +0000 |
commit | a42bafa7a7c496b51d0003dec48fcd7f0a78c6ac (patch) | |
tree | c1aa8ec5ccb5a355e708b41c90f0b77ba384425a /sys | |
parent | 945edc728f8c2b49653ec54af3cae1e8af64d04c (diff) |
Same as just done for radeon. Add and use a lock for procecting against
races when waiting on fences, and use that in preference to irq_lock.
Don't use drm_irq_handler_wrap() anymore for irq handler, just the
mgadrm main irq handler. knf while here.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/drm/mga_drv.c | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/mga_drv.h | 10 | ||||
-rw-r--r-- | sys/dev/pci/drm/mga_irq.c | 42 | ||||
-rw-r--r-- | sys/dev/pci/drm/mga_state.c | 11 |
4 files changed, 34 insertions, 30 deletions
diff --git a/sys/dev/pci/drm/mga_drv.c b/sys/dev/pci/drm/mga_drv.c index 278249746d7..5e5464b4532 100644 --- a/sys/dev/pci/drm/mga_drv.c +++ b/sys/dev/pci/drm/mga_drv.c @@ -173,6 +173,7 @@ mgadrm_attach(struct device *parent, struct device *self, void *aux) return; } printf(": %s\n", pci_intr_string(pa->pa_pc, dev_priv->ih)); + mtx_init(&dev_priv->fence_lock, IPL_BIO); /* XXX pcie */ is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, diff --git a/sys/dev/pci/drm/mga_drv.h b/sys/dev/pci/drm/mga_drv.h index 8ca1d7cca3a..0c979ce9b55 100644 --- a/sys/dev/pci/drm/mga_drv.h +++ b/sys/dev/pci/drm/mga_drv.h @@ -119,9 +119,10 @@ typedef struct drm_mga_private { u32 clear_cmd; u32 maccess; - atomic_t vbl_received; /**< Number of vblanks received. */ - atomic_t last_fence_retired; - u32 next_fence_to_post; + atomic_t vbl_received; /**< Number of vblanks received. */ + struct mutex fence_lock; + u_int32_t last_fence_retired; + u_int32_t next_fence_to_post; unsigned int fb_cpp; unsigned int front_offset; @@ -186,8 +187,7 @@ extern int mga_warp_init(drm_mga_private_t * dev_priv); extern int mga_enable_vblank(struct drm_device *dev, int crtc); extern void mga_disable_vblank(struct drm_device *dev, int crtc); extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); -extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); -extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); +extern int mga_driver_fence_wait(struct drm_device * dev, u_int32_t *sequence); extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); extern int mga_driver_irq_install(struct drm_device * dev); extern void mga_driver_irq_uninstall(struct drm_device * dev); diff --git a/sys/dev/pci/drm/mga_irq.c b/sys/dev/pci/drm/mga_irq.c index 0d3bdac8730..6e0a736f84d 100644 --- a/sys/dev/pci/drm/mga_irq.c +++ b/sys/dev/pci/drm/mga_irq.c @@ -45,7 +45,6 @@ mga_get_vblank_counter(struct drm_device *dev, int crtc) return (0); } - return (atomic_read(&dev_priv->vbl_received)); } @@ -69,8 +68,8 @@ mga_driver_irq_handler(DRM_IRQ_ARGS) /* SOFTRAP interrupt */ if (status & MGA_SOFTRAPEN) { - const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); - const u32 prim_end = MGA_READ(MGA_PRIMEND); + const u_int32_t prim_start = MGA_READ(MGA_PRIMADDRESS); + const u_int32_t prim_end = MGA_READ(MGA_PRIMEND); MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); @@ -82,8 +81,10 @@ mga_driver_irq_handler(DRM_IRQ_ARGS) MGA_WRITE(MGA_PRIMEND, prim_end); } - atomic_inc(&dev_priv->last_fence_retired); + mtx_enter(&dev_priv->fence_lock); + dev_priv->last_fence_retired++; wakeup(dev_priv); + mtx_leave(&dev_priv->fence_lock); handled = 1; } @@ -92,22 +93,24 @@ mga_driver_irq_handler(DRM_IRQ_ARGS) return (IRQ_NONE); } -int mga_enable_vblank(struct drm_device *dev, int crtc) +int +mga_enable_vblank(struct drm_device *dev, int crtc) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; if (crtc != 0) { DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return 0; + return (0); } MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); - return 0; + return (0); } -void mga_disable_vblank(struct drm_device *dev, int crtc) +void +mga_disable_vblank(struct drm_device *dev, int crtc) { if (crtc != 0) { DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", @@ -122,29 +125,30 @@ void mga_disable_vblank(struct drm_device *dev, int crtc) /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ } -int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) +int +mga_driver_fence_wait(struct drm_device * dev, u_int32_t *sequence) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - unsigned int cur_fence; - int ret = 0; + drm_mga_private_t *dev_priv = dev->dev_private; + u_int32_t cur_fence; + int ret = 0; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using fences. */ - DRM_WAIT_ON(ret, dev_priv, &dev->irq_lock, 3 * hz, "mgawt", - (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) - + DRM_WAIT_ON(ret, dev_priv, &dev_priv->fence_lock, 3 * hz, "mgawt", + (((cur_fence = dev_priv->last_fence_retired) - *sequence) <= (1 << 23))); *sequence = cur_fence; - return ret; + return (ret); } int mga_driver_irq_install(struct drm_device * dev) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; /* Disable *all* interrupts */ MGA_WRITE(MGA_IEN, 0); @@ -152,7 +156,7 @@ mga_driver_irq_install(struct drm_device * dev) MGA_WRITE(MGA_ICLEAR, ~0); dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO, - drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname); + mga_driver_irq_handler, dev, dev_priv->dev.dv_xname); if (dev_priv->irqh == NULL) return (ENOENT); @@ -166,7 +170,7 @@ mga_driver_irq_install(struct drm_device * dev) void mga_driver_irq_uninstall(struct drm_device * dev) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; /* Disable *all* interrupts */ MGA_WRITE(MGA_IEN, 0); diff --git a/sys/dev/pci/drm/mga_state.c b/sys/dev/pci/drm/mga_state.c index f13c60fcdaa..3db6c44415d 100644 --- a/sys/dev/pci/drm/mga_state.c +++ b/sys/dev/pci/drm/mga_state.c @@ -1102,19 +1102,18 @@ int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv return 0; } -int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) +int +mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_mga_private_t *dev_priv = dev->dev_private; - u32 *fence = data; + drm_mga_private_t *dev_priv = dev->dev_private; + u_int32_t *fence = data; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return EINVAL; } - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - mga_driver_fence_wait(dev, fence); - return 0; + return (0); } |