aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_drv.c2
-rw-r--r--drivers/gpu/drm/drm_irq.c447
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c5
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c11
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h20
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c395
-rw-r--r--drivers/gpu/drm/mga/mga_drv.c29
-rw-r--r--drivers/gpu/drm/mga/mga_drv.h6
-rw-r--r--drivers/gpu/drm/mga/mga_irq.c74
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c29
-rw-r--r--drivers/gpu/drm/r128/r128_drv.h11
-rw-r--r--drivers/gpu/drm/r128/r128_irq.c55
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h27
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c268
-rw-r--r--drivers/gpu/drm/via/via_drv.c26
-rw-r--r--drivers/gpu/drm/via/via_drv.h16
-rw-r--r--drivers/gpu/drm/via/via_irq.c102
-rw-r--r--include/drm/drm.h15
-rw-r--r--include/drm/drmP.h90
21 files changed, 1189 insertions, 473 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 452c2d866ec..fb45fe7aeb8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -116,6 +116,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
116 116
117 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), 117 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
118 118
119 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
120
119 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 121 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
120}; 122};
121 123
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 61ed5158f78..d0c13d954f5 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -71,19 +71,131 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
71 return 0; 71 return 0;
72} 72}
73 73
74static void vblank_disable_fn(unsigned long arg)
75{
76 struct drm_device *dev = (struct drm_device *)arg;
77 unsigned long irqflags;
78 int i;
79
80 if (!dev->vblank_disable_allowed)
81 return;
82
83 for (i = 0; i < dev->num_crtcs; i++) {
84 spin_lock_irqsave(&dev->vbl_lock, irqflags);
85 if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
86 dev->vblank_enabled[i]) {
87 DRM_DEBUG("disabling vblank on crtc %d\n", i);
88 dev->last_vblank[i] =
89 dev->driver->get_vblank_counter(dev, i);
90 dev->driver->disable_vblank(dev, i);
91 dev->vblank_enabled[i] = 0;
92 }
93 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
94 }
95}
96
97static void drm_vblank_cleanup(struct drm_device *dev)
98{
99 /* Bail if the driver didn't call drm_vblank_init() */
100 if (dev->num_crtcs == 0)
101 return;
102
103 del_timer(&dev->vblank_disable_timer);
104
105 vblank_disable_fn((unsigned long)dev);
106
107 drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
108 DRM_MEM_DRIVER);
109 drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
110 DRM_MEM_DRIVER);
111 drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
112 dev->num_crtcs, DRM_MEM_DRIVER);
113 drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
114 dev->num_crtcs, DRM_MEM_DRIVER);
115 drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
116 dev->num_crtcs, DRM_MEM_DRIVER);
117 drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
118 DRM_MEM_DRIVER);
119 drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
120 dev->num_crtcs, DRM_MEM_DRIVER);
121
122 dev->num_crtcs = 0;
123}
124
125int drm_vblank_init(struct drm_device *dev, int num_crtcs)
126{
127 int i, ret = -ENOMEM;
128
129 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
130 (unsigned long)dev);
131 spin_lock_init(&dev->vbl_lock);
132 atomic_set(&dev->vbl_signal_pending, 0);
133 dev->num_crtcs = num_crtcs;
134
135 dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
136 DRM_MEM_DRIVER);
137 if (!dev->vbl_queue)
138 goto err;
139
140 dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
141 DRM_MEM_DRIVER);
142 if (!dev->vbl_sigs)
143 goto err;
144
145 dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
146 DRM_MEM_DRIVER);
147 if (!dev->_vblank_count)
148 goto err;
149
150 dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
151 DRM_MEM_DRIVER);
152 if (!dev->vblank_refcount)
153 goto err;
154
155 dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
156 DRM_MEM_DRIVER);
157 if (!dev->vblank_enabled)
158 goto err;
159
160 dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
161 if (!dev->last_vblank)
162 goto err;
163
164 dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
165 DRM_MEM_DRIVER);
166 if (!dev->vblank_inmodeset)
167 goto err;
168
169 /* Zero per-crtc vblank stuff */
170 for (i = 0; i < num_crtcs; i++) {
171 init_waitqueue_head(&dev->vbl_queue[i]);
172 INIT_LIST_HEAD(&dev->vbl_sigs[i]);
173 atomic_set(&dev->_vblank_count[i], 0);
174 atomic_set(&dev->vblank_refcount[i], 0);
175 }
176
177 dev->vblank_disable_allowed = 0;
178
179 return 0;
180
181err:
182 drm_vblank_cleanup(dev);
183 return ret;
184}
185EXPORT_SYMBOL(drm_vblank_init);
186
74/** 187/**
75 * Install IRQ handler. 188 * Install IRQ handler.
76 * 189 *
77 * \param dev DRM device. 190 * \param dev DRM device.
78 * \param irq IRQ number.
79 * 191 *
80 * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver 192 * Initializes the IRQ related data. Installs the handler, calling the driver
81 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions 193 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
82 * before and after the installation. 194 * before and after the installation.
83 */ 195 */
84static int drm_irq_install(struct drm_device * dev) 196int drm_irq_install(struct drm_device *dev)
85{ 197{
86 int ret; 198 int ret = 0;
87 unsigned long sh_flags = 0; 199 unsigned long sh_flags = 0;
88 200
89 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 201 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
@@ -109,17 +221,6 @@ static int drm_irq_install(struct drm_device * dev)
109 221
110 DRM_DEBUG("irq=%d\n", dev->pdev->irq); 222 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
111 223
112 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
113 init_waitqueue_head(&dev->vbl_queue);
114
115 spin_lock_init(&dev->vbl_lock);
116
117 INIT_LIST_HEAD(&dev->vbl_sigs);
118 INIT_LIST_HEAD(&dev->vbl_sigs2);
119
120 dev->vbl_pending = 0;
121 }
122
123 /* Before installing handler */ 224 /* Before installing handler */
124 dev->driver->irq_preinstall(dev); 225 dev->driver->irq_preinstall(dev);
125 226
@@ -141,10 +242,16 @@ static int drm_irq_install(struct drm_device * dev)
141 } 242 }
142 243
143 /* After installing handler */ 244 /* After installing handler */
144 dev->driver->irq_postinstall(dev); 245 ret = dev->driver->irq_postinstall(dev);
246 if (ret < 0) {
247 mutex_lock(&dev->struct_mutex);
248 dev->irq_enabled = 0;
249 mutex_unlock(&dev->struct_mutex);
250 }
145 251
146 return 0; 252 return ret;
147} 253}
254EXPORT_SYMBOL(drm_irq_install);
148 255
149/** 256/**
150 * Uninstall the IRQ handler. 257 * Uninstall the IRQ handler.
@@ -174,11 +281,12 @@ int drm_irq_uninstall(struct drm_device * dev)
174 281
175 free_irq(dev->pdev->irq, dev); 282 free_irq(dev->pdev->irq, dev);
176 283
284 drm_vblank_cleanup(dev);
285
177 dev->locked_tasklet_func = NULL; 286 dev->locked_tasklet_func = NULL;
178 287
179 return 0; 288 return 0;
180} 289}
181
182EXPORT_SYMBOL(drm_irq_uninstall); 290EXPORT_SYMBOL(drm_irq_uninstall);
183 291
184/** 292/**
@@ -218,6 +326,174 @@ int drm_control(struct drm_device *dev, void *data,
218} 326}
219 327
220/** 328/**
329 * drm_vblank_count - retrieve "cooked" vblank counter value
330 * @dev: DRM device
331 * @crtc: which counter to retrieve
332 *
333 * Fetches the "cooked" vblank count value that represents the number of
334 * vblank events since the system was booted, including lost events due to
335 * modesetting activity.
336 */
337u32 drm_vblank_count(struct drm_device *dev, int crtc)
338{
339 return atomic_read(&dev->_vblank_count[crtc]);
340}
341EXPORT_SYMBOL(drm_vblank_count);
342
343/**
344 * drm_update_vblank_count - update the master vblank counter
345 * @dev: DRM device
346 * @crtc: counter to update
347 *
348 * Call back into the driver to update the appropriate vblank counter
349 * (specified by @crtc). Deal with wraparound, if it occurred, and
350 * update the last read value so we can deal with wraparound on the next
351 * call if necessary.
352 *
353 * Only necessary when going from off->on, to account for frames we
354 * didn't get an interrupt for.
355 *
356 * Note: caller must hold dev->vbl_lock since this reads & writes
357 * device vblank fields.
358 */
359static void drm_update_vblank_count(struct drm_device *dev, int crtc)
360{
361 u32 cur_vblank, diff;
362
363 /*
364 * Interrupts were disabled prior to this call, so deal with counter
365 * wrap if needed.
366 * NOTE! It's possible we lost a full dev->max_vblank_count events
367 * here if the register is small or we had vblank interrupts off for
368 * a long time.
369 */
370 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
371 diff = cur_vblank - dev->last_vblank[crtc];
372 if (cur_vblank < dev->last_vblank[crtc]) {
373 diff += dev->max_vblank_count;
374
375 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
376 crtc, dev->last_vblank[crtc], cur_vblank, diff);
377 }
378
379 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
380 crtc, diff);
381
382 atomic_add(diff, &dev->_vblank_count[crtc]);
383}
384
385/**
386 * drm_vblank_get - get a reference count on vblank events
387 * @dev: DRM device
388 * @crtc: which CRTC to own
389 *
390 * Acquire a reference count on vblank events to avoid having them disabled
391 * while in use.
392 *
393 * RETURNS
394 * Zero on success, nonzero on failure.
395 */
396int drm_vblank_get(struct drm_device *dev, int crtc)
397{
398 unsigned long irqflags;
399 int ret = 0;
400
401 spin_lock_irqsave(&dev->vbl_lock, irqflags);
402 /* Going from 0->1 means we have to enable interrupts again */
403 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
404 !dev->vblank_enabled[crtc]) {
405 ret = dev->driver->enable_vblank(dev, crtc);
406 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
407 if (ret)
408 atomic_dec(&dev->vblank_refcount[crtc]);
409 else {
410 dev->vblank_enabled[crtc] = 1;
411 drm_update_vblank_count(dev, crtc);
412 }
413 }
414 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
415
416 return ret;
417}
418EXPORT_SYMBOL(drm_vblank_get);
419
420/**
421 * drm_vblank_put - give up ownership of vblank events
422 * @dev: DRM device
423 * @crtc: which counter to give up
424 *
425 * Release ownership of a given vblank counter, turning off interrupts
426 * if possible.
427 */
428void drm_vblank_put(struct drm_device *dev, int crtc)
429{
430 /* Last user schedules interrupt disable */
431 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
432 mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
433}
434EXPORT_SYMBOL(drm_vblank_put);
435
436/**
437 * drm_modeset_ctl - handle vblank event counter changes across mode switch
438 * @DRM_IOCTL_ARGS: standard ioctl arguments
439 *
440 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
441 * ioctls around modesetting so that any lost vblank events are accounted for.
442 *
443 * Generally the counter will reset across mode sets. If interrupts are
444 * enabled around this call, we don't have to do anything since the counter
445 * will have already been incremented.
446 */
447int drm_modeset_ctl(struct drm_device *dev, void *data,
448 struct drm_file *file_priv)
449{
450 struct drm_modeset_ctl *modeset = data;
451 unsigned long irqflags;
452 int crtc, ret = 0;
453
454 /* If drm_vblank_init() hasn't been called yet, just no-op */
455 if (!dev->num_crtcs)
456 goto out;
457
458 crtc = modeset->crtc;
459 if (crtc >= dev->num_crtcs) {
460 ret = -EINVAL;
461 goto out;
462 }
463
464 /*
465 * To avoid all the problems that might happen if interrupts
466 * were enabled/disabled around or between these calls, we just
467 * have the kernel take a reference on the CRTC (just once though
468 * to avoid corrupting the count if multiple, mismatch calls occur),
469 * so that interrupts remain enabled in the interim.
470 */
471 switch (modeset->cmd) {
472 case _DRM_PRE_MODESET:
473 if (!dev->vblank_inmodeset[crtc]) {
474 dev->vblank_inmodeset[crtc] = 1;
475 drm_vblank_get(dev, crtc);
476 }
477 break;
478 case _DRM_POST_MODESET:
479 if (dev->vblank_inmodeset[crtc]) {
480 spin_lock_irqsave(&dev->vbl_lock, irqflags);
481 dev->vblank_disable_allowed = 1;
482 dev->vblank_inmodeset[crtc] = 0;
483 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
484 drm_vblank_put(dev, crtc);
485 }
486 break;
487 default:
488 ret = -EINVAL;
489 break;
490 }
491
492out:
493 return ret;
494}
495
496/**
221 * Wait for VBLANK. 497 * Wait for VBLANK.
222 * 498 *
223 * \param inode device inode. 499 * \param inode device inode.
@@ -236,12 +512,12 @@ int drm_control(struct drm_device *dev, void *data,
236 * 512 *
237 * If a signal is not requested, then calls vblank_wait(). 513 * If a signal is not requested, then calls vblank_wait().
238 */ 514 */
239int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) 515int drm_wait_vblank(struct drm_device *dev, void *data,
516 struct drm_file *file_priv)
240{ 517{
241 union drm_wait_vblank *vblwait = data; 518 union drm_wait_vblank *vblwait = data;
242 struct timeval now;
243 int ret = 0; 519 int ret = 0;
244 unsigned int flags, seq; 520 unsigned int flags, seq, crtc;
245 521
246 if ((!dev->pdev->irq) || (!dev->irq_enabled)) 522 if ((!dev->pdev->irq) || (!dev->irq_enabled))
247 return -EINVAL; 523 return -EINVAL;
@@ -255,13 +531,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
255 } 531 }
256 532
257 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 533 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
534 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
258 535
259 if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? 536 if (crtc >= dev->num_crtcs)
260 DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
261 return -EINVAL; 537 return -EINVAL;
262 538
263 seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 539 ret = drm_vblank_get(dev, crtc);
264 : &dev->vbl_received); 540 if (ret) {
541 DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
542 return ret;
543 }
544 seq = drm_vblank_count(dev, crtc);
265 545
266 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { 546 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
267 case _DRM_VBLANK_RELATIVE: 547 case _DRM_VBLANK_RELATIVE:
@@ -270,7 +550,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
270 case _DRM_VBLANK_ABSOLUTE: 550 case _DRM_VBLANK_ABSOLUTE:
271 break; 551 break;
272 default: 552 default:
273 return -EINVAL; 553 ret = -EINVAL;
554 goto done;
274 } 555 }
275 556
276 if ((flags & _DRM_VBLANK_NEXTONMISS) && 557 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
@@ -280,8 +561,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
280 561
281 if (flags & _DRM_VBLANK_SIGNAL) { 562 if (flags & _DRM_VBLANK_SIGNAL) {
282 unsigned long irqflags; 563 unsigned long irqflags;
283 struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) 564 struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
284 ? &dev->vbl_sigs2 : &dev->vbl_sigs;
285 struct drm_vbl_sig *vbl_sig; 565 struct drm_vbl_sig *vbl_sig;
286 566
287 spin_lock_irqsave(&dev->vbl_lock, irqflags); 567 spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -302,22 +582,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
302 } 582 }
303 } 583 }
304 584
305 if (dev->vbl_pending >= 100) { 585 if (atomic_read(&dev->vbl_signal_pending) >= 100) {
306 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 586 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
307 return -EBUSY; 587 ret = -EBUSY;
588 goto done;
308 } 589 }
309 590
310 dev->vbl_pending++;
311
312 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 591 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
313 592
314 if (! 593 vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
315 (vbl_sig = 594 DRM_MEM_DRIVER);
316 drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { 595 if (!vbl_sig) {
317 return -ENOMEM; 596 ret = -ENOMEM;
597 goto done;
598 }
599
600 ret = drm_vblank_get(dev, crtc);
601 if (ret) {
602 drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
603 DRM_MEM_DRIVER);
604 return ret;
318 } 605 }
319 606
320 memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); 607 atomic_inc(&dev->vbl_signal_pending);
321 608
322 vbl_sig->sequence = vblwait->request.sequence; 609 vbl_sig->sequence = vblwait->request.sequence;
323 vbl_sig->info.si_signo = vblwait->request.signal; 610 vbl_sig->info.si_signo = vblwait->request.signal;
@@ -331,20 +618,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
331 618
332 vblwait->reply.sequence = seq; 619 vblwait->reply.sequence = seq;
333 } else { 620 } else {
334 if (flags & _DRM_VBLANK_SECONDARY) { 621 DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
335 if (dev->driver->vblank_wait2) 622 vblwait->request.sequence, crtc);
336 ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); 623 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
337 } else if (dev->driver->vblank_wait) 624 ((drm_vblank_count(dev, crtc)
338 ret = 625 - vblwait->request.sequence) <= (1 << 23)));
339 dev->driver->vblank_wait(dev, 626
340 &vblwait->request.sequence); 627 if (ret != -EINTR) {
341 628 struct timeval now;
342 do_gettimeofday(&now); 629
343 vblwait->reply.tval_sec = now.tv_sec; 630 do_gettimeofday(&now);
344 vblwait->reply.tval_usec = now.tv_usec; 631
632 vblwait->reply.tval_sec = now.tv_sec;
633 vblwait->reply.tval_usec = now.tv_usec;
634 vblwait->reply.sequence = drm_vblank_count(dev, crtc);
635 DRM_DEBUG("returning %d to client\n",
636 vblwait->reply.sequence);
637 } else {
638 DRM_DEBUG("vblank wait interrupted by signal\n");
639 }
345 } 640 }
346 641
347 done: 642done:
643 drm_vblank_put(dev, crtc);
348 return ret; 644 return ret;
349} 645}
350 646
@@ -352,44 +648,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
352 * Send the VBLANK signals. 648 * Send the VBLANK signals.
353 * 649 *
354 * \param dev DRM device. 650 * \param dev DRM device.
651 * \param crtc CRTC where the vblank event occurred
355 * 652 *
356 * Sends a signal for each task in drm_device::vbl_sigs and empties the list. 653 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
357 * 654 *
358 * If a signal is not requested, then calls vblank_wait(). 655 * If a signal is not requested, then calls vblank_wait().
359 */ 656 */
360void drm_vbl_send_signals(struct drm_device * dev) 657static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
361{ 658{
659 struct drm_vbl_sig *vbl_sig, *tmp;
660 struct list_head *vbl_sigs;
661 unsigned int vbl_seq;
362 unsigned long flags; 662 unsigned long flags;
363 int i;
364 663
365 spin_lock_irqsave(&dev->vbl_lock, flags); 664 spin_lock_irqsave(&dev->vbl_lock, flags);
366 665
367 for (i = 0; i < 2; i++) { 666 vbl_sigs = &dev->vbl_sigs[crtc];
368 struct drm_vbl_sig *vbl_sig, *tmp; 667 vbl_seq = drm_vblank_count(dev, crtc);
369 struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
370 unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
371 &dev->vbl_received);
372 668
373 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { 669 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
374 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { 670 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
375 vbl_sig->info.si_code = vbl_seq; 671 vbl_sig->info.si_code = vbl_seq;
376 send_sig_info(vbl_sig->info.si_signo, 672 send_sig_info(vbl_sig->info.si_signo,
377 &vbl_sig->info, vbl_sig->task); 673 &vbl_sig->info, vbl_sig->task);
378 674
379 list_del(&vbl_sig->head); 675 list_del(&vbl_sig->head);
380
381 drm_free(vbl_sig, sizeof(*vbl_sig),
382 DRM_MEM_DRIVER);
383 676
384 dev->vbl_pending--; 677 drm_free(vbl_sig, sizeof(*vbl_sig),
385 } 678 DRM_MEM_DRIVER);
386 } 679 atomic_dec(&dev->vbl_signal_pending);
680 drm_vblank_put(dev, crtc);
681 }
387 } 682 }
388 683
389 spin_unlock_irqrestore(&dev->vbl_lock, flags); 684 spin_unlock_irqrestore(&dev->vbl_lock, flags);
390} 685}
391 686
392EXPORT_SYMBOL(drm_vbl_send_signals); 687/**
688 * drm_handle_vblank - handle a vblank event
689 * @dev: DRM device
690 * @crtc: where this event occurred
691 *
692 * Drivers should call this routine in their vblank interrupt handlers to
693 * update the vblank counter and send any signals that may be pending.
694 */
695void drm_handle_vblank(struct drm_device *dev, int crtc)
696{
697 atomic_inc(&dev->_vblank_count[crtc]);
698 DRM_WAKEUP(&dev->vbl_queue[crtc]);
699 drm_vbl_send_signals(dev, crtc);
700}
701EXPORT_SYMBOL(drm_handle_vblank);
393 702
394/** 703/**
395 * Tasklet wrapper function. 704 * Tasklet wrapper function.
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 29115450ee4..63c6803d471 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -673,7 +673,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
673 673
674 switch (param->param) { 674 switch (param->param) {
675 case I915_PARAM_IRQ_ACTIVE: 675 case I915_PARAM_IRQ_ACTIVE:
676 value = dev->irq_enabled; 676 value = dev->pdev->irq ? 1 : 0;
677 break; 677 break;
678 case I915_PARAM_ALLOW_BATCHBUFFER: 678 case I915_PARAM_ALLOW_BATCHBUFFER:
679 value = dev_priv->allow_batchbuffer ? 1 : 0; 679 value = dev_priv->allow_batchbuffer ? 1 : 0;
@@ -808,7 +808,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
808 * and the registers being closely associated. 808 * and the registers being closely associated.
809 */ 809 */
810 if (!IS_I945G(dev) && !IS_I945GM(dev)) 810 if (!IS_I945G(dev) && !IS_I945GM(dev))
811 pci_enable_msi(dev->pdev); 811 if (pci_enable_msi(dev->pdev))
812 DRM_ERROR("failed to enable MSI\n");
812 813
813 intel_opregion_init(dev); 814 intel_opregion_init(dev);
814 815
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index eff66ed3e58..37af03f4db3 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -85,10 +85,8 @@ static struct drm_driver driver = {
85 /* don't use mtrr's here, the Xserver or user space app should 85 /* don't use mtrr's here, the Xserver or user space app should
86 * deal with them for intel hardware. 86 * deal with them for intel hardware.
87 */ 87 */
88 .driver_features = 88 .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
89 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ 89 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
90 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
91 DRIVER_IRQ_VBL2,
92 .load = i915_driver_load, 90 .load = i915_driver_load,
93 .unload = i915_driver_unload, 91 .unload = i915_driver_unload,
94 .lastclose = i915_driver_lastclose, 92 .lastclose = i915_driver_lastclose,
@@ -96,8 +94,9 @@ static struct drm_driver driver = {
96 .suspend = i915_suspend, 94 .suspend = i915_suspend,
97 .resume = i915_resume, 95 .resume = i915_resume,
98 .device_is_agp = i915_driver_device_is_agp, 96 .device_is_agp = i915_driver_device_is_agp,
99 .vblank_wait = i915_driver_vblank_wait, 97 .get_vblank_counter = i915_get_vblank_counter,
100 .vblank_wait2 = i915_driver_vblank_wait2, 98 .enable_vblank = i915_enable_vblank,
99 .disable_vblank = i915_disable_vblank,
101 .irq_preinstall = i915_driver_irq_preinstall, 100 .irq_preinstall = i915_driver_irq_preinstall,
102 .irq_postinstall = i915_driver_irq_postinstall, 101 .irq_postinstall = i915_driver_irq_postinstall,
103 .irq_uninstall = i915_driver_irq_uninstall, 102 .irq_uninstall = i915_driver_irq_uninstall,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 71326ca9367..d1a02bead45 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -83,10 +83,15 @@ struct mem_block {
83typedef struct _drm_i915_vbl_swap { 83typedef struct _drm_i915_vbl_swap {
84 struct list_head head; 84 struct list_head head;
85 drm_drawable_t drw_id; 85 drm_drawable_t drw_id;
86 unsigned int pipe; 86 unsigned int plane;
87 unsigned int sequence; 87 unsigned int sequence;
88} drm_i915_vbl_swap_t; 88} drm_i915_vbl_swap_t;
89 89
90struct opregion_header;
91struct opregion_acpi;
92struct opregion_swsci;
93struct opregion_asle;
94
90struct intel_opregion { 95struct intel_opregion {
91 struct opregion_header *header; 96 struct opregion_header *header;
92 struct opregion_acpi *acpi; 97 struct opregion_acpi *acpi;
@@ -105,7 +110,7 @@ typedef struct drm_i915_private {
105 drm_dma_handle_t *status_page_dmah; 110 drm_dma_handle_t *status_page_dmah;
106 void *hw_status_page; 111 void *hw_status_page;
107 dma_addr_t dma_status_page; 112 dma_addr_t dma_status_page;
108 unsigned long counter; 113 uint32_t counter;
109 unsigned int status_gfx_addr; 114 unsigned int status_gfx_addr;
110 drm_local_map_t hws_map; 115 drm_local_map_t hws_map;
111 116
@@ -247,16 +252,17 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
247extern int i915_irq_wait(struct drm_device *dev, void *data, 252extern int i915_irq_wait(struct drm_device *dev, void *data,
248 struct drm_file *file_priv); 253 struct drm_file *file_priv);
249 254
250extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
251extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
252extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 255extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
253extern void i915_driver_irq_preinstall(struct drm_device * dev); 256extern void i915_driver_irq_preinstall(struct drm_device * dev);
254extern void i915_driver_irq_postinstall(struct drm_device * dev); 257extern int i915_driver_irq_postinstall(struct drm_device *dev);
255extern void i915_driver_irq_uninstall(struct drm_device * dev); 258extern void i915_driver_irq_uninstall(struct drm_device * dev);
256extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, 259extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
257 struct drm_file *file_priv); 260 struct drm_file *file_priv);
258extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, 261extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
259 struct drm_file *file_priv); 262 struct drm_file *file_priv);
263extern int i915_enable_vblank(struct drm_device *dev, int crtc);
264extern void i915_disable_vblank(struct drm_device *dev, int crtc);
265extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
260extern int i915_vblank_swap(struct drm_device *dev, void *data, 266extern int i915_vblank_swap(struct drm_device *dev, void *data,
261 struct drm_file *file_priv); 267 struct drm_file *file_priv);
262extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); 268extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
@@ -278,6 +284,10 @@ extern void i915_mem_release(struct drm_device * dev,
278extern int i915_save_state(struct drm_device *dev); 284extern int i915_save_state(struct drm_device *dev);
279extern int i915_restore_state(struct drm_device *dev); 285extern int i915_restore_state(struct drm_device *dev);
280 286
287/* i915_suspend.c */
288extern int i915_save_state(struct drm_device *dev);
289extern int i915_restore_state(struct drm_device *dev);
290
281/* i915_opregion.c */ 291/* i915_opregion.c */
282extern int intel_opregion_init(struct drm_device *dev); 292extern int intel_opregion_init(struct drm_device *dev);
283extern void intel_opregion_free(struct drm_device *dev); 293extern void intel_opregion_free(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index ae7d3a82a6d..f8759597233 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -35,9 +35,8 @@
35 35
36/** These are the interrupts used by the driver */ 36/** These are the interrupts used by the driver */
37#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ 37#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
38 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
39 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
40 I915_ASLE_INTERRUPT | \ 38 I915_ASLE_INTERRUPT | \
39 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
41 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) 40 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
42 41
43void 42void
@@ -61,6 +60,64 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
61} 60}
62 61
63/** 62/**
63 * i915_get_pipe - return the the pipe associated with a given plane
64 * @dev: DRM device
65 * @plane: plane to look for
66 *
67 * The Intel Mesa & 2D drivers call the vblank routines with a plane number
68 * rather than a pipe number, since they may not always be equal. This routine
69 * maps the given @plane back to a pipe number.
70 */
71static int
72i915_get_pipe(struct drm_device *dev, int plane)
73{
74 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
75 u32 dspcntr;
76
77 dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
78
79 return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
80}
81
82/**
83 * i915_get_plane - return the the plane associated with a given pipe
84 * @dev: DRM device
85 * @pipe: pipe to look for
86 *
87 * The Intel Mesa & 2D drivers call the vblank routines with a plane number
88 * rather than a plane number, since they may not always be equal. This routine
89 * maps the given @pipe back to a plane number.
90 */
91static int
92i915_get_plane(struct drm_device *dev, int pipe)
93{
94 if (i915_get_pipe(dev, 0) == pipe)
95 return 0;
96 return 1;
97}
98
99/**
100 * i915_pipe_enabled - check if a pipe is enabled
101 * @dev: DRM device
102 * @pipe: pipe to check
103 *
104 * Reading certain registers when the pipe is disabled can hang the chip.
105 * Use this routine to make sure the PLL is running and the pipe is active
106 * before reading such registers if unsure.
107 */
108static int
109i915_pipe_enabled(struct drm_device *dev, int pipe)
110{
111 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
112 unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
113
114 if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
115 return 1;
116
117 return 0;
118}
119
120/**
64 * Emit blits for scheduled buffer swaps. 121 * Emit blits for scheduled buffer swaps.
65 * 122 *
66 * This function will be called with the HW lock held. 123 * This function will be called with the HW lock held.
@@ -71,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
71 unsigned long irqflags; 128 unsigned long irqflags;
72 struct list_head *list, *tmp, hits, *hit; 129 struct list_head *list, *tmp, hits, *hit;
73 int nhits, nrects, slice[2], upper[2], lower[2], i; 130 int nhits, nrects, slice[2], upper[2], lower[2], i;
74 unsigned counter[2] = { atomic_read(&dev->vbl_received), 131 unsigned counter[2];
75 atomic_read(&dev->vbl_received2) };
76 struct drm_drawable_info *drw; 132 struct drm_drawable_info *drw;
77 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; 133 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
78 u32 cpp = dev_priv->cpp; 134 u32 cpp = dev_priv->cpp;
@@ -94,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
94 src_pitch >>= 2; 150 src_pitch >>= 2;
95 } 151 }
96 152
153 counter[0] = drm_vblank_count(dev, 0);
154 counter[1] = drm_vblank_count(dev, 1);
155
97 DRM_DEBUG("\n"); 156 DRM_DEBUG("\n");
98 157
99 INIT_LIST_HEAD(&hits); 158 INIT_LIST_HEAD(&hits);
@@ -106,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev)
106 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { 165 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
107 drm_i915_vbl_swap_t *vbl_swap = 166 drm_i915_vbl_swap_t *vbl_swap =
108 list_entry(list, drm_i915_vbl_swap_t, head); 167 list_entry(list, drm_i915_vbl_swap_t, head);
168 int pipe = i915_get_pipe(dev, vbl_swap->plane);
109 169
110 if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) 170 if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
111 continue; 171 continue;
112 172
113 list_del(list); 173 list_del(list);
114 dev_priv->swaps_pending--; 174 dev_priv->swaps_pending--;
175 drm_vblank_put(dev, pipe);
115 176
116 spin_unlock(&dev_priv->swaps_lock); 177 spin_unlock(&dev_priv->swaps_lock);
117 spin_lock(&dev->drw_lock); 178 spin_lock(&dev->drw_lock);
@@ -204,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
204 drm_i915_vbl_swap_t *swap_hit = 265 drm_i915_vbl_swap_t *swap_hit =
205 list_entry(hit, drm_i915_vbl_swap_t, head); 266 list_entry(hit, drm_i915_vbl_swap_t, head);
206 struct drm_clip_rect *rect; 267 struct drm_clip_rect *rect;
207 int num_rects, pipe; 268 int num_rects, plane;
208 unsigned short top, bottom; 269 unsigned short top, bottom;
209 270
210 drw = drm_get_drawable_info(dev, swap_hit->drw_id); 271 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
@@ -213,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
213 continue; 274 continue;
214 275
215 rect = drw->rects; 276 rect = drw->rects;
216 pipe = swap_hit->pipe; 277 plane = swap_hit->plane;
217 top = upper[pipe]; 278 top = upper[plane];
218 bottom = lower[pipe]; 279 bottom = lower[plane];
219 280
220 for (num_rects = drw->num_rects; num_rects--; rect++) { 281 for (num_rects = drw->num_rects; num_rects--; rect++) {
221 int y1 = max(rect->y1, top); 282 int y1 = max(rect->y1, top);
@@ -252,22 +313,54 @@ static void i915_vblank_tasklet(struct drm_device *dev)
252 } 313 }
253} 314}
254 315
316u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
317{
318 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
319 unsigned long high_frame;
320 unsigned long low_frame;
321 u32 high1, high2, low, count;
322 int pipe;
323
324 pipe = i915_get_pipe(dev, plane);
325 high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
326 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
327
328 if (!i915_pipe_enabled(dev, pipe)) {
329 DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
330 return 0;
331 }
332
333 /*
334 * High & low register fields aren't synchronized, so make sure
335 * we get a low value that's stable across two reads of the high
336 * register.
337 */
338 do {
339 high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
340 PIPE_FRAME_HIGH_SHIFT);
341 low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
342 PIPE_FRAME_LOW_SHIFT);
343 high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
344 PIPE_FRAME_HIGH_SHIFT);
345 } while (high1 != high2);
346
347 count = (high1 << 8) | low;
348
349 return count;
350}
351
255irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 352irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
256{ 353{
257 struct drm_device *dev = (struct drm_device *) arg; 354 struct drm_device *dev = (struct drm_device *) arg;
258 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 355 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
259 u32 pipea_stats, pipeb_stats;
260 u32 iir; 356 u32 iir;
261 357 u32 pipea_stats, pipeb_stats;
262 pipea_stats = I915_READ(PIPEASTAT); 358 int vblank = 0;
263 pipeb_stats = I915_READ(PIPEBSTAT);
264 359
265 if (dev->pdev->msi_enabled) 360 if (dev->pdev->msi_enabled)
266 I915_WRITE(IMR, ~0); 361 I915_WRITE(IMR, ~0);
267 iir = I915_READ(IIR); 362 iir = I915_READ(IIR);
268 363
269 DRM_DEBUG("iir=%08x\n", iir);
270
271 if (iir == 0) { 364 if (iir == 0) {
272 if (dev->pdev->msi_enabled) { 365 if (dev->pdev->msi_enabled) {
273 I915_WRITE(IMR, dev_priv->irq_mask_reg); 366 I915_WRITE(IMR, dev_priv->irq_mask_reg);
@@ -276,48 +369,56 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
276 return IRQ_NONE; 369 return IRQ_NONE;
277 } 370 }
278 371
279 I915_WRITE(PIPEASTAT, pipea_stats); 372 /*
280 I915_WRITE(PIPEBSTAT, pipeb_stats); 373 * Clear the PIPE(A|B)STAT regs before the IIR otherwise
281 374 * we may get extra interrupts.
282 I915_WRITE(IIR, iir); 375 */
283 if (dev->pdev->msi_enabled) 376 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
284 I915_WRITE(IMR, dev_priv->irq_mask_reg); 377 pipea_stats = I915_READ(PIPEASTAT);
285 (void) I915_READ(IIR); /* Flush posted writes */ 378 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
286 379 pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
287 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 380 PIPE_VBLANK_INTERRUPT_ENABLE);
288 381 else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
289 if (iir & I915_USER_INTERRUPT) 382 PIPE_VBLANK_INTERRUPT_STATUS)) {
290 DRM_WAKEUP(&dev_priv->irq_queue); 383 vblank++;
291 384 drm_handle_vblank(dev, i915_get_plane(dev, 0));
292 if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | 385 }
293 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
294 int vblank_pipe = dev_priv->vblank_pipe;
295
296 if ((vblank_pipe &
297 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
298 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
299 if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
300 atomic_inc(&dev->vbl_received);
301 if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
302 atomic_inc(&dev->vbl_received2);
303 } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
304 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
305 ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
306 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
307 atomic_inc(&dev->vbl_received);
308 386
309 DRM_WAKEUP(&dev->vbl_queue); 387 I915_WRITE(PIPEASTAT, pipea_stats);
310 drm_vbl_send_signals(dev); 388 }
389 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
390 pipeb_stats = I915_READ(PIPEBSTAT);
391 /* Ack the event */
392 I915_WRITE(PIPEBSTAT, pipeb_stats);
393
394 /* The vblank interrupt gets enabled even if we didn't ask for
395 it, so make sure it's shut down again */
396 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
397 pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
398 PIPE_VBLANK_INTERRUPT_ENABLE);
399 else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
400 PIPE_VBLANK_INTERRUPT_STATUS)) {
401 vblank++;
402 drm_handle_vblank(dev, i915_get_plane(dev, 1));
403 }
311 404
312 if (dev_priv->swaps_pending > 0) 405 if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
313 drm_locked_tasklet(dev, i915_vblank_tasklet); 406 opregion_asle_intr(dev);
407 I915_WRITE(PIPEBSTAT, pipeb_stats);
314 } 408 }
315 409
316 if (iir & I915_ASLE_INTERRUPT) 410 if (iir & I915_ASLE_INTERRUPT)
317 opregion_asle_intr(dev); 411 opregion_asle_intr(dev);
318 412
319 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) 413 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
320 opregion_asle_intr(dev); 414
415 if (dev->pdev->msi_enabled)
416 I915_WRITE(IMR, dev_priv->irq_mask_reg);
417 I915_WRITE(IIR, iir);
418 (void) I915_READ(IIR);
419
420 if (vblank && dev_priv->swaps_pending > 0)
421 drm_locked_tasklet(dev, i915_vblank_tasklet);
321 422
322 return IRQ_HANDLED; 423 return IRQ_HANDLED;
323} 424}
@@ -358,7 +459,7 @@ static void i915_user_irq_get(struct drm_device *dev)
358 spin_unlock(&dev_priv->user_irq_lock); 459 spin_unlock(&dev_priv->user_irq_lock);
359} 460}
360 461
361static void i915_user_irq_put(struct drm_device *dev) 462void i915_user_irq_put(struct drm_device *dev)
362{ 463{
363 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 464 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
364 465
@@ -395,41 +496,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
395 } 496 }
396 497
397 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 498 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
398 return ret;
399}
400
401static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
402 atomic_t *counter)
403{
404 drm_i915_private_t *dev_priv = dev->dev_private;
405 unsigned int cur_vblank;
406 int ret = 0;
407
408 if (!dev_priv) {
409 DRM_ERROR("called with no initialization\n");
410 return -EINVAL;
411 }
412
413 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
414 (((cur_vblank = atomic_read(counter))
415 - *sequence) <= (1<<23)));
416
417 *sequence = cur_vblank;
418 499
419 return ret; 500 return ret;
420} 501}
421 502
422
423int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
424{
425 return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
426}
427
428int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
429{
430 return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
431}
432
433/* Needs the lock as it touches the ring. 503/* Needs the lock as it touches the ring.
434 */ 504 */
435int i915_irq_emit(struct drm_device *dev, void *data, 505int i915_irq_emit(struct drm_device *dev, void *data,
@@ -472,40 +542,88 @@ int i915_irq_wait(struct drm_device *dev, void *data,
472 return i915_wait_irq(dev, irqwait->irq_seq); 542 return i915_wait_irq(dev, irqwait->irq_seq);
473} 543}
474 544
545int i915_enable_vblank(struct drm_device *dev, int plane)
546{
547 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
548 int pipe = i915_get_pipe(dev, plane);
549 u32 pipestat_reg = 0;
550 u32 pipestat;
551
552 switch (pipe) {
553 case 0:
554 pipestat_reg = PIPEASTAT;
555 i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
556 break;
557 case 1:
558 pipestat_reg = PIPEBSTAT;
559 i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
560 break;
561 default:
562 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
563 pipe);
564 break;
565 }
566
567 if (pipestat_reg) {
568 pipestat = I915_READ(pipestat_reg);
569 if (IS_I965G(dev))
570 pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
571 else
572 pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
573 /* Clear any stale interrupt status */
574 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
575 PIPE_VBLANK_INTERRUPT_STATUS);
576 I915_WRITE(pipestat_reg, pipestat);
577 }
578
579 return 0;
580}
581
582void i915_disable_vblank(struct drm_device *dev, int plane)
583{
584 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
585 int pipe = i915_get_pipe(dev, plane);
586 u32 pipestat_reg = 0;
587 u32 pipestat;
588
589 switch (pipe) {
590 case 0:
591 pipestat_reg = PIPEASTAT;
592 i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
593 break;
594 case 1:
595 pipestat_reg = PIPEBSTAT;
596 i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
597 break;
598 default:
599 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
600 pipe);
601 break;
602 }
603
604 if (pipestat_reg) {
605 pipestat = I915_READ(pipestat_reg);
606 pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
607 PIPE_VBLANK_INTERRUPT_ENABLE);
608 /* Clear any stale interrupt status */
609 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
610 PIPE_VBLANK_INTERRUPT_STATUS);
611 I915_WRITE(pipestat_reg, pipestat);
612 }
613}
614
475/* Set the vblank monitor pipe 615/* Set the vblank monitor pipe
476 */ 616 */
477int i915_vblank_pipe_set(struct drm_device *dev, void *data, 617int i915_vblank_pipe_set(struct drm_device *dev, void *data,
478 struct drm_file *file_priv) 618 struct drm_file *file_priv)
479{ 619{
480 drm_i915_private_t *dev_priv = dev->dev_private; 620 drm_i915_private_t *dev_priv = dev->dev_private;
481 drm_i915_vblank_pipe_t *pipe = data;
482 u32 enable_mask = 0, disable_mask = 0;
483 621
484 if (!dev_priv) { 622 if (!dev_priv) {
485 DRM_ERROR("called with no initialization\n"); 623 DRM_ERROR("called with no initialization\n");
486 return -EINVAL; 624 return -EINVAL;
487 } 625 }
488 626
489 if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
490 DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
491 return -EINVAL;
492 }
493
494 if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
495 enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
496 else
497 disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
498
499 if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
500 enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
501 else
502 disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
503
504 i915_enable_irq(dev_priv, enable_mask);
505 i915_disable_irq(dev_priv, disable_mask);
506
507 dev_priv->vblank_pipe = pipe->pipe;
508
509 return 0; 627 return 0;
510} 628}
511 629
@@ -514,19 +632,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
514{ 632{
515 drm_i915_private_t *dev_priv = dev->dev_private; 633 drm_i915_private_t *dev_priv = dev->dev_private;
516 drm_i915_vblank_pipe_t *pipe = data; 634 drm_i915_vblank_pipe_t *pipe = data;
517 u16 flag;
518 635
519 if (!dev_priv) { 636 if (!dev_priv) {
520 DRM_ERROR("called with no initialization\n"); 637 DRM_ERROR("called with no initialization\n");
521 return -EINVAL; 638 return -EINVAL;
522 } 639 }
523 640
524 flag = I915_READ(IMR); 641 pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
525 pipe->pipe = 0;
526 if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
527 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
528 if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
529 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
530 642
531 return 0; 643 return 0;
532} 644}
@@ -540,9 +652,10 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
540 drm_i915_private_t *dev_priv = dev->dev_private; 652 drm_i915_private_t *dev_priv = dev->dev_private;
541 drm_i915_vblank_swap_t *swap = data; 653 drm_i915_vblank_swap_t *swap = data;
542 drm_i915_vbl_swap_t *vbl_swap; 654 drm_i915_vbl_swap_t *vbl_swap;
543 unsigned int pipe, seqtype, curseq; 655 unsigned int pipe, seqtype, curseq, plane;
544 unsigned long irqflags; 656 unsigned long irqflags;
545 struct list_head *list; 657 struct list_head *list;
658 int ret;
546 659
547 if (!dev_priv) { 660 if (!dev_priv) {
548 DRM_ERROR("%s called with no initialization\n", __func__); 661 DRM_ERROR("%s called with no initialization\n", __func__);
@@ -560,7 +673,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
560 return -EINVAL; 673 return -EINVAL;
561 } 674 }
562 675
563 pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; 676 plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
677 pipe = i915_get_pipe(dev, plane);
564 678
565 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); 679 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
566 680
@@ -579,7 +693,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
579 693
580 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 694 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
581 695
582 curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); 696 /*
697 * We take the ref here and put it when the swap actually completes
698 * in the tasklet.
699 */
700 ret = drm_vblank_get(dev, pipe);
701 if (ret)
702 return ret;
703 curseq = drm_vblank_count(dev, pipe);
583 704
584 if (seqtype == _DRM_VBLANK_RELATIVE) 705 if (seqtype == _DRM_VBLANK_RELATIVE)
585 swap->sequence += curseq; 706 swap->sequence += curseq;
@@ -589,6 +710,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
589 swap->sequence = curseq + 1; 710 swap->sequence = curseq + 1;
590 } else { 711 } else {
591 DRM_DEBUG("Missed target sequence\n"); 712 DRM_DEBUG("Missed target sequence\n");
713 drm_vblank_put(dev, pipe);
592 return -EINVAL; 714 return -EINVAL;
593 } 715 }
594 } 716 }
@@ -599,7 +721,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
599 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); 721 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
600 722
601 if (vbl_swap->drw_id == swap->drawable && 723 if (vbl_swap->drw_id == swap->drawable &&
602 vbl_swap->pipe == pipe && 724 vbl_swap->plane == plane &&
603 vbl_swap->sequence == swap->sequence) { 725 vbl_swap->sequence == swap->sequence) {
604 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); 726 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
605 DRM_DEBUG("Already scheduled\n"); 727 DRM_DEBUG("Already scheduled\n");
@@ -611,6 +733,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
611 733
612 if (dev_priv->swaps_pending >= 100) { 734 if (dev_priv->swaps_pending >= 100) {
613 DRM_DEBUG("Too many swaps queued\n"); 735 DRM_DEBUG("Too many swaps queued\n");
736 drm_vblank_put(dev, pipe);
614 return -EBUSY; 737 return -EBUSY;
615 } 738 }
616 739
@@ -618,13 +741,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
618 741
619 if (!vbl_swap) { 742 if (!vbl_swap) {
620 DRM_ERROR("Failed to allocate memory to queue swap\n"); 743 DRM_ERROR("Failed to allocate memory to queue swap\n");
744 drm_vblank_put(dev, pipe);
621 return -ENOMEM; 745 return -ENOMEM;
622 } 746 }
623 747
624 DRM_DEBUG("\n"); 748 DRM_DEBUG("\n");
625 749
626 vbl_swap->drw_id = swap->drawable; 750 vbl_swap->drw_id = swap->drawable;
627 vbl_swap->pipe = pipe; 751 vbl_swap->plane = plane;
628 vbl_swap->sequence = swap->sequence; 752 vbl_swap->sequence = swap->sequence;
629 753
630 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 754 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
@@ -643,28 +767,32 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
643{ 767{
644 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 768 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
645 769
646 I915_WRITE(HWSTAM, 0xfffe); 770 I915_WRITE(HWSTAM, 0xeffe);
647 I915_WRITE(IMR, 0x0); 771 I915_WRITE(IMR, 0xffffffff);
648 I915_WRITE(IER, 0x0); 772 I915_WRITE(IER, 0x0);
649} 773}
650 774
651void i915_driver_irq_postinstall(struct drm_device * dev) 775int i915_driver_irq_postinstall(struct drm_device *dev)
652{ 776{
653 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 777 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
778 int ret, num_pipes = 2;
654 779
655 spin_lock_init(&dev_priv->swaps_lock); 780 spin_lock_init(&dev_priv->swaps_lock);
656 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); 781 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
657 dev_priv->swaps_pending = 0; 782 dev_priv->swaps_pending = 0;
658 783
659 if (!dev_priv->vblank_pipe)
660 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
661
662 /* Set initial unmasked IRQs to just the selected vblank pipes. */ 784 /* Set initial unmasked IRQs to just the selected vblank pipes. */
663 dev_priv->irq_mask_reg = ~0; 785 dev_priv->irq_mask_reg = ~0;
664 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) 786
665 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; 787 ret = drm_vblank_init(dev, num_pipes);
666 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) 788 if (ret)
667 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; 789 return ret;
790
791 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
792 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
793 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
794
795 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
668 796
669 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK; 797 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
670 798
@@ -673,22 +801,29 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
673 (void) I915_READ(IER); 801 (void) I915_READ(IER);
674 802
675 opregion_enable_asle(dev); 803 opregion_enable_asle(dev);
676
677 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 804 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
805
806 return 0;
678} 807}
679 808
680void i915_driver_irq_uninstall(struct drm_device * dev) 809void i915_driver_irq_uninstall(struct drm_device * dev)
681{ 810{
682 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 811 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
683 u16 temp; 812 u32 temp;
684 813
685 if (!dev_priv) 814 if (!dev_priv)
686 return; 815 return;
687 816
688 I915_WRITE(HWSTAM, 0xffff); 817 dev_priv->vblank_pipe = 0;
689 I915_WRITE(IMR, 0xffff); 818
819 I915_WRITE(HWSTAM, 0xffffffff);
820 I915_WRITE(IMR, 0xffffffff);
690 I915_WRITE(IER, 0x0); 821 I915_WRITE(IER, 0x0);
691 822
823 temp = I915_READ(PIPEASTAT);
824 I915_WRITE(PIPEASTAT, temp);
825 temp = I915_READ(PIPEBSTAT);
826 I915_WRITE(PIPEBSTAT, temp);
692 temp = I915_READ(IIR); 827 temp = I915_READ(IIR);
693 I915_WRITE(IIR, temp); 828 I915_WRITE(IIR, temp);
694} 829}
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 5572939fc7d..97ee566ef74 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -45,15 +45,16 @@ static struct pci_device_id pciidlist[] = {
45static struct drm_driver driver = { 45static struct drm_driver driver = {
46 .driver_features = 46 .driver_features =
47 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | 47 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
48 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 48 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
49 DRIVER_IRQ_VBL,
50 .dev_priv_size = sizeof(drm_mga_buf_priv_t), 49 .dev_priv_size = sizeof(drm_mga_buf_priv_t),
51 .load = mga_driver_load, 50 .load = mga_driver_load,
52 .unload = mga_driver_unload, 51 .unload = mga_driver_unload,
53 .lastclose = mga_driver_lastclose, 52 .lastclose = mga_driver_lastclose,
54 .dma_quiescent = mga_driver_dma_quiescent, 53 .dma_quiescent = mga_driver_dma_quiescent,
55 .device_is_agp = mga_driver_device_is_agp, 54 .device_is_agp = mga_driver_device_is_agp,
56 .vblank_wait = mga_driver_vblank_wait, 55 .get_vblank_counter = mga_get_vblank_counter,
56 .enable_vblank = mga_enable_vblank,
57 .disable_vblank = mga_disable_vblank,
57 .irq_preinstall = mga_driver_irq_preinstall, 58 .irq_preinstall = mga_driver_irq_preinstall,
58 .irq_postinstall = mga_driver_irq_postinstall, 59 .irq_postinstall = mga_driver_irq_postinstall,
59 .irq_uninstall = mga_driver_irq_uninstall, 60 .irq_uninstall = mga_driver_irq_uninstall,
@@ -64,20 +65,20 @@ static struct drm_driver driver = {
64 .ioctls = mga_ioctls, 65 .ioctls = mga_ioctls,
65 .dma_ioctl = mga_dma_buffers, 66 .dma_ioctl = mga_dma_buffers,
66 .fops = { 67 .fops = {
67 .owner = THIS_MODULE, 68 .owner = THIS_MODULE,
68 .open = drm_open, 69 .open = drm_open,
69 .release = drm_release, 70 .release = drm_release,
70 .ioctl = drm_ioctl, 71 .ioctl = drm_ioctl,
71 .mmap = drm_mmap, 72 .mmap = drm_mmap,
72 .poll = drm_poll, 73 .poll = drm_poll,
73 .fasync = drm_fasync, 74 .fasync = drm_fasync,
74#ifdef CONFIG_COMPAT 75#ifdef CONFIG_COMPAT
75 .compat_ioctl = mga_compat_ioctl, 76 .compat_ioctl = mga_compat_ioctl,
76#endif 77#endif
77 }, 78 },
78 .pci_driver = { 79 .pci_driver = {
79 .name = DRIVER_NAME, 80 .name = DRIVER_NAME,
80 .id_table = pciidlist, 81 .id_table = pciidlist,
81 }, 82 },
82 83
83 .name = DRIVER_NAME, 84 .name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index f6ebd24bd58..88257c276eb 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -120,6 +120,7 @@ typedef struct drm_mga_private {
120 u32 clear_cmd; 120 u32 clear_cmd;
121 u32 maccess; 121 u32 maccess;
122 122
123 atomic_t vbl_received; /**< Number of vblanks received. */
123 wait_queue_head_t fence_queue; 124 wait_queue_head_t fence_queue;
124 atomic_t last_fence_retired; 125 atomic_t last_fence_retired;
125 u32 next_fence_to_post; 126 u32 next_fence_to_post;
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
181extern int mga_warp_init(drm_mga_private_t * dev_priv); 182extern int mga_warp_init(drm_mga_private_t * dev_priv);
182 183
183 /* mga_irq.c */ 184 /* mga_irq.c */
185extern int mga_enable_vblank(struct drm_device *dev, int crtc);
186extern void mga_disable_vblank(struct drm_device *dev, int crtc);
187extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
184extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); 188extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
185extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); 189extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
186extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); 190extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
187extern void mga_driver_irq_preinstall(struct drm_device * dev); 191extern void mga_driver_irq_preinstall(struct drm_device * dev);
188extern void mga_driver_irq_postinstall(struct drm_device * dev); 192extern int mga_driver_irq_postinstall(struct drm_device *dev);
189extern void mga_driver_irq_uninstall(struct drm_device * dev); 193extern void mga_driver_irq_uninstall(struct drm_device * dev);
190extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, 194extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
191 unsigned long arg); 195 unsigned long arg);
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c
index 9302cb8f0f8..bab42f41188 100644
--- a/drivers/gpu/drm/mga/mga_irq.c
+++ b/drivers/gpu/drm/mga/mga_irq.c
@@ -1,5 +1,6 @@
1/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- 1/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
2 * 2 */
3/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 * 5 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 6 * The Weather Channel (TM) funded Tungsten Graphics to develop the
@@ -35,6 +36,18 @@
35#include "mga_drm.h" 36#include "mga_drm.h"
36#include "mga_drv.h" 37#include "mga_drv.h"
37 38
39u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
40{
41 const drm_mga_private_t *const dev_priv =
42 (drm_mga_private_t *) dev->dev_private;
43
44 if (crtc != 0)
45 return 0;
46
47 return atomic_read(&dev_priv->vbl_received);
48}
49
50
38irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) 51irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
39{ 52{
40 struct drm_device *dev = (struct drm_device *) arg; 53 struct drm_device *dev = (struct drm_device *) arg;
@@ -47,9 +60,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
47 /* VBLANK interrupt */ 60 /* VBLANK interrupt */
48 if (status & MGA_VLINEPEN) { 61 if (status & MGA_VLINEPEN) {
49 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); 62 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
50 atomic_inc(&dev->vbl_received); 63 atomic_inc(&dev_priv->vbl_received);
51 DRM_WAKEUP(&dev->vbl_queue); 64 drm_handle_vblank(dev, 0);
52 drm_vbl_send_signals(dev);
53 handled = 1; 65 handled = 1;
54 } 66 }
55 67
@@ -58,6 +70,7 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
58 const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); 70 const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
59 const u32 prim_end = MGA_READ(MGA_PRIMEND); 71 const u32 prim_end = MGA_READ(MGA_PRIMEND);
60 72
73
61 MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); 74 MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
62 75
63 /* In addition to clearing the interrupt-pending bit, we 76 /* In addition to clearing the interrupt-pending bit, we
@@ -72,28 +85,39 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
72 handled = 1; 85 handled = 1;
73 } 86 }
74 87
75 if (handled) { 88 if (handled)
76 return IRQ_HANDLED; 89 return IRQ_HANDLED;
77 }
78 return IRQ_NONE; 90 return IRQ_NONE;
79} 91}
80 92
81int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) 93int mga_enable_vblank(struct drm_device *dev, int crtc)
82{ 94{
83 unsigned int cur_vblank; 95 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
84 int ret = 0;
85 96
86 /* Assume that the user has missed the current sequence number 97 if (crtc != 0) {
87 * by about a day rather than she wants to wait for years 98 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
88 * using vertical blanks... 99 crtc);
89 */ 100 return 0;
90 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 101 }
91 (((cur_vblank = atomic_read(&dev->vbl_received))
92 - *sequence) <= (1 << 23)));
93 102
94 *sequence = cur_vblank; 103 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
104 return 0;
105}
95 106
96 return ret; 107
108void mga_disable_vblank(struct drm_device *dev, int crtc)
109{
110 if (crtc != 0) {
111 DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
112 crtc);
113 }
114
115 /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
116 * a nice hardware counter that tracks the number of refreshes when
117 * the interrupt is disabled, and the kernel doesn't know the refresh
118 * rate to calculate an estimate.
119 */
120 /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
97} 121}
98 122
99int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) 123int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
@@ -125,14 +149,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
125 MGA_WRITE(MGA_ICLEAR, ~0); 149 MGA_WRITE(MGA_ICLEAR, ~0);
126} 150}
127 151
128void mga_driver_irq_postinstall(struct drm_device * dev) 152int mga_driver_irq_postinstall(struct drm_device *dev)
129{ 153{
130 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; 154 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
155 int ret;
156
157 ret = drm_vblank_init(dev, 1);
158 if (ret)
159 return ret;
131 160
132 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); 161 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
133 162
134 /* Turn on vertical blank interrupt and soft trap interrupt. */ 163 /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
135 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); 164 * in mga_enable_vblank.
165 */
166 MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
167 return 0;
136} 168}
137 169
138void mga_driver_irq_uninstall(struct drm_device * dev) 170void mga_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index 6108e7587e1..3265d53ba91 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -43,12 +43,13 @@ static struct pci_device_id pciidlist[] = {
43static struct drm_driver driver = { 43static struct drm_driver driver = {
44 .driver_features = 44 .driver_features =
45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | 45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
47 DRIVER_IRQ_VBL,
48 .dev_priv_size = sizeof(drm_r128_buf_priv_t), 47 .dev_priv_size = sizeof(drm_r128_buf_priv_t),
49 .preclose = r128_driver_preclose, 48 .preclose = r128_driver_preclose,
50 .lastclose = r128_driver_lastclose, 49 .lastclose = r128_driver_lastclose,
51 .vblank_wait = r128_driver_vblank_wait, 50 .get_vblank_counter = r128_get_vblank_counter,
51 .enable_vblank = r128_enable_vblank,
52 .disable_vblank = r128_disable_vblank,
52 .irq_preinstall = r128_driver_irq_preinstall, 53 .irq_preinstall = r128_driver_irq_preinstall,
53 .irq_postinstall = r128_driver_irq_postinstall, 54 .irq_postinstall = r128_driver_irq_postinstall,
54 .irq_uninstall = r128_driver_irq_uninstall, 55 .irq_uninstall = r128_driver_irq_uninstall,
@@ -59,21 +60,20 @@ static struct drm_driver driver = {
59 .ioctls = r128_ioctls, 60 .ioctls = r128_ioctls,
60 .dma_ioctl = r128_cce_buffers, 61 .dma_ioctl = r128_cce_buffers,
61 .fops = { 62 .fops = {
62 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
63 .open = drm_open, 64 .open = drm_open,
64 .release = drm_release, 65 .release = drm_release,
65 .ioctl = drm_ioctl, 66 .ioctl = drm_ioctl,
66 .mmap = drm_mmap, 67 .mmap = drm_mmap,
67 .poll = drm_poll, 68 .poll = drm_poll,
68 .fasync = drm_fasync, 69 .fasync = drm_fasync,
69#ifdef CONFIG_COMPAT 70#ifdef CONFIG_COMPAT
70 .compat_ioctl = r128_compat_ioctl, 71 .compat_ioctl = r128_compat_ioctl,
71#endif 72#endif
72 }, 73 },
73
74 .pci_driver = { 74 .pci_driver = {
75 .name = DRIVER_NAME, 75 .name = DRIVER_NAME,
76 .id_table = pciidlist, 76 .id_table = pciidlist,
77 }, 77 },
78 78
79 .name = DRIVER_NAME, 79 .name = DRIVER_NAME,
@@ -87,6 +87,7 @@ static struct drm_driver driver = {
87static int __init r128_init(void) 87static int __init r128_init(void)
88{ 88{
89 driver.num_ioctls = r128_max_ioctl; 89 driver.num_ioctls = r128_max_ioctl;
90
90 return drm_init(&driver); 91 return drm_init(&driver);
91} 92}
92 93
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h
index 011105e51ac..5898b274279 100644
--- a/drivers/gpu/drm/r128/r128_drv.h
+++ b/drivers/gpu/drm/r128/r128_drv.h
@@ -29,7 +29,7 @@
29 * Rickard E. (Rik) Faith <faith@valinux.com> 29 * Rickard E. (Rik) Faith <faith@valinux.com>
30 * Kevin E. Martin <martin@valinux.com> 30 * Kevin E. Martin <martin@valinux.com>
31 * Gareth Hughes <gareth@valinux.com> 31 * Gareth Hughes <gareth@valinux.com>
32 * Michel Dänzer <daenzerm@student.ethz.ch> 32 * Michel D�zer <daenzerm@student.ethz.ch>
33 */ 33 */
34 34
35#ifndef __R128_DRV_H__ 35#ifndef __R128_DRV_H__
@@ -97,6 +97,8 @@ typedef struct drm_r128_private {
97 u32 crtc_offset; 97 u32 crtc_offset;
98 u32 crtc_offset_cntl; 98 u32 crtc_offset_cntl;
99 99
100 atomic_t vbl_received;
101
100 u32 color_fmt; 102 u32 color_fmt;
101 unsigned int front_offset; 103 unsigned int front_offset;
102 unsigned int front_pitch; 104 unsigned int front_pitch;
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
149extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); 151extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
150extern int r128_do_cleanup_cce(struct drm_device * dev); 152extern int r128_do_cleanup_cce(struct drm_device * dev);
151 153
152extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); 154extern int r128_enable_vblank(struct drm_device *dev, int crtc);
153 155extern void r128_disable_vblank(struct drm_device *dev, int crtc);
156extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
154extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); 157extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
155extern void r128_driver_irq_preinstall(struct drm_device * dev); 158extern void r128_driver_irq_preinstall(struct drm_device * dev);
156extern void r128_driver_irq_postinstall(struct drm_device * dev); 159extern int r128_driver_irq_postinstall(struct drm_device *dev);
157extern void r128_driver_irq_uninstall(struct drm_device * dev); 160extern void r128_driver_irq_uninstall(struct drm_device * dev);
158extern void r128_driver_lastclose(struct drm_device * dev); 161extern void r128_driver_lastclose(struct drm_device * dev);
159extern void r128_driver_preclose(struct drm_device * dev, 162extern void r128_driver_preclose(struct drm_device * dev,
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c
index c76fdca7662..d7349012a68 100644
--- a/drivers/gpu/drm/r128/r128_irq.c
+++ b/drivers/gpu/drm/r128/r128_irq.c
@@ -35,6 +35,16 @@
35#include "r128_drm.h" 35#include "r128_drm.h"
36#include "r128_drv.h" 36#include "r128_drv.h"
37 37
38u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
39{
40 const drm_r128_private_t *dev_priv = dev->dev_private;
41
42 if (crtc != 0)
43 return 0;
44
45 return atomic_read(&dev_priv->vbl_received);
46}
47
38irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) 48irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
39{ 49{
40 struct drm_device *dev = (struct drm_device *) arg; 50 struct drm_device *dev = (struct drm_device *) arg;
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
46 /* VBLANK interrupt */ 56 /* VBLANK interrupt */
47 if (status & R128_CRTC_VBLANK_INT) { 57 if (status & R128_CRTC_VBLANK_INT) {
48 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); 58 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
49 atomic_inc(&dev->vbl_received); 59 atomic_inc(&dev_priv->vbl_received);
50 DRM_WAKEUP(&dev->vbl_queue); 60 drm_handle_vblank(dev, 0);
51 drm_vbl_send_signals(dev);
52 return IRQ_HANDLED; 61 return IRQ_HANDLED;
53 } 62 }
54 return IRQ_NONE; 63 return IRQ_NONE;
55} 64}
56 65
57int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) 66int r128_enable_vblank(struct drm_device *dev, int crtc)
58{ 67{
59 unsigned int cur_vblank; 68 drm_r128_private_t *dev_priv = dev->dev_private;
60 int ret = 0;
61 69
62 /* Assume that the user has missed the current sequence number 70 if (crtc != 0) {
63 * by about a day rather than she wants to wait for years 71 DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
64 * using vertical blanks... 72 return -EINVAL;
65 */ 73 }
66 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
67 (((cur_vblank = atomic_read(&dev->vbl_received))
68 - *sequence) <= (1 << 23)));
69 74
70 *sequence = cur_vblank; 75 R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
76 return 0;
77}
78
79void r128_disable_vblank(struct drm_device *dev, int crtc)
80{
81 if (crtc != 0)
82 DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
71 83
72 return ret; 84 /*
85 * FIXME: implement proper interrupt disable by using the vblank
86 * counter register (if available)
87 *
88 * R128_WRITE(R128_GEN_INT_CNTL,
89 * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
90 */
73} 91}
74 92
75void r128_driver_irq_preinstall(struct drm_device * dev) 93void r128_driver_irq_preinstall(struct drm_device * dev)
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
82 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); 100 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
83} 101}
84 102
85void r128_driver_irq_postinstall(struct drm_device * dev) 103int r128_driver_irq_postinstall(struct drm_device *dev)
86{ 104{
87 drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; 105 return drm_vblank_init(dev, 1);
88
89 /* Turn on VBL interrupt */
90 R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
91} 106}
92 107
93void r128_driver_irq_uninstall(struct drm_device * dev) 108void r128_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index e1678cae9cc..6157cd4bb43 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -1287,7 +1287,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
1287 radeon_cp_init_ring_buffer(dev, dev_priv); 1287 radeon_cp_init_ring_buffer(dev, dev_priv);
1288 1288
1289 radeon_do_engine_reset(dev); 1289 radeon_do_engine_reset(dev);
1290 radeon_enable_interrupt(dev); 1290 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
1291 1291
1292 DRM_DEBUG("radeon_do_resume_cp() complete\n"); 1292 DRM_DEBUG("radeon_do_resume_cp() complete\n");
1293 1293
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 637bd7faf13..71af746a4e4 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -52,6 +52,28 @@ static int dri_library_name(struct drm_device *dev, char *buf)
52 "r300")); 52 "r300"));
53} 53}
54 54
55static int radeon_suspend(struct drm_device *dev, pm_message_t state)
56{
57 drm_radeon_private_t *dev_priv = dev->dev_private;
58
59 /* Disable *all* interrupts */
60 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
61 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
62 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
63 return 0;
64}
65
66static int radeon_resume(struct drm_device *dev)
67{
68 drm_radeon_private_t *dev_priv = dev->dev_private;
69
70 /* Restore interrupt registers */
71 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
72 RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
73 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
74 return 0;
75}
76
55static struct pci_device_id pciidlist[] = { 77static struct pci_device_id pciidlist[] = {
56 radeon_PCI_IDS 78 radeon_PCI_IDS
57}; 79};
@@ -59,8 +81,7 @@ static struct pci_device_id pciidlist[] = {
59static struct drm_driver driver = { 81static struct drm_driver driver = {
60 .driver_features = 82 .driver_features =
61 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | 83 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
62 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | 84 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
63 DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
64 .dev_priv_size = sizeof(drm_radeon_buf_priv_t), 85 .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
65 .load = radeon_driver_load, 86 .load = radeon_driver_load,
66 .firstopen = radeon_driver_firstopen, 87 .firstopen = radeon_driver_firstopen,
@@ -69,8 +90,11 @@ static struct drm_driver driver = {
69 .postclose = radeon_driver_postclose, 90 .postclose = radeon_driver_postclose,
70 .lastclose = radeon_driver_lastclose, 91 .lastclose = radeon_driver_lastclose,
71 .unload = radeon_driver_unload, 92 .unload = radeon_driver_unload,
72 .vblank_wait = radeon_driver_vblank_wait, 93 .suspend = radeon_suspend,
73 .vblank_wait2 = radeon_driver_vblank_wait2, 94 .resume = radeon_resume,
95 .get_vblank_counter = radeon_get_vblank_counter,
96 .enable_vblank = radeon_enable_vblank,
97 .disable_vblank = radeon_disable_vblank,
74 .dri_library_name = dri_library_name, 98 .dri_library_name = dri_library_name,
75 .irq_preinstall = radeon_driver_irq_preinstall, 99 .irq_preinstall = radeon_driver_irq_preinstall,
76 .irq_postinstall = radeon_driver_irq_postinstall, 100 .irq_postinstall = radeon_driver_irq_postinstall,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 09938169317..d7e9c6cc6a1 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -378,17 +378,17 @@ extern void radeon_mem_release(struct drm_file *file_priv,
378 struct mem_block *heap); 378 struct mem_block *heap);
379 379
380 /* radeon_irq.c */ 380 /* radeon_irq.c */
381extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state);
381extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); 382extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
382extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); 383extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
383 384
384extern void radeon_do_release(struct drm_device * dev); 385extern void radeon_do_release(struct drm_device * dev);
385extern int radeon_driver_vblank_wait(struct drm_device * dev, 386extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
386 unsigned int *sequence); 387extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
387extern int radeon_driver_vblank_wait2(struct drm_device * dev, 388extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
388 unsigned int *sequence);
389extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); 389extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
390extern void radeon_driver_irq_preinstall(struct drm_device * dev); 390extern void radeon_driver_irq_preinstall(struct drm_device * dev);
391extern void radeon_driver_irq_postinstall(struct drm_device * dev); 391extern int radeon_driver_irq_postinstall(struct drm_device *dev);
392extern void radeon_driver_irq_uninstall(struct drm_device * dev); 392extern void radeon_driver_irq_uninstall(struct drm_device * dev);
393extern void radeon_enable_interrupt(struct drm_device *dev); 393extern void radeon_enable_interrupt(struct drm_device *dev);
394extern int radeon_vblank_crtc_get(struct drm_device *dev); 394extern int radeon_vblank_crtc_get(struct drm_device *dev);
@@ -397,19 +397,22 @@ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
397extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); 397extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
398extern int radeon_driver_unload(struct drm_device *dev); 398extern int radeon_driver_unload(struct drm_device *dev);
399extern int radeon_driver_firstopen(struct drm_device *dev); 399extern int radeon_driver_firstopen(struct drm_device *dev);
400extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv); 400extern void radeon_driver_preclose(struct drm_device *dev,
401extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp); 401 struct drm_file *file_priv);
402extern void radeon_driver_postclose(struct drm_device *dev,
403 struct drm_file *file_priv);
402extern void radeon_driver_lastclose(struct drm_device * dev); 404extern void radeon_driver_lastclose(struct drm_device * dev);
403extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv); 405extern int radeon_driver_open(struct drm_device *dev,
406 struct drm_file *file_priv);
404extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, 407extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
405 unsigned long arg); 408 unsigned long arg);
406 409
407/* r300_cmdbuf.c */ 410/* r300_cmdbuf.c */
408extern void r300_init_reg_flags(struct drm_device *dev); 411extern void r300_init_reg_flags(struct drm_device *dev);
409 412
410extern int r300_do_cp_cmdbuf(struct drm_device * dev, 413extern int r300_do_cp_cmdbuf(struct drm_device *dev,
411 struct drm_file *file_priv, 414 struct drm_file *file_priv,
412 drm_radeon_kcmd_buffer_t * cmdbuf); 415 drm_radeon_kcmd_buffer_t *cmdbuf);
413 416
414/* Flags for stats.boxes 417/* Flags for stats.boxes
415 */ 418 */
@@ -623,6 +626,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
623# define RADEON_SW_INT_TEST (1 << 25) 626# define RADEON_SW_INT_TEST (1 << 25)
624# define RADEON_SW_INT_TEST_ACK (1 << 25) 627# define RADEON_SW_INT_TEST_ACK (1 << 25)
625# define RADEON_SW_INT_FIRE (1 << 26) 628# define RADEON_SW_INT_FIRE (1 << 26)
629# define R500_DISPLAY_INT_STATUS (1 << 0)
626 630
627#define RADEON_HOST_PATH_CNTL 0x0130 631#define RADEON_HOST_PATH_CNTL 0x0130
628# define RADEON_HDP_SOFT_RESET (1 << 26) 632# define RADEON_HDP_SOFT_RESET (1 << 26)
@@ -1116,6 +1120,9 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
1116 1120
1117#define R200_VAP_PVS_CNTL_1 0x22D0 1121#define R200_VAP_PVS_CNTL_1 0x22D0
1118 1122
1123#define RADEON_CRTC_CRNT_FRAME 0x0214
1124#define RADEON_CRTC2_CRNT_FRAME 0x0314
1125
1119#define R500_D1CRTC_STATUS 0x609c 1126#define R500_D1CRTC_STATUS 0x609c
1120#define R500_D2CRTC_STATUS 0x689c 1127#define R500_D2CRTC_STATUS 0x689c
1121#define R500_CRTC_V_BLANK (1<<0) 1128#define R500_CRTC_V_BLANK (1<<0)
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index ee40d197deb..5079f7054a2 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -27,7 +27,7 @@
27 * 27 *
28 * Authors: 28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com> 29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Michel Dänzer <michel@daenzer.net> 30 * Michel D�zer <michel@daenzer.net>
31 */ 31 */
32 32
33#include "drmP.h" 33#include "drmP.h"
@@ -35,12 +35,128 @@
35#include "radeon_drm.h" 35#include "radeon_drm.h"
36#include "radeon_drv.h" 36#include "radeon_drv.h"
37 37
38static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, 38void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
39 u32 mask)
40{ 39{
41 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; 40 drm_radeon_private_t *dev_priv = dev->dev_private;
41
42 if (state)
43 dev_priv->irq_enable_reg |= mask;
44 else
45 dev_priv->irq_enable_reg &= ~mask;
46
47 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
48}
49
50static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state)
51{
52 drm_radeon_private_t *dev_priv = dev->dev_private;
53
54 if (state)
55 dev_priv->r500_disp_irq_reg |= mask;
56 else
57 dev_priv->r500_disp_irq_reg &= ~mask;
58
59 RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
60}
61
62int radeon_enable_vblank(struct drm_device *dev, int crtc)
63{
64 drm_radeon_private_t *dev_priv = dev->dev_private;
65
66 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
67 switch (crtc) {
68 case 0:
69 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
70 break;
71 case 1:
72 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1);
73 break;
74 default:
75 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
76 crtc);
77 return EINVAL;
78 }
79 } else {
80 switch (crtc) {
81 case 0:
82 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
83 break;
84 case 1:
85 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
86 break;
87 default:
88 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
89 crtc);
90 return EINVAL;
91 }
92 }
93
94 return 0;
95}
96
97void radeon_disable_vblank(struct drm_device *dev, int crtc)
98{
99 drm_radeon_private_t *dev_priv = dev->dev_private;
100
101 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
102 switch (crtc) {
103 case 0:
104 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
105 break;
106 case 1:
107 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0);
108 break;
109 default:
110 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
111 crtc);
112 break;
113 }
114 } else {
115 switch (crtc) {
116 case 0:
117 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
118 break;
119 case 1:
120 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
121 break;
122 default:
123 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
124 crtc);
125 break;
126 }
127 }
128}
129
130static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int)
131{
132 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS);
133 u32 irq_mask = RADEON_SW_INT_TEST;
134
135 *r500_disp_int = 0;
136 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
137 /* vbl interrupts in a different place */
138
139 if (irqs & R500_DISPLAY_INT_STATUS) {
140 /* if a display interrupt */
141 u32 disp_irq;
142
143 disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS);
144
145 *r500_disp_int = disp_irq;
146 if (disp_irq & R500_D1_VBLANK_INTERRUPT)
147 RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK);
148 if (disp_irq & R500_D2_VBLANK_INTERRUPT)
149 RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK);
150 }
151 irq_mask |= R500_DISPLAY_INT_STATUS;
152 } else
153 irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT;
154
155 irqs &= irq_mask;
156
42 if (irqs) 157 if (irqs)
43 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); 158 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
159
44 return irqs; 160 return irqs;
45} 161}
46 162
@@ -68,44 +184,33 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
68 drm_radeon_private_t *dev_priv = 184 drm_radeon_private_t *dev_priv =
69 (drm_radeon_private_t *) dev->dev_private; 185 (drm_radeon_private_t *) dev->dev_private;
70 u32 stat; 186 u32 stat;
187 u32 r500_disp_int;
71 188
72 /* Only consider the bits we're interested in - others could be used 189 /* Only consider the bits we're interested in - others could be used
73 * outside the DRM 190 * outside the DRM
74 */ 191 */
75 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 192 stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
76 RADEON_CRTC_VBLANK_STAT |
77 RADEON_CRTC2_VBLANK_STAT));
78 if (!stat) 193 if (!stat)
79 return IRQ_NONE; 194 return IRQ_NONE;
80 195
81 stat &= dev_priv->irq_enable_reg; 196 stat &= dev_priv->irq_enable_reg;
82 197
83 /* SW interrupt */ 198 /* SW interrupt */
84 if (stat & RADEON_SW_INT_TEST) { 199 if (stat & RADEON_SW_INT_TEST)
85 DRM_WAKEUP(&dev_priv->swi_queue); 200 DRM_WAKEUP(&dev_priv->swi_queue);
86 }
87 201
88 /* VBLANK interrupt */ 202 /* VBLANK interrupt */
89 if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { 203 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
90 int vblank_crtc = dev_priv->vblank_crtc; 204 if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
91 205 drm_handle_vblank(dev, 0);
92 if ((vblank_crtc & 206 if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
93 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == 207 drm_handle_vblank(dev, 1);
94 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { 208 } else {
95 if (stat & RADEON_CRTC_VBLANK_STAT) 209 if (stat & RADEON_CRTC_VBLANK_STAT)
96 atomic_inc(&dev->vbl_received); 210 drm_handle_vblank(dev, 0);
97 if (stat & RADEON_CRTC2_VBLANK_STAT) 211 if (stat & RADEON_CRTC2_VBLANK_STAT)
98 atomic_inc(&dev->vbl_received2); 212 drm_handle_vblank(dev, 1);
99 } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
100 (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
101 ((stat & RADEON_CRTC2_VBLANK_STAT) &&
102 (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
103 atomic_inc(&dev->vbl_received);
104
105 DRM_WAKEUP(&dev->vbl_queue);
106 drm_vbl_send_signals(dev);
107 } 213 }
108
109 return IRQ_HANDLED; 214 return IRQ_HANDLED;
110} 215}
111 216
@@ -144,54 +249,31 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
144 return ret; 249 return ret;
145} 250}
146 251
147static int radeon_driver_vblank_do_wait(struct drm_device * dev, 252u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
148 unsigned int *sequence, int crtc)
149{ 253{
150 drm_radeon_private_t *dev_priv = 254 drm_radeon_private_t *dev_priv = dev->dev_private;
151 (drm_radeon_private_t *) dev->dev_private; 255
152 unsigned int cur_vblank;
153 int ret = 0;
154 int ack = 0;
155 atomic_t *counter;
156 if (!dev_priv) { 256 if (!dev_priv) {
157 DRM_ERROR("called with no initialization\n"); 257 DRM_ERROR("called with no initialization\n");
158 return -EINVAL; 258 return -EINVAL;
159 } 259 }
160 260
161 if (crtc == DRM_RADEON_VBLANK_CRTC1) { 261 if (crtc < 0 || crtc > 1) {
162 counter = &dev->vbl_received; 262 DRM_ERROR("Invalid crtc %d\n", crtc);
163 ack |= RADEON_CRTC_VBLANK_STAT;
164 } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
165 counter = &dev->vbl_received2;
166 ack |= RADEON_CRTC2_VBLANK_STAT;
167 } else
168 return -EINVAL; 263 return -EINVAL;
264 }
169 265
170 radeon_acknowledge_irqs(dev_priv, ack); 266 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
171 267 if (crtc == 0)
172 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 268 return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
173 269 else
174 /* Assume that the user has missed the current sequence number 270 return RADEON_READ(R500_D2CRTC_FRAME_COUNT);
175 * by about a day rather than she wants to wait for years 271 } else {
176 * using vertical blanks... 272 if (crtc == 0)
177 */ 273 return RADEON_READ(RADEON_CRTC_CRNT_FRAME);
178 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 274 else
179 (((cur_vblank = atomic_read(counter)) 275 return RADEON_READ(RADEON_CRTC2_CRNT_FRAME);
180 - *sequence) <= (1 << 23))); 276 }
181
182 *sequence = cur_vblank;
183
184 return ret;
185}
186
187int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
188{
189 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
190}
191
192int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
193{
194 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
195} 277}
196 278
197/* Needs the lock as it touches the ring. 279/* Needs the lock as it touches the ring.
@@ -234,46 +316,41 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
234 return radeon_wait_irq(dev, irqwait->irq_seq); 316 return radeon_wait_irq(dev, irqwait->irq_seq);
235} 317}
236 318
237void radeon_enable_interrupt(struct drm_device *dev)
238{
239 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
240
241 dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
242 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
243 dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
244
245 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
246 dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
247
248 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
249 dev_priv->irq_enabled = 1;
250}
251
252/* drm_dma.h hooks 319/* drm_dma.h hooks
253*/ 320*/
254void radeon_driver_irq_preinstall(struct drm_device * dev) 321void radeon_driver_irq_preinstall(struct drm_device * dev)
255{ 322{
256 drm_radeon_private_t *dev_priv = 323 drm_radeon_private_t *dev_priv =
257 (drm_radeon_private_t *) dev->dev_private; 324 (drm_radeon_private_t *) dev->dev_private;
325 u32 dummy;
258 326
259 /* Disable *all* interrupts */ 327 /* Disable *all* interrupts */
328 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
329 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
260 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 330 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
261 331
262 /* Clear bits if they're already high */ 332 /* Clear bits if they're already high */
263 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 333 radeon_acknowledge_irqs(dev_priv, &dummy);
264 RADEON_CRTC_VBLANK_STAT |
265 RADEON_CRTC2_VBLANK_STAT));
266} 334}
267 335
268void radeon_driver_irq_postinstall(struct drm_device * dev) 336int radeon_driver_irq_postinstall(struct drm_device *dev)
269{ 337{
270 drm_radeon_private_t *dev_priv = 338 drm_radeon_private_t *dev_priv =
271 (drm_radeon_private_t *) dev->dev_private; 339 (drm_radeon_private_t *) dev->dev_private;
340 int ret;
272 341
273 atomic_set(&dev_priv->swi_emitted, 0); 342 atomic_set(&dev_priv->swi_emitted, 0);
274 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 343 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
275 344
276 radeon_enable_interrupt(dev); 345 ret = drm_vblank_init(dev, 2);
346 if (ret)
347 return ret;
348
349 dev->max_vblank_count = 0x001fffff;
350
351 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
352
353 return 0;
277} 354}
278 355
279void radeon_driver_irq_uninstall(struct drm_device * dev) 356void radeon_driver_irq_uninstall(struct drm_device * dev)
@@ -285,6 +362,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
285 362
286 dev_priv->irq_enabled = 0; 363 dev_priv->irq_enabled = 0;
287 364
365 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
366 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
288 /* Disable *all* interrupts */ 367 /* Disable *all* interrupts */
289 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 368 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
290} 369}
@@ -293,18 +372,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
293int radeon_vblank_crtc_get(struct drm_device *dev) 372int radeon_vblank_crtc_get(struct drm_device *dev)
294{ 373{
295 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 374 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
296 u32 flag;
297 u32 value;
298
299 flag = RADEON_READ(RADEON_GEN_INT_CNTL);
300 value = 0;
301
302 if (flag & RADEON_CRTC_VBLANK_MASK)
303 value |= DRM_RADEON_VBLANK_CRTC1;
304 375
305 if (flag & RADEON_CRTC2_VBLANK_MASK) 376 return dev_priv->vblank_crtc;
306 value |= DRM_RADEON_VBLANK_CRTC2;
307 return value;
308} 377}
309 378
310int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) 379int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
@@ -315,6 +384,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
315 return -EINVAL; 384 return -EINVAL;
316 } 385 }
317 dev_priv->vblank_crtc = (unsigned int)value; 386 dev_priv->vblank_crtc = (unsigned int)value;
318 radeon_enable_interrupt(dev);
319 return 0; 387 return 0;
320} 388}
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 80c01cdfa37..0993b441fc4 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -40,11 +40,13 @@ static struct pci_device_id pciidlist[] = {
40static struct drm_driver driver = { 40static struct drm_driver driver = {
41 .driver_features = 41 .driver_features =
42 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | 42 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
43 DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 43 DRIVER_IRQ_SHARED,
44 .load = via_driver_load, 44 .load = via_driver_load,
45 .unload = via_driver_unload, 45 .unload = via_driver_unload,
46 .context_dtor = via_final_context, 46 .context_dtor = via_final_context,
47 .vblank_wait = via_driver_vblank_wait, 47 .get_vblank_counter = via_get_vblank_counter,
48 .enable_vblank = via_enable_vblank,
49 .disable_vblank = via_disable_vblank,
48 .irq_preinstall = via_driver_irq_preinstall, 50 .irq_preinstall = via_driver_irq_preinstall,
49 .irq_postinstall = via_driver_irq_postinstall, 51 .irq_postinstall = via_driver_irq_postinstall,
50 .irq_uninstall = via_driver_irq_uninstall, 52 .irq_uninstall = via_driver_irq_uninstall,
@@ -59,17 +61,17 @@ static struct drm_driver driver = {
59 .get_reg_ofs = drm_core_get_reg_ofs, 61 .get_reg_ofs = drm_core_get_reg_ofs,
60 .ioctls = via_ioctls, 62 .ioctls = via_ioctls,
61 .fops = { 63 .fops = {
62 .owner = THIS_MODULE, 64 .owner = THIS_MODULE,
63 .open = drm_open, 65 .open = drm_open,
64 .release = drm_release, 66 .release = drm_release,
65 .ioctl = drm_ioctl, 67 .ioctl = drm_ioctl,
66 .mmap = drm_mmap, 68 .mmap = drm_mmap,
67 .poll = drm_poll, 69 .poll = drm_poll,
68 .fasync = drm_fasync, 70 .fasync = drm_fasync,
69 }, 71 },
70 .pci_driver = { 72 .pci_driver = {
71 .name = DRIVER_NAME, 73 .name = DRIVER_NAME,
72 .id_table = pciidlist, 74 .id_table = pciidlist,
73 }, 75 },
74 76
75 .name = DRIVER_NAME, 77 .name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 2daae81874c..cafcb844a22 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -75,6 +75,7 @@ typedef struct drm_via_private {
75 struct timeval last_vblank; 75 struct timeval last_vblank;
76 int last_vblank_valid; 76 int last_vblank_valid;
77 unsigned usec_per_vblank; 77 unsigned usec_per_vblank;
78 atomic_t vbl_received;
78 drm_via_state_t hc_state; 79 drm_via_state_t hc_state;
79 char pci_buf[VIA_PCI_BUF_SIZE]; 80 char pci_buf[VIA_PCI_BUF_SIZE];
80 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; 81 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@ -130,21 +131,24 @@ extern int via_init_context(struct drm_device * dev, int context);
130extern int via_final_context(struct drm_device * dev, int context); 131extern int via_final_context(struct drm_device * dev, int context);
131 132
132extern int via_do_cleanup_map(struct drm_device * dev); 133extern int via_do_cleanup_map(struct drm_device * dev);
133extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); 134extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
135extern int via_enable_vblank(struct drm_device *dev, int crtc);
136extern void via_disable_vblank(struct drm_device *dev, int crtc);
134 137
135extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); 138extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
136extern void via_driver_irq_preinstall(struct drm_device * dev); 139extern void via_driver_irq_preinstall(struct drm_device * dev);
137extern void via_driver_irq_postinstall(struct drm_device * dev); 140extern int via_driver_irq_postinstall(struct drm_device *dev);
138extern void via_driver_irq_uninstall(struct drm_device * dev); 141extern void via_driver_irq_uninstall(struct drm_device * dev);
139 142
140extern int via_dma_cleanup(struct drm_device * dev); 143extern int via_dma_cleanup(struct drm_device * dev);
141extern void via_init_command_verifier(void); 144extern void via_init_command_verifier(void);
142extern int via_driver_dma_quiescent(struct drm_device * dev); 145extern int via_driver_dma_quiescent(struct drm_device * dev);
143extern void via_init_futex(drm_via_private_t * dev_priv); 146extern void via_init_futex(drm_via_private_t *dev_priv);
144extern void via_cleanup_futex(drm_via_private_t * dev_priv); 147extern void via_cleanup_futex(drm_via_private_t *dev_priv);
145extern void via_release_futex(drm_via_private_t * dev_priv, int context); 148extern void via_release_futex(drm_via_private_t *dev_priv, int context);
146 149
147extern void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); 150extern void via_reclaim_buffers_locked(struct drm_device *dev,
151 struct drm_file *file_priv);
148extern void via_lastclose(struct drm_device *dev); 152extern void via_lastclose(struct drm_device *dev);
149 153
150extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq); 154extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq);
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index c6bb978a110..1b966fbdb49 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -43,7 +43,7 @@
43#define VIA_REG_INTERRUPT 0x200 43#define VIA_REG_INTERRUPT 0x200
44 44
45/* VIA_REG_INTERRUPT */ 45/* VIA_REG_INTERRUPT */
46#define VIA_IRQ_GLOBAL (1 << 31) 46#define VIA_IRQ_GLOBAL (1 << 31)
47#define VIA_IRQ_VBLANK_ENABLE (1 << 19) 47#define VIA_IRQ_VBLANK_ENABLE (1 << 19)
48#define VIA_IRQ_VBLANK_PENDING (1 << 3) 48#define VIA_IRQ_VBLANK_PENDING (1 << 3)
49#define VIA_IRQ_HQV0_ENABLE (1 << 11) 49#define VIA_IRQ_HQV0_ENABLE (1 << 11)
@@ -68,16 +68,15 @@
68 68
69static maskarray_t via_pro_group_a_irqs[] = { 69static maskarray_t via_pro_group_a_irqs[] = {
70 {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 70 {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
71 0x00000000}, 71 0x00000000 },
72 {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 72 {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
73 0x00000000}, 73 0x00000000 },
74 {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, 74 {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
75 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, 75 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
76 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, 76 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
77 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, 77 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
78}; 78};
79static int via_num_pro_group_a = 79static int via_num_pro_group_a = ARRAY_SIZE(via_pro_group_a_irqs);
80 sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
81static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; 80static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
82 81
83static maskarray_t via_unichrome_irqs[] = { 82static maskarray_t via_unichrome_irqs[] = {
@@ -86,14 +85,24 @@ static maskarray_t via_unichrome_irqs[] = {
86 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, 85 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
87 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} 86 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
88}; 87};
89static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); 88static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs);
90static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; 89static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
91 90
91
92static unsigned time_diff(struct timeval *now, struct timeval *then) 92static unsigned time_diff(struct timeval *now, struct timeval *then)
93{ 93{
94 return (now->tv_usec >= then->tv_usec) ? 94 return (now->tv_usec >= then->tv_usec) ?
95 now->tv_usec - then->tv_usec : 95 now->tv_usec - then->tv_usec :
96 1000000 - (then->tv_usec - now->tv_usec); 96 1000000 - (then->tv_usec - now->tv_usec);
97}
98
99u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
100{
101 drm_via_private_t *dev_priv = dev->dev_private;
102 if (crtc != 0)
103 return 0;
104
105 return atomic_read(&dev_priv->vbl_received);
97} 106}
98 107
99irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) 108irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
@@ -108,23 +117,22 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
108 117
109 status = VIA_READ(VIA_REG_INTERRUPT); 118 status = VIA_READ(VIA_REG_INTERRUPT);
110 if (status & VIA_IRQ_VBLANK_PENDING) { 119 if (status & VIA_IRQ_VBLANK_PENDING) {
111 atomic_inc(&dev->vbl_received); 120 atomic_inc(&dev_priv->vbl_received);
112 if (!(atomic_read(&dev->vbl_received) & 0x0F)) { 121 if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
113 do_gettimeofday(&cur_vblank); 122 do_gettimeofday(&cur_vblank);
114 if (dev_priv->last_vblank_valid) { 123 if (dev_priv->last_vblank_valid) {
115 dev_priv->usec_per_vblank = 124 dev_priv->usec_per_vblank =
116 time_diff(&cur_vblank, 125 time_diff(&cur_vblank,
117 &dev_priv->last_vblank) >> 4; 126 &dev_priv->last_vblank) >> 4;
118 } 127 }
119 dev_priv->last_vblank = cur_vblank; 128 dev_priv->last_vblank = cur_vblank;
120 dev_priv->last_vblank_valid = 1; 129 dev_priv->last_vblank_valid = 1;
121 } 130 }
122 if (!(atomic_read(&dev->vbl_received) & 0xFF)) { 131 if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
123 DRM_DEBUG("US per vblank is: %u\n", 132 DRM_DEBUG("US per vblank is: %u\n",
124 dev_priv->usec_per_vblank); 133 dev_priv->usec_per_vblank);
125 } 134 }
126 DRM_WAKEUP(&dev->vbl_queue); 135 drm_handle_vblank(dev, 0);
127 drm_vbl_send_signals(dev);
128 handled = 1; 136 handled = 1;
129 } 137 }
130 138
@@ -145,6 +153,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
145 /* Acknowlege interrupts */ 153 /* Acknowlege interrupts */
146 VIA_WRITE(VIA_REG_INTERRUPT, status); 154 VIA_WRITE(VIA_REG_INTERRUPT, status);
147 155
156
148 if (handled) 157 if (handled)
149 return IRQ_HANDLED; 158 return IRQ_HANDLED;
150 else 159 else
@@ -163,31 +172,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
163 } 172 }
164} 173}
165 174
166int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) 175int via_enable_vblank(struct drm_device *dev, int crtc)
167{ 176{
168 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 177 drm_via_private_t *dev_priv = dev->dev_private;
169 unsigned int cur_vblank; 178 u32 status;
170 int ret = 0;
171 179
172 DRM_DEBUG("\n"); 180 if (crtc != 0) {
173 if (!dev_priv) { 181 DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
174 DRM_ERROR("called with no initialization\n");
175 return -EINVAL; 182 return -EINVAL;
176 } 183 }
177 184
178 viadrv_acknowledge_irqs(dev_priv); 185 status = VIA_READ(VIA_REG_INTERRUPT);
186 VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
187
188 VIA_WRITE8(0x83d4, 0x11);
189 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
179 190
180 /* Assume that the user has missed the current sequence number 191 return 0;
181 * by about a day rather than she wants to wait for years 192}
182 * using vertical blanks...
183 */
184 193
185 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 194void via_disable_vblank(struct drm_device *dev, int crtc)
186 (((cur_vblank = atomic_read(&dev->vbl_received)) - 195{
187 *sequence) <= (1 << 23))); 196 drm_via_private_t *dev_priv = dev->dev_private;
188 197
189 *sequence = cur_vblank; 198 VIA_WRITE8(0x83d4, 0x11);
190 return ret; 199 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
200
201 if (crtc != 0)
202 DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
191} 203}
192 204
193static int 205static int
@@ -239,6 +251,7 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc
239 return ret; 251 return ret;
240} 252}
241 253
254
242/* 255/*
243 * drm_dma.h hooks 256 * drm_dma.h hooks
244 */ 257 */
@@ -292,23 +305,25 @@ void via_driver_irq_preinstall(struct drm_device * dev)
292 } 305 }
293} 306}
294 307
295void via_driver_irq_postinstall(struct drm_device * dev) 308int via_driver_irq_postinstall(struct drm_device *dev)
296{ 309{
297 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 310 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
298 u32 status; 311 u32 status;
299 312
300 DRM_DEBUG("\n"); 313 DRM_DEBUG("via_driver_irq_postinstall\n");
301 if (dev_priv) { 314 if (!dev_priv)
302 status = VIA_READ(VIA_REG_INTERRUPT); 315 return -EINVAL;
303 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
304 | dev_priv->irq_enable_mask);
305 316
306 /* Some magic, oh for some data sheets ! */ 317 drm_vblank_init(dev, 1);
318 status = VIA_READ(VIA_REG_INTERRUPT);
319 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
320 | dev_priv->irq_enable_mask);
307 321
308 VIA_WRITE8(0x83d4, 0x11); 322 /* Some magic, oh for some data sheets ! */
309 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); 323 VIA_WRITE8(0x83d4, 0x11);
324 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
310 325
311 } 326 return 0;
312} 327}
313 328
314void via_driver_irq_uninstall(struct drm_device * dev) 329void via_driver_irq_uninstall(struct drm_device * dev)
@@ -352,7 +367,8 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
352 367
353 switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) { 368 switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) {
354 case VIA_IRQ_RELATIVE: 369 case VIA_IRQ_RELATIVE:
355 irqwait->request.sequence += atomic_read(&cur_irq->irq_received); 370 irqwait->request.sequence +=
371 atomic_read(&cur_irq->irq_received);
356 irqwait->request.type &= ~_DRM_VBLANK_RELATIVE; 372 irqwait->request.type &= ~_DRM_VBLANK_RELATIVE;
357 case VIA_IRQ_ABSOLUTE: 373 case VIA_IRQ_ABSOLUTE:
358 break; 374 break;
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 0864c692094..15e55039b7f 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -454,6 +454,7 @@ struct drm_irq_busid {
454enum drm_vblank_seq_type { 454enum drm_vblank_seq_type {
455 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ 455 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
456 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ 456 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
457 _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
457 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ 458 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
458 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ 459 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
459 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ 460 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
@@ -486,6 +487,19 @@ union drm_wait_vblank {
486 struct drm_wait_vblank_reply reply; 487 struct drm_wait_vblank_reply reply;
487}; 488};
488 489
490#define _DRM_PRE_MODESET 1
491#define _DRM_POST_MODESET 2
492
493/**
494 * DRM_IOCTL_MODESET_CTL ioctl argument type
495 *
496 * \sa drmModesetCtl().
497 */
498struct drm_modeset_ctl {
499 uint32_t crtc;
500 uint32_t cmd;
501};
502
489/** 503/**
490 * DRM_IOCTL_AGP_ENABLE ioctl argument type. 504 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
491 * 505 *
@@ -570,6 +584,7 @@ struct drm_set_version {
570#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) 584#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
571#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) 585#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
572#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) 586#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
587#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
573 588
574#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) 589#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
575#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) 590#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 1c1b13e2922..e79ce0781f0 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -580,11 +580,54 @@ struct drm_driver {
580 int (*kernel_context_switch) (struct drm_device *dev, int old, 580 int (*kernel_context_switch) (struct drm_device *dev, int old,
581 int new); 581 int new);
582 void (*kernel_context_switch_unlock) (struct drm_device *dev); 582 void (*kernel_context_switch_unlock) (struct drm_device *dev);
583 int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
584 int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
585 int (*dri_library_name) (struct drm_device *dev, char *buf); 583 int (*dri_library_name) (struct drm_device *dev, char *buf);
586 584
587 /** 585 /**
586 * get_vblank_counter - get raw hardware vblank counter
587 * @dev: DRM device
588 * @crtc: counter to fetch
589 *
590 * Driver callback for fetching a raw hardware vblank counter
591 * for @crtc. If a device doesn't have a hardware counter, the
592 * driver can simply return the value of drm_vblank_count and
593 * make the enable_vblank() and disable_vblank() hooks into no-ops,
594 * leaving interrupts enabled at all times.
595 *
596 * Wraparound handling and loss of events due to modesetting is dealt
597 * with in the DRM core code.
598 *
599 * RETURNS
600 * Raw vblank counter value.
601 */
602 u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
603
604 /**
605 * enable_vblank - enable vblank interrupt events
606 * @dev: DRM device
607 * @crtc: which irq to enable
608 *
609 * Enable vblank interrupts for @crtc. If the device doesn't have
610 * a hardware vblank counter, this routine should be a no-op, since
611 * interrupts will have to stay on to keep the count accurate.
612 *
613 * RETURNS
614 * Zero on success, appropriate errno if the given @crtc's vblank
615 * interrupt cannot be enabled.
616 */
617 int (*enable_vblank) (struct drm_device *dev, int crtc);
618
619 /**
620 * disable_vblank - disable vblank interrupt events
621 * @dev: DRM device
622 * @crtc: which irq to enable
623 *
624 * Disable vblank interrupts for @crtc. If the device doesn't have
625 * a hardware vblank counter, this routine should be a no-op, since
626 * interrupts will have to stay on to keep the count accurate.
627 */
628 void (*disable_vblank) (struct drm_device *dev, int crtc);
629
630 /**
588 * Called by \c drm_device_is_agp. Typically used to determine if a 631 * Called by \c drm_device_is_agp. Typically used to determine if a
589 * card is really attached to AGP or not. 632 * card is really attached to AGP or not.
590 * 633 *
@@ -601,7 +644,7 @@ struct drm_driver {
601 644
602 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); 645 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
603 void (*irq_preinstall) (struct drm_device *dev); 646 void (*irq_preinstall) (struct drm_device *dev);
604 void (*irq_postinstall) (struct drm_device *dev); 647 int (*irq_postinstall) (struct drm_device *dev);
605 void (*irq_uninstall) (struct drm_device *dev); 648 void (*irq_uninstall) (struct drm_device *dev);
606 void (*reclaim_buffers) (struct drm_device *dev, 649 void (*reclaim_buffers) (struct drm_device *dev,
607 struct drm_file * file_priv); 650 struct drm_file * file_priv);
@@ -730,13 +773,28 @@ struct drm_device {
730 /** \name VBLANK IRQ support */ 773 /** \name VBLANK IRQ support */
731 /*@{ */ 774 /*@{ */
732 775
733 wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ 776 /*
734 atomic_t vbl_received; 777 * At load time, disabling the vblank interrupt won't be allowed since
735 atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ 778 * old clients may not call the modeset ioctl and therefore misbehave.
779 * Once the modeset ioctl *has* been called though, we can safely
780 * disable them when unused.
781 */
782 int vblank_disable_allowed;
783
784 wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
785 atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
736 spinlock_t vbl_lock; 786 spinlock_t vbl_lock;
737 struct list_head vbl_sigs; /**< signal list to send on VBLANK */ 787 struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
738 struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ 788 atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
739 unsigned int vbl_pending; 789 atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
790 u32 *last_vblank; /* protected by dev->vbl_lock, used */
791 /* for wraparound handling */
792 int *vblank_enabled; /* so we don't call enable more than
793 once per disable */
794 int *vblank_inmodeset; /* Display driver is setting mode */
795 struct timer_list vblank_disable_timer;
796
797 u32 max_vblank_count; /**< size of vblank counter register */
740 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ 798 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
741 void (*locked_tasklet_func)(struct drm_device *dev); 799 void (*locked_tasklet_func)(struct drm_device *dev);
742 800
@@ -757,6 +815,7 @@ struct drm_device {
757 struct pci_controller *hose; 815 struct pci_controller *hose;
758#endif 816#endif
759 struct drm_sg_mem *sg; /**< Scatter gather memory */ 817 struct drm_sg_mem *sg; /**< Scatter gather memory */
818 int num_crtcs; /**< Number of CRTCs on this device */
760 void *dev_private; /**< device private data */ 819 void *dev_private; /**< device private data */
761 struct drm_sigdata sigdata; /**< For block_all_signals */ 820 struct drm_sigdata sigdata; /**< For block_all_signals */
762 sigset_t sigmask; 821 sigset_t sigmask;
@@ -990,10 +1049,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev);
990extern void drm_driver_irq_postinstall(struct drm_device *dev); 1049extern void drm_driver_irq_postinstall(struct drm_device *dev);
991extern void drm_driver_irq_uninstall(struct drm_device *dev); 1050extern void drm_driver_irq_uninstall(struct drm_device *dev);
992 1051
1052extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
993extern int drm_wait_vblank(struct drm_device *dev, void *data, 1053extern int drm_wait_vblank(struct drm_device *dev, void *data,
994 struct drm_file *file_priv); 1054 struct drm_file *filp);
995extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); 1055extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
996extern void drm_vbl_send_signals(struct drm_device *dev); 1056extern void drm_locked_tasklet(struct drm_device *dev,
1057 void(*func)(struct drm_device *));
1058extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1059extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1060extern int drm_vblank_get(struct drm_device *dev, int crtc);
1061extern void drm_vblank_put(struct drm_device *dev, int crtc);
1062/* Modesetting support */
1063extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1064 struct drm_file *file_priv);
997extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); 1065extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
998 1066
999 /* AGP/GART support (drm_agpsupport.h) */ 1067 /* AGP/GART support (drm_agpsupport.h) */