Subversion Repositories Kolibri OS

Rev

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

Rev 4104 Rev 4293
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_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
49
	((count) % DRM_VBLANKTIME_RBSIZE)])
49
	((count) % DRM_VBLANKTIME_RBSIZE)])
50
 
50
 
51
/* Retry timestamp calculation up to 3 times to satisfy
51
/* Retry timestamp calculation up to 3 times to satisfy
52
 * drm_timestamp_precision before giving up.
52
 * drm_timestamp_precision before giving up.
53
 */
53
 */
54
#define DRM_TIMESTAMP_MAXRETRIES 3
54
#define DRM_TIMESTAMP_MAXRETRIES 3
55
 
55
 
56
/* Threshold in nanoseconds for detection of redundant
56
/* Threshold in nanoseconds for detection of redundant
57
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
57
 * vblank irq in drm_handle_vblank(). 1 msec should be ok.
58
 */
58
 */
59
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
59
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
60
 
60
 
61
 
61
 
62
irqreturn_t device_irq_handler(struct drm_device *dev)
62
irqreturn_t device_irq_handler(struct drm_device *dev)
63
{
63
{
64
 
64
 
65
//    printf("video irq\n");
65
//    printf("video irq\n");
66
 
66
 
67
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
67
//    printf("device %p driver %p handler %p\n", dev, dev->driver, dev->driver->irq_handler) ;
68
 
68
 
69
    return dev->driver->irq_handler(0, dev);
69
    return dev->driver->irq_handler(0, dev);
70
}
70
}
71
 
71
 
72
/**
72
/**
73
 * Install IRQ handler.
73
 * Install IRQ handler.
74
 *
74
 *
75
 * \param dev DRM device.
75
 * \param dev DRM device.
76
 *
76
 *
77
 * Initializes the IRQ related data. Installs the handler, calling the driver
77
 * Initializes the IRQ related data. Installs the handler, calling the driver
78
 * \c irq_preinstall() and \c irq_postinstall() functions
78
 * \c irq_preinstall() and \c irq_postinstall() functions
79
 * before and after the installation.
79
 * before and after the installation.
80
 */
80
 */
81
int drm_irq_install(struct drm_device *dev)
81
int drm_irq_install(struct drm_device *dev)
82
{
82
{
83
	int ret;
83
	int ret;
84
    unsigned long sh_flags = 0;
84
    unsigned long sh_flags = 0;
85
	char *irqname;
85
	char *irqname;
-
 
86
 
-
 
87
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
86
 
88
		return -EINVAL;
87
 
89
 
88
	if (drm_dev_to_irq(dev) == 0)
90
	if (drm_dev_to_irq(dev) == 0)
89
		return -EINVAL;
91
		return -EINVAL;
90
 
92
 
91
    mutex_lock(&dev->struct_mutex);
93
    mutex_lock(&dev->struct_mutex);
92
 
94
 
93
    /* Driver must have been initialized */
95
    /* Driver must have been initialized */
94
    if (!dev->dev_private) {
96
    if (!dev->dev_private) {
95
            mutex_unlock(&dev->struct_mutex);
97
            mutex_unlock(&dev->struct_mutex);
96
            return -EINVAL;
98
            return -EINVAL;
97
    }
99
    }
98
 
100
 
99
    if (dev->irq_enabled) {
101
    if (dev->irq_enabled) {
100
            mutex_unlock(&dev->struct_mutex);
102
            mutex_unlock(&dev->struct_mutex);
101
            return -EBUSY;
103
            return -EBUSY;
102
    }
104
    }
103
    dev->irq_enabled = 1;
105
    dev->irq_enabled = 1;
104
    mutex_unlock(&dev->struct_mutex);
106
    mutex_unlock(&dev->struct_mutex);
105
 
107
 
106
    DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
108
    DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
107
 
109
 
108
    /* Before installing handler */
110
    /* Before installing handler */
109
    if (dev->driver->irq_preinstall)
111
    if (dev->driver->irq_preinstall)
110
            dev->driver->irq_preinstall(dev);
112
            dev->driver->irq_preinstall(dev);
111
 
113
 
112
    ret = !AttachIntHandler(drm_dev_to_irq(dev), device_irq_handler, (u32)dev);
114
    ret = !AttachIntHandler(drm_dev_to_irq(dev), device_irq_handler, (u32)dev);
113
 
115
 
114
    /* After installing handler */
116
    /* After installing handler */
115
    if (dev->driver->irq_postinstall)
117
    if (dev->driver->irq_postinstall)
116
            ret = dev->driver->irq_postinstall(dev);
118
            ret = dev->driver->irq_postinstall(dev);
117
 
119
 
118
    if (ret < 0) {
120
    if (ret < 0) {
119
		dev->irq_enabled = 0;
121
		dev->irq_enabled = 0;
120
            DRM_ERROR(__FUNCTION__);
122
            DRM_ERROR(__FUNCTION__);
121
    }
123
    }
122
 
124
 
123
    u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
125
    u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
124
    cmd&= ~(1<<10);
126
    cmd&= ~(1<<10);
125
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
127
    PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
126
 
128
 
127
    return ret;
129
    return ret;
128
}
130
}
129
EXPORT_SYMBOL(drm_irq_install);
131
EXPORT_SYMBOL(drm_irq_install);
130
 
132
 
131
 
133
 
132
 
134
 
133
 
135
 
134
u64 div64_u64(u64 dividend, u64 divisor)
136
u64 div64_u64(u64 dividend, u64 divisor)
135
{
137
{
136
        u32 high, d;
138
        u32 high, d;
137
 
139
 
138
        high = divisor >> 32;
140
        high = divisor >> 32;
139
        if (high) {
141
        if (high) {
140
                unsigned int shift = fls(high);
142
                unsigned int shift = fls(high);
141
 
143
 
142
                d = divisor >> shift;
144
                d = divisor >> shift;
143
                dividend >>= shift;
145
                dividend >>= shift;
144
        } else
146
        } else
145
                d = divisor;
147
                d = divisor;
146
 
148
 
147
        return div_u64(dividend, d);
149
        return div_u64(dividend, d);
148
}
150
}
149
 
151
 
150
/**
152
/**
151
 * drm_calc_timestamping_constants - Calculate and
153
 * drm_calc_timestamping_constants - Calculate and
152
 * store various constants which are later needed by
154
 * store various constants which are later needed by
153
 * vblank and swap-completion timestamping, e.g, by
155
 * vblank and swap-completion timestamping, e.g, by
154
 * drm_calc_vbltimestamp_from_scanoutpos().
156
 * drm_calc_vbltimestamp_from_scanoutpos().
155
 * They are derived from crtc's true scanout timing,
157
 * They are derived from crtc's true scanout timing,
156
 * so they take things like panel scaling or other
158
 * so they take things like panel scaling or other
157
 * adjustments into account.
159
 * adjustments into account.
158
 *
160
 *
159
 * @crtc drm_crtc whose timestamp constants should be updated.
161
 * @crtc drm_crtc whose timestamp constants should be updated.
160
 *
162
 *
161
 */
163
 */
162
void drm_calc_timestamping_constants(struct drm_crtc *crtc)
164
void drm_calc_timestamping_constants(struct drm_crtc *crtc)
163
{
165
{
164
	s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
166
	s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
165
	u64 dotclock;
167
	u64 dotclock;
166
 
168
 
167
	/* Dot clock in Hz: */
169
	/* Dot clock in Hz: */
168
	dotclock = (u64) crtc->hwmode.clock * 1000;
170
	dotclock = (u64) crtc->hwmode.clock * 1000;
169
 
171
 
170
	/* Fields of interlaced scanout modes are only halve a frame duration.
172
	/* Fields of interlaced scanout modes are only halve a frame duration.
171
	 * Double the dotclock to get halve the frame-/line-/pixelduration.
173
	 * Double the dotclock to get halve the frame-/line-/pixelduration.
172
	 */
174
	 */
173
	if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE)
175
	if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE)
174
		dotclock *= 2;
176
		dotclock *= 2;
175
 
177
 
176
	/* Valid dotclock? */
178
	/* Valid dotclock? */
177
	if (dotclock > 0) {
179
	if (dotclock > 0) {
178
		int frame_size;
180
		int frame_size;
179
		/* Convert scanline length in pixels and video dot clock to
181
		/* Convert scanline length in pixels and video dot clock to
180
		 * line duration, frame duration and pixel duration in
182
		 * line duration, frame duration and pixel duration in
181
		 * nanoseconds:
183
		 * nanoseconds:
182
		 */
184
		 */
183
		pixeldur_ns = (s64) div64_u64(1000000000, dotclock);
185
		pixeldur_ns = (s64) div64_u64(1000000000, dotclock);
184
		linedur_ns  = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal *
186
		linedur_ns  = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal *
185
					      1000000000), dotclock);
187
					      1000000000), dotclock);
186
		frame_size = crtc->hwmode.crtc_htotal *
188
		frame_size = crtc->hwmode.crtc_htotal *
187
				crtc->hwmode.crtc_vtotal;
189
				crtc->hwmode.crtc_vtotal;
188
		framedur_ns = (s64) div64_u64((u64) frame_size * 1000000000,
190
		framedur_ns = (s64) div64_u64((u64) frame_size * 1000000000,
189
					      dotclock);
191
					      dotclock);
190
	} else
192
	} else
191
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
193
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
192
			  crtc->base.id);
194
			  crtc->base.id);
193
 
195
 
194
	crtc->pixeldur_ns = pixeldur_ns;
196
	crtc->pixeldur_ns = pixeldur_ns;
195
	crtc->linedur_ns  = linedur_ns;
197
	crtc->linedur_ns  = linedur_ns;
196
	crtc->framedur_ns = framedur_ns;
198
	crtc->framedur_ns = framedur_ns;
197
 
199
 
198
	DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
200
	DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
199
		  crtc->base.id, crtc->hwmode.crtc_htotal,
201
		  crtc->base.id, crtc->hwmode.crtc_htotal,
200
		  crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay);
202
		  crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay);
201
	DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
203
	DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
202
		  crtc->base.id, (int) dotclock/1000, (int) framedur_ns,
204
		  crtc->base.id, (int) dotclock/1000, (int) framedur_ns,
203
		  (int) linedur_ns, (int) pixeldur_ns);
205
		  (int) linedur_ns, (int) pixeldur_ns);
204
}
206
}
-
 
207
EXPORT_SYMBOL(drm_calc_timestamping_constants);
-
 
208
 
-
 
209
/**
-
 
210
 * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms
-
 
211
 * drivers. Implements calculation of exact vblank timestamps from
-
 
212
 * given drm_display_mode timings and current video scanout position
-
 
213
 * of a crtc. This can be called from within get_vblank_timestamp()
-
 
214
 * implementation of a kms driver to implement the actual timestamping.
-
 
215
 *
-
 
216
 * Should return timestamps conforming to the OML_sync_control OpenML
-
 
217
 * extension specification. The timestamp corresponds to the end of
-
 
218
 * the vblank interval, aka start of scanout of topmost-leftmost display
-
 
219
 * pixel in the following video frame.
-
 
220
 *
-
 
221
 * 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
-
 
223
 * that corresponds to the true scanout timing.
-
 
224
 *
-
 
225
 * The current implementation only handles standard video modes. It
-
 
226
 * returns as no operation if a doublescan or interlaced video mode is
-
 
227
 * active. Higher level code is expected to handle this.
-
 
228
 *
-
 
229
 * @dev: DRM device.
-
 
230
 * @crtc: Which crtc's vblank timestamp to retrieve.
-
 
231
 * @max_error: Desired maximum allowable error in timestamps (nanosecs).
-
 
232
 *             On return contains true maximum error of timestamp.
-
 
233
 * @vblank_time: Pointer to struct timeval which should receive the timestamp.
-
 
234
 * @flags: Flags to pass to driver:
-
 
235
 *         0 = Default.
-
 
236
 *         DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler.
-
 
237
 * @refcrtc: drm_crtc* of crtc which defines scanout timing.
-
 
238
 *
-
 
239
 * Returns negative value on error, failure or if not supported in current
-
 
240
 * video mode:
-
 
241
 *
-
 
242
 * -EINVAL   - Invalid crtc.
-
 
243
 * -EAGAIN   - Temporary unavailable, e.g., called before initial modeset.
-
 
244
 * -ENOTSUPP - Function not supported in current display mode.
-
 
245
 * -EIO      - Failed, e.g., due to failed scanout position query.
-
 
246
 *
-
 
247
 * Returns or'ed positive status flags on success:
-
 
248
 *
-
 
249
 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
-
 
250
 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
-
 
251
 *
-
 
252
 */
-
 
253
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
-
 
254
					  int *max_error,
-
 
255
					  struct timeval *vblank_time,
-
 
256
					  unsigned flags,
-
 
257
					  struct drm_crtc *refcrtc)
-
 
258
{
-
 
259
//	ktime_t stime, etime, mono_time_offset;
-
 
260
	struct timeval tv_etime;
-
 
261
	struct drm_display_mode *mode;
-
 
262
	int vbl_status, vtotal, vdisplay;
-
 
263
	int vpos, hpos, i;
-
 
264
	s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
-
 
265
	bool invbl;
-
 
266
 
-
 
267
	if (crtc < 0 || crtc >= dev->num_crtcs) {
-
 
268
		DRM_ERROR("Invalid crtc %d\n", crtc);
-
 
269
		return -EINVAL;
-
 
270
	}
-
 
271
 
-
 
272
	/* Scanout position query not supported? Should not happen. */
-
 
273
	if (!dev->driver->get_scanout_position) {
-
 
274
		DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
-
 
275
		return -EIO;
-
 
276
	}
-
 
277
 
-
 
278
	mode = &refcrtc->hwmode;
-
 
279
	vtotal = mode->crtc_vtotal;
-
 
280
	vdisplay = mode->crtc_vdisplay;
-
 
281
 
-
 
282
	/* Durations of frames, lines, pixels in nanoseconds. */
-
 
283
	framedur_ns = refcrtc->framedur_ns;
-
 
284
	linedur_ns  = refcrtc->linedur_ns;
-
 
285
	pixeldur_ns = refcrtc->pixeldur_ns;
-
 
286
 
-
 
287
	/* If mode timing undefined, just return as no-op:
-
 
288
	 * Happens during initial modesetting of a crtc.
-
 
289
	 */
-
 
290
	if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) {
-
 
291
		DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
-
 
292
		return -EAGAIN;
-
 
293
	}
-
 
294
 
-
 
295
	return -EIO;
-
 
296
}
-
 
297
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
205
 
298
 
206
 
299
 
207
/**
300
/**
208
 * drm_vblank_pre_modeset - account for vblanks across mode sets
301
 * drm_vblank_pre_modeset - account for vblanks across mode sets
209
 * @dev: DRM device
302
 * @dev: DRM device
210
 * @crtc: CRTC in question
303
 * @crtc: CRTC in question
211
 *
304
 *
212
 * Account for vblank events across mode setting events, which will likely
305
 * Account for vblank events across mode setting events, which will likely
213
 * reset the hardware frame counter.
306
 * reset the hardware frame counter.
214
 */
307
 */
215
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
308
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
216
{
309
{
217
#if 0
310
#if 0
218
    /* vblank is not initialized (IRQ not installed ?) */
311
    /* vblank is not initialized (IRQ not installed ?) */
219
    if (!dev->num_crtcs)
312
    if (!dev->num_crtcs)
220
        return;
313
        return;
221
    /*
314
    /*
222
     * To avoid all the problems that might happen if interrupts
315
     * To avoid all the problems that might happen if interrupts
223
     * were enabled/disabled around or between these calls, we just
316
     * were enabled/disabled around or between these calls, we just
224
     * have the kernel take a reference on the CRTC (just once though
317
     * have the kernel take a reference on the CRTC (just once though
225
     * to avoid corrupting the count if multiple, mismatch calls occur),
318
     * to avoid corrupting the count if multiple, mismatch calls occur),
226
     * so that interrupts remain enabled in the interim.
319
     * so that interrupts remain enabled in the interim.
227
     */
320
     */
228
    if (!dev->vblank_inmodeset[crtc]) {
321
    if (!dev->vblank_inmodeset[crtc]) {
229
        dev->vblank_inmodeset[crtc] = 0x1;
322
        dev->vblank_inmodeset[crtc] = 0x1;
230
        if (drm_vblank_get(dev, crtc) == 0)
323
        if (drm_vblank_get(dev, crtc) == 0)
231
            dev->vblank_inmodeset[crtc] |= 0x2;
324
            dev->vblank_inmodeset[crtc] |= 0x2;
232
    }
325
    }
233
#endif
326
#endif
234
}
327
}
235
EXPORT_SYMBOL(drm_vblank_pre_modeset);
328
EXPORT_SYMBOL(drm_vblank_pre_modeset);
236
 
329
 
237
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
330
void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
238
{
331
{
239
#if 0
332
#if 0
240
    unsigned long irqflags;
333
    unsigned long irqflags;
241
 
334
 
242
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
335
	/* vblank is not initialized (IRQ not installed ?), or has been freed */
243
	if (!dev->num_crtcs)
336
	if (!dev->num_crtcs)
244
		return;
337
		return;
245
 
338
 
246
    if (dev->vblank_inmodeset[crtc]) {
339
    if (dev->vblank_inmodeset[crtc]) {
247
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
340
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
248
        dev->vblank_disable_allowed = 1;
341
        dev->vblank_disable_allowed = 1;
249
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
342
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
250
 
343
 
251
        if (dev->vblank_inmodeset[crtc] & 0x2)
344
        if (dev->vblank_inmodeset[crtc] & 0x2)
252
            drm_vblank_put(dev, crtc);
345
            drm_vblank_put(dev, crtc);
253
 
346
 
254
        dev->vblank_inmodeset[crtc] = 0;
347
        dev->vblank_inmodeset[crtc] = 0;
255
    }
348
    }
256
#endif
349
#endif
257
}
350
}
258
EXPORT_SYMBOL(drm_vblank_post_modeset);
351
EXPORT_SYMBOL(drm_vblank_post_modeset);
259
>
352
>
260
>
353
>