Lines Matching +full:up +full:- +full:counter

1 // SPDX-License-Identifier: MIT
3 * Copyright © 2022-2023 Intel Corporation
25 * increment frame counter (ctg+)
30 * | may be shifted forward 1-3 extra lines via TRANSCONF
37 * ----va---> <-----------------vb--------------------> <--------va-------------
38 * | | <----vs-----> |
39 …* -vbs-----> <---vbs+1---> <---vbs+2---> <-----0-----> <-----1-----> <-----2--- (scanline counter
40 …* -vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2---> <-----0--- (scanline counter
41 …* -vbs-2---> <---vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2- (scanline counter
44 * | increment frame counter (gen3/4)
45 * pixel counter = vblank_start * htotal pixel counter = 0 (gen3/4)
56 * - most events happen at the start of horizontal sync
57 * - frame start happens at the start of horizontal blank, 1-4 lines
59 * - gen3/4 pixel and frame counter are synchronized with the start
68 struct drm_i915_private *dev_priv = to_i915(crtc->dev); in i915_get_vblank_counter()
69 struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[drm_crtc_index(crtc)]; in i915_get_vblank_counter()
70 const struct drm_display_mode *mode = &vblank->hwmode; in i915_get_vblank_counter()
71 enum pipe pipe = to_intel_crtc(crtc)->pipe; in i915_get_vblank_counter()
76 * On i965gm TV output the frame counter only works up to in i915_get_vblank_counter()
78 * frame counter ceases to work and reads zero. We need a in i915_get_vblank_counter()
80 * have to enable vblank interrupts while the frame counter in i915_get_vblank_counter()
82 * does not like us returning non-zero frame counter values in i915_get_vblank_counter()
84 * counter. Thus we must stop non-zero values leaking out. in i915_get_vblank_counter()
86 if (!vblank->max_vblank_count) in i915_get_vblank_counter()
89 htotal = mode->crtc_htotal; in i915_get_vblank_counter()
90 hsync_start = mode->crtc_hsync_start; in i915_get_vblank_counter()
91 vbl_start = mode->crtc_vblank_start; in i915_get_vblank_counter()
92 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in i915_get_vblank_counter()
99 vbl_start -= htotal - hsync_start; in i915_get_vblank_counter()
112 * The frame counter increments at beginning of active. in i915_get_vblank_counter()
113 * Cook up a vblank counter by also checking the pixel in i915_get_vblank_counter()
114 * counter against vblank start. in i915_get_vblank_counter()
121 struct drm_i915_private *dev_priv = to_i915(crtc->dev); in g4x_get_vblank_counter()
122 struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[drm_crtc_index(crtc)]; in g4x_get_vblank_counter()
123 enum pipe pipe = to_intel_crtc(crtc)->pipe; in g4x_get_vblank_counter()
125 if (!vblank->max_vblank_count) in g4x_get_vblank_counter()
133 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in intel_crtc_scanlines_since_frame_timestamp()
135 &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; in intel_crtc_scanlines_since_frame_timestamp()
136 const struct drm_display_mode *mode = &vblank->hwmode; in intel_crtc_scanlines_since_frame_timestamp()
137 u32 htotal = mode->crtc_htotal; in intel_crtc_scanlines_since_frame_timestamp()
138 u32 clock = mode->crtc_clock; in intel_crtc_scanlines_since_frame_timestamp()
154 PIPE_FRMTMSTMP(crtc->pipe)); in intel_crtc_scanlines_since_frame_timestamp()
163 PIPE_FRMTMSTMP(crtc->pipe)); in intel_crtc_scanlines_since_frame_timestamp()
166 return div_u64(mul_u32_u32(scan_curr_time - scan_prev_time, in intel_crtc_scanlines_since_frame_timestamp()
181 &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; in __intel_get_crtc_scanline_from_timestamp()
182 const struct drm_display_mode *mode = &vblank->hwmode; in __intel_get_crtc_scanline_from_timestamp()
183 u32 vblank_start = mode->crtc_vblank_start; in __intel_get_crtc_scanline_from_timestamp()
184 u32 vtotal = mode->crtc_vtotal; in __intel_get_crtc_scanline_from_timestamp()
188 scanline = min(scanline, vtotal - 1); in __intel_get_crtc_scanline_from_timestamp()
200 struct drm_device *dev = crtc->base.dev; in __intel_get_crtc_scanline()
204 enum pipe pipe = crtc->pipe; in __intel_get_crtc_scanline()
207 if (!crtc->active) in __intel_get_crtc_scanline()
210 vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; in __intel_get_crtc_scanline()
211 mode = &vblank->hwmode; in __intel_get_crtc_scanline()
213 if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP) in __intel_get_crtc_scanline()
216 vtotal = mode->crtc_vtotal; in __intel_get_crtc_scanline()
217 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in __intel_get_crtc_scanline()
225 * so we don't accidentally end up spanning a vblank frame in __intel_get_crtc_scanline()
251 return (position + crtc->scanline_offset) % vtotal; in __intel_get_crtc_scanline()
260 struct drm_device *dev = _crtc->dev; in i915_get_crtc_scanoutpos()
263 enum pipe pipe = crtc->pipe; in i915_get_crtc_scanoutpos()
269 crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER; in i915_get_crtc_scanoutpos()
271 if (drm_WARN_ON(&dev_priv->drm, !mode->crtc_clock)) { in i915_get_crtc_scanoutpos()
272 drm_dbg(&dev_priv->drm, in i915_get_crtc_scanoutpos()
278 htotal = mode->crtc_htotal; in i915_get_crtc_scanoutpos()
279 hsync_start = mode->crtc_hsync_start; in i915_get_crtc_scanoutpos()
280 vtotal = mode->crtc_vtotal; in i915_get_crtc_scanoutpos()
281 vbl_start = mode->crtc_vblank_start; in i915_get_crtc_scanoutpos()
282 vbl_end = mode->crtc_vblank_end; in i915_get_crtc_scanoutpos()
284 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { in i915_get_crtc_scanoutpos()
295 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); in i915_get_crtc_scanoutpos()
303 if (crtc->mode_flags & I915_MODE_FLAG_VRR) { in i915_get_crtc_scanoutpos()
315 position = min(crtc->vmax_vblank_start + scanlines, vtotal - 1); in i915_get_crtc_scanoutpos()
335 * In interlaced modes, the pixel counter counts all pixels, in i915_get_crtc_scanoutpos()
338 * counter is beyond the length of the shorter field, just in i915_get_crtc_scanoutpos()
340 * matches how the scanline counter based position works since in i915_get_crtc_scanoutpos()
341 * the scanline counter doesn't count the two half lines. in i915_get_crtc_scanoutpos()
343 position = min(position, vtotal - 1); in i915_get_crtc_scanoutpos()
352 * always add htotal-hsync_start to the current pixel position. in i915_get_crtc_scanoutpos()
354 position = (position + htotal - hsync_start) % vtotal; in i915_get_crtc_scanoutpos()
363 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); in i915_get_crtc_scanoutpos()
367 * counting up towards 0 at vbl_end. And outside in i915_get_crtc_scanoutpos()
369 * up since vbl_end. in i915_get_crtc_scanoutpos()
372 position -= vbl_end; in i915_get_crtc_scanoutpos()
374 position += vtotal - vbl_end; in i915_get_crtc_scanoutpos()
381 *hpos = position - (*vpos * htotal); in i915_get_crtc_scanoutpos()
397 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in intel_get_crtc_scanline()
401 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); in intel_get_crtc_scanline()
403 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); in intel_get_crtc_scanline()
423 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in wait_for_pipe_scanline_moving()
424 enum pipe pipe = crtc->pipe; in wait_for_pipe_scanline_moving()
428 drm_err(&dev_priv->drm, in wait_for_pipe_scanline_moving()
445 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); in intel_crtc_scanline_offset()
446 const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; in intel_crtc_scanline_offset()
449 * The scanline counter increments at the leading edge of hsync. in intel_crtc_scanline_offset()
451 * On most platforms it starts counting from vtotal-1 on the in intel_crtc_scanline_offset()
452 * first active line. That means the scanline counter value is in intel_crtc_scanline_offset()
455 * last active line), the scanline counter will read vblank_start-1. in intel_crtc_scanline_offset()
457 * On gen2 the scanline counter starts counting from 1 instead in intel_crtc_scanline_offset()
458 * of vtotal-1, so we have to subtract one (or rather add vtotal-1 in intel_crtc_scanline_offset()
461 * On HSW+ the behaviour of the scanline counter depends on the output in intel_crtc_scanline_offset()
466 * On VLV/CHV DSI the scanline counter would appear to increment in intel_crtc_scanline_offset()
471 * the scanline counter from within the vblank interrupt handler. in intel_crtc_scanline_offset()
478 vtotal = adjusted_mode->crtc_vtotal; in intel_crtc_scanline_offset()
479 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) in intel_crtc_scanline_offset()
482 return vtotal - 1; in intel_crtc_scanline_offset()
493 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_update_active_timings()
494 struct drm_i915_private *i915 = to_i915(crtc->base.dev); in intel_crtc_update_active_timings()
495 u8 mode_flags = crtc_state->mode_flags; in intel_crtc_update_active_timings()
500 drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode); in intel_crtc_update_active_timings()
503 drm_WARN_ON(&i915->drm, (mode_flags & I915_MODE_FLAG_VRR) == 0); in intel_crtc_update_active_timings()
505 adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax; in intel_crtc_update_active_timings()
506 adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax; in intel_crtc_update_active_timings()
525 spin_lock_irqsave(&i915->drm.vblank_time_lock, irqflags); in intel_crtc_update_active_timings()
526 spin_lock(&i915->uncore.lock); in intel_crtc_update_active_timings()
528 drm_calc_timestamping_constants(&crtc->base, &adjusted_mode); in intel_crtc_update_active_timings()
530 crtc->vmax_vblank_start = vmax_vblank_start; in intel_crtc_update_active_timings()
532 crtc->mode_flags = mode_flags; in intel_crtc_update_active_timings()
534 crtc->scanline_offset = intel_crtc_scanline_offset(crtc_state); in intel_crtc_update_active_timings()
536 spin_unlock(&i915->uncore.lock); in intel_crtc_update_active_timings()
537 spin_unlock_irqrestore(&i915->drm.vblank_time_lock, irqflags); in intel_crtc_update_active_timings()