diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_crtc.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_crtc.c | 99 |
1 files changed, 97 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index a187db6df2d3..9d2a23c96c61 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -9,6 +9,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_plane.h> +#include <drm/drm_print.h> #include <drm/drm_vblank.h> #include <drm/drm_vblank_work.h> @@ -84,8 +85,13 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc) if (!crtc->active) return 0; - if (!vblank->max_vblank_count) - return (u32)drm_crtc_accurate_vblank_count(&crtc->base); + if (!vblank->max_vblank_count) { + /* On preempt-rt we cannot take the vblank spinlock since this function is called from tracepoints */ + if (IS_ENABLED(CONFIG_PREEMPT_RT)) + return (u32)drm_crtc_vblank_count(&crtc->base); + else + return (u32)drm_crtc_accurate_vblank_count(&crtc->base); + } return crtc->base.funcs->get_vblank_counter(&crtc->base); } @@ -390,6 +396,9 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) drm_WARN_ON(display->drm, drm_crtc_index(&crtc->base) != crtc->pipe); + if (HAS_CASF(display)) + drm_crtc_create_sharpness_strength_property(&crtc->base); + return 0; fail: @@ -748,3 +757,89 @@ void intel_pipe_update_end(struct intel_atomic_state *state, out: intel_psr_unlock(new_crtc_state); } + +bool intel_crtc_enable_changed(const struct intel_crtc_state *old_crtc_state, + const struct intel_crtc_state *new_crtc_state) +{ + return old_crtc_state->hw.enable != new_crtc_state->hw.enable; +} + +bool intel_any_crtc_enable_changed(struct intel_atomic_state *state) +{ + const struct intel_crtc_state *old_crtc_state, *new_crtc_state; + struct intel_crtc *crtc; + int i; + + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + if (intel_crtc_enable_changed(old_crtc_state, new_crtc_state)) + return true; + } + + return false; +} + +bool intel_crtc_active_changed(const struct intel_crtc_state *old_crtc_state, + const struct intel_crtc_state *new_crtc_state) +{ + return old_crtc_state->hw.active != new_crtc_state->hw.active; +} + +bool intel_any_crtc_active_changed(struct intel_atomic_state *state) +{ + const struct intel_crtc_state *old_crtc_state, *new_crtc_state; + struct intel_crtc *crtc; + int i; + + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + if (intel_crtc_active_changed(old_crtc_state, new_crtc_state)) + return true; + } + + return false; +} + +unsigned int intel_crtc_bw_num_active_planes(const struct intel_crtc_state *crtc_state) +{ + /* + * We assume cursors are small enough + * to not cause bandwidth problems. + */ + return hweight8(crtc_state->active_planes & ~BIT(PLANE_CURSOR)); +} + +unsigned int intel_crtc_bw_data_rate(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + unsigned int data_rate = 0; + enum plane_id plane_id; + + for_each_plane_id_on_crtc(crtc, plane_id) { + /* + * We assume cursors are small enough + * to not cause bandwidth problems. + */ + if (plane_id == PLANE_CURSOR) + continue; + + data_rate += crtc_state->data_rate[plane_id]; + + if (DISPLAY_VER(display) < 11) + data_rate += crtc_state->data_rate_y[plane_id]; + } + + return data_rate; +} + +/* "Maximum Pipe Read Bandwidth" */ +int intel_crtc_bw_min_cdclk(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + if (DISPLAY_VER(display) < 12) + return 0; + + return DIV_ROUND_UP_ULL(mul_u32_u32(intel_crtc_bw_data_rate(crtc_state), 10), 512); +} |
