Enable CMTG with fixed refresh rate mode and with dynamic dc state enabled.
Disable CMTG with transcoder disable or if there is a transition to vrr mode from fixed refresh rate mode. v2: - Move the enabled flag update to avoid issue in the disable timeout path. [Uma] v3: - Introduce intel_cmtg_program() rather calling multiple cmtg functions. [Dibin] - Set clock select before cmtg disable as can lost during dc6 entry. [Dibin] - Disable cmtg interrupt in crtc-disable(). [Dibin] Signed-off-by: Animesh Manna <[email protected]> --- drivers/gpu/drm/i915/display/intel_cmtg.c | 25 ++++++++++---------- drivers/gpu/drm/i915/display/intel_cmtg.h | 4 +--- drivers/gpu/drm/i915/display/intel_display.c | 24 +++++++++++++++++++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c b/drivers/gpu/drm/i915/display/intel_cmtg.c index 1d63b612c44b..b7f4be33ce2e 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.c +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c @@ -323,15 +323,12 @@ void intel_cmtg_set_m_n(const struct intel_crtc_state *crtc_state) intel_de_write(display, PIPE_LINK_N1(display, cmtg_transcoder), m_n->link_n); } -void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state) +static void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 cmtg_ctl; - if (!intel_cmtg_is_allowed(crtc_state)) - return; - cmtg_ctl = CMTG_SYNC_TO_PORT | CMTG_ENABLE; intel_de_rmw(display, TRANS_CMTG_CTL(cpu_transcoder), 0, cmtg_ctl); @@ -342,15 +339,12 @@ void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state) } } -void intel_cmtg_enable_ddi(const struct intel_crtc_state *crtc_state) +static void intel_cmtg_enable_ddi(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); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (!intel_cmtg_is_allowed(crtc_state)) - return; - intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), 0, CMTG_SECONDARY_MODE); intel_de_rmw(display, CMTG_SCANLINE_GB1(cpu_transcoder), 0, CMTG_HW_GB_ENABLE); crtc->cmtg.enabled = true; @@ -406,7 +400,7 @@ void intel_cmtg_disable_interrupt(const struct intel_crtc_state *crtc_state) #define DC3CO_ENTRY_LATENCY 55 #define DC3CO_EXIT_LATENCY 40 -void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state) +static void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; @@ -415,9 +409,6 @@ void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state) u32 line_time_us = 75; u32 val; - if (!intel_cmtg_is_allowed(crtc_state)) - return; - if (crtc_state->linetime) line_time_us = DIV_ROUND_UP(crtc_state->linetime, 8); @@ -433,3 +424,13 @@ void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state) intel_de_write(display, CMTG_HW_GB(cpu_transcoder), val); } + +void intel_cmtg_program(const struct intel_crtc_state *crtc_state) +{ + if (!intel_cmtg_is_allowed(crtc_state)) + return; + + intel_cmtg_enable_sync(crtc_state); + intel_cmtg_set_hwgb(crtc_state); + intel_cmtg_enable_ddi(crtc_state); +} diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h b/drivers/gpu/drm/i915/display/intel_cmtg.h index 2c801a74acf9..51fc3f5a89f4 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.h +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h @@ -12,8 +12,6 @@ struct intel_display; struct intel_crtc_state; void intel_cmtg_disable(const struct intel_crtc_state *crtc_state); -void intel_cmtg_enable_ddi(const struct intel_crtc_state *crtc_state); -void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state); void intel_cmtg_set_m_n(const struct intel_crtc_state *crtc_state); void intel_cmtg_set_vrr_timings(const struct intel_crtc_state *crtc_state); void intel_cmtg_set_vrr_ctl(const struct intel_crtc_state *crtc_state); @@ -23,6 +21,6 @@ void intel_cmtg_sanitize(struct intel_display *display); bool intel_cmtg_is_allowed(const struct intel_crtc_state *crtc_state); void intel_cmtg_enable_interrupt(const struct intel_crtc_state *crtc_state); void intel_cmtg_disable_interrupt(const struct intel_crtc_state *crtc_state); -void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state); +void intel_cmtg_program(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_CMTG_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e4763ac81c39..e751a4c37842 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1790,6 +1790,11 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; + if (crtc->cmtg.enabled) { + intel_cmtg_set_clk_select(old_crtc_state); + intel_cmtg_disable(old_crtc_state); + intel_cmtg_disable_interrupt(old_crtc_state); + } /* * FIXME collapse everything to one hook. * Need care with mst->ddi interactions. @@ -6878,6 +6883,12 @@ static void intel_update_crtc(struct intel_atomic_state *state, if (intel_crtc_needs_fastset(new_crtc_state) && old_crtc_state->inherited) intel_crtc_arm_fifo_underrun(crtc, new_crtc_state); + + if (crtc->cmtg.enabled && (intel_crtc_vrr_enabling(state, crtc))) { + intel_cmtg_set_clk_select(new_crtc_state); + intel_cmtg_disable(new_crtc_state); + intel_cmtg_disable_interrupt(new_crtc_state); + } } static void intel_old_crtc_state_disables(struct intel_atomic_state *state, @@ -7547,6 +7558,19 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) /* FIXME probably need to sequence this properly */ intel_program_dpkgc_latency(state); + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { + bool modeset = intel_crtc_needs_modeset(new_crtc_state); + + /* + * TODO: CMTG needs to be restored on DC6 exit and DC3co entry condition + * need to be checked before calling CMTG functions. + */ + if (modeset && new_crtc_state->hw.active && !crtc->cmtg.enabled) { + intel_cmtg_program(new_crtc_state); + intel_cmtg_enable_interrupt(new_crtc_state); + } + } + intel_wait_for_vblank_workers(state); /* FIXME: We should call drm_atomic_helper_commit_hw_done() here -- 2.29.0
