Lines Matching +full:display +full:- +full:pipe

1 // SPDX-License-Identifier: MIT
3 * Copyright © 2022-2023 Intel Corporation
34 * | may be shifted forward 1-3 extra lines via TRANSCONF
41 * ----va---> <-----------------vb--------------------> <--------va-------------
42 * | | <----vs-----> |
43 …* -vbs-----> <---vbs+1---> <---vbs+2---> <-----0-----> <-----1-----> <-----2--- (scanline counter …
44 …* -vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2---> <-----0--- (scanline counter …
45 …* -vbs-2---> <---vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2- (scanline counter …
60 * - most events happen at the start of horizontal sync
61 * - frame start happens at the start of horizontal blank, 1-4 lines
63 * - gen3/4 pixel and frame counter are synchronized with the start
68 * Called from drm generic code, passed a 'crtc', which we use as a pipe index.
72 struct intel_display *display = to_intel_display(crtc->dev); in i915_get_vblank_counter() local
74 const struct drm_display_mode *mode = &vblank->hwmode; in i915_get_vblank_counter()
75 enum pipe pipe = to_intel_crtc(crtc)->pipe; in i915_get_vblank_counter() local
86 * does not like us returning non-zero frame counter values in i915_get_vblank_counter()
88 * counter. Thus we must stop non-zero values leaking out. in i915_get_vblank_counter()
90 if (!vblank->max_vblank_count) in i915_get_vblank_counter()
93 htotal = mode->crtc_htotal; in i915_get_vblank_counter()
94 hsync_start = mode->crtc_hsync_start; in i915_get_vblank_counter()
101 vbl_start -= htotal - hsync_start; in i915_get_vblank_counter()
108 frame = intel_de_read64_2x32(display, PIPEFRAMEPIXEL(display, pipe), in i915_get_vblank_counter()
109 PIPEFRAME(display, pipe)); in i915_get_vblank_counter()
124 struct intel_display *display = to_intel_display(crtc->dev); in g4x_get_vblank_counter() local
126 enum pipe pipe = to_intel_crtc(crtc)->pipe; in g4x_get_vblank_counter() local
128 if (!vblank->max_vblank_count) in g4x_get_vblank_counter()
131 return intel_de_read(display, PIPE_FRMCOUNT_G4X(display, pipe)); in g4x_get_vblank_counter()
136 struct intel_display *display = to_intel_display(crtc); in intel_crtc_scanlines_since_frame_timestamp() local
137 struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base); in intel_crtc_scanlines_since_frame_timestamp()
138 const struct drm_display_mode *mode = &vblank->hwmode; in intel_crtc_scanlines_since_frame_timestamp()
139 u32 htotal = mode->crtc_htotal; in intel_crtc_scanlines_since_frame_timestamp()
140 u32 clock = mode->crtc_clock; in intel_crtc_scanlines_since_frame_timestamp()
151 * This field provides read back of the display in intel_crtc_scanlines_since_frame_timestamp()
152 * pipe frame time stamp. The time stamp value in intel_crtc_scanlines_since_frame_timestamp()
155 scan_prev_time = intel_de_read_fw(display, in intel_crtc_scanlines_since_frame_timestamp()
156 PIPE_FRMTMSTMP(crtc->pipe)); in intel_crtc_scanlines_since_frame_timestamp()
162 scan_curr_time = intel_de_read_fw(display, IVB_TIMESTAMP_CTR); in intel_crtc_scanlines_since_frame_timestamp()
164 scan_post_time = intel_de_read_fw(display, in intel_crtc_scanlines_since_frame_timestamp()
165 PIPE_FRMTMSTMP(crtc->pipe)); in intel_crtc_scanlines_since_frame_timestamp()
168 return div_u64(mul_u32_u32(scan_curr_time - scan_prev_time, in intel_crtc_scanlines_since_frame_timestamp()
173 * On certain encoders on certain platforms, pipe
182 struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base); in __intel_get_crtc_scanline_from_timestamp()
183 const struct drm_display_mode *mode = &vblank->hwmode; in __intel_get_crtc_scanline_from_timestamp()
184 u32 vblank_start = mode->crtc_vblank_start; in __intel_get_crtc_scanline_from_timestamp()
185 u32 vtotal = mode->crtc_vtotal; in __intel_get_crtc_scanline_from_timestamp()
189 scanline = min(scanline, vtotal - 1); in __intel_get_crtc_scanline_from_timestamp()
197 struct intel_display *display = to_intel_display(crtc_state); in intel_crtc_scanline_offset() local
202 * On most platforms it starts counting from vtotal-1 on the in intel_crtc_scanline_offset()
206 * last active line), the scanline counter will read vblank_start-1. in intel_crtc_scanline_offset()
209 * of vtotal-1, so we have to subtract one. in intel_crtc_scanline_offset()
225 if (DISPLAY_VER(display) >= 20 || display->platform.battlemage) in intel_crtc_scanline_offset()
227 else if (DISPLAY_VER(display) == 2) in intel_crtc_scanline_offset()
228 return -1; in intel_crtc_scanline_offset()
229 else if (HAS_DDI(display) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) in intel_crtc_scanline_offset()
236 * intel_de_read_fw(), only for fast reads of display block, no need for
241 struct intel_display *display = to_intel_display(crtc); in __intel_get_crtc_scanline() local
242 struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base); in __intel_get_crtc_scanline()
243 const struct drm_display_mode *mode = &vblank->hwmode; in __intel_get_crtc_scanline()
244 enum pipe pipe = crtc->pipe; in __intel_get_crtc_scanline() local
247 if (!crtc->active) in __intel_get_crtc_scanline()
250 if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP) in __intel_get_crtc_scanline()
255 position = intel_de_read_fw(display, PIPEDSL(display, pipe)) & PIPEDSL_LINE_MASK; in __intel_get_crtc_scanline()
269 if (HAS_DDI(display) && !position) { in __intel_get_crtc_scanline()
274 temp = intel_de_read_fw(display, in __intel_get_crtc_scanline()
275 PIPEDSL(display, pipe)) & PIPEDSL_LINE_MASK; in __intel_get_crtc_scanline()
287 return (position + vtotal + crtc->scanline_offset) % vtotal; in __intel_get_crtc_scanline()
301 static void intel_vblank_section_enter(struct intel_display *display) in intel_vblank_section_enter() argument
302 __acquires(i915->uncore.lock) in intel_vblank_section_enter()
304 struct drm_i915_private *i915 = to_i915(display->drm); in intel_vblank_section_enter()
305 spin_lock(&i915->uncore.lock); in intel_vblank_section_enter()
308 static void intel_vblank_section_exit(struct intel_display *display) in intel_vblank_section_exit() argument
309 __releases(i915->uncore.lock) in intel_vblank_section_exit()
311 struct drm_i915_private *i915 = to_i915(display->drm); in intel_vblank_section_exit()
312 spin_unlock(&i915->uncore.lock); in intel_vblank_section_exit()
315 static void intel_vblank_section_enter(struct intel_display *display) in intel_vblank_section_enter() argument
319 static void intel_vblank_section_exit(struct intel_display *display) in intel_vblank_section_exit() argument
330 struct intel_display *display = to_intel_display(_crtc->dev); in i915_get_crtc_scanoutpos() local
332 enum pipe pipe = crtc->pipe; in i915_get_crtc_scanoutpos() local
336 bool use_scanline_counter = DISPLAY_VER(display) >= 5 || in i915_get_crtc_scanoutpos()
337 display->platform.g4x || DISPLAY_VER(display) == 2 || in i915_get_crtc_scanoutpos()
338 crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER; in i915_get_crtc_scanoutpos()
340 if (drm_WARN_ON(display->drm, !mode->crtc_clock)) { in i915_get_crtc_scanoutpos()
341 drm_dbg(display->drm, in i915_get_crtc_scanoutpos()
342 "trying to get scanoutpos for disabled pipe %c\n", in i915_get_crtc_scanoutpos()
343 pipe_name(pipe)); in i915_get_crtc_scanoutpos()
347 htotal = mode->crtc_htotal; in i915_get_crtc_scanoutpos()
348 hsync_start = mode->crtc_hsync_start; in i915_get_crtc_scanoutpos()
359 intel_vblank_section_enter(display); in i915_get_crtc_scanoutpos()
367 if (crtc->mode_flags & I915_MODE_FLAG_VRR) { in i915_get_crtc_scanoutpos()
379 position = min(crtc->vmax_vblank_start + scanlines, vtotal - 1); in i915_get_crtc_scanoutpos()
382 * scanout position from Display scan line register. in i915_get_crtc_scanoutpos()
391 …position = (intel_de_read_fw(display, PIPEFRAMEPIXEL(display, pipe)) & PIPE_PIXEL_MASK) >> PIPE_PI… in i915_get_crtc_scanoutpos()
407 position = min(position, vtotal - 1); in i915_get_crtc_scanoutpos()
416 * always add htotal-hsync_start to the current pixel position. in i915_get_crtc_scanoutpos()
418 position = (position + htotal - hsync_start) % vtotal; in i915_get_crtc_scanoutpos()
427 intel_vblank_section_exit(display); in i915_get_crtc_scanoutpos()
437 position -= vbl_end; in i915_get_crtc_scanoutpos()
439 position += vtotal - vbl_end; in i915_get_crtc_scanoutpos()
446 *hpos = position - (*vpos * htotal); in i915_get_crtc_scanoutpos()
462 struct intel_display *display = to_intel_display(crtc); in intel_get_crtc_scanline() local
467 intel_vblank_section_enter(display); in intel_get_crtc_scanline()
471 intel_vblank_section_exit(display); in intel_get_crtc_scanline()
477 static bool pipe_scanline_is_moving(struct intel_display *display, in pipe_scanline_is_moving() argument
478 enum pipe pipe) in pipe_scanline_is_moving() argument
480 i915_reg_t reg = PIPEDSL(display, pipe); in pipe_scanline_is_moving()
483 line1 = intel_de_read(display, reg) & PIPEDSL_LINE_MASK; in pipe_scanline_is_moving()
485 line2 = intel_de_read(display, reg) & PIPEDSL_LINE_MASK; in pipe_scanline_is_moving()
492 struct intel_display *display = to_intel_display(crtc); in wait_for_pipe_scanline_moving() local
493 enum pipe pipe = crtc->pipe; in wait_for_pipe_scanline_moving() local
495 /* Wait for the display line to settle/start moving */ in wait_for_pipe_scanline_moving()
496 if (wait_for(pipe_scanline_is_moving(display, pipe) == state, 100)) in wait_for_pipe_scanline_moving()
497 drm_err(display->drm, in wait_for_pipe_scanline_moving()
498 "pipe %c scanline %s wait timed out\n", in wait_for_pipe_scanline_moving()
499 pipe_name(pipe), str_on_off(state)); in wait_for_pipe_scanline_moving()
517 drm_mode_init(mode, &crtc_state->hw.adjusted_mode); in intel_crtc_active_timings()
523 mode->crtc_vtotal = intel_vrr_vmax_vtotal(crtc_state); in intel_crtc_active_timings()
524 mode->crtc_vblank_end = intel_vrr_vmax_vtotal(crtc_state); in intel_crtc_active_timings()
525 mode->crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state); in intel_crtc_active_timings()
532 struct intel_display *display = to_intel_display(crtc_state); in intel_crtc_update_active_timings() local
533 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_update_active_timings()
534 u8 mode_flags = crtc_state->mode_flags; in intel_crtc_update_active_timings()
543 drm_WARN_ON(display->drm, (mode_flags & I915_MODE_FLAG_VRR) == 0); in intel_crtc_update_active_timings()
559 spin_lock_irqsave(&display->drm->vblank_time_lock, irqflags); in intel_crtc_update_active_timings()
560 intel_vblank_section_enter(display); in intel_crtc_update_active_timings()
562 drm_calc_timestamping_constants(&crtc->base, &adjusted_mode); in intel_crtc_update_active_timings()
564 crtc->vmax_vblank_start = vmax_vblank_start; in intel_crtc_update_active_timings()
566 crtc->mode_flags = mode_flags; in intel_crtc_update_active_timings()
568 crtc->scanline_offset = intel_crtc_scanline_offset(crtc_state); in intel_crtc_update_active_timings()
569 intel_vblank_section_exit(display); in intel_crtc_update_active_timings()
570 spin_unlock_irqrestore(&display->drm->vblank_time_lock, irqflags); in intel_crtc_update_active_timings()
575 int vdisplay = mode->crtc_vdisplay; in intel_mode_vdisplay()
577 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in intel_mode_vdisplay()
585 int vblank_start = mode->crtc_vblank_start; in intel_mode_vblank_start()
587 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in intel_mode_vblank_start()
595 int vblank_end = mode->crtc_vblank_end; in intel_mode_vblank_end()
597 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in intel_mode_vblank_end()
605 int vtotal = mode->crtc_vtotal; in intel_mode_vtotal()
607 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in intel_mode_vtotal()
615 return intel_mode_vblank_start(mode) - intel_mode_vdisplay(mode); in intel_mode_vblank_delay()
648 struct intel_display *display = to_intel_display(new_crtc_state); in intel_vblank_evade_init() local
649 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); in intel_vblank_evade_init()
654 evade->crtc = crtc; in intel_vblank_evade_init()
656 evade->need_vlv_dsi_wa = (display->platform.valleyview || in intel_vblank_evade_init()
657 display->platform.cherryview) && in intel_vblank_evade_init()
663 adjusted_mode = &crtc_state->hw.adjusted_mode; in intel_vblank_evade_init()
665 if (crtc->mode_flags & I915_MODE_FLAG_VRR) { in intel_vblank_evade_init()
667 drm_WARN_ON(crtc->base.dev, intel_crtc_needs_modeset(new_crtc_state) || in intel_vblank_evade_init()
668 new_crtc_state->update_m_n || new_crtc_state->update_lrr); in intel_vblank_evade_init()
671 evade->vblank_start = intel_vrr_vmin_vblank_start(crtc_state); in intel_vblank_evade_init()
673 evade->vblank_start = intel_vrr_vmax_vblank_start(crtc_state); in intel_vblank_evade_init()
677 evade->vblank_start = intel_mode_vblank_start(adjusted_mode); in intel_vblank_evade_init()
683 evade->min = evade->vblank_start - intel_usecs_to_scanlines(adjusted_mode, in intel_vblank_evade_init()
685 evade->max = evade->vblank_start - 1; in intel_vblank_evade_init()
696 new_crtc_state->update_m_n || new_crtc_state->update_lrr) in intel_vblank_evade_init()
697 evade->min -= vblank_delay; in intel_vblank_evade_init()
703 struct intel_crtc *crtc = evade->crtc; in intel_vblank_evade()
704 struct intel_display *display = to_intel_display(crtc); in intel_vblank_evade() local
706 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); in intel_vblank_evade()
710 if (evade->min <= 0 || evade->max <= 0) in intel_vblank_evade()
722 if (scanline < evade->min || scanline > evade->max) in intel_vblank_evade()
726 drm_err(display->drm, in intel_vblank_evade()
727 "Potential atomic update failure on pipe %c\n", in intel_vblank_evade()
728 pipe_name(crtc->pipe)); in intel_vblank_evade()
756 while (evade->need_vlv_dsi_wa && scanline == evade->vblank_start) in intel_vblank_evade()