Subversion Repositories Kolibri OS

Rev

Rev 4539 | Rev 5271 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4539 Rev 4560
1
/**
1
/**
2
 * \file drm_irq.c
2
 * \file drm_irq.c
3
 * IRQ support
3
 * IRQ support
4
 *
4
 *
5
 * \author Rickard E. (Rik) Faith 
5
 * \author Rickard E. (Rik) Faith 
6
 * \author Gareth Hughes 
6
 * \author Gareth Hughes 
7
 */
7
 */
8
 
8
 
9
/*
9
/*
10
 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
10
 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
11
 *
11
 *
12
 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
12
 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
13
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14
 * All Rights Reserved.
14
 * All Rights Reserved.
15
 *
15
 *
16
 * Permission is hereby granted, free of charge, to any person obtaining a
16
 * Permission is hereby granted, free of charge, to any person obtaining a
17
 * copy of this software and associated documentation files (the "Software"),
17
 * copy of this software and associated documentation files (the "Software"),
18
 * to deal in the Software without restriction, including without limitation
18
 * to deal in the Software without restriction, including without limitation
19
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20
 * and/or sell copies of the Software, and to permit persons to whom the
20
 * and/or sell copies of the Software, and to permit persons to whom the
21
 * Software is furnished to do so, subject to the following conditions:
21
 * Software is furnished to do so, subject to the following conditions:
22
 *
22
 *
23
 * The above copyright notice and this permission notice (including the next
23
 * The above copyright notice and this permission notice (including the next
24
 * paragraph) shall be included in all copies or substantial portions of the
24
 * paragraph) shall be included in all copies or substantial portions of the
25
 * Software.
25
 * Software.
26
 *
26
 *
27
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
29
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
30
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
30
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
31
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33
 * OTHER DEALINGS IN THE SOFTWARE.
33
 * OTHER DEALINGS IN THE SOFTWARE.
34
 */
34
 */
35
 
35
 
36
#include 
36
#include 
37
#include 
37
#include 
38
//#include "drm_trace.h"
38
//#include "drm_trace.h"
39
 
39
 
40
//#include    /* For task queue support */
40
//#include    /* For task queue support */
41
#include 
41
#include 
42
 
42
 
43
//#include 
43
//#include 
44
#include 
44
#include 
45
 
45
 
46
/* Access macro for slots in vblank timestamp ringbuffer. */
46
/* Access macro for slots in vblank timestamp ringbuffer. */
47
#define vblanktimestamp(dev, crtc, count) ( \
47
#define vblanktimestamp(dev, crtc, count) \
48
	(dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
48
	((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
49
	((count) % DRM_VBLANKTIME_RBSIZE)])
-
 
50
 
49
 
51
/* Retry timestamp calculation up to 3 times to satisfy
50
/* Retry timestamp calculation up to 3 times to satisfy
52
 * drm_timestamp_precision before giving up.
51
 * drm_timestamp_precision before giving up.
53
 */
52
 */
54
#define DRM_TIMESTAMP_MAXRETRIES 3
53
#define DRM_TIMESTAMP_MAXRETRIES 3
55
 
54
 
56
/* Threshold in nanoseconds for detection of redundant
55
/* Threshold in nanoseconds for detection of redundant
57
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
56
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
58
 */
57
 */
59
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
58
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
60
 
59
 
61
 
60
 
62
irqreturn_t device_irq_handler(struct drm_device *dev)
61
irqreturn_t device_irq_handler(struct drm_device *dev)
63
{
62
{
64
 
63
 
65
//    printf("video irq\n");
64
//    printf("video irq\n");
66
 
65
 
67
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
66
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
68
 
67
 
69
    return dev->driver->irq_handler(0, dev);
68
    return dev->driver->irq_handler(0, dev);
70
}
69
}
71
 
70
 
72
/**
71
/**
73
 * Install IRQ handler.
72
 * Install IRQ handler.
74
 *
73
 *
75
 * \param dev DRM device.
74
 * \param dev DRM device.
76
 *
75
 *
77
 * Initializes the IRQ related data. Installs the handler, calling the driver
76
 * Initializes the IRQ related data. Installs the handler, calling the driver
78
 * \c irq_preinstall() and \c irq_postinstall() functions
77
 * \c irq_preinstall() and \c irq_postinstall() functions
79
 * before and after the installation.
78
 * before and after the installation.
80
 */
79
 */
81
int drm_irq_install(struct drm_device *dev)
80
int drm_irq_install(struct drm_device *dev)
82
{
81
{
83
	int ret;
82
	int ret;
84
    unsigned long sh_flags = 0;
83
    unsigned long sh_flags = 0;
85
	char *irqname;
84
	char *irqname;
86
 
85
 
87
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
86
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
88
		return -EINVAL;
87
		return -EINVAL;
89
 
88
 
90
	if (drm_dev_to_irq(dev) == 0)
89
	if (drm_dev_to_irq(dev) == 0)
91
		return -EINVAL;
90
		return -EINVAL;
92
 
91
 
93
    mutex_lock(&dev->struct_mutex);
92
    mutex_lock(&dev->struct_mutex);
94
 
93
 
95
    /* Driver must have been initialized */
94
    /* Driver must have been initialized */
96
    if (!dev->dev_private) {
95
    if (!dev->dev_private) {
97
            mutex_unlock(&dev->struct_mutex);
96
            mutex_unlock(&dev->struct_mutex);
98
            return -EINVAL;
97
            return -EINVAL;
99
    }
98
    }
100
 
99
 
101
    if (dev->irq_enabled) {
100
    if (dev->irq_enabled) {
102
            mutex_unlock(&dev->struct_mutex);
101
            mutex_unlock(&dev->struct_mutex);
103
            return -EBUSY;
102
            return -EBUSY;
104
    }
103
    }
105
    dev->irq_enabled = 1;
104
	dev->irq_enabled = true;
106
    mutex_unlock(&dev->struct_mutex);
105
    mutex_unlock(&dev->struct_mutex);
107
 
106
 
108
    DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
107
    DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
109
 
108
 
110
    /* Before installing handler */
109
    /* Before installing handler */
111
    if (dev->driver->irq_preinstall)
110
    if (dev->driver->irq_preinstall)
112
            dev->driver->irq_preinstall(dev);
111
            dev->driver->irq_preinstall(dev);
113
 
112
 
114
    ret = !AttachIntHandler(drm_dev_to_irq(dev), device_irq_handler, (u32)dev);
113
    ret = !AttachIntHandler(drm_dev_to_irq(dev), device_irq_handler, (u32)dev);
115
 
114
 
116
    /* After installing handler */
115
    /* After installing handler */
117
    if (dev->driver->irq_postinstall)
116
    if (dev->driver->irq_postinstall)
118
            ret = dev->driver->irq_postinstall(dev);
117
            ret = dev->driver->irq_postinstall(dev);
119
 
118
 
120
    if (ret < 0) {
119
    if (ret < 0) {
121
		dev->irq_enabled = 0;
120
		dev->irq_enabled = 0;
122
        DRM_ERROR(__FUNCTION__);
121
        DRM_ERROR(__FUNCTION__);
123
    }
122
    }
124
 
123
 
125
    u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
124
    u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
126
    cmd&= ~(1<<10);
125
    cmd&= ~(1<<10);
127
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
126
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
128
 
127
 
129
    return ret;
128
    return ret;
130
}
129
}
131
EXPORT_SYMBOL(drm_irq_install);
130
EXPORT_SYMBOL(drm_irq_install);
132
 
131
 
133
 
132
 
134
 
133
 
135
 
134
 
136
u64 div64_u64(u64 dividend, u64 divisor)
135
u64 div64_u64(u64 dividend, u64 divisor)
137
{
136
{
138
        u32 high, d;
137
        u32 high, d;
139
 
138
 
140
        high = divisor >> 32;
139
        high = divisor >> 32;
141
        if (high) {
140
        if (high) {
142
                unsigned int shift = fls(high);
141
                unsigned int shift = fls(high);
143
 
142
 
144
                d = divisor >> shift;
143
                d = divisor >> shift;
145
                dividend >>= shift;
144
                dividend >>= shift;
146
        } else
145
        } else
147
                d = divisor;
146
                d = divisor;
148
 
147
 
149
        return div_u64(dividend, d);
148
        return div_u64(dividend, d);
150
}
149
}
151
 
150
 
152
/**
151
/**
153
 * drm_calc_timestamping_constants - Calculate and
152
 * drm_calc_timestamping_constants - Calculate vblank timestamp constants
154
 * store various constants which are later needed by
-
 
155
 * vblank and swap-completion timestamping, e.g, by
-
 
156
 * drm_calc_vbltimestamp_from_scanoutpos().
-
 
157
 * They are derived from crtc's true scanout timing,
-
 
158
 * so they take things like panel scaling or other
-
 
159
 * adjustments into account.
-
 
160
 *
153
 *
161
 * @crtc drm_crtc whose timestamp constants should be updated.
154
 * @crtc drm_crtc whose timestamp constants should be updated.
-
 
155
 * @mode display mode containing the scanout timings
162
 *
156
 *
-
 
157
 * Calculate and store various constants which are later
-
 
158
 * needed by vblank and swap-completion timestamping, e.g,
-
 
159
 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
-
 
160
 * derived from crtc's true scanout timing, so they take
-
 
161
 * things like panel scaling or other adjustments into account.
163
 */
162
 */
164
void drm_calc_timestamping_constants(struct drm_crtc *crtc)
163
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
-
 
164
				     const struct drm_display_mode *mode)
165
{
165
{
166
	s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
166
	int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
167
	u64 dotclock;
167
	int dotclock = mode->crtc_clock;
-
 
168
 
168
 
169
	/* Valid dotclock? */
169
	/* Dot clock in Hz: */
170
	if (dotclock > 0) {
-
 
171
		int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
170
	dotclock = (u64) crtc->hwmode.clock * 1000;
172
 
171
 
173
		/*
-
 
174
		 * Convert scanline length in pixels and video
172
	/* Fields of interlaced scanout modes are only halve a frame duration.
175
		 * dot clock to line duration, frame duration
173
	 * Double the dotclock to get halve the frame-/line-/pixelduration.
176
		 * and pixel duration in nanoseconds:
174
	 */
177
	 */
-
 
178
		pixeldur_ns = 1000000 / dotclock;
175
	if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE)
-
 
176
		dotclock *= 2;
-
 
177
 
179
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
178
	/* Valid dotclock? */
-
 
179
	if (dotclock > 0) {
180
		framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
180
		int frame_size;
-
 
181
		/* Convert scanline length in pixels and video dot clock to
181
 
182
		 * line duration, frame duration and pixel duration in
-
 
183
		 * nanoseconds:
-
 
184
		 */
-
 
185
		pixeldur_ns = (s64) div64_u64(1000000000, dotclock);
182
		/*
186
		linedur_ns  = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal *
-
 
187
					      1000000000), dotclock);
-
 
188
		frame_size = crtc->hwmode.crtc_htotal *
183
		 * Fields of interlaced scanout modes are only half a frame duration.
189
				crtc->hwmode.crtc_vtotal;
184
		 */
190
		framedur_ns = (s64) div64_u64((u64) frame_size * 1000000000,
185
		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
191
					      dotclock);
186
			framedur_ns /= 2;
192
	} else
187
	} else
193
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
188
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
194
			  crtc->base.id);
189
			  crtc->base.id);
195
 
190
 
196
	crtc->pixeldur_ns = pixeldur_ns;
191
	crtc->pixeldur_ns = pixeldur_ns;
197
	crtc->linedur_ns  = linedur_ns;
192
	crtc->linedur_ns  = linedur_ns;
198
	crtc->framedur_ns = framedur_ns;
193
	crtc->framedur_ns = framedur_ns;
199
 
194
 
200
	DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
195
	DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
201
		  crtc->base.id, crtc->hwmode.crtc_htotal,
196
		  crtc->base.id, mode->crtc_htotal,
202
		  crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay);
197
		  mode->crtc_vtotal, mode->crtc_vdisplay);
203
	DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
198
	DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
204
		  crtc->base.id, (int) dotclock/1000, (int) framedur_ns,
199
		  crtc->base.id, dotclock, framedur_ns,
205
		  (int) linedur_ns, (int) pixeldur_ns);
200
		  linedur_ns, pixeldur_ns);
206
}
201
}
207
EXPORT_SYMBOL(drm_calc_timestamping_constants);
202
EXPORT_SYMBOL(drm_calc_timestamping_constants);
208
 
203
 
209
/**
204
/**
210
 * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms
205
 * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms
211
 * drivers. Implements calculation of exact vblank timestamps from
206
 * drivers. Implements calculation of exact vblank timestamps from
212
 * given drm_display_mode timings and current video scanout position
207
 * given drm_display_mode timings and current video scanout position
213
 * of a crtc. This can be called from within get_vblank_timestamp()
208
 * of a crtc. This can be called from within get_vblank_timestamp()
214
 * implementation of a kms driver to implement the actual timestamping.
209
 * implementation of a kms driver to implement the actual timestamping.
215
 *
210
 *
216
 * Should return timestamps conforming to the OML_sync_control OpenML
211
 * Should return timestamps conforming to the OML_sync_control OpenML
217
 * extension specification. The timestamp corresponds to the end of
212
 * extension specification. The timestamp corresponds to the end of
218
 * the vblank interval, aka start of scanout of topmost-leftmost display
213
 * the vblank interval, aka start of scanout of topmost-leftmost display
219
 * pixel in the following video frame.
214
 * pixel in the following video frame.
220
 *
215
 *
221
 * Requires support for optional dev->driver->get_scanout_position()
216
 * Requires support for optional dev->driver->get_scanout_position()
222
 * in kms driver, plus a bit of setup code to provide a drm_display_mode
217
 * in kms driver, plus a bit of setup code to provide a drm_display_mode
223
 * that corresponds to the true scanout timing.
218
 * that corresponds to the true scanout timing.
224
 *
219
 *
225
 * The current implementation only handles standard video modes. It
220
 * The current implementation only handles standard video modes. It
226
 * returns as no operation if a doublescan or interlaced video mode is
221
 * returns as no operation if a doublescan or interlaced video mode is
227
 * active. Higher level code is expected to handle this.
222
 * active. Higher level code is expected to handle this.
228
 *
223
 *
229
 * @dev: DRM device.
224
 * @dev: DRM device.
230
 * @crtc: Which crtc's vblank timestamp to retrieve.
225
 * @crtc: Which crtc's vblank timestamp to retrieve.
231
 * @max_error: Desired maximum allowable error in timestamps (nanosecs).
226
 * @max_error: Desired maximum allowable error in timestamps (nanosecs).
232
 *             On return contains true maximum error of timestamp.
227
 *             On return contains true maximum error of timestamp.
233
 * @vblank_time: Pointer to struct timeval which should receive the timestamp.
228
 * @vblank_time: Pointer to struct timeval which should receive the timestamp.
234
 * @flags: Flags to pass to driver:
229
 * @flags: Flags to pass to driver:
235
 *         0 = Default.
230
 *         0 = Default.
236
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler.
231
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler.
237
 * @refcrtc: drm_crtc* of crtc which defines scanout timing.
232
 * @refcrtc: drm_crtc* of crtc which defines scanout timing.
-
 
233
 * @mode: mode which defines the scanout timings
238
 *
234
 *
239
 * Returns negative value on error, failure or if not supported in current
235
 * Returns negative value on error, failure or if not supported in current
240
 * video mode:
236
 * video mode:
241
 *
237
 *
242
 * -EINVAL   - Invalid crtc.
238
 * -EINVAL   - Invalid crtc.
243
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
239
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
244
 * -ENOTSUPP - Function not supported in current display mode.
240
 * -ENOTSUPP - Function not supported in current display mode.
245
 * -EIO      - Failed, e.g., due to failed scanout position query.
241
 * -EIO      - Failed, e.g., due to failed scanout position query.
246
 *
242
 *
247
 * Returns or'ed positive status flags on success:
243
 * Returns or'ed positive status flags on success:
248
 *
244
 *
249
 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
245
 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
250
 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
246
 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
251
 *
247
 *
252
 */
248
 */
253
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
249
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
254
					  int *max_error,
250
					  int *max_error,
255
					  struct timeval *vblank_time,
251
					  struct timeval *vblank_time,
256
					  unsigned flags,
252
					  unsigned flags,
257
					  struct drm_crtc *refcrtc)
253
					  const struct drm_crtc *refcrtc,
-
 
254
					  const struct drm_display_mode *mode)
258
{
255
{
259
//	ktime_t stime, etime, mono_time_offset;
-
 
260
	struct timeval tv_etime;
256
	struct timeval tv_etime;
261
	struct drm_display_mode *mode;
-
 
262
	int vbl_status, vtotal, vdisplay;
257
	int vbl_status;
263
	int vpos, hpos, i;
258
	int vpos, hpos, i;
264
	s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
259
	int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
265
	bool invbl;
260
	bool invbl;
266
 
261
 
267
	if (crtc < 0 || crtc >= dev->num_crtcs) {
262
	if (crtc < 0 || crtc >= dev->num_crtcs) {
268
		DRM_ERROR("Invalid crtc %d\n", crtc);
263
		DRM_ERROR("Invalid crtc %d\n", crtc);
269
		return -EINVAL;
264
		return -EINVAL;
270
	}
265
	}
271
 
266
 
272
	/* Scanout position query not supported? Should not happen. */
267
	/* Scanout position query not supported? Should not happen. */
273
	if (!dev->driver->get_scanout_position) {
268
	if (!dev->driver->get_scanout_position) {
274
		DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
269
		DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
275
		return -EIO;
270
		return -EIO;
276
	}
271
	}
277
 
-
 
278
	mode = &refcrtc->hwmode;
-
 
279
	vtotal = mode->crtc_vtotal;
-
 
280
	vdisplay = mode->crtc_vdisplay;
-
 
281
 
272
 
282
	/* Durations of frames, lines, pixels in nanoseconds. */
273
	/* Durations of frames, lines, pixels in nanoseconds. */
283
	framedur_ns = refcrtc->framedur_ns;
274
	framedur_ns = refcrtc->framedur_ns;
284
	linedur_ns  = refcrtc->linedur_ns;
275
	linedur_ns  = refcrtc->linedur_ns;
285
	pixeldur_ns = refcrtc->pixeldur_ns;
276
	pixeldur_ns = refcrtc->pixeldur_ns;
286
 
277
 
287
	/* If mode timing undefined, just return as no-op:
278
	/* If mode timing undefined, just return as no-op:
288
	 * Happens during initial modesetting of a crtc.
279
	 * Happens during initial modesetting of a crtc.
289
	 */
280
	 */
290
	if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) {
281
	if (framedur_ns == 0) {
291
		DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
282
		DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
292
		return -EAGAIN;
283
		return -EAGAIN;
293
	}
284
	}
294
 
285
 
295
	return -EIO;
286
	return -EIO;
296
}
287
}
297
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
288
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
298
 
289
 
299
 
290
 
300
/**
291
/**
301
 * drm_vblank_pre_modeset - account for vblanks across mode sets
292
 * drm_vblank_pre_modeset - account for vblanks across mode sets
302
 * @dev: DRM device
293
 * @dev: DRM device
303
 * @crtc: CRTC in question
294
 * @crtc: CRTC in question
304
 *
295
 *
305
 * Account for vblank events across mode setting events, which will likely
296
 * Account for vblank events across mode setting events, which will likely
306
 * reset the hardware frame counter.
297
 * reset the hardware frame counter.
307
 */
298
 */
308
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
299
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
309
{
300
{
310
#if 0
301
#if 0
311
    /* vblank is not initialized (IRQ not installed ?) */
302
    /* vblank is not initialized (IRQ not installed ?) */
312
    if (!dev->num_crtcs)
303
    if (!dev->num_crtcs)
313
        return;
304
        return;
314
    /*
305
    /*
315
     * To avoid all the problems that might happen if interrupts
306
     * To avoid all the problems that might happen if interrupts
316
     * were enabled/disabled around or between these calls, we just
307
     * were enabled/disabled around or between these calls, we just
317
     * have the kernel take a reference on the CRTC (just once though
308
     * have the kernel take a reference on the CRTC (just once though
318
     * to avoid corrupting the count if multiple, mismatch calls occur),
309
     * to avoid corrupting the count if multiple, mismatch calls occur),
319
     * so that interrupts remain enabled in the interim.
310
     * so that interrupts remain enabled in the interim.
320
     */
311
     */
321
    if (!dev->vblank_inmodeset[crtc]) {
312
	if (!dev->vblank[crtc].inmodeset) {
322
        dev->vblank_inmodeset[crtc] = 0x1;
313
		dev->vblank[crtc].inmodeset = 0x1;
323
        if (drm_vblank_get(dev, crtc) == 0)
314
        if (drm_vblank_get(dev, crtc) == 0)
324
            dev->vblank_inmodeset[crtc] |= 0x2;
315
			dev->vblank[crtc].inmodeset |= 0x2;
325
    }
316
    }
326
#endif
317
#endif
327
}
318
}
328
EXPORT_SYMBOL(drm_vblank_pre_modeset);
319
EXPORT_SYMBOL(drm_vblank_pre_modeset);
329
 
320
 
330
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
321
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
331
{
322
{
332
#if 0
323
#if 0
333
    unsigned long irqflags;
324
    unsigned long irqflags;
334
 
325
 
335
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
326
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
336
	if (!dev->num_crtcs)
327
	if (!dev->num_crtcs)
337
		return;
328
		return;
338
 
329
 
339
    if (dev->vblank_inmodeset[crtc]) {
330
	if (dev->vblank[crtc].inmodeset) {
340
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
331
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
341
        dev->vblank_disable_allowed = 1;
332
		dev->vblank_disable_allowed = true;
342
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
333
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
343
 
334
 
344
        if (dev->vblank_inmodeset[crtc] & 0x2)
335
		if (dev->vblank[crtc].inmodeset & 0x2)
345
            drm_vblank_put(dev, crtc);
336
            drm_vblank_put(dev, crtc);
346
 
337
 
347
        dev->vblank_inmodeset[crtc] = 0;
338
		dev->vblank[crtc].inmodeset = 0;
348
    }
339
    }
349
#endif
340
#endif
350
}
341
}
351
EXPORT_SYMBOL(drm_vblank_post_modeset);
342
EXPORT_SYMBOL(drm_vblank_post_modeset);
352
>
343
>
353
>
344
>