[PATCH AUTOSEL 6.19-6.12] drm/amd/display: Fix dsc eDP issue

Sasha Levin
2026-02-14T01:04:33Z

From: Charlene Liu <Charlene.Liu@amd.com>

[ Upstream commit 878a4b73c11111ff5f820730f59a7f8c6fd59374 ]

[why]
Need to add function hook check before use

Reviewed-by: Mohit Bawa <mohit.bawa@amd.com>
Signed-off-by: Charlene Liu <Charlene.Liu@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Analysis

### Commit Overview

This commit makes two changes to `dce110_hwseq.c`:

1. **IPS early return in
`disable_vga_and_power_gate_all_controllers()`**: Adds `if
(dc->caps.ips_support) return;` to skip the entire function on IPS-
capable hardware (DCN 3.5/3.51/3.6 APUs).

2. **NULL function pointer checks in `clean_up_dsc_blocks()`**: Adds
NULL checks before calling `tg->funcs->set_dsc_config`,
`se->funcs->dp_set_dsc_config`, and
`se->funcs->dp_set_dsc_pps_info_packet`.

### Bug Mechanism Analysis

**IPS change (Change 1):**

DCN 3.5+ APUs support IPS (Idle Power Save) which can power down display
blocks. The `disable_vga_and_power_gate_all_controllers` function is
called from two paths:
- `dce110_enable_accelerated_mode()` (line 2066) during VBIOS-to-driver
transition
- `dce110_power_down()` (line 2724) during hardware power down

Both DCN 3.5 (`dcn35_init.c` line 54) and DCN 3.51 (`dcn351_init.c`) use
`dce110_enable_accelerated_mode` as their `enable_accelerated_mode`
hook. The function iterates all pipes calling `dc->hwss.disable_plane()`
= `dcn35_disable_plane()` which accesses hardware registers. On IPS-
capable hardware:
- VGA doesn't exist (the `disable_vga` pointer is already NULL for all
DCN optc implementations)
- Display pipe register accesses may conflict with IPS power management
state
- This can cause hangs or register access failures during mode
transitions

**NULL checks (Change 2):**

The `clean_up_dsc_blocks()` function (introduced in v6.12 with `Cc:
stable`) is reached on APUs with DCN >= 3.15. Critically, I found that
**DCN 4.01 explicitly sets `dp_set_dsc_config = NULL`** in
`dcn401_dio_stream_encoder.c` line 760. While DCN 4.01 is not currently
an APU, this demonstrates that not all hardware implements these
functions. The pattern of NULL-checking before calling is already
established in this very function (`dccg->funcs->set_ref_dscclk` at line
1928 already has a NULL check). Without these checks, if any future APU
hardware variant doesn't implement these functions, calling NULL would
cause a **kernel crash (NULL pointer dereference)**.

### Stability Indicators

- **Reviewed-by**: Mohit Bawa (AMD)
- **Tested-by**: Daniel Wheeler (AMD)
- **Signed-off-by**: Alex Deucher (AMD GPU subsystem maintainer)
- Author is Charlene Liu, an experienced AMD display engineer

### Scope and Risk

- **Files changed**: 1 file
- **Lines added**: ~10 lines of guards/checks
- **Risk**: Negligible - only adds early returns and NULL guards; cannot
break existing functionality
- **Pattern consistency**: Follows existing patterns in the same
functions

### Applicability to Stable Trees

- `clean_up_dsc_blocks` was introduced in v6.12 with `Cc: stable`
(3766a840e093d), so it exists in 6.12.y stable trees
- DCN 3.5 IPS support exists in 6.8+ kernels, so the IPS change is
relevant to 6.12.y
- The `disable_vga_and_power_gate_all_controllers` has existed since
early AMDGPU display code
- Minor context adaptation may be needed for pre-6.19 trees (the
`d8ed14f1dc679` condition change is 6.19-only), but the fix itself is
self-contained

### Conclusion

This commit fixes two real issues: (1) prevents hardware register access
on IPS-capable AMD APUs that could cause hangs during mode transitions,
and (2) adds defensive NULL pointer dereference protection for function
pointers that are demonstrably NULL on some hardware variants. The fix
is small, surgical, well-reviewed by AMD engineers, has zero regression
risk, and protects against kernel crashes on AMD eDP laptop hardware.
The affected code (`clean_up_dsc_blocks`) was itself backported to
stable with `Cc: stable`, making this follow-up fix equally important.

**YES**

.../drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index ebd74b43e935e..0513784e1c6fc 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -1840,6 +1840,9 @@ static void disable_vga_and_power_gate_all_controllers(
struct timing_generator *tg;
struct dc_context *ctx = dc->ctx;

+ if (dc->caps.ips_support)
+ return;
+
for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
tg = dc->res_pool->timing_generators[i];

@@ -1916,13 +1919,16 @@ static void clean_up_dsc_blocks(struct dc *dc)
/* disable DSC in OPTC */
if (i < dc->res_pool->timing_generator_count) {
tg = dc->res_pool->timing_generators[i];
- tg->funcs->set_dsc_config(tg, OPTC_DSC_DISABLED, 0, 0);
+ if (tg->funcs->set_dsc_config)
+ tg->funcs->set_dsc_config(tg, OPTC_DSC_DISABLED, 0, 0);
}
/* disable DSC in stream encoder */
if (i < dc->res_pool->stream_enc_count) {
se = dc->res_pool->stream_enc[i];
- se->funcs->dp_set_dsc_config(se, OPTC_DSC_DISABLED, 0, 0);
- se->funcs->dp_set_dsc_pps_info_packet(se, false, NULL, true);
+ if (se->funcs->dp_set_dsc_config)
+ se->funcs->dp_set_dsc_config(se, OPTC_DSC_DISABLED, 0, 0);
+ if (se->funcs->dp_set_dsc_pps_info_packet)
+ se->funcs->dp_set_dsc_pps_info_packet(se, false, NULL, true);
}
/* disable DSC block */
if (dccg->funcs->set_ref_dscclk)
--
2.51.0