Subversion Repositories Kolibri OS

Rev

Rev 5060 | Rev 6084 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5060 Rev 5271
1
/*
1
/*
2
 * drm_irq.c IRQ and vblank support
2
 * drm_irq.c IRQ and vblank support
3
 *
3
 *
4
 * \author Rickard E. (Rik) Faith 
4
 * \author Rickard E. (Rik) Faith 
5
 * \author Gareth Hughes 
5
 * \author Gareth Hughes 
6
 */
6
 */
7
 
7
 
8
/*
8
/*
9
 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
9
 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
10
 *
10
 *
11
 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
11
 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
12
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
13
 * All Rights Reserved.
13
 * All Rights Reserved.
14
 *
14
 *
15
 * Permission is hereby granted, free of charge, to any person obtaining a
15
 * Permission is hereby granted, free of charge, to any person obtaining a
16
 * copy of this software and associated documentation files (the "Software"),
16
 * copy of this software and associated documentation files (the "Software"),
17
 * to deal in the Software without restriction, including without limitation
17
 * to deal in the Software without restriction, including without limitation
18
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
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
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:
20
 * Software is furnished to do so, subject to the following conditions:
21
 *
21
 *
22
 * The above copyright notice and this permission notice (including the next
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
23
 * paragraph) shall be included in all copies or substantial portions of the
24
 * Software.
24
 * Software.
25
 *
25
 *
26
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
27
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
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
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,
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
31
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32
 * OTHER DEALINGS IN THE SOFTWARE.
32
 * OTHER DEALINGS IN THE SOFTWARE.
33
 */
33
 */
34
 
34
 
35
#include 
35
#include 
36
#include 
-
 
37
//#include "drm_trace.h"
36
//#include "drm_trace.h"
-
 
37
#include "drm_internal.h"
38
 
38
 
39
//#include    /* For task queue support */
39
//#include    /* For task queue support */
40
#include 
40
#include 
41
 
41
 
42
//#include 
42
#include 
43
#include 
43
#include 
44
 
44
 
45
/* Access macro for slots in vblank timestamp ringbuffer. */
45
/* Access macro for slots in vblank timestamp ringbuffer. */
46
#define vblanktimestamp(dev, crtc, count) \
46
#define vblanktimestamp(dev, crtc, count) \
47
	((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
47
	((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
48
 
48
 
49
/* Retry timestamp calculation up to 3 times to satisfy
49
/* Retry timestamp calculation up to 3 times to satisfy
50
 * drm_timestamp_precision before giving up.
50
 * drm_timestamp_precision before giving up.
51
 */
51
 */
52
#define DRM_TIMESTAMP_MAXRETRIES 3
52
#define DRM_TIMESTAMP_MAXRETRIES 3
53
 
53
 
54
/* Threshold in nanoseconds for detection of redundant
54
/* Threshold in nanoseconds for detection of redundant
55
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
55
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
56
 */
56
 */
57
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
57
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
-
 
58
 
-
 
59
static bool
-
 
60
drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
-
 
61
			  struct timeval *tvblank, unsigned flags);
-
 
62
 
-
 
63
static unsigned int drm_timestamp_precision = 20;  /* Default to 20 usecs. */
58
 
64
 
59
/*
65
/*
60
 * Clear vblank timestamp buffer for a crtc.
66
 * Clear vblank timestamp buffer for a crtc.
61
 */
67
 */
62
 
68
 
63
 
69
 
64
#if 0
70
#if 0
65
/**
71
/**
66
 * drm_vblank_init - initialize vblank support
72
 * drm_vblank_init - initialize vblank support
67
 * @dev: drm_device
73
 * @dev: drm_device
68
 * @num_crtcs: number of crtcs supported by @dev
74
 * @num_crtcs: number of crtcs supported by @dev
69
 *
75
 *
70
 * This function initializes vblank support for @num_crtcs display pipelines.
76
 * This function initializes vblank support for @num_crtcs display pipelines.
71
 *
77
 *
72
 * Returns:
78
 * Returns:
73
 * Zero on success or a negative error code on failure.
79
 * Zero on success or a negative error code on failure.
74
 */
80
 */
75
int drm_vblank_init(struct drm_device *dev, int num_crtcs)
81
int drm_vblank_init(struct drm_device *dev, int num_crtcs)
76
{
82
{
77
	int i, ret = -ENOMEM;
83
	int i, ret = -ENOMEM;
78
 
84
 
79
	spin_lock_init(&dev->vbl_lock);
85
	spin_lock_init(&dev->vbl_lock);
80
	spin_lock_init(&dev->vblank_time_lock);
86
	spin_lock_init(&dev->vblank_time_lock);
81
 
87
 
82
	dev->num_crtcs = num_crtcs;
88
	dev->num_crtcs = num_crtcs;
83
 
89
 
84
	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
90
	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
85
	if (!dev->vblank)
91
	if (!dev->vblank)
86
		goto err;
92
		goto err;
87
 
93
 
88
	for (i = 0; i < num_crtcs; i++) {
94
	for (i = 0; i < num_crtcs; i++) {
-
 
95
		struct drm_vblank_crtc *vblank = &dev->vblank[i];
-
 
96
 
89
		dev->vblank[i].dev = dev;
97
		vblank->dev = dev;
90
		dev->vblank[i].crtc = i;
98
		vblank->crtc = i;
91
		init_waitqueue_head(&dev->vblank[i].queue);
99
		init_waitqueue_head(&vblank->queue);
92
		setup_timer(&dev->vblank[i].disable_timer, vblank_disable_fn,
100
		setup_timer(&vblank->disable_timer, vblank_disable_fn,
93
			    (unsigned long)&dev->vblank[i]);
101
			    (unsigned long)vblank);
94
	}
102
	}
95
 
103
 
96
	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
104
	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
97
 
105
 
98
	/* Driver specific high-precision vblank timestamping supported? */
106
	/* Driver specific high-precision vblank timestamping supported? */
99
	if (dev->driver->get_vblank_timestamp)
107
	if (dev->driver->get_vblank_timestamp)
100
		DRM_INFO("Driver supports precise vblank timestamp query.\n");
108
		DRM_INFO("Driver supports precise vblank timestamp query.\n");
101
	else
109
	else
102
		DRM_INFO("No driver support for vblank timestamp query.\n");
110
		DRM_INFO("No driver support for vblank timestamp query.\n");
103
 
111
 
104
	dev->vblank_disable_allowed = false;
112
	dev->vblank_disable_allowed = false;
105
 
113
 
106
	return 0;
114
	return 0;
107
 
115
 
108
err:
116
err:
109
	drm_vblank_cleanup(dev);
117
	dev->num_crtcs = 0;
110
	return ret;
118
	return ret;
111
}
119
}
112
EXPORT_SYMBOL(drm_vblank_init);
120
EXPORT_SYMBOL(drm_vblank_init);
113
 
121
 
114
#endif
122
#endif
115
 
123
 
116
irqreturn_t device_irq_handler(struct drm_device *dev)
124
irqreturn_t device_irq_handler(struct drm_device *dev)
117
{
125
{
118
 
126
 
119
//    printf("video irq\n");
127
//    printf("video irq\n");
120
 
128
 
121
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
129
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
122
 
130
 
123
    return dev->driver->irq_handler(0, dev);
131
    return dev->driver->irq_handler(0, dev);
124
}
132
}
125
 
133
 
126
/**
134
/**
127
 * drm_irq_install - install IRQ handler
135
 * drm_irq_install - install IRQ handler
128
 * @dev: DRM device
136
 * @dev: DRM device
129
 * @irq: IRQ number to install the handler for
137
 * @irq: IRQ number to install the handler for
130
 *
138
 *
131
 * Initializes the IRQ related data. Installs the handler, calling the driver
139
 * Initializes the IRQ related data. Installs the handler, calling the driver
132
 * irq_preinstall() and irq_postinstall() functions before and after the
140
 * irq_preinstall() and irq_postinstall() functions before and after the
133
 * installation.
141
 * installation.
134
 *
142
 *
135
 * This is the simplified helper interface provided for drivers with no special
143
 * This is the simplified helper interface provided for drivers with no special
136
 * needs. Drivers which need to install interrupt handlers for multiple
144
 * needs. Drivers which need to install interrupt handlers for multiple
137
 * interrupts must instead set drm_device->irq_enabled to signal the DRM core
145
 * interrupts must instead set drm_device->irq_enabled to signal the DRM core
138
 * that vblank interrupts are available.
146
 * that vblank interrupts are available.
139
 *
147
 *
140
 * Returns:
148
 * Returns:
141
 * Zero on success or a negative error code on failure.
149
 * Zero on success or a negative error code on failure.
142
 */
150
 */
143
int drm_irq_install(struct drm_device *dev, int irq)
151
int drm_irq_install(struct drm_device *dev, int irq)
144
{
152
{
145
	int ret;
153
	int ret;
146
    unsigned long sh_flags = 0;
154
    unsigned long sh_flags = 0;
147
 
155
 
148
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
156
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
149
		return -EINVAL;
157
		return -EINVAL;
150
 
158
 
151
	if (irq == 0)
159
	if (irq == 0)
152
		return -EINVAL;
160
		return -EINVAL;
153
 
161
 
154
    /* Driver must have been initialized */
162
    /* Driver must have been initialized */
155
	if (!dev->dev_private)
163
	if (!dev->dev_private)
156
            return -EINVAL;
164
            return -EINVAL;
157
 
165
 
158
	if (dev->irq_enabled)
166
	if (dev->irq_enabled)
159
            return -EBUSY;
167
            return -EBUSY;
160
	dev->irq_enabled = true;
168
	dev->irq_enabled = true;
161
 
169
 
162
	DRM_DEBUG("irq=%d\n", irq);
170
	DRM_DEBUG("irq=%d\n", irq);
163
 
171
 
164
    /* Before installing handler */
172
    /* Before installing handler */
165
    if (dev->driver->irq_preinstall)
173
    if (dev->driver->irq_preinstall)
166
            dev->driver->irq_preinstall(dev);
174
            dev->driver->irq_preinstall(dev);
167
 
175
 
168
    ret = !AttachIntHandler(irq, device_irq_handler, (u32)dev);
176
    ret = !AttachIntHandler(irq, device_irq_handler, (u32)dev);
169
 
177
 
170
    /* After installing handler */
178
    /* After installing handler */
171
    if (dev->driver->irq_postinstall)
179
    if (dev->driver->irq_postinstall)
172
            ret = dev->driver->irq_postinstall(dev);
180
            ret = dev->driver->irq_postinstall(dev);
173
 
181
 
174
    if (ret < 0) {
182
    if (ret < 0) {
175
		dev->irq_enabled = false;
183
		dev->irq_enabled = false;
176
        DRM_ERROR(__FUNCTION__);
184
        DRM_ERROR(__FUNCTION__);
177
	} else {
185
	} else {
178
		dev->irq = irq;
186
		dev->irq = irq;
179
    }
187
    }
180
 
188
 
181
    u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
189
    u16 cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
182
    cmd&= ~(1<<10);
190
    cmd&= ~(1<<10);
183
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
191
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
184
 
192
 
185
    return ret;
193
    return ret;
186
}
194
}
187
EXPORT_SYMBOL(drm_irq_install);
195
EXPORT_SYMBOL(drm_irq_install);
188
 
196
 
189
 
197
 
190
 
198
 
191
 
199
 
192
u64 div64_u64(u64 dividend, u64 divisor)
200
u64 div64_u64(u64 dividend, u64 divisor)
193
{
201
{
194
        u32 high, d;
202
        u32 high, d;
195
 
203
 
196
        high = divisor >> 32;
204
        high = divisor >> 32;
197
        if (high) {
205
        if (high) {
198
                unsigned int shift = fls(high);
206
                unsigned int shift = fls(high);
199
 
207
 
200
                d = divisor >> shift;
208
                d = divisor >> shift;
201
                dividend >>= shift;
209
                dividend >>= shift;
202
        } else
210
        } else
203
                d = divisor;
211
                d = divisor;
204
 
212
 
205
        return div_u64(dividend, d);
213
        return div_u64(dividend, d);
206
}
214
}
207
 
215
 
208
/**
216
/**
209
 * drm_calc_timestamping_constants - calculate vblank timestamp constants
217
 * drm_calc_timestamping_constants - calculate vblank timestamp constants
210
 * @crtc: drm_crtc whose timestamp constants should be updated.
218
 * @crtc: drm_crtc whose timestamp constants should be updated.
211
 * @mode: display mode containing the scanout timings
219
 * @mode: display mode containing the scanout timings
212
 *
220
 *
213
 * Calculate and store various constants which are later
221
 * Calculate and store various constants which are later
214
 * needed by vblank and swap-completion timestamping, e.g,
222
 * needed by vblank and swap-completion timestamping, e.g,
215
 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
223
 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
216
 * derived from CRTC's true scanout timing, so they take
224
 * derived from CRTC's true scanout timing, so they take
217
 * things like panel scaling or other adjustments into account.
225
 * things like panel scaling or other adjustments into account.
218
 */
226
 */
219
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
227
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
220
				     const struct drm_display_mode *mode)
228
				     const struct drm_display_mode *mode)
221
{
229
{
222
	int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
230
	int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
223
	int dotclock = mode->crtc_clock;
231
	int dotclock = mode->crtc_clock;
224
 
232
 
225
	/* Valid dotclock? */
233
	/* Valid dotclock? */
226
	if (dotclock > 0) {
234
	if (dotclock > 0) {
227
		int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
235
		int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
228
 
236
 
229
		/*
237
		/*
230
		 * Convert scanline length in pixels and video
238
		 * Convert scanline length in pixels and video
231
		 * dot clock to line duration, frame duration
239
		 * dot clock to line duration, frame duration
232
		 * and pixel duration in nanoseconds:
240
		 * and pixel duration in nanoseconds:
233
	 */
241
	 */
234
		pixeldur_ns = 1000000 / dotclock;
242
		pixeldur_ns = 1000000 / dotclock;
235
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
243
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
236
		framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
244
		framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
237
 
245
 
238
		/*
246
		/*
239
		 * Fields of interlaced scanout modes are only half a frame duration.
247
		 * Fields of interlaced scanout modes are only half a frame duration.
240
		 */
248
		 */
241
		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
249
		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
242
			framedur_ns /= 2;
250
			framedur_ns /= 2;
243
	} else
251
	} else
244
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
252
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
245
			  crtc->base.id);
253
			  crtc->base.id);
246
 
254
 
247
	crtc->pixeldur_ns = pixeldur_ns;
255
	crtc->pixeldur_ns = pixeldur_ns;
248
	crtc->linedur_ns  = linedur_ns;
256
	crtc->linedur_ns  = linedur_ns;
249
	crtc->framedur_ns = framedur_ns;
257
	crtc->framedur_ns = framedur_ns;
250
 
258
 
251
	DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
259
	DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
252
		  crtc->base.id, mode->crtc_htotal,
260
		  crtc->base.id, mode->crtc_htotal,
253
		  mode->crtc_vtotal, mode->crtc_vdisplay);
261
		  mode->crtc_vtotal, mode->crtc_vdisplay);
254
	DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
262
	DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
255
		  crtc->base.id, dotclock, framedur_ns,
263
		  crtc->base.id, dotclock, framedur_ns,
256
		  linedur_ns, pixeldur_ns);
264
		  linedur_ns, pixeldur_ns);
257
}
265
}
258
EXPORT_SYMBOL(drm_calc_timestamping_constants);
266
EXPORT_SYMBOL(drm_calc_timestamping_constants);
259
 
267
 
260
/**
268
/**
261
 * drm_calc_vbltimestamp_from_scanoutpos - precise vblank timestamp helper
269
 * drm_calc_vbltimestamp_from_scanoutpos - precise vblank timestamp helper
262
 * @dev: DRM device
270
 * @dev: DRM device
263
 * @crtc: Which CRTC's vblank timestamp to retrieve
271
 * @crtc: Which CRTC's vblank timestamp to retrieve
264
 * @max_error: Desired maximum allowable error in timestamps (nanosecs)
272
 * @max_error: Desired maximum allowable error in timestamps (nanosecs)
265
 *             On return contains true maximum error of timestamp
273
 *             On return contains true maximum error of timestamp
266
 * @vblank_time: Pointer to struct timeval which should receive the timestamp
274
 * @vblank_time: Pointer to struct timeval which should receive the timestamp
267
 * @flags: Flags to pass to driver:
275
 * @flags: Flags to pass to driver:
268
 *         0 = Default,
276
 *         0 = Default,
269
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
277
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
270
 * @refcrtc: CRTC which defines scanout timing
278
 * @refcrtc: CRTC which defines scanout timing
271
 * @mode: mode which defines the scanout timings
279
 * @mode: mode which defines the scanout timings
272
 *
280
 *
273
 * Implements calculation of exact vblank timestamps from given drm_display_mode
281
 * Implements calculation of exact vblank timestamps from given drm_display_mode
274
 * timings and current video scanout position of a CRTC. This can be called from
282
 * 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
283
 * within get_vblank_timestamp() implementation of a kms driver to implement the
276
 * actual timestamping.
284
 * actual timestamping.
277
 *
285
 *
278
 * Should return timestamps conforming to the OML_sync_control OpenML
286
 * Should return timestamps conforming to the OML_sync_control OpenML
279
 * extension specification. The timestamp corresponds to the end of
287
 * extension specification. The timestamp corresponds to the end of
280
 * the vblank interval, aka start of scanout of topmost-leftmost display
288
 * the vblank interval, aka start of scanout of topmost-leftmost display
281
 * pixel in the following video frame.
289
 * pixel in the following video frame.
282
 *
290
 *
283
 * Requires support for optional dev->driver->get_scanout_position()
291
 * Requires support for optional dev->driver->get_scanout_position()
284
 * in kms driver, plus a bit of setup code to provide a drm_display_mode
292
 * in kms driver, plus a bit of setup code to provide a drm_display_mode
285
 * that corresponds to the true scanout timing.
293
 * that corresponds to the true scanout timing.
286
 *
294
 *
287
 * The current implementation only handles standard video modes. It
295
 * The current implementation only handles standard video modes. It
288
 * returns as no operation if a doublescan or interlaced video mode is
296
 * returns as no operation if a doublescan or interlaced video mode is
289
 * active. Higher level code is expected to handle this.
297
 * active. Higher level code is expected to handle this.
290
 *
298
 *
291
 * Returns:
299
 * Returns:
292
 * Negative value on error, failure or if not supported in current
300
 * Negative value on error, failure or if not supported in current
293
 * video mode:
301
 * video mode:
294
 *
302
 *
295
 * -EINVAL   - Invalid CRTC.
303
 * -EINVAL   - Invalid CRTC.
296
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
304
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
297
 * -ENOTSUPP - Function not supported in current display mode.
305
 * -ENOTSUPP - Function not supported in current display mode.
298
 * -EIO      - Failed, e.g., due to failed scanout position query.
306
 * -EIO      - Failed, e.g., due to failed scanout position query.
299
 *
307
 *
300
 * Returns or'ed positive status flags on success:
308
 * Returns or'ed positive status flags on success:
301
 *
309
 *
302
 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
310
 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
303
 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
311
 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
304
 *
312
 *
305
 */
313
 */
306
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
314
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
307
					  int *max_error,
315
					  int *max_error,
308
					  struct timeval *vblank_time,
316
					  struct timeval *vblank_time,
309
					  unsigned flags,
317
					  unsigned flags,
310
					  const struct drm_crtc *refcrtc,
318
					  const struct drm_crtc *refcrtc,
311
					  const struct drm_display_mode *mode)
319
					  const struct drm_display_mode *mode)
312
{
320
{
313
	struct timeval tv_etime;
321
	struct timeval tv_etime;
314
	int vbl_status;
322
	int vbl_status;
315
	int vpos, hpos, i;
323
	int vpos, hpos, i;
316
	int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
324
	int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
317
	bool invbl;
325
	bool invbl;
318
 
326
 
319
	if (crtc < 0 || crtc >= dev->num_crtcs) {
327
	if (crtc < 0 || crtc >= dev->num_crtcs) {
320
		DRM_ERROR("Invalid crtc %d\n", crtc);
328
		DRM_ERROR("Invalid crtc %d\n", crtc);
321
		return -EINVAL;
329
		return -EINVAL;
322
	}
330
	}
323
 
331
 
324
	/* Scanout position query not supported? Should not happen. */
332
	/* Scanout position query not supported? Should not happen. */
325
	if (!dev->driver->get_scanout_position) {
333
	if (!dev->driver->get_scanout_position) {
326
		DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
334
		DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
327
		return -EIO;
335
		return -EIO;
328
	}
336
	}
329
 
337
 
330
	/* Durations of frames, lines, pixels in nanoseconds. */
338
	/* Durations of frames, lines, pixels in nanoseconds. */
331
	framedur_ns = refcrtc->framedur_ns;
339
	framedur_ns = refcrtc->framedur_ns;
332
	linedur_ns  = refcrtc->linedur_ns;
340
	linedur_ns  = refcrtc->linedur_ns;
333
	pixeldur_ns = refcrtc->pixeldur_ns;
341
	pixeldur_ns = refcrtc->pixeldur_ns;
334
 
342
 
335
	/* If mode timing undefined, just return as no-op:
343
	/* If mode timing undefined, just return as no-op:
336
	 * Happens during initial modesetting of a crtc.
344
	 * Happens during initial modesetting of a crtc.
337
	 */
345
	 */
338
	if (framedur_ns == 0) {
346
	if (framedur_ns == 0) {
339
		DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
347
		DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
340
		return -EAGAIN;
348
		return -EAGAIN;
341
	}
349
	}
342
 
350
 
343
	return -EIO;
351
	return -EIO;
344
}
352
}
345
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
353
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
346
 
354
 
347
/**
355
/**
-
 
356
 * drm_vblank_get - get a reference count on vblank events
-
 
357
 * @dev: DRM device
-
 
358
 * @crtc: which CRTC to own
-
 
359
 *
-
 
360
 * Acquire a reference count on vblank events to avoid having them disabled
-
 
361
 * while in use.
-
 
362
 *
-
 
363
 * This is the legacy version of drm_crtc_vblank_get().
-
 
364
 *
-
 
365
 * Returns:
-
 
366
 * Zero on success, nonzero on failure.
-
 
367
 */
-
 
368
int drm_vblank_get(struct drm_device *dev, int crtc)
-
 
369
{
-
 
370
	struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
-
 
371
	unsigned long irqflags;
-
 
372
	int ret = 0;
-
 
373
#if 0
-
 
374
 
-
 
375
	if (WARN_ON(crtc >= dev->num_crtcs))
-
 
376
		return -EINVAL;
-
 
377
 
-
 
378
	spin_lock_irqsave(&dev->vbl_lock, irqflags);
-
 
379
	/* Going from 0->1 means we have to enable interrupts again */
-
 
380
	if (atomic_add_return(1, &vblank->refcount) == 1) {
-
 
381
		ret = drm_vblank_enable(dev, crtc);
-
 
382
	} else {
-
 
383
		if (!vblank->enabled) {
-
 
384
			atomic_dec(&vblank->refcount);
-
 
385
			ret = -EINVAL;
-
 
386
		}
-
 
387
	}
-
 
388
	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
-
 
389
#endif
-
 
390
	return ret;
-
 
391
}
-
 
392
EXPORT_SYMBOL(drm_vblank_get);
-
 
393
 
-
 
394
/**
-
 
395
 * drm_crtc_vblank_get - get a reference count on vblank events
-
 
396
 * @crtc: which CRTC to own
-
 
397
 *
-
 
398
 * Acquire a reference count on vblank events to avoid having them disabled
-
 
399
 * while in use.
-
 
400
 *
-
 
401
 * This is the native kms version of drm_vblank_off().
-
 
402
 *
-
 
403
 * Returns:
-
 
404
 * Zero on success, nonzero on failure.
-
 
405
 */
-
 
406
int drm_crtc_vblank_get(struct drm_crtc *crtc)
-
 
407
{
-
 
408
	return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
-
 
409
}
-
 
410
EXPORT_SYMBOL(drm_crtc_vblank_get);
-
 
411
 
-
 
412
/**
-
 
413
 * drm_vblank_put - give up ownership of vblank events
-
 
414
 * @dev: DRM device
-
 
415
 * @crtc: which counter to give up
-
 
416
 *
-
 
417
 * Release ownership of a given vblank counter, turning off interrupts
-
 
418
 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
-
 
419
 *
-
 
420
 * This is the legacy version of drm_crtc_vblank_put().
-
 
421
 */
-
 
422
void drm_vblank_put(struct drm_device *dev, int crtc)
-
 
423
{
-
 
424
#if 0
-
 
425
	struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
-
 
426
 
-
 
427
	if (WARN_ON(atomic_read(&vblank->refcount) == 0))
-
 
428
		return;
-
 
429
 
-
 
430
	if (WARN_ON(crtc >= dev->num_crtcs))
-
 
431
		return;
-
 
432
 
-
 
433
	/* Last user schedules interrupt disable */
-
 
434
	if (atomic_dec_and_test(&vblank->refcount)) {
-
 
435
		if (drm_vblank_offdelay == 0)
-
 
436
			return;
-
 
437
		else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
-
 
438
			vblank_disable_fn((unsigned long)vblank);
-
 
439
		else
-
 
440
			mod_timer(&vblank->disable_timer,
-
 
441
				  jiffies + ((drm_vblank_offdelay * HZ)/1000));
-
 
442
	}
-
 
443
#endif
-
 
444
}
-
 
445
EXPORT_SYMBOL(drm_vblank_put);
-
 
446
 
-
 
447
/**
-
 
448
 * drm_crtc_vblank_put - give up ownership of vblank events
-
 
449
 * @crtc: which counter to give up
-
 
450
 *
-
 
451
 * Release ownership of a given vblank counter, turning off interrupts
-
 
452
 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
-
 
453
 *
-
 
454
 * This is the native kms version of drm_vblank_put().
-
 
455
 */
-
 
456
void drm_crtc_vblank_put(struct drm_crtc *crtc)
-
 
457
{
-
 
458
	drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
-
 
459
}
-
 
460
EXPORT_SYMBOL(drm_crtc_vblank_put);
-
 
461
 
-
 
462
/**
-
 
463
 * drm_wait_one_vblank - wait for one vblank
-
 
464
 * @dev: DRM device
-
 
465
 * @crtc: crtc index
-
 
466
 *
-
 
467
 * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
-
 
468
 * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
-
 
469
 * due to lack of driver support or because the crtc is off.
-
 
470
 */
-
 
471
void drm_wait_one_vblank(struct drm_device *dev, int crtc)
-
 
472
{
-
 
473
#if 0
-
 
474
	int ret;
-
 
475
	u32 last;
-
 
476
 
-
 
477
	ret = drm_vblank_get(dev, crtc);
-
 
478
	if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
-
 
479
		return;
-
 
480
 
-
 
481
	last = drm_vblank_count(dev, crtc);
-
 
482
 
-
 
483
	ret = wait_event_timeout(dev->vblank[crtc].queue,
-
 
484
				 last != drm_vblank_count(dev, crtc),
-
 
485
				 msecs_to_jiffies(100));
-
 
486
 
-
 
487
	WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc);
-
 
488
 
-
 
489
	drm_vblank_put(dev, crtc);
-
 
490
#endif
-
 
491
}
-
 
492
EXPORT_SYMBOL(drm_wait_one_vblank);
-
 
493
 
-
 
494
/**
-
 
495
 * drm_crtc_wait_one_vblank - wait for one vblank
-
 
496
 * @crtc: DRM crtc
-
 
497
 *
-
 
498
 * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
-
 
499
 * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
-
 
500
 * due to lack of driver support or because the crtc is off.
-
 
501
 */
-
 
502
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
-
 
503
{
-
 
504
	drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
-
 
505
}
-
 
506
EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
-
 
507
 
-
 
508
/**
348
 * drm_vblank_off - disable vblank events on a CRTC
509
 * drm_vblank_off - disable vblank events on a CRTC
349
 * @dev: DRM device
510
 * @dev: DRM device
350
 * @crtc: CRTC in question
511
 * @crtc: CRTC in question
351
 *
512
 *
352
 * Drivers can use this function to shut down the vblank interrupt handling when
513
 * 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
514
 * disabling a crtc. This function ensures that the latest vblank frame count is
354
 * stored so that drm_vblank_on() can restore it again.
515
 * stored so that drm_vblank_on() can restore it again.
355
 *
516
 *
356
 * Drivers must use this function when the hardware vblank counter can get
517
 * Drivers must use this function when the hardware vblank counter can get
357
 * reset, e.g. when suspending.
518
 * reset, e.g. when suspending.
358
 *
519
 *
359
 * This is the legacy version of drm_crtc_vblank_off().
520
 * This is the legacy version of drm_crtc_vblank_off().
360
 */
521
 */
361
void drm_vblank_off(struct drm_device *dev, int crtc)
522
void drm_vblank_off(struct drm_device *dev, int crtc)
362
{
523
{
-
 
524
	struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
363
	struct drm_pending_vblank_event *e, *t;
525
	struct drm_pending_vblank_event *e, *t;
364
	struct timeval now;
526
	struct timeval now;
365
	unsigned long irqflags;
527
	unsigned long irqflags;
366
	unsigned int seq;
528
	unsigned int seq;
367
 
529
 
368
 
530
 
369
}
531
}
370
EXPORT_SYMBOL(drm_vblank_off);
532
EXPORT_SYMBOL(drm_vblank_off);
371
 
533
 
372
/**
534
/**
373
 * drm_crtc_vblank_off - disable vblank events on a CRTC
535
 * drm_crtc_vblank_off - disable vblank events on a CRTC
374
 * @crtc: CRTC in question
536
 * @crtc: CRTC in question
375
 *
537
 *
376
 * Drivers can use this function to shut down the vblank interrupt handling when
538
 * 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
539
 * disabling a crtc. This function ensures that the latest vblank frame count is
378
 * stored so that drm_vblank_on can restore it again.
540
 * stored so that drm_vblank_on can restore it again.
379
 *
541
 *
380
 * Drivers must use this function when the hardware vblank counter can get
542
 * Drivers must use this function when the hardware vblank counter can get
381
 * reset, e.g. when suspending.
543
 * reset, e.g. when suspending.
382
 *
544
 *
383
 * This is the native kms version of drm_vblank_off().
545
 * This is the native kms version of drm_vblank_off().
384
 */
546
 */
385
void drm_crtc_vblank_off(struct drm_crtc *crtc)
547
void drm_crtc_vblank_off(struct drm_crtc *crtc)
386
{
548
{
387
	drm_vblank_off(crtc->dev, drm_crtc_index(crtc));
549
	drm_vblank_off(crtc->dev, drm_crtc_index(crtc));
388
}
550
}
389
EXPORT_SYMBOL(drm_crtc_vblank_off);
551
EXPORT_SYMBOL(drm_crtc_vblank_off);
390
 
552
 
391
/**
553
/**
392
 * drm_vblank_on - enable vblank events on a CRTC
554
 * drm_vblank_on - enable vblank events on a CRTC
393
 * @dev: DRM device
555
 * @dev: DRM device
394
 * @crtc: CRTC in question
556
 * @crtc: CRTC in question
395
 *
557
 *
396
 * This functions restores the vblank interrupt state captured with
558
 * This functions restores the vblank interrupt state captured with
397
 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
559
 * 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
560
 * drm_vblank_off() can be unbalanced and so can also be unconditionally called
399
 * in driver load code to reflect the current hardware state of the crtc.
561
 * in driver load code to reflect the current hardware state of the crtc.
400
 *
562
 *
401
 * This is the legacy version of drm_crtc_vblank_on().
563
 * This is the legacy version of drm_crtc_vblank_on().
402
 */
564
 */
403
void drm_vblank_on(struct drm_device *dev, int crtc)
565
void drm_vblank_on(struct drm_device *dev, int crtc)
404
{
566
{
-
 
567
	struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
405
	unsigned long irqflags;
568
	unsigned long irqflags;
406
 
569
 
407
}
570
}
408
EXPORT_SYMBOL(drm_vblank_on);
571
EXPORT_SYMBOL(drm_vblank_on);
409
 
572
 
410
/**
573
/**
411
 * drm_crtc_vblank_on - enable vblank events on a CRTC
574
 * drm_crtc_vblank_on - enable vblank events on a CRTC
412
 * @crtc: CRTC in question
575
 * @crtc: CRTC in question
413
 *
576
 *
414
 * This functions restores the vblank interrupt state captured with
577
 * This functions restores the vblank interrupt state captured with
415
 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
578
 * 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
579
 * drm_vblank_off() can be unbalanced and so can also be unconditionally called
417
 * in driver load code to reflect the current hardware state of the crtc.
580
 * in driver load code to reflect the current hardware state of the crtc.
418
 *
581
 *
419
 * This is the native kms version of drm_vblank_on().
582
 * This is the native kms version of drm_vblank_on().
420
 */
583
 */
421
void drm_crtc_vblank_on(struct drm_crtc *crtc)
584
void drm_crtc_vblank_on(struct drm_crtc *crtc)
422
{
585
{
423
	drm_vblank_on(crtc->dev, drm_crtc_index(crtc));
586
	drm_vblank_on(crtc->dev, drm_crtc_index(crtc));
424
}
587
}
425
EXPORT_SYMBOL(drm_crtc_vblank_on);
588
EXPORT_SYMBOL(drm_crtc_vblank_on);
426
 
589
 
427
/**
590
/**
428
 * drm_vblank_pre_modeset - account for vblanks across mode sets
591
 * drm_vblank_pre_modeset - account for vblanks across mode sets
429
 * @dev: DRM device
592
 * @dev: DRM device
430
 * @crtc: CRTC in question
593
 * @crtc: CRTC in question
431
 *
594
 *
432
 * Account for vblank events across mode setting events, which will likely
595
 * Account for vblank events across mode setting events, which will likely
433
 * reset the hardware frame counter.
596
 * reset the hardware frame counter.
434
 *
597
 *
435
 * This is done by grabbing a temporary vblank reference to ensure that the
598
 * 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
599
 * 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
600
 * software-side vblank frame counting will ensure that there are no jumps or
438
 * discontinuities.
601
 * discontinuities.
439
 *
602
 *
440
 * Unfortunately this approach is racy and also doesn't work when the vblank
603
 * 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
604
 * interrupt stops running, e.g. across system suspend resume. It is therefore
442
 * highly recommended that drivers use the newer drm_vblank_off() and
605
 * highly recommended that drivers use the newer drm_vblank_off() and
443
 * drm_vblank_on() instead. drm_vblank_pre_modeset() only works correctly when
606
 * 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
607
 * using "cooked" software vblank frame counters and not relying on any hardware
445
 * counters.
608
 * counters.
446
 *
609
 *
447
 * Drivers must call drm_vblank_post_modeset() when re-enabling the same crtc
610
 * Drivers must call drm_vblank_post_modeset() when re-enabling the same crtc
448
 * again.
611
 * again.
449
 */
612
 */
450
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
613
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
451
{
614
{
452
#if 0
615
#if 0
453
    /* vblank is not initialized (IRQ not installed ?) */
616
    /* vblank is not initialized (IRQ not installed ?) */
454
    if (!dev->num_crtcs)
617
    if (!dev->num_crtcs)
455
        return;
618
        return;
-
 
619
 
-
 
620
	if (WARN_ON(crtc >= dev->num_crtcs))
-
 
621
		return;
-
 
622
 
456
    /*
623
    /*
457
     * To avoid all the problems that might happen if interrupts
624
     * To avoid all the problems that might happen if interrupts
458
     * were enabled/disabled around or between these calls, we just
625
     * were enabled/disabled around or between these calls, we just
459
     * have the kernel take a reference on the CRTC (just once though
626
     * have the kernel take a reference on the CRTC (just once though
460
     * to avoid corrupting the count if multiple, mismatch calls occur),
627
     * to avoid corrupting the count if multiple, mismatch calls occur),
461
     * so that interrupts remain enabled in the interim.
628
     * so that interrupts remain enabled in the interim.
462
     */
629
     */
463
	if (!dev->vblank[crtc].inmodeset) {
630
	if (!vblank->inmodeset) {
464
		dev->vblank[crtc].inmodeset = 0x1;
631
		vblank->inmodeset = 0x1;
465
        if (drm_vblank_get(dev, crtc) == 0)
632
        if (drm_vblank_get(dev, crtc) == 0)
466
			dev->vblank[crtc].inmodeset |= 0x2;
633
			vblank->inmodeset |= 0x2;
467
    }
634
    }
468
#endif
635
#endif
469
}
636
}
470
EXPORT_SYMBOL(drm_vblank_pre_modeset);
637
EXPORT_SYMBOL(drm_vblank_pre_modeset);
471
 
638
 
472
/**
639
/**
473
 * drm_vblank_post_modeset - undo drm_vblank_pre_modeset changes
640
 * drm_vblank_post_modeset - undo drm_vblank_pre_modeset changes
474
 * @dev: DRM device
641
 * @dev: DRM device
475
 * @crtc: CRTC in question
642
 * @crtc: CRTC in question
476
 *
643
 *
477
 * This function again drops the temporary vblank reference acquired in
644
 * This function again drops the temporary vblank reference acquired in
478
 * drm_vblank_pre_modeset.
645
 * drm_vblank_pre_modeset.
479
 */
646
 */
480
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
647
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
481
{
648
{
482
#if 0
649
#if 0
483
    unsigned long irqflags;
650
    unsigned long irqflags;
484
 
651
 
485
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
652
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
486
	if (!dev->num_crtcs)
653
	if (!dev->num_crtcs)
487
		return;
654
		return;
488
 
655
 
489
	if (dev->vblank[crtc].inmodeset) {
656
	if (vblank->inmodeset) {
490
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
657
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
491
		dev->vblank_disable_allowed = true;
658
		dev->vblank_disable_allowed = true;
492
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
659
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
493
 
660
 
494
		if (dev->vblank[crtc].inmodeset & 0x2)
661
		if (vblank->inmodeset & 0x2)
495
            drm_vblank_put(dev, crtc);
662
            drm_vblank_put(dev, crtc);
496
 
663
 
497
		dev->vblank[crtc].inmodeset = 0;
664
		vblank->inmodeset = 0;
498
    }
665
    }
499
#endif
666
#endif
500
}
667
}
501
EXPORT_SYMBOL(drm_vblank_post_modeset);
668
EXPORT_SYMBOL(drm_vblank_post_modeset);
-
 
669
>
-
 
670
>
502
>
-
 
503
>
-