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

Reply via email to