Subversion Repositories Kolibri OS

Rev

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

Rev 4539 Rev 4560
Line 42... Line 42...
42
 
42
 
43
//#include 
43
//#include 
Line 44... Line 44...
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) ( \
-
 
Line 48... Line 47...
48
	(dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
47
#define vblanktimestamp(dev, crtc, count) \
49
	((count) % DRM_VBLANKTIME_RBSIZE)])
48
	((dev)->vblank[crtc].time[(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
Line 100... Line 99...
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;
Line 106... Line 105...
106
    mutex_unlock(&dev->struct_mutex);
105
    mutex_unlock(&dev->struct_mutex);
Line 107... Line 106...
107
 
106
 
Line 148... Line 147...
148
 
147
 
149
        return div_u64(dividend, d);
148
        return div_u64(dividend, d);
Line 150... Line 149...
150
}
149
}
151
 
150
 
152
/**
-
 
153
 * drm_calc_timestamping_constants - Calculate and
-
 
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
151
/**
159
 * adjustments into account.
152
 * drm_calc_timestamping_constants - Calculate vblank timestamp constants
-
 
153
 *
160
 *
154
 * @crtc drm_crtc whose timestamp constants should be updated.
-
 
155
 * @mode display mode containing the scanout timings
-
 
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
161
 * @crtc drm_crtc whose timestamp constants should be updated.
160
 * derived from crtc's true scanout timing, so they take
162
 *
161
 * things like panel scaling or other adjustments into account.
-
 
162
 */
163
 */
163
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
164
void drm_calc_timestamping_constants(struct drm_crtc *crtc)
164
				     const struct drm_display_mode *mode)
165
{
165
{
Line -... Line 166...
-
 
166
	int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
166
	s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
167
	int dotclock = mode->crtc_clock;
167
	u64 dotclock;
168
 
Line -... Line 169...
-
 
169
	/* Valid dotclock? */
168
 
170
	if (dotclock > 0) {
169
	/* Dot clock in Hz: */
171
		int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
-
 
172
 
170
	dotclock = (u64) crtc->hwmode.clock * 1000;
173
		/*
171
 
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
-
 
176
		 * and pixel duration in nanoseconds:
Line 173... Line -...
173
	 * Double the dotclock to get halve the frame-/line-/pixelduration.
-
 
174
	 */
-
 
175
	if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE)
177
	 */
176
		dotclock *= 2;
-
 
177
 
178
		pixeldur_ns = 1000000 / dotclock;
178
	/* Valid dotclock? */
-
 
179
	if (dotclock > 0) {
179
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
180
		int frame_size;
-
 
181
		/* Convert scanline length in pixels and video dot clock to
-
 
182
		 * line duration, frame duration and pixel duration in
-
 
183
		 * nanoseconds:
180
		framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
184
		 */
-
 
185
		pixeldur_ns = (s64) div64_u64(1000000000, dotclock);
-
 
186
		linedur_ns  = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal *
181
 
187
					      1000000000), dotclock);
182
		/*
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
		 */
Line 190... Line 185...
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
Line 193... Line 188...
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",
Line 201... Line 196...
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);
Line 233... Line 228...
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.
Line 252... Line 248...
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;
Line 266... Line 261...
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);
Line 273... Line 268...
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
	}
Line 277... Line -...
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;
Line 285... Line 276...
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);
Line 292... Line 283...
292
		return -EAGAIN;
283
		return -EAGAIN;
Line 316... Line 307...
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);
Line 334... Line 325...
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)
Line 337... Line 328...
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);
Line 341... Line 332...
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);
Line 343... Line 334...
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;