From: Animesh Manna <[email protected]> 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] - Got R-b from Uma. v4: - Simplify the code further by moving for_each_new_intel_crtc_in_state inside intel_cmtg.c. Signed-off-by: Animesh Manna <[email protected]> --- drivers/gpu/drm/i915/display/intel_cmtg.c | 37 +++++++++++++------- drivers/gpu/drm/i915/display/intel_cmtg.h | 5 ++- drivers/gpu/drm/i915/display/intel_display.c | 14 ++++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c b/drivers/gpu/drm/i915/display/intel_cmtg.c index 96c7608144b9..8684d2ec2f83 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.c +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c @@ -12,6 +12,7 @@ #include "intel_cmtg_regs.h" #include "intel_crtc.h" #include "intel_de.h" +#include "intel_display.h" #include "intel_display_device.h" #include "intel_display_power.h" #include "intel_display_regs.h" @@ -333,15 +334,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); @@ -352,15 +350,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; @@ -371,7 +366,7 @@ void intel_cmtg_enable_ddi(const struct intel_crtc_state *crtc_state) #define DC3CO_ENTRY_LATENCY_US 55 #define DC3CO_EXIT_LATENCY_US 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; @@ -380,9 +375,6 @@ void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state) u32 line_time_us = 75; /* Max default initialization value */ u32 val; - if (!intel_cmtg_is_allowed(crtc_state)) - return; - if (crtc_state->linetime) line_time_us = DIV_ROUND_UP(crtc_state->linetime, 8); @@ -398,3 +390,24 @@ 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(struct intel_atomic_state *state) +{ + struct intel_crtc *crtc; + struct intel_crtc_state *new_crtc_state; + + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { + bool modeset = intel_crtc_needs_modeset(new_crtc_state); + + if (!intel_cmtg_is_allowed(new_crtc_state)) + continue; + /* + * TODO: CMTG needs to be restored on DC6 exit. + */ + if (modeset && new_crtc_state->hw.active && !crtc->cmtg.enabled) { + intel_cmtg_enable_sync(new_crtc_state); + intel_cmtg_set_hwgb(new_crtc_state); + intel_cmtg_enable_ddi(new_crtc_state); + } + } +} diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h b/drivers/gpu/drm/i915/display/intel_cmtg.h index b2b68b38b7e3..a08cb2dcee67 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.h +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h @@ -8,6 +8,7 @@ #include <linux/types.h> +struct intel_atomic_state; struct intel_display; struct intel_crtc_state; @@ -17,8 +18,6 @@ enum set_timing_type { }; 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); @@ -26,6 +25,6 @@ void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, enum set_ void intel_cmtg_set_clk_select(const struct intel_crtc_state *crtc_state); void intel_cmtg_sanitize(struct intel_display *display); bool intel_cmtg_is_allowed(const struct intel_crtc_state *crtc_state); -void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state); +void intel_cmtg_program(struct intel_atomic_state *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 62dc2b414f3c..e76aa6c8dab6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1790,6 +1790,10 @@ 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); + } /* * FIXME collapse everything to one hook. * Need care with mst->ddi interactions. @@ -6898,6 +6902,11 @@ 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); + } } static void intel_old_crtc_state_disables(struct intel_atomic_state *state, @@ -7567,6 +7576,11 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) /* FIXME probably need to sequence this properly */ intel_program_dpkgc_latency(state); + /* + * TODO: DC3co entry condition need to be checked before calling CMTG functions. + */ + intel_cmtg_program(state); + intel_wait_for_vblank_workers(state); /* FIXME: We should call drm_atomic_helper_commit_hw_done() here -- 2.43.0
