diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-08-21 18:23:18 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-08-21 18:23:18 +0000 |
commit | f44e4b203deb68368dd4bec45d50123844a89f26 (patch) | |
tree | b260a37ecb1efd8be2d4657c9693ec8b5a1c7267 /sys/dev/pci/drm | |
parent | d50db245ff77c46102ad1821b47c3a78aa72d1f6 (diff) |
Instead of having a number of malloced arrays for vblank handling, just
put them in a structure and malloc free an array of those, it is nicer
that way and They're all needed at the same time, anyway.
Idea taken from a suggestion on the dri-devel mailing list.
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r-- | sys/dev/pci/drm/drmP.h | 35 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_irq.c | 91 |
2 files changed, 47 insertions, 79 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index 65e9320f8cd..cbdbb6760a5 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -481,6 +481,18 @@ typedef struct drm_local_map { drm_map_type_t type; /* Type of memory mapped */ } drm_local_map_t; +struct drm_vblank { +#if 0 /* unneeded for now, signal support */ + TAILQ_HEAD(vbl_sigs); +#endif + u_int32_t last_vblank; /* Last vblank we recieved */ + atomic_t vbl_count; /* Number of interrupts */ + int vbl_queue; /* sleep on this when waiting */ + atomic_t vbl_refcount; /* Number of users */ + int vbl_enabled; /* Enabled? */ + int vbl_inmodeset; /* is the DDX currently modesetting */ +}; + TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig); typedef struct drm_vbl_sig { TAILQ_ENTRY(drm_vbl_sig) link; @@ -638,22 +650,13 @@ struct drm_device { int pci_func; /* VBLANK support */ - int vblank_disable_allowed; - int *vbl_queue; /* vbl wait channel */ - atomic_t *_vblank_count; /* no vblank interrupts */ - DRM_SPINTYPE vbl_lock; /* locking for vblank operations */ -#if 0 /* unneeded for now */ - TAILQ_HEAD(vbl_sigs); -#endif - atomic_t vbl_signal_pending; /* sigs pending on all crtcs */ - atomic_t *vblank_refcount; /* no. users for vlank interrupts */ - u_int32_t *last_vblank; /* locked, used for overflow handling*/ - int *vblank_enabled; /* make sure we only disable once */ - int *vblank_inmodeset; /* X DDX is currently setting mode */ - struct timeout vblank_disable_timer; - int num_crtcs; /* number of crtcs on device */ - - u_int32_t max_vblank_count; /* size of counter reg */ + int num_crtcs; /* number of crtcs */ + u_int32_t max_vblank_count; /* size of counter reg*/ + DRM_SPINTYPE vbl_lock; /* VBLANK data lock */ + atomic_t vbl_signal_pending; /* No. pending sigs */ + int vblank_disable_allowed; + struct timeout vblank_disable_timer; /* timer for disable */ + struct drm_vblank *vblank; /* One per ctrc */ pid_t buf_pgid; diff --git a/sys/dev/pci/drm/drm_irq.c b/sys/dev/pci/drm/drm_irq.c index dfd0bfdc98c..32d1abc9206 100644 --- a/sys/dev/pci/drm/drm_irq.c +++ b/sys/dev/pci/drm/drm_irq.c @@ -186,12 +186,12 @@ vblank_disable(void *arg) for (i=0; i < dev->num_crtcs; i++){ DRM_SPINLOCK(&dev->vbl_lock); - if (atomic_read(&dev->vblank_refcount[i]) == 0 && - dev->vblank_enabled[i]) { - dev->last_vblank[i] = + if (atomic_read(&dev->vblank[i].vbl_refcount) == 0 && + dev->vblank[i].vbl_enabled) { + dev->vblank[i].last_vblank = dev->driver.get_vblank_counter(dev, i); dev->driver.disable_vblank(dev, i); - dev->vblank_enabled[i] = 0; + dev->vblank[i].vbl_enabled = 0; } DRM_SPINUNLOCK(&dev->vbl_lock); } @@ -207,22 +207,10 @@ drm_vblank_cleanup(struct drm_device *dev) vblank_disable(dev); - drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * - dev->num_crtcs, M_DRM); -#if 0 /* disabled for now */ - drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, M_DRM); -#endif - drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * - dev->num_crtcs, M_DRM); - drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * - dev->num_crtcs, M_DRM); - drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * - dev->num_crtcs, M_DRM); - drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * - dev->num_crtcs, M_DRM); - drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * + drm_free(dev->vblank, sizeof(*dev->vblank) * dev->num_crtcs, M_DRM); + dev->vblank = NULL; dev->num_crtcs = 0; DRM_SPINUNINIT(&dev->vbl_lock); } @@ -230,40 +218,15 @@ drm_vblank_cleanup(struct drm_device *dev) int drm_vblank_init(struct drm_device *dev, int num_crtcs) { - int i; - timeout_set(&dev->vblank_disable_timer, vblank_disable, dev); mtx_init(&dev->vbl_lock, IPL_BIO); atomic_set(&dev->vbl_signal_pending, 0); dev->num_crtcs = num_crtcs; - if ((dev->vbl_queue = drm_calloc(num_crtcs, sizeof(*dev->vbl_queue), - M_DRM)) == NULL) - goto err; - - if ((dev->_vblank_count = drm_calloc(num_crtcs, - sizeof(*dev->_vblank_count), M_DRM)) == NULL) + dev->vblank = drm_calloc(num_crtcs, sizeof(*dev->vblank), M_DRM); + if (dev->vblank == NULL) goto err; - if ((dev->vblank_refcount = drm_calloc(num_crtcs, - sizeof(*dev->vblank_refcount), M_DRM)) == NULL) - goto err; - if ((dev->vblank_enabled = drm_calloc(num_crtcs, - sizeof(*dev->vblank_enabled), M_DRM)) == NULL) - goto err; - if ((dev->last_vblank = drm_calloc(num_crtcs, - sizeof(*dev->last_vblank), M_DRM)) == NULL) - goto err; - if ((dev->vblank_inmodeset = drm_calloc(num_crtcs, - sizeof(*dev->vblank_inmodeset), M_DRM)) == NULL) - goto err; - - /* Zero everything */ - for (i = 0; i < num_crtcs; i++) { - atomic_set(&dev->_vblank_count[i], 0); - atomic_set(&dev->vblank_refcount[i], 0); - } - dev->vblank_disable_allowed = 0; return (0); @@ -276,7 +239,7 @@ err: u_int32_t drm_vblank_count(struct drm_device *dev, int crtc) { - return atomic_read(&dev->_vblank_count[crtc]); + return atomic_read(&dev->vblank[crtc].vbl_count); } void @@ -290,11 +253,11 @@ drm_update_vblank_count(struct drm_device *dev, int crtc) * the register is small or the interrupts were off for a long time. */ cur_vblank = dev->driver.get_vblank_counter(dev, crtc); - diff = cur_vblank - dev->last_vblank[crtc]; - if (cur_vblank < dev->last_vblank[crtc]) + diff = cur_vblank - dev->vblank[crtc].last_vblank; + if (cur_vblank < dev->vblank[crtc].last_vblank) diff += dev->max_vblank_count; - atomic_add(diff, &dev->_vblank_count[crtc]); + atomic_add(diff, &dev->vblank[crtc].vbl_count); } int @@ -304,14 +267,14 @@ drm_vblank_get(struct drm_device *dev, int crtc) DRM_SPINLOCK(&dev->vbl_lock); - atomic_add(1, &dev->vblank_refcount[crtc]); - if (dev->vblank_refcount[crtc] == 1 && - dev->vblank_enabled[crtc] == 0) { + atomic_add(1, &dev->vblank[crtc].vbl_refcount); + if (dev->vblank[crtc].vbl_refcount == 1 && + dev->vblank[crtc].vbl_enabled == 0) { ret = dev->driver.enable_vblank(dev, crtc); if (ret) { - atomic_dec(&dev->vblank_refcount[crtc]); + atomic_dec(&dev->vblank[crtc].vbl_refcount); } else { - dev->vblank_enabled[crtc] = 1; + dev->vblank[crtc].vbl_enabled = 1; drm_update_vblank_count(dev, crtc); } } @@ -325,8 +288,8 @@ drm_vblank_put(struct drm_device *dev, int crtc) { DRM_SPINLOCK(&dev->vbl_lock); /* Last user schedules interrupt disable */ - atomic_dec(&dev->vblank_refcount[crtc]); - if (dev->vblank_refcount[crtc] == 0) + atomic_dec(&dev->vblank[crtc].vbl_refcount); + if (dev->vblank[crtc].vbl_refcount == 0) timeout_add_sec(&dev->vblank_disable_timer, 5); DRM_SPINUNLOCK(&dev->vbl_lock); } @@ -354,16 +317,18 @@ drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv) */ switch (modeset->cmd) { case _DRM_PRE_MODESET: - if (dev->vblank_inmodeset[crtc] == 0) { - dev->vblank_inmodeset[crtc] = 1; + if (dev->vblank[crtc].vbl_inmodeset == 0) { + DRM_SPINLOCK(&dev->vbl_lock); + dev->vblank[crtc].vbl_inmodeset = 1; + DRM_SPINUNLOCK(&dev->vbl_lock); drm_vblank_get(dev, crtc); } break; case _DRM_POST_MODESET: - if (dev->vblank_inmodeset[crtc]) { + if (dev->vblank[crtc].vbl_inmodeset) { DRM_SPINLOCK(&dev->vbl_lock); dev->vblank_disable_allowed = 1; - dev->vblank_inmodeset[crtc] = 0; + dev->vblank[crtc].vbl_inmodeset = 0; DRM_SPINUNLOCK(&dev->vbl_lock); drm_vblank_put(dev, crtc); } @@ -436,7 +401,7 @@ drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) DRM_SPINUNLOCK(&dev->vbl_lock); break; } - ret = msleep(&dev->vbl_queue[crtc], + ret = msleep(&dev->vblank[crtc].vbl_queue, &dev->vbl_lock, PZERO | PCATCH, "drmvblq", 3 * DRM_HZ); DRM_SPINUNLOCK(&dev->vbl_lock); @@ -489,8 +454,8 @@ drm_vbl_send_signals(struct drm_device *dev, int crtc) void drm_handle_vblank(struct drm_device *dev, int crtc) { - atomic_inc(&dev->_vblank_count[crtc]); - DRM_WAKEUP(&dev->vbl_queue[crtc]); + atomic_inc(&dev->vblank[crtc].vbl_count); + DRM_WAKEUP(&dev->vblank[crtc].vbl_queue); drm_vbl_send_signals(dev, crtc); } |