Subversion Repositories Kolibri OS

Rev

Rev 4560 | Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4560 Rev 5060
Line 1... Line 1...
1
/**
1
/*
2
 * \file drm_irq.c
-
 
3
 * IRQ support
2
 * drm_irq.c IRQ and vblank support
4
 *
3
 *
5
 * \author Rickard E. (Rik) Faith 
4
 * \author Rickard E. (Rik) Faith 
6
 * \author Gareth Hughes 
5
 * \author Gareth Hughes 
7
 */
6
 */
Line 55... Line 54...
55
/* Threshold in nanoseconds for detection of redundant
54
/* Threshold in nanoseconds for detection of redundant
56
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
55
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
57
 */
56
 */
58
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
57
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
Line -... Line 58...
-
 
58
 
-
 
59
/*
-
 
60
 * Clear vblank timestamp buffer for a crtc.
-
 
61
 */
-
 
62
 
-
 
63
 
-
 
64
#if 0
-
 
65
/**
-
 
66
 * drm_vblank_init - initialize vblank support
-
 
67
 * @dev: drm_device
-
 
68
 * @num_crtcs: number of crtcs supported by @dev
-
 
69
 *
-
 
70
 * This function initializes vblank support for @num_crtcs display pipelines.
-
 
71
 *
-
 
72
 * Returns:
-
 
73
 * Zero on success or a negative error code on failure.
-
 
74
 */
-
 
75
int drm_vblank_init(struct drm_device *dev, int num_crtcs)
-
 
76
{
-
 
77
	int i, ret = -ENOMEM;
-
 
78
 
-
 
79
	spin_lock_init(&dev->vbl_lock);
-
 
80
	spin_lock_init(&dev->vblank_time_lock);
-
 
81
 
-
 
82
	dev->num_crtcs = num_crtcs;
-
 
83
 
-
 
84
	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
-
 
85
	if (!dev->vblank)
-
 
86
		goto err;
-
 
87
 
-
 
88
	for (i = 0; i < num_crtcs; i++) {
-
 
89
		dev->vblank[i].dev = dev;
-
 
90
		dev->vblank[i].crtc = i;
-
 
91
		init_waitqueue_head(&dev->vblank[i].queue);
-
 
92
		setup_timer(&dev->vblank[i].disable_timer, vblank_disable_fn,
-
 
93
			    (unsigned long)&dev->vblank[i]);
-
 
94
	}
-
 
95
 
-
 
96
	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
-
 
97
 
-
 
98
	/* Driver specific high-precision vblank timestamping supported? */
-
 
99
	if (dev->driver->get_vblank_timestamp)
-
 
100
		DRM_INFO("Driver supports precise vblank timestamp query.\n");
-
 
101
	else
-
 
102
		DRM_INFO("No driver support for vblank timestamp query.\n");
-
 
103
 
-
 
104
	dev->vblank_disable_allowed = false;
-
 
105
 
-
 
106
	return 0;
-
 
107
 
-
 
108
err:
-
 
109
	drm_vblank_cleanup(dev);
-
 
110
	return ret;
-
 
111
}
-
 
112
EXPORT_SYMBOL(drm_vblank_init);
-
 
113
 
Line 59... Line 114...
59
 
114
#endif
60
 
115
 
Line 61... Line 116...
61
irqreturn_t device_irq_handler(struct drm_device *dev)
116
irqreturn_t device_irq_handler(struct drm_device *dev)
Line 67... Line 122...
67
 
122
 
68
    return dev->driver->irq_handler(0, dev);
123
    return dev->driver->irq_handler(0, dev);
Line 69... Line 124...
69
}
124
}
70
 
125
 
71
/**
-
 
72
 * Install IRQ handler.
126
/**
-
 
127
 * drm_irq_install - install IRQ handler
73
 *
128
 * @dev: DRM device
74
 * \param dev DRM device.
129
 * @irq: IRQ number to install the handler for
75
 *
130
 *
-
 
131
 * Initializes the IRQ related data. Installs the handler, calling the driver
-
 
132
 * irq_preinstall() and irq_postinstall() functions before and after the
-
 
133
 * installation.
-
 
134
 *
-
 
135
 * This is the simplified helper interface provided for drivers with no special
76
 * Initializes the IRQ related data. Installs the handler, calling the driver
136
 * needs. Drivers which need to install interrupt handlers for multiple
-
 
137
 * interrupts must instead set drm_device->irq_enabled to signal the DRM core
-
 
138
 * that vblank interrupts are available.
-
 
139
 *
77
 * \c irq_preinstall() and \c irq_postinstall() functions
140
 * Returns:
78
 * before and after the installation.
141
 * Zero on success or a negative error code on failure.
79
 */
142
 */
80
int drm_irq_install(struct drm_device *dev)
143
int drm_irq_install(struct drm_device *dev, int irq)
81
{
144
{
82
	int ret;
-
 
Line 83... Line 145...
83
    unsigned long sh_flags = 0;
145
	int ret;
84
	char *irqname;
146
    unsigned long sh_flags = 0;
Line 85... Line 147...
85
 
147
 
86
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
148
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
Line 87... Line -...
87
		return -EINVAL;
-
 
88
 
-
 
89
	if (drm_dev_to_irq(dev) == 0)
149
		return -EINVAL;
90
		return -EINVAL;
150
 
91
 
-
 
92
    mutex_lock(&dev->struct_mutex);
151
	if (irq == 0)
93
 
-
 
Line 94... Line 152...
94
    /* Driver must have been initialized */
152
		return -EINVAL;
95
    if (!dev->dev_private) {
-
 
96
            mutex_unlock(&dev->struct_mutex);
153
 
97
            return -EINVAL;
-
 
98
    }
154
    /* Driver must have been initialized */
99
 
-
 
Line 100... Line 155...
100
    if (dev->irq_enabled) {
155
	if (!dev->dev_private)
Line 101... Line 156...
101
            mutex_unlock(&dev->struct_mutex);
156
            return -EINVAL;
102
            return -EBUSY;
157
 
103
    }
158
	if (dev->irq_enabled)
Line 104... Line 159...
104
	dev->irq_enabled = true;
159
            return -EBUSY;
Line 105... Line 160...
105
    mutex_unlock(&dev->struct_mutex);
160
	dev->irq_enabled = true;
106
 
161
 
107
    DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
162
	DRM_DEBUG("irq=%d\n", irq);
Line 108... Line 163...
108
 
163
 
109
    /* Before installing handler */
164
    /* Before installing handler */
110
    if (dev->driver->irq_preinstall)
165
    if (dev->driver->irq_preinstall)
-
 
166
            dev->driver->irq_preinstall(dev);
-
 
167
 
111
            dev->driver->irq_preinstall(dev);
168
    ret = !AttachIntHandler(irq, device_irq_handler, (u32)dev);
Line 112... Line 169...
112
 
169
 
113
    ret = !AttachIntHandler(drm_dev_to_irq(dev), device_irq_handler, (u32)dev);
170
    /* After installing handler */
114
 
171
    if (dev->driver->irq_postinstall)
Line 147... Line 204...
147
 
204
 
148
        return div_u64(dividend, d);
205
        return div_u64(dividend, d);
Line 149... Line 206...
149
}
206
}
150
 
207
 
151
/**
-
 
152
 * drm_calc_timestamping_constants - Calculate vblank timestamp constants
208
/**
153
 *
209
 * drm_calc_timestamping_constants - calculate vblank timestamp constants
154
 * @crtc drm_crtc whose timestamp constants should be updated.
210
 * @crtc: drm_crtc whose timestamp constants should be updated.
155
 * @mode display mode containing the scanout timings
211
 * @mode: display mode containing the scanout timings
156
 *
212
 *
157
 * Calculate and store various constants which are later
213
 * Calculate and store various constants which are later
158
 * needed by vblank and swap-completion timestamping, e.g,
214
 * needed by vblank and swap-completion timestamping, e.g,
159
 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
215
 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
160
 * derived from crtc's true scanout timing, so they take
216
 * derived from CRTC's true scanout timing, so they take
161
 * things like panel scaling or other adjustments into account.
217
 * things like panel scaling or other adjustments into account.
162
 */
218
 */
163
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
219
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
Line 200... Line 256...
200
		  linedur_ns, pixeldur_ns);
256
		  linedur_ns, pixeldur_ns);
201
}
257
}
202
EXPORT_SYMBOL(drm_calc_timestamping_constants);
258
EXPORT_SYMBOL(drm_calc_timestamping_constants);
Line 203... Line 259...
203
 
259
 
204
/**
260
/**
-
 
261
 * drm_calc_vbltimestamp_from_scanoutpos - precise vblank timestamp helper
-
 
262
 * @dev: DRM device
205
 * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms
263
 * @crtc: Which CRTC's vblank timestamp to retrieve
-
 
264
 * @max_error: Desired maximum allowable error in timestamps (nanosecs)
-
 
265
 *             On return contains true maximum error of timestamp
-
 
266
 * @vblank_time: Pointer to struct timeval which should receive the timestamp
-
 
267
 * @flags: Flags to pass to driver:
-
 
268
 *         0 = Default,
-
 
269
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
206
 * drivers. Implements calculation of exact vblank timestamps from
270
 * @refcrtc: CRTC which defines scanout timing
-
 
271
 * @mode: mode which defines the scanout timings
-
 
272
 *
207
 * given drm_display_mode timings and current video scanout position
273
 * Implements calculation of exact vblank timestamps from given drm_display_mode
208
 * of a crtc. This can be called from within get_vblank_timestamp()
274
 * timings and current video scanout position of a CRTC. This can be called from
-
 
275
 * within get_vblank_timestamp() implementation of a kms driver to implement the
209
 * implementation of a kms driver to implement the actual timestamping.
276
 * actual timestamping.
210
 *
277
 *
211
 * Should return timestamps conforming to the OML_sync_control OpenML
278
 * Should return timestamps conforming to the OML_sync_control OpenML
212
 * extension specification. The timestamp corresponds to the end of
279
 * extension specification. The timestamp corresponds to the end of
213
 * the vblank interval, aka start of scanout of topmost-leftmost display
280
 * the vblank interval, aka start of scanout of topmost-leftmost display
Line 219... Line 286...
219
 *
286
 *
220
 * The current implementation only handles standard video modes. It
287
 * The current implementation only handles standard video modes. It
221
 * returns as no operation if a doublescan or interlaced video mode is
288
 * returns as no operation if a doublescan or interlaced video mode is
222
 * active. Higher level code is expected to handle this.
289
 * active. Higher level code is expected to handle this.
223
 *
290
 *
224
 * @dev: DRM device.
291
 * Returns:
225
 * @crtc: Which crtc's vblank timestamp to retrieve.
-
 
226
 * @max_error: Desired maximum allowable error in timestamps (nanosecs).
-
 
227
 *             On return contains true maximum error of timestamp.
-
 
228
 * @vblank_time: Pointer to struct timeval which should receive the timestamp.
-
 
229
 * @flags: Flags to pass to driver:
-
 
230
 *         0 = Default.
-
 
231
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler.
-
 
232
 * @refcrtc: drm_crtc* of crtc which defines scanout timing.
-
 
233
 * @mode: mode which defines the scanout timings
-
 
234
 *
-
 
235
 * Returns negative value on error, failure or if not supported in current
292
 * Negative value on error, failure or if not supported in current
236
 * video mode:
293
 * video mode:
237
 *
294
 *
238
 * -EINVAL   - Invalid crtc.
295
 * -EINVAL   - Invalid CRTC.
239
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
296
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
240
 * -ENOTSUPP - Function not supported in current display mode.
297
 * -ENOTSUPP - Function not supported in current display mode.
241
 * -EIO      - Failed, e.g., due to failed scanout position query.
298
 * -EIO      - Failed, e.g., due to failed scanout position query.
242
 *
299
 *
243
 * Returns or'ed positive status flags on success:
300
 * Returns or'ed positive status flags on success:
Line 285... Line 342...
285
 
342
 
286
	return -EIO;
343
	return -EIO;
287
}
344
}
Line -... Line 345...
-
 
345
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
-
 
346
 
-
 
347
/**
-
 
348
 * drm_vblank_off - disable vblank events on a CRTC
-
 
349
 * @dev: DRM device
-
 
350
 * @crtc: CRTC in question
-
 
351
 *
-
 
352
 * Drivers can use this function to shut down the vblank interrupt handling when
-
 
353
 * disabling a crtc. This function ensures that the latest vblank frame count is
-
 
354
 * stored so that drm_vblank_on() can restore it again.
-
 
355
 *
-
 
356
 * Drivers must use this function when the hardware vblank counter can get
-
 
357
 * reset, e.g. when suspending.
-
 
358
 *
-
 
359
 * This is the legacy version of drm_crtc_vblank_off().
-
 
360
 */
-
 
361
void drm_vblank_off(struct drm_device *dev, int crtc)
-
 
362
{
-
 
363
	struct drm_pending_vblank_event *e, *t;
-
 
364
	struct timeval now;
-
 
365
	unsigned long irqflags;
-
 
366
	unsigned int seq;
-
 
367
 
-
 
368
 
-
 
369
}
-
 
370
EXPORT_SYMBOL(drm_vblank_off);
-
 
371
 
-
 
372
/**
-
 
373
 * drm_crtc_vblank_off - disable vblank events on a CRTC
-
 
374
 * @crtc: CRTC in question
-
 
375
 *
-
 
376
 * Drivers can use this function to shut down the vblank interrupt handling when
-
 
377
 * disabling a crtc. This function ensures that the latest vblank frame count is
-
 
378
 * stored so that drm_vblank_on can restore it again.
-
 
379
 *
-
 
380
 * Drivers must use this function when the hardware vblank counter can get
-
 
381
 * reset, e.g. when suspending.
-
 
382
 *
-
 
383
 * This is the native kms version of drm_vblank_off().
-
 
384
 */
-
 
385
void drm_crtc_vblank_off(struct drm_crtc *crtc)
-
 
386
{
-
 
387
	drm_vblank_off(crtc->dev, drm_crtc_index(crtc));
-
 
388
}
-
 
389
EXPORT_SYMBOL(drm_crtc_vblank_off);
-
 
390
 
-
 
391
/**
-
 
392
 * drm_vblank_on - enable vblank events on a CRTC
-
 
393
 * @dev: DRM device
-
 
394
 * @crtc: CRTC in question
-
 
395
 *
-
 
396
 * This functions restores the vblank interrupt state captured with
-
 
397
 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
-
 
398
 * drm_vblank_off() can be unbalanced and so can also be unconditionaly called
-
 
399
 * in driver load code to reflect the current hardware state of the crtc.
-
 
400
 *
-
 
401
 * This is the legacy version of drm_crtc_vblank_on().
-
 
402
 */
-
 
403
void drm_vblank_on(struct drm_device *dev, int crtc)
-
 
404
{
-
 
405
	unsigned long irqflags;
-
 
406
 
-
 
407
}
-
 
408
EXPORT_SYMBOL(drm_vblank_on);
-
 
409
 
-
 
410
/**
-
 
411
 * drm_crtc_vblank_on - enable vblank events on a CRTC
-
 
412
 * @crtc: CRTC in question
-
 
413
 *
-
 
414
 * This functions restores the vblank interrupt state captured with
-
 
415
 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
-
 
416
 * drm_vblank_off() can be unbalanced and so can also be unconditionaly called
-
 
417
 * in driver load code to reflect the current hardware state of the crtc.
-
 
418
 *
-
 
419
 * This is the native kms version of drm_vblank_on().
-
 
420
 */
-
 
421
void drm_crtc_vblank_on(struct drm_crtc *crtc)
-
 
422
{
-
 
423
	drm_vblank_on(crtc->dev, drm_crtc_index(crtc));
Line 288... Line 424...
288
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
424
}
289
 
425
EXPORT_SYMBOL(drm_crtc_vblank_on);
290
 
426
 
291
/**
427
/**
292
 * drm_vblank_pre_modeset - account for vblanks across mode sets
428
 * drm_vblank_pre_modeset - account for vblanks across mode sets
293
 * @dev: DRM device
429
 * @dev: DRM device
294
 * @crtc: CRTC in question
430
 * @crtc: CRTC in question
-
 
431
 *
-
 
432
 * Account for vblank events across mode setting events, which will likely
-
 
433
 * reset the hardware frame counter.
-
 
434
 *
-
 
435
 * This is done by grabbing a temporary vblank reference to ensure that the
-
 
436
 * vblank interrupt keeps running across the modeset sequence. With this the
-
 
437
 * software-side vblank frame counting will ensure that there are no jumps or
-
 
438
 * discontinuities.
-
 
439
 *
-
 
440
 * Unfortunately this approach is racy and also doesn't work when the vblank
-
 
441
 * interrupt stops running, e.g. across system suspend resume. It is therefore
-
 
442
 * highly recommended that drivers use the newer drm_vblank_off() and
-
 
443
 * drm_vblank_on() instead. drm_vblank_pre_modeset() only works correctly when
-
 
444
 * using "cooked" software vblank frame counters and not relying on any hardware
-
 
445
 * counters.
295
 *
446
 *
296
 * Account for vblank events across mode setting events, which will likely
447
 * Drivers must call drm_vblank_post_modeset() when re-enabling the same crtc
297
 * reset the hardware frame counter.
448
 * again.
298
 */
449
 */
299
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
450
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
Line 316... Line 467...
316
    }
467
    }
317
#endif
468
#endif
318
}
469
}
319
EXPORT_SYMBOL(drm_vblank_pre_modeset);
470
EXPORT_SYMBOL(drm_vblank_pre_modeset);
Line -... Line 471...
-
 
471
 
-
 
472
/**
-
 
473
 * drm_vblank_post_modeset - undo drm_vblank_pre_modeset changes
-
 
474
 * @dev: DRM device
-
 
475
 * @crtc: CRTC in question
-
 
476
 *
-
 
477
 * This function again drops the temporary vblank reference acquired in
-
 
478
 * drm_vblank_pre_modeset.
320
 
479
 */
321
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
480
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
322
{
481
{
323
#if 0
482
#if 0