Lines Matching +full:display +full:- +full:pipe
1 // SPDX-License-Identifier: MIT
40 struct intel_display *display = to_intel_display(crtc->dev); in assert_vblank_disabled() local
42 if (INTEL_DISPLAY_STATE_WARN(display, drm_crtc_vblank_get(crtc) == 0, in assert_vblank_disabled()
44 crtc->base.id, crtc->name)) in assert_vblank_disabled()
48 struct intel_crtc *intel_first_crtc(struct intel_display *display) in intel_first_crtc() argument
50 return to_intel_crtc(drm_crtc_from_index(display->drm, 0)); in intel_first_crtc()
53 struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display, in intel_crtc_for_pipe() argument
54 enum pipe pipe) in intel_crtc_for_pipe() argument
58 for_each_intel_crtc(display->drm, crtc) { in intel_crtc_for_pipe()
59 if (crtc->pipe == pipe) in intel_crtc_for_pipe()
68 drm_crtc_wait_one_vblank(&crtc->base); in intel_crtc_wait_for_next_vblank()
71 void intel_wait_for_vblank_if_active(struct intel_display *display, in intel_wait_for_vblank_if_active() argument
72 enum pipe pipe) in intel_wait_for_vblank_if_active() argument
74 struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); in intel_wait_for_vblank_if_active()
76 if (crtc->active) in intel_wait_for_vblank_if_active()
82 struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base); in intel_crtc_get_vblank_counter()
84 if (!crtc->active) in intel_crtc_get_vblank_counter()
87 if (!vblank->max_vblank_count) in intel_crtc_get_vblank_counter()
88 return (u32)drm_crtc_accurate_vblank_count(&crtc->base); in intel_crtc_get_vblank_counter()
90 return crtc->base.funcs->get_vblank_counter(&crtc->base); in intel_crtc_get_vblank_counter()
95 struct intel_display *display = to_intel_display(crtc_state); in intel_crtc_max_vblank_count() local
103 if (crtc_state->mode_flags & (I915_MODE_FLAG_DSI_USE_TE0 | in intel_crtc_max_vblank_count()
111 if (display->platform.i965gm && in intel_crtc_max_vblank_count()
112 (crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT))) in intel_crtc_max_vblank_count()
115 if (DISPLAY_VER(display) >= 5 || display->platform.g4x) in intel_crtc_max_vblank_count()
117 else if (DISPLAY_VER(display) >= 3) in intel_crtc_max_vblank_count()
125 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_vblank_on()
127 crtc->block_dc_for_vblank = intel_psr_needs_block_dc_vblank(crtc_state); in intel_crtc_vblank_on()
129 assert_vblank_disabled(&crtc->base); in intel_crtc_vblank_on()
130 drm_crtc_set_max_vblank_count(&crtc->base, in intel_crtc_vblank_on()
132 drm_crtc_vblank_on(&crtc->base); in intel_crtc_vblank_on()
135 * Should really happen exactly when we enable the pipe in intel_crtc_vblank_on()
144 struct intel_display *display = to_intel_display(crtc_state); in intel_crtc_vblank_off() local
145 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_vblank_off()
148 * Should really happen exactly when we disable the pipe in intel_crtc_vblank_off()
154 drm_crtc_vblank_off(&crtc->base); in intel_crtc_vblank_off()
155 assert_vblank_disabled(&crtc->base); in intel_crtc_vblank_off()
157 crtc->block_dc_for_vblank = false; in intel_crtc_vblank_off()
159 flush_work(&display->irq.vblank_dc_work); in intel_crtc_vblank_off()
179 __drm_atomic_helper_crtc_state_reset(&crtc_state->uapi, &crtc->base); in intel_crtc_state_reset()
181 crtc_state->cpu_transcoder = INVALID_TRANSCODER; in intel_crtc_state_reset()
182 crtc_state->master_transcoder = INVALID_TRANSCODER; in intel_crtc_state_reset()
183 crtc_state->hsw_workaround_pipe = INVALID_PIPE; in intel_crtc_state_reset()
184 crtc_state->scaler_state.scaler_id = -1; in intel_crtc_state_reset()
185 crtc_state->mst_master_transcoder = INVALID_TRANSCODER; in intel_crtc_state_reset()
186 crtc_state->max_link_bpp_x16 = INT_MAX; in intel_crtc_state_reset()
196 return ERR_PTR(-ENOMEM); in intel_crtc_alloc()
201 return ERR_PTR(-ENOMEM); in intel_crtc_alloc()
204 crtc->base.state = &crtc_state->uapi; in intel_crtc_alloc()
205 crtc->config = crtc_state; in intel_crtc_alloc()
212 intel_crtc_destroy_state(&crtc->base, crtc->base.state); in intel_crtc_free()
220 cpu_latency_qos_remove_request(&crtc->vblank_pm_qos); in intel_crtc_destroy()
222 drm_crtc_cleanup(&crtc->base); in intel_crtc_destroy()
306 int intel_crtc_init(struct intel_display *display, enum pipe pipe) in intel_crtc_init() argument
308 struct drm_i915_private *dev_priv = to_i915(display->drm); in intel_crtc_init()
318 crtc->pipe = pipe; in intel_crtc_init()
319 crtc->num_scalers = DISPLAY_RUNTIME_INFO(display)->num_scalers[pipe]; in intel_crtc_init()
321 if (DISPLAY_VER(display) >= 9) in intel_crtc_init()
322 primary = skl_universal_plane_create(display, pipe, PLANE_1); in intel_crtc_init()
324 primary = intel_primary_plane_create(display, pipe); in intel_crtc_init()
329 crtc->plane_ids_mask |= BIT(primary->id); in intel_crtc_init()
331 intel_init_fifo_underrun_reporting(display, crtc, false); in intel_crtc_init()
333 for_each_sprite(display, pipe, sprite) { in intel_crtc_init()
337 plane = skl_universal_plane_create(display, pipe, PLANE_2 + sprite); in intel_crtc_init()
339 plane = intel_sprite_plane_create(display, pipe, sprite); in intel_crtc_init()
344 crtc->plane_ids_mask |= BIT(plane->id); in intel_crtc_init()
347 cursor = intel_cursor_plane_create(display, pipe); in intel_crtc_init()
352 crtc->plane_ids_mask |= BIT(cursor->id); in intel_crtc_init()
354 if (HAS_GMCH(display)) { in intel_crtc_init()
355 if (display->platform.cherryview || in intel_crtc_init()
356 display->platform.valleyview || in intel_crtc_init()
357 display->platform.g4x) in intel_crtc_init()
359 else if (DISPLAY_VER(display) == 4) in intel_crtc_init()
361 else if (display->platform.i945gm || in intel_crtc_init()
362 display->platform.i915gm) in intel_crtc_init()
364 else if (DISPLAY_VER(display) == 3) in intel_crtc_init()
369 if (DISPLAY_VER(display) >= 8) in intel_crtc_init()
375 ret = drm_crtc_init_with_planes(display->drm, &crtc->base, in intel_crtc_init()
376 &primary->base, &cursor->base, in intel_crtc_init()
377 funcs, "pipe %c", pipe_name(pipe)); in intel_crtc_init()
381 if (DISPLAY_VER(display) >= 11) in intel_crtc_init()
382 drm_crtc_create_scaling_filter_property(&crtc->base, in intel_crtc_init()
390 cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE); in intel_crtc_init()
392 drm_WARN_ON(display->drm, drm_crtc_index(&crtc->base) != crtc->pipe); in intel_crtc_init()
409 drm_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id); in intel_crtc_get_pipe_from_crtc_id_ioctl()
411 return -ENOENT; in intel_crtc_get_pipe_from_crtc_id_ioctl()
414 pipe_from_crtc_id->pipe = crtc->pipe; in intel_crtc_get_pipe_from_crtc_id_ioctl()
421 return crtc_state->hw.active && in intel_crtc_needs_vblank_work()
422 !crtc_state->preload_luts && in intel_crtc_needs_vblank_work()
426 !crtc_state->use_dsb; in intel_crtc_needs_vblank_work()
434 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_vblank_work()
440 if (crtc_state->uapi.event) { in intel_crtc_vblank_work()
441 spin_lock_irq(&crtc->base.dev->event_lock); in intel_crtc_vblank_work()
442 drm_crtc_send_vblank_event(&crtc->base, crtc_state->uapi.event); in intel_crtc_vblank_work()
443 spin_unlock_irq(&crtc->base.dev->event_lock); in intel_crtc_vblank_work()
444 crtc_state->uapi.event = NULL; in intel_crtc_vblank_work()
452 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_vblank_work_init()
454 drm_vblank_work_init(&crtc_state->vblank_work, &crtc->base, in intel_crtc_vblank_work_init()
460 cpu_latency_qos_update_request(&crtc->vblank_pm_qos, 0); in intel_crtc_vblank_work_init()
473 drm_vblank_work_flush(&crtc_state->vblank_work); in intel_wait_for_vblank_workers()
474 cpu_latency_qos_update_request(&crtc->vblank_pm_qos, in intel_wait_for_vblank_workers()
483 if (!adjusted_mode->crtc_htotal) in intel_usecs_to_scanlines()
486 return DIV_ROUND_UP_ULL(mul_u32_u32(usecs, adjusted_mode->crtc_clock), in intel_usecs_to_scanlines()
487 1000 * adjusted_mode->crtc_htotal); in intel_usecs_to_scanlines()
494 if (!adjusted_mode->crtc_clock) in intel_scanlines_to_usecs()
497 return DIV_ROUND_UP_ULL(mul_u32_u32(scanlines, adjusted_mode->crtc_htotal * 1000), in intel_scanlines_to_usecs()
498 adjusted_mode->crtc_clock); in intel_scanlines_to_usecs()
502 * intel_pipe_update_start() - start update of a set of display registers
506 * Mark the start of an update to pipe registers that should be updated
517 struct intel_display *display = to_intel_display(state); in intel_pipe_update_start() local
525 drm_WARN_ON(display->drm, new_crtc_state->use_dsb); in intel_pipe_update_start()
529 if (new_crtc_state->do_async_flip) { in intel_pipe_update_start()
531 &crtc->flip_done_event); in intel_pipe_update_start()
538 if (state->base.legacy_cursor_update) { in intel_pipe_update_start()
545 if (old_plane_state->uapi.crtc == &crtc->base) in intel_pipe_update_start()
553 if (drm_WARN_ON(display->drm, drm_crtc_vblank_get(&crtc->base))) in intel_pipe_update_start()
559 * re-entry as well. in intel_pipe_update_start()
565 crtc->debug.min_vbl = evade.min; in intel_pipe_update_start()
566 crtc->debug.max_vbl = evade.max; in intel_pipe_update_start()
571 drm_crtc_vblank_put(&crtc->base); in intel_pipe_update_start()
573 crtc->debug.scanline_start = scanline; in intel_pipe_update_start()
574 crtc->debug.start_vbl_time = ktime_get(); in intel_pipe_update_start()
575 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); in intel_pipe_update_start()
587 u64 delta = ktime_to_ns(ktime_sub(end, crtc->debug.start_vbl_time)); in dbg_vblank_evade()
591 if (h >= ARRAY_SIZE(crtc->debug.vbl.times)) in dbg_vblank_evade()
592 h = ARRAY_SIZE(crtc->debug.vbl.times) - 1; in dbg_vblank_evade()
593 crtc->debug.vbl.times[h]++; in dbg_vblank_evade()
595 crtc->debug.vbl.sum += delta; in dbg_vblank_evade()
596 if (!crtc->debug.vbl.min || delta < crtc->debug.vbl.min) in dbg_vblank_evade()
597 crtc->debug.vbl.min = delta; in dbg_vblank_evade()
598 if (delta > crtc->debug.vbl.max) in dbg_vblank_evade()
599 crtc->debug.vbl.max = delta; in dbg_vblank_evade()
602 drm_dbg_kms(crtc->base.dev, in dbg_vblank_evade()
603 "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", in dbg_vblank_evade()
604 pipe_name(crtc->pipe), in dbg_vblank_evade()
607 crtc->debug.vbl.over++; in dbg_vblank_evade()
616 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_arm_vblank_event()
619 if (!crtc_state->uapi.event) in intel_crtc_arm_vblank_event()
622 drm_WARN_ON(crtc->base.dev, drm_crtc_vblank_get(&crtc->base) != 0); in intel_crtc_arm_vblank_event()
624 spin_lock_irqsave(&crtc->base.dev->event_lock, irqflags); in intel_crtc_arm_vblank_event()
625 drm_crtc_arm_vblank_event(&crtc->base, crtc_state->uapi.event); in intel_crtc_arm_vblank_event()
626 spin_unlock_irqrestore(&crtc->base.dev->event_lock, irqflags); in intel_crtc_arm_vblank_event()
628 crtc_state->uapi.event = NULL; in intel_crtc_arm_vblank_event()
634 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_crtc_prepare_vblank_event()
637 spin_lock_irqsave(&crtc->base.dev->event_lock, irqflags); in intel_crtc_prepare_vblank_event()
638 *event = crtc_state->uapi.event; in intel_crtc_prepare_vblank_event()
639 spin_unlock_irqrestore(&crtc->base.dev->event_lock, irqflags); in intel_crtc_prepare_vblank_event()
641 crtc_state->uapi.event = NULL; in intel_crtc_prepare_vblank_event()
645 * intel_pipe_update_end() - end update of a set of display registers
650 * re-enables interrupts and verifies the update was actually completed
656 struct intel_display *display = to_intel_display(state); in intel_pipe_update_end() local
659 enum pipe pipe = crtc->pipe; in intel_pipe_update_end() local
663 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in intel_pipe_update_end()
665 drm_WARN_ON(display->drm, new_crtc_state->use_dsb); in intel_pipe_update_end()
667 if (new_crtc_state->do_async_flip) in intel_pipe_update_end()
676 if (DISPLAY_VER(display) >= 11 && in intel_pipe_update_end()
680 /* We're still in the vblank-evade critical section, this can't race. in intel_pipe_update_end()
682 * event outside of the critical section - the spinlock might spin for a in intel_pipe_update_end()
685 drm_vblank_work_schedule(&new_crtc_state->vblank_work, in intel_pipe_update_end()
686 drm_crtc_accurate_vblank_count(&crtc->base) + 1, in intel_pipe_update_end()
692 if (state->base.legacy_cursor_update) { in intel_pipe_update_end()
698 if (old_plane_state->uapi.crtc == &crtc->base && in intel_pipe_update_end()
699 old_plane_state->unpin_work.vblank) { in intel_pipe_update_end()
700 drm_vblank_work_schedule(&old_plane_state->unpin_work, in intel_pipe_update_end()
701 drm_crtc_accurate_vblank_count(&crtc->base) + 1, in intel_pipe_update_end()
705 memset(&state->base.planes[i], 0, sizeof(state->base.planes[i])); in intel_pipe_update_end()
724 if (!state->base.legacy_cursor_update) in intel_pipe_update_end()
732 if (crtc->debug.start_vbl_count && in intel_pipe_update_end()
733 crtc->debug.start_vbl_count != end_vbl_count) { in intel_pipe_update_end()
734 drm_err(display->drm, in intel_pipe_update_end()
735 …"Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %… in intel_pipe_update_end()
736 pipe_name(pipe), crtc->debug.start_vbl_count, in intel_pipe_update_end()
739 crtc->debug.start_vbl_time), in intel_pipe_update_end()
740 crtc->debug.min_vbl, crtc->debug.max_vbl, in intel_pipe_update_end()
741 crtc->debug.scanline_start, scanline_end); in intel_pipe_update_end()