Timing registers are separate for CMTG, read transcoder register
and program cmtg transcoder with those values.

v2:
- Use sw state instead of reading directly from hardware. [Jani]
- Move set_timing later after encoder enable. [Dibin]

v3:
- Replace id with trans. [Jani]
- Program cmtg set_timing() along with primary transcoder timing.

v4:
- Use _MMIO_TRANS() for cmtg registers instead of direct
multiplication. [Jani]

v5:
- Modify register definition approach and match existing
transcoder definition. [Ville]

Signed-off-by: Animesh Manna <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_cmtg.c    | 72 ++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_cmtg.h    |  1 +
 drivers/gpu/drm/i915/display/intel_display.c |  4 ++
 3 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c 
b/drivers/gpu/drm/i915/display/intel_cmtg.c
index 0a2b2bfee1e2..e8a5429c888f 100644
--- a/drivers/gpu/drm/i915/display/intel_cmtg.c
+++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
@@ -220,3 +220,75 @@ void intel_cmtg_set_clk_select(const struct 
intel_crtc_state *crtc_state)
        if (clk_sel_set)
                intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
 }
+
+static inline enum transcoder to_cmtg_transcoder(enum transcoder 
cpu_transcoder)
+{
+       switch (cpu_transcoder) {
+       case TRANSCODER_A:
+               return TRANSCODER_CMTG0;
+       case TRANSCODER_B:
+               return TRANSCODER_CMTG1;
+       default:
+               return INVALID_TRANSCODER;
+       }
+}
+
+void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, bool 
lrr)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+       const struct drm_display_mode *adjusted_mode = 
&crtc_state->hw.adjusted_mode;
+       enum transcoder cmtg_transcoder = 
to_cmtg_transcoder(crtc_state->cpu_transcoder);
+       u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end;
+
+       if (!intel_cmtg_is_allowed(crtc_state))
+               return;
+
+       crtc_vdisplay = adjusted_mode->crtc_vdisplay;
+
+       /*
+        * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal
+        * bits are not required. Since the support for these bits is going to
+        * be deprecated in upcoming platforms, avoid writing these bits for the
+        * platforms that do not use legacy Timing Generator.
+        */
+       crtc_vtotal = 1;
+
+       /*
+        * VBLANK_START not used by hw, just clear it
+        * to make it stand out in register dumps.
+        */
+       crtc_vblank_start = 1;
+
+       crtc_vblank_end = adjusted_mode->crtc_vblank_end;
+
+       if (lrr) {
+               intel_de_write(display, TRANS_VTOTAL(display, cmtg_transcoder),
+                              VACTIVE(crtc_vdisplay - 1) |
+                              VTOTAL(crtc_vtotal - 1));
+               intel_de_write(display, TRANS_VBLANK(display, cmtg_transcoder),
+                              VBLANK_START(crtc_vblank_start - 1) |
+                              VBLANK_END(crtc_vblank_end - 1));
+               return;
+       }
+
+       intel_de_write(display, TRANS_HTOTAL(display, cmtg_transcoder),
+                      HACTIVE(adjusted_mode->crtc_hdisplay - 1) |
+                      HTOTAL(adjusted_mode->crtc_htotal - 1));
+       intel_de_write(display, TRANS_HBLANK(display, cmtg_transcoder),
+                      HBLANK_START(adjusted_mode->crtc_hblank_start - 1) |
+                      HBLANK_END(adjusted_mode->crtc_hblank_end - 1));
+       intel_de_write(display, TRANS_HSYNC(display, cmtg_transcoder),
+                      HSYNC_START(adjusted_mode->crtc_hsync_start - 1) |
+                      HSYNC_END(adjusted_mode->crtc_hsync_end - 1));
+       intel_de_write(display, TRANS_VTOTAL(display, cmtg_transcoder),
+                      VACTIVE(crtc_vdisplay - 1) |
+                      VTOTAL(crtc_vtotal - 1));
+       intel_de_write(display, TRANS_VBLANK(display, cmtg_transcoder),
+                      VBLANK_START(crtc_vblank_start - 1) |
+                      VBLANK_END(crtc_vblank_end - 1));
+       intel_de_write(display, TRANS_VSYNC(display, cmtg_transcoder),
+                      VSYNC_START(adjusted_mode->crtc_vsync_start - 1) |
+                      VSYNC_END(adjusted_mode->crtc_vsync_end - 1));
+       intel_de_write(display, TRANS_SET_CONTEXT_LATENCY(display, 
cmtg_transcoder),
+                      crtc_state->set_context_latency);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h 
b/drivers/gpu/drm/i915/display/intel_cmtg.h
index 87092ce6d67b..53a44f505dd2 100644
--- a/drivers/gpu/drm/i915/display/intel_cmtg.h
+++ b/drivers/gpu/drm/i915/display/intel_cmtg.h
@@ -11,6 +11,7 @@
 struct intel_display;
 struct intel_crtc_state;
 
+void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, bool 
lrr);
 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);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index d5cf1476c7b9..701cb4f9d70d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -60,6 +60,7 @@
 #include "intel_bw.h"
 #include "intel_cdclk.h"
 #include "intel_clock_gating.h"
+#include "intel_cmtg.h"
 #include "intel_color.h"
 #include "intel_crt.h"
 #include "intel_crtc.h"
@@ -2753,6 +2754,8 @@ static void intel_set_transcoder_timings(const struct 
intel_crtc_state *crtc_sta
                intel_de_write(display, DP_MIN_HBLANK_CTL(cpu_transcoder),
                               crtc_state->min_hblank);
        }
+
+       intel_cmtg_set_timings(crtc_state, false);
 }
 
 static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state 
*crtc_state)
@@ -2814,6 +2817,7 @@ static void intel_set_transcoder_timings_lrr(const struct 
intel_crtc_state *crtc
                       VACTIVE(crtc_vdisplay - 1) |
                       VTOTAL(crtc_vtotal - 1));
 
+       intel_cmtg_set_timings(crtc_state, true);
        intel_vrr_set_fixed_rr_timings(crtc_state);
        intel_vrr_transcoder_enable(crtc_state);
 }
-- 
2.29.0

Reply via email to