From 2de34fbcab2063cd3d52e5872a801b9a5fc755d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 26 Jan 2026 22:08:24 +0100 Subject: [PATCH 01/28] drm/amd/display: Use DCE 6 link encoder for DCE 6 analog connectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DCE 6 should use the DCE 6 specific link encoder. This was a copy paste mistake. Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") Signed-off-by: Timur Kristóf Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c index f0152933bee2..068fb1df8d88 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c @@ -734,7 +734,7 @@ static struct link_encoder *dce60_link_encoder_create( return NULL; if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { - dce110_link_encoder_construct(enc110, + dce60_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, &link_enc_regs[ENGINE_ID_DACA], From f402898bd101af3166bde236b7f6a43d926e17a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 26 Jan 2026 22:08:25 +0100 Subject: [PATCH 02/28] drm/amd/display: Only use analog link encoder with analog engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some GPUs have analog connectors that work with a DP bridge chip and don't actually have an internal DAC: Those should not use the analog link encoder code path. Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") Signed-off-by: Timur Kristóf Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c index a929e64524e5..864634e14de1 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c @@ -638,7 +638,8 @@ static struct link_encoder *dce100_link_encoder_create( if (!enc110) return NULL; - if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { + if (enc_init_data->connector.id == CONNECTOR_ID_VGA && + enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { dce110_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c index 068fb1df8d88..90d826237cf0 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c @@ -733,7 +733,8 @@ static struct link_encoder *dce60_link_encoder_create( if (!enc110) return NULL; - if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { + if (enc_init_data->connector.id == CONNECTOR_ID_VGA && + enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { dce60_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c index 8687104cabb7..cde2c2cba1dd 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c @@ -740,7 +740,8 @@ static struct link_encoder *dce80_link_encoder_create( if (!enc110) return NULL; - if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { + if (enc_init_data->connector.id == CONNECTOR_ID_VGA && + enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { dce110_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, From 17ff034f805e032ed1358624a71381f9d6e29e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 26 Jan 2026 22:08:26 +0100 Subject: [PATCH 03/28] drm/amd/display: Only use analog stream encoder with analog engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some GPUs have analog connectors that work with a DP bridge chip and don't actually have an internal DAC: Those should not use the analog stream encoders. Fixes: 5834c33fd3f6 ("drm/amd/display: Add concept of analog encoders (v2)") Signed-off-by: Timur Kristóf Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c index 864634e14de1..f49d67fcafe0 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c @@ -979,7 +979,10 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link( struct dc_link *link = stream->link; enum engine_id preferred_engine = link->link_enc->preferred_engine; - if (dc_is_rgb_signal(stream->signal)) + /* Prefer analog engine if the link encoder has one. + * Otherwise, it's an external encoder. + */ + if (dc_is_rgb_signal(stream->signal) && link->link_enc->analog_engine != ENGINE_ID_UNKNOWN) preferred_engine = link->link_enc->analog_engine; for (i = 0; i < pool->stream_enc_count; i++) { From 4a063f64f905310ae7ec81f2e1cc9fdefb7ac3d7 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Mon, 15 Dec 2025 17:14:21 -0500 Subject: [PATCH 04/28] drm/amd/display: Add static keyword for sharpness tables [Why & How] Sharpness tables are only accessed in dc_spl_isharp_filters source file. Reviewed-by: Joshua Aberback Reviewed-by: Jun Lei Signed-off-by: Samson Tam Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c index 1d9edb89e47a..a75ab23b0726 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c @@ -293,7 +293,7 @@ static const uint16_t filter_isharp_bs_3tap_64p_s1_12[99] = { }; /* Pre-generated 1DLUT for given setup and sharpness level */ -struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = { +static struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = { { 0, 0, { @@ -332,7 +332,7 @@ struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = }, }; -struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = { +static struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = { {1125, 1000, 0}, {11, 10, 1}, {1075, 1000, 2}, From 8175ea4159e9c4275503cb287802fae6d6a8a055 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 28 Jan 2026 11:09:23 -0500 Subject: [PATCH 05/28] drm/amd/display: Expose functions of other dcn use [Why & HOw] Expose some functions for later dcns to reuse Reviewed-by: Charlene Liu Reviewed-by: Nicholas Kazlauskas Signed-off-by: Dmytro Laktyushkin Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c | 15 +++++---------- .../amd/display/dc/hubbub/dcn401/dcn401_hubbub.c | 10 +++++----- .../amd/display/dc/hubbub/dcn401/dcn401_hubbub.h | 10 ++++++++++ .../drm/amd/display/dc/optc/dcn35/dcn35_optc.c | 6 +++--- .../drm/amd/display/dc/optc/dcn35/dcn35_optc.h | 9 +++++++++ 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c index 663a18ee5162..3063b6ab32e5 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c @@ -595,16 +595,6 @@ void dccg401_set_dp_dto( bool enable = false; - if (params->otg_inst > 3) { - /* dcn401 only has 4 instances */ - BREAK_TO_DEBUGGER(); - return; - } - if (!params->refclk_hz) { - BREAK_TO_DEBUGGER(); - return; - } - if (!dc_is_tmds_signal(params->signal)) { uint64_t dto_integer; uint64_t dto_phase_hz; @@ -612,6 +602,11 @@ void dccg401_set_dp_dto( enable = true; + if (!params->refclk_hz) { + BREAK_TO_DEBUGGER(); + return; + } + /* Set DTO values: * int = target_pix_rate / reference_clock * phase = target_pix_rate - int * reference_clock, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c index d11afd1ce72a..941dce439e97 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c @@ -41,7 +41,7 @@ #define FN(reg_name, field_name) \ hubbub2->shifts->field_name, hubbub2->masks->field_name -static void dcn401_init_crb(struct hubbub *hubbub) +void dcn401_init_crb(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1110,7 +1110,7 @@ bool hubbub401_get_dcc_compression_cap(struct hubbub *hubbub, return true; } -static void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg) +void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1147,7 +1147,7 @@ static void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, un } } -static void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase) +void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1170,7 +1170,7 @@ static void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned comp } } -static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) +void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1192,7 +1192,7 @@ static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) } } -static bool dcn401_program_arbiter(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower) +bool dcn401_program_arbiter(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h index b1d9ea9d1c3d..f48715544429 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h @@ -194,6 +194,11 @@ bool hubbub401_get_dcc_compression_cap( const struct dc_dcc_surface_param *input, struct dc_surface_dcc_cap *output); +bool dcn401_program_arbiter( + struct hubbub *hubbub, + struct dml2_display_arb_regs *arb_regs, + bool safe_to_lower); + void hubbub401_construct(struct dcn20_hubbub *hubbub2, struct dc_context *ctx, const struct dcn_hubbub_registers *hubbub_regs, @@ -203,4 +208,9 @@ void hubbub401_construct(struct dcn20_hubbub *hubbub2, int pixel_chunk_size_kb, int config_return_buffer_size_kb); +void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg); +void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase); +void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst); +void dcn401_init_crb(struct hubbub *hubbub); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c index 0953acbcc6d4..5aafd0eedf66 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c @@ -270,7 +270,7 @@ static bool optc35_get_crc(struct timing_generator *optc, uint8_t idx, return true; } -static bool optc35_configure_crc(struct timing_generator *optc, +bool optc35_configure_crc(struct timing_generator *optc, const struct crc_params *params) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -437,7 +437,7 @@ void optc35_set_drr( REG_WRITE(OTG_V_COUNT_STOP_CONTROL2, 0); } -static void optc35_set_long_vtotal( +void optc35_set_long_vtotal( struct timing_generator *optc, const struct long_vtotal_params *params) { @@ -524,7 +524,7 @@ static void optc35_set_long_vtotal( } } -static void optc35_wait_otg_disable(struct timing_generator *optc) +void optc35_wait_otg_disable(struct timing_generator *optc) { struct optc *optc1; uint32_t is_master_en; diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h index 5c2cb1f27783..82e0818c8f9f 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h @@ -90,4 +90,13 @@ void dcn35_timing_generator_set_fgcg(struct optc *optc1, bool enable); void optc35_set_drr(struct timing_generator *optc, const struct drr_params *params); +void optc35_set_long_vtotal( + struct timing_generator *optc, + const struct long_vtotal_params *params); + +bool optc35_configure_crc(struct timing_generator *optc, + const struct crc_params *params); + +void optc35_wait_otg_disable(struct timing_generator *optc); + #endif /* __DC_OPTC_DCN35_H__ */ From c6e2639cdcf07810dcd56c64ab1aeccaa5877035 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 2 Feb 2026 20:34:42 -0500 Subject: [PATCH 06/28] drm/amd/display: Disable SR feature on eDP1 by default [Why & How] Disable SR feature on eDP1 by default. Reviewed-by: Wenjing Liu Signed-off-by: Charlene Liu Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 12 ++++++++++-- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 8 ++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 1 - drivers/gpu/drm/amd/display/dc/dm_helpers.h | 2 +- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 2 +- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 1f41d6540b83..bf2a356b3475 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -1153,11 +1153,19 @@ void dm_helpers_init_panel_settings( void dm_helpers_override_panel_settings( struct dc_context *ctx, - struct dc_panel_config *panel_config) + struct dc_link *link) { + unsigned int panel_inst = 0; + // Feature DSC if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) - panel_config->dsc.disable_dsc_edp = true; + link->panel_config.dsc.disable_dsc_edp = true; + + if (dc_get_edp_link_panel_inst(ctx->dc, link, &panel_inst) && panel_inst == 1) { + link->panel_config.psr.disable_psr = true; + link->panel_config.psr.disallow_psrsu = true;; + link->panel_config.psr.disallow_replay = true; + } } void *dm_helpers_allocate_gpu_mem( diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index fd491b7a3cd7..99d6d6c93561 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -80,12 +80,20 @@ void amdgpu_dm_set_psr_caps(struct dc_link *link) link->psr_settings.psr_feature_enabled = false; } else { + unsigned int panel_inst = 0; + if (link_supports_psrsu(link)) link->psr_settings.psr_version = DC_PSR_VERSION_SU_1; else link->psr_settings.psr_version = DC_PSR_VERSION_1; link->psr_settings.psr_feature_enabled = true; + + /*disable allow psr/psrsu/replay on eDP1*/ + if (dc_get_edp_link_panel_inst(link->ctx->dc, link, &panel_inst) && panel_inst == 1) { + link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; + link->psr_settings.psr_feature_enabled = false; + } } } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ce08477d1ccd..4c4239cac863 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -505,7 +505,6 @@ union allow_lttpr_non_transparent_mode { } bits; unsigned char raw; }; - /* Structure to hold configuration flags set by dm at dc creation. */ struct dc_config { bool gpu_vm_support; diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 7014b8c2c956..2818df555e62 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -209,7 +209,7 @@ void dm_helpers_init_panel_settings( struct dc_sink *sink); void dm_helpers_override_panel_settings( struct dc_context *ctx, - struct dc_panel_config *config); + struct dc_link *link); int dm_helper_dmub_aux_transfer_sync( struct dc_context *ctx, const struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 578509e8d0e2..b2c020071cbf 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1333,7 +1333,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, // Pickup base DM settings dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink); // Override dc_panel_config if system has specific settings - dm_helpers_override_panel_settings(dc_ctx, &link->panel_config); + dm_helpers_override_panel_settings(dc_ctx, link); //sink only can use supported link rate table, we are foreced to enable it if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN) From 63b7f5826508a2b81e3010200d13ce92f0b2311d Mon Sep 17 00:00:00 2001 From: Muaaz Nisar Date: Wed, 4 Feb 2026 03:08:01 -0500 Subject: [PATCH 07/28] drm/amd/display: Implementing ramless idle mouse trigger [Why & How] Adding mouse trigger in dc_stream to recover from low refresh rate idle state upon mouse movement without vsync interrupts. Reviewed-by: Aric Cyr Signed-off-by: Muaaz Nisar Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++++ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 15 +++++++++++++++ drivers/gpu/drm/amd/display/dc/dc_stream.h | 9 +++++++++ 3 files changed, 28 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 17ba7af0ddcd..6f3c283431d4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3369,6 +3369,10 @@ static void copy_stream_update_to_stream(struct dc *dc, stream->scaler_sharpener_update = *update->scaler_sharpener_update; if (update->sharpening_required) stream->sharpening_required = *update->sharpening_required; + + if (update->drr_trigger_mode) { + stream->drr_trigger_mode = *update->drr_trigger_mode; + } } static void backup_planes_and_stream_state( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 9349cccc8438..191f6435e7c6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -515,6 +515,21 @@ bool dc_stream_program_cursor_position( } } + if (stream->drr_trigger_mode == DRR_TRIGGER_ON_FLIP_AND_CURSOR) { + /* apply manual trigger */ + int i; + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + + /* trigger event on first pipe with current stream */ + if (stream == pipe_ctx->stream) { + pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); + break; + } + } + } + return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 9960494007ff..86394203cee7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -183,6 +183,11 @@ struct luminance_data { int dm_max_decrease_from_nominal; }; +enum dc_drr_trigger_mode { + DRR_TRIGGER_ON_FLIP = 0, + DRR_TRIGGER_ON_FLIP_AND_CURSOR, +}; + struct dc_stream_state { // sink is deprecated, new code should not reference // this pointer @@ -316,6 +321,8 @@ struct dc_stream_state { bool scaler_sharpener_update; bool sharpening_required; + enum dc_drr_trigger_mode drr_trigger_mode; + struct dc_update_scratch_space *update_scratch; }; @@ -366,6 +373,8 @@ struct dc_stream_update { bool *hw_cursor_req; bool *scaler_sharpener_update; bool *sharpening_required; + + enum dc_drr_trigger_mode *drr_trigger_mode; }; bool dc_is_stream_unchanged( From 4c595e75110ece20af3a68c1ebef8ed4c1b69afe Mon Sep 17 00:00:00 2001 From: Bhuvanachandra Pinninti Date: Tue, 3 Feb 2026 15:37:07 +0530 Subject: [PATCH 08/28] drm/amd/display: Migrate DCCG registers access from hwseq to dccg component. [Why] Direct DCCG register access in hwseq layer was creating register conflicts. [How] Migrated DCCG registers from hwseq-dccg component. Reviewed-by: Martin Leung Signed-off-by: Bhuvanachandra Pinninti Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dccg/dcn20/dcn20_dccg.c | 54 ++++++++++++++++++- .../amd/display/dc/dccg/dcn20/dcn20_dccg.h | 14 +++-- .../amd/display/dc/dccg/dcn201/dcn201_dccg.c | 7 ++- .../amd/display/dc/dccg/dcn21/dcn21_dccg.c | 6 ++- .../amd/display/dc/dccg/dcn30/dcn30_dccg.c | 6 ++- .../amd/display/dc/dccg/dcn301/dcn301_dccg.c | 6 ++- .../amd/display/dc/dccg/dcn31/dcn31_dccg.c | 5 ++ .../amd/display/dc/dccg/dcn314/dcn314_dccg.c | 7 ++- .../amd/display/dc/dccg/dcn32/dcn32_dccg.c | 5 ++ .../amd/display/dc/dccg/dcn35/dcn35_dccg.c | 11 +++- .../amd/display/dc/dccg/dcn401/dcn401_dccg.c | 2 + .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 5 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 29 +++------- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 5 +- .../amd/display/dc/hwss/dcn21/dcn21_hwseq.c | 9 ++-- .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 5 +- .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 5 +- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 5 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 3 +- .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 5 +- drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 4 ++ 21 files changed, 143 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c index 33d8bd91cb01..733b85d450d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c @@ -131,6 +131,54 @@ void dccg2_otg_drop_pixel(struct dccg *dccg, void dccg2_init(struct dccg *dccg) { + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + /* Hardcoded register values for DCN20 + * These are specific to 100Mhz refclk + * Different ASICs with different refclk may override this in their own init + */ + REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x00120264); + REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x001186a0); + REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x0e01003c); + + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); +} + +void dccg2_refclk_setup(struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + /* REFCLK programming that must occur after hubbub initialization */ + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); +} + +bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + return REG_READ(MICROSECOND_TIME_BASE_DIV) == 0x00120464; +} + +void dccg2_allow_clock_gating(struct dccg *dccg, bool allow) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + if (allow) { + REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + } else { + REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0xFFFFFFFF); + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0xFFFFFFFF); + } +} + +void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, enable ? 0 : 1); } static const struct dccg_funcs dccg2_funcs = { @@ -139,7 +187,11 @@ static const struct dccg_funcs dccg2_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg2_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h index 8bdffd9ff31b..3711d400773a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h @@ -37,7 +37,8 @@ SR(REFCLK_CNTL),\ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1),\ - SR(DISPCLK_FREQ_CHANGE_CNTL) + SR(DISPCLK_FREQ_CHANGE_CNTL),\ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL) #define DCCG_REG_LIST_DCN2() \ DCCG_COMMON_REG_LIST_DCN_BASE(),\ @@ -81,7 +82,8 @@ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 0, mask_sh),\ - DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh) + DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh),\ + DCCG_SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh) @@ -130,7 +132,8 @@ type DISPCLK_CHG_FWD_CORR_DISABLE;\ type DISPCLK_FREQ_CHANGE_CNTL;\ type OTG_ADD_PIXEL[MAX_PIPES];\ - type OTG_DROP_PIXEL[MAX_PIPES]; + type OTG_DROP_PIXEL[MAX_PIPES];\ + type DC_MEM_GLOBAL_PWR_REQ_DIS; #define DCCG3_REG_FIELD_LIST(type) \ type HDMICHARCLK0_EN;\ @@ -515,6 +518,11 @@ void dccg2_otg_drop_pixel(struct dccg *dccg, void dccg2_init(struct dccg *dccg); +void dccg2_refclk_setup(struct dccg *dccg); +void dccg2_allow_clock_gating(struct dccg *dccg, bool allow); +void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable); +bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg); + struct dccg *dccg2_create( struct dc_context *ctx, const struct dccg_registers *regs, diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c index 9a3402148fde..79d14ce19393 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c @@ -24,6 +24,7 @@ */ #include "dcn201_dccg.h" +#include "dcn20/dcn20_dccg.h" #include "reg_helper.h" #include "core_types.h" @@ -56,7 +57,11 @@ static const struct dccg_funcs dccg201_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg201_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c index d07c04458d31..b48dcafbae66 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c @@ -103,7 +103,11 @@ static const struct dccg_funcs dccg21_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg21_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c index d445dfefc047..adec7c3c2d49 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c @@ -49,7 +49,11 @@ static const struct dccg_funcs dccg3_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg3_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c index 97e9be87afd9..fc9bddd94b50 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c @@ -48,7 +48,11 @@ static const struct dccg_funcs dccg301_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg301_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c index 97df04b7e39d..c647dff5234a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c @@ -26,6 +26,7 @@ #include "reg_helper.h" #include "core_types.h" #include "dcn31_dccg.h" +#include "dcn20/dcn20_dccg.h" #include "dal_asic_id.h" #define TO_DCN_DCCG(dccg)\ @@ -850,6 +851,10 @@ static const struct dccg_funcs dccg31_funcs = { .disable_dsc = dccg31_disable_dscclk, .enable_dsc = dccg31_enable_dscclk, .dccg_read_reg_state = dccg31_read_reg_state, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg31_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c index ef3db6beba25..2e9c4b13988a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c @@ -29,6 +29,7 @@ #include "dcn31/dcn31_dccg.h" #include "dcn314_dccg.h" +#include "dcn20/dcn20_dccg.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -378,7 +379,11 @@ static const struct dccg_funcs dccg314_funcs = { .trigger_dio_fifo_resync = dccg314_trigger_dio_fifo_resync, .set_valid_pixel_rate = dccg314_set_valid_pixel_rate, .set_dtbclk_p_src = dccg314_set_dtbclk_p_src, - .dccg_read_reg_state = dccg31_read_reg_state + .dccg_read_reg_state = dccg31_read_reg_state, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg314_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c index 21a6ca5ca192..ce697c3249fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c @@ -26,6 +26,7 @@ #include "reg_helper.h" #include "core_types.h" #include "dcn32_dccg.h" +#include "dcn20/dcn20_dccg.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -347,6 +348,10 @@ static const struct dccg_funcs dccg32_funcs = { .get_pixel_rate_div = dccg32_get_pixel_rate_div, .trigger_dio_fifo_resync = dccg32_trigger_dio_fifo_resync, .set_dtbclk_p_src = dccg32_set_dtbclk_p_src, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg32_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c index 838c6617c029..943ec1983076 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c @@ -26,6 +26,7 @@ #include "core_types.h" #include "resource.h" #include "dcn35_dccg.h" +#include "dcn20/dcn20_dccg.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -2411,6 +2412,10 @@ static const struct dccg_funcs dccg35_funcs_new = { .enable_symclk_se = dccg35_enable_symclk_se_cb, .disable_symclk_se = dccg35_disable_symclk_se_cb, .set_dtbclk_p_src = dccg35_set_dtbclk_p_src_cb, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; static const struct dccg_funcs dccg35_funcs = { @@ -2442,8 +2447,12 @@ static const struct dccg_funcs dccg35_funcs = { .enable_symclk_se = dccg35_enable_symclk_se, .disable_symclk_se = dccg35_disable_symclk_se, .set_dtbclk_p_src = dccg35_set_dtbclk_p_src, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done, /* Deprecated - for backward compatibility only */ .dccg_root_gate_disable_control = dccg35_root_gate_disable_control, - .dccg_read_reg_state = dccg31_read_reg_state, + .dccg_read_reg_state = dccg31_read_reg_state }; struct dccg *dccg35_create( diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c index 3063b6ab32e5..f1d394560892 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c @@ -27,6 +27,7 @@ #include "core_types.h" #include "dcn401_dccg.h" #include "dcn31/dcn31_dccg.h" +#include "dcn20/dcn20_dccg.h" /* #include "dmub_common.h" @@ -861,6 +862,7 @@ static const struct dccg_funcs dccg401_funcs = { .update_dpp_dto = dccg401_update_dpp_dto, .get_dccg_ref_freq = dccg401_get_dccg_ref_freq, .dccg_init = dccg401_init, + .allow_clock_gating = dccg2_allow_clock_gating, .set_dpstreamclk = dccg401_set_dpstreamclk, .enable_symclk32_se = dccg31_enable_symclk32_se, .disable_symclk32_se = dccg31_disable_symclk32_se, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index 9613d1ceb5dc..5243177c1faa 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -1887,9 +1887,8 @@ void dcn10_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 0ee3a0041c61..307e8f8060e6 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -357,26 +357,10 @@ void dcn20_enable_power_gating_plane( void dcn20_dccg_init(struct dce_hwseq *hws) { - /* - * set MICROSECOND_TIME_BASE_DIV - * 100Mhz refclk -> 0x120264 - * 27Mhz refclk -> 0x12021b - * 48Mhz refclk -> 0x120230 - * - */ - REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264); + struct dc *dc = hws->ctx->dc; - /* - * set MILLISECOND_TIME_BASE_DIV - * 100Mhz refclk -> 0x1186a0 - * 27Mhz refclk -> 0x106978 - * 48Mhz refclk -> 0x10bb80 - * - */ - REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0); - - /* This value is dependent on the hardware pipeline delay so set once per SOC */ - REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->dccg_init) + dc->res_pool->dccg->funcs->dccg_init(dc->res_pool->dccg); } void dcn20_disable_vga( @@ -3156,8 +3140,11 @@ void dcn20_fpga_init_hw(struct dc *dc) dcn10_hubbub_global_timer_enable(dc->res_pool->hubbub, true, 2); - if (REG(REFCLK_CNTL)) - REG_WRITE(REFCLK_CNTL, 0); + if (hws->funcs.dccg_init) + hws->funcs.dccg_init(hws); + + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->refclk_setup) + dc->res_pool->dccg->funcs->refclk_setup(dc->res_pool->dccg); // diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c index 6298bd87a18b..ce18d75fd991 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c @@ -367,9 +367,8 @@ void dcn201_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c index e2269211553c..062745389d9a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c @@ -33,6 +33,7 @@ #include "vmid.h" #include "reg_helper.h" #include "hw/clk_mgr.h" +#include "hw/dccg.h" #include "dc_dmub_srv.h" #include "abm.h" #include "link_service.h" @@ -87,12 +88,10 @@ int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_ bool dcn21_s0i3_golden_init_wa(struct dc *dc) { - struct dce_hwseq *hws = dc->hwseq; - uint32_t value = 0; + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done) + return !dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done(dc->res_pool->dccg); - value = REG_READ(MICROSECOND_TIME_BASE_DIV); - - return value != 0x00120464; + return false; } void dcn21_exit_optimized_pwr_state( diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c index 333275088a6c..d04cfd403b7e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c @@ -801,9 +801,8 @@ void dcn30_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c index fa35d538a10a..db2f7cbb12ff 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c @@ -247,9 +247,8 @@ void dcn31_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c index 01fa459ae7b0..2767d3a97812 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -963,9 +963,8 @@ void dcn32_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index 0cbd75ab61a1..b5a4cefbd35f 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -286,7 +286,8 @@ void dcn35_init_hw(struct dc *dc) } if (dc->debug.disable_mem_low_power) { - REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->enable_memory_low_power) + dc->res_pool->dccg->funcs->enable_memory_low_power(dc->res_pool->dccg, false); } if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks) dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index d1515039e824..b91517b9fedc 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -326,9 +326,8 @@ void dcn401_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index 1e6ffd86a4c0..d6f5e01a0b66 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -224,6 +224,10 @@ struct dccg_funcs { void (*otg_drop_pixel)(struct dccg *dccg, uint32_t otg_inst); void (*dccg_init)(struct dccg *dccg); + void (*refclk_setup)(struct dccg *dccg); /* Deprecated - for backward compatibility only */ + void (*allow_clock_gating)(struct dccg *dccg, bool allow); + void (*enable_memory_low_power)(struct dccg *dccg, bool enable); + bool (*is_s0i3_golden_init_wa_done)(struct dccg *dccg); void (*set_dpstreamclk_root_clock_gating)( struct dccg *dccg, int dp_hpo_inst, From 1a524d9a872f0fa164160869f2b69b590a22ad4f Mon Sep 17 00:00:00 2001 From: Nicholas Carbones Date: Wed, 4 Feb 2026 16:52:48 -0500 Subject: [PATCH 09/28] Revert "drm/amd/display: Add Handling for gfxversion DcGfxBase" This reverts commit 2e193f5b1b4f ("drm/amd/display: Add Handling for gfxversion DcGfxBase") Reason for revert: Cause some regressions Reviewed-by: Dillon Varone Signed-off-by: Nicholas Carbones Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c index 3f4963ce3a00..bf5e7f4e0416 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c @@ -460,9 +460,6 @@ static void populate_dml21_surface_config_from_plane_state( case DcGfxAddr3: surface->tiling = gfx_addr3_to_dml2_swizzle_mode(plane_state->tiling_info.gfx_addr3.swizzle); break; - case DcGfxBase: - surface->tiling = dml2_sw_linear; - break; } } From c1cf87eb796a8342ca3fe096ea96aee9fcd937b3 Mon Sep 17 00:00:00 2001 From: Nicholas Carbones Date: Mon, 9 Feb 2026 11:34:00 +0800 Subject: [PATCH 10/28] Revert "drm/amd/display: Correct hubp GfxVersion verification" This reverts commit 3303aa64e7a6 ("drm/amd/display: Correct hubp GfxVersion verification") Reason for revert: Got blank screen issues while doing PNP Reviewed-by: Joshua Aberback Signed-off-by: Nicholas Carbones Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/hubp/dcn10/dcn10_hubp.c | 31 ++++++++----------- .../amd/display/dc/hubp/dcn20/dcn20_hubp.c | 24 ++++++-------- .../amd/display/dc/hubp/dcn30/dcn30_hubp.c | 24 ++++++-------- 3 files changed, 33 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c index 78c866688c61..e697d9bf1b44 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c @@ -145,26 +145,21 @@ void hubp1_program_tiling( { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - ASSERT(info->gfxversion == DcGfxVersion9 || info->gfxversion == DcGfxBase); + ASSERT(info->gfxversion == DcGfxVersion9); - if (info->gfxversion == DcGfxVersion9) { - REG_UPDATE_6(DCSURF_ADDR_CONFIG, - NUM_PIPES, log_2(info->gfx9.num_pipes), - NUM_BANKS, log_2(info->gfx9.num_banks), - PIPE_INTERLEAVE, info->gfx9.pipe_interleave, - NUM_SE, log_2(info->gfx9.num_shader_engines), - NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se), - MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags)); - - REG_UPDATE_4(DCSURF_TILING_CONFIG, - SW_MODE, info->gfx9.swizzle, - META_LINEAR, info->gfx9.meta_linear, - RB_ALIGNED, info->gfx9.rb_aligned, - PIPE_ALIGNED, info->gfx9.pipe_aligned); - } else { - hubp1_clear_tiling(&hubp1->base); - } + REG_UPDATE_6(DCSURF_ADDR_CONFIG, + NUM_PIPES, log_2(info->gfx9.num_pipes), + NUM_BANKS, log_2(info->gfx9.num_banks), + PIPE_INTERLEAVE, info->gfx9.pipe_interleave, + NUM_SE, log_2(info->gfx9.num_shader_engines), + NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se), + MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags)); + REG_UPDATE_4(DCSURF_TILING_CONFIG, + SW_MODE, info->gfx9.swizzle, + META_LINEAR, info->gfx9.meta_linear, + RB_ALIGNED, info->gfx9.rb_aligned, + PIPE_ALIGNED, info->gfx9.pipe_aligned); } void hubp1_program_size( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c index aaa8f8cf6c30..4715e60e812a 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c @@ -313,22 +313,18 @@ static void hubp2_program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion9 || info->gfxversion == DcGfxBase); + ASSERT(info->gfxversion == DcGfxVersion9); - if (info->gfxversion == DcGfxVersion9) { - REG_UPDATE_3(DCSURF_ADDR_CONFIG, - NUM_PIPES, log_2(info->gfx9.num_pipes), - PIPE_INTERLEAVE, info->gfx9.pipe_interleave, - MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags)); + REG_UPDATE_3(DCSURF_ADDR_CONFIG, + NUM_PIPES, log_2(info->gfx9.num_pipes), + PIPE_INTERLEAVE, info->gfx9.pipe_interleave, + MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags)); - REG_UPDATE_4(DCSURF_TILING_CONFIG, - SW_MODE, info->gfx9.swizzle, - META_LINEAR, 0, - RB_ALIGNED, 0, - PIPE_ALIGNED, 0); - } else { - hubp2_clear_tiling(&hubp2->base); - } + REG_UPDATE_4(DCSURF_TILING_CONFIG, + SW_MODE, info->gfx9.swizzle, + META_LINEAR, 0, + RB_ALIGNED, 0, + PIPE_ALIGNED, 0); } void hubp2_program_size( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c index 2126830a5a9e..207c2f86b7d7 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c @@ -321,22 +321,18 @@ void hubp3_program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion9 || info->gfxversion == DcGfxBase); + ASSERT(info->gfxversion == DcGfxVersion9); - if (info->gfxversion == DcGfxVersion9) { - REG_UPDATE_4(DCSURF_ADDR_CONFIG, - NUM_PIPES, log_2(info->gfx9.num_pipes), - PIPE_INTERLEAVE, info->gfx9.pipe_interleave, - MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags), - NUM_PKRS, log_2(info->gfx9.num_pkrs)); + REG_UPDATE_4(DCSURF_ADDR_CONFIG, + NUM_PIPES, log_2(info->gfx9.num_pipes), + PIPE_INTERLEAVE, info->gfx9.pipe_interleave, + MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags), + NUM_PKRS, log_2(info->gfx9.num_pkrs)); - REG_UPDATE_3(DCSURF_TILING_CONFIG, - SW_MODE, info->gfx9.swizzle, - META_LINEAR, info->gfx9.meta_linear, - PIPE_ALIGNED, info->gfx9.pipe_aligned); - } else { - hubp3_clear_tiling(&hubp2->base); - } + REG_UPDATE_3(DCSURF_TILING_CONFIG, + SW_MODE, info->gfx9.swizzle, + META_LINEAR, info->gfx9.meta_linear, + PIPE_ALIGNED, info->gfx9.pipe_aligned); } From d637dd7288814bc4dfbc851780f7a3eada1e13d3 Mon Sep 17 00:00:00 2001 From: Nicholas Carbones Date: Mon, 9 Feb 2026 11:37:23 +0800 Subject: [PATCH 11/28] Revert "drm/amd/display: Add Gfx Base Case For Linear Tiling Handling" This reverts commit 08a01ec306db ("drm/amd/display: Add Gfx Base Case For Linear Tiling Handling") Reason for revert: Got blank screen issues while doing PNP Reviewed-by: Joshua Aberback Signed-off-by: Nicholas Carbones Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - drivers/gpu/drm/amd/display/dc/core/dc.c | 1 - drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 7 ------- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 1 - drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 +-- drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c | 3 --- drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c | 3 --- drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c | 1 - drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c | 2 -- drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c | 2 -- drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c | 2 -- drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 7 +------ .../amd/display/dc/resource/dcn32/dcn32_resource_helpers.c | 3 +-- 13 files changed, 3 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ef9df52dd34b..9a9f8362811f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8040,7 +8040,6 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc, dc_plane_state->plane_size.chroma_size.height = stream->src.height; dc_plane_state->plane_size.chroma_size.width = stream->src.width; dc_plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888; - dc_plane_state->tiling_info.gfxversion = DcGfxVersion9; dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN; dc_plane_state->rotation = ROTATION_ANGLE_0; dc_plane_state->is_tiling_rotated = false; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 6f3c283431d4..984b4bc5f53c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2770,7 +2770,6 @@ static struct surface_update_descriptor get_plane_info_update_type(const struct case DcGfxVersion7: case DcGfxVersion8: case DcGfxVersionUnknown: - case DcGfxBase: default: break; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index a13d9d7dd6c5..052d573408c3 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -2065,13 +2065,6 @@ void get_surface_tile_visual_confirm_color( while (bottom_pipe_ctx->bottom_pipe != NULL) bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe; - if (bottom_pipe_ctx->plane_state->tiling_info.gfxversion == DcGfxBase) { - /* LINEAR Surface - set border color to red */ - color->color_r_cr = color_value; - return; - } - - ASSERT(bottom_pipe_ctx->plane_state->tiling_info.gfxversion == DcGfxVersion9); switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) { case DC_SW_LINEAR: /* LINEAR Surface - set border color to red */ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 639831295b21..03d125f794b0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -4434,7 +4434,6 @@ enum dc_status dc_validate_global_state( if (dc->res_pool->funcs->patch_unknown_plane_state && pipe_ctx->plane_state && - pipe_ctx->plane_state->tiling_info.gfxversion == DcGfxVersion9 && pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) { result = dc->res_pool->funcs->patch_unknown_plane_state(pipe_ctx->plane_state); if (result != DC_OK) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 7121629da38e..cfa569a7bff1 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -342,8 +342,7 @@ enum swizzle_mode_addr3_values { }; enum dc_gfxversion { - DcGfxBase = 0, - DcGfxVersion7, + DcGfxVersion7 = 0, DcGfxVersion8, DcGfxVersion9, DcGfxVersion10, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index 5df58fadc862..1c2009e38aa1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c @@ -100,7 +100,6 @@ static enum mi_bits_per_pixel get_mi_bpp( static enum mi_tiling_format get_mi_tiling( struct dc_tiling_info *tiling_info) { - ASSERT(tiling_info->gfxversion == DcGfxVersion8); switch (tiling_info->gfx8.array_mode) { case DC_ARRAY_1D_TILED_THIN1: case DC_ARRAY_1D_TILED_THICK: @@ -434,7 +433,6 @@ static void program_tiling( struct dce_mem_input *dce_mi, const struct dc_tiling_info *info) { if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */ - ASSERT(info->gfxversion == DcGfxVersion9); REG_UPDATE_6(GRPH_CONTROL, GRPH_SW_MODE, info->gfx9.swizzle, GRPH_NUM_BANKS, log_2(info->gfx9.num_banks), @@ -449,7 +447,6 @@ static void program_tiling( } if (dce_mi->masks->GRPH_MICRO_TILE_MODE) { /* GFX8 */ - ASSERT(info->gfxversion == DcGfxVersion8); REG_UPDATE_9(GRPH_CONTROL, GRPH_NUM_BANKS, info->gfx8.num_banks, GRPH_BANK_WIDTH, info->gfx8.bank_width, diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c index 67cfca3361fb..2c43c2422638 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c @@ -165,8 +165,6 @@ static void program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion8); - uint32_t value = 0; set_reg_field_value(value, info->gfx8.num_banks, @@ -543,7 +541,6 @@ static const unsigned int *get_dvmm_hw_setting( else bpp = bpp_8; - ASSERT(tiling_info->gfxversion == DcGfxVersion8); switch (tiling_info->gfx8.array_mode) { case DC_ARRAY_1D_TILED_THIN1: case DC_ARRAY_1D_TILED_THICK: diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c index 71eeee02c0fa..74962791302f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c @@ -1006,7 +1006,6 @@ bool dcn_validate_bandwidth( v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs( pipe->plane_state->format); - ASSERT(pipe->plane_state->tiling_info.gfxversion == DcGfxVersion9); v->source_surface_mode[input_idx] = tl_sw_mode_to_bw_defs( pipe->plane_state->tiling_info.gfx9.swizzle); v->lb_bit_per_pixel[input_idx] = tl_lb_bpp_to_int(pipe->plane_res.scl_data.lb_params.depth); diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c index e697d9bf1b44..6378e3fd7249 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c @@ -145,8 +145,6 @@ void hubp1_program_tiling( { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - ASSERT(info->gfxversion == DcGfxVersion9); - REG_UPDATE_6(DCSURF_ADDR_CONFIG, NUM_PIPES, log_2(info->gfx9.num_pipes), NUM_BANKS, log_2(info->gfx9.num_banks), diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c index 4715e60e812a..92288de4cc10 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c @@ -313,8 +313,6 @@ static void hubp2_program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion9); - REG_UPDATE_3(DCSURF_ADDR_CONFIG, NUM_PIPES, log_2(info->gfx9.num_pipes), PIPE_INTERLEAVE, info->gfx9.pipe_interleave, diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c index 207c2f86b7d7..0cc6f4558989 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c @@ -321,8 +321,6 @@ void hubp3_program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion9); - REG_UPDATE_4(DCSURF_ADDR_CONFIG, NUM_PIPES, log_2(info->gfx9.num_pipes), PIPE_INTERLEAVE, info->gfx9.pipe_interleave, diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index 861e940250af..c205500290ec 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c @@ -589,12 +589,7 @@ void hubp401_program_tiling( * * DIM_TYPE field in DCSURF_TILING for Display is always 1 (2D dimension) which is HW default. */ - if (info->gfxversion == DcGfxAddr3) { - REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info->gfx_addr3.swizzle); - } else { - /* linear */ - REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, 0); - } + REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info->gfx_addr3.swizzle); } void hubp401_program_size( diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c index 7d99f5d79e6d..f5a4e97c40ce 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c @@ -401,8 +401,7 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context, */ if (pipe_cnt == 1) { pipes[0].pipe.src.det_size_override = DCN3_2_MAX_DET_SIZE; - if (pipe->plane_state && !disable_unbounded_requesting && pipe->plane_state->tiling_info.gfxversion != DcGfxBase && - !(pipe->plane_state->tiling_info.gfxversion == DcGfxVersion9 && pipe->plane_state->tiling_info.gfx9.swizzle == DC_SW_LINEAR)) { + if (pipe->plane_state && !disable_unbounded_requesting && pipe->plane_state->tiling_info.gfx9.swizzle != DC_SW_LINEAR) { if (!is_dual_plane(pipe->plane_state->format)) { pipes[0].pipe.src.det_size_override = DCN3_2_DEFAULT_DET_SIZE; pipes[0].pipe.src.unbounded_req_mode = true; From d1d51519bc3bf4ae316203427d733a002d947cd0 Mon Sep 17 00:00:00 2001 From: Saidireddy Yenugu Date: Wed, 21 Jan 2026 18:57:25 +0530 Subject: [PATCH 12/28] drm/amd/display: Skip eDP detection when no sink [Why & How] When there is no eDP panel connected and during s0ix resume, unnecessary eDP power sequence and HPD happening, resulting in ~2 seconds delay. Fixed the issue by avoiding link detect for eDP connection with no sink in dm_resume. Reviewed-by: Mario Limonciello Signed-off-by: Saidireddy Yenugu Co-developed-by: ThummarDip Kishorbhai Signed-off-by: ThummarDip Kishorbhai Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 9a9f8362811f..c3c045c8144f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3614,6 +3614,11 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) if (aconnector->mst_root) continue; + /* Skip eDP detection, when there is no sink present */ + if (aconnector->dc_link->connector_signal == SIGNAL_TYPE_EDP && + !aconnector->dc_link->edp_sink_present) + continue; + guard(mutex)(&aconnector->hpd_lock); if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type)) drm_err(adev_to_drm(adev), "KMS: Failed to detect connector\n"); From b6a65009e7ce3f0cc72da18f186adb60717b51a0 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Thu, 5 Feb 2026 20:28:49 -0500 Subject: [PATCH 13/28] drm/amd/display: Correct logic check error for fastboot [Why] Fix fastboot broken in driver. This is caused by an open source backport change 7495962c. from the comment, the intended check is to disable fastboot for pre-DCN10. but the logic check is reversed, and causes fastboot to be disabled on all DCN10 and after. fastboot is for driver trying to pick up bios used hw setting and bypass reprogramming the hw if dc_validate_boot_timing() condition meets. Fixes: 7495962cbceb ("drm/amd/display: Disable fastboot on DCE 6 too") Cc: stable@vger.kernel.org Reviewed-by: Mario Limonciello Reviewed-by: Ovidiu Bunea Signed-off-by: Charlene Liu Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 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 4659e1b489ba..4277b6761522 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 @@ -1964,8 +1964,8 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) get_edp_streams(context, edp_streams, &edp_stream_num); - /* Check fastboot support, disable on DCE 6-8 because of blank screens */ - if (edp_num && edp_stream_num && dc->ctx->dce_version < DCE_VERSION_10_0) { + /* Check fastboot support, disable on DCE 6-8-10 because of blank screens */ + if (edp_num && edp_stream_num && dc->ctx->dce_version > DCE_VERSION_10_0) { for (i = 0; i < edp_num; i++) { edp_link = edp_links[i]; if (edp_link != edp_streams[0]->link) From d3b03850bddc775eacb13cb3969141cf725308ab Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Thu, 5 Feb 2026 22:54:27 -0700 Subject: [PATCH 14/28] drm/amd/display: Check return of shaper curve to HW format [Why & How] Check return of cm3_helper_translate_curve_to_hw_format. This is reported as a CHECKED_RETURN error by Coverity. Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Hung Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c index 2767d3a97812..a0aaa727e9fa 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -486,7 +486,7 @@ bool dcn32_set_mcm_luts( struct dpp *dpp_base = pipe_ctx->plane_res.dpp; int mpcc_id = pipe_ctx->plane_res.hubp->inst; struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; - bool result = true; + bool rval, result; const struct pwl_params *lut_params = NULL; // 1D LUT @@ -509,10 +509,10 @@ bool dcn32_set_mcm_luts( lut_params = &plane_state->in_shaper_func.pwl; else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) { // TODO: dpp_base replace - cm3_helper_translate_curve_to_hw_format(plane_state->ctx, + rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, &plane_state->in_shaper_func, &dpp_base->shaper_params, true); - lut_params = &dpp_base->shaper_params; + lut_params = rval ? &dpp_base->shaper_params : NULL; } mpc->funcs->program_shaper(mpc, lut_params, mpcc_id); From 1b38a87b8f8020e8ef4563e7752a64182b5a39b9 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 4 Feb 2026 22:05:16 -0700 Subject: [PATCH 15/28] drm/amd/display: Remove conditional for shaper 3DLUT power-on [Why] Shaper programming has high chance to fail on first time after power-on or reboot. This can be verified by running IGT's kms_colorop. [How] Always power on the shaper and 3DLUT before programming by removing the debug flag of low power mode. Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Hung Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c index 83bbbf34bcac..badcef027b84 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c @@ -724,8 +724,7 @@ bool mpc32_program_shaper( return false; } - if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) - mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); + mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); current_mode = mpc32_get_shaper_current(mpc, mpcc_id); From 73463e26f7e2adc5e00873a8afb03ddf49fd838f Mon Sep 17 00:00:00 2001 From: Andrew Martin Date: Mon, 2 Feb 2026 05:42:44 -0500 Subject: [PATCH 16/28] drm/amdkfd: Disable MQD queue priority This solves a priority inversion issue, caused by the language runtime making high-priority queues wait for activity on lower-priority queues. Signed-off-by: Andrew Martin Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index 90ac3a30e81d..76483d91af98 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c @@ -70,7 +70,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct cik_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c index 97055f808d4a..0186b3de67c0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c @@ -70,7 +70,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v10_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c index 7e5a7ab6d0c0..c9e397366782 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c @@ -96,7 +96,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v11_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c index a51f217329db..3bbc2648f51d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c @@ -77,7 +77,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v12_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c index d0776ba2cc99..0d6b601962eb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c @@ -131,7 +131,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v12_1_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 5578c241b7d0..3622d8392cb3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -106,7 +106,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v9_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static bool mqd_on_vram(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c index 09483f0862d4..e63ef6442b35 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c @@ -73,7 +73,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct vi_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, From a1e0a6b55216820286b31443724b26ed58e96e0b Mon Sep 17 00:00:00 2001 From: Harish Kasiviswanathan Date: Fri, 30 Jan 2026 15:31:14 -0500 Subject: [PATCH 17/28] drm/amdgpu: Set vmid0 PAGE_TABLE_DEPTH for GFX12.1 GFX12.1 uses 2 level gart table. Set the context register appropriately Signed-off-by: Feifei Xu Signed-off-by: Harish Kasiviswanathan Reviewed-by: Mukul Joshi Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c index 7e917eb47a8c..a72770e3d0e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c @@ -395,7 +395,10 @@ static void mmhub_v4_2_0_mid_enable_system_domain(struct amdgpu_device *adev, tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1); tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, - PAGE_TABLE_DEPTH, 0); + PAGE_TABLE_DEPTH, adev->gmc.vmid0_page_table_depth); + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, + PAGE_TABLE_BLOCK_SIZE, + adev->gmc.vmid0_page_table_block_size); tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0); WREG32_SOC15(MMHUB, GET_INST(MMHUB, i), From f0157ce46cf0e5e2257e19d590c9b16036ce26d4 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 6 Feb 2026 23:38:28 +0100 Subject: [PATCH 18/28] drm/amd/display: Use same max plane scaling limits for all 64 bpp formats The plane scaling hw seems to have the same min/max plane scaling limits for all 16 bpc / 64 bpp interleaved pixel color formats. Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for all the 16 bpc fixed-point / unorm formats to use the same .fp16 up/downscaling factor limits as used by the fp16 floating point formats. So far, 16 bpc unorm formats were not handled, and the default: path returned max/min factors for 32 bpp argb8888 formats, which were wrong and bigger than what many DCE / DCN hw generations could handle. The result sometimes was misscaling of framebuffers with DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616, DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested on Polaris11 / DCE-11.2. So far this went unnoticed, because only few userspace clients used such 16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they did not experience this issue. With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland compositor allowing for direct scanout of these formats, the scaling hw will be used on these formats if possible for HiDPI display scaling, so it is important to use the correct hw scaling limits to avoid wrong display. Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50 on HiDPI displays with scaling enabled. The mutter Wayland compositor now correctly falls back to scaling via desktop compositing instead of direct scanout, thereby avoiding wrong image display. For unscaled mode, it correctly uses direct scanout. Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.") Signed-off-by: Mario Kleiner Tested-by: Mario Kleiner Cc: Alex Deucher Cc: Harry Wentland Cc: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index ce56734c09b8..198064acf9f6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -1060,10 +1060,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev, *min_downscale = plane_cap->max_downscale_factor.nv12; break; + /* All 64 bpp formats have the same fp16 scaling limits */ case DRM_FORMAT_XRGB16161616F: case DRM_FORMAT_ARGB16161616F: case DRM_FORMAT_XBGR16161616F: case DRM_FORMAT_ABGR16161616F: + case DRM_FORMAT_XRGB16161616: + case DRM_FORMAT_ARGB16161616: + case DRM_FORMAT_XBGR16161616: + case DRM_FORMAT_ABGR16161616: *max_upscale = plane_cap->max_upscale_factor.fp16; *min_downscale = plane_cap->max_downscale_factor.fp16; break; From 09da66f139b43c217e22435d6e50b0d9960f5183 Mon Sep 17 00:00:00 2001 From: Andrew Martin Date: Fri, 12 Dec 2025 15:59:17 +0800 Subject: [PATCH 19/28] drm/amdkfd: Check for NULL return values This patch fixes issues when the code moves forward with a potential NULL pointer, without checking. Removed one redundant NULL check for a function parameter. This check is already done in the only caller. Signed-off-by: Andrew Martin Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 15 ++++++++++++--- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 3 --- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c index 193ed8becab8..31b8fa52b42f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c @@ -107,7 +107,7 @@ static const char *amdkfd_fence_get_timeline_name(struct dma_fence *f) { struct amdgpu_amdkfd_fence *fence = to_amdgpu_amdkfd_fence(f); - return fence->timeline_name; + return fence ? fence->timeline_name : NULL; } /** diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 36ffc3c78536..a1087c13f241 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -2359,7 +2359,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, if (kdev->kfd->hive_id) { for (nid = 0; nid < proximity_domain; ++nid) { peer_dev = kfd_topology_device_by_proximity_domain_no_lock(nid); - if (!peer_dev->gpu) + if (!peer_dev || !peer_dev->gpu) continue; if (peer_dev->gpu->kfd->hive_id != kdev->kfd->hive_id) continue; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index bedb95ce9659..0f7aa51b629e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -523,10 +523,15 @@ int kfd_dbg_trap_set_flags(struct kfd_process *target, uint32_t *flags) int i, r = 0, rewind_count = 0; for (i = 0; i < target->n_pdds; i++) { + uint32_t caps; + uint32_t caps2; struct kfd_topology_device *topo_dev = - kfd_topology_device_by_id(target->pdds[i]->dev->id); - uint32_t caps = topo_dev->node_props.capability; - uint32_t caps2 = topo_dev->node_props.capability2; + kfd_topology_device_by_id(target->pdds[i]->dev->id); + if (!topo_dev) + return -EINVAL; + + caps = topo_dev->node_props.capability; + caps2 = topo_dev->node_props.capability2; if (!(caps & HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED) && (*flags & KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP)) { @@ -1086,6 +1091,10 @@ int kfd_dbg_trap_device_snapshot(struct kfd_process *target, for (i = 0; i < tmp_num_devices; i++) { struct kfd_process_device *pdd = target->pdds[i]; struct kfd_topology_device *topo_dev = kfd_topology_device_by_id(pdd->dev->id); + if (!topo_dev) { + r = -EINVAL; + break; + } device_info.gpu_id = pdd->dev->id; device_info.exception_status = pdd->exception_status; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ba25d83c23e7..6d32941ce8c7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -1773,9 +1773,6 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, struct kfd_node *dev; int ret; - if (!drm_file) - return -EINVAL; - if (pdd->drm_priv) return -EBUSY; From 23c098b5fc89c17cec6b25ebe071f47a54b7d613 Mon Sep 17 00:00:00 2001 From: Harish Kasiviswanathan Date: Thu, 12 Feb 2026 12:13:26 -0500 Subject: [PATCH 20/28] drm/amdgpu: Set atomics to true for xgmi xgmi support atomics between links. Set them to true. This only set for GFX12 onwards to avoid regression on older generations v2: Use correct xgmi flag that indicates CPU connection Signed-off-by: Harish Kasiviswanathan Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0a0109be4d06..c3cb9570f0ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4615,9 +4615,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* APUs w/ gfx9 onwards doesn't reply on PCIe atomics, rather it is a * internal path natively support atomics, set have_atomics_support to true. */ - } else if ((adev->flags & AMD_IS_APU) && - (amdgpu_ip_version(adev, GC_HWIP, 0) > - IP_VERSION(9, 0, 0))) { + } else if ((adev->flags & AMD_IS_APU && + amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(9, 0, 0)) || + (adev->gmc.xgmi.connected_to_cpu && + amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 1, 0))) { adev->have_atomics_support = true; } else { adev->have_atomics_support = From 096bb75e13cc508d3915b7604e356bcb12b17766 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 16 Feb 2026 10:02:32 -0500 Subject: [PATCH 21/28] drm/amdgpu: keep vga memory on MacBooks with switchable graphics On Intel MacBookPros with switchable graphics, when the iGPU is enabled, the address of VRAM gets put at 0 in the dGPU's virtual address space. This is non-standard and seems to cause issues with the cursor if it ends up at 0. We have the framework to reserve memory at 0 in the address space, so enable it here if the vram start address is 0. Reviewed-and-tested-by: Mario Kleiner Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4302 Cc: stable@vger.kernel.org Cc: Mario Kleiner Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index d35d9719d566..6a6b334428f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -1068,6 +1068,16 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev) case CHIP_RENOIR: adev->mman.keep_stolen_vga_memory = true; break; + case CHIP_POLARIS10: + case CHIP_POLARIS11: + case CHIP_POLARIS12: + /* MacBookPros with switchable graphics put VRAM at 0 when + * the iGPU is enabled which results in cursor issues if + * the cursor ends up at 0. Reserve vram at 0 in that case. + */ + if (adev->gmc.vram_start == 0) + adev->mman.keep_stolen_vga_memory = true; + break; default: adev->mman.keep_stolen_vga_memory = false; break; From aa25c111a782e711d9eaad0adc3d5e086d175a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 11 Feb 2026 13:28:55 +0100 Subject: [PATCH 22/28] drm/amdgpu: fix 4-level paging if GMC supports 57-bit VA v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turned that using 4 level page tables on GMC generations which support 57bit VAs actually doesn't work at all. Background is that the GMC actually can't switch between 4 and 5 levels, but rather just uses a subset of address space when less than 5 levels are selected. Philip already removed the automatically switch to 4levels, now fix it as well should it be enabled by module parameters. v2: fix AMDGPU_GMC_HOLE_MASK as well, fix off by one issue pointed out by Philip Signed-off-by: Christian König Acked-by: Alex Deucher Reviewed-by: Philip Yang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 8 ++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index e8e8bfa098c3..0e8a52d96573 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -33,9 +33,9 @@ #include "amdgpu_ras.h" /* VA hole for 48bit and 57bit addresses */ -#define AMDGPU_GMC_HOLE_START (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\ +#define AMDGPU_GMC_HOLE_START (adev->vm_manager.max_level == 4 ?\ 0x0100000000000000ULL : 0x0000800000000000ULL) -#define AMDGPU_GMC_HOLE_END (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\ +#define AMDGPU_GMC_HOLE_END (adev->vm_manager.max_level == 4 ?\ 0xff00000000000000ULL : 0xffff800000000000ULL) /* @@ -45,8 +45,8 @@ * This mask is used to remove the upper 16bits of the VA and so come up with * the linear addr value. */ -#define AMDGPU_GMC_HOLE_MASK (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\ - 0x00ffffffffffffffULL : 0x0000ffffffffffffULL) +#define AMDGPU_GMC_HOLE_MASK (adev->vm_manager.max_level == 4 ?\ + 0x01ffffffffffffffULL : 0x0000ffffffffffffULL) /* * Ring size as power of two for the log of recent faults. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 11597224d437..8f1a998cb7ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2400,6 +2400,7 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, } adev->vm_manager.max_pfn = (uint64_t)vm_size << 18; + adev->vm_manager.max_level = max_level; tmp = roundup_pow_of_two(adev->vm_manager.max_pfn); if (amdgpu_vm_block_size != -1) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 139642eacdd0..806d62ed61ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -456,6 +456,7 @@ struct amdgpu_vm_manager { bool concurrent_flush; uint64_t max_pfn; + uint32_t max_level; uint32_t num_level; uint32_t block_size; uint32_t fragment_size; From 613b1737abe1bd0a65b49851e777231302095e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 2 Feb 2026 12:25:03 +0100 Subject: [PATCH 23/28] drm/amd/display: Don't call find_analog_engine() twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The analog engine is already there in the link_analog_engine variable and assigned to enc_init_data.analog_engine already. I suspect this was a rebase mistake. Fixes: 436d0d22aa70 ("drm/amd/display: Pass proper DAC encoder ID to VBIOS") Signed-off-by: Timur Kristóf Tested-by: Mauro Rossi Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 6f4c3c73e113..49db8123f08c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -561,7 +561,6 @@ static bool construct_phy(struct dc_link *link, enc_init_data.connector = link->link_id; enc_init_data.channel = get_ddc_line(link); enc_init_data.transmitter = transmitter_from_encoder; - enc_init_data.analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder); enc_init_data.encoder = link_encoder; enc_init_data.analog_engine = link_analog_engine; if (link->ctx->dce_version <= DCN_VERSION_4_01) From e021ee995056ee7e58114edd92bcd4578d8b4bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 2 Feb 2026 12:25:04 +0100 Subject: [PATCH 24/28] drm/amd/display: Turn off DAC in DCE link encoder using VBIOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently, the VBIOS DAC1EncoderControl function is much more graceful about turning off the DAC. It writes various DAC registers in a specific sequence. Use that instead of just clearing the DAC_ENABLE register. Do this in just the dce110_link_encoder_disable_output function and remove it from the HWSS. Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") Signed-off-by: Timur Kristóf Tested-by: Mauro Rossi Suggested-by: Alex Deucher Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dce/dce_link_encoder.c | 30 +++++++++++-------- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 3 -- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 7f0766b5fa3d..f8fcf8d1a4dd 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -133,6 +133,21 @@ static enum bp_result link_transmitter_control( return result; } +static enum bp_result link_dac_encoder_control( + struct dce110_link_encoder *link_enc, + enum bp_encoder_control_action action, + uint32_t pix_clk_100hz) +{ + struct dc_bios *bios = link_enc->base.ctx->dc_bios; + struct bp_encoder_control encoder_control = {0}; + + encoder_control.action = action; + encoder_control.engine_id = link_enc->base.analog_engine; + encoder_control.pixel_clock = pix_clk_100hz / 10; + + return bios->funcs->encoder_control(bios, &encoder_control); +} + static void enable_phy_bypass_mode( struct dce110_link_encoder *enc110, bool enable) @@ -1345,19 +1360,8 @@ void dce110_link_encoder_disable_output( struct bp_transmitter_control cntl = { 0 }; enum bp_result result; - switch (enc->analog_engine) { - case ENGINE_ID_DACA: - REG_UPDATE(DAC_ENABLE, DAC_ENABLE, 0); - break; - case ENGINE_ID_DACB: - /* DACB doesn't seem to be present on DCE6+, - * although there are references to it in the register file. - */ - DC_LOG_ERROR("%s DACB is unsupported\n", __func__); - break; - default: - break; - } + if (enc->analog_engine != ENGINE_ID_UNKNOWN) + link_dac_encoder_control(enc110, ENCODER_CONTROL_DISABLE, 0); /* The code below only applies to connectors that support digital signals. */ if (enc->transmitter == TRANSMITTER_UNKNOWN) 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 4277b6761522..95cd8c7f6c5b 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 @@ -1199,9 +1199,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A); } - - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) - dce110_dac_encoder_control(pipe_ctx, false); } void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, From e2a024345bce78a8e1ed7d9e84c859b05979e41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 2 Feb 2026 12:25:05 +0100 Subject: [PATCH 25/28] drm/amd/display: Initialize DAC in DCE link encoder using VBIOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VBIOS DAC1EncoderControl() function can initialize the DAC, by writing board-specific values to certain registers. Call this at link encoder hardware initialization time similarly to how the equivalent UNIPHYTransmitterControl initialization is done. This fixes DAC output on the Radeon HD 7790. Also remove the ENCODER_CONTROL_SETUP enum from the dac_encoder_control_prepare_params function which is actually not a supported operation for DAC encoders. Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") Signed-off-by: Timur Kristóf Tested-by: Mauro Rossi Suggested-by: Alex Deucher Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/bios/command_table.c | 3 +-- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c index 76a3559f0ddc..b692fa37402d 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -1874,8 +1874,7 @@ static void dac_encoder_control_prepare_params( uint8_t dac_standard) { params->ucDacStandard = dac_standard; - if (action == ENCODER_CONTROL_SETUP || - action == ENCODER_CONTROL_INIT) + if (action == ENCODER_CONTROL_INIT) params->ucAction = ATOM_ENCODER_INIT; else if (action == ENCODER_CONTROL_ENABLE) params->ucAction = ATOM_ENABLE; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index f8fcf8d1a4dd..8903bdb89c66 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -1036,6 +1036,16 @@ void dce110_link_encoder_hw_init( cntl.coherent = false; cntl.hpd_sel = enc110->base.hpd_source; + if (enc110->base.analog_engine != ENGINE_ID_UNKNOWN) { + result = link_dac_encoder_control(enc110, ENCODER_CONTROL_INIT, 0); + if (result != BP_RESULT_OK) { + DC_LOG_ERROR("%s: Failed to execute VBIOS command table for DAC!\n", + __func__); + BREAK_TO_DEBUGGER(); + return; + } + } + /* The code below is only applicable to encoders with a digital transmitter. */ if (enc110->base.transmitter == TRANSMITTER_UNKNOWN) return; From cbced93894d145239c83881d7fd953b7392c23a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 2 Feb 2026 12:25:06 +0100 Subject: [PATCH 26/28] drm/amd/display: Set CRTC source for DAC using registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently the VBIOS SelectCRTC_Source function overwrites a few registers (such as FMT_*) which DC writes in a different place, which can cause problems. Instead of using the SelectCRTC_Source function from the VBIOS, use the DAC_SOURCE_SELECT register directly, similarly to how it is done for digital link encoders. Fixes: 3be26d81b150 ("drm/amd/display: Support DAC in dce110_hwseq") Signed-off-by: Timur Kristóf Tested-by: Mauro Rossi Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- .../amd/display/dc/dce/dce_stream_encoder.c | 23 +++++++++++++--- .../amd/display/dc/dce/dce_stream_encoder.h | 12 +++++++-- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 26 +------------------ .../dc/resource/dce100/dce100_resource.c | 6 +++-- .../dc/resource/dce60/dce60_resource.c | 7 +++-- .../dc/resource/dce80/dce80_resource.c | 6 +++-- 6 files changed, 43 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 574618d5d4a4..87c19f17c799 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -1498,7 +1498,10 @@ static void dig_connect_to_otg( { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); + if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB) + REG_UPDATE(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, tg_inst); + else + REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); } static unsigned int dig_source_otg( @@ -1507,7 +1510,10 @@ static unsigned int dig_source_otg( uint32_t tg_inst = 0; struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); + if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB) + REG_GET(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, &tg_inst); + else + REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); return tg_inst; } @@ -1568,16 +1574,25 @@ void dce110_stream_encoder_construct( enc110->se_mask = se_mask; } -static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {}; +static const struct stream_encoder_funcs dce110_an_str_enc_funcs = { + .dig_connect_to_otg = dig_connect_to_otg, + .dig_source_otg = dig_source_otg, +}; void dce110_analog_stream_encoder_construct( struct dce110_stream_encoder *enc110, struct dc_context *ctx, struct dc_bios *bp, - enum engine_id eng_id) + enum engine_id eng_id, + const struct dce110_stream_enc_registers *regs, + const struct dce_stream_encoder_shift *se_shift, + const struct dce_stream_encoder_mask *se_mask) { enc110->base.funcs = &dce110_an_str_enc_funcs; enc110->base.ctx = ctx; enc110->base.id = eng_id; enc110->base.bp = bp; + enc110->regs = regs; + enc110->se_shift = se_shift; + enc110->se_mask = se_mask; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h index 068de1392121..342c0afe6a94 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h @@ -65,6 +65,7 @@ SRI(AFMT_60958_1, DIG, id), \ SRI(AFMT_60958_2, DIG, id), \ SRI(DIG_FE_CNTL, DIG, id), \ + SR(DAC_SOURCE_SELECT), \ SRI(HDMI_CONTROL, DIG, id), \ SRI(HDMI_GC, DIG, id), \ SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \ @@ -290,7 +291,8 @@ #define SE_COMMON_MASK_SH_LIST_DCE80_100(mask_sh)\ SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\ SE_SF(TMDS_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\ - SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh) + SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh),\ + SE_SF(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, mask_sh) #define SE_COMMON_MASK_SH_LIST_DCE110(mask_sh)\ SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\ @@ -494,6 +496,7 @@ struct dce_stream_encoder_shift { uint8_t DP_VID_N_MUL; uint8_t DP_VID_M_DOUBLE_VALUE_EN; uint8_t DIG_SOURCE_SELECT; + uint8_t DAC_SOURCE_SELECT; }; struct dce_stream_encoder_mask { @@ -626,6 +629,7 @@ struct dce_stream_encoder_mask { uint32_t DP_VID_N_MUL; uint32_t DP_VID_M_DOUBLE_VALUE_EN; uint32_t DIG_SOURCE_SELECT; + uint32_t DAC_SOURCE_SELECT; }; struct dce110_stream_enc_registers { @@ -653,6 +657,7 @@ struct dce110_stream_enc_registers { uint32_t AFMT_60958_1; uint32_t AFMT_60958_2; uint32_t DIG_FE_CNTL; + uint32_t DAC_SOURCE_SELECT; uint32_t DP_MSE_RATE_CNTL; uint32_t DP_MSE_RATE_UPDATE; uint32_t DP_PIXEL_FORMAT; @@ -712,7 +717,10 @@ void dce110_analog_stream_encoder_construct( struct dce110_stream_encoder *enc110, struct dc_context *ctx, struct dc_bios *bp, - enum engine_id eng_id); + enum engine_id eng_id, + const struct dce110_stream_enc_registers *regs, + const struct dce_stream_encoder_shift *se_shift, + const struct dce_stream_encoder_mask *se_mask); void dce110_se_audio_mute_control( struct stream_encoder *enc, bool mute); 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 95cd8c7f6c5b..b4a7e2fc7c2b 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 @@ -1581,25 +1581,6 @@ static enum dc_status dce110_enable_stream_timing( return DC_OK; } -static void -dce110_select_crtc_source(struct pipe_ctx *pipe_ctx) -{ - struct dc_link *link = pipe_ctx->stream->link; - struct dc_bios *bios = link->ctx->dc_bios; - struct bp_crtc_source_select crtc_source_select = {0}; - enum engine_id engine_id = link->link_enc->preferred_engine; - - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) - engine_id = link->link_enc->analog_engine; - - crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst; - crtc_source_select.color_depth = pipe_ctx->stream->timing.display_color_depth; - crtc_source_select.engine_id = engine_id; - crtc_source_select.sink_signal = pipe_ctx->stream->signal; - - bios->funcs->select_crtc_source(bios, &crtc_source_select); -} - enum dc_status dce110_apply_single_controller_ctx_to_hw( struct pipe_ctx *pipe_ctx, struct dc_state *context, @@ -1619,10 +1600,6 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw( hws->funcs.disable_stream_gating(dc, pipe_ctx); } - if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) { - dce110_select_crtc_source(pipe_ctx); - } - if (pipe_ctx->stream_res.audio != NULL) { struct audio_output audio_output = {0}; @@ -1702,8 +1679,7 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw( pipe_ctx->stream_res.tg->funcs->set_static_screen_control( pipe_ctx->stream_res.tg, event_triggers, 2); - if (!dc_is_virtual_signal(pipe_ctx->stream->signal) && - !dc_is_rgb_signal(pipe_ctx->stream->signal)) + if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( pipe_ctx->stream_res.stream_enc, pipe_ctx->stream_res.tg->inst); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c index f49d67fcafe0..dfb64905e1a4 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c @@ -242,7 +242,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { stream_enc_regs(3), stream_enc_regs(4), stream_enc_regs(5), - stream_enc_regs(6) + stream_enc_regs(6), + {SR(DAC_SOURCE_SELECT),} /* DACA */ }; static const struct dce_stream_encoder_shift se_shift = { @@ -491,7 +492,8 @@ static struct stream_encoder *dce100_stream_encoder_create( return NULL; if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { - dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); + dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, + &stream_enc_regs[eng_id], &se_shift, &se_mask); return &enc110->base; } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c index 90d826237cf0..6cf2faffc961 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c @@ -258,7 +258,9 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { stream_enc_regs(2), stream_enc_regs(3), stream_enc_regs(4), - stream_enc_regs(5) + stream_enc_regs(5), + {0}, + {SR(DAC_SOURCE_SELECT),} /* DACA */ }; static const struct dce_stream_encoder_shift se_shift = { @@ -607,7 +609,8 @@ static struct stream_encoder *dce60_stream_encoder_create( return NULL; if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { - dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); + dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, + &stream_enc_regs[eng_id], &se_shift, &se_mask); return &enc110->base; } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c index cde2c2cba1dd..066dbf8125a8 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c @@ -258,7 +258,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { stream_enc_regs(3), stream_enc_regs(4), stream_enc_regs(5), - stream_enc_regs(6) + stream_enc_regs(6), + {SR(DAC_SOURCE_SELECT),} /* DACA */ }; static const struct dce_stream_encoder_shift se_shift = { @@ -614,7 +615,8 @@ static struct stream_encoder *dce80_stream_encoder_create( return NULL; if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { - dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); + dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, + &stream_enc_regs[eng_id], &se_shift, &se_mask); return &enc110->base; } From 4bd8b5f8bcb57b430c35494d8a2471ce5fd7661d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 2 Feb 2026 12:25:07 +0100 Subject: [PATCH 27/28] drm/amd/display: Enable DAC in DCE link encoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that the DAC output is enabled at the correct time by moving it to the DCE link encoder similarly to how digital outputs are enabled. This also removes the call to DAC1EncoderControl from the DCE HWSS, which always felt like it was a hacky solution. Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") Signed-off-by: Timur Kristóf Tested-by: Mauro Rossi Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dce/dce_link_encoder.c | 18 +++++++++++++ .../drm/amd/display/dc/dce/dce_link_encoder.h | 5 ++++ .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 26 +++++++------------ .../drm/amd/display/dc/hwss/hw_sequencer.h | 2 ++ .../drm/amd/display/dc/inc/hw/link_encoder.h | 2 ++ .../gpu/drm/amd/display/dc/link/link_dpms.c | 14 +++++++++- 6 files changed, 50 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 8903bdb89c66..2ba3d3a3aac5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -102,6 +102,7 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { .enable_dp_output = dce110_link_encoder_enable_dp_output, .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output, .enable_lvds_output = dce110_link_encoder_enable_lvds_output, + .enable_analog_output = dce110_link_encoder_enable_analog_output, .disable_output = dce110_link_encoder_disable_output, .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern, @@ -1200,6 +1201,22 @@ void dce110_link_encoder_enable_lvds_output( } } +void dce110_link_encoder_enable_analog_output( + struct link_encoder *enc, + uint32_t pixel_clock) +{ + struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); + enum bp_result result; + + result = link_dac_encoder_control(enc110, ENCODER_CONTROL_ENABLE, pixel_clock); + + if (result != BP_RESULT_OK) { + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", + __func__); + BREAK_TO_DEBUGGER(); + } +} + /* enables DP PHY output */ void dce110_link_encoder_enable_dp_output( struct link_encoder *enc, @@ -1818,6 +1835,7 @@ static const struct link_encoder_funcs dce60_lnk_enc_funcs = { .enable_dp_output = dce60_link_encoder_enable_dp_output, .enable_dp_mst_output = dce60_link_encoder_enable_dp_mst_output, .enable_lvds_output = dce110_link_encoder_enable_lvds_output, + .enable_analog_output = dce110_link_encoder_enable_analog_output, .disable_output = dce110_link_encoder_disable_output, .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, .dp_set_phy_pattern = dce60_link_encoder_dp_set_phy_pattern, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 9ba533aa6f88..f853e3c3fc75 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -268,6 +268,11 @@ void dce110_link_encoder_enable_lvds_output( enum clock_source_id clock_source, uint32_t pixel_clock); +/* enables analog output from the DAC */ +void dce110_link_encoder_enable_analog_output( + struct link_encoder *enc, + uint32_t pixel_clock); + /* disable PHY output */ void dce110_link_encoder_disable_output( struct link_encoder *enc, 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 b4a7e2fc7c2b..699a756bbc40 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 @@ -660,20 +660,6 @@ void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) } } -static void -dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable) -{ - struct dc_link *link = pipe_ctx->stream->link; - struct dc_bios *bios = link->ctx->dc_bios; - struct bp_encoder_control encoder_control = {0}; - - encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE; - encoder_control.engine_id = link->link_enc->analog_engine; - encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10; - - bios->funcs->encoder_control(bios, &encoder_control); -} - void dce110_enable_stream(struct pipe_ctx *pipe_ctx) { enum dc_lane_count lane_count = @@ -704,8 +690,6 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) tg->funcs->set_early_control(tg, early_control); - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) - dce110_dac_encoder_control(pipe_ctx, true); } static enum bp_result link_transmitter_control( @@ -3277,6 +3261,15 @@ void dce110_enable_tmds_link_output(struct dc_link *link, link->phy_state.symclk_state = SYMCLK_ON_TX_ON; } +static void dce110_enable_analog_link_output( + struct dc_link *link, + uint32_t pix_clk_100hz) +{ + link->link_enc->funcs->enable_analog_output( + link->link_enc, + pix_clk_100hz); +} + void dce110_enable_dp_link_output( struct dc_link *link, const struct link_resource *link_res, @@ -3414,6 +3407,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .enable_lvds_link_output = dce110_enable_lvds_link_output, .enable_tmds_link_output = dce110_enable_tmds_link_output, .enable_dp_link_output = dce110_enable_dp_link_output, + .enable_analog_link_output = dce110_enable_analog_link_output, .disable_link_output = dce110_disable_link_output, }; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h index 51b0f0fd8fcd..4632a5761b16 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -1184,6 +1184,8 @@ struct hw_sequencer_funcs { const struct link_resource *link_res, enum clock_source_id clock_source, uint32_t pixel_clock); + void (*enable_analog_link_output)(struct dc_link *link, + uint32_t pixel_clock); void (*disable_link_output)(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index d795fc43dc9d..5abbf485d273 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -132,6 +132,8 @@ struct link_encoder_funcs { void (*enable_lvds_output)(struct link_encoder *enc, enum clock_source_id clock_source, uint32_t pixel_clock); + void (*enable_analog_output)(struct link_encoder *enc, + uint32_t pixel_clock); void (*disable_output)(struct link_encoder *link_enc, enum signal_type signal); void (*dp_set_lane_settings)(struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 91742bde4dc2..9b1d34c3438b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2155,6 +2155,18 @@ static enum dc_status enable_link_dp_mst( return enable_link_dp(state, pipe_ctx); } +static enum dc_status enable_link_analog( + struct dc_state *state, + struct pipe_ctx *pipe_ctx) +{ + struct dc_link *link = pipe_ctx->stream->link; + + link->dc->hwss.enable_analog_link_output( + link, pipe_ctx->stream->timing.pix_clk_100hz); + + return DC_OK; +} + static enum dc_status enable_link_virtual(struct pipe_ctx *pipe_ctx) { struct dc_link *link = pipe_ctx->stream->link; @@ -2210,7 +2222,7 @@ static enum dc_status enable_link( status = DC_OK; break; case SIGNAL_TYPE_RGB: - status = DC_OK; + status = enable_link_analog(state, pipe_ctx); break; case SIGNAL_TYPE_VIRTUAL: status = enable_link_virtual(pipe_ctx); From 3ce2ad267079fcdd2c087bbbfb4f91bec527a4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Mon, 2 Feb 2026 12:25:08 +0100 Subject: [PATCH 28/28] drm/amd/display: Remove unneeded DAC link encoder register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not needed anymore since we use the VBIOS function. Signed-off-by: Timur Kristóf Tested-by: Mauro Rossi Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h | 3 +-- .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index f853e3c3fc75..8841000361fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -101,8 +101,7 @@ SRI(DP_SEC_CNTL, DP, id), \ SRI(DP_VID_STREAM_CNTL, DP, id), \ SRI(DP_DPHY_FAST_TRAINING, DP, id), \ - SRI(DP_SEC_CNTL1, DP, id), \ - SR(DAC_ENABLE) + SRI(DP_SEC_CNTL1, DP, id) #endif #define LE_DCE80_REG_LIST(id)\ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c index dfb64905e1a4..05f7ff60f8f5 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c @@ -226,7 +226,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = { link_regs(4), link_regs(5), link_regs(6), - { .DAC_ENABLE = mmDAC_ENABLE }, + {0} }; #define stream_enc_regs(id)\ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c index 6cf2faffc961..8d810d5c8781 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c @@ -243,7 +243,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = { link_regs(4), link_regs(5), {0}, - { .DAC_ENABLE = mmDAC_ENABLE }, + {0} }; #define stream_enc_regs(id)\ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c index 066dbf8125a8..a68e799d5885 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c @@ -242,7 +242,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = { link_regs(4), link_regs(5), link_regs(6), - { .DAC_ENABLE = mmDAC_ENABLE }, + {0} }; #define stream_enc_regs(id)\