aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-09-30 15:14:26 -0400
committerDave Airlie <airlied@linux.ie>2008-10-17 17:10:11 -0400
commit0a3e67a4caac273a3bfc4ced3da364830b1ab241 (patch)
tree02a2e5e76d9dffcb556d09b0eee4d34ebe5d81cb /drivers/gpu
parent2df68b439fcb97a4c55f81516206ef4ee325e28d (diff)
drm: Rework vblank-wait handling to allow interrupt reduction.
Previously, drivers supporting vblank interrupt waits would run the interrupt all the time, or all the time that any 3d client was running, preventing the CPU from sleeping for long when the system was otherwise idle. Now, interrupts are disabled any time that no client is waiting on a vblank event. The new method uses vblank counters on the chipsets when the interrupts are turned off, rather than counting interrupts, so that we can continue to present accurate vblank numbers. Co-author: Michel Dänzer <michel@tungstengraphics.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-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
19 files changed, 1095 insertions, 462 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;