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

Reply via email to