xref: /linux/drivers/gpu/drm/i915/display/intel_cmtg.c (revision 18fbf5151d2c0bfe433c7428eef03cabf5fdb2fa)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright (C) 2025 Intel Corporation
4  */
5 
6 #include <linux/string_choices.h>
7 
8 #include <drm/drm_device.h>
9 #include <drm/drm_print.h>
10 
11 #include "intel_cmtg.h"
12 #include "intel_cmtg_regs.h"
13 #include "intel_crtc.h"
14 #include "intel_de.h"
15 #include "intel_display.h"
16 #include "intel_display_device.h"
17 #include "intel_display_irq.h"
18 #include "intel_display_power.h"
19 #include "intel_display_regs.h"
20 #include "intel_display_types.h"
21 #include "intel_vrr.h"
22 #include "intel_vrr_regs.h"
23 
24 /**
25  * DOC: Common Primary Timing Generator (CMTG)
26  *
27  * The CMTG is a timing generator that runs in parallel to transcoders timing
28  * generators (TG) to provide a synchronization mechanism where CMTG acts as
29  * primary and transcoders TGs act as secondary to the CMTG. The CMTG outputs
30  * its TG start and frame sync signals to the transcoders that are configured
31  * as secondary, which use those signals to synchronize their own timing with
32  * the CMTG's.
33  *
34  * The CMTG can be used only with eDP or MIPI command mode and supports the
35  * following use cases:
36  *
37  * - Dual eDP: The CMTG can be used to keep two eDP TGs in sync when on a
38  *   dual eDP configuration (with or without PSR/PSR2 enabled).
39  *
40  * - Single eDP as secondary: It is also possible to use a single eDP
41  *   configuration with the transcoder TG as secondary to the CMTG. That would
42  *   allow a flow that would not require a modeset on the existing eDP when a
43  *   new eDP is added for a dual eDP configuration with CMTG.
44  *
45  * - DC6v: In DC6v, the transcoder might be off but the CMTG keeps running to
46  *   maintain frame timings. When exiting DC6v, the transcoder TG then is
47  *   synced back the CMTG.
48  *
49  * Currently, the driver does not use the CMTG, but we need to make sure that
50  * we disable it in case we inherit a display configuration with it enabled.
51  */
52 
53 /*
54  * We describe here only the minimum data required to allow us to properly
55  * disable the CMTG if necessary.
56  */
57 struct intel_cmtg_config {
58 	bool cmtg_a_enable;
59 	/*
60 	 * Xe2_LPD adds a second CMTG that can be used for dual eDP async mode.
61 	 */
62 	bool cmtg_b_enable;
63 	bool trans_a_secondary;
64 	bool trans_b_secondary;
65 };
66 
67 static bool intel_cmtg_has_cmtg_b(struct intel_display *display)
68 {
69 	return DISPLAY_VER(display) >= 20;
70 }
71 
72 static bool intel_cmtg_has_clock_sel(struct intel_display *display)
73 {
74 	return DISPLAY_VER(display) >= 14;
75 }
76 
77 static void intel_cmtg_dump_config(struct intel_display *display,
78 				   struct intel_cmtg_config *cmtg_config)
79 {
80 	drm_dbg_kms(display->drm,
81 		    "CMTG readout: CMTG A: %s, CMTG B: %s, Transcoder A secondary: %s, Transcoder B secondary: %s\n",
82 		    str_enabled_disabled(cmtg_config->cmtg_a_enable),
83 		    intel_cmtg_has_cmtg_b(display) ? str_enabled_disabled(cmtg_config->cmtg_b_enable) : "n/a",
84 		    str_yes_no(cmtg_config->trans_a_secondary),
85 		    str_yes_no(cmtg_config->trans_b_secondary));
86 }
87 
88 static inline enum transcoder to_cmtg_transcoder(enum transcoder cpu_transcoder)
89 {
90 	switch (cpu_transcoder) {
91 	case TRANSCODER_A:
92 		return TRANSCODER_CMTG0;
93 	case TRANSCODER_B:
94 		return TRANSCODER_CMTG1;
95 	default:
96 		return INVALID_TRANSCODER;
97 	}
98 }
99 
100 static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display,
101 					       enum transcoder trans)
102 {
103 	enum intel_display_power_domain power_domain;
104 	u32 val = 0;
105 
106 	if (!HAS_TRANSCODER(display, trans))
107 		return false;
108 
109 	power_domain = POWER_DOMAIN_TRANSCODER(trans);
110 
111 	with_intel_display_power_if_enabled(display, power_domain)
112 		val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, trans));
113 
114 	return val & CMTG_SECONDARY_MODE;
115 }
116 
117 static void intel_cmtg_get_config(struct intel_display *display,
118 				  struct intel_cmtg_config *cmtg_config)
119 {
120 	u32 val;
121 
122 	val = intel_de_read(display, TRANS_CMTG_CTL(TRANSCODER_A));
123 	cmtg_config->cmtg_a_enable = val & CMTG_ENABLE;
124 
125 	if (intel_cmtg_has_cmtg_b(display)) {
126 		val = intel_de_read(display, TRANS_CMTG_CTL(TRANSCODER_B));
127 		cmtg_config->cmtg_b_enable = val & CMTG_ENABLE;
128 	}
129 
130 	cmtg_config->trans_a_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_A);
131 	cmtg_config->trans_b_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_B);
132 }
133 
134 static bool intel_cmtg_disable_requires_modeset(struct intel_display *display,
135 						struct intel_cmtg_config *cmtg_config)
136 {
137 	if (DISPLAY_VER(display) >= 20)
138 		return false;
139 
140 	return cmtg_config->trans_a_secondary || cmtg_config->trans_b_secondary;
141 }
142 
143 static void intel_cmtg_disable_all(struct intel_display *display,
144 				   struct intel_cmtg_config *cmtg_config)
145 {
146 	u32 clk_sel_clr = 0;
147 	u32 clk_sel_set = 0;
148 
149 	if (cmtg_config->trans_a_secondary)
150 		intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_A),
151 			     CMTG_SECONDARY_MODE, 0);
152 
153 	if (cmtg_config->trans_b_secondary)
154 		intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_B),
155 			     CMTG_SECONDARY_MODE, 0);
156 
157 	if (cmtg_config->cmtg_a_enable) {
158 		drm_dbg_kms(display->drm, "Disabling CMTG A\n");
159 		intel_de_rmw(display, TRANS_CMTG_CTL(TRANSCODER_A), CMTG_ENABLE, 0);
160 		clk_sel_clr |= CMTG_CLK_SEL_A_MASK;
161 		clk_sel_set |= CMTG_CLK_SEL_A_DISABLED;
162 	}
163 
164 	if (cmtg_config->cmtg_b_enable) {
165 		drm_dbg_kms(display->drm, "Disabling CMTG B\n");
166 		intel_de_rmw(display, TRANS_CMTG_CTL(TRANSCODER_B), CMTG_ENABLE, 0);
167 		clk_sel_clr |= CMTG_CLK_SEL_B_MASK;
168 		clk_sel_set |= CMTG_CLK_SEL_B_DISABLED;
169 	}
170 
171 	if (intel_cmtg_has_clock_sel(display) && clk_sel_clr)
172 		intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
173 }
174 
175 void intel_cmtg_disable(const struct intel_crtc_state *crtc_state)
176 {
177 	struct intel_display *display = to_intel_display(crtc_state);
178 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
179 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
180 	enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
181 	u32 clk_sel_clr = 0, interrupt_mask = 0;
182 
183 	if (!crtc->cmtg.enabled)
184 		return;
185 
186 	if (drm_WARN_ON(display->drm, cmtg_transcoder == INVALID_TRANSCODER))
187 		return;
188 
189 	crtc->cmtg.enabled = false;
190 	intel_de_rmw(display, TRANS_VRR_CTL(display, cmtg_transcoder),
191 		     VRR_CTL_VRR_ENABLE | VRR_CTL_FLIP_LINE_EN, 0);
192 
193 	/*
194 	 * Use cpu_transcoder for:
195 	 * 1. Exclusive CMTG registers that do not use the standard transcoder offset
196 	 *    (e.g., TRANS_CMTG_CTL, CMTG_CLK_SEL).
197 	 * 2. Registers shared between the eDP and CMTG transcoders.
198 	 *    (e.g., TRANS_DDI_FUNC_CTL2).
199 	 */
200 
201 	intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, cpu_transcoder),
202 		     CMTG_SECONDARY_MODE, 0);
203 	intel_de_rmw(display, CMTG_SCANLINE_GB1(cpu_transcoder), CMTG_HW_GB_ENABLE, 0);
204 
205 	intel_de_rmw(display, TRANS_CMTG_CTL(cpu_transcoder), CMTG_ENABLE, 0);
206 
207 	if (intel_de_wait_for_clear_ms(display, TRANS_CMTG_CTL(cpu_transcoder), CMTG_STATE, 50)) {
208 		drm_WARN(display->drm, 1, "CMTG: %s disable timeout\n",
209 			 transcoder_name(cpu_transcoder));
210 		return;
211 	}
212 
213 	clk_sel_clr = cpu_transcoder == TRANSCODER_A ? CMTG_CLK_SEL_A_MASK : CMTG_CLK_SEL_B_MASK;
214 	intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, 0);
215 
216 	drm_dbg_kms(display->drm, "CMTG: %s disabled\n", transcoder_name(cpu_transcoder));
217 
218 	if (cpu_transcoder == TRANSCODER_A)
219 		interrupt_mask = CMTG_VBLANK_A;
220 	else if (cpu_transcoder == TRANSCODER_B)
221 		interrupt_mask = CMTG_VBLANK_B;
222 
223 	intel_display_irq_port_interrupt_mask(display, interrupt_mask, true);
224 }
225 
226 /*
227  * Read out CMTG configuration and, on platforms that allow disabling it without
228  * a modeset, do it.
229  *
230  * This function must be called before any port PLL is disabled in the general
231  * sanitization process, because we need whatever port PLL that is providing the
232  * clock for CMTG to be on before accessing CMTG registers.
233  */
234 void intel_cmtg_sanitize(struct intel_display *display)
235 {
236 	struct intel_cmtg_config cmtg_config = {};
237 
238 	if (!HAS_CMTG(display))
239 		return;
240 
241 	intel_cmtg_get_config(display, &cmtg_config);
242 	intel_cmtg_dump_config(display, &cmtg_config);
243 
244 	/*
245 	 * FIXME: The driver is not prepared to handle cases where a modeset is
246 	 * required for disabling the CMTG: we need a proper way of tracking
247 	 * CMTG state and do the right syncronization with respect to triggering
248 	 * the modeset as part of the disable sequence.
249 	 */
250 	if (intel_cmtg_disable_requires_modeset(display, &cmtg_config))
251 		return;
252 
253 	intel_cmtg_disable_all(display, &cmtg_config);
254 }
255 
256 bool intel_cmtg_is_allowed(const struct intel_crtc_state *crtc_state)
257 {
258 	struct intel_display *display = to_intel_display(crtc_state);
259 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
260 
261 	if ((cpu_transcoder == TRANSCODER_A || cpu_transcoder == TRANSCODER_B) &&
262 	    DISPLAY_VER(display) == 35 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
263 		return true;
264 
265 	return false;
266 }
267 
268 void intel_cmtg_set_clk_select(const struct intel_crtc_state *crtc_state)
269 {
270 	struct intel_display *display = to_intel_display(crtc_state);
271 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
272 	u32 clk_sel_clr = 0;
273 	u32 clk_sel_set = 0;
274 
275 	if (!intel_cmtg_is_allowed(crtc_state))
276 		return;
277 
278 	if (cpu_transcoder == TRANSCODER_A) {
279 		clk_sel_clr = CMTG_CLK_SEL_A_MASK;
280 		clk_sel_set = CMTG_CLK_SELECT_PHYA_ENABLE;
281 	} else if (cpu_transcoder == TRANSCODER_B) {
282 		clk_sel_clr = CMTG_CLK_SEL_B_MASK;
283 		clk_sel_set = CMTG_CLK_SELECT_PHYB_ENABLE;
284 	}
285 
286 	if (clk_sel_set)
287 		intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
288 }
289 
290 void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, enum set_timing_type type)
291 {
292 	enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
293 
294 	if (cmtg_transcoder == INVALID_TRANSCODER)
295 		return;
296 
297 	if (!intel_cmtg_is_allowed(crtc_state))
298 		return;
299 
300 	if (type == LRR)
301 		intel_set_transcoder_timings_lrr(crtc_state, cmtg_transcoder);
302 	else
303 		intel_set_transcoder_timings(crtc_state, cmtg_transcoder);
304 }
305 
306 void intel_cmtg_set_vrr_timings(const struct intel_crtc_state *crtc_state)
307 {
308 	enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
309 
310 	if (!intel_cmtg_is_allowed(crtc_state))
311 		return;
312 
313 	intel_vrr_set_fixed_rr_timings(crtc_state, cmtg_transcoder);
314 }
315 
316 void intel_cmtg_set_vrr_ctl(const struct intel_crtc_state *crtc_state)
317 {
318 	struct intel_display *display = to_intel_display(crtc_state);
319 	enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
320 	u32 vrr_ctl;
321 
322 	if (!intel_cmtg_is_allowed(crtc_state))
323 		return;
324 
325 	vrr_ctl = VRR_CTL_VRR_ENABLE | VRR_CTL_FLIP_LINE_EN |
326 		  XELPD_VRR_CTL_VRR_GUARDBAND(crtc_state->vrr.guardband);
327 
328 	/* TODO: The code below may need to be revisited once CMRR is enabled */
329 	if (crtc_state->cmrr.enable)
330 		vrr_ctl |= VRR_CTL_CMRR_ENABLE;
331 
332 	intel_de_write(display, TRANS_VRR_CTL(display, cmtg_transcoder), vrr_ctl);
333 }
334 
335 void intel_cmtg_set_m_n(const struct intel_crtc_state *crtc_state)
336 {
337 	struct intel_display *display = to_intel_display(crtc_state);
338 	enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
339 	const struct intel_link_m_n *m_n = &crtc_state->dp_m_n;
340 
341 	if (!intel_cmtg_is_allowed(crtc_state))
342 		return;
343 
344 	intel_de_write(display, PIPE_LINK_M1(display, cmtg_transcoder), m_n->link_m);
345 	intel_de_write(display, PIPE_LINK_N1(display, cmtg_transcoder), m_n->link_n);
346 }
347 
348 static void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state)
349 {
350 	struct intel_display *display = to_intel_display(crtc_state);
351 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
352 	u32 cmtg_ctl;
353 
354 	cmtg_ctl = CMTG_SYNC_TO_PORT | CMTG_ENABLE;
355 
356 	intel_de_rmw(display, TRANS_CMTG_CTL(cpu_transcoder), 0, cmtg_ctl);
357 	if (intel_de_wait_for_clear_ms(display, TRANS_CMTG_CTL(cpu_transcoder),
358 				       CMTG_SYNC_TO_PORT, 50)) {
359 		drm_WARN(display->drm, 1, "CMTG: %s enable timeout\n",
360 			 transcoder_name(cpu_transcoder));
361 	}
362 }
363 
364 static void intel_cmtg_enable_ddi(const struct intel_crtc_state *crtc_state)
365 {
366 	struct intel_display *display = to_intel_display(crtc_state);
367 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
368 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
369 	u32 interrupt_mask = 0;
370 
371 	intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), 0, CMTG_SECONDARY_MODE);
372 	intel_de_rmw(display, CMTG_SCANLINE_GB1(cpu_transcoder), 0, CMTG_HW_GB_ENABLE);
373 	crtc->cmtg.enabled = true;
374 	drm_dbg_kms(display->drm, "CMTG: %s enabled\n", transcoder_name(cpu_transcoder));
375 
376 	/*
377 	 * TODO: Currently cmtg is enabled along with eDP transcoder so cmtg
378 	 * interrupt is not enabled through IER, need to do some fine
379 	 * tuning in future.
380 	 */
381 
382 	if (cpu_transcoder == TRANSCODER_A)
383 		interrupt_mask = CMTG_VBLANK_A;
384 	else if (cpu_transcoder == TRANSCODER_B)
385 		interrupt_mask = CMTG_VBLANK_B;
386 
387 	intel_display_irq_port_interrupt_mask(display, interrupt_mask, false);
388 }
389 
390 /* Bspec: 75253 */
391 #define DC3CO_ENTRY_LATENCY_US	55
392 #define DC3CO_EXIT_LATENCY_US	40
393 
394 static void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state)
395 {
396 	struct intel_display *display = to_intel_display(crtc_state);
397 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
398 	u32 breakeven_gb;
399 	u32 dc5_exit_latency;
400 	u32 line_time_us = 75;	/* Max default initialization value */
401 	u32 val;
402 
403 	if (crtc_state->linetime)
404 		line_time_us = DIV_ROUND_UP(crtc_state->linetime, 8);
405 
406 	/* Break Even Guardband - DC3co Entry Latency / linetime */
407 	breakeven_gb = DIV_ROUND_UP(DC3CO_ENTRY_LATENCY_US, line_time_us);
408 
409 	/* DC5 Exit Latency - DC3co Exit Latency / linetime */
410 	dc5_exit_latency = DIV_ROUND_UP(DC3CO_EXIT_LATENCY_US, line_time_us);
411 
412 	val = REG_FIELD_PREP(CMTG_HW_GB_BREAKEVEN_MASK, breakeven_gb) |
413 	      REG_FIELD_PREP(CMTG_HW_GB_DC5_EXIT_LATENCY_MASK, dc5_exit_latency) |
414 	      REG_FIELD_PREP(CMTG_HW_GB_UP_LW_BG_DIFF_MASK, 1);
415 
416 	intel_de_write(display, CMTG_HW_GB(cpu_transcoder), val);
417 }
418 
419 static void intel_cmtg_restore(const struct intel_crtc_state *crtc_state)
420 {
421 	intel_cmtg_set_clk_select(crtc_state);
422 	intel_cmtg_set_timings(crtc_state, MODESET);
423 	intel_cmtg_set_vrr_timings(crtc_state);
424 	intel_cmtg_set_vrr_ctl(crtc_state);
425 	intel_cmtg_set_m_n(crtc_state);
426 }
427 
428 void intel_cmtg_program(struct intel_atomic_state *state)
429 {
430 	struct intel_display *display = to_intel_display(state);
431 	struct intel_crtc *crtc;
432 	struct intel_crtc_state *new_crtc_state;
433 	bool dc3co_to_dc6 = intel_display_power_get_and_reset_dc3co_to_dc6(display);
434 
435 	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
436 		bool modeset = intel_crtc_needs_modeset(new_crtc_state);
437 
438 		if (!intel_cmtg_is_allowed(new_crtc_state))
439 			continue;
440 
441 		if ((modeset || dc3co_to_dc6) &&
442 		    new_crtc_state->hw.active && !crtc->cmtg.enabled) {
443 			if (dc3co_to_dc6)
444 				intel_cmtg_restore(new_crtc_state);
445 
446 			intel_cmtg_enable_sync(new_crtc_state);
447 			intel_cmtg_set_hwgb(new_crtc_state);
448 			intel_cmtg_enable_ddi(new_crtc_state);
449 		}
450 	}
451 }
452