summaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch1534
1 files changed, 1534 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch
new file mode 100644
index 0000000000..6161a71f04
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch
@@ -0,0 +1,1534 @@
1commit 2aebb4e4e62d09b4a95be7be7c24a7f6528385b7
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Sep 30 12:14:26 2008 -0700
4
5 drm: Rework vblank-wait handling to allow interrupt reduction.
6
7 Previously, drivers supporting vblank interrupt waits would run the interrupt
8 all the time, or all the time that any 3d client was running, preventing the
9 CPU from sleeping for long when the system was otherwise idle. Now, interrupts
10 are disabled any time that no client is waiting on a vblank event. The new
11 method uses vblank counters on the chipsets when the interrupts are turned
12 off, rather than counting interrupts, so that we can continue to present
13 accurate vblank numbers.
14
15 Co-author: Michel Dänzer <michel@tungstengraphics.com>
16 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
17 Signed-off-by: Eric Anholt <eric@anholt.net>
18 Signed-off-by: Dave Airlie <airlied@redhat.com>
19
20diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
21index 452c2d8..fb45fe7 100644
22--- a/drivers/gpu/drm/drm_drv.c
23+++ b/drivers/gpu/drm/drm_drv.c
24@@ -116,6 +116,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
25
26 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
27
28+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
29+
30 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
31 };
32
33diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
34index 61ed515..d0c13d9 100644
35--- a/drivers/gpu/drm/drm_irq.c
36+++ b/drivers/gpu/drm/drm_irq.c
37@@ -71,19 +71,131 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
38 return 0;
39 }
40
41+static void vblank_disable_fn(unsigned long arg)
42+{
43+ struct drm_device *dev = (struct drm_device *)arg;
44+ unsigned long irqflags;
45+ int i;
46+
47+ if (!dev->vblank_disable_allowed)
48+ return;
49+
50+ for (i = 0; i < dev->num_crtcs; i++) {
51+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
52+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
53+ dev->vblank_enabled[i]) {
54+ DRM_DEBUG("disabling vblank on crtc %d\n", i);
55+ dev->last_vblank[i] =
56+ dev->driver->get_vblank_counter(dev, i);
57+ dev->driver->disable_vblank(dev, i);
58+ dev->vblank_enabled[i] = 0;
59+ }
60+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
61+ }
62+}
63+
64+static void drm_vblank_cleanup(struct drm_device *dev)
65+{
66+ /* Bail if the driver didn't call drm_vblank_init() */
67+ if (dev->num_crtcs == 0)
68+ return;
69+
70+ del_timer(&dev->vblank_disable_timer);
71+
72+ vblank_disable_fn((unsigned long)dev);
73+
74+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
75+ DRM_MEM_DRIVER);
76+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
77+ DRM_MEM_DRIVER);
78+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
79+ dev->num_crtcs, DRM_MEM_DRIVER);
80+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
81+ dev->num_crtcs, DRM_MEM_DRIVER);
82+ drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
83+ dev->num_crtcs, DRM_MEM_DRIVER);
84+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
85+ DRM_MEM_DRIVER);
86+ drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
87+ dev->num_crtcs, DRM_MEM_DRIVER);
88+
89+ dev->num_crtcs = 0;
90+}
91+
92+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
93+{
94+ int i, ret = -ENOMEM;
95+
96+ setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
97+ (unsigned long)dev);
98+ spin_lock_init(&dev->vbl_lock);
99+ atomic_set(&dev->vbl_signal_pending, 0);
100+ dev->num_crtcs = num_crtcs;
101+
102+ dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
103+ DRM_MEM_DRIVER);
104+ if (!dev->vbl_queue)
105+ goto err;
106+
107+ dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
108+ DRM_MEM_DRIVER);
109+ if (!dev->vbl_sigs)
110+ goto err;
111+
112+ dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
113+ DRM_MEM_DRIVER);
114+ if (!dev->_vblank_count)
115+ goto err;
116+
117+ dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
118+ DRM_MEM_DRIVER);
119+ if (!dev->vblank_refcount)
120+ goto err;
121+
122+ dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
123+ DRM_MEM_DRIVER);
124+ if (!dev->vblank_enabled)
125+ goto err;
126+
127+ dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
128+ if (!dev->last_vblank)
129+ goto err;
130+
131+ dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
132+ DRM_MEM_DRIVER);
133+ if (!dev->vblank_inmodeset)
134+ goto err;
135+
136+ /* Zero per-crtc vblank stuff */
137+ for (i = 0; i < num_crtcs; i++) {
138+ init_waitqueue_head(&dev->vbl_queue[i]);
139+ INIT_LIST_HEAD(&dev->vbl_sigs[i]);
140+ atomic_set(&dev->_vblank_count[i], 0);
141+ atomic_set(&dev->vblank_refcount[i], 0);
142+ }
143+
144+ dev->vblank_disable_allowed = 0;
145+
146+ return 0;
147+
148+err:
149+ drm_vblank_cleanup(dev);
150+ return ret;
151+}
152+EXPORT_SYMBOL(drm_vblank_init);
153+
154 /**
155 * Install IRQ handler.
156 *
157 * \param dev DRM device.
158- * \param irq IRQ number.
159 *
160- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
161+ * Initializes the IRQ related data. Installs the handler, calling the driver
162 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
163 * before and after the installation.
164 */
165-static int drm_irq_install(struct drm_device * dev)
166+int drm_irq_install(struct drm_device *dev)
167 {
168- int ret;
169+ int ret = 0;
170 unsigned long sh_flags = 0;
171
172 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
173@@ -109,17 +221,6 @@ static int drm_irq_install(struct drm_device * dev)
174
175 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
176
177- if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
178- init_waitqueue_head(&dev->vbl_queue);
179-
180- spin_lock_init(&dev->vbl_lock);
181-
182- INIT_LIST_HEAD(&dev->vbl_sigs);
183- INIT_LIST_HEAD(&dev->vbl_sigs2);
184-
185- dev->vbl_pending = 0;
186- }
187-
188 /* Before installing handler */
189 dev->driver->irq_preinstall(dev);
190
191@@ -141,10 +242,16 @@ static int drm_irq_install(struct drm_device * dev)
192 }
193
194 /* After installing handler */
195- dev->driver->irq_postinstall(dev);
196+ ret = dev->driver->irq_postinstall(dev);
197+ if (ret < 0) {
198+ mutex_lock(&dev->struct_mutex);
199+ dev->irq_enabled = 0;
200+ mutex_unlock(&dev->struct_mutex);
201+ }
202
203- return 0;
204+ return ret;
205 }
206+EXPORT_SYMBOL(drm_irq_install);
207
208 /**
209 * Uninstall the IRQ handler.
210@@ -174,11 +281,12 @@ int drm_irq_uninstall(struct drm_device * dev)
211
212 free_irq(dev->pdev->irq, dev);
213
214+ drm_vblank_cleanup(dev);
215+
216 dev->locked_tasklet_func = NULL;
217
218 return 0;
219 }
220-
221 EXPORT_SYMBOL(drm_irq_uninstall);
222
223 /**
224@@ -218,6 +326,174 @@ int drm_control(struct drm_device *dev, void *data,
225 }
226
227 /**
228+ * drm_vblank_count - retrieve "cooked" vblank counter value
229+ * @dev: DRM device
230+ * @crtc: which counter to retrieve
231+ *
232+ * Fetches the "cooked" vblank count value that represents the number of
233+ * vblank events since the system was booted, including lost events due to
234+ * modesetting activity.
235+ */
236+u32 drm_vblank_count(struct drm_device *dev, int crtc)
237+{
238+ return atomic_read(&dev->_vblank_count[crtc]);
239+}
240+EXPORT_SYMBOL(drm_vblank_count);
241+
242+/**
243+ * drm_update_vblank_count - update the master vblank counter
244+ * @dev: DRM device
245+ * @crtc: counter to update
246+ *
247+ * Call back into the driver to update the appropriate vblank counter
248+ * (specified by @crtc). Deal with wraparound, if it occurred, and
249+ * update the last read value so we can deal with wraparound on the next
250+ * call if necessary.
251+ *
252+ * Only necessary when going from off->on, to account for frames we
253+ * didn't get an interrupt for.
254+ *
255+ * Note: caller must hold dev->vbl_lock since this reads & writes
256+ * device vblank fields.
257+ */
258+static void drm_update_vblank_count(struct drm_device *dev, int crtc)
259+{
260+ u32 cur_vblank, diff;
261+
262+ /*
263+ * Interrupts were disabled prior to this call, so deal with counter
264+ * wrap if needed.
265+ * NOTE! It's possible we lost a full dev->max_vblank_count events
266+ * here if the register is small or we had vblank interrupts off for
267+ * a long time.
268+ */
269+ cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
270+ diff = cur_vblank - dev->last_vblank[crtc];
271+ if (cur_vblank < dev->last_vblank[crtc]) {
272+ diff += dev->max_vblank_count;
273+
274+ DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
275+ crtc, dev->last_vblank[crtc], cur_vblank, diff);
276+ }
277+
278+ DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
279+ crtc, diff);
280+
281+ atomic_add(diff, &dev->_vblank_count[crtc]);
282+}
283+
284+/**
285+ * drm_vblank_get - get a reference count on vblank events
286+ * @dev: DRM device
287+ * @crtc: which CRTC to own
288+ *
289+ * Acquire a reference count on vblank events to avoid having them disabled
290+ * while in use.
291+ *
292+ * RETURNS
293+ * Zero on success, nonzero on failure.
294+ */
295+int drm_vblank_get(struct drm_device *dev, int crtc)
296+{
297+ unsigned long irqflags;
298+ int ret = 0;
299+
300+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
301+ /* Going from 0->1 means we have to enable interrupts again */
302+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
303+ !dev->vblank_enabled[crtc]) {
304+ ret = dev->driver->enable_vblank(dev, crtc);
305+ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
306+ if (ret)
307+ atomic_dec(&dev->vblank_refcount[crtc]);
308+ else {
309+ dev->vblank_enabled[crtc] = 1;
310+ drm_update_vblank_count(dev, crtc);
311+ }
312+ }
313+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
314+
315+ return ret;
316+}
317+EXPORT_SYMBOL(drm_vblank_get);
318+
319+/**
320+ * drm_vblank_put - give up ownership of vblank events
321+ * @dev: DRM device
322+ * @crtc: which counter to give up
323+ *
324+ * Release ownership of a given vblank counter, turning off interrupts
325+ * if possible.
326+ */
327+void drm_vblank_put(struct drm_device *dev, int crtc)
328+{
329+ /* Last user schedules interrupt disable */
330+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
331+ mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
332+}
333+EXPORT_SYMBOL(drm_vblank_put);
334+
335+/**
336+ * drm_modeset_ctl - handle vblank event counter changes across mode switch
337+ * @DRM_IOCTL_ARGS: standard ioctl arguments
338+ *
339+ * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
340+ * ioctls around modesetting so that any lost vblank events are accounted for.
341+ *
342+ * Generally the counter will reset across mode sets. If interrupts are
343+ * enabled around this call, we don't have to do anything since the counter
344+ * will have already been incremented.
345+ */
346+int drm_modeset_ctl(struct drm_device *dev, void *data,
347+ struct drm_file *file_priv)
348+{
349+ struct drm_modeset_ctl *modeset = data;
350+ unsigned long irqflags;
351+ int crtc, ret = 0;
352+
353+ /* If drm_vblank_init() hasn't been called yet, just no-op */
354+ if (!dev->num_crtcs)
355+ goto out;
356+
357+ crtc = modeset->crtc;
358+ if (crtc >= dev->num_crtcs) {
359+ ret = -EINVAL;
360+ goto out;
361+ }
362+
363+ /*
364+ * To avoid all the problems that might happen if interrupts
365+ * were enabled/disabled around or between these calls, we just
366+ * have the kernel take a reference on the CRTC (just once though
367+ * to avoid corrupting the count if multiple, mismatch calls occur),
368+ * so that interrupts remain enabled in the interim.
369+ */
370+ switch (modeset->cmd) {
371+ case _DRM_PRE_MODESET:
372+ if (!dev->vblank_inmodeset[crtc]) {
373+ dev->vblank_inmodeset[crtc] = 1;
374+ drm_vblank_get(dev, crtc);
375+ }
376+ break;
377+ case _DRM_POST_MODESET:
378+ if (dev->vblank_inmodeset[crtc]) {
379+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
380+ dev->vblank_disable_allowed = 1;
381+ dev->vblank_inmodeset[crtc] = 0;
382+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
383+ drm_vblank_put(dev, crtc);
384+ }
385+ break;
386+ default:
387+ ret = -EINVAL;
388+ break;
389+ }
390+
391+out:
392+ return ret;
393+}
394+
395+/**
396 * Wait for VBLANK.
397 *
398 * \param inode device inode.
399@@ -236,12 +512,12 @@ int drm_control(struct drm_device *dev, void *data,
400 *
401 * If a signal is not requested, then calls vblank_wait().
402 */
403-int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
404+int drm_wait_vblank(struct drm_device *dev, void *data,
405+ struct drm_file *file_priv)
406 {
407 union drm_wait_vblank *vblwait = data;
408- struct timeval now;
409 int ret = 0;
410- unsigned int flags, seq;
411+ unsigned int flags, seq, crtc;
412
413 if ((!dev->pdev->irq) || (!dev->irq_enabled))
414 return -EINVAL;
415@@ -255,13 +531,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
416 }
417
418 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
419+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
420
421- if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
422- DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
423+ if (crtc >= dev->num_crtcs)
424 return -EINVAL;
425
426- seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
427- : &dev->vbl_received);
428+ ret = drm_vblank_get(dev, crtc);
429+ if (ret) {
430+ DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
431+ return ret;
432+ }
433+ seq = drm_vblank_count(dev, crtc);
434
435 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
436 case _DRM_VBLANK_RELATIVE:
437@@ -270,7 +550,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
438 case _DRM_VBLANK_ABSOLUTE:
439 break;
440 default:
441- return -EINVAL;
442+ ret = -EINVAL;
443+ goto done;
444 }
445
446 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
447@@ -280,8 +561,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
448
449 if (flags & _DRM_VBLANK_SIGNAL) {
450 unsigned long irqflags;
451- struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
452- ? &dev->vbl_sigs2 : &dev->vbl_sigs;
453+ struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
454 struct drm_vbl_sig *vbl_sig;
455
456 spin_lock_irqsave(&dev->vbl_lock, irqflags);
457@@ -302,22 +582,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
458 }
459 }
460
461- if (dev->vbl_pending >= 100) {
462+ if (atomic_read(&dev->vbl_signal_pending) >= 100) {
463 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
464- return -EBUSY;
465+ ret = -EBUSY;
466+ goto done;
467 }
468
469- dev->vbl_pending++;
470-
471 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
472
473- if (!
474- (vbl_sig =
475- drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
476- return -ENOMEM;
477+ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
478+ DRM_MEM_DRIVER);
479+ if (!vbl_sig) {
480+ ret = -ENOMEM;
481+ goto done;
482+ }
483+
484+ ret = drm_vblank_get(dev, crtc);
485+ if (ret) {
486+ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
487+ DRM_MEM_DRIVER);
488+ return ret;
489 }
490
491- memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
492+ atomic_inc(&dev->vbl_signal_pending);
493
494 vbl_sig->sequence = vblwait->request.sequence;
495 vbl_sig->info.si_signo = vblwait->request.signal;
496@@ -331,20 +618,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
497
498 vblwait->reply.sequence = seq;
499 } else {
500- if (flags & _DRM_VBLANK_SECONDARY) {
501- if (dev->driver->vblank_wait2)
502- ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
503- } else if (dev->driver->vblank_wait)
504- ret =
505- dev->driver->vblank_wait(dev,
506- &vblwait->request.sequence);
507-
508- do_gettimeofday(&now);
509- vblwait->reply.tval_sec = now.tv_sec;
510- vblwait->reply.tval_usec = now.tv_usec;
511+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
512+ vblwait->request.sequence, crtc);
513+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
514+ ((drm_vblank_count(dev, crtc)
515+ - vblwait->request.sequence) <= (1 << 23)));
516+
517+ if (ret != -EINTR) {
518+ struct timeval now;
519+
520+ do_gettimeofday(&now);
521+
522+ vblwait->reply.tval_sec = now.tv_sec;
523+ vblwait->reply.tval_usec = now.tv_usec;
524+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
525+ DRM_DEBUG("returning %d to client\n",
526+ vblwait->reply.sequence);
527+ } else {
528+ DRM_DEBUG("vblank wait interrupted by signal\n");
529+ }
530 }
531
532- done:
533+done:
534+ drm_vblank_put(dev, crtc);
535 return ret;
536 }
537
538@@ -352,44 +648,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
539 * Send the VBLANK signals.
540 *
541 * \param dev DRM device.
542+ * \param crtc CRTC where the vblank event occurred
543 *
544 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
545 *
546 * If a signal is not requested, then calls vblank_wait().
547 */
548-void drm_vbl_send_signals(struct drm_device * dev)
549+static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
550 {
551+ struct drm_vbl_sig *vbl_sig, *tmp;
552+ struct list_head *vbl_sigs;
553+ unsigned int vbl_seq;
554 unsigned long flags;
555- int i;
556
557 spin_lock_irqsave(&dev->vbl_lock, flags);
558
559- for (i = 0; i < 2; i++) {
560- struct drm_vbl_sig *vbl_sig, *tmp;
561- struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
562- unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
563- &dev->vbl_received);
564+ vbl_sigs = &dev->vbl_sigs[crtc];
565+ vbl_seq = drm_vblank_count(dev, crtc);
566
567- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
568- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
569- vbl_sig->info.si_code = vbl_seq;
570- send_sig_info(vbl_sig->info.si_signo,
571- &vbl_sig->info, vbl_sig->task);
572+ list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
573+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
574+ vbl_sig->info.si_code = vbl_seq;
575+ send_sig_info(vbl_sig->info.si_signo,
576+ &vbl_sig->info, vbl_sig->task);
577
578- list_del(&vbl_sig->head);
579-
580- drm_free(vbl_sig, sizeof(*vbl_sig),
581- DRM_MEM_DRIVER);
582+ list_del(&vbl_sig->head);
583
584- dev->vbl_pending--;
585- }
586- }
587+ drm_free(vbl_sig, sizeof(*vbl_sig),
588+ DRM_MEM_DRIVER);
589+ atomic_dec(&dev->vbl_signal_pending);
590+ drm_vblank_put(dev, crtc);
591+ }
592 }
593
594 spin_unlock_irqrestore(&dev->vbl_lock, flags);
595 }
596
597-EXPORT_SYMBOL(drm_vbl_send_signals);
598+/**
599+ * drm_handle_vblank - handle a vblank event
600+ * @dev: DRM device
601+ * @crtc: where this event occurred
602+ *
603+ * Drivers should call this routine in their vblank interrupt handlers to
604+ * update the vblank counter and send any signals that may be pending.
605+ */
606+void drm_handle_vblank(struct drm_device *dev, int crtc)
607+{
608+ atomic_inc(&dev->_vblank_count[crtc]);
609+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
610+ drm_vbl_send_signals(dev, crtc);
611+}
612+EXPORT_SYMBOL(drm_handle_vblank);
613
614 /**
615 * Tasklet wrapper function.
616diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
617index cead62f..8609ec2 100644
618--- a/drivers/gpu/drm/i915/i915_dma.c
619+++ b/drivers/gpu/drm/i915/i915_dma.c
620@@ -673,7 +673,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
621
622 switch (param->param) {
623 case I915_PARAM_IRQ_ACTIVE:
624- value = dev->irq_enabled;
625+ value = dev->pdev->irq ? 1 : 0;
626 break;
627 case I915_PARAM_ALLOW_BATCHBUFFER:
628 value = dev_priv->allow_batchbuffer ? 1 : 0;
629@@ -808,7 +808,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
630 * and the registers being closely associated.
631 */
632 if (!IS_I945G(dev) && !IS_I945GM(dev))
633- pci_enable_msi(dev->pdev);
634+ if (pci_enable_msi(dev->pdev))
635+ DRM_ERROR("failed to enable MSI\n");
636
637 intel_opregion_init(dev);
638
639diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
640index eff66ed..37af03f 100644
641--- a/drivers/gpu/drm/i915/i915_drv.c
642+++ b/drivers/gpu/drm/i915/i915_drv.c
643@@ -85,10 +85,8 @@ static struct drm_driver driver = {
644 /* don't use mtrr's here, the Xserver or user space app should
645 * deal with them for intel hardware.
646 */
647- .driver_features =
648- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
649- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
650- DRIVER_IRQ_VBL2,
651+ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
652+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
653 .load = i915_driver_load,
654 .unload = i915_driver_unload,
655 .lastclose = i915_driver_lastclose,
656@@ -96,8 +94,9 @@ static struct drm_driver driver = {
657 .suspend = i915_suspend,
658 .resume = i915_resume,
659 .device_is_agp = i915_driver_device_is_agp,
660- .vblank_wait = i915_driver_vblank_wait,
661- .vblank_wait2 = i915_driver_vblank_wait2,
662+ .get_vblank_counter = i915_get_vblank_counter,
663+ .enable_vblank = i915_enable_vblank,
664+ .disable_vblank = i915_disable_vblank,
665 .irq_preinstall = i915_driver_irq_preinstall,
666 .irq_postinstall = i915_driver_irq_postinstall,
667 .irq_uninstall = i915_driver_irq_uninstall,
668diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
669index 71326ca..d1a02be 100644
670--- a/drivers/gpu/drm/i915/i915_drv.h
671+++ b/drivers/gpu/drm/i915/i915_drv.h
672@@ -83,10 +83,15 @@ struct mem_block {
673 typedef struct _drm_i915_vbl_swap {
674 struct list_head head;
675 drm_drawable_t drw_id;
676- unsigned int pipe;
677+ unsigned int plane;
678 unsigned int sequence;
679 } drm_i915_vbl_swap_t;
680
681+struct opregion_header;
682+struct opregion_acpi;
683+struct opregion_swsci;
684+struct opregion_asle;
685+
686 struct intel_opregion {
687 struct opregion_header *header;
688 struct opregion_acpi *acpi;
689@@ -105,7 +110,7 @@ typedef struct drm_i915_private {
690 drm_dma_handle_t *status_page_dmah;
691 void *hw_status_page;
692 dma_addr_t dma_status_page;
693- unsigned long counter;
694+ uint32_t counter;
695 unsigned int status_gfx_addr;
696 drm_local_map_t hws_map;
697
698@@ -247,16 +252,17 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
699 extern int i915_irq_wait(struct drm_device *dev, void *data,
700 struct drm_file *file_priv);
701
702-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
703-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
704 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
705 extern void i915_driver_irq_preinstall(struct drm_device * dev);
706-extern void i915_driver_irq_postinstall(struct drm_device * dev);
707+extern int i915_driver_irq_postinstall(struct drm_device *dev);
708 extern void i915_driver_irq_uninstall(struct drm_device * dev);
709 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
710 struct drm_file *file_priv);
711 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
712 struct drm_file *file_priv);
713+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
714+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
715+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
716 extern int i915_vblank_swap(struct drm_device *dev, void *data,
717 struct drm_file *file_priv);
718 extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
719@@ -278,6 +284,10 @@ extern void i915_mem_release(struct drm_device * dev,
720 extern int i915_save_state(struct drm_device *dev);
721 extern int i915_restore_state(struct drm_device *dev);
722
723+/* i915_suspend.c */
724+extern int i915_save_state(struct drm_device *dev);
725+extern int i915_restore_state(struct drm_device *dev);
726+
727 /* i915_opregion.c */
728 extern int intel_opregion_init(struct drm_device *dev);
729 extern void intel_opregion_free(struct drm_device *dev);
730diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
731index ae7d3a8..f875959 100644
732--- a/drivers/gpu/drm/i915/i915_irq.c
733+++ b/drivers/gpu/drm/i915/i915_irq.c
734@@ -35,9 +35,8 @@
735
736 /** These are the interrupts used by the driver */
737 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
738- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
739- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
740 I915_ASLE_INTERRUPT | \
741+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
742 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
743
744 void
745@@ -61,6 +60,64 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
746 }
747
748 /**
749+ * i915_get_pipe - return the the pipe associated with a given plane
750+ * @dev: DRM device
751+ * @plane: plane to look for
752+ *
753+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
754+ * rather than a pipe number, since they may not always be equal. This routine
755+ * maps the given @plane back to a pipe number.
756+ */
757+static int
758+i915_get_pipe(struct drm_device *dev, int plane)
759+{
760+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
761+ u32 dspcntr;
762+
763+ dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
764+
765+ return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
766+}
767+
768+/**
769+ * i915_get_plane - return the the plane associated with a given pipe
770+ * @dev: DRM device
771+ * @pipe: pipe to look for
772+ *
773+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
774+ * rather than a plane number, since they may not always be equal. This routine
775+ * maps the given @pipe back to a plane number.
776+ */
777+static int
778+i915_get_plane(struct drm_device *dev, int pipe)
779+{
780+ if (i915_get_pipe(dev, 0) == pipe)
781+ return 0;
782+ return 1;
783+}
784+
785+/**
786+ * i915_pipe_enabled - check if a pipe is enabled
787+ * @dev: DRM device
788+ * @pipe: pipe to check
789+ *
790+ * Reading certain registers when the pipe is disabled can hang the chip.
791+ * Use this routine to make sure the PLL is running and the pipe is active
792+ * before reading such registers if unsure.
793+ */
794+static int
795+i915_pipe_enabled(struct drm_device *dev, int pipe)
796+{
797+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
798+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
799+
800+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
801+ return 1;
802+
803+ return 0;
804+}
805+
806+/**
807 * Emit blits for scheduled buffer swaps.
808 *
809 * This function will be called with the HW lock held.
810@@ -71,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
811 unsigned long irqflags;
812 struct list_head *list, *tmp, hits, *hit;
813 int nhits, nrects, slice[2], upper[2], lower[2], i;
814- unsigned counter[2] = { atomic_read(&dev->vbl_received),
815- atomic_read(&dev->vbl_received2) };
816+ unsigned counter[2];
817 struct drm_drawable_info *drw;
818 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
819 u32 cpp = dev_priv->cpp;
820@@ -94,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
821 src_pitch >>= 2;
822 }
823
824+ counter[0] = drm_vblank_count(dev, 0);
825+ counter[1] = drm_vblank_count(dev, 1);
826+
827 DRM_DEBUG("\n");
828
829 INIT_LIST_HEAD(&hits);
830@@ -106,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev)
831 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
832 drm_i915_vbl_swap_t *vbl_swap =
833 list_entry(list, drm_i915_vbl_swap_t, head);
834+ int pipe = i915_get_pipe(dev, vbl_swap->plane);
835
836- if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
837+ if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
838 continue;
839
840 list_del(list);
841 dev_priv->swaps_pending--;
842+ drm_vblank_put(dev, pipe);
843
844 spin_unlock(&dev_priv->swaps_lock);
845 spin_lock(&dev->drw_lock);
846@@ -204,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
847 drm_i915_vbl_swap_t *swap_hit =
848 list_entry(hit, drm_i915_vbl_swap_t, head);
849 struct drm_clip_rect *rect;
850- int num_rects, pipe;
851+ int num_rects, plane;
852 unsigned short top, bottom;
853
854 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
855@@ -213,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
856 continue;
857
858 rect = drw->rects;
859- pipe = swap_hit->pipe;
860- top = upper[pipe];
861- bottom = lower[pipe];
862+ plane = swap_hit->plane;
863+ top = upper[plane];
864+ bottom = lower[plane];
865
866 for (num_rects = drw->num_rects; num_rects--; rect++) {
867 int y1 = max(rect->y1, top);
868@@ -252,22 +313,54 @@ static void i915_vblank_tasklet(struct drm_device *dev)
869 }
870 }
871
872+u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
873+{
874+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
875+ unsigned long high_frame;
876+ unsigned long low_frame;
877+ u32 high1, high2, low, count;
878+ int pipe;
879+
880+ pipe = i915_get_pipe(dev, plane);
881+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
882+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
883+
884+ if (!i915_pipe_enabled(dev, pipe)) {
885+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
886+ return 0;
887+ }
888+
889+ /*
890+ * High & low register fields aren't synchronized, so make sure
891+ * we get a low value that's stable across two reads of the high
892+ * register.
893+ */
894+ do {
895+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
896+ PIPE_FRAME_HIGH_SHIFT);
897+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
898+ PIPE_FRAME_LOW_SHIFT);
899+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
900+ PIPE_FRAME_HIGH_SHIFT);
901+ } while (high1 != high2);
902+
903+ count = (high1 << 8) | low;
904+
905+ return count;
906+}
907+
908 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
909 {
910 struct drm_device *dev = (struct drm_device *) arg;
911 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
912- u32 pipea_stats, pipeb_stats;
913 u32 iir;
914-
915- pipea_stats = I915_READ(PIPEASTAT);
916- pipeb_stats = I915_READ(PIPEBSTAT);
917+ u32 pipea_stats, pipeb_stats;
918+ int vblank = 0;
919
920 if (dev->pdev->msi_enabled)
921 I915_WRITE(IMR, ~0);
922 iir = I915_READ(IIR);
923
924- DRM_DEBUG("iir=%08x\n", iir);
925-
926 if (iir == 0) {
927 if (dev->pdev->msi_enabled) {
928 I915_WRITE(IMR, dev_priv->irq_mask_reg);
929@@ -276,48 +369,56 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
930 return IRQ_NONE;
931 }
932
933- I915_WRITE(PIPEASTAT, pipea_stats);
934- I915_WRITE(PIPEBSTAT, pipeb_stats);
935-
936- I915_WRITE(IIR, iir);
937- if (dev->pdev->msi_enabled)
938- I915_WRITE(IMR, dev_priv->irq_mask_reg);
939- (void) I915_READ(IIR); /* Flush posted writes */
940-
941- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
942-
943- if (iir & I915_USER_INTERRUPT)
944- DRM_WAKEUP(&dev_priv->irq_queue);
945-
946- if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
947- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
948- int vblank_pipe = dev_priv->vblank_pipe;
949-
950- if ((vblank_pipe &
951- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
952- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
953- if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
954- atomic_inc(&dev->vbl_received);
955- if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
956- atomic_inc(&dev->vbl_received2);
957- } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
958- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
959- ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
960- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
961- atomic_inc(&dev->vbl_received);
962+ /*
963+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
964+ * we may get extra interrupts.
965+ */
966+ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
967+ pipea_stats = I915_READ(PIPEASTAT);
968+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
969+ pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
970+ PIPE_VBLANK_INTERRUPT_ENABLE);
971+ else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
972+ PIPE_VBLANK_INTERRUPT_STATUS)) {
973+ vblank++;
974+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
975+ }
976
977- DRM_WAKEUP(&dev->vbl_queue);
978- drm_vbl_send_signals(dev);
979+ I915_WRITE(PIPEASTAT, pipea_stats);
980+ }
981+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
982+ pipeb_stats = I915_READ(PIPEBSTAT);
983+ /* Ack the event */
984+ I915_WRITE(PIPEBSTAT, pipeb_stats);
985+
986+ /* The vblank interrupt gets enabled even if we didn't ask for
987+ it, so make sure it's shut down again */
988+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
989+ pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
990+ PIPE_VBLANK_INTERRUPT_ENABLE);
991+ else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
992+ PIPE_VBLANK_INTERRUPT_STATUS)) {
993+ vblank++;
994+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
995+ }
996
997- if (dev_priv->swaps_pending > 0)
998- drm_locked_tasklet(dev, i915_vblank_tasklet);
999+ if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
1000+ opregion_asle_intr(dev);
1001+ I915_WRITE(PIPEBSTAT, pipeb_stats);
1002 }
1003
1004 if (iir & I915_ASLE_INTERRUPT)
1005 opregion_asle_intr(dev);
1006
1007- if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
1008- opregion_asle_intr(dev);
1009+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1010+
1011+ if (dev->pdev->msi_enabled)
1012+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
1013+ I915_WRITE(IIR, iir);
1014+ (void) I915_READ(IIR);
1015+
1016+ if (vblank && dev_priv->swaps_pending > 0)
1017+ drm_locked_tasklet(dev, i915_vblank_tasklet);
1018
1019 return IRQ_HANDLED;
1020 }
1021@@ -358,7 +459,7 @@ static void i915_user_irq_get(struct drm_device *dev)
1022 spin_unlock(&dev_priv->user_irq_lock);
1023 }
1024
1025-static void i915_user_irq_put(struct drm_device *dev)
1026+void i915_user_irq_put(struct drm_device *dev)
1027 {
1028 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1029
1030@@ -395,41 +496,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
1031 }
1032
1033 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1034- return ret;
1035-}
1036-
1037-static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
1038- atomic_t *counter)
1039-{
1040- drm_i915_private_t *dev_priv = dev->dev_private;
1041- unsigned int cur_vblank;
1042- int ret = 0;
1043-
1044- if (!dev_priv) {
1045- DRM_ERROR("called with no initialization\n");
1046- return -EINVAL;
1047- }
1048-
1049- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
1050- (((cur_vblank = atomic_read(counter))
1051- - *sequence) <= (1<<23)));
1052-
1053- *sequence = cur_vblank;
1054
1055 return ret;
1056 }
1057
1058-
1059-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
1060-{
1061- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
1062-}
1063-
1064-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
1065-{
1066- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
1067-}
1068-
1069 /* Needs the lock as it touches the ring.
1070 */
1071 int i915_irq_emit(struct drm_device *dev, void *data,
1072@@ -472,40 +542,88 @@ int i915_irq_wait(struct drm_device *dev, void *data,
1073 return i915_wait_irq(dev, irqwait->irq_seq);
1074 }
1075
1076+int i915_enable_vblank(struct drm_device *dev, int plane)
1077+{
1078+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1079+ int pipe = i915_get_pipe(dev, plane);
1080+ u32 pipestat_reg = 0;
1081+ u32 pipestat;
1082+
1083+ switch (pipe) {
1084+ case 0:
1085+ pipestat_reg = PIPEASTAT;
1086+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1087+ break;
1088+ case 1:
1089+ pipestat_reg = PIPEBSTAT;
1090+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1091+ break;
1092+ default:
1093+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
1094+ pipe);
1095+ break;
1096+ }
1097+
1098+ if (pipestat_reg) {
1099+ pipestat = I915_READ(pipestat_reg);
1100+ if (IS_I965G(dev))
1101+ pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
1102+ else
1103+ pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
1104+ /* Clear any stale interrupt status */
1105+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1106+ PIPE_VBLANK_INTERRUPT_STATUS);
1107+ I915_WRITE(pipestat_reg, pipestat);
1108+ }
1109+
1110+ return 0;
1111+}
1112+
1113+void i915_disable_vblank(struct drm_device *dev, int plane)
1114+{
1115+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1116+ int pipe = i915_get_pipe(dev, plane);
1117+ u32 pipestat_reg = 0;
1118+ u32 pipestat;
1119+
1120+ switch (pipe) {
1121+ case 0:
1122+ pipestat_reg = PIPEASTAT;
1123+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1124+ break;
1125+ case 1:
1126+ pipestat_reg = PIPEBSTAT;
1127+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1128+ break;
1129+ default:
1130+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
1131+ pipe);
1132+ break;
1133+ }
1134+
1135+ if (pipestat_reg) {
1136+ pipestat = I915_READ(pipestat_reg);
1137+ pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
1138+ PIPE_VBLANK_INTERRUPT_ENABLE);
1139+ /* Clear any stale interrupt status */
1140+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1141+ PIPE_VBLANK_INTERRUPT_STATUS);
1142+ I915_WRITE(pipestat_reg, pipestat);
1143+ }
1144+}
1145+
1146 /* Set the vblank monitor pipe
1147 */
1148 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
1149 struct drm_file *file_priv)
1150 {
1151 drm_i915_private_t *dev_priv = dev->dev_private;
1152- drm_i915_vblank_pipe_t *pipe = data;
1153- u32 enable_mask = 0, disable_mask = 0;
1154
1155 if (!dev_priv) {
1156 DRM_ERROR("called with no initialization\n");
1157 return -EINVAL;
1158 }
1159
1160- if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
1161- DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
1162- return -EINVAL;
1163- }
1164-
1165- if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
1166- enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1167- else
1168- disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1169-
1170- if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
1171- enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1172- else
1173- disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1174-
1175- i915_enable_irq(dev_priv, enable_mask);
1176- i915_disable_irq(dev_priv, disable_mask);
1177-
1178- dev_priv->vblank_pipe = pipe->pipe;
1179-
1180 return 0;
1181 }
1182
1183@@ -514,19 +632,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1184 {
1185 drm_i915_private_t *dev_priv = dev->dev_private;
1186 drm_i915_vblank_pipe_t *pipe = data;
1187- u16 flag;
1188
1189 if (!dev_priv) {
1190 DRM_ERROR("called with no initialization\n");
1191 return -EINVAL;
1192 }
1193
1194- flag = I915_READ(IMR);
1195- pipe->pipe = 0;
1196- if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1197- pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1198- if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1199- pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1200+ pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1201
1202 return 0;
1203 }
1204@@ -540,9 +652,10 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1205 drm_i915_private_t *dev_priv = dev->dev_private;
1206 drm_i915_vblank_swap_t *swap = data;
1207 drm_i915_vbl_swap_t *vbl_swap;
1208- unsigned int pipe, seqtype, curseq;
1209+ unsigned int pipe, seqtype, curseq, plane;
1210 unsigned long irqflags;
1211 struct list_head *list;
1212+ int ret;
1213
1214 if (!dev_priv) {
1215 DRM_ERROR("%s called with no initialization\n", __func__);
1216@@ -560,7 +673,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1217 return -EINVAL;
1218 }
1219
1220- pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1221+ plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1222+ pipe = i915_get_pipe(dev, plane);
1223
1224 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
1225
1226@@ -579,7 +693,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1227
1228 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
1229
1230- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
1231+ /*
1232+ * We take the ref here and put it when the swap actually completes
1233+ * in the tasklet.
1234+ */
1235+ ret = drm_vblank_get(dev, pipe);
1236+ if (ret)
1237+ return ret;
1238+ curseq = drm_vblank_count(dev, pipe);
1239
1240 if (seqtype == _DRM_VBLANK_RELATIVE)
1241 swap->sequence += curseq;
1242@@ -589,6 +710,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1243 swap->sequence = curseq + 1;
1244 } else {
1245 DRM_DEBUG("Missed target sequence\n");
1246+ drm_vblank_put(dev, pipe);
1247 return -EINVAL;
1248 }
1249 }
1250@@ -599,7 +721,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1251 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
1252
1253 if (vbl_swap->drw_id == swap->drawable &&
1254- vbl_swap->pipe == pipe &&
1255+ vbl_swap->plane == plane &&
1256 vbl_swap->sequence == swap->sequence) {
1257 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
1258 DRM_DEBUG("Already scheduled\n");
1259@@ -611,6 +733,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1260
1261 if (dev_priv->swaps_pending >= 100) {
1262 DRM_DEBUG("Too many swaps queued\n");
1263+ drm_vblank_put(dev, pipe);
1264 return -EBUSY;
1265 }
1266
1267@@ -618,13 +741,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1268
1269 if (!vbl_swap) {
1270 DRM_ERROR("Failed to allocate memory to queue swap\n");
1271+ drm_vblank_put(dev, pipe);
1272 return -ENOMEM;
1273 }
1274
1275 DRM_DEBUG("\n");
1276
1277 vbl_swap->drw_id = swap->drawable;
1278- vbl_swap->pipe = pipe;
1279+ vbl_swap->plane = plane;
1280 vbl_swap->sequence = swap->sequence;
1281
1282 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
1283@@ -643,28 +767,32 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1284 {
1285 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1286
1287- I915_WRITE(HWSTAM, 0xfffe);
1288- I915_WRITE(IMR, 0x0);
1289+ I915_WRITE(HWSTAM, 0xeffe);
1290+ I915_WRITE(IMR, 0xffffffff);
1291 I915_WRITE(IER, 0x0);
1292 }
1293
1294-void i915_driver_irq_postinstall(struct drm_device * dev)
1295+int i915_driver_irq_postinstall(struct drm_device *dev)
1296 {
1297 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1298+ int ret, num_pipes = 2;
1299
1300 spin_lock_init(&dev_priv->swaps_lock);
1301 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
1302 dev_priv->swaps_pending = 0;
1303
1304- if (!dev_priv->vblank_pipe)
1305- dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
1306-
1307 /* Set initial unmasked IRQs to just the selected vblank pipes. */
1308 dev_priv->irq_mask_reg = ~0;
1309- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1310- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1311- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1312- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1313+
1314+ ret = drm_vblank_init(dev, num_pipes);
1315+ if (ret)
1316+ return ret;
1317+
1318+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1319+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1320+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1321+
1322+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1323
1324 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
1325
1326@@ -673,22 +801,29 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
1327 (void) I915_READ(IER);
1328
1329 opregion_enable_asle(dev);
1330-
1331 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
1332+
1333+ return 0;
1334 }
1335
1336 void i915_driver_irq_uninstall(struct drm_device * dev)
1337 {
1338 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1339- u16 temp;
1340+ u32 temp;
1341
1342 if (!dev_priv)
1343 return;
1344
1345- I915_WRITE(HWSTAM, 0xffff);
1346- I915_WRITE(IMR, 0xffff);
1347+ dev_priv->vblank_pipe = 0;
1348+
1349+ I915_WRITE(HWSTAM, 0xffffffff);
1350+ I915_WRITE(IMR, 0xffffffff);
1351 I915_WRITE(IER, 0x0);
1352
1353+ temp = I915_READ(PIPEASTAT);
1354+ I915_WRITE(PIPEASTAT, temp);
1355+ temp = I915_READ(PIPEBSTAT);
1356+ I915_WRITE(PIPEBSTAT, temp);
1357 temp = I915_READ(IIR);
1358 I915_WRITE(IIR, temp);
1359 }
1360diff --git a/include/drm/drm.h b/include/drm/drm.h
1361index 0864c69..15e5503 100644
1362--- a/include/drm/drm.h
1363+++ b/include/drm/drm.h
1364@@ -454,6 +454,7 @@ struct drm_irq_busid {
1365 enum drm_vblank_seq_type {
1366 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
1367 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
1368+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
1369 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
1370 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
1371 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
1372@@ -486,6 +487,19 @@ union drm_wait_vblank {
1373 struct drm_wait_vblank_reply reply;
1374 };
1375
1376+#define _DRM_PRE_MODESET 1
1377+#define _DRM_POST_MODESET 2
1378+
1379+/**
1380+ * DRM_IOCTL_MODESET_CTL ioctl argument type
1381+ *
1382+ * \sa drmModesetCtl().
1383+ */
1384+struct drm_modeset_ctl {
1385+ uint32_t crtc;
1386+ uint32_t cmd;
1387+};
1388+
1389 /**
1390 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
1391 *
1392@@ -570,6 +584,7 @@ struct drm_set_version {
1393 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
1394 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
1395 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
1396+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
1397
1398 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
1399 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
1400diff --git a/include/drm/drmP.h b/include/drm/drmP.h
1401index 1c1b13e..e79ce07 100644
1402--- a/include/drm/drmP.h
1403+++ b/include/drm/drmP.h
1404@@ -580,11 +580,54 @@ struct drm_driver {
1405 int (*kernel_context_switch) (struct drm_device *dev, int old,
1406 int new);
1407 void (*kernel_context_switch_unlock) (struct drm_device *dev);
1408- int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
1409- int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
1410 int (*dri_library_name) (struct drm_device *dev, char *buf);
1411
1412 /**
1413+ * get_vblank_counter - get raw hardware vblank counter
1414+ * @dev: DRM device
1415+ * @crtc: counter to fetch
1416+ *
1417+ * Driver callback for fetching a raw hardware vblank counter
1418+ * for @crtc. If a device doesn't have a hardware counter, the
1419+ * driver can simply return the value of drm_vblank_count and
1420+ * make the enable_vblank() and disable_vblank() hooks into no-ops,
1421+ * leaving interrupts enabled at all times.
1422+ *
1423+ * Wraparound handling and loss of events due to modesetting is dealt
1424+ * with in the DRM core code.
1425+ *
1426+ * RETURNS
1427+ * Raw vblank counter value.
1428+ */
1429+ u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
1430+
1431+ /**
1432+ * enable_vblank - enable vblank interrupt events
1433+ * @dev: DRM device
1434+ * @crtc: which irq to enable
1435+ *
1436+ * Enable vblank interrupts for @crtc. If the device doesn't have
1437+ * a hardware vblank counter, this routine should be a no-op, since
1438+ * interrupts will have to stay on to keep the count accurate.
1439+ *
1440+ * RETURNS
1441+ * Zero on success, appropriate errno if the given @crtc's vblank
1442+ * interrupt cannot be enabled.
1443+ */
1444+ int (*enable_vblank) (struct drm_device *dev, int crtc);
1445+
1446+ /**
1447+ * disable_vblank - disable vblank interrupt events
1448+ * @dev: DRM device
1449+ * @crtc: which irq to enable
1450+ *
1451+ * Disable vblank interrupts for @crtc. If the device doesn't have
1452+ * a hardware vblank counter, this routine should be a no-op, since
1453+ * interrupts will have to stay on to keep the count accurate.
1454+ */
1455+ void (*disable_vblank) (struct drm_device *dev, int crtc);
1456+
1457+ /**
1458 * Called by \c drm_device_is_agp. Typically used to determine if a
1459 * card is really attached to AGP or not.
1460 *
1461@@ -601,7 +644,7 @@ struct drm_driver {
1462
1463 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
1464 void (*irq_preinstall) (struct drm_device *dev);
1465- void (*irq_postinstall) (struct drm_device *dev);
1466+ int (*irq_postinstall) (struct drm_device *dev);
1467 void (*irq_uninstall) (struct drm_device *dev);
1468 void (*reclaim_buffers) (struct drm_device *dev,
1469 struct drm_file * file_priv);
1470@@ -730,13 +773,28 @@ struct drm_device {
1471 /** \name VBLANK IRQ support */
1472 /*@{ */
1473
1474- wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
1475- atomic_t vbl_received;
1476- atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
1477+ /*
1478+ * At load time, disabling the vblank interrupt won't be allowed since
1479+ * old clients may not call the modeset ioctl and therefore misbehave.
1480+ * Once the modeset ioctl *has* been called though, we can safely
1481+ * disable them when unused.
1482+ */
1483+ int vblank_disable_allowed;
1484+
1485+ wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
1486+ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
1487 spinlock_t vbl_lock;
1488- struct list_head vbl_sigs; /**< signal list to send on VBLANK */
1489- struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */
1490- unsigned int vbl_pending;
1491+ struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
1492+ atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
1493+ atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
1494+ u32 *last_vblank; /* protected by dev->vbl_lock, used */
1495+ /* for wraparound handling */
1496+ int *vblank_enabled; /* so we don't call enable more than
1497+ once per disable */
1498+ int *vblank_inmodeset; /* Display driver is setting mode */
1499+ struct timer_list vblank_disable_timer;
1500+
1501+ u32 max_vblank_count; /**< size of vblank counter register */
1502 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
1503 void (*locked_tasklet_func)(struct drm_device *dev);
1504
1505@@ -757,6 +815,7 @@ struct drm_device {
1506 struct pci_controller *hose;
1507 #endif
1508 struct drm_sg_mem *sg; /**< Scatter gather memory */
1509+ int num_crtcs; /**< Number of CRTCs on this device */
1510 void *dev_private; /**< device private data */
1511 struct drm_sigdata sigdata; /**< For block_all_signals */
1512 sigset_t sigmask;
1513@@ -990,10 +1049,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev);
1514 extern void drm_driver_irq_postinstall(struct drm_device *dev);
1515 extern void drm_driver_irq_uninstall(struct drm_device *dev);
1516
1517+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
1518 extern int drm_wait_vblank(struct drm_device *dev, void *data,
1519- struct drm_file *file_priv);
1520+ struct drm_file *filp);
1521 extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
1522-extern void drm_vbl_send_signals(struct drm_device *dev);
1523+extern void drm_locked_tasklet(struct drm_device *dev,
1524+ void(*func)(struct drm_device *));
1525+extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1526+extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1527+extern int drm_vblank_get(struct drm_device *dev, int crtc);
1528+extern void drm_vblank_put(struct drm_device *dev, int crtc);
1529+/* Modesetting support */
1530+extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1531+ struct drm_file *file_priv);
1532 extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
1533
1534 /* AGP/GART support (drm_agpsupport.h) */