From ea06598e23f18005ff320e16f141e40a0c392d81 Mon Sep 17 00:00:00 2001 From: Asad Kamal Date: Fri, 6 Feb 2026 14:23:59 +0800 Subject: [PATCH 01/49] drm/amd/pm: Add acc counter & fw timestamp to xcp metrics Add accumulation counter and firmware timestamp to partition metrics for smu_v13_0_6 & smu_v13_0_12 v2: Use U64 for accumulation counter (Lijo) Signed-off-by: Asad Kamal Reviewed-by: Lijo Lazar Reviewed-by: Yang Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c | 3 +++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 2 ++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h | 6 +++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c index 3d60d3c1e585..f2a6ecb64c03 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c @@ -823,6 +823,9 @@ ssize_t smu_v13_0_12_get_xcp_metrics(struct smu_context *smu, struct amdgpu_xcp idx++; } + xcp_metrics->accumulation_counter = metrics->AccumulationCounter; + xcp_metrics->firmware_timestamp = metrics->Timestamp; + return sizeof(*xcp_metrics); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 3a9210083ce3..07592e285cf5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -2668,6 +2668,8 @@ static ssize_t smu_v13_0_6_get_xcp_metrics(struct smu_context *smu, int xcp_id, idx++; } } + xcp_metrics->accumulation_counter = GET_METRIC_FIELD(AccumulationCounter, version); + xcp_metrics->firmware_timestamp = GET_METRIC_FIELD(Timestamp, version); return sizeof(*xcp_metrics); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h index 0588a5aa952d..07d4cb6562b0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h @@ -259,7 +259,11 @@ void smu_v13_0_12_get_gpu_metrics(struct smu_context *smu, void **table, SMU_13_0_6_MAX_XCC); \ SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_TOTAL_ACC), SMU_MUNIT(NONE), \ SMU_MTYPE(U64), gfx_below_host_limit_total_acc, \ - SMU_13_0_6_MAX_XCC); + SMU_13_0_6_MAX_XCC); \ + SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ + SMU_MTYPE(U64), accumulation_counter); \ + SMU_SCALAR(SMU_MATTR(FIRMWARE_TIMESTAMP), SMU_MUNIT(TIME_2), \ + SMU_MTYPE(U64), firmware_timestamp); DECLARE_SMU_METRICS_CLASS(smu_v13_0_6_partition_metrics, SMU_13_0_6_PARTITION_METRICS_FIELDS); From 34b11d0a7530ac374f889f4559f5dd85be86670e Mon Sep 17 00:00:00 2001 From: Asad Kamal Date: Fri, 6 Feb 2026 16:32:31 +0800 Subject: [PATCH 02/49] drm/amd/pm: Use U64 for accumulation counter Use U64 for accumulation counter in gpu metrics for smu_v13_0_6 and smu_v13_0_12 Signed-off-by: Asad Kamal Reviewed-by: Lijo Lazar Reviewed-by: Yang Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h index 07d4cb6562b0..ffb06564f830 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h @@ -140,7 +140,7 @@ extern const struct ras_smu_drv smu_v13_0_12_ras_smu_drv; SMU_SCALAR(SMU_MATTR(SYSTEM_CLOCK_COUNTER), SMU_MUNIT(TIME_1), \ SMU_MTYPE(U64), system_clock_counter); \ SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ - SMU_MTYPE(U32), accumulation_counter); \ + SMU_MTYPE(U64), accumulation_counter); \ SMU_SCALAR(SMU_MATTR(PROCHOT_RESIDENCY_ACC), SMU_MUNIT(NONE), \ SMU_MTYPE(U32), prochot_residency_acc); \ SMU_SCALAR(SMU_MATTR(PPT_RESIDENCY_ACC), SMU_MUNIT(NONE), \ From 64c94cd9be2e188ed07efeafa6a109bce638c967 Mon Sep 17 00:00:00 2001 From: Tom Chung Date: Tue, 20 Jan 2026 18:10:31 +0800 Subject: [PATCH 03/49] drm/amd/display: Fix system resume lag issue [Why] System will try to apply idle power optimizations setting during system resume. But system power state is still in D3 state, and it will cause the idle power optimizations command not actually to be sent to DMUB and cause some platforms to go into IPS. [How] Set power state to D0 first before calling the dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false) Reviewed-by: Nicholas Kazlauskas Signed-off-by: Tom Chung Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++++ 1 file changed, 10 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 631b44fd6dae..d870ce267b37 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3479,7 +3479,17 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) struct dc_commit_streams_params commit_params = {}; if (dm->dc->caps.ips_support) { + if (!amdgpu_in_reset(adev)) + mutex_lock(&dm->dc_lock); + + /* Need to set POWER_STATE_D0 first or it will not execute + * idle_power_optimizations command to DMUB. + */ + dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0); dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false); + + if (!amdgpu_in_reset(adev)) + mutex_unlock(&dm->dc_lock); } if (amdgpu_in_reset(adev)) { From 1a38ded4bc8ac09fd029ec656b1e2c98cc0d238c Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 23 Jan 2026 14:47:01 +0800 Subject: [PATCH 04/49] drm/amd/display: Avoid updating surface with the same surface under MPO [Why & How] Although it's dummy updates of surface update for committing stream updates, we should not have dummy_updates[j].surface all indicating to the same surface under multiple surfaces case. Otherwise, copy_surface_update_to_plane() in update_planes_and_stream_state() will update to the same surface only. Reviewed-by: Harry Wentland Signed-off-by: Wayne Lin Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d870ce267b37..9fcb4677d0f0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10974,7 +10974,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) continue; } for (j = 0; j < status->plane_count; j++) - dummy_updates[j].surface = status->plane_states[0]; + dummy_updates[j].surface = status->plane_states[j]; sort(dummy_updates, status->plane_count, sizeof(*dummy_updates), dm_plane_layer_index_cmp, NULL); From d2ca311a832098423261d19f8b9d8e2fc745073f Mon Sep 17 00:00:00 2001 From: Leon Huang Date: Tue, 20 Jan 2026 16:04:09 +0800 Subject: [PATCH 05/49] drm/amd/display: Check frame skip capability in Sink side [Why&How] Frame skip capability is described in AMD VSDB in EDID. Need to retrieve the cap and determine fr.skipping mode enablement Reviewed-by: ChunTao Tso Signed-off-by: Leon Huang Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../display/dc/link/protocols/link_dp_panel_replay.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c index cc3b44cf7662..4a9e86d32dbb 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c @@ -34,6 +34,7 @@ link->ctx->logger #define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B +#define DP_SINK_ENABLE_FRAME_SKIPPING_MODE_SHIFT (5) static unsigned int dp_pr_calc_num_static_frames(unsigned int vsync_rate_hz) { @@ -89,6 +90,7 @@ static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_s union panel_replay_enable_and_configuration_2 pr_config_2 = { 0 }; union dpcd_alpm_configuration alpm_config; + uint8_t data = 0; replay_context.controllerId = CONTROLLER_ID_UNDEFINED; @@ -186,6 +188,14 @@ static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_s DP_RECEIVER_ALPM_CONFIG, &alpm_config.raw, sizeof(alpm_config.raw)); + + //Enable frame skipping + if (link->replay_settings.config.frame_skip_supported) + data = data | (1 << DP_SINK_ENABLE_FRAME_SKIPPING_MODE_SHIFT); + + dm_helpers_dp_write_dpcd(link->ctx, link, + DP_SINK_PR_ENABLE_AND_CONFIGURATION, + (uint8_t *)&(data), sizeof(uint8_t)); } return true; From d0728aee5090853d0b9982757f5fb1b13e2e2b27 Mon Sep 17 00:00:00 2001 From: YiLing Chen Date: Tue, 27 Jan 2026 13:32:40 +0800 Subject: [PATCH 06/49] drm/amd/display: set enable_legacy_fast_update to false for DCN36 [Why/How] Align the default value of the flag with DCN35/351. Reviewed-by: Nicholas Kazlauskas Signed-off-by: YiLing Chen Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c index 0ee16926db4e..1d8ca312fe1e 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c @@ -775,7 +775,7 @@ static const struct dc_debug_options debug_defaults_drv = { }; static const struct dc_check_config config_defaults = { - .enable_legacy_fast_update = true, + .enable_legacy_fast_update = false, }; static const struct dc_panel_config panel_config_defaults = { From 9156bf442ee56c0f883aa4c81af9c8471eef6846 Mon Sep 17 00:00:00 2001 From: Bhuvanachandra Pinninti Date: Wed, 21 Jan 2026 16:05:00 +0530 Subject: [PATCH 07/49] drm/amd/display: Refactor virtual directory reorganize encoder and hwss files. [why] Virtual encoders & hwss were grouped in a separate directory, not aligned with dio and link component structure. [how] Moved virtual_link_encoder and virtual_stream_encoder to dc/dio/virtual/. Moved virtual_link_hwss to dc/link/hwss/ and renamed to link_hwss_virtual. Removed dc/virtual/ directory. Updated all includes and build files (Makefiles) Reviewed-by: Nicholas Kazlauskas Signed-off-by: Bhuvanachandra Pinninti Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 4 +-- drivers/gpu/drm/amd/display/dc/dio/Makefile | 9 ++++++ .../{ => dio}/virtual/virtual_link_encoder.c | 2 -- .../{ => dio}/virtual/virtual_link_encoder.h | 0 .../virtual/virtual_stream_encoder.c | 1 - .../virtual/virtual_stream_encoder.h | 0 drivers/gpu/drm/amd/display/dc/link/Makefile | 3 +- .../hwss/link_hwss_virtual.c} | 2 +- .../hwss/link_hwss_virtual.h} | 6 ++-- .../dc/resource/dce100/dce100_resource.c | 2 +- .../dc/resource/dce120/dce120_resource.c | 2 +- .../dc/resource/dcn10/dcn10_resource.c | 2 +- .../dc/resource/dcn20/dcn20_resource.c | 2 +- .../dc/resource/dcn201/dcn201_resource.c | 2 +- .../dc/resource/dcn21/dcn21_resource.c | 2 +- .../dc/resource/dcn30/dcn30_resource.c | 2 +- .../dc/resource/dcn301/dcn301_resource.c | 2 +- .../dc/resource/dcn31/dcn31_resource.c | 2 +- .../dc/resource/dcn314/dcn314_resource.c | 2 +- .../dc/resource/dcn315/dcn315_resource.c | 2 +- .../dc/resource/dcn316/dcn316_resource.c | 2 +- .../dc/resource/dcn32/dcn32_resource.c | 2 +- .../dc/resource/dcn321/dcn321_resource.c | 2 +- .../dc/resource/dcn35/dcn35_resource.c | 2 +- .../dc/resource/dcn351/dcn351_resource.c | 2 +- .../dc/resource/dcn36/dcn36_resource.c | 2 +- .../dc/resource/dcn401/dcn401_resource.c | 2 +- .../gpu/drm/amd/display/dc/virtual/Makefile | 30 ------------------- 30 files changed, 37 insertions(+), 60 deletions(-) rename drivers/gpu/drm/amd/display/dc/{ => dio}/virtual/virtual_link_encoder.c (99%) rename drivers/gpu/drm/amd/display/dc/{ => dio}/virtual/virtual_link_encoder.h (100%) rename drivers/gpu/drm/amd/display/dc/{ => dio}/virtual/virtual_stream_encoder.c (99%) rename drivers/gpu/drm/amd/display/dc/{ => dio}/virtual/virtual_stream_encoder.h (100%) rename drivers/gpu/drm/amd/display/dc/{virtual/virtual_link_hwss.c => link/hwss/link_hwss_virtual.c} (98%) rename drivers/gpu/drm/amd/display/dc/{virtual/virtual_link_hwss.h => link/hwss/link_hwss_virtual.h} (92%) delete mode 100644 drivers/gpu/drm/amd/display/dc/virtual/Makefile diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index 7277ed21552f..93d02956c5eb 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -22,7 +22,7 @@ # # Makefile for Display Core (dc) component. -DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link virtual dsc resource optc dpp hubbub dccg hubp dio dwb hpo mmhubbub mpc opp pg +DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link dsc resource optc dpp hubbub dccg hubp dio dwb hpo mmhubbub mpc opp pg ifdef CONFIG_DRM_AMD_DC_FP diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index e7d2b861dedd..17ba7af0ddcd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -53,7 +53,7 @@ #include "dpp.h" #include "timing_generator.h" #include "abm.h" -#include "virtual/virtual_link_encoder.h" +#include "dio/virtual/virtual_link_encoder.h" #include "hubp.h" #include "link_hwss.h" 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 b4e5a79e9749..639831295b21 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -37,7 +37,7 @@ #include "dpp.h" #include "core_types.h" #include "set_mode_types.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dpcd_defs.h" #include "link_enc_cfg.h" #include "link_service.h" @@ -45,7 +45,7 @@ #include "dc_state_priv.h" #include "dc_stream_priv.h" -#include "virtual/virtual_link_hwss.h" +#include "link/hwss/link_hwss_virtual.h" #include "link/hwss/link_hwss_dio.h" #include "link/hwss/link_hwss_dpia.h" #include "link/hwss/link_hwss_hpo_dp.h" diff --git a/drivers/gpu/drm/amd/display/dc/dio/Makefile b/drivers/gpu/drm/amd/display/dc/dio/Makefile index 02eec03dc204..2f5619078e1f 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dio/Makefile @@ -23,6 +23,15 @@ # # +############################################################################### +# VIRTUAL +############################################################################### +DIO_VIRTUAL = virtual_link_encoder.o virtual_stream_encoder.o + +AMD_DAL_DIO_VIRTUAL = $(addprefix $(AMDDALPATH)/dc/dio/virtual/,$(DIO_VIRTUAL)) + +AMD_DISPLAY_FILES += $(AMD_DAL_DIO_VIRTUAL) + ifdef CONFIG_DRM_AMD_DC_FP ############################################################################### # DCN10 diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.c similarity index 99% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.c index 1d226e0519a5..2655bc194a35 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.c @@ -128,5 +128,3 @@ bool virtual_link_encoder_construct( return true; } - - diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.h similarity index 100% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.h rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.h diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.c similarity index 99% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.c index ad088d70e189..c5d2e9404d94 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.c @@ -171,4 +171,3 @@ struct stream_encoder *virtual_stream_encoder_create( kfree(enc); return NULL; } - diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.h similarity index 100% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.h rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.h diff --git a/drivers/gpu/drm/amd/display/dc/link/Makefile b/drivers/gpu/drm/amd/display/dc/link/Makefile index 84dace27daf7..0f3670e30232 100644 --- a/drivers/gpu/drm/amd/display/dc/link/Makefile +++ b/drivers/gpu/drm/amd/display/dc/link/Makefile @@ -43,7 +43,8 @@ AMD_DISPLAY_FILES += $(AMD_DAL_LINK_ACCESSORIES) # hwss ############################################################################### LINK_HWSS = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o \ -link_hwss_dio_fixed_vs_pe_retimer.o link_hwss_hpo_fixed_vs_pe_retimer_dp.o +link_hwss_dio_fixed_vs_pe_retimer.o link_hwss_hpo_fixed_vs_pe_retimer_dp.o \ +link_hwss_virtual.o AMD_DAL_LINK_HWSS = $(addprefix $(AMDDALPATH)/dc/link/hwss/, \ $(LINK_HWSS)) diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.c similarity index 98% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c rename to drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.c index 4f7f99156897..64742c24f7e6 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.c @@ -23,7 +23,7 @@ * */ -#include "virtual_link_hwss.h" +#include "link_hwss_virtual.h" void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx) { diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.h similarity index 92% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h rename to drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.h index fbcbc5afb47d..f6e448c89751 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.h @@ -22,8 +22,8 @@ * Authors: AMD * */ -#ifndef __DC_VIRTUAL_LINK_HWSS_H__ -#define __DC_VIRTUAL_LINK_HWSS_H__ +#ifndef __DC_LINK_HWSS_VIRTUAL_H__ +#define __DC_LINK_HWSS_VIRTUAL_H__ #include "core_types.h" @@ -32,4 +32,4 @@ void virtual_setup_stream_attribute(struct pipe_ctx *pipe_ctx); void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx); const struct link_hwss *get_virtual_link_hwss(void); -#endif /* __DC_VIRTUAL_LINK_HWSS_H__ */ +#endif /* __DC_LINK_HWSS_VIRTUAL_H__ */ 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 d40d91ec2035..a929e64524e5 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 @@ -31,7 +31,7 @@ #include "resource.h" #include "clk_mgr.h" #include "include/irq_service_interface.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce110/dce110_timing_generator.h" #include "irq/dce110/irq_service_dce110.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c index b1570b6b1af3..92890784caa6 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c @@ -35,7 +35,7 @@ #include "dce112/dce112_resource.h" #include "dce110/dce110_resource.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce120/dce120_timing_generator.h" #include "irq/dce120/irq_service_dce120.h" #include "dce/dce_opp.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c index f12367adf145..476780a5450f 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c @@ -48,7 +48,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce112/dce112_resource.h" #include "dcn10/dcn10_hubp.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c index 46985eb2a623..6731544f0981 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c @@ -55,7 +55,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn20/dcn20_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c index 055107843a70..90d38631f63a 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c @@ -51,7 +51,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce/dce_aux.h" #include "dce/dce_i2c.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c index 967e813a45e5..107612595db6 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c @@ -57,7 +57,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn20/dcn20_dccg.h" #include "dcn21/dcn21_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c index d0ebb733e802..6cfdc37dab58 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c @@ -55,7 +55,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn30/dcn30_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c index 3ad6a3d4858e..e1d0c166b484 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c @@ -54,7 +54,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn301/dcn301_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c index e853ea110310..8ad72557b16a 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c @@ -64,7 +64,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c index 3ccde75a4ecb..5f0fe6e5bd82 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c @@ -66,7 +66,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c index 4e962f522f1b..a8283f21008e 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c @@ -63,7 +63,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c index 5a95dd54cb42..4da0e9320159 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c @@ -63,7 +63,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c index b276fec3e479..d3b92c61b7ad 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c @@ -65,7 +65,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn32/dcn32_dccg.h" #include "dcn10/dcn10_resource.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c index 3466ca34c93f..d08691ea27ea 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c @@ -68,7 +68,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn32/dcn32_dccg.h" #include "dcn10/dcn10_resource.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 45454a097264..945da8cffada 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -70,7 +70,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn35/dcn35_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index e3c587165807..e660889904a9 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -49,7 +49,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn35/dcn35_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c index 1d8ca312fe1e..7582217bd06d 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c @@ -49,7 +49,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn35/dcn35_dccg.h" diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c index 4875faffe873..f5e02a1ff771 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c @@ -47,7 +47,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn401/dcn401_dccg.h" #include "dcn10/dcn10_resource.h" diff --git a/drivers/gpu/drm/amd/display/dc/virtual/Makefile b/drivers/gpu/drm/amd/display/dc/virtual/Makefile deleted file mode 100644 index 931facd4dab5..000000000000 --- a/drivers/gpu/drm/amd/display/dc/virtual/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright 2017 Advanced Micro Devices, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -# -# Makefile for the virtual sub-component of DAL. -# It provides the control and status of HW CRTC block. - -VIRTUAL = virtual_link_encoder.o virtual_stream_encoder.o virtual_link_hwss.o - -AMD_DAL_VIRTUAL = $(addprefix $(AMDDALPATH)/dc/virtual/,$(VIRTUAL)) - -AMD_DISPLAY_FILES += $(AMD_DAL_VIRTUAL) From 4a9c9882153a31818f25ef860e62d227f106e93f Mon Sep 17 00:00:00 2001 From: Peichen Huang Date: Mon, 26 Jan 2026 11:56:28 +0800 Subject: [PATCH 08/49] drm/amd/display: use enum value for panel replay setting [WHY & HOW] use enum value for Panel Replay setting. Reviewed-by: Robin Chen Signed-off-by: Peichen Huang Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/link/protocols/link_dp_panel_replay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c index 4a9e86d32dbb..7e45d1e767bb 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c @@ -333,10 +333,10 @@ bool dp_pr_copy_settings(struct dc_link *link, struct replay_context *replay_con pipe_ctx->stream->timing.dsc_cfg.num_slices_v; if (dc_is_embedded_signal(link->connector_signal)) - cmd.pr_copy_settings.data.main_link_activity_option = 0x03;//OPTION_1C; + cmd.pr_copy_settings.data.main_link_activity_option = OPTION_1C; else // For external DP, use option 1-A - cmd.pr_copy_settings.data.main_link_activity_option = 0x01;//OPTION_1A; + cmd.pr_copy_settings.data.main_link_activity_option = OPTION_1A; dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); return true; From 4d687d06c3409e4e041c65645eab10520bd78afe Mon Sep 17 00:00:00 2001 From: Vitaly Prosyak Date: Thu, 5 Feb 2026 17:31:24 -0500 Subject: [PATCH 09/49] drm/amd/display: guard NULL manual-trigger callback in cursor programming KASAN reports a NULL instruction fetch (RIP=0x0) from dc_stream_program_cursor_position(): BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:0x0 Call Trace: dc_stream_program_cursor_position+0x344/0x920 [amdgpu] amdgpu_dm_atomic_commit_tail+... [ +1.041013] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ +0.000027] #PF: supervisor instruction fetch in kernel mode [ +0.000013] #PF: error_code(0x0010) - not-present page [ +0.000012] PGD 0 P4D 0 [ +0.000017] Oops: Oops: 0010 [#1] SMP KASAN NOPTI [ +0.000017] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Tainted: G E 6.18.0+ #3 PREEMPT(voluntary) [ +0.000023] Tainted: [E]=UNSIGNED_MODULE [ +0.000010] Hardware name: ASUS System Product Name/ROG STRIX B550-F GAMING (WI-FI), BIOS 1401 12/03/2020 [ +0.000016] Workqueue: events drm_mode_rmfb_work_fn [ +0.000022] RIP: 0010:0x0 [ +0.000017] Code: Unable to access opcode bytes at 0xffffffffffffffd6. [ +0.000015] RSP: 0018:ffffc9000017f4c8 EFLAGS: 00010246 [ +0.000016] RAX: 0000000000000000 RBX: ffff88810afdda80 RCX: 1ffff110457000d1 [ +0.000014] RDX: 1ffffffff87b75bd RSI: 0000000000000000 RDI: ffff88810afdda80 [ +0.000014] RBP: ffffc9000017f538 R08: 0000000000000000 R09: ffff88822b800690 [ +0.000013] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc3dbac20 [ +0.000014] R13: 0000000000000000 R14: ffff88811ab80000 R15: dffffc0000000000 [ +0.000014] FS: 0000000000000000(0000) GS:ffff888434599000(0000) knlGS:0000000000000000 [ +0.000015] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ +0.000013] CR2: ffffffffffffffd6 CR3: 000000010ee88000 CR4: 0000000000350ef0 [ +0.000014] Call Trace: [ +0.000010] [ +0.000010] dc_stream_program_cursor_position+0x344/0x920 [amdgpu] [ +0.001086] ? __pfx_mutex_lock+0x10/0x10 [ +0.000015] ? unwind_next_frame+0x18b/0xa70 [ +0.000019] amdgpu_dm_atomic_commit_tail+0x1124/0xfa20 [amdgpu] [ +0.001040] ? ret_from_fork_asm+0x1a/0x30 [ +0.000018] ? filter_irq_stacks+0x90/0xa0 [ +0.000022] ? __pfx_amdgpu_dm_atomic_commit_tail+0x10/0x10 [amdgpu] [ +0.001058] ? kasan_save_track+0x18/0x70 [ +0.000015] ? kasan_save_alloc_info+0x37/0x60 [ +0.000015] ? __kasan_kmalloc+0xc3/0xd0 [ +0.000013] ? __kmalloc_cache_noprof+0x1aa/0x600 [ +0.000016] ? drm_atomic_helper_setup_commit+0x788/0x1450 [ +0.000017] ? drm_atomic_helper_commit+0x7e/0x290 [ +0.000014] ? drm_atomic_commit+0x205/0x2e0 [ +0.000015] ? process_one_work+0x629/0xf80 [ +0.000016] ? worker_thread+0x87f/0x1570 [ +0.000020] ? srso_return_thunk+0x5/0x5f [ +0.000014] ? __kasan_check_write+0x14/0x30 [ +0.000014] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? _raw_spin_lock_irq+0x8a/0xf0 [ +0.000015] ? __pfx__raw_spin_lock_irq+0x10/0x10 [ +0.000016] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? __kasan_check_write+0x14/0x30 [ +0.000014] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? __wait_for_common+0x204/0x460 [ +0.000015] ? sched_clock_noinstr+0x9/0x10 [ +0.000014] ? __pfx_schedule_timeout+0x10/0x10 [ +0.000014] ? local_clock_noinstr+0xe/0xd0 [ +0.000015] ? __pfx___wait_for_common+0x10/0x10 [ +0.000014] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? __wait_for_common+0x204/0x460 [ +0.000014] ? __pfx_schedule_timeout+0x10/0x10 [ +0.000015] ? __kasan_kmalloc+0xc3/0xd0 [ +0.000015] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? wait_for_completion_timeout+0x1d/0x30 [ +0.000015] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? drm_crtc_commit_wait+0x32/0x180 [ +0.000015] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? drm_atomic_helper_wait_for_dependencies+0x46a/0x800 [ +0.000019] commit_tail+0x231/0x510 [ +0.000017] drm_atomic_helper_commit+0x219/0x290 [ +0.000015] ? __pfx_drm_atomic_helper_commit+0x10/0x10 [ +0.000016] drm_atomic_commit+0x205/0x2e0 [ +0.000014] ? __pfx_drm_atomic_commit+0x10/0x10 [ +0.000013] ? __pfx_drm_connector_free+0x10/0x10 [ +0.000014] ? __pfx___drm_printfn_info+0x10/0x10 [ +0.000017] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? drm_atomic_set_crtc_for_connector+0x49e/0x660 [ +0.000015] ? drm_atomic_set_fb_for_plane+0x155/0x290 [ +0.000015] drm_framebuffer_remove+0xa9b/0x1240 [ +0.000014] ? finish_task_switch.isra.0+0x15a/0x840 [ +0.000015] ? __switch_to+0x385/0xda0 [ +0.000015] ? srso_safe_ret+0x1/0x20 [ +0.000013] ? __pfx_drm_framebuffer_remove+0x10/0x10 [ +0.000016] ? kasan_print_address_stack_frame+0x221/0x280 [ +0.000015] drm_mode_rmfb_work_fn+0x14b/0x240 [ +0.000015] process_one_work+0x629/0xf80 [ +0.000012] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? __kasan_check_write+0x14/0x30 [ +0.000019] worker_thread+0x87f/0x1570 [ +0.000013] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ +0.000014] ? __pfx_try_to_wake_up+0x10/0x10 [ +0.000017] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? kasan_print_address_stack_frame+0x227/0x280 [ +0.000017] ? __pfx_worker_thread+0x10/0x10 [ +0.000014] kthread+0x396/0x830 [ +0.000013] ? __pfx__raw_spin_lock_irq+0x10/0x10 [ +0.000015] ? __pfx_kthread+0x10/0x10 [ +0.000012] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? __kasan_check_write+0x14/0x30 [ +0.000014] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? recalc_sigpending+0x180/0x210 [ +0.000015] ? srso_return_thunk+0x5/0x5f [ +0.000013] ? __pfx_kthread+0x10/0x10 [ +0.000014] ret_from_fork+0x31c/0x3e0 [ +0.000014] ? __pfx_kthread+0x10/0x10 [ +0.000013] ret_from_fork_asm+0x1a/0x30 [ +0.000019] [ +0.000010] Modules linked in: rfcomm(E) cmac(E) algif_hash(E) algif_skcipher(E) af_alg(E) snd_seq_dummy(E) snd_hrtimer(E) qrtr(E) xt_MASQUERADE(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) xt_mark(E) xt_tcpudp(E) nft_compat(E) nf_tables(E) x_tables(E) bnep(E) snd_hda_codec_alc882(E) snd_hda_codec_atihdmi(E) snd_hda_codec_realtek_lib(E) snd_hda_codec_hdmi(E) snd_hda_codec_generic(E) iwlmvm(E) snd_hda_intel(E) binfmt_misc(E) snd_hda_codec(E) snd_hda_core(E) mac80211(E) snd_intel_dspcfg(E) snd_intel_sdw_acpi(E) snd_hwdep(E) snd_pcm(E) libarc4(E) snd_seq_midi(E) snd_seq_midi_event(E) snd_rawmidi(E) amd_atl(E) intel_rapl_msr(E) snd_seq(E) intel_rapl_common(E) iwlwifi(E) jc42(E) snd_seq_device(E) btusb(E) snd_timer(E) btmtk(E) btrtl(E) edac_mce_amd(E) eeepc_wmi(E) polyval_clmulni(E) btbcm(E) ghash_clmulni_intel(E) asus_wmi(E) ee1004(E) platform_profile(E) btintel(E) snd(E) nls_iso8859_1(E) aesni_intel(E) soundcore(E) i2c_piix4(E) cfg80211(E) sparse_keymap(E) wmi_bmof(E) bluetooth(E) k10temp(E) rapl(E) [ +0.000300] i2c_smbus(E) ccp(E) joydev(E) input_leds(E) gpio_amdpt(E) mac_hid(E) sch_fq_codel(E) msr(E) parport_pc(E) ppdev(E) lp(E) parport(E) efi_pstore(E) nfnetlink(E) dmi_sysfs(E) autofs4(E) cdc_ether(E) usbnet(E) amdgpu(E) amdxcp(E) hid_generic(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) drm_panel_backlight_quirks(E) gpu_sched(E) drm_suballoc_helper(E) video(E) drm_buddy(E) usbhid(E) drm_display_helper(E) r8152(E) hid(E) mii(E) cec(E) ahci(E) rc_core(E) igc(E) libahci(E) wmi(E) [ +0.000294] CR2: 0000000000000000 [ +0.000013] ---[ end trace 0000000000000000 ]--- The crash happens when we unconditionally call into the timing generator manual trigger hook: pipe_ctx->stream_res.tg->funcs->program_manual_trigger(...) On some configurations the timing generator (tg), its funcs table, or the program_manual_trigger callback can be NULL. Guard all of these before calling the hook. If the first pipe matching the stream cannot trigger, keep scanning to find another matching pipe with a valid hook. The issue was originally found on Vg20/DCE 12.1 Mario successfully tested on Polaris 11/DCE 11.2 Cc: Aurabindo Pillai Cc: Alexander Deucher Cc: Christian Koenig Fixes: ba448f9ed62c ("drm/amd/display: mouse event trigger to boost RR when idle") Suggested-by: Aurabindo Pillai Signed-off-by: Vitaly Prosyak Reviewed-by: Aurabindo Pillai Reviewed-and-tested-by: Mario Kleiner Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 f59020f1a722..ecd08580937d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -522,8 +522,10 @@ bool dc_stream_program_cursor_position( 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); + if (stream == pipe_ctx->stream && + pipe_ctx->stream_res.tg->funcs->program_manual_trigger) { + pipe_ctx->stream_res.tg->funcs->program_manual_trigger( + pipe_ctx->stream_res.tg); break; } } From 318917e1d8ecc89f820f4fabf79935f4fed718cd Mon Sep 17 00:00:00 2001 From: Leo Li Date: Mon, 3 Nov 2025 11:14:59 -0500 Subject: [PATCH 10/49] drm/amd/display: Increase DCN35 SR enter/exit latency [Why & How] On Framework laptops with DDR5 modules, underflow can be observed. It's unclear why it only occurs on specific desktop contents. However, increasing enter/exit latencies by 3us seems to resolve it. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4463 Reviewed-by: Nicholas Kazlauskas Signed-off-by: Leo Li Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- .../amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 16 ++++++++-------- .../gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c index 7abe6811e4df..6fc524752613 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -766,32 +766,32 @@ static struct wm_table ddr5_wm_table = { .wm_inst = WM_A, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, { .wm_inst = WM_B, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, { .wm_inst = WM_C, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, { .wm_inst = WM_D, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c index 817a370e80a7..8a177d5ae213 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c @@ -164,8 +164,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { }, }, .num_states = 5, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .sr_exit_z8_time_us = 250.0, .sr_enter_plus_exit_z8_time_us = 350.0, .fclk_change_latency_us = 24.0, From 4bff89bad90cff5b8422813f659317637d0a1994 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Fri, 23 Jan 2026 17:00:06 -0500 Subject: [PATCH 11/49] drm/amd/display: Make GPIO HPD path conditional [Why] Avoid unnecessary GPIO configuration attempts on dcn that doesn't support it. [How] Conditionally use GPIO HPD detection or rely on hw encoder path. Reviewed-by: Charlene Liu Signed-off-by: Roman Li Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 8 +++++--- drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c | 9 +++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) 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 5fbcf04c6251..6f4c3c73e113 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -564,9 +564,11 @@ static bool construct_phy(struct dc_link *link, 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; - enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, - link->ctx->gpio_service); - + if (link->ctx->dce_version <= DCN_VERSION_4_01) + enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, + link->ctx->gpio_service); + else + enc_init_data.hpd_gpio = NULL; if (enc_init_data.hpd_gpio) { dal_gpio_open(enc_init_data.hpd_gpio, GPIO_MODE_INTERRUPT); dal_gpio_unlock_pin(enc_init_data.hpd_gpio); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c index 29f3a03687b2..b157d05b67ad 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c @@ -136,8 +136,13 @@ enum hpd_source_id get_hpd_line(struct dc_link *link) hpd_id = HPD_SOURCEID_UNKNOWN; - hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, - link->ctx->gpio_service); + /* Use GPIO path where supported, otherwise use hardware encoder path */ + if (link->ctx && link->ctx->dce_version <= DCN_VERSION_4_01) { + hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, + link->ctx->gpio_service); + } else { + hpd = NULL; + } if (hpd) { switch (dal_irq_get_source(hpd)) { From 0faccfa9ca8e9688f106c961972b885f7eb86941 Mon Sep 17 00:00:00 2001 From: Ray Wu Date: Mon, 26 Jan 2026 15:55:18 +0800 Subject: [PATCH 12/49] drm/amd/display: Parse all extension blocks for VSDB [Why] VSDB parsing loop only searched within the first extension block. If the VSDB was located in a subsequent extension block, it would not be found. [How] Calculate the total length of all extension blocks (EDID_LENGTH * edid->extensions) and use that as the loop boundary, allowing the parser to search through all available extension blocks. Reviewed-by: Tom Chung Signed-off-by: Ray Wu Signed-off-by: Tom Chung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 9fcb4677d0f0..510df1134b56 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -13149,6 +13149,7 @@ static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector, u8 *edid_ext = NULL; int i; int j = 0; + int total_ext_block_len; if (edid == NULL || edid->extensions == 0) return -ENODEV; @@ -13160,7 +13161,8 @@ static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector, break; } - while (j < EDID_LENGTH - sizeof(struct amd_vsdb_block)) { + total_ext_block_len = EDID_LENGTH * edid->extensions; + while (j < total_ext_block_len - sizeof(struct amd_vsdb_block)) { struct amd_vsdb_block *amd_vsdb = (struct amd_vsdb_block *)&edid_ext[j]; unsigned int ieeeId = (amd_vsdb->ieee_id[2] << 16) | (amd_vsdb->ieee_id[1] << 8) | (amd_vsdb->ieee_id[0]); From 6386a0bcdb7e4c20943d3983520ebc22f041a226 Mon Sep 17 00:00:00 2001 From: Muaaz Nisar Date: Wed, 21 Jan 2026 14:25:38 -0500 Subject: [PATCH 13/49] Revert "drm/amd/display: mouse event trigger to boost RR when idle" This reverts commit ba448f9ed62cf5a89603a738e6de91fc6c42ab35. It cause some regression. Reviewed-by: Sreeja Golui Signed-off-by: Muaaz Nisar Signed-off-by: Tom Chung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 15 --------------- 1 file changed, 15 deletions(-) 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 ecd08580937d..9349cccc8438 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -515,21 +515,6 @@ bool dc_stream_program_cursor_position( } } - /* 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->funcs->program_manual_trigger( - pipe_ctx->stream_res.tg); - break; - } - } - return true; } From 3303aa64e7a646bd0f17d447b42ad3615c3b0101 Mon Sep 17 00:00:00 2001 From: Nicholas Carbones Date: Wed, 28 Jan 2026 15:52:46 -0500 Subject: [PATCH 14/49] drm/amd/display: Correct hubp GfxVersion verification [Why] DcGfxBase case was not accounted for in hubp program tiling functions, causing tiling corruption on PNP. [How] Add handling for DcGfxBase so that tiling gets properly cleared. Reviewed-by: Charlene Liu Signed-off-by: Nicholas Carbones Signed-off-by: Tom Chung 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, 46 insertions(+), 33 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 e697d9bf1b44..78c866688c61 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,21 +145,26 @@ void hubp1_program_tiling( { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - ASSERT(info->gfxversion == DcGfxVersion9); + ASSERT(info->gfxversion == DcGfxVersion9 || info->gfxversion == DcGfxBase); - 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)); + 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_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 4715e60e812a..aaa8f8cf6c30 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,18 +313,22 @@ static void hubp2_program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion9); + ASSERT(info->gfxversion == DcGfxVersion9 || info->gfxversion == DcGfxBase); - 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)); + 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_4(DCSURF_TILING_CONFIG, - SW_MODE, info->gfx9.swizzle, - META_LINEAR, 0, - RB_ALIGNED, 0, - PIPE_ALIGNED, 0); + 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); + } } 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 207c2f86b7d7..2126830a5a9e 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,18 +321,22 @@ void hubp3_program_tiling( const struct dc_tiling_info *info, const enum surface_pixel_format pixel_format) { - ASSERT(info->gfxversion == DcGfxVersion9); + ASSERT(info->gfxversion == DcGfxVersion9 || info->gfxversion == DcGfxBase); - 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)); + 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_3(DCSURF_TILING_CONFIG, - SW_MODE, info->gfx9.swizzle, - META_LINEAR, info->gfx9.meta_linear, - PIPE_ALIGNED, info->gfx9.pipe_aligned); + 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); + } } From 6246c12f52c389342358c3039475ef822921dcae Mon Sep 17 00:00:00 2001 From: Nicholas Carbones Date: Wed, 28 Jan 2026 12:28:54 -0500 Subject: [PATCH 15/49] drm/amd/display: Revert "Migrate DCCG register access from hwseq to dccg component." [Why & How] This reverts commit 949adb4789fe3c24eea01d9c2efe94ab92694a0d, which causes regressions related to HDCP when resuming from S3. Reviewed-by: Joshua Aberback Signed-off-by: Nicholas Carbones Signed-off-by: Tom Chung Signed-off-by: Alex Deucher --- .../amd/display/dc/dccg/dcn20/dcn20_dccg.c | 54 +------------------ .../amd/display/dc/dccg/dcn20/dcn20_dccg.h | 18 ++----- .../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 -- 12 files changed, 49 insertions(+), 98 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 50b98822b6fd..33d8bd91cb01 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,54 +131,6 @@ 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 = { @@ -187,11 +139,7 @@ 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, - .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 + .dccg_init = dccg2_init }; 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 237a684ded86..8bdffd9ff31b 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 @@ -46,9 +46,7 @@ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 2),\ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 3),\ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 4),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 5),\ - SR(DCCG_GATE_DISABLE_CNTL),\ - SR(DCCG_GATE_DISABLE_CNTL2) + DCCG_SRII(PIXEL_RATE_CNTL, OTG, 5) #define DCCG_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -83,8 +81,7 @@ 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_SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh) + DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh) @@ -133,8 +130,7 @@ type DISPCLK_CHG_FWD_CORR_DISABLE;\ type DISPCLK_FREQ_CHANGE_CNTL;\ type OTG_ADD_PIXEL[MAX_PIPES];\ - type OTG_DROP_PIXEL[MAX_PIPES];\ - type DC_MEM_GLOBAL_PWR_REQ_DIS; + type OTG_DROP_PIXEL[MAX_PIPES]; #define DCCG3_REG_FIELD_LIST(type) \ type HDMICHARCLK0_EN;\ @@ -519,14 +515,6 @@ void dccg2_otg_drop_pixel(struct dccg *dccg, void dccg2_init(struct dccg *dccg); -void dccg2_refclk_setup(struct dccg *dccg); - -bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg); - -void dccg2_allow_clock_gating(struct dccg *dccg, bool allow); - -void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable); - struct dccg *dccg2_create( struct dc_context *ctx, const struct dccg_registers *regs, 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 5243177c1faa..9613d1ceb5dc 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,8 +1887,9 @@ void dcn10_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - 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_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); 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 307e8f8060e6..0ee3a0041c61 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,10 +357,26 @@ void dcn20_enable_power_gating_plane( void dcn20_dccg_init(struct dce_hwseq *hws) { - struct dc *dc = hws->ctx->dc; + /* + * set MICROSECOND_TIME_BASE_DIV + * 100Mhz refclk -> 0x120264 + * 27Mhz refclk -> 0x12021b + * 48Mhz refclk -> 0x120230 + * + */ + REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264); - 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); + /* + * 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); } void dcn20_disable_vga( @@ -3140,11 +3156,8 @@ void dcn20_fpga_init_hw(struct dc *dc) dcn10_hubbub_global_timer_enable(dc->res_pool->hubbub, true, 2); - 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); + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); // 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 ce18d75fd991..6298bd87a18b 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,8 +367,9 @@ void dcn201_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - 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_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); 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 062745389d9a..e2269211553c 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,7 +33,6 @@ #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" @@ -88,10 +87,12 @@ 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) { - 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); + struct dce_hwseq *hws = dc->hwseq; + uint32_t value = 0; - return false; + value = REG_READ(MICROSECOND_TIME_BASE_DIV); + + return value != 0x00120464; } 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 d04cfd403b7e..333275088a6c 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,8 +801,9 @@ void dcn30_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - 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_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); 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 db2f7cbb12ff..fa35d538a10a 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,8 +247,9 @@ void dcn31_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - 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_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); 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 2767d3a97812..01fa459ae7b0 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,8 +963,9 @@ void dcn32_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - 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_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); 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 b5a4cefbd35f..0cbd75ab61a1 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,8 +286,7 @@ void dcn35_init_hw(struct dc *dc) } if (dc->debug.disable_mem_low_power) { - 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); + REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1); } 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 b91517b9fedc..d1515039e824 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,8 +326,9 @@ void dcn401_init_hw(struct dc *dc) if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - 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_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); 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 a26d31ab7cba..1e6ffd86a4c0 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -224,9 +224,6 @@ 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); void (*set_dpstreamclk_root_clock_gating)( struct dccg *dccg, int dp_hpo_inst, @@ -337,7 +334,6 @@ struct dccg_funcs { void (*dccg_root_gate_disable_control)(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating); void (*dccg_read_reg_state)(struct dccg *dccg, struct dcn_dccg_reg_state *dccg_reg_state); void (*dccg_enable_global_fgcg)(struct dccg *dccg, bool enable); - bool (*is_s0i3_golden_init_wa_done)(struct dccg *dccg); }; #endif //__DAL_DCCG_H__ From 7d9ec9dc20ecdb1661f4538cd9112cd3d6a5f15a Mon Sep 17 00:00:00 2001 From: Clay King Date: Fri, 30 Jan 2026 11:40:06 -0500 Subject: [PATCH 16/49] drm/amd/display: bypass post csc for additional color spaces in dal [Why] For RGB BT2020 full and limited color spaces, overlay adjustments were applied twice (once by MM and once by DAL). This results in incorrect colours and a noticeable difference between mpo and non-mpo cases. [How] Add RGB BT2020 full and limited color spaces to list that bypasses post csc adjustment. Reviewed-by: Aric Cyr Signed-off-by: Clay King Signed-off-by: Tom Chung Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c | 21 ++++++++++++++++--- .../drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h | 4 ++++ .../amd/display/dc/dpp/dcn401/dcn401_dpp.c | 6 +++--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c index ef4a16117181..c7923531da83 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c @@ -376,10 +376,10 @@ void dpp3_cnv_setup ( tbl_entry.color_space = input_color_space; - if (color_space >= COLOR_SPACE_YCBCR601) - select = INPUT_CSC_SELECT_ICSC; - else + if (dpp3_should_bypass_post_csc_for_colorspace(color_space)) select = INPUT_CSC_SELECT_BYPASS; + else + select = INPUT_CSC_SELECT_ICSC; dpp3_program_post_csc(dpp_base, color_space, select, &tbl_entry); @@ -1541,3 +1541,18 @@ bool dpp3_construct( return true; } +bool dpp3_should_bypass_post_csc_for_colorspace(enum dc_color_space dc_color_space) +{ + switch (dc_color_space) { + case COLOR_SPACE_UNKNOWN: + case COLOR_SPACE_SRGB: + case COLOR_SPACE_XR_RGB: + case COLOR_SPACE_SRGB_LIMITED: + case COLOR_SPACE_MSREF_SCRGB: + case COLOR_SPACE_2020_RGB_FULLRANGE: + case COLOR_SPACE_2020_RGB_LIMITEDRANGE: + return true; + default: + return false; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h index d4a70b4379ea..6a61b99d6a79 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h @@ -644,4 +644,8 @@ void dpp3_program_cm_dealpha( void dpp3_cm_get_gamut_remap(struct dpp *dpp_base, struct dpp_grph_csc_adjustment *adjust); + +bool dpp3_should_bypass_post_csc_for_colorspace( + enum dc_color_space dc_color_space); + #endif /* __DC_HWSS_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c index 96c2c853de42..2d6a646462e2 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c @@ -206,10 +206,10 @@ void dpp401_dpp_setup( tbl_entry.color_space = input_color_space; - if (color_space >= COLOR_SPACE_YCBCR601) - select = INPUT_CSC_SELECT_ICSC; - else + if (dpp3_should_bypass_post_csc_for_colorspace(color_space)) select = INPUT_CSC_SELECT_BYPASS; + else + select = INPUT_CSC_SELECT_ICSC; dpp3_program_post_csc(dpp_base, color_space, select, &tbl_entry); From 0f2620c48640e6635270d54d2cd9d724e5a1338a Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 7 Jan 2026 17:31:37 -0700 Subject: [PATCH 17/49] drm/amd/display: Fix the incorrect type in dml_print [Why & How] soc->max_outstanding_reqs is a dml_uint_t, not a dml_float_t. Reviewed-by: Austin Zheng Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Hung Signed-off-by: Tom Chung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c index 89890c88fd66..4022f91193ed 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c @@ -655,7 +655,7 @@ __DML_DLL_EXPORT__ void dml_print_soc_bounding_box(const struct soc_bounding_box dml_print("DML: soc_bbox: refclk_mhz = %f\n", soc->refclk_mhz); dml_print("DML: soc_bbox: amclk_mhz = %f\n", soc->amclk_mhz); - dml_print("DML: soc_bbox: max_outstanding_reqs = %f\n", soc->max_outstanding_reqs); + dml_print("DML: soc_bbox: max_outstanding_reqs = %d\n", soc->max_outstanding_reqs); dml_print("DML: soc_bbox: pct_ideal_sdp_bw_after_urgent = %f\n", soc->pct_ideal_sdp_bw_after_urgent); dml_print("DML: soc_bbox: pct_ideal_fabric_bw_after_urgent = %f\n", soc->pct_ideal_fabric_bw_after_urgent); dml_print("DML: soc_bbox: pct_ideal_dram_bw_after_urgent_pixel_only = %f\n", soc->pct_ideal_dram_bw_after_urgent_pixel_only); From e8c7156240a00fc3f13107dcd66aa5b51640cccb Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Fri, 30 Jan 2026 16:29:05 -0500 Subject: [PATCH 18/49] drm/amd/display: [FW Promotion] Release 0.1.46.0 Add some struct member and enum for panel replay Acked-by: Wayne Lin Signed-off-by: Taimur Hassan Signed-off-by: Tom Chung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 3b4f5e990ec5..6f388c910e18 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -1638,6 +1638,11 @@ enum dmub_gpint_command { * DESC: Initiates IPS wake sequence. */ DMUB_GPINT__IPS_DEBUG_WAKE = 137, + /** + * DESC: Do panel power off sequence + * ARGS: 1 - Power off + */ + DMUB_GPINT__PANEL_POWER_OFF_SEQ = 138, }; /** @@ -4408,6 +4413,7 @@ enum dmub_cmd_panel_replay_type { enum dmub_cmd_panel_replay_state_update_subtype { PR_STATE_UPDATE_COASTING_VTOTAL = 0x1, PR_STATE_UPDATE_SYNC_MODE = 0x2, + PR_STATE_UPDATE_RUNTIME_FLAGS = 0x3, }; enum dmub_cmd_panel_replay_general_subtype { @@ -6701,6 +6707,13 @@ struct dmub_rb_cmd_pr_copy_settings { struct dmub_cmd_pr_copy_settings_data data; }; +union dmub_pr_runtime_flags { + struct { + uint32_t disable_abm_optimization : 1; // Disable ABM optimization for PR + } bitfields; + uint32_t u32All; +}; + struct dmub_cmd_pr_update_state_data { /** * Panel Instance. @@ -6719,6 +6732,8 @@ struct dmub_cmd_pr_update_state_data { */ uint32_t coasting_vtotal; uint32_t sync_mode; + + union dmub_pr_runtime_flags pr_runtime_flags; }; struct dmub_cmd_pr_general_cmd_data { From 1778a64f9bea4173f8eb3767d6f385c51fd09bf8 Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Fri, 30 Jan 2026 18:35:15 -0500 Subject: [PATCH 19/49] drm/amd/display: Promote DC to 3.2.369 This version brings along following update: -Fix system resume lag issue -Correct hubp GfxVersion verification -Add parse all extension blocks for VSDB -Increase DCN35 SR enter/exit latency -Refactor virtual directory reorganize encoder and hwss files -Set enable_legacy_fast_update to false for DCN36 -Have dm_atomic_state context aligned with dc_state current -Avoid updating surface with the same surface under MPO Acked-by: Wayne Lin Signed-off-by: Taimur Hassan Signed-off-by: Tom Chung Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index fdfcfa416d16..ce08477d1ccd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -63,7 +63,7 @@ struct dcn_dsc_reg_state; struct dcn_optc_reg_state; struct dcn_dccg_reg_state; -#define DC_VER "3.2.368" +#define DC_VER "3.2.369" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC From 226a40c06a183abaeb7529a4f54d6c203bd14407 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 6 Feb 2026 20:06:19 +0530 Subject: [PATCH 20/49] drm/amd/display: Fix dc_link NULL handling in HPD init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amdgpu_dm_hpd_init() may see connectors without a valid dc_link. The code already checks dc_link for the polling decision, but later unconditionally dereferences it when setting up HPD interrupts. Assign dc_link early and skip connectors where it is NULL. Fixes the below: drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c:940 amdgpu_dm_hpd_init() error: we previously assumed 'dc_link' could be null (see line 931) drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c 923 /* 924 * Analog connectors may be hot-plugged unlike other connector 925 * types that don't support HPD. Only poll analog connectors. 926 */ 927 use_polling |= 928 amdgpu_dm_connector->dc_link && ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The patch adds this NULL check but hopefully it can be removed 929 dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id); 930 931 dc_link = amdgpu_dm_connector->dc_link; dc_link assigned here. 932 933 /* 934 * Get a base driver irq reference for hpd ints for the lifetime 935 * of dm. Note that only hpd interrupt types are registered with 936 * base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on 937 * hpd_rx isn't available. DM currently controls hpd_rx 938 * explicitly with dc_interrupt_set() 939 */ --> 940 if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) { ^^^^^^^^^^^^^^^^^^^^^^^ If it's NULL then we are trouble because we dereference it here. 941 irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1; 942 /* 943 * TODO: There's a mismatch between mode_info.num_hpd 944 * and what bios reports as the # of connectors with hpd Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") Cc: Timur Kristóf Cc: Harry Wentland Cc: Mario Limonciello Cc: Alex Hung Cc: Aurabindo Pillai Cc: ChiaHsuan Chung Cc: Roman Li Reported-by: Dan Carpenter Signed-off-by: Srinivasan Shanmugam Reviewed-by: Timur Kristóf Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index e7b0928bd3db..5948e2a6219e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -919,16 +919,15 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) continue; amdgpu_dm_connector = to_amdgpu_dm_connector(connector); + dc_link = amdgpu_dm_connector->dc_link; + if (!dc_link) + continue; /* * Analog connectors may be hot-plugged unlike other connector * types that don't support HPD. Only poll analog connectors. */ - use_polling |= - amdgpu_dm_connector->dc_link && - dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id); - - dc_link = amdgpu_dm_connector->dc_link; + use_polling |= dc_connector_supports_analog(dc_link->link_id.id); /* * Get a base driver irq reference for hpd ints for the lifetime From ba038065655c45728be346d0b174a6da08d8a5c5 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 6 Feb 2026 19:53:05 +0530 Subject: [PATCH 21/49] drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amdgpu_ib_schedule() returns early after calling amdgpu_ring_undo(). This skips the common free_fence cleanup path. Other error paths were already changed to use goto free_fence, but this one was missed. Change the early return to goto free_fence so all error paths clean up the same way. Fixes the below: drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c:232 amdgpu_ib_schedule() warn: missing unwind goto? drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c 124 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, 125 struct amdgpu_ib *ibs, struct amdgpu_job *job, 126 struct dma_fence **f) 127 { ... 224 225 if (ring->funcs->insert_start) 226 ring->funcs->insert_start(ring); 227 228 if (job) { 229 r = amdgpu_vm_flush(ring, job, need_pipe_sync); 230 if (r) { 231 amdgpu_ring_undo(ring); --> 232 return r; The patch changed the other error paths to goto free_fence but this one was accidentally skipped. 233 } 234 } 235 236 amdgpu_ring_ib_begin(ring); ... 338 339 free_fence: 340 if (!job) 341 kfree(af); 342 return r; 343 } Fixes: f903b85ed0f1 ("drm/amdgpu: fix possible fence leaks from job structure") Reported-by: Dan Carpenter Cc: Alex Deucher Cc: Christian König Signed-off-by: Srinivasan Shanmugam Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 44f230d67da2..bfa64cd7a62d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -229,7 +229,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, r = amdgpu_vm_flush(ring, job, need_pipe_sync); if (r) { amdgpu_ring_undo(ring); - return r; + goto free_fence; } } From 5a19302cab5cec7ae7f1a60c619951e6c17d8742 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 6 Feb 2026 21:18:11 +0530 Subject: [PATCH 22/49] drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The address watch clear code receives watch_id as an unsigned value (u32), but some helper functions were using a signed int and checked bits by shifting with watch_id. If a very large watch_id is passed from userspace, it can be converted to a negative value. This can cause invalid shifts and may access memory outside the watch_points array. drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before using it. Also use BIT(watch_id) to test and clear bits safely. This keeps the behavior unchanged for valid watch IDs and avoids undefined behavior for invalid ones. Fixes the below: drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448 kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow 'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, 434 uint32_t watch_id) 435 { 436 int r; 437 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if watch_id is larger than INT_MAX it leads to a buffer overflow. (Negative shifts are undefined). 439 return -EINVAL; 440 441 if (!pdd->dev->kfd->shared_resources.enable_mes) { 442 r = debug_lock_and_unmap(pdd->dev->dqm); 443 if (r) 444 return r; 445 } 446 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false); --> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch( 449 pdd->dev->adev, 450 watch_id); v2: (as per, Jonathan Kim) - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to match the clear path. - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id(). Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation") Reported-by: Dan Carpenter Cc: Jonathan Kim Cc: Felix Kuehling Cc: Alex Deucher Cc: Christian König Signed-off-by: Srinivasan Shanmugam Reviewed-by: Jonathan Kim Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index 1dae317858e9..bedb95ce9659 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -404,27 +404,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i return -ENOMEM; } -static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) +static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) { spin_lock(&pdd->dev->watch_points_lock); /* process owns device watch point so safe to clear */ - if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { - pdd->alloc_watch_ids &= ~(0x1 << watch_id); - pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); + if (pdd->alloc_watch_ids & BIT(watch_id)) { + pdd->alloc_watch_ids &= ~BIT(watch_id); + pdd->dev->alloc_watch_ids &= ~BIT(watch_id); } spin_unlock(&pdd->dev->watch_points_lock); } -static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) +static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) { bool owns_watch_id = false; spin_lock(&pdd->dev->watch_points_lock); - owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && - ((pdd->alloc_watch_ids >> watch_id) & 0x1); - + owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id); spin_unlock(&pdd->dev->watch_points_lock); return owns_watch_id; @@ -435,6 +433,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, { int r; + if (watch_id >= MAX_WATCH_ADDRESSES) + return -EINVAL; + if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) return -EINVAL; @@ -472,6 +473,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd, if (r) return r; + if (*watch_id >= MAX_WATCH_ADDRESSES) + return -EINVAL; + if (!pdd->dev->kfd->shared_resources.enable_mes) { r = debug_lock_and_unmap(pdd->dev->dqm); if (r) { From f5a8292aab5be0f52b656ac393df4c26edac8e90 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Wed, 4 Feb 2026 01:38:23 -0500 Subject: [PATCH 23/49] drm/amd/pm: use sysfs_streq for string matching in amdgpu_pm The driver uses strncmp() to compare sysfs attribute strings, which does not handle trailing newlines and lacks NULL safety. sysfs_streq() is the recommended function for sysfs string equality checks in the kernel, providing safer and more correct behavior. replace strncmp() with sysfs_streq() in drivers/gpu/drm/amd/pm/amdgpu_pm.c Signed-off-by: Yang Wang Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 07641c9413d2..938361ecae05 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -243,11 +243,11 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev, enum amd_pm_state_type state; int ret; - if (strncmp("battery", buf, strlen("battery")) == 0) + if (sysfs_streq(buf, "battery")) state = POWER_STATE_TYPE_BATTERY; - else if (strncmp("balanced", buf, strlen("balanced")) == 0) + else if (sysfs_streq(buf, "balanced")) state = POWER_STATE_TYPE_BALANCED; - else if (strncmp("performance", buf, strlen("performance")) == 0) + else if (sysfs_streq(buf, "performance")) state = POWER_STATE_TYPE_PERFORMANCE; else return -EINVAL; @@ -363,29 +363,28 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, enum amd_dpm_forced_level level; int ret = 0; - if (strncmp("low", buf, strlen("low")) == 0) { + if (sysfs_streq(buf, "low")) level = AMD_DPM_FORCED_LEVEL_LOW; - } else if (strncmp("high", buf, strlen("high")) == 0) { + else if (sysfs_streq(buf, "high")) level = AMD_DPM_FORCED_LEVEL_HIGH; - } else if (strncmp("auto", buf, strlen("auto")) == 0) { + else if (sysfs_streq(buf, "auto")) level = AMD_DPM_FORCED_LEVEL_AUTO; - } else if (strncmp("manual", buf, strlen("manual")) == 0) { + else if (sysfs_streq(buf, "manual")) level = AMD_DPM_FORCED_LEVEL_MANUAL; - } else if (strncmp("profile_exit", buf, strlen("profile_exit")) == 0) { + else if (sysfs_streq(buf, "profile_exit")) level = AMD_DPM_FORCED_LEVEL_PROFILE_EXIT; - } else if (strncmp("profile_standard", buf, strlen("profile_standard")) == 0) { + else if (sysfs_streq(buf, "profile_standard")) level = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD; - } else if (strncmp("profile_min_sclk", buf, strlen("profile_min_sclk")) == 0) { + else if (sysfs_streq(buf, "profile_min_sclk")) level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK; - } else if (strncmp("profile_min_mclk", buf, strlen("profile_min_mclk")) == 0) { + else if (sysfs_streq(buf, "profile_min_mclk")) level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK; - } else if (strncmp("profile_peak", buf, strlen("profile_peak")) == 0) { + else if (sysfs_streq(buf, "profile_peak")) level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK; - } else if (strncmp("perf_determinism", buf, strlen("perf_determinism")) == 0) { + else if (sysfs_streq(buf, "perf_determinism")) level = AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM; - } else { + else return -EINVAL; - } ret = amdgpu_pm_get_access(adev); if (ret < 0) From 41af6215cdbcecd12920f211239479027904abf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Sun, 18 Jan 2026 15:57:41 +0100 Subject: [PATCH 24/49] drm/amd/display: Reject cursor plane on DCE when scaled differently than primary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently DCE doesn't support the overlay cursor, so the dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE unconditionally. The outcome is that it doesn't check for the conditions that would necessitate the overlay cursor, meaning that it doesn't reject cases where the native cursor mode isn't supported on DCE. Remove the early return from dm_crtc_get_cursor_mode() for DCE and instead let it perform the necessary checks and return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects when DM_CURSOR_OVERLAY_MODE would be used with DCE. Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600 Suggested-by: Leo Li Signed-off-by: Timur Kristóf Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 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 510df1134b56..ef9df52dd34b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -12309,10 +12309,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, /* Overlay cursor not supported on HW before DCN * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions - * as previous DCN generations, so enable native mode on DCN401 in addition to DCE + * as previous DCN generations, so enable native mode on DCN401 */ - if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 || - amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { + if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { *cursor_mode = DM_CURSOR_NATIVE_MODE; return 0; } @@ -12632,6 +12631,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, * need to be added for DC to not disable a plane by mistake */ if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) { + if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) { + drm_dbg(dev, "Overlay cursor not supported on DCE\n"); + ret = -EINVAL; + goto fail; + } + ret = drm_atomic_add_affected_planes(state, crtc); if (ret) goto fail; From 29b1b0b06defd4dcbb8af246270a9ad8686b89ed Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Thu, 22 Jan 2026 18:00:27 +0800 Subject: [PATCH 25/49] drm/amd/pm: use debug port for mode1 reset request on smu 13&14 use debug port for mode1 reset request so fw can handle mode1 reset even when it is stuck. Signed-off-by: Kenneth Feng Reviewed-by: Yang Wang Signed-off-by: Alex Deucher --- .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 15 ++----- .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 45 ++++++++++++++++++- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index de770c10da3d..784a1af46527 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2615,21 +2615,11 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - u32 smu_version; - int ret; /* SRIOV does not support SMU mode1 reset */ if (amdgpu_sriov_vf(adev)) return false; - /* PMFW support is available since 78.41 */ - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) - return false; - - if (smu_version < 0x004e2900) - return false; - return true; } @@ -2828,8 +2818,9 @@ static int smu_v13_0_0_mode1_reset(struct smu_context *smu) /* SMU 13_0_0 PMFW supports RAS fatal error reset from 78.77 */ smu_v13_0_0_set_mode1_reset_param(smu, 0x004e4d00, ¶m); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_Mode1Reset, param, NULL); + ret = smu_cmn_send_debug_smc_msg_with_param(smu, + DEBUGSMC_MSG_Mode1Reset, param); + break; case IP_VERSION(13, 0, 10): diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index fe3d6bfe6812..a6c22ae86c98 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -74,6 +74,17 @@ static const struct smu_feature_bits smu_v13_0_7_dpm_features = { #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 +#define mmMP1_SMN_C2PMSG_75 0x028b +#define mmMP1_SMN_C2PMSG_75_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_53 0x0275 +#define mmMP1_SMN_C2PMSG_53_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_54 0x0276 +#define mmMP1_SMN_C2PMSG_54_BASE_IDX 0 + +#define DEBUGSMC_MSG_Mode1Reset 2 + #define PP_OD_FEATURE_GFXCLK_FMIN 0 #define PP_OD_FEATURE_GFXCLK_FMAX 1 #define PP_OD_FEATURE_UCLK_FMIN 2 @@ -2734,6 +2745,36 @@ static int smu_v13_0_7_update_pcie_parameters(struct smu_context *smu, return ret; } +static int smu_v13_0_7_mode1_reset(struct smu_context *smu) +{ + int ret; + + ret = smu_cmn_send_debug_smc_msg(smu, DEBUGSMC_MSG_Mode1Reset); + if (!ret) { + /* disable mmio access while doing mode 1 reset*/ + smu->adev->no_hw_access = true; + /* ensure no_hw_access is globally visible before any MMIO */ + smp_mb(); + msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS); + } + + return ret; +} + +static void smu_v13_0_7_init_msg_ctl(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + smu_v13_0_init_msg_ctl(smu, smu_v13_0_7_message_map); + + /* Set up debug mailbox registers */ + ctl->config.debug_param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_53); + ctl->config.debug_msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_75); + ctl->config.debug_resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_54); + ctl->flags |= SMU_MSG_CTL_DEBUG_MAILBOX; +} + static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .init_allowed_features = smu_v13_0_7_init_allowed_features, .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table, @@ -2795,7 +2836,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .baco_enter = smu_v13_0_baco_enter, .baco_exit = smu_v13_0_baco_exit, .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported, - .mode1_reset = smu_v13_0_mode1_reset, + .mode1_reset = smu_v13_0_7_mode1_reset, .set_mp1_state = smu_v13_0_7_set_mp1_state, .set_df_cstate = smu_v13_0_7_set_df_cstate, .gpo_control = smu_v13_0_gpo_control, @@ -2814,5 +2855,5 @@ void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu) smu->pwr_src_map = smu_v13_0_7_pwr_src_map; smu->workload_map = smu_v13_0_7_workload_map; smu->smc_driver_if_version = SMU13_0_7_DRIVER_IF_VERSION; - smu_v13_0_init_msg_ctl(smu, smu_v13_0_7_message_map); + smu_v13_0_7_init_msg_ctl(smu); } From d76c66c6ad83994181967d7427385aab4c009ae0 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Thu, 22 Jan 2026 18:04:01 +0800 Subject: [PATCH 26/49] drm/amd/pm: send unload command to smu during modprobe -r amdgpu Send unload command to smu during modprobe -r amdgpu for smu 13/14. 1. This can fix the high voltage/temperatue issue after driver is unloaded. 2. Reloading driver could fail but with the debug port based mode1 reset during driver is reloaded, it is good and safe. Signed-off-by: Kenneth Feng Reviewed-by: Yang Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 7 +++---- drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 1 - drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 8 +------- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 975822141381..0a0109be4d06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4652,9 +4652,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, dev_info(adev->dev, "Pending hive reset.\n"); amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_MINIMAL_XGMI); - } else if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && - !amdgpu_device_has_display_hardware(adev)) { - r = psp_gpu_reset(adev); } else { tmp = amdgpu_reset_method; /* It should do a default reset when loading or reloading the driver, diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 9f52b7b24198..18ece5c714c5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -810,7 +810,7 @@ static int smu_early_init(struct amdgpu_ip_block *ip_block) smu->adev = adev; smu->pm_enabled = !!amdgpu_dpm; smu->is_apu = false; - smu->smu_baco.state = SMU_BACO_STATE_NONE; + smu->smu_baco.state = SMU_BACO_STATE_EXIT; smu->smu_baco.platform_support = false; smu->smu_baco.maco_support = false; smu->user_dpm_profile.fan_mode = -1; @@ -2120,9 +2120,8 @@ static int smu_reset_mp1_state(struct smu_context *smu) int ret = 0; if ((!adev->in_runpm) && (!adev->in_suspend) && - (!amdgpu_in_reset(adev)) && amdgpu_ip_version(adev, MP1_HWIP, 0) == - IP_VERSION(13, 0, 10) && - !amdgpu_device_has_display_hardware(adev)) + (!amdgpu_in_reset(adev)) && !smu->is_apu && + amdgpu_ip_version(adev, MP1_HWIP, 0) >= IP_VERSION(13, 0, 0)) ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD); return ret; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 512493a8452b..a6303d093c50 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -536,7 +536,6 @@ enum smu_reset_mode { enum smu_baco_state { SMU_BACO_STATE_ENTER = 0, SMU_BACO_STATE_EXIT, - SMU_BACO_STATE_NONE, }; struct smu_baco_context { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 784a1af46527..468d51f5f918 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2768,13 +2768,7 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu, switch (mp1_state) { case PP_MP1_STATE_UNLOAD: - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_PrepareMp1ForUnload, - 0x55, NULL); - - if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) - ret = smu_v13_0_disable_pmfw_state(smu); - + ret = smu_cmn_set_mp1_state(smu, mp1_state); break; default: /* Ignore others */ From e98bb71e246cd18c9718aba70718e845b6d134e8 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Mon, 24 Nov 2025 04:40:21 +0000 Subject: [PATCH 27/49] drm/amdgpu: Load TA ucode for PSP 15_0_0 TOC and TA both are required Signed-off-by: Pratik Vishwakarma Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/psp_v15_0.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c index 3aca293e2f0c..723ddae17644 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c @@ -45,6 +45,10 @@ static int psp_v15_0_0_init_microcode(struct psp_context *psp) if (err) return err; + err = psp_init_ta_microcode(psp, ucode_prefix); + if (err) + return err; + return 0; } From 5cc934e089fd70f69e089b0620a83386c99fbcf8 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Wed, 28 Jan 2026 03:52:03 +0000 Subject: [PATCH 28/49] drm/amd/swsmu: Add new param regs for SMU15 Some SMU messages have changed to multi reg read/write Initialize during smu_early_init Signed-off-by: Pratik Vishwakarma Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index c3f22844ba2f..d58b0bc2bf78 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -52,6 +52,12 @@ #define mmMP1_SMN_C2PMSG_32 0x0060 #define mmMP1_SMN_C2PMSG_32_BASE_IDX 1 +#define mmMP1_SMN_C2PMSG_33 0x0061 +#define mmMP1_SMN_C2PMSG_33_BASE_IDX 1 + +#define mmMP1_SMN_C2PMSG_34 0x0062 +#define mmMP1_SMN_C2PMSG_34_BASE_IDX 1 + /* MALLPowerController message arguments (Defines for the Cache mode control) */ #define SMU_MALL_PMFW_CONTROL 0 #define SMU_MALL_DRIVER_CONTROL 1 @@ -1347,7 +1353,9 @@ static void smu_v15_0_0_init_msg_ctl(struct smu_context *smu) ctl->config.msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_30); ctl->config.resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_31); ctl->config.arg_regs[0] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_32); - ctl->config.num_arg_regs = 1; + ctl->config.arg_regs[1] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_33); + ctl->config.arg_regs[2] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_34); + ctl->config.num_arg_regs = 3; ctl->ops = &smu_msg_v1_ops; ctl->default_timeout = adev->usec_timeout * 20; ctl->message_map = smu_v15_0_0_message_map; From ce1598f018ef7fd65f6e6a5b36a34dbf71aef6c8 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Thu, 8 Jan 2026 09:01:02 +0000 Subject: [PATCH 29/49] drm/amdgpu: Add support for update_table for SMU15 Add update_table for SMU 15_0_0 Signed-off-by: Pratik Vishwakarma Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h | 5 ++ .../gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h index 14e8d8c7a80a..af87c31ca9a4 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h @@ -241,5 +241,10 @@ int smu_v15_0_enable_thermal_alert(struct smu_context *smu); int smu_v15_0_disable_thermal_alert(struct smu_context *smu); +int smu_v15_0_0_update_table(struct smu_context *smu, + enum smu_table_id table_index, + int argument, void *table_data, + bool drv2smu); + #endif #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c index a2854d528bab..d7a4d5d6cc8d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c @@ -1726,6 +1726,64 @@ int smu_v15_0_set_gfx_power_up_by_imu(struct smu_context *smu) return ret; } +int smu_v15_0_0_update_table(struct smu_context *smu, + enum smu_table_id table_index, + int argument, + void *table_data, + bool drv2smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct amdgpu_device *adev = smu->adev; + struct smu_table *table = &smu_table->driver_table; + int table_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_TABLE, + table_index); + uint64_t address; + uint32_t table_size; + int ret; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0) + return -EINVAL; + + table_size = smu_table->tables[table_index].size; + + if (drv2smu) { + memcpy(table->cpu_addr, table_data, table_size); + /* + * Flush hdp cache: to guard the content seen by + * GPU is consitent with CPU. + */ + amdgpu_hdp_flush(adev, NULL); + } + + address = table->mc_address; + + struct smu_msg_args args = { + .msg = drv2smu ? + SMU_MSG_TransferTableDram2Smu : + SMU_MSG_TransferTableSmu2Dram, + .num_args = 3, + .num_out_args = 0, + }; + + args.args[0] = table_id; + args.args[1] = (uint32_t)lower_32_bits(address); + args.args[2] = (uint32_t)upper_32_bits(address); + + ret = ctl->ops->send_msg(ctl, &args); + + if (ret) + return ret; + + if (!drv2smu) { + amdgpu_hdp_invalidate(adev, NULL); + memcpy(table_data, table->cpu_addr, table_size); + } + + return 0; +} + int smu_v15_0_set_default_dpm_tables(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; From a0562828d14410bc9b63c80ffb770e1ca7a7b27d Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Thu, 8 Jan 2026 09:05:30 +0000 Subject: [PATCH 30/49] drm/admgpu: Update metrics_table for SMU15 Use multi param based get op for metrics_table Signed-off-by: Pratik Vishwakarma Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index d58b0bc2bf78..b42d56f7e621 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -246,6 +246,36 @@ static int smu_v15_0_0_system_features_control(struct smu_context *smu, bool en) return ret; } +static int smu_v15_0_0_get_metrics_table(struct smu_context *smu, + void *metrics_table, + bool bypass_cache) +{ + struct smu_table_context *smu_table = &smu->smu_table; + uint32_t table_size = + smu_table->tables[SMU_TABLE_SMU_METRICS].size; + int ret; + + if (bypass_cache || + !smu_table->metrics_time || + time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) { + ret = smu_v15_0_0_update_table(smu, + SMU_TABLE_SMU_METRICS, + 0, + smu_table->metrics_table, + false); + if (ret) { + dev_info(smu->adev->dev, "Failed to export SMU15_0_0 metrics table!\n"); + return ret; + } + smu_table->metrics_time = jiffies; + } + + if (metrics_table) + memcpy(metrics_table, smu_table->metrics_table, table_size); + + return 0; +} + static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) @@ -255,7 +285,7 @@ static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu, SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; - ret = smu_cmn_get_metrics_table(smu, NULL, false); + ret = smu_v15_0_0_get_metrics_table(smu, NULL, false); if (ret) return ret; @@ -530,7 +560,7 @@ static ssize_t smu_v15_0_0_get_gpu_metrics(struct smu_context *smu, SmuMetrics_t metrics; int ret = 0; - ret = smu_cmn_get_metrics_table(smu, &metrics, true); + ret = smu_v15_0_0_get_metrics_table(smu, &metrics, false); if (ret) return ret; From f4011253c2287dab6517839c7f7ff8d178400bdb Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Thu, 8 Jan 2026 08:46:53 +0000 Subject: [PATCH 31/49] drm/amdgpu: Fix set_default_dpm_tables Use smu_v15_0_0_update_table instead of common api Signed-off-by: Pratik Vishwakarma Acked-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c index d7a4d5d6cc8d..37fe4c1bdbd9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c @@ -1788,7 +1788,7 @@ int smu_v15_0_set_default_dpm_tables(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; - return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, + return smu_v15_0_0_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); } From 4d632161e921b44c0b65561e26c6d74ae0dd5e0b Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Thu, 8 Jan 2026 08:49:06 +0000 Subject: [PATCH 32/49] drm/amdgpu: Fix is_dpm_running Use multi args for get_enabled_mask to fix is_dpm_running Signed-off-by: Pratik Vishwakarma Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index b42d56f7e621..c1ce603fcdd1 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -479,12 +479,36 @@ static int smu_v15_0_0_read_sensor(struct smu_context *smu, return ret; } +static int smu_v15_0_0_get_enabled_mask(struct smu_context *smu, + struct smu_feature_bits *feature_mask) +{ + int ret; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + if (!feature_mask) + return -EINVAL; + + struct smu_msg_args args = { + .msg = SMU_MSG_GetEnabledSmuFeatures, + .num_args = 0, + .num_out_args = 2, + }; + + ret = ctl->ops->send_msg(ctl, &args); + + if (!ret) + smu_feature_bits_from_arr32(feature_mask, args.out_args, + SMU_FEATURE_NUM_DEFAULT); + + return ret; +} + static bool smu_v15_0_0_is_dpm_running(struct smu_context *smu) { int ret = 0; struct smu_feature_bits feature_enabled; - ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); + ret = smu_v15_0_0_get_enabled_mask(smu, &feature_enabled); if (ret) return false; @@ -1356,7 +1380,7 @@ static const struct pptable_funcs smu_v15_0_0_ppt_funcs = { .is_dpm_running = smu_v15_0_0_is_dpm_running, .set_watermarks_table = smu_v15_0_0_set_watermarks_table, .get_gpu_metrics = smu_v15_0_0_get_gpu_metrics, - .get_enabled_mask = smu_cmn_get_enabled_mask, + .get_enabled_mask = smu_v15_0_0_get_enabled_mask, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_driver_table_location = smu_v15_0_set_driver_table_location, .gfx_off_control = smu_v15_0_gfx_off_control, From c6948604eba672b63ff82d70f39238f4288e9e21 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Fri, 9 Jan 2026 12:15:47 +0000 Subject: [PATCH 33/49] drm/amdgpu: Drop unsupported function drop set_driver_table_location Signed-off-by: Pratik Vishwakarma Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index c1ce603fcdd1..5260de5344ae 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -1382,7 +1382,6 @@ static const struct pptable_funcs smu_v15_0_0_ppt_funcs = { .get_gpu_metrics = smu_v15_0_0_get_gpu_metrics, .get_enabled_mask = smu_v15_0_0_get_enabled_mask, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, - .set_driver_table_location = smu_v15_0_set_driver_table_location, .gfx_off_control = smu_v15_0_gfx_off_control, .mode2_reset = smu_v15_0_0_mode2_reset, .get_dpm_ultimate_freq = smu_v15_0_common_get_dpm_ultimate_freq, From 782baa76ee46a9772b76b5df6d96e4645e362f07 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Wed, 28 Jan 2026 10:03:18 +0000 Subject: [PATCH 34/49] drm/amd: Drop MALL Not supported on SMU 15_0_0 Signed-off-by: Pratik Vishwakarma Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index 5260de5344ae..72a78fc5c827 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -58,19 +58,6 @@ #define mmMP1_SMN_C2PMSG_34 0x0062 #define mmMP1_SMN_C2PMSG_34_BASE_IDX 1 -/* MALLPowerController message arguments (Defines for the Cache mode control) */ -#define SMU_MALL_PMFW_CONTROL 0 -#define SMU_MALL_DRIVER_CONTROL 1 - -/* - * MALLPowerState message arguments - * (Defines for the Allocate/Release Cache mode if in driver mode) - */ -#define SMU_MALL_EXIT_PG 0 -#define SMU_MALL_ENTER_PG 1 - -#define SMU_MALL_PG_CONFIG_DEFAULT SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON - #define SMU_15_0_UMD_PSTATE_GFXCLK 700 #define SMU_15_0_UMD_PSTATE_SOCCLK 678 #define SMU_15_0_UMD_PSTATE_FCLK 1800 From 39a96f126d43e504be54230ff13834277b543802 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Wed, 28 Jan 2026 10:10:36 +0000 Subject: [PATCH 35/49] drm/amdgpu: enable mode2 reset for SMU IP v15.0.0 Set the default reset method to mode2 for SMU 15.0.0. Signed-off-by: Kanala Ramalingeswara Reddy Signed-off-by: Pratik Vishwakarma Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc21.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index d9cc649d81ad..79d132fc8ca9 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -422,6 +422,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev) case IP_VERSION(14, 0, 1): case IP_VERSION(14, 0, 4): case IP_VERSION(14, 0, 5): + case IP_VERSION(15, 0, 0): return AMD_RESET_METHOD_MODE2; default: if (amdgpu_dpm_is_baco_supported(adev)) From 33ed922d24d0c73bdb51b2ddf8f2de8b42ffb015 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Wed, 28 Jan 2026 10:12:44 +0000 Subject: [PATCH 36/49] drm/amd: Add CG/PG flags for GC 11.5.4 Enable GFXOff for GC 11.5.4 Signed-off-by: Pratik Vishwakarma Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc21.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index 79d132fc8ca9..8122a5cacf07 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -839,9 +839,28 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) break; case IP_VERSION(11, 5, 4): adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG | - AMD_CG_SUPPORT_JPEG_MGCG; + AMD_CG_SUPPORT_JPEG_MGCG | + AMD_CG_SUPPORT_GFX_CGCG | + AMD_CG_SUPPORT_GFX_CGLS | + AMD_CG_SUPPORT_GFX_MGCG | + AMD_CG_SUPPORT_GFX_FGCG | + AMD_CG_SUPPORT_REPEATER_FGCG | + AMD_CG_SUPPORT_GFX_PERF_CLK | + AMD_CG_SUPPORT_GFX_3D_CGCG | + AMD_CG_SUPPORT_GFX_3D_CGLS | + AMD_CG_SUPPORT_MC_MGCG | + AMD_CG_SUPPORT_MC_LS | + AMD_CG_SUPPORT_HDP_LS | + AMD_CG_SUPPORT_HDP_DS | + AMD_CG_SUPPORT_HDP_SD | + AMD_CG_SUPPORT_ATHUB_MGCG | + AMD_CG_SUPPORT_ATHUB_LS | + AMD_CG_SUPPORT_IH_CG | + AMD_CG_SUPPORT_BIF_MGCG | + AMD_CG_SUPPORT_BIF_LS; adev->pg_flags = AMD_PG_SUPPORT_VCN | - AMD_PG_SUPPORT_JPEG; + AMD_PG_SUPPORT_JPEG | + AMD_PG_SUPPORT_GFX_PG; adev->external_rev_id = adev->rev_id + 0x1; break; default: From cde3894904cf7820e8518f9df716ba50e91513fd Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Wed, 4 Feb 2026 02:30:42 +0000 Subject: [PATCH 37/49] drm/amd/smu: Fix User mode stable P-states SMU15 SMU 15_0_0 exports only soft limits for CLKs Use correct messages Signed-off-by: Pratik Vishwakarma Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index 72a78fc5c827..4dc8f0095713 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -1026,26 +1026,21 @@ static int smu_v15_0_0_set_soft_freq_limited_range(struct smu_context *smu, switch (clk_type) { case SMU_GFXCLK: case SMU_SCLK: - msg_set_min = SMU_MSG_SetHardMinGfxClk; + msg_set_min = SMU_MSG_SetSoftMinGfxclk; msg_set_max = SMU_MSG_SetSoftMaxGfxClk; break; case SMU_FCLK: - msg_set_min = SMU_MSG_SetHardMinFclkByFreq; + msg_set_min = SMU_MSG_SetSoftMinFclk; msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; break; case SMU_SOCCLK: - msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; + msg_set_min = SMU_MSG_SetSoftMinSocclkByFreq; msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; break; case SMU_VCLK: case SMU_DCLK: - msg_set_min = SMU_MSG_SetHardMinVcn0; - msg_set_max = SMU_MSG_SetSoftMaxVcn0; - break; - case SMU_VCLK1: - case SMU_DCLK1: - msg_set_min = SMU_MSG_SetHardMinVcn1; - msg_set_max = SMU_MSG_SetSoftMaxVcn1; + msg_set_min = SMU_MSG_SetSoftMinVcn; + msg_set_max = SMU_MSG_SetSoftMaxVcn; break; default: return -EINVAL; From 3ee1c72606bd2842f0f377fd4b118362af0323ae Mon Sep 17 00:00:00 2001 From: Ce Sun Date: Tue, 10 Feb 2026 15:32:01 +0800 Subject: [PATCH 38/49] drm/amdgpu: Adjust usleep_range in fence wait Tune the sleep interval in the PSP fence wait loop from 10-100us to 60-100us.This adjustment results in an overall wait window of 1.2s (60us * 20000 iterations) to 2 seconds (100us * 20000 iterations), which guarantees that we can retrieve the correct fence value Signed-off-by: Ce Sun Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index b0540b009e84..5eeea965032a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -735,7 +735,7 @@ psp_cmd_submit_buf(struct psp_context *psp, ras_intr = amdgpu_ras_intr_triggered(); if (ras_intr) break; - usleep_range(10, 100); + usleep_range(60, 100); amdgpu_device_invalidate_hdp(psp->adev, NULL); } From 044f8d3b1fac6ac89c560f61415000e6bdab3a03 Mon Sep 17 00:00:00 2001 From: Gangliang Xie Date: Mon, 9 Feb 2026 17:32:00 +0800 Subject: [PATCH 39/49] drm/amdgpu: return when ras table checksum is error end the function flow when ras table checksum is error Signed-off-by: Gangliang Xie Reviewed-by: Tao Zhou Reviewed-by: Kent Russell Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index 2c5d7f87e593..6fba9d5b29ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -1701,10 +1701,12 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control) } res = __verify_ras_table_checksum(control); - if (res) + if (res) { dev_err(adev->dev, "RAS table incorrect checksum or error:%d\n", res); + return -EINVAL; + } /* Warn if we are at 90% of the threshold or above */ From 9aca641143cec1b25e76f54fc49187b17393c12f Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Fri, 6 Feb 2026 19:13:23 +0530 Subject: [PATCH 40/49] drm/amdgpu: Move xgmi status to interface header These definitions are used by user APIs. Signed-off-by: Lijo Lazar Reviewed-by: Asad Kamal Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 6 ++---- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 5 +++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 9e32f343097e..0ca6fa40a87c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -42,8 +42,6 @@ #define XGMI_STATE_DISABLE 0xD1 #define XGMI_STATE_LS0 0x81 -#define XGMI_LINK_ACTIVE 1 -#define XGMI_LINK_INACTIVE 0 static DEFINE_MUTEX(xgmi_mutex); @@ -365,9 +363,9 @@ int amdgpu_get_xgmi_link_status(struct amdgpu_device *adev, int global_link_num) return -ENOLINK; if ((xgmi_state_reg_val & 0xFF) == XGMI_STATE_LS0) - return XGMI_LINK_ACTIVE; + return AMDGPU_XGMI_LINK_ACTIVE; - return XGMI_LINK_INACTIVE; + return AMDGPU_XGMI_LINK_INACTIVE; } /** diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 9fd78fcff15c..6683ffd6aa68 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -1829,4 +1829,9 @@ struct amdgpu_partition_metrics_v1_1 { struct gpu_metrics_attr metrics_attrs[]; }; +enum amdgpu_xgmi_link_status { + AMDGPU_XGMI_LINK_INACTIVE = 0, + AMDGPU_XGMI_LINK_ACTIVE = 1, +}; + #endif From b18fc0ab837381c1a6ef28386602cd888f2d9edf Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 9 Feb 2026 18:54:45 +0100 Subject: [PATCH 41/49] drm/amdgpu: fix sync handling in amdgpu_dma_buf_move_notify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Invalidating a dmabuf will impact other users of the shared BO. In the scenario where process A moves the BO, it needs to inform process B about the move and process B will need to update its page table. The commit fixes a synchronisation bug caused by the use of the ticket: it made amdgpu_vm_handle_moved behave as if updating the page table immediately was correct but in this case it's not. An example is the following scenario, with 2 GPUs and glxgears running on GPU0 and Xorg running on GPU1, on a system where P2P PCI isn't supported: glxgears: export linear buffer from GPU0 and import using GPU1 submit frame rendering to GPU0 submit tiled->linear blit Xorg: copy of linear buffer The sequence of jobs would be: drm_sched_job_run # GPU0, frame rendering drm_sched_job_queue # GPU0, blit drm_sched_job_done # GPU0, frame rendering drm_sched_job_run # GPU0, blit move linear buffer for GPU1 access # amdgpu_dma_buf_move_notify -> update pt # GPU0 It this point the blit job on GPU0 is still running and would likely produce a page fault. Cc: stable@vger.kernel.org Fixes: a448cb003edc ("drm/amdgpu: implement amdgpu_gem_prime_move_notify v2") Signed-off-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index b9c38a4fe546..656c267dbe58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -514,8 +514,15 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach) r = dma_resv_reserve_fences(resv, 2); if (!r) r = amdgpu_vm_clear_freed(adev, vm, NULL); + + /* Don't pass 'ticket' to amdgpu_vm_handle_moved: we want the clear=true + * path to be used otherwise we might update the PT of another process + * while it's using the BO. + * With clear=true, amdgpu_vm_bo_update will sync to command submission + * from the same VM. + */ if (!r) - r = amdgpu_vm_handle_moved(adev, vm, ticket); + r = amdgpu_vm_handle_moved(adev, vm, NULL); if (r && r != -EBUSY) DRM_ERROR("Failed to invalidate VM page tables (%d))\n", From f38bb9b0928638c09fefb26d9d22745bfbfc7586 Mon Sep 17 00:00:00 2001 From: Pratik Vishwakarma Date: Wed, 11 Feb 2026 08:35:30 +0000 Subject: [PATCH 42/49] drm/amd/swsmu: Move IP specific functions Move SMU v15_0_0 specific functions to IP file - smu_v15_0_0_set_default_dpm_tables and - smu_v15_0_0_update_table Signed-off-by: Pratik Vishwakarma Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h | 7 -- .../gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c | 66 ------------------ .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c | 68 ++++++++++++++++++- 3 files changed, 67 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h index af87c31ca9a4..ab4a64f54e79 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h @@ -226,8 +226,6 @@ int smu_v15_0_deep_sleep_control(struct smu_context *smu, int smu_v15_0_set_gfx_power_up_by_imu(struct smu_context *smu); -int smu_v15_0_set_default_dpm_tables(struct smu_context *smu); - int smu_v15_0_get_pptable_from_firmware(struct smu_context *smu, void **table, uint32_t *size, @@ -241,10 +239,5 @@ int smu_v15_0_enable_thermal_alert(struct smu_context *smu); int smu_v15_0_disable_thermal_alert(struct smu_context *smu); -int smu_v15_0_0_update_table(struct smu_context *smu, - enum smu_table_id table_index, - int argument, void *table_data, - bool drv2smu); - #endif #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c index 37fe4c1bdbd9..a2f446d38be8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c @@ -1726,72 +1726,6 @@ int smu_v15_0_set_gfx_power_up_by_imu(struct smu_context *smu) return ret; } -int smu_v15_0_0_update_table(struct smu_context *smu, - enum smu_table_id table_index, - int argument, - void *table_data, - bool drv2smu) -{ - struct smu_table_context *smu_table = &smu->smu_table; - struct amdgpu_device *adev = smu->adev; - struct smu_table *table = &smu_table->driver_table; - int table_id = smu_cmn_to_asic_specific_index(smu, - CMN2ASIC_MAPPING_TABLE, - table_index); - uint64_t address; - uint32_t table_size; - int ret; - struct smu_msg_ctl *ctl = &smu->msg_ctl; - - if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0) - return -EINVAL; - - table_size = smu_table->tables[table_index].size; - - if (drv2smu) { - memcpy(table->cpu_addr, table_data, table_size); - /* - * Flush hdp cache: to guard the content seen by - * GPU is consitent with CPU. - */ - amdgpu_hdp_flush(adev, NULL); - } - - address = table->mc_address; - - struct smu_msg_args args = { - .msg = drv2smu ? - SMU_MSG_TransferTableDram2Smu : - SMU_MSG_TransferTableSmu2Dram, - .num_args = 3, - .num_out_args = 0, - }; - - args.args[0] = table_id; - args.args[1] = (uint32_t)lower_32_bits(address); - args.args[2] = (uint32_t)upper_32_bits(address); - - ret = ctl->ops->send_msg(ctl, &args); - - if (ret) - return ret; - - if (!drv2smu) { - amdgpu_hdp_invalidate(adev, NULL); - memcpy(table_data, table->cpu_addr, table_size); - } - - return 0; -} - -int smu_v15_0_set_default_dpm_tables(struct smu_context *smu) -{ - struct smu_table_context *smu_table = &smu->smu_table; - - return smu_v15_0_0_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, - smu_table->clocks_table, false); -} - int smu_v15_0_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index 4dc8f0095713..660335d7bda9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -233,6 +233,72 @@ static int smu_v15_0_0_system_features_control(struct smu_context *smu, bool en) return ret; } +static int smu_v15_0_0_update_table(struct smu_context *smu, + enum smu_table_id table_index, + int argument, + void *table_data, + bool drv2smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct amdgpu_device *adev = smu->adev; + struct smu_table *table = &smu_table->driver_table; + int table_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_TABLE, + table_index); + uint64_t address; + uint32_t table_size; + int ret; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0) + return -EINVAL; + + table_size = smu_table->tables[table_index].size; + + if (drv2smu) { + memcpy(table->cpu_addr, table_data, table_size); + /* + * Flush hdp cache: to guard the content seen by + * GPU is consitent with CPU. + */ + amdgpu_hdp_flush(adev, NULL); + } + + address = table->mc_address; + + struct smu_msg_args args = { + .msg = drv2smu ? + SMU_MSG_TransferTableDram2Smu : + SMU_MSG_TransferTableSmu2Dram, + .num_args = 3, + .num_out_args = 0, + }; + + args.args[0] = table_id; + args.args[1] = (uint32_t)lower_32_bits(address); + args.args[2] = (uint32_t)upper_32_bits(address); + + ret = ctl->ops->send_msg(ctl, &args); + + if (ret) + return ret; + + if (!drv2smu) { + amdgpu_hdp_invalidate(adev, NULL); + memcpy(table_data, table->cpu_addr, table_size); + } + + return 0; +} + +static int smu_v15_0_0_set_default_dpm_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + return smu_v15_0_0_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, + smu_table->clocks_table, false); +} + static int smu_v15_0_0_get_metrics_table(struct smu_context *smu, void *metrics_table, bool bypass_cache) @@ -1357,7 +1423,7 @@ static const struct pptable_funcs smu_v15_0_0_ppt_funcs = { .system_features_control = smu_v15_0_0_system_features_control, .dpm_set_vcn_enable = smu_v15_0_set_vcn_enable, .dpm_set_jpeg_enable = smu_v15_0_set_jpeg_enable, - .set_default_dpm_table = smu_v15_0_set_default_dpm_tables, + .set_default_dpm_table = smu_v15_0_0_set_default_dpm_tables, .read_sensor = smu_v15_0_0_read_sensor, .is_dpm_running = smu_v15_0_0_is_dpm_running, .set_watermarks_table = smu_v15_0_0_set_watermarks_table, From 908d318f23d6b5d625bea093c5fc056238cdb7ff Mon Sep 17 00:00:00 2001 From: decce6 Date: Tue, 10 Feb 2026 07:26:00 +0000 Subject: [PATCH 43/49] drm/radeon: Add HAINAN clock adjustment This patch limits the clock speeds of the AMD Radeon R5 M420 GPU from 850/1000MHz (core/memory) to 800/950 MHz, making it work stably. This patch is for radeon. Signed-off-by: decce6 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si_dpm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 9deb91970d4d..f12227145ef0 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2925,6 +2925,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, max_sclk = 60000; max_mclk = 80000; } + if ((rdev->pdev->device == 0x666f) && + (rdev->pdev->revision == 0x00)) { + max_sclk = 80000; + max_mclk = 95000; + } } else if (rdev->family == CHIP_OLAND) { if ((rdev->pdev->revision == 0xC7) || (rdev->pdev->revision == 0x80) || From 49fe2c57bdc0acff9d2551ae337270b6fd8119d9 Mon Sep 17 00:00:00 2001 From: decce6 Date: Tue, 10 Feb 2026 07:24:01 +0000 Subject: [PATCH 44/49] drm/amdgpu: Add HAINAN clock adjustment This patch limits the clock speeds of the AMD Radeon R5 M420 GPU from 850/1000MHz (core/memory) to 800/950 MHz, making it work stably. This patch is for amdgpu. Signed-off-by: decce6 Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index 0f8f69481f5b..d8959e0f109c 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -3464,6 +3464,11 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, max_sclk = 60000; max_mclk = 80000; } + if ((adev->pdev->device == 0x666f) && + (adev->pdev->revision == 0x00)) { + max_sclk = 80000; + max_mclk = 95000; + } } else if (adev->asic_type == CHIP_OLAND) { if ((adev->pdev->revision == 0xC7) || (adev->pdev->revision == 0x80) || From 57d00816c6a9c152f01b65bb7b3662f4d03ccd09 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 10 Feb 2026 16:53:08 -0500 Subject: [PATCH 45/49] drm/amdgpu: set family for GC 11.5.4 Set the family for GC 11.5.4 Fixes: 47ae1f938d12 ("drm/amdgpu: add support for GC IP version 11.5.4") Cc: Tim Huang Cc: Pratik Vishwakarma Cc: Roman Li Reviewed-by: Tim Huang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 4 +++- include/uapi/drm/amdgpu_drm.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 41e63c286912..4143a25a498b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -2988,9 +2988,11 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) case IP_VERSION(11, 5, 1): case IP_VERSION(11, 5, 2): case IP_VERSION(11, 5, 3): - case IP_VERSION(11, 5, 4): adev->family = AMDGPU_FAMILY_GC_11_5_0; break; + case IP_VERSION(11, 5, 4): + adev->family = AMDGPU_FAMILY_GC_11_5_4; + break; case IP_VERSION(12, 0, 0): case IP_VERSION(12, 0, 1): case IP_VERSION(12, 1, 0): diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 1d34daa0ebcd..ebbd861ef0bc 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1667,6 +1667,7 @@ struct drm_amdgpu_info_uq_metadata { #define AMDGPU_FAMILY_GC_10_3_6 149 /* GC 10.3.6 */ #define AMDGPU_FAMILY_GC_10_3_7 151 /* GC 10.3.7 */ #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ +#define AMDGPU_FAMILY_GC_11_5_4 154 /* GC 11.5.4 */ #define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ #if defined(__cplusplus) From 5e9aec4ea350db868e38f901fa19bb1d70c7a6ed Mon Sep 17 00:00:00 2001 From: Mangesh Gadre Date: Tue, 27 Jan 2026 18:00:59 +0800 Subject: [PATCH 46/49] drm/amdgpu:Add psp v13_0_15 ip block Add support for psp v13_0_15 ip block Signed-off-by: Mangesh Gadre Reviewed-by: Asad Kamal Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 5 ++++- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 15 +++++++++++---- drivers/gpu/drm/amd/amdgpu/soc15.c | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 4143a25a498b..fc8c1f36be58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -2164,6 +2164,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev) case IP_VERSION(13, 0, 11): case IP_VERSION(13, 0, 12): case IP_VERSION(13, 0, 14): + case IP_VERSION(13, 0, 15): case IP_VERSION(14, 0, 0): case IP_VERSION(14, 0, 1): case IP_VERSION(14, 0, 4): diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 5eeea965032a..a7c7b378c696 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -148,6 +148,7 @@ static int psp_init_sriov_microcode(struct psp_context *psp) break; case IP_VERSION(13, 0, 6): case IP_VERSION(13, 0, 14): + case IP_VERSION(13, 0, 15): ret = psp_init_cap_microcode(psp, ucode_prefix); ret &= psp_init_ta_microcode(psp, ucode_prefix); break; @@ -219,6 +220,7 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block) psp->autoload_supported = false; break; case IP_VERSION(13, 0, 12): + case IP_VERSION(13, 0, 15): psp_v13_0_set_psp_funcs(psp); psp->autoload_supported = false; adev->psp.sup_ifwi_up = !amdgpu_sriov_vf(adev); @@ -383,7 +385,8 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev, if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) return false; db_header_pos = adev->gmc.mc_vram_size - PSP_RUNTIME_DB_OFFSET; diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index af4a7d7c4abd..d1e1a4369521 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -57,6 +57,8 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_12_sos.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_12_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_14_sos.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_14_ta.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_15_sos.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_15_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_14_0_0_toc.bin"); MODULE_FIRMWARE("amdgpu/psp_14_0_0_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_14_0_1_toc.bin"); @@ -121,6 +123,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp) case IP_VERSION(13, 0, 10): case IP_VERSION(13, 0, 12): case IP_VERSION(13, 0, 14): + case IP_VERSION(13, 0, 15): err = psp_init_sos_microcode(psp, ucode_prefix); if (err) return err; @@ -156,7 +159,8 @@ static void psp_v13_0_bootloader_print_status(struct psp_context *psp, if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) { + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) { at = 0; for_each_inst(i, adev->aid_mask) { bl_status_reg = @@ -202,7 +206,8 @@ static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) retry_cnt = ((amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14))) ? + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15))) ? PSP_VMBX_POLLING_LIMIT : 10; /* Wait for bootloader to signify that it is ready having bit 31 of @@ -232,7 +237,8 @@ static int psp_v13_0_wait_for_bootloader_steady_state(struct psp_context *psp) if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) { + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) { ret = psp_v13_0_wait_for_vmbx_ready(psp); if (ret) amdgpu_ras_query_boot_status(adev, 4); @@ -872,7 +878,8 @@ static bool psp_v13_0_get_ras_capability(struct psp_context *psp) if ((amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) && + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) && (!(adev->flags & AMD_IS_APU))) { reg_data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_127); adev->ras_hw_enabled = (reg_data & GENMASK_ULL(23, 0)); diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 54b14751fd7a..4e037a6978f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -1478,7 +1478,8 @@ static void soc15_common_get_clockgating_state(struct amdgpu_ip_block *ip_block, if ((amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 2)) && (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6)) && (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 12)) && - (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 14))) { + (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 14)) && + (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 15))) { /* AMD_CG_SUPPORT_DRM_MGCG */ data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); if (!(data & 0x01000000)) From 8446c747370ab31a3ae0177227f0de3e65c8815c Mon Sep 17 00:00:00 2001 From: Siwei He Date: Mon, 9 Feb 2026 16:13:20 -0500 Subject: [PATCH 47/49] drm/amdkfd: Fix APU to use GTT, not VRAM for MQD Add a check in mqd_on_vram. If the device prefers GTT, it returns false Fixes: d4a814f400d4 ("drm/amdkfd: Move gfx9.4.3 and gfx 9.5 MQD to HBM") Signed-off-by: Siwei He Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 3 +++ 1 file changed, 3 insertions(+) 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 dcf4bbfa641b..5578c241b7d0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -111,6 +111,9 @@ static void set_priority(struct v9_mqd *m, struct queue_properties *q) static bool mqd_on_vram(struct amdgpu_device *adev) { + if (adev->apu_prefer_gtt) + return false; + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { case IP_VERSION(9, 4, 3): case IP_VERSION(9, 5, 0): From abde491143e4e12eecc41337910aace4e8d59603 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 6 Feb 2026 20:49:23 +0530 Subject: [PATCH 48/49] drm/amd/display: Fix out-of-bounds stream encoder index v3 eng_id can be negative and that stream_enc_regs[] can be indexed out of bounds. eng_id is used directly as an index into stream_enc_regs[], which has only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can access memory past the end of the array. Add a bounds check using ARRAY_SIZE() before using eng_id as an index. The unsigned cast also rejects negative values. This avoids out-of-bounds access. Fixes the below smatch error: dcn*_resource.c: stream_encoder_create() may index stream_enc_regs[eng_id] out of bounds (size 5). drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c 1246 static struct stream_encoder *dcn35_stream_encoder_create( 1247 enum engine_id eng_id, 1248 struct dc_context *ctx) 1249 { ... 1255 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ 1257 if (eng_id <= ENGINE_ID_DIGF) { ENGINE_ID_DIGF is 5. should <= be dc_bios, 1283 eng_id, vpg, afmt, --> 1284 &stream_enc_regs[eng_id], ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array. ... 1287 return &enc1->base; 1288 } v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast v3: The compiler already knows how to compare the two values, so the cast (int) is not needed. (Roman) Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351") Reported-by: Dan Carpenter Cc: Harry Wentland Cc: Mario Limonciello Cc: Alex Hung Cc: Aurabindo Pillai Cc: ChiaHsuan Chung Cc: Roman Li Signed-off-by: Srinivasan Shanmugam Reviewed-by: Roman Li Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++---- .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++---- .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++---- .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++---- .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++---- .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c index a8283f21008e..3ae787a377b1 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c @@ -1230,12 +1230,12 @@ static struct stream_encoder *dcn315_stream_encoder_create( /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; + vpg_inst = eng_id; + afmt_inst = eng_id; + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c index 4da0e9320159..4b8668458f03 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c @@ -1223,12 +1223,12 @@ static struct stream_encoder *dcn316_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; + vpg_inst = eng_id; + afmt_inst = eng_id; + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c index d3b92c61b7ad..a55078458ba5 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c @@ -1211,12 +1211,12 @@ static struct stream_encoder *dcn32_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; + vpg_inst = eng_id; + afmt_inst = eng_id; + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); vpg = dcn32_vpg_create(ctx, vpg_inst); afmt = dcn32_afmt_create(ctx, afmt_inst); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c index d08691ea27ea..188c3f24f110 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c @@ -1192,12 +1192,12 @@ static struct stream_encoder *dcn321_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; + vpg_inst = eng_id; + afmt_inst = eng_id; + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); vpg = dcn321_vpg_create(ctx, vpg_inst); afmt = dcn321_afmt_create(ctx, afmt_inst); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 945da8cffada..5ea805fcff48 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -1274,12 +1274,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; + vpg_inst = eng_id; + afmt_inst = eng_id; + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index e660889904a9..424b52e2dd7b 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -1254,12 +1254,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; + vpg_inst = eng_id; + afmt_inst = eng_id; + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); From fd1fa48b935f22c7d99713bf33846e14a6bb6ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 20 Jan 2026 12:57:21 +0100 Subject: [PATCH 49/49] drm/amdgpu: lock both VM and BO in amdgpu_gem_object_open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VM was not locked in the past since we initially only cleared the linked list element and not added it to any VM state. But this has changed quite some time ago, we just never realized this problem because the VM state lock was masking it. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 19 +++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 22 ++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 10 +++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 ++ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 00ea69baa126..6893d175f7c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -878,6 +878,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, struct amdgpu_bo *bo[2] = {NULL, NULL}; struct amdgpu_bo_va *bo_va; bool same_hive = false; + struct drm_exec exec; int i, ret; if (!va) { @@ -958,19 +959,25 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, goto unwind; } - /* Add BO to VM internal data structures */ - ret = amdgpu_bo_reserve(bo[i], false); - if (ret) { - pr_debug("Unable to reserve BO during memory attach"); - goto unwind; + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); + drm_exec_until_all_locked(&exec) { + ret = amdgpu_vm_lock_pd(vm, &exec, 0); + drm_exec_retry_on_contention(&exec); + if (unlikely(ret)) + goto unwind; + ret = drm_exec_lock_obj(&exec, &bo[i]->tbo.base); + drm_exec_retry_on_contention(&exec); + if (unlikely(ret)) + goto unwind; } + bo_va = amdgpu_vm_bo_find(vm, bo[i]); if (!bo_va) bo_va = amdgpu_vm_bo_add(adev, vm, bo[i]); else ++bo_va->ref_count; attachment[i]->bo_va = bo_va; - amdgpu_bo_unreserve(bo[i]); + drm_exec_fini(&exec); if (unlikely(!attachment[i]->bo_va)) { ret = -ENOMEM; pr_err("Failed to add BO object to VM. ret == %d\n", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 5f9fa2140f09..5c90de58cc28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -232,6 +232,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_va *bo_va; struct mm_struct *mm; + struct drm_exec exec; int r; mm = amdgpu_ttm_tt_get_usermm(abo->tbo.ttm); @@ -242,9 +243,18 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, !amdgpu_vm_is_bo_always_valid(vm, abo)) return -EPERM; - r = amdgpu_bo_reserve(abo, false); - if (r) - return r; + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); + drm_exec_until_all_locked(&exec) { + r = drm_exec_prepare_obj(&exec, &abo->tbo.base, 1); + drm_exec_retry_on_contention(&exec); + if (unlikely(r)) + goto out_unlock; + + r = amdgpu_vm_lock_pd(vm, &exec, 0); + drm_exec_retry_on_contention(&exec); + if (unlikely(r)) + goto out_unlock; + } amdgpu_vm_bo_update_shared(abo); bo_va = amdgpu_vm_bo_find(vm, abo); @@ -260,8 +270,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, amdgpu_bo_unreserve(abo); return r; } - - amdgpu_bo_unreserve(abo); + drm_exec_fini(&exec); /* Validate and add eviction fence to DMABuf imports with dynamic * attachment in compute VMs. Re-validation will be done by @@ -294,7 +303,10 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, } } mutex_unlock(&vm->process_info->lock); + return r; +out_unlock: + drm_exec_fini(&exec); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1878e0faa722..f69332eed051 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1445,6 +1445,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) { struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_fpriv *fpriv; + struct drm_exec exec; int r, pasid; /* Ensure IB tests are run on ring */ @@ -1484,7 +1485,16 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) if (r) goto error_pasid; + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); + drm_exec_until_all_locked(&exec) { + r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 0); + drm_exec_retry_on_contention(&exec); + if (unlikely(r)) + goto error_vm; + } + fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL); + drm_exec_fini(&exec); if (!fpriv->prt_va) { r = -ENOMEM; goto error_vm; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 31383583fc68..11597224d437 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1735,6 +1735,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, { struct amdgpu_bo_va *bo_va; + amdgpu_vm_assert_locked(vm); + bo_va = kzalloc(sizeof(struct amdgpu_bo_va), GFP_KERNEL); if (bo_va == NULL) { return NULL;