Skip to content

Commit 73230ff

Browse files
committed
Merge tag 'drm-intel-next-fixes-2025-05-22' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
- Fix for Thunderbolt sink disconnect on MTL/ARL/LNL - Fix for DDI port clock select mask on PTL+ - Add error checks for alloc_ordered_workqueue() and alloc_workqueue() in display Signed-off-by: Dave Airlie <[email protected]> From: Joonas Lahtinen <[email protected]> Link: https://lore.kernel.org/r/aC7LQUtxXKgOVTVt@jlahtine-mobl
2 parents c4f8ac0 + f4c7baa commit 73230ff

File tree

4 files changed

+63
-26
lines changed

4 files changed

+63
-26
lines changed

drivers/gpu/drm/i915/display/intel_cx0_phy.c

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,9 +2763,9 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
27632763
val |= XELPDP_FORWARD_CLOCK_UNGATE;
27642764

27652765
if (!is_dp && is_hdmi_frl(port_clock))
2766-
val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
2766+
val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
27672767
else
2768-
val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
2768+
val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
27692769

27702770
/* TODO: HDMI FRL */
27712771
/* DP2.0 10G and 20G rates enable MPLLA*/
@@ -2776,7 +2776,7 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
27762776

27772777
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
27782778
XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
2779-
XELPDP_DDI_CLOCK_SELECT_MASK | XELPDP_SSC_ENABLE_PLLA |
2779+
XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA |
27802780
XELPDP_SSC_ENABLE_PLLB, val);
27812781
}
27822782

@@ -3099,10 +3099,7 @@ int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
30993099

31003100
val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port));
31013101

3102-
if (DISPLAY_VER(display) >= 30)
3103-
clock = REG_FIELD_GET(XE3_DDI_CLOCK_SELECT_MASK, val);
3104-
else
3105-
clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val);
3102+
clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val);
31063103

31073104
drm_WARN_ON(display->drm, !(val & XELPDP_FORWARD_CLOCK_UNGATE));
31083105
drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_REQUEST));
@@ -3170,13 +3167,9 @@ static void intel_mtl_tbt_pll_enable(struct intel_encoder *encoder,
31703167
* clock muxes, gating and SSC
31713168
*/
31723169

3173-
if (DISPLAY_VER(display) >= 30) {
3174-
mask = XE3_DDI_CLOCK_SELECT_MASK;
3175-
val |= XE3_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock));
3176-
} else {
3177-
mask = XELPDP_DDI_CLOCK_SELECT_MASK;
3178-
val |= XELPDP_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock));
3179-
}
3170+
mask = XELPDP_DDI_CLOCK_SELECT_MASK(display);
3171+
val |= XELPDP_DDI_CLOCK_SELECT_PREP(display,
3172+
intel_mtl_tbt_clock_select(display, crtc_state->port_clock));
31803173

31813174
mask |= XELPDP_FORWARD_CLOCK_UNGATE;
31823175
val |= XELPDP_FORWARD_CLOCK_UNGATE;
@@ -3289,7 +3282,7 @@ static void intel_cx0pll_disable(struct intel_encoder *encoder)
32893282

32903283
/* 7. Program PORT_CLOCK_CTL register to disable and gate clocks. */
32913284
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
3292-
XELPDP_DDI_CLOCK_SELECT_MASK, 0);
3285+
XELPDP_DDI_CLOCK_SELECT_MASK(display), 0);
32933286
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
32943287
XELPDP_FORWARD_CLOCK_UNGATE, 0);
32953288

@@ -3338,7 +3331,7 @@ static void intel_mtl_tbt_pll_disable(struct intel_encoder *encoder)
33383331
* 5. Program PORT CLOCK CTRL register to disable and gate clocks
33393332
*/
33403333
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
3341-
XELPDP_DDI_CLOCK_SELECT_MASK |
3334+
XELPDP_DDI_CLOCK_SELECT_MASK(display) |
33423335
XELPDP_FORWARD_CLOCK_UNGATE, 0);
33433336

33443337
/* 6. Program DDI_CLK_VALFREQ to 0. */
@@ -3367,7 +3360,7 @@ intel_mtl_port_pll_type(struct intel_encoder *encoder,
33673360
* handling is done via the standard shared DPLL framework.
33683361
*/
33693362
val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port));
3370-
clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val);
3363+
clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val);
33713364

33723365
if (clock == XELPDP_DDI_CLOCK_SELECT_MAXPCLK ||
33733366
clock == XELPDP_DDI_CLOCK_SELECT_DIV18CLK)

drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,17 @@
192192

193193
#define XELPDP_TBT_CLOCK_REQUEST REG_BIT(19)
194194
#define XELPDP_TBT_CLOCK_ACK REG_BIT(18)
195-
#define XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12)
196-
#define XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12)
197-
#define XELPDP_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XELPDP_DDI_CLOCK_SELECT_MASK, val)
198-
#define XE3_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XE3_DDI_CLOCK_SELECT_MASK, val)
195+
#define _XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12)
196+
#define _XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12)
197+
#define XELPDP_DDI_CLOCK_SELECT_MASK(display) (DISPLAY_VER(display) >= 30 ? \
198+
_XE3_DDI_CLOCK_SELECT_MASK : _XELPDP_DDI_CLOCK_SELECT_MASK)
199+
#define XELPDP_DDI_CLOCK_SELECT_PREP(display, val) (DISPLAY_VER(display) >= 30 ? \
200+
REG_FIELD_PREP(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \
201+
REG_FIELD_PREP(_XELPDP_DDI_CLOCK_SELECT_MASK, (val)))
202+
#define XELPDP_DDI_CLOCK_SELECT_GET(display, val) (DISPLAY_VER(display) >= 30 ? \
203+
REG_FIELD_GET(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \
204+
REG_FIELD_GET(_XELPDP_DDI_CLOCK_SELECT_MASK, (val)))
205+
199206
#define XELPDP_DDI_CLOCK_SELECT_NONE 0x0
200207
#define XELPDP_DDI_CLOCK_SELECT_MAXPCLK 0x8
201208
#define XELPDP_DDI_CLOCK_SELECT_DIV18CLK 0x9

drivers/gpu/drm/i915/display/intel_display_driver.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,38 +244,58 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
244244
intel_dmc_init(display);
245245

246246
display->wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
247+
if (!display->wq.modeset) {
248+
ret = -ENOMEM;
249+
goto cleanup_vga_client_pw_domain_dmc;
250+
}
251+
247252
display->wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
248253
WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
254+
if (!display->wq.flip) {
255+
ret = -ENOMEM;
256+
goto cleanup_wq_modeset;
257+
}
258+
249259
display->wq.cleanup = alloc_workqueue("i915_cleanup", WQ_HIGHPRI, 0);
260+
if (!display->wq.cleanup) {
261+
ret = -ENOMEM;
262+
goto cleanup_wq_flip;
263+
}
250264

251265
intel_mode_config_init(display);
252266

253267
ret = intel_cdclk_init(display);
254268
if (ret)
255-
goto cleanup_vga_client_pw_domain_dmc;
269+
goto cleanup_wq_cleanup;
256270

257271
ret = intel_color_init(display);
258272
if (ret)
259-
goto cleanup_vga_client_pw_domain_dmc;
273+
goto cleanup_wq_cleanup;
260274

261275
ret = intel_dbuf_init(display);
262276
if (ret)
263-
goto cleanup_vga_client_pw_domain_dmc;
277+
goto cleanup_wq_cleanup;
264278

265279
ret = intel_bw_init(display);
266280
if (ret)
267-
goto cleanup_vga_client_pw_domain_dmc;
281+
goto cleanup_wq_cleanup;
268282

269283
ret = intel_pmdemand_init(display);
270284
if (ret)
271-
goto cleanup_vga_client_pw_domain_dmc;
285+
goto cleanup_wq_cleanup;
272286

273287
intel_init_quirks(display);
274288

275289
intel_fbc_init(display);
276290

277291
return 0;
278292

293+
cleanup_wq_cleanup:
294+
destroy_workqueue(display->wq.cleanup);
295+
cleanup_wq_flip:
296+
destroy_workqueue(display->wq.flip);
297+
cleanup_wq_modeset:
298+
destroy_workqueue(display->wq.modeset);
279299
cleanup_vga_client_pw_domain_dmc:
280300
intel_dmc_fini(display);
281301
intel_power_domains_driver_remove(display);

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4532,6 +4532,23 @@ intel_dp_mst_disconnect(struct intel_dp *intel_dp)
45324532
static bool
45334533
intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi)
45344534
{
4535+
struct intel_display *display = to_intel_display(intel_dp);
4536+
4537+
/*
4538+
* Display WA for HSD #13013007775: mtl/arl/lnl
4539+
* Read the sink count and link service IRQ registers in separate
4540+
* transactions to prevent disconnecting the sink on a TBT link
4541+
* inadvertently.
4542+
*/
4543+
if (IS_DISPLAY_VER(display, 14, 20) && !display->platform.battlemage) {
4544+
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3) != 3)
4545+
return false;
4546+
4547+
/* DP_SINK_COUNT_ESI + 3 == DP_LINK_SERVICE_IRQ_VECTOR_ESI0 */
4548+
return drm_dp_dpcd_readb(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0,
4549+
&esi[3]) == 1;
4550+
}
4551+
45354552
return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4;
45364553
}
45374554

0 commit comments

Comments
 (0)