summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnimesh Manna <animesh.manna@intel.com>2026-06-16 01:33:37 +0530
committerAnimesh Manna <animesh.manna@intel.com>2026-06-16 17:21:03 +0530
commitc588a324183b08db37697158213596b14866337e (patch)
tree2c2b930749156126d08f634ea93d8606a3be804e
parent81c7da958f4707de13bde3687fc45094325a5636 (diff)
drm/i915/cmtg: Add trigger to enable/disable cmtg
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 <animesh.manna@intel.com> Reviewed-by: Uma Shankar <uma.shankar@intel.com> Link: https://patch.msgid.link/20260615200339.885190-21-animesh.manna@intel.com
-rw-r--r--drivers/gpu/drm/i915/display/intel_cmtg.c37
-rw-r--r--drivers/gpu/drm/i915/display/intel_cmtg.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c14
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