Subversion Repositories Kolibri OS

Rev

Rev 5271 | Rev 6088 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5060 serge 1
/*
2
 * drm_irq.c IRQ and vblank support
1963 serge 3
 *
4
 * \author Rickard E. (Rik) Faith 
5
 * \author Gareth Hughes 
6
 */
7
 
8
/*
9
 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
10
 *
11
 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
12
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
13
 * All Rights Reserved.
14
 *
15
 * Permission is hereby granted, free of charge, to any person obtaining a
16
 * copy of this software and associated documentation files (the "Software"),
17
 * to deal in the Software without restriction, including without limitation
18
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19
 * and/or sell copies of the Software, and to permit persons to whom the
20
 * Software is furnished to do so, subject to the following conditions:
21
 *
22
 * The above copyright notice and this permission notice (including the next
23
 * paragraph) shall be included in all copies or substantial portions of the
24
 * Software.
25
 *
26
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
29
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
30
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
31
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32
 * OTHER DEALINGS IN THE SOFTWARE.
33
 */
34
 
3031 serge 35
#include 
1963 serge 36
//#include "drm_trace.h"
5271 serge 37
#include "drm_internal.h"
1963 serge 38
 
39
//#include    /* For task queue support */
40
#include 
41
 
5271 serge 42
#include 
3031 serge 43
#include 
1963 serge 44
 
6084 serge 45
ktime_t ktime_get(void);
46
 
47
static inline ktime_t ktime_get_real(void)
48
{
49
	return ktime_get();
50
}
51
 
52
static inline ktime_t ktime_mono_to_real(ktime_t mono)
53
{
54
	return mono;
55
}
56
 
57
 
1963 serge 58
/* Access macro for slots in vblank timestamp ringbuffer. */
6084 serge 59
#define vblanktimestamp(dev, pipe, count) \
60
	((dev)->vblank[pipe].time[(count) % DRM_VBLANKTIME_RBSIZE])
1963 serge 61
 
62
/* Retry timestamp calculation up to 3 times to satisfy
63
 * drm_timestamp_precision before giving up.
64
 */
65
#define DRM_TIMESTAMP_MAXRETRIES 3
66
 
67
/* Threshold in nanoseconds for detection of redundant
68
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
69
 */
70
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
71
 
5271 serge 72
static bool
6084 serge 73
drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
5271 serge 74
			  struct timeval *tvblank, unsigned flags);
75
 
76
static unsigned int drm_timestamp_precision = 20;  /* Default to 20 usecs. */
77
 
5060 serge 78
/*
6084 serge 79
 * Default to use monotonic timestamps for wait-for-vblank and page-flip
80
 * complete events.
5060 serge 81
 */
6084 serge 82
unsigned int drm_timestamp_monotonic = 1;
1963 serge 83
 
6084 serge 84
static int drm_vblank_offdelay = 5000;    /* Default to 5000 msecs. */
5060 serge 85
 
6084 serge 86
module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
87
module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
88
module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
89
 
90
static void store_vblank(struct drm_device *dev, unsigned int pipe,
91
			 u32 vblank_count_inc,
92
			 struct timeval *t_vblank, u32 last)
93
{
94
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
95
	u32 tslot;
96
 
97
	assert_spin_locked(&dev->vblank_time_lock);
98
 
99
	vblank->last = last;
100
 
101
	/* All writers hold the spinlock, but readers are serialized by
102
	 * the latching of vblank->count below.
103
	 */
104
	tslot = vblank->count + vblank_count_inc;
105
	vblanktimestamp(dev, pipe, tslot) = *t_vblank;
106
 
107
	/*
108
	 * vblank timestamp updates are protected on the write side with
109
	 * vblank_time_lock, but on the read side done locklessly using a
110
	 * sequence-lock on the vblank counter. Ensure correct ordering using
111
	 * memory barrriers. We need the barrier both before and also after the
112
	 * counter update to synchronize with the next timestamp write.
113
	 * The read-side barriers for this are in drm_vblank_count_and_time.
114
	 */
115
	smp_wmb();
116
	vblank->count += vblank_count_inc;
117
	smp_wmb();
118
}
119
 
5060 serge 120
/**
6084 serge 121
 * drm_reset_vblank_timestamp - reset the last timestamp to the last vblank
122
 * @dev: DRM device
123
 * @pipe: index of CRTC for which to reset the timestamp
124
 *
125
 * Reset the stored timestamp for the current vblank count to correspond
126
 * to the last vblank occurred.
127
 *
128
 * Only to be called from drm_vblank_on().
129
 *
130
 * Note: caller must hold dev->vbl_lock since this reads & writes
131
 * device vblank fields.
132
 */
133
static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe)
134
{
135
	u32 cur_vblank;
136
	bool rc;
137
	struct timeval t_vblank;
138
	int count = DRM_TIMESTAMP_MAXRETRIES;
139
 
140
	spin_lock(&dev->vblank_time_lock);
141
 
142
	/*
143
	 * sample the current counter to avoid random jumps
144
	 * when drm_vblank_enable() applies the diff
145
	 */
146
	do {
147
		cur_vblank = dev->driver->get_vblank_counter(dev, pipe);
148
		rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0);
149
	} while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe) && --count > 0);
150
 
151
	/*
152
	 * Only reinitialize corresponding vblank timestamp if high-precision query
153
	 * available and didn't fail. Otherwise reinitialize delayed at next vblank
154
	 * interrupt and assign 0 for now, to mark the vblanktimestamp as invalid.
155
	 */
156
	if (!rc)
157
		t_vblank = (struct timeval) {0, 0};
158
 
159
	/*
160
	 * +1 to make sure user will never see the same
161
	 * vblank counter value before and after a modeset
162
	 */
163
	store_vblank(dev, pipe, 1, &t_vblank, cur_vblank);
164
 
165
	spin_unlock(&dev->vblank_time_lock);
166
}
167
 
168
/**
169
 * drm_update_vblank_count - update the master vblank counter
170
 * @dev: DRM device
171
 * @pipe: counter to update
172
 *
173
 * Call back into the driver to update the appropriate vblank counter
174
 * (specified by @pipe).  Deal with wraparound, if it occurred, and
175
 * update the last read value so we can deal with wraparound on the next
176
 * call if necessary.
177
 *
178
 * Only necessary when going from off->on, to account for frames we
179
 * didn't get an interrupt for.
180
 *
181
 * Note: caller must hold dev->vbl_lock since this reads & writes
182
 * device vblank fields.
183
 */
184
static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
185
				    unsigned long flags)
186
{
187
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
188
	u32 cur_vblank, diff;
189
	bool rc;
190
	struct timeval t_vblank;
191
	int count = DRM_TIMESTAMP_MAXRETRIES;
192
	int framedur_ns = vblank->framedur_ns;
193
 
194
	/*
195
	 * Interrupts were disabled prior to this call, so deal with counter
196
	 * wrap if needed.
197
	 * NOTE!  It's possible we lost a full dev->max_vblank_count + 1 events
198
	 * here if the register is small or we had vblank interrupts off for
199
	 * a long time.
200
	 *
201
	 * We repeat the hardware vblank counter & timestamp query until
202
	 * we get consistent results. This to prevent races between gpu
203
	 * updating its hardware counter while we are retrieving the
204
	 * corresponding vblank timestamp.
205
	 */
206
	do {
207
		cur_vblank = dev->driver->get_vblank_counter(dev, pipe);
208
		rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags);
209
	} while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe) && --count > 0);
210
 
211
	if (dev->max_vblank_count != 0) {
212
		/* trust the hw counter when it's around */
213
		diff = (cur_vblank - vblank->last) & dev->max_vblank_count;
214
	} else if (rc && framedur_ns) {
215
		const struct timeval *t_old;
216
		u64 diff_ns;
217
 
218
		t_old = &vblanktimestamp(dev, pipe, vblank->count);
219
		diff_ns = timeval_to_ns(&t_vblank) - timeval_to_ns(t_old);
220
 
221
		/*
222
		 * Figure out how many vblanks we've missed based
223
		 * on the difference in the timestamps and the
224
		 * frame/field duration.
225
		 */
226
		diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
227
 
228
		if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ)
229
			DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored."
230
				      " diff_ns = %lld, framedur_ns = %d)\n",
231
				      pipe, (long long) diff_ns, framedur_ns);
232
	} else {
233
		/* some kind of default for drivers w/o accurate vbl timestamping */
234
		diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0;
235
	}
236
 
237
	DRM_DEBUG_VBL("updating vblank count on crtc %u:"
238
		      " current=%u, diff=%u, hw=%u hw_last=%u\n",
239
		      pipe, vblank->count, diff, cur_vblank, vblank->last);
240
 
241
	if (diff == 0) {
242
		WARN_ON_ONCE(cur_vblank != vblank->last);
243
		return;
244
	}
245
 
246
	/*
247
	 * Only reinitialize corresponding vblank timestamp if high-precision query
248
	 * available and didn't fail, or we were called from the vblank interrupt.
249
	 * Otherwise reinitialize delayed at next vblank interrupt and assign 0
250
	 * for now, to mark the vblanktimestamp as invalid.
251
	 */
252
	if (!rc && (flags & DRM_CALLED_FROM_VBLIRQ) == 0)
253
		t_vblank = (struct timeval) {0, 0};
254
 
255
	store_vblank(dev, pipe, diff, &t_vblank, cur_vblank);
256
}
257
 
258
/*
259
 * Disable vblank irq's on crtc, make sure that last vblank count
260
 * of hardware and corresponding consistent software vblank counter
261
 * are preserved, even if there are any spurious vblank irq's after
262
 * disable.
263
 */
264
static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
265
{
266
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
267
	unsigned long irqflags;
268
 
269
	/* Prevent vblank irq processing while disabling vblank irqs,
270
	 * so no updates of timestamps or count can happen after we've
271
	 * disabled. Needed to prevent races in case of delayed irq's.
272
	 */
273
	spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
274
 
275
	/*
276
	 * Only disable vblank interrupts if they're enabled. This avoids
277
	 * calling the ->disable_vblank() operation in atomic context with the
278
	 * hardware potentially runtime suspended.
279
	 */
280
	if (vblank->enabled) {
281
		dev->driver->disable_vblank(dev, pipe);
282
		vblank->enabled = false;
283
	}
284
 
285
	/*
286
	 * Always update the count and timestamp to maintain the
287
	 * appearance that the counter has been ticking all along until
288
	 * this time. This makes the count account for the entire time
289
	 * between drm_vblank_on() and drm_vblank_off().
290
	 */
291
	drm_update_vblank_count(dev, pipe, 0);
292
 
293
	spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
294
}
295
 
296
static void vblank_disable_fn(unsigned long arg)
297
{
298
	struct drm_vblank_crtc *vblank = (void *)arg;
299
	struct drm_device *dev = vblank->dev;
300
	unsigned int pipe = vblank->pipe;
301
	unsigned long irqflags;
302
 
303
	if (!dev->vblank_disable_allowed)
304
		return;
305
 
306
	spin_lock_irqsave(&dev->vbl_lock, irqflags);
307
	if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
308
		DRM_DEBUG("disabling vblank on crtc %u\n", pipe);
309
		vblank_disable_and_save(dev, pipe);
310
	}
311
	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
312
}
313
 
314
/**
315
 * drm_vblank_cleanup - cleanup vblank support
316
 * @dev: DRM device
317
 *
318
 * This function cleans up any resources allocated in drm_vblank_init.
319
 */
320
void drm_vblank_cleanup(struct drm_device *dev)
321
{
322
	unsigned int pipe;
323
 
324
	/* Bail if the driver didn't call drm_vblank_init() */
325
	if (dev->num_crtcs == 0)
326
		return;
327
 
328
	for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
329
		struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
330
 
331
		WARN_ON(vblank->enabled &&
332
			drm_core_check_feature(dev, DRIVER_MODESET));
333
 
334
		del_timer_sync(&vblank->disable_timer);
335
	}
336
 
337
	kfree(dev->vblank);
338
 
339
	dev->num_crtcs = 0;
340
}
341
EXPORT_SYMBOL(drm_vblank_cleanup);
342
 
343
/**
5060 serge 344
 * drm_vblank_init - initialize vblank support
6084 serge 345
 * @dev: DRM device
346
 * @num_crtcs: number of CRTCs supported by @dev
5060 serge 347
 *
348
 * This function initializes vblank support for @num_crtcs display pipelines.
349
 *
350
 * Returns:
351
 * Zero on success or a negative error code on failure.
352
 */
6084 serge 353
int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
5060 serge 354
{
6084 serge 355
	int ret = -ENOMEM;
356
	unsigned int i;
5060 serge 357
 
358
	spin_lock_init(&dev->vbl_lock);
359
	spin_lock_init(&dev->vblank_time_lock);
360
 
361
	dev->num_crtcs = num_crtcs;
362
 
363
	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
364
	if (!dev->vblank)
365
		goto err;
366
 
367
	for (i = 0; i < num_crtcs; i++) {
5271 serge 368
		struct drm_vblank_crtc *vblank = &dev->vblank[i];
369
 
370
		vblank->dev = dev;
6084 serge 371
		vblank->pipe = i;
5271 serge 372
		init_waitqueue_head(&vblank->queue);
6084 serge 373
//		setup_timer(&vblank->disable_timer, vblank_disable_fn,
374
//			    (unsigned long)vblank);
5060 serge 375
	}
376
 
377
	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
378
 
379
	/* Driver specific high-precision vblank timestamping supported? */
380
	if (dev->driver->get_vblank_timestamp)
381
		DRM_INFO("Driver supports precise vblank timestamp query.\n");
382
	else
383
		DRM_INFO("No driver support for vblank timestamp query.\n");
384
 
6084 serge 385
	/* Must have precise timestamping for reliable vblank instant disable */
386
	if (dev->vblank_disable_immediate && !dev->driver->get_vblank_timestamp) {
387
		dev->vblank_disable_immediate = false;
388
		DRM_INFO("Setting vblank_disable_immediate to false because "
389
			 "get_vblank_timestamp == NULL\n");
390
	}
391
 
5060 serge 392
	dev->vblank_disable_allowed = false;
393
 
394
	return 0;
395
 
396
err:
5271 serge 397
	dev->num_crtcs = 0;
5060 serge 398
	return ret;
399
}
400
EXPORT_SYMBOL(drm_vblank_init);
401
 
402
 
6084 serge 403
 
4075 Serge 404
irqreturn_t device_irq_handler(struct drm_device *dev)
405
{
406
 
4104 Serge 407
//    printf("video irq\n");
4075 Serge 408
 
409
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
410
 
411
    return dev->driver->irq_handler(0, dev);
412
}
413
 
414
/**
5060 serge 415
 * drm_irq_install - install IRQ handler
416
 * @dev: DRM device
417
 * @irq: IRQ number to install the handler for
4075 Serge 418
 *
5060 serge 419
 * Initializes the IRQ related data. Installs the handler, calling the driver
420
 * irq_preinstall() and irq_postinstall() functions before and after the
421
 * installation.
4075 Serge 422
 *
5060 serge 423
 * This is the simplified helper interface provided for drivers with no special
424
 * needs. Drivers which need to install interrupt handlers for multiple
425
 * interrupts must instead set drm_device->irq_enabled to signal the DRM core
426
 * that vblank interrupts are available.
427
 *
428
 * Returns:
429
 * Zero on success or a negative error code on failure.
4075 Serge 430
 */
5060 serge 431
int drm_irq_install(struct drm_device *dev, int irq)
4075 Serge 432
{
433
	int ret;
6084 serge 434
	unsigned long sh_flags = 0;
4075 Serge 435
 
4293 Serge 436
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
437
		return -EINVAL;
4075 Serge 438
 
5060 serge 439
	if (irq == 0)
4075 Serge 440
		return -EINVAL;
441
 
6084 serge 442
	/* Driver must have been initialized */
5060 serge 443
	if (!dev->dev_private)
6084 serge 444
		return -EINVAL;
4075 Serge 445
 
5060 serge 446
	if (dev->irq_enabled)
6084 serge 447
		return -EBUSY;
4560 Serge 448
	dev->irq_enabled = true;
4075 Serge 449
 
5060 serge 450
	DRM_DEBUG("irq=%d\n", irq);
4075 Serge 451
 
6084 serge 452
	/* Before installing handler */
453
	if (dev->driver->irq_preinstall)
454
		dev->driver->irq_preinstall(dev);
4075 Serge 455
 
5060 serge 456
    ret = !AttachIntHandler(irq, device_irq_handler, (u32)dev);
4075 Serge 457
 
6084 serge 458
	/* After installing handler */
459
	if (dev->driver->irq_postinstall)
460
		ret = dev->driver->irq_postinstall(dev);
4075 Serge 461
 
6084 serge 462
	if (ret < 0) {
5060 serge 463
		dev->irq_enabled = false;
464
	} else {
465
		dev->irq = irq;
6084 serge 466
	}
4075 Serge 467
 
5271 serge 468
    u16 cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
4075 Serge 469
    cmd&= ~(1<<10);
470
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
471
 
472
    return ret;
473
}
474
EXPORT_SYMBOL(drm_irq_install);
475
 
476
 
1963 serge 477
 
478
 
479
 
480
/**
5060 serge 481
 * drm_calc_timestamping_constants - calculate vblank timestamp constants
482
 * @crtc: drm_crtc whose timestamp constants should be updated.
483
 * @mode: display mode containing the scanout timings
1963 serge 484
 *
4560 Serge 485
 * Calculate and store various constants which are later
486
 * needed by vblank and swap-completion timestamping, e.g,
487
 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
5060 serge 488
 * derived from CRTC's true scanout timing, so they take
4560 Serge 489
 * things like panel scaling or other adjustments into account.
1963 serge 490
 */
4560 Serge 491
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
492
				     const struct drm_display_mode *mode)
1963 serge 493
{
6084 serge 494
	struct drm_device *dev = crtc->dev;
495
	unsigned int pipe = drm_crtc_index(crtc);
496
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
497
	int linedur_ns = 0, framedur_ns = 0;
4560 Serge 498
	int dotclock = mode->crtc_clock;
1963 serge 499
 
6084 serge 500
	if (!dev->num_crtcs)
501
		return;
502
 
503
	if (WARN_ON(pipe >= dev->num_crtcs))
504
		return;
505
 
4560 Serge 506
	/* Valid dotclock? */
507
	if (dotclock > 0) {
508
		int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
1963 serge 509
 
4560 Serge 510
		/*
511
		 * Convert scanline length in pixels and video
6084 serge 512
		 * dot clock to line duration and frame duration
513
		 * in nanoseconds:
514
		 */
4560 Serge 515
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
516
		framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
1963 serge 517
 
4560 Serge 518
		/*
519
		 * Fields of interlaced scanout modes are only half a frame duration.
1963 serge 520
		 */
4560 Serge 521
		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
522
			framedur_ns /= 2;
1963 serge 523
	} else
6084 serge 524
		DRM_ERROR("crtc %u: Can't calculate constants, dotclock = 0!\n",
1963 serge 525
			  crtc->base.id);
526
 
6084 serge 527
	vblank->linedur_ns  = linedur_ns;
528
	vblank->framedur_ns = framedur_ns;
1963 serge 529
 
6084 serge 530
	DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
4560 Serge 531
		  crtc->base.id, mode->crtc_htotal,
532
		  mode->crtc_vtotal, mode->crtc_vdisplay);
6084 serge 533
	DRM_DEBUG("crtc %u: clock %d kHz framedur %d linedur %d\n",
534
		  crtc->base.id, dotclock, framedur_ns, linedur_ns);
1963 serge 535
}
4293 Serge 536
EXPORT_SYMBOL(drm_calc_timestamping_constants);
1963 serge 537
 
4293 Serge 538
/**
5060 serge 539
 * drm_calc_vbltimestamp_from_scanoutpos - precise vblank timestamp helper
540
 * @dev: DRM device
6084 serge 541
 * @pipe: index of CRTC whose vblank timestamp to retrieve
5060 serge 542
 * @max_error: Desired maximum allowable error in timestamps (nanosecs)
543
 *             On return contains true maximum error of timestamp
544
 * @vblank_time: Pointer to struct timeval which should receive the timestamp
545
 * @flags: Flags to pass to driver:
546
 *         0 = Default,
547
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
548
 * @mode: mode which defines the scanout timings
4293 Serge 549
 *
5060 serge 550
 * Implements calculation of exact vblank timestamps from given drm_display_mode
551
 * timings and current video scanout position of a CRTC. This can be called from
552
 * within get_vblank_timestamp() implementation of a kms driver to implement the
553
 * actual timestamping.
554
 *
4293 Serge 555
 * Should return timestamps conforming to the OML_sync_control OpenML
556
 * extension specification. The timestamp corresponds to the end of
557
 * the vblank interval, aka start of scanout of topmost-leftmost display
558
 * pixel in the following video frame.
559
 *
560
 * Requires support for optional dev->driver->get_scanout_position()
561
 * in kms driver, plus a bit of setup code to provide a drm_display_mode
562
 * that corresponds to the true scanout timing.
563
 *
564
 * The current implementation only handles standard video modes. It
565
 * returns as no operation if a doublescan or interlaced video mode is
566
 * active. Higher level code is expected to handle this.
567
 *
5060 serge 568
 * Returns:
569
 * Negative value on error, failure or if not supported in current
4293 Serge 570
 * video mode:
571
 *
5060 serge 572
 * -EINVAL   - Invalid CRTC.
4293 Serge 573
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
574
 * -ENOTSUPP - Function not supported in current display mode.
575
 * -EIO      - Failed, e.g., due to failed scanout position query.
576
 *
577
 * Returns or'ed positive status flags on success:
578
 *
579
 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
580
 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
581
 *
582
 */
6084 serge 583
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
584
					  unsigned int pipe,
4293 Serge 585
					  int *max_error,
586
					  struct timeval *vblank_time,
587
					  unsigned flags,
4560 Serge 588
					  const struct drm_display_mode *mode)
4293 Serge 589
{
590
	struct timeval tv_etime;
6084 serge 591
	ktime_t stime, etime;
592
	unsigned int vbl_status;
593
	int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
4293 Serge 594
	int vpos, hpos, i;
6084 serge 595
	int delta_ns, duration_ns;
3031 serge 596
 
6084 serge 597
	if (pipe >= dev->num_crtcs) {
598
		DRM_ERROR("Invalid crtc %u\n", pipe);
4293 Serge 599
		return -EINVAL;
600
	}
601
 
602
	/* Scanout position query not supported? Should not happen. */
603
	if (!dev->driver->get_scanout_position) {
604
		DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
605
		return -EIO;
606
	}
607
 
608
	/* If mode timing undefined, just return as no-op:
609
	 * Happens during initial modesetting of a crtc.
610
	 */
6084 serge 611
	if (mode->crtc_clock == 0) {
612
		DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
4293 Serge 613
		return -EAGAIN;
614
	}
615
 
6084 serge 616
	/* Get current scanout position with system timestamp.
617
	 * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times
618
	 * if single query takes longer than max_error nanoseconds.
619
	 *
620
	 * This guarantees a tight bound on maximum error if
621
	 * code gets preempted or delayed for some reason.
622
	 */
623
	for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) {
624
		/*
625
		 * Get vertical and horizontal scanout position vpos, hpos,
626
		 * and bounding timestamps stime, etime, pre/post query.
627
		 */
628
		vbl_status = dev->driver->get_scanout_position(dev, pipe, flags,
629
							       &vpos, &hpos,
630
							       &stime, &etime,
631
							       mode);
632
 
633
		/* Return as no-op if scanout query unsupported or failed. */
634
		if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
635
			DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n",
636
				  pipe, vbl_status);
637
			return -EIO;
638
		}
639
 
640
		/* Compute uncertainty in timestamp of scanout position query. */
641
		duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
642
 
643
		/* Accept result with <  max_error nsecs timing uncertainty. */
644
		if (duration_ns <= *max_error)
645
			break;
646
	}
647
 
648
	/* Noisy system timing? */
649
	if (i == DRM_TIMESTAMP_MAXRETRIES) {
650
		DRM_DEBUG("crtc %u: Noisy timestamp %d us > %d us [%d reps].\n",
651
			  pipe, duration_ns/1000, *max_error/1000, i);
652
	}
653
 
654
	/* Return upper bound of timestamp precision error. */
655
	*max_error = duration_ns;
656
 
657
	/* Check if in vblank area:
658
	 * vpos is >=0 in video scanout area, but negative
659
	 * within vblank area, counting down the number of lines until
660
	 * start of scanout.
661
	 */
662
	if (vbl_status & DRM_SCANOUTPOS_IN_VBLANK)
663
		ret |= DRM_VBLANKTIME_IN_VBLANK;
664
 
665
	/* Convert scanout position into elapsed time at raw_time query
666
	 * since start of scanout at first display scanline. delta_ns
667
	 * can be negative if start of scanout hasn't happened yet.
668
	 */
669
	delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos),
670
			   mode->crtc_clock);
671
 
672
	if (!drm_timestamp_monotonic)
673
		etime = ktime_mono_to_real(etime);
674
 
675
	/* save this only for debugging purposes */
676
	tv_etime = ktime_to_timeval(etime);
677
	/* Subtract time delta from raw timestamp to get final
678
	 * vblank_time timestamp for end of vblank.
679
	 */
680
	if (delta_ns < 0)
681
		etime = ktime_add_ns(etime, -delta_ns);
682
	else
683
		etime = ktime_sub_ns(etime, delta_ns);
684
	*vblank_time = ktime_to_timeval(etime);
685
 
686
	DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
687
		      pipe, vbl_status, hpos, vpos,
688
		      (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
689
		      (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
690
		      duration_ns/1000, i);
691
 
692
	return ret;
4293 Serge 693
}
694
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
695
 
6084 serge 696
static struct timeval get_drm_timestamp(void)
697
{
698
	ktime_t now;
699
 
700
	now = drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
701
	return ktime_to_timeval(now);
702
}
703
 
5060 serge 704
/**
6084 serge 705
 * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent
706
 *                             vblank interval
707
 * @dev: DRM device
708
 * @pipe: index of CRTC whose vblank timestamp to retrieve
709
 * @tvblank: Pointer to target struct timeval which should receive the timestamp
710
 * @flags: Flags to pass to driver:
711
 *         0 = Default,
712
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
713
 *
714
 * Fetches the system timestamp corresponding to the time of the most recent
715
 * vblank interval on specified CRTC. May call into kms-driver to
716
 * compute the timestamp with a high-precision GPU specific method.
717
 *
718
 * Returns zero if timestamp originates from uncorrected do_gettimeofday()
719
 * call, i.e., it isn't very precisely locked to the true vblank.
720
 *
721
 * Returns:
722
 * True if timestamp is considered to be very precise, false otherwise.
723
 */
724
static bool
725
drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
726
			  struct timeval *tvblank, unsigned flags)
727
{
728
	int ret;
729
 
730
	/* Define requested maximum error on timestamps (nanoseconds). */
731
	int max_error = (int) drm_timestamp_precision * 1000;
732
 
733
	/* Query driver if possible and precision timestamping enabled. */
734
	if (dev->driver->get_vblank_timestamp && (max_error > 0)) {
735
		ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error,
736
							tvblank, flags);
737
		if (ret > 0)
738
			return true;
739
	}
740
 
741
	/* GPU high precision timestamp query unsupported or failed.
742
	 * Return current monotonic/gettimeofday timestamp as best estimate.
743
	 */
744
	*tvblank = get_drm_timestamp();
745
 
746
	return false;
747
}
748
 
749
/**
750
 * drm_vblank_count - retrieve "cooked" vblank counter value
751
 * @dev: DRM device
752
 * @pipe: index of CRTC for which to retrieve the counter
753
 *
754
 * Fetches the "cooked" vblank count value that represents the number of
755
 * vblank events since the system was booted, including lost events due to
756
 * modesetting activity.
757
 *
758
 * This is the legacy version of drm_crtc_vblank_count().
759
 *
760
 * Returns:
761
 * The software vblank counter.
762
 */
763
u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
764
{
765
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
766
 
767
	if (WARN_ON(pipe >= dev->num_crtcs))
768
		return 0;
769
 
770
	return vblank->count;
771
}
772
EXPORT_SYMBOL(drm_vblank_count);
773
 
774
/**
775
 * drm_crtc_vblank_count - retrieve "cooked" vblank counter value
776
 * @crtc: which counter to retrieve
777
 *
778
 * Fetches the "cooked" vblank count value that represents the number of
779
 * vblank events since the system was booted, including lost events due to
780
 * modesetting activity.
781
 *
782
 * This is the native KMS version of drm_vblank_count().
783
 *
784
 * Returns:
785
 * The software vblank counter.
786
 */
787
u32 drm_crtc_vblank_count(struct drm_crtc *crtc)
788
{
789
	return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
790
}
791
EXPORT_SYMBOL(drm_crtc_vblank_count);
792
 
793
/**
794
 * drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the
795
 *     system timestamp corresponding to that vblank counter value.
796
 * @dev: DRM device
797
 * @pipe: index of CRTC whose counter to retrieve
798
 * @vblanktime: Pointer to struct timeval to receive the vblank timestamp.
799
 *
800
 * Fetches the "cooked" vblank count value that represents the number of
801
 * vblank events since the system was booted, including lost events due to
802
 * modesetting activity. Returns corresponding system timestamp of the time
803
 * of the vblank interval that corresponds to the current vblank counter value.
804
 *
805
 * This is the legacy version of drm_crtc_vblank_count_and_time().
806
 */
807
u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
808
			      struct timeval *vblanktime)
809
{
810
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
811
	int count = DRM_TIMESTAMP_MAXRETRIES;
812
	u32 cur_vblank;
813
 
814
	if (WARN_ON(pipe >= dev->num_crtcs))
815
		return 0;
816
 
817
	/*
818
	 * Vblank timestamps are read lockless. To ensure consistency the vblank
819
	 * counter is rechecked and ordering is ensured using memory barriers.
820
	 * This works like a seqlock. The write-side barriers are in store_vblank.
821
	 */
822
	do {
823
		cur_vblank = vblank->count;
824
		smp_rmb();
825
		*vblanktime = vblanktimestamp(dev, pipe, cur_vblank);
826
		smp_rmb();
827
	} while (cur_vblank != vblank->count && --count > 0);
828
 
829
	return cur_vblank;
830
}
831
EXPORT_SYMBOL(drm_vblank_count_and_time);
832
/**
833
 * drm_vblank_enable - enable the vblank interrupt on a CRTC
834
 * @dev: DRM device
835
 * @pipe: CRTC index
836
 *
837
 * Returns:
838
 * Zero on success or a negative error code on failure.
839
 */
840
static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
841
{
842
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
843
	int ret = 0;
844
 
845
	assert_spin_locked(&dev->vbl_lock);
846
 
847
	spin_lock(&dev->vblank_time_lock);
848
 
849
	if (!vblank->enabled) {
850
		/*
851
		 * Enable vblank irqs under vblank_time_lock protection.
852
		 * All vblank count & timestamp updates are held off
853
		 * until we are done reinitializing master counter and
854
		 * timestamps. Filtercode in drm_handle_vblank() will
855
		 * prevent double-accounting of same vblank interval.
856
		 */
857
		ret = dev->driver->enable_vblank(dev, pipe);
858
		DRM_DEBUG("enabling vblank on crtc %u, ret: %d\n", pipe, ret);
859
		if (ret)
860
			atomic_dec(&vblank->refcount);
861
		else {
862
			vblank->enabled = true;
863
			drm_update_vblank_count(dev, pipe, 0);
864
		}
865
	}
866
 
867
	spin_unlock(&dev->vblank_time_lock);
868
 
869
	return ret;
870
}
871
 
872
/**
5271 serge 873
 * drm_vblank_get - get a reference count on vblank events
874
 * @dev: DRM device
6084 serge 875
 * @pipe: index of CRTC to own
5271 serge 876
 *
877
 * Acquire a reference count on vblank events to avoid having them disabled
878
 * while in use.
879
 *
880
 * This is the legacy version of drm_crtc_vblank_get().
881
 *
882
 * Returns:
6084 serge 883
 * Zero on success or a negative error code on failure.
5271 serge 884
 */
6084 serge 885
int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
5271 serge 886
{
6084 serge 887
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
5271 serge 888
	unsigned long irqflags;
889
	int ret = 0;
890
 
6084 serge 891
	if (!dev->num_crtcs)
5271 serge 892
		return -EINVAL;
893
 
6084 serge 894
	if (WARN_ON(pipe >= dev->num_crtcs))
895
		return -EINVAL;
896
 
5271 serge 897
	spin_lock_irqsave(&dev->vbl_lock, irqflags);
898
	/* Going from 0->1 means we have to enable interrupts again */
899
	if (atomic_add_return(1, &vblank->refcount) == 1) {
6084 serge 900
		ret = drm_vblank_enable(dev, pipe);
5271 serge 901
	} else {
902
		if (!vblank->enabled) {
903
			atomic_dec(&vblank->refcount);
904
			ret = -EINVAL;
905
		}
906
	}
907
	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
6084 serge 908
 
5271 serge 909
	return ret;
910
}
911
EXPORT_SYMBOL(drm_vblank_get);
912
 
913
/**
914
 * drm_crtc_vblank_get - get a reference count on vblank events
915
 * @crtc: which CRTC to own
916
 *
917
 * Acquire a reference count on vblank events to avoid having them disabled
918
 * while in use.
919
 *
6084 serge 920
 * This is the native kms version of drm_vblank_get().
5271 serge 921
 *
922
 * Returns:
6084 serge 923
 * Zero on success or a negative error code on failure.
5271 serge 924
 */
925
int drm_crtc_vblank_get(struct drm_crtc *crtc)
926
{
927
	return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
928
}
929
EXPORT_SYMBOL(drm_crtc_vblank_get);
930
 
931
/**
6084 serge 932
 * drm_vblank_put - release ownership of vblank events
5271 serge 933
 * @dev: DRM device
6084 serge 934
 * @pipe: index of CRTC to release
5271 serge 935
 *
936
 * Release ownership of a given vblank counter, turning off interrupts
937
 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
938
 *
939
 * This is the legacy version of drm_crtc_vblank_put().
940
 */
6084 serge 941
void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
5271 serge 942
{
6084 serge 943
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
5271 serge 944
 
6084 serge 945
	if (WARN_ON(pipe >= dev->num_crtcs))
5271 serge 946
		return;
947
 
6084 serge 948
	if (WARN_ON(atomic_read(&vblank->refcount) == 0))
5271 serge 949
		return;
950
 
951
	/* Last user schedules interrupt disable */
952
	if (atomic_dec_and_test(&vblank->refcount)) {
953
		if (drm_vblank_offdelay == 0)
954
			return;
955
		else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
956
			vblank_disable_fn((unsigned long)vblank);
957
		else
958
			mod_timer(&vblank->disable_timer,
959
				  jiffies + ((drm_vblank_offdelay * HZ)/1000));
960
	}
961
}
962
EXPORT_SYMBOL(drm_vblank_put);
963
 
964
/**
965
 * drm_crtc_vblank_put - give up ownership of vblank events
966
 * @crtc: which counter to give up
967
 *
968
 * Release ownership of a given vblank counter, turning off interrupts
969
 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
970
 *
971
 * This is the native kms version of drm_vblank_put().
972
 */
973
void drm_crtc_vblank_put(struct drm_crtc *crtc)
974
{
975
	drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
976
}
977
EXPORT_SYMBOL(drm_crtc_vblank_put);
978
 
979
/**
980
 * drm_wait_one_vblank - wait for one vblank
981
 * @dev: DRM device
6084 serge 982
 * @pipe: CRTC index
5271 serge 983
 *
6084 serge 984
 * This waits for one vblank to pass on @pipe, using the irq driver interfaces.
985
 * It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
5271 serge 986
 * due to lack of driver support or because the crtc is off.
987
 */
6084 serge 988
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
5271 serge 989
{
990
#if 0
991
	int ret;
992
	u32 last;
993
 
994
	ret = drm_vblank_get(dev, crtc);
995
	if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
996
		return;
997
 
998
	last = drm_vblank_count(dev, crtc);
999
 
1000
	ret = wait_event_timeout(dev->vblank[crtc].queue,
1001
				 last != drm_vblank_count(dev, crtc),
1002
				 msecs_to_jiffies(100));
1003
 
1004
	WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc);
1005
 
1006
	drm_vblank_put(dev, crtc);
1007
#endif
1008
}
1009
EXPORT_SYMBOL(drm_wait_one_vblank);
1010
 
1011
/**
1012
 * drm_crtc_wait_one_vblank - wait for one vblank
1013
 * @crtc: DRM crtc
1014
 *
1015
 * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
1016
 * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
1017
 * due to lack of driver support or because the crtc is off.
1018
 */
1019
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
1020
{
1021
	drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
1022
}
1023
EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
1024
 
1025
/**
5060 serge 1026
 * drm_vblank_off - disable vblank events on a CRTC
1027
 * @dev: DRM device
6084 serge 1028
 * @pipe: CRTC index
5060 serge 1029
 *
1030
 * Drivers can use this function to shut down the vblank interrupt handling when
1031
 * disabling a crtc. This function ensures that the latest vblank frame count is
1032
 * stored so that drm_vblank_on() can restore it again.
1033
 *
1034
 * Drivers must use this function when the hardware vblank counter can get
1035
 * reset, e.g. when suspending.
1036
 *
1037
 * This is the legacy version of drm_crtc_vblank_off().
1038
 */
6084 serge 1039
void drm_vblank_off(struct drm_device *dev, unsigned int pipe)
5060 serge 1040
{
6084 serge 1041
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
5060 serge 1042
	struct drm_pending_vblank_event *e, *t;
1043
	struct timeval now;
1044
	unsigned long irqflags;
1045
	unsigned int seq;
4293 Serge 1046
 
5060 serge 1047
 
1048
}
1049
EXPORT_SYMBOL(drm_vblank_off);
1050
 
3031 serge 1051
/**
5060 serge 1052
 * drm_crtc_vblank_off - disable vblank events on a CRTC
1053
 * @crtc: CRTC in question
1054
 *
1055
 * Drivers can use this function to shut down the vblank interrupt handling when
1056
 * disabling a crtc. This function ensures that the latest vblank frame count is
1057
 * stored so that drm_vblank_on can restore it again.
1058
 *
1059
 * Drivers must use this function when the hardware vblank counter can get
1060
 * reset, e.g. when suspending.
1061
 *
1062
 * This is the native kms version of drm_vblank_off().
1063
 */
1064
void drm_crtc_vblank_off(struct drm_crtc *crtc)
1065
{
1066
	drm_vblank_off(crtc->dev, drm_crtc_index(crtc));
1067
}
1068
EXPORT_SYMBOL(drm_crtc_vblank_off);
1069
 
1070
/**
6084 serge 1071
 * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
1072
 * @crtc: CRTC in question
1073
 *
1074
 * Drivers can use this function to reset the vblank state to off at load time.
1075
 * Drivers should use this together with the drm_crtc_vblank_off() and
1076
 * drm_crtc_vblank_on() functions. The difference compared to
1077
 * drm_crtc_vblank_off() is that this function doesn't save the vblank counter
1078
 * and hence doesn't need to call any driver hooks.
1079
 */
1080
void drm_crtc_vblank_reset(struct drm_crtc *crtc)
1081
{
1082
	struct drm_device *dev = crtc->dev;
1083
	unsigned long irqflags;
1084
	unsigned int pipe = drm_crtc_index(crtc);
1085
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1086
 
1087
	spin_lock_irqsave(&dev->vbl_lock, irqflags);
1088
	/*
1089
	 * Prevent subsequent drm_vblank_get() from enabling the vblank
1090
	 * interrupt by bumping the refcount.
1091
	 */
1092
	if (!vblank->inmodeset) {
1093
		atomic_inc(&vblank->refcount);
1094
		vblank->inmodeset = 1;
1095
	}
1096
	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1097
 
1098
	WARN_ON(!list_empty(&dev->vblank_event_list));
1099
}
1100
EXPORT_SYMBOL(drm_crtc_vblank_reset);
1101
 
1102
/**
5060 serge 1103
 * drm_vblank_on - enable vblank events on a CRTC
1104
 * @dev: DRM device
6084 serge 1105
 * @pipe: CRTC index
5060 serge 1106
 *
1107
 * This functions restores the vblank interrupt state captured with
1108
 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
5271 serge 1109
 * drm_vblank_off() can be unbalanced and so can also be unconditionally called
5060 serge 1110
 * in driver load code to reflect the current hardware state of the crtc.
1111
 *
1112
 * This is the legacy version of drm_crtc_vblank_on().
1113
 */
6084 serge 1114
void drm_vblank_on(struct drm_device *dev, unsigned int pipe)
5060 serge 1115
{
6084 serge 1116
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
5060 serge 1117
	unsigned long irqflags;
1118
 
6084 serge 1119
    dbgprintf("%s pipe %d dev->num_crtcs %d\n", pipe,dev->num_crtcs);\
1120
 
1121
	if (WARN_ON(pipe >= dev->num_crtcs))
1122
		return;
1123
 
1124
	spin_lock_irqsave(&dev->vbl_lock, irqflags);
1125
	/* Drop our private "prevent drm_vblank_get" refcount */
1126
	if (vblank->inmodeset) {
1127
		atomic_dec(&vblank->refcount);
1128
		vblank->inmodeset = 0;
1129
	}
1130
 
1131
	drm_reset_vblank_timestamp(dev, pipe);
1132
 
1133
	/*
1134
	 * re-enable interrupts if there are users left, or the
1135
	 * user wishes vblank interrupts to be enabled all the time.
1136
	 */
1137
	if (atomic_read(&vblank->refcount) != 0 ||
1138
	    (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0))
1139
		WARN_ON(drm_vblank_enable(dev, pipe));
1140
	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5060 serge 1141
}
1142
EXPORT_SYMBOL(drm_vblank_on);
1143
 
1144
/**
1145
 * drm_crtc_vblank_on - enable vblank events on a CRTC
1146
 * @crtc: CRTC in question
1147
 *
1148
 * This functions restores the vblank interrupt state captured with
1149
 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
5271 serge 1150
 * drm_vblank_off() can be unbalanced and so can also be unconditionally called
5060 serge 1151
 * in driver load code to reflect the current hardware state of the crtc.
1152
 *
1153
 * This is the native kms version of drm_vblank_on().
1154
 */
1155
void drm_crtc_vblank_on(struct drm_crtc *crtc)
1156
{
1157
	drm_vblank_on(crtc->dev, drm_crtc_index(crtc));
1158
}
1159
EXPORT_SYMBOL(drm_crtc_vblank_on);
1160
 
1161
/**
3031 serge 1162
 * drm_vblank_pre_modeset - account for vblanks across mode sets
1163
 * @dev: DRM device
6084 serge 1164
 * @pipe: CRTC index
3031 serge 1165
 *
1166
 * Account for vblank events across mode setting events, which will likely
1167
 * reset the hardware frame counter.
5060 serge 1168
 *
1169
 * This is done by grabbing a temporary vblank reference to ensure that the
1170
 * vblank interrupt keeps running across the modeset sequence. With this the
1171
 * software-side vblank frame counting will ensure that there are no jumps or
1172
 * discontinuities.
1173
 *
1174
 * Unfortunately this approach is racy and also doesn't work when the vblank
1175
 * interrupt stops running, e.g. across system suspend resume. It is therefore
1176
 * highly recommended that drivers use the newer drm_vblank_off() and
1177
 * drm_vblank_on() instead. drm_vblank_pre_modeset() only works correctly when
1178
 * using "cooked" software vblank frame counters and not relying on any hardware
1179
 * counters.
1180
 *
1181
 * Drivers must call drm_vblank_post_modeset() when re-enabling the same crtc
1182
 * again.
3031 serge 1183
 */
6084 serge 1184
void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe)
3031 serge 1185
{
6084 serge 1186
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
5271 serge 1187
 
6084 serge 1188
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
1189
	if (!dev->num_crtcs)
5271 serge 1190
		return;
1191
 
6084 serge 1192
	if (WARN_ON(pipe >= dev->num_crtcs))
1193
		return;
1194
 
1195
	/*
1196
	 * To avoid all the problems that might happen if interrupts
1197
	 * were enabled/disabled around or between these calls, we just
1198
	 * have the kernel take a reference on the CRTC (just once though
1199
	 * to avoid corrupting the count if multiple, mismatch calls occur),
1200
	 * so that interrupts remain enabled in the interim.
1201
	 */
5271 serge 1202
	if (!vblank->inmodeset) {
1203
		vblank->inmodeset = 0x1;
6084 serge 1204
		if (drm_vblank_get(dev, pipe) == 0)
5271 serge 1205
			vblank->inmodeset |= 0x2;
6084 serge 1206
	}
3031 serge 1207
}
1208
EXPORT_SYMBOL(drm_vblank_pre_modeset);
1209
 
5060 serge 1210
/**
1211
 * drm_vblank_post_modeset - undo drm_vblank_pre_modeset changes
1212
 * @dev: DRM device
6084 serge 1213
 * @pipe: CRTC index
5060 serge 1214
 *
1215
 * This function again drops the temporary vblank reference acquired in
1216
 * drm_vblank_pre_modeset.
1217
 */
6084 serge 1218
void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe)
3031 serge 1219
{
6084 serge 1220
	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1221
	unsigned long irqflags;
3031 serge 1222
 
4075 Serge 1223
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
1224
	if (!dev->num_crtcs)
1225
		return;
1226
 
6084 serge 1227
	if (WARN_ON(pipe >= dev->num_crtcs))
1228
		return;
1229
 
5271 serge 1230
	if (vblank->inmodeset) {
6084 serge 1231
		spin_lock_irqsave(&dev->vbl_lock, irqflags);
4560 Serge 1232
		dev->vblank_disable_allowed = true;
6084 serge 1233
		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
3031 serge 1234
 
5271 serge 1235
		if (vblank->inmodeset & 0x2)
6084 serge 1236
			drm_vblank_put(dev, pipe);
3031 serge 1237
 
5271 serge 1238
		vblank->inmodeset = 0;
6084 serge 1239
	}
3031 serge 1240
}
1241
EXPORT_SYMBOL(drm_vblank_post_modeset);
5271 serge 1242
 
1243
 
6084 serge 1244
u64 div64_u64(u64 dividend, u64 divisor)
1245
{
1246
        u32 high, d;
1247
 
1248
        high = divisor >> 32;
1249
        if (high) {
1250
                unsigned int shift = fls(high);
1251
 
1252
                d = divisor >> shift;
1253
                dividend >>= shift;
1254
        } else
1255
                d = divisor;
1256
 
1257
        return div_u64(dividend, d);
1258
}