summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsd-core/drmP.h27
-rw-r--r--bsd-core/drm_irq.c101
2 files changed, 46 insertions, 82 deletions
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h
index 326b2202..473427f3 100644
--- a/bsd-core/drmP.h
+++ b/bsd-core/drmP.h
@@ -608,6 +608,19 @@ typedef struct drm_vbl_sig {
int pid;
} drm_vbl_sig_t;
+struct drm_vblank_info {
+ wait_queue_head_t queue; /* vblank wait queue */
+ atomic_t count; /* number of VBLANK interrupts */
+ /* (driver must alloc the right number of counters) */
+ struct drm_vbl_sig_list sigs; /* signal list to send on VBLANK */
+ atomic_t refcount; /* number of users of vblank interrupts */
+ u32 last; /* protected by dev->vbl_lock, used */
+ /* for wraparound handling */
+ int enabled; /* so we don't call enable more than */
+ /* once per disable */
+ int inmodeset; /* Display driver is setting mode */
+};
+
/* location of GART table */
#define DRM_ATI_GART_MAIN 1
#define DRM_ATI_GART_FB 2
@@ -787,20 +800,12 @@ struct drm_device {
atomic_t context_flag; /* Context swapping flag */
int last_context; /* Last current context */
+
int vblank_disable_allowed;
- wait_queue_head_t *vbl_queue; /* vblank wait queue */
- atomic_t *_vblank_count; /* number of VBLANK interrupts */
- /* (driver must alloc the right number of counters) */
- struct drm_vbl_sig_list *vbl_sigs; /* signal list to send on VBLANK */
- atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
- atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */
- u32 *last_vblank; /* protected by dev->vbl_lock, used */
- /* for wraparound handling */
- int *vblank_enabled; /* so we don't call enable more than */
- /* once per disable */
- int *vblank_inmodeset; /* Display driver is setting mode */
+ atomic_t vbl_signal_pending; /* number of signals pending on all crtcs */
struct callout vblank_disable_timer;
u32 max_vblank_count; /* size of vblank counter register */
+ struct drm_vblank_info *vblank; /* per crtc vblank info */
int num_crtcs;
#ifdef __FreeBSD__
diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c
index 6e21d41c..0f0d0fc8 100644
--- a/bsd-core/drm_irq.c
+++ b/bsd-core/drm_irq.c
@@ -85,13 +85,13 @@ static void vblank_disable_fn(void *arg)
return;
for (i = 0; i < dev->num_crtcs; i++) {
- if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
- dev->vblank_enabled[i]) {
+ if (atomic_read(&dev->vblank[i].refcount) == 0 &&
+ dev->vblank[i].enabled) {
DRM_DEBUG("disabling vblank on crtc %d\n", i);
- dev->last_vblank[i] =
+ dev->vblank[i].last =
dev->driver.get_vblank_counter(dev, i);
dev->driver.disable_vblank(dev, i);
- dev->vblank_enabled[i] = 0;
+ dev->vblank[i].enabled = 0;
}
}
}
@@ -112,20 +112,8 @@ static void drm_vblank_cleanup(struct drm_device *dev)
vblank_disable_fn((void *)dev);
- drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
+ drm_free(dev->vblank, sizeof(struct drm_vblank_info) * dev->num_crtcs,
DRM_MEM_DRIVER);
- drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
- DRM_MEM_DRIVER);
- drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
- dev->num_crtcs, DRM_MEM_DRIVER);
- drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
- dev->num_crtcs, DRM_MEM_DRIVER);
- drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
- dev->num_crtcs, DRM_MEM_DRIVER);
- drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
- DRM_MEM_DRIVER);
- drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
- dev->num_crtcs, DRM_MEM_DRIVER);
dev->num_crtcs = 0;
}
@@ -138,46 +126,17 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
atomic_set(&dev->vbl_signal_pending, 0);
dev->num_crtcs = num_crtcs;
- dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
- DRM_MEM_DRIVER);
- if (!dev->vbl_queue)
- goto err;
-
- dev->vbl_sigs = drm_alloc(sizeof(struct drm_vbl_sig) * num_crtcs,
- DRM_MEM_DRIVER);
- if (!dev->vbl_sigs)
- goto err;
-
- dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
- DRM_MEM_DRIVER);
- if (!dev->_vblank_count)
- goto err;
-
- dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
- DRM_MEM_DRIVER);
- if (!dev->vblank_refcount)
- goto err;
-
- dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
- DRM_MEM_DRIVER);
- if (!dev->vblank_enabled)
- goto err;
-
- dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
- if (!dev->last_vblank)
- goto err;
-
- dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
+ dev->vblank = drm_calloc(num_crtcs, sizeof(struct drm_vblank_info),
DRM_MEM_DRIVER);
- if (!dev->vblank_inmodeset)
+ if (!dev->vblank)
goto err;
/* Zero per-crtc vblank stuff */
for (i = 0; i < num_crtcs; i++) {
- DRM_INIT_WAITQUEUE(&dev->vbl_queue[i]);
- TAILQ_INIT(&dev->vbl_sigs[i]);
- atomic_set(&dev->_vblank_count[i], 0);
- atomic_set(&dev->vblank_refcount[i], 0);
+ DRM_INIT_WAITQUEUE(&dev->vblank[i].queue);
+ TAILQ_INIT(&dev->vblank[i].sigs);
+ atomic_set(&dev->vblank[i].count, 0);
+ atomic_set(&dev->vblank[i].refcount, 0);
}
dev->vblank_disable_allowed = 0;
@@ -330,7 +289,7 @@ int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv)
u32 drm_vblank_count(struct drm_device *dev, int crtc)
{
- return atomic_read(&dev->_vblank_count[crtc]);
+ return atomic_read(&dev->vblank[crtc].count);
}
static void drm_update_vblank_count(struct drm_device *dev, int crtc)
@@ -345,18 +304,18 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
* 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;
+ if (cur_vblank < dev->vblank[crtc].last) {
diff += dev->max_vblank_count;
DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
- crtc, dev->last_vblank[crtc], cur_vblank, diff);
+ crtc, dev->vblank[crtc].last, cur_vblank, diff);
}
DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
crtc, diff);
- atomic_add(diff, &dev->_vblank_count[crtc]);
+ atomic_add(diff, &dev->vblank[crtc].count);
}
int drm_vblank_get(struct drm_device *dev, int crtc)
@@ -366,14 +325,14 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
- atomic_add_acq_int(&dev->vblank_refcount[crtc], 1);
- if (dev->vblank_refcount[crtc] == 1 &&
- !dev->vblank_enabled[crtc]) {
+ atomic_add_acq_int(&dev->vblank[crtc].refcount, 1);
+ if (dev->vblank[crtc].refcount == 1 &&
+ !dev->vblank[crtc].enabled) {
ret = dev->driver.enable_vblank(dev, crtc);
if (ret)
- atomic_dec(&dev->vblank_refcount[crtc]);
+ atomic_dec(&dev->vblank[crtc].refcount);
else {
- dev->vblank_enabled[crtc] = 1;
+ dev->vblank[crtc].enabled = 1;
drm_update_vblank_count(dev, crtc);
}
}
@@ -388,8 +347,8 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);
/* Last user schedules interrupt disable */
- atomic_subtract_acq_int(&dev->vblank_refcount[crtc], 1);
- if (dev->vblank_refcount[crtc] == 0)
+ atomic_subtract_acq_int(&dev->vblank[crtc].refcount, 1);
+ if (dev->vblank[crtc].refcount == 0)
callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ,
(timeout_t *)vblank_disable_fn, (void *)dev);
DRM_SPINUNLOCK_IRQRESTORE(&dev->vbl_lock, irqflags);
@@ -421,16 +380,16 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,
*/
switch (modeset->cmd) {
case _DRM_PRE_MODESET:
- if (!dev->vblank_inmodeset[crtc]) {
- dev->vblank_inmodeset[crtc] = 1;
+ if (!dev->vblank[crtc].inmodeset) {
+ dev->vblank[crtc].inmodeset = 1;
drm_vblank_get(dev, crtc);
}
break;
case _DRM_POST_MODESET:
- if (dev->vblank_inmodeset[crtc]) {
+ if (dev->vblank[crtc].inmodeset) {
DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);
dev->vblank_disable_allowed = 1;
- dev->vblank_inmodeset[crtc] = 0;
+ dev->vblank[crtc].inmodeset = 0;
DRM_SPINUNLOCK_IRQRESTORE(&dev->vbl_lock, irqflags);
drm_vblank_put(dev, crtc);
}
@@ -511,7 +470,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
DRM_LOCK();
/* shared code returns -errno */
- DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
+ DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * DRM_HZ,
((drm_vblank_count(dev, crtc)
- vblwait->request.sequence) <= (1 << 23)));
DRM_UNLOCK();
@@ -561,8 +520,8 @@ void 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].count);
+ DRM_WAKEUP(&dev->vblank[crtc].queue);
drm_vbl_send_signals(dev, crtc);
}