* [PATCH 00/24] DC Patches Aug 17 2026
@ 2026-08-10 21:28 James Lin
2026-08-10 21:28 ` [PATCH 01/24] drm/amd/display: Add CACP ACE curve area debugfs for IGT validation James Lin
` (23 more replies)
0 siblings, 24 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen
This DC patchset brings improvements in multiple areas. In summary, we have:
- Reworked per-DPM derate handling: refactor the per-DPM derate logic,
update derates with default per-DPM values, and move the
soc_and_ip_translator onto the new per-DPM organization
- DCN6 mode-support and UTM work: opt-out for the OutstandingRequests
check, a utm_support capability flag, and a guard against an empty
DCN6 UTM QoS table
- More DMU/DMUB offload: send DPM0 clock values for Z8 retention, allow
DCHVM<->rIOMMU SDP port disconnection on DCN42, and add the DC_BLS
command
- HWSS block-sequence cleanups: move periodic interrupt calculations
to HWSS, drop pipe_ctx from HUBP_WAIT_FOR_DCC_META_PROP, use mpcc_id
instead of the hubp instance, and add a wait stream regen event
- DML updates: unify CalculateFlipSchedule logic and relax the frame
size limit for the dcn5/6 core funcs files
- clk_mgr refactor renaming carried DCE clock manager functions for
dcn10, plus a missing-prototype build fix and a static DCN42 SOC BB
struct
- Expanded IGT/KUnit validation: CACP ACE curve area debugfs and cursor
mode tests on disabled CRTCs
- eDP fix to skip teardown while a forced PSR is active
Cc: Daniel Wheeler <daniel.wheeler@amd.com>
Austin Zheng (5):
drm/amd/display: Make Struct In DCN42 SOC BB Header Static
drm/amd/display: Refactor Per-DPM Derate Logic
drm/amd/display: Update Derates And Set Default Per-DPM Derates
drm/amd/display: Unify CalculateFlipSchedule Logic
drm/amd/display: Update soc_and_ip_translator To Use Updated Per-DPM
Derate Organization
Chenyu Chen (1):
drm/amd/display: Add CACP ACE curve area debugfs for IGT validation
Dillon Varone (1):
drm/amd/display: Rename carried dce clock manager functions for dcn10
Ivan Lipski (1):
drm/amd/display: Relax frame size limit for dcn5/6 DML core funcs
files
James Lin (1):
drm/amd/display: Add missing prototype for
amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags
Jun Lei (1):
drm/amd/display: Add opt-out for DCN6 OutstandingRequests mode-support
check
Karthi Kandasamy (1):
drm/amd/display: Skip eDP teardown while forced PSR is active
Ovidiu Bunea (3):
drm/amd/display: Add DC_BLS command
drm/amd/display: Notify DMU to allow DCHVM<->rIOMMU SDP port
disconnection for DCN42
drm/amd/display: Send DPM0 clock values to DMU
Peichen Huang (1):
drm/amd/display: add wait stream regen event
Taimur Hassan (2):
drm/amd/display: [FW Promotion] Release 0.1.71.0
drm/amd/display: Promote DC to 3.2.394
Tom Chung (2):
drm/amd/display: set base.enable in cursor mode tests
drm/amd/display: test native cursor mode on a disabled CRTC
Tomasz Siemek (3):
drm/amd/display: Move periodic interrupt calculations to HWSS
drm/amd/display: Refactor HUBP_WAIT_FOR_DCC_META_PROP to drop pipe_ctx
drm/amd/display: Use mpcc_id instead of hubp instance
Wenjing Liu (2):
drm/amd/display: Add utm_support capability flag
drm/amd/display: Guard against empty DCN6 UTM QoS table
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 68 +++++++
.../amd/display/amdgpu_dm/amdgpu_dm_plane.h | 2 +
.../amdgpu_dm/tests/amdgpu_dm_cursor_test.c | 24 +++
.../display/dc/clk_mgr/dce100/dce_clk_mgr.c | 115 +++++++++++
.../display/dc/clk_mgr/dce100/dce_clk_mgr.h | 8 +-
.../dc/clk_mgr/dce112/dce112_clk_mgr.c | 59 ++++++
.../dc/clk_mgr/dce112/dce112_clk_mgr.h | 4 +-
.../display/dc/clk_mgr/dcn10/dcn10_clk_mgr.c | 14 +-
.../display/dc/clk_mgr/dcn10/dcn10_clk_mgr.h | 12 +-
.../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c | 9 +-
.../display/dc/clk_mgr/dcn10/rv2_clk_mgr.c | 6 +-
.../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 12 +-
.../dc/clk_mgr/dcn201/dcn201_clk_mgr.c | 6 +-
.../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 5 +-
.../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 8 +-
.../display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 8 +-
.../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 10 +-
.../dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 10 +-
.../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 10 +-
.../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 10 +-
.../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 18 +-
.../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 12 +-
.../dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 18 +-
.../display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c | 26 ++-
.../display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h | 5 +
.../dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c | 11 +-
.../display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c | 9 +-
drivers/gpu/drm/amd/display/dc/core/dc.c | 8 +-
.../drm/amd/display/dc/core/dc_hw_sequencer.c | 136 +++++++++----
drivers/gpu/drm/amd/display/dc/dc.h | 3 +-
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 18 ++
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 12 ++
.../gpu/drm/amd/display/dc/dml2_0/Makefile | 8 +
.../dml21/inc/bounding_boxes/dcn42_soc_bb.h | 39 ++--
.../dml21/inc/bounding_boxes/dcn42b_soc_bb.h | 25 ++-
.../dml21/inc/bounding_boxes/dcn4_soc_bb.h | 27 ++-
.../dml21/inc/dml_top_display_cfg_types.h | 1 +
.../dml21/inc/dml_top_soc_parameter_types.h | 44 ++++-
.../src/dml2_core/dml2_core_dcn4_calcs.c | 183 +++++++-----------
.../dml2_core_dcn6_funcs_mode_support.c | 7 +
.../src/dml2_core/dml2_core_shared_types.h | 3 +
.../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 106 +++++++++-
.../src/inc/dml2_internal_shared_types.h | 1 +
.../display/dc/hubbub/dcn35/dcn35_hubbub.c | 7 +
.../amd/display/dc/hwss/dce110/dce110_hwseq.c | 7 +-
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 60 ++----
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 5 +-
.../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 17 +-
.../amd/display/dc/hwss/dcn314/dcn314_hwseq.c | 8 +-
.../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 7 +-
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 24 +--
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 3 +-
.../amd/display/dc/hwss/dcn60/dcn60_hwseq.c | 8 +-
.../drm/amd/display/dc/hwss/hw_sequencer.h | 23 ++-
.../dc/resource/dcn60/dcn60_resource.c | 1 +
.../dcn401/dcn401_soc_and_ip_translator.c | 6 +-
.../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 39 ++++
.../drm/amd/display/modules/inc/mod_power.h | 1 +
58 files changed, 924 insertions(+), 412 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 01/24] drm/amd/display: Add CACP ACE curve area debugfs for IGT validation
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 02/24] drm/amd/display: Move periodic interrupt calculations to HWSS James Lin
` (22 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Chenyu Chen, James Lin
From: Chenyu Chen <chen-yu.chen@amd.com>
[Why]
IGT test cases for CACP need a way to validate that the ACE
(Adaptive Contrast Enhancement) curve responds to the CACP
aggression level. No interface exists to read the resulting
curve back from firmware for automated validation.
[How]
Add a read-only "cacp_ace_curve_area" debugfs node on eDP
connectors that support CACP. It issues a
DMUB_CMD__CACP_GET_ACE_CURVE_AREA command and reports the area
under the ACE PWL curve returned by firmware, which is directly
comparable across CACP levels, so IGT tests can query it per panel.
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index c4b2fc690fd7..1a574f508b8d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -3677,6 +3677,72 @@ DEFINE_DEBUGFS_ATTRIBUTE(ips_residency_cntl_fops, ips_residency_cntl_get,
DEFINE_SHOW_ATTRIBUTE(current_backlight);
DEFINE_SHOW_ATTRIBUTE(target_backlight);
+
+/*
+ * CACP ACE curve area. Read only.
+ * Returns the area under the ACE PWL curve computed by DMUB firmware on
+ * eDP panels that support CACP. The value is in DMU-internal units (PWL
+ * area); it is only meaningful for relative comparison between CACP
+ * levels on the same panel. Level 0 returns the linear baseline (largest).
+ *
+ * Example usage: cat /sys/kernel/debug/dri/0/eDP-1/cacp_ace_curve_area
+ */
+static int cacp_ace_curve_area_show(struct seq_file *m, void *unused)
+{
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
+ struct dc_link *link = aconnector->dc_link;
+ struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev);
+ struct dc *dc;
+ union dmub_rb_cmd cmd;
+ unsigned int panel_inst = 0;
+ bool reallow_idle = false;
+ int ret = 0;
+
+ if (!link || link->type == dc_connection_none)
+ return -ENODEV;
+
+ if (!(link->connector_signal & SIGNAL_TYPE_EDP))
+ return -ENODEV;
+
+ if (!link->panel_config.cacp.cacp_supported)
+ return -EOPNOTSUPP;
+
+ dc = link->ctx->dc;
+
+ if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
+ return -EINVAL;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cacp_get_ace_curve_area.header.type = DMUB_CMD__CACP;
+ cmd.cacp_get_ace_curve_area.header.sub_type = DMUB_CMD__CACP_GET_ACE_CURVE_AREA;
+ cmd.cacp_get_ace_curve_area.header.payload_bytes =
+ sizeof(cmd.cacp_get_ace_curve_area) -
+ sizeof(cmd.cacp_get_ace_curve_area.header);
+ cmd.cacp_get_ace_curve_area.data.in.panel_inst = panel_inst;
+
+ mutex_lock(&adev->dm.dc_lock);
+
+ if (dc->idle_optimizations_allowed) {
+ dc_allow_idle_optimizations(dc, false);
+ reallow_idle = true;
+ }
+
+ if (!dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd,
+ DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) ||
+ cmd.cacp_get_ace_curve_area.header.ret_status)
+ ret = -EIO;
+ else
+ seq_printf(m, "%u\n", cmd.cacp_get_ace_curve_area.data.out.area);
+
+ if (reallow_idle)
+ dc_allow_idle_optimizations(dc, true);
+
+ mutex_unlock(&adev->dm.dc_lock);
+
+ return ret;
+}
+DEFINE_SHOW_ATTRIBUTE(cacp_ace_curve_area);
+
DEFINE_SHOW_ATTRIBUTE(ips_status);
DEFINE_SHOW_ATTRIBUTE(ips_residency);
@@ -3877,6 +3943,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
&disallow_edp_enter_psr_fops);
debugfs_create_file("disallow_edp_enter_replay", 0644, dir, connector,
&disallow_edp_enter_replay_fops);
+ debugfs_create_file("cacp_ace_curve_area", 0444, dir, connector,
+ &cacp_ace_curve_area_fops);
}
for (i = 0; i < ARRAY_SIZE(connector_debugfs_entries); i++) {
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 02/24] drm/amd/display: Move periodic interrupt calculations to HWSS
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
2026-08-10 21:28 ` [PATCH 01/24] drm/amd/display: Add CACP ACE curve area debugfs for IGT validation James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 03/24] drm/amd/display: Add missing prototype for amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags James Lin
` (21 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Tomasz Siemek, Alvin Lee,
James Lin
From: Tomasz Siemek <tomasz.siemek@amd.com>
[why]
Periodic interrupt line calculations depends on stream and pipe state, not
ASIC-specific register programming. Keeping it in the DCN10 implementation
also prevents block-sequence callers from carrying fully resolved
parameters.
We want HWSS block parameters to not include complex structures like
pipe_ctx.
[how]
- Move the vertical interrupt line calculation into common HWSS code.
- Update the periodic interrupt callback.
- Calculate the values before direct or block-sequence execution.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Tomasz Siemek <tomasz.siemek@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +-
.../drm/amd/display/dc/core/dc_hw_sequencer.c | 76 ++++++++++++++++---
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 41 +---------
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 5 +-
.../drm/amd/display/dc/hwss/hw_sequencer.h | 12 +--
5 files changed, 83 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 68f228014305..bc2207d29954 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4367,8 +4367,8 @@ static void commit_planes_do_stream_update(struct dc *dc,
if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && pipe_ctx->stream == stream) {
- if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt)
- dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
+ if (stream_update->periodic_interrupt)
+ hwss_setup_periodic_interrupt(dc, pipe_ctx);
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
stream_update->vrr_infopacket ||
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 90d754d192f1..bfb598a22c26 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -745,6 +745,38 @@ static bool get_update_dchubp_dpp_flags_status(struct pipe_ctx *pipe)
return false;
}
+static void calc_vline_position(
+ struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ uint32_t *start_line,
+ uint32_t *end_line)
+{
+ if (!dc->hwss.get_vupdate_offset_from_vsync)
+ return;
+
+ const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+ int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
+
+ if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
+ if (vline_pos > 0)
+ vline_pos--;
+ else if (vline_pos < 0)
+ vline_pos++;
+
+ vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+ if (vline_pos >= 0)
+ *start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total);
+ else
+ *start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1;
+ *end_line = (*start_line + 2) % timing->v_total;
+ } else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) {
+ // vsync is line 0 so start_line is just the requested line offset
+ *start_line = vline_pos;
+ *end_line = (*start_line + 2) % timing->v_total;
+ } else
+ ASSERT(0);
+}
+
// Function to check if any update flags are set
static bool get_pipe_update_bits_status(struct pipe_ctx *pipe, struct dc_plane_state *plane, struct dc_stream_state *stream)
{
@@ -1173,8 +1205,16 @@ void hwss_build_fast_sequence(struct dc *dc,
}
if (dc->hwss.setup_periodic_interrupt && stream->update_flags.bits.periodic_interrupt) {
- block_sequence[*num_steps].params.setup_periodic_interrupt_params.dc = dc;
- block_sequence[*num_steps].params.setup_periodic_interrupt_params.pipe_ctx = pipe_ctx;
+ uint32_t start_line = 0;
+ uint32_t end_line = 0;
+
+ calc_vline_position(dc, pipe_ctx, &start_line, &end_line);
+ block_sequence[*num_steps].params.setup_periodic_interrupt_params.tg =
+ pipe_ctx->stream_res.tg;
+ block_sequence[*num_steps].params.setup_periodic_interrupt_params.start_line =
+ start_line;
+ block_sequence[*num_steps].params.setup_periodic_interrupt_params.end_line =
+ end_line;
block_sequence[*num_steps].func = HWSS_SETUP_PERIODIC_INTERRUPT;
(*num_steps)++;
}
@@ -1668,7 +1708,11 @@ void hwss_execute_sequence(struct dc *dc,
hwss_tg_setup_vertical_interrupt0(params);
break;
case HWSS_SETUP_PERIODIC_INTERRUPT:
- hwss_setup_periodic_interrupt(dc, params);
+ if (dc->hwss.setup_periodic_interrupt)
+ dc->hwss.setup_periodic_interrupt(
+ params->setup_periodic_interrupt_params.tg,
+ params->setup_periodic_interrupt_params.start_line,
+ params->setup_periodic_interrupt_params.end_line);
break;
case HWSS_UPDATE_INFO_FRAME:
hwss_update_info_frame(dc, params);
@@ -3322,12 +3366,18 @@ void hwss_update_info_frame(struct dc *dc, union block_sequence_params *params)
dc->hwss.update_info_frame(pipe_ctx);
}
-void hwss_setup_periodic_interrupt(struct dc *dc, union block_sequence_params *params)
+void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- struct pipe_ctx *pipe_ctx = params->setup_periodic_interrupt_params.pipe_ctx;
+ uint32_t start_line = 0;
+ uint32_t end_line = 0;
- if (dc->hwss.setup_periodic_interrupt)
- dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
+ if (dc->hwss.setup_periodic_interrupt) {
+ calc_vline_position(dc, pipe_ctx, &start_line, &end_line);
+ dc->hwss.setup_periodic_interrupt(
+ pipe_ctx->stream_res.tg,
+ start_line,
+ end_line);
+ }
}
void hwss_tg_setup_vertical_interrupt0(union block_sequence_params *params)
@@ -5934,9 +5984,17 @@ void hwss_add_setup_periodic_interrupt(struct block_sequence_state *seq_state,
struct pipe_ctx *pipe_ctx)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
+ uint32_t start_line = 0;
+ uint32_t end_line = 0;
+
+ calc_vline_position(dc, pipe_ctx, &start_line, &end_line);
seq_state->steps[*seq_state->num_steps].func = HWSS_SETUP_PERIODIC_INTERRUPT;
- seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.dc = dc;
- seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.pipe_ctx = pipe_ctx;
+ seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.tg =
+ pipe_ctx->stream_res.tg;
+ seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.start_line =
+ start_line;
+ seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.end_line =
+ end_line;
(*seq_state->num_steps)++;
}
}
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 097e4ac2df05..850639b6fd9b 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
@@ -4026,45 +4026,12 @@ void dcn10_calc_vupdate_position(
*end_line = (*start_line + 2) % timing->v_total;
}
-static void dcn10_cal_vline_position(
- struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- uint32_t *start_line,
- uint32_t *end_line)
-{
- const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
- int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
-
- if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
- if (vline_pos > 0)
- vline_pos--;
- else if (vline_pos < 0)
- vline_pos++;
-
- vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
- if (vline_pos >= 0)
- *start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total);
- else
- *start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1;
- *end_line = (*start_line + 2) % timing->v_total;
- } else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) {
- // vsync is line 0 so start_line is just the requested line offset
- *start_line = vline_pos;
- *end_line = (*start_line + 2) % timing->v_total;
- } else
- ASSERT(0);
-}
-
void dcn10_setup_periodic_interrupt(
- struct dc *dc,
- struct pipe_ctx *pipe_ctx)
+ struct timing_generator *tg,
+ uint32_t start_line,
+ uint32_t end_line
+ )
{
- struct timing_generator *tg = pipe_ctx->stream_res.tg;
- uint32_t start_line = 0;
- uint32_t end_line = 0;
-
- dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line);
-
tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
index 2cb674ba54e1..a93109c2199b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
@@ -183,8 +183,9 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx);
void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx);
void dcn10_setup_periodic_interrupt(
- struct dc *dc,
- struct pipe_ctx *pipe_ctx);
+ struct timing_generator *tg,
+ uint32_t start_line,
+ uint32_t end_line);
enum dc_status dcn10_set_clock(struct dc *dc,
enum dc_clock_type clock_type,
uint32_t clk_khz,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index cdf2562a9a40..129120ac6d9e 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -819,8 +819,9 @@ struct cursor_lock_params {
};
struct setup_periodic_interrupt_params {
- struct dc *dc;
- struct pipe_ctx *pipe_ctx;
+ struct timing_generator *tg;
+ uint32_t start_line;
+ uint32_t end_line;
};
struct send_cursor_info_to_dmu_params {
@@ -1452,8 +1453,9 @@ struct hw_sequencer_funcs {
void (*enable_vblanks_synchronization)(struct dc *dc,
int group_index, int group_size,
struct pipe_ctx *grouped_pipes[]);
- void (*setup_periodic_interrupt)(struct dc *dc,
- struct pipe_ctx *pipe_ctx);
+ void (*setup_periodic_interrupt)(struct timing_generator *tg,
+ uint32_t start_line,
+ uint32_t end_line);
void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
struct dc_crtc_timing_adjust adjust);
void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
@@ -2113,7 +2115,7 @@ void hwss_commit_cursor_offload_update(union block_sequence_params *params);
void hwss_update_cursor_offload_pipe(union block_sequence_params *params);
-void hwss_setup_periodic_interrupt(struct dc *dc, union block_sequence_params *params);
+void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
void hwss_disable_audio_stream(struct dc *dc, union block_sequence_params *params);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 03/24] drm/amd/display: Add missing prototype for amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
2026-08-10 21:28 ` [PATCH 01/24] drm/amd/display: Add CACP ACE curve area debugfs for IGT validation James Lin
2026-08-10 21:28 ` [PATCH 02/24] drm/amd/display: Move periodic interrupt calculations to HWSS James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 04/24] drm/amd/display: Rename carried dce clock manager functions for dcn10 James Lin
` (20 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, James Lin
From: James Lin <pinglei.lin@amd.com>
[Why]
amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags was introduced
without a forward declaration in amdgpu_dm_plane.h, causing a
-Werror=missing-prototypes build failure.
[How]
Add the missing prototype to amdgpu_dm_plane.h alongside the
already-present declaration for
amdgpu_dm_plane_fill_gfx6_tiling_info_from_modifier.
Fixes: 4ff8ab874a6a ("drm/amd/display: Support DRM format modifiers on GFX6-8")
Reviewed-by: Roman Li <roman.li@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index 092ade738ce9..323872d984ee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -123,6 +123,8 @@ void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
void amdgpu_dm_plane_add_modifier_dedup(uint64_t **mods, uint64_t *size,
uint64_t *cap, uint64_t mod);
+void amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags(struct dc_tiling_info *tiling_info,
+ uint64_t tiling_flags);
int amdgpu_dm_plane_fill_gfx6_tiling_info_from_modifier(struct dc_tiling_info *tiling_info,
uint64_t modifier);
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 04/24] drm/amd/display: Rename carried dce clock manager functions for dcn10
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (2 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 03/24] drm/amd/display: Add missing prototype for amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 05/24] drm/amd/display: Add utm_support capability flag James Lin
` (19 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Dillon Varone, Alvin Lee,
James Lin
From: Dillon Varone <Dillon.Varone@amd.com>
[WHY&HOW]
Some legacy DCE functions were carried over to DCN10 and later. These
functions are now renamed to remove the DCE prefix and be more generic.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Dillon Varone <Dillon.Varone@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../display/dc/clk_mgr/dce100/dce_clk_mgr.c | 115 ++++++++++++++++++
.../display/dc/clk_mgr/dce100/dce_clk_mgr.h | 8 +-
.../dc/clk_mgr/dce112/dce112_clk_mgr.c | 59 +++++++++
.../dc/clk_mgr/dce112/dce112_clk_mgr.h | 4 +-
.../display/dc/clk_mgr/dcn10/dcn10_clk_mgr.c | 14 +--
.../display/dc/clk_mgr/dcn10/dcn10_clk_mgr.h | 12 +-
.../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c | 9 +-
.../display/dc/clk_mgr/dcn10/rv2_clk_mgr.c | 6 +-
.../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 12 +-
.../dc/clk_mgr/dcn201/dcn201_clk_mgr.c | 6 +-
.../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 5 +-
.../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 8 +-
.../display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 8 +-
.../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 10 +-
.../dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 10 +-
.../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 10 +-
.../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 10 +-
.../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 18 +--
.../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 12 +-
.../dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 18 +--
.../display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c | 14 +--
.../dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c | 10 +-
.../display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c | 4 +-
23 files changed, 281 insertions(+), 101 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
index 42e6d6538825..d891b3bfe2a1 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
@@ -62,6 +62,56 @@ static const struct clk_mgr_mask disp_clk_mask = {
CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
};
+unsigned int dentist_get_divider_from_did(unsigned int did)
+{
+ if (did < DENTIST_BASE_DID_1)
+ did = DENTIST_BASE_DID_1;
+ if (did > DENTIST_MAX_DID)
+ did = DENTIST_MAX_DID;
+
+ if (did < DENTIST_BASE_DID_2) {
+ return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP
+ * (did - DENTIST_BASE_DID_1);
+ } else if (did < DENTIST_BASE_DID_3) {
+ return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP
+ * (did - DENTIST_BASE_DID_2);
+ } else if (did < DENTIST_BASE_DID_4) {
+ return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP
+ * (did - DENTIST_BASE_DID_3);
+ } else {
+ return DENTIST_DIVIDER_RANGE_4_START + DENTIST_DIVIDER_RANGE_4_STEP
+ * (did - DENTIST_BASE_DID_4);
+ }
+}
+
+/* SW will adjust DP REF Clock average value for all purposes
+ * (DP DTO / DP Audio DTO and DP GTC)
+ if clock is spread for all cases:
+ -if SS enabled on DP Ref clock and HW de-spreading enabled with SW
+ calculations for DS_INCR/DS_MODULO (this is planned to be default case)
+ -if SS enabled on DP Ref clock and HW de-spreading enabled with HW
+ calculations (not planned to be used, but average clock should still
+ be valid)
+ -if SS enabled on DP Ref clock and HW de-spreading disabled
+ (should not be case with CIK) then SW should program all rates
+ generated according to average value (case as with previous ASICs)
+ */
+
+int dce_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_ref_clk_khz)
+{
+ if (clk_mgr_dce->ss_on_dprefclk && clk_mgr_dce->dprefclk_ss_divider != 0) {
+ struct fixed31_32 ss_percentage = dc_fixpt_div_int(
+ dc_fixpt_from_fraction(clk_mgr_dce->dprefclk_ss_percentage,
+ clk_mgr_dce->dprefclk_ss_divider), 200);
+ struct fixed31_32 adj_dp_ref_clk_khz;
+
+ ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage);
+ adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz);
+ dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz);
+ }
+ return dp_ref_clk_khz;
+}
+
static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
{
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
@@ -105,6 +155,13 @@ int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
}
+int dce12_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
+{
+ struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+
+ return dce_adjust_dp_ref_freq_for_ss(clk_mgr_dce, clk_mgr_base->dprefclk_khz);
+}
+
/* unit: in_khz before mode set, get pixel clock from context. ASIC register
* may not be programmed yet
*/
@@ -199,6 +256,64 @@ static void dce_clock_read_integrated_info(struct clk_mgr_internal *clk_mgr_dce)
clk_mgr_dce->dfs_bypass_enabled = true;
}
+void dce_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce)
+{
+ struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios;
+ int ss_info_num = bp->funcs->get_ss_entry_number(
+ bp, AS_SIGNAL_TYPE_GPU_PLL);
+
+ if (ss_info_num) {
+ struct spread_spectrum_info info = { { 0 } };
+ enum bp_result result = bp->funcs->get_spread_spectrum_info(
+ bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info);
+
+ /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS
+ * even if SS not enabled and in that case
+ * SSInfo.spreadSpectrumPercentage !=0 would be sign
+ * that SS is enabled
+ */
+ if (result == BP_RESULT_OK &&
+ info.spread_spectrum_percentage != 0) {
+ clk_mgr_dce->ss_on_dprefclk = true;
+ clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider;
+
+ if (info.type.CENTER_MODE == 0) {
+ /* TODO: Currently for DP Reference clock we
+ * need only SS percentage for
+ * downspread */
+ clk_mgr_dce->dprefclk_ss_percentage =
+ info.spread_spectrum_percentage;
+ }
+
+ return;
+ }
+
+ result = bp->funcs->get_spread_spectrum_info(
+ bp, AS_SIGNAL_TYPE_DISPLAY_PORT, 0, &info);
+
+ /* Based on VBIOS, VBIOS will keep entry for DPREFCLK SS
+ * even if SS not enabled and in that case
+ * SSInfo.spreadSpectrumPercentage !=0 would be sign
+ * that SS is enabled
+ */
+ if (result == BP_RESULT_OK &&
+ info.spread_spectrum_percentage != 0) {
+ clk_mgr_dce->ss_on_dprefclk = true;
+ clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider;
+
+ if (info.type.CENTER_MODE == 0) {
+ /* Currently for DP Reference clock we
+ * need only SS percentage for
+ * downspread */
+ clk_mgr_dce->dprefclk_ss_percentage =
+ info.spread_spectrum_percentage;
+ }
+ if (clk_mgr_dce->base.ctx->dc->config.ignore_dpref_ss)
+ clk_mgr_dce->dprefclk_ss_percentage = 0;
+ }
+ }
+}
+
static void dce_pplib_apply_display_requirements(
struct dc *dc,
struct dc_state *context)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.h
index 2f4165f1a7bc..e1c6a92d7957 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.h
@@ -28,9 +28,9 @@
#define _DCE_CLK_MGR_H_
#include "dc.h"
-#include "dcn10/dcn10_clk_mgr.h"
/* functions shared by other dce clk mgrs */
+int dce_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_ref_clk_khz);
int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base);
uint32_t dce_get_max_pixel_clock_for_all_paths(struct dc_state *context);
@@ -40,6 +40,10 @@ void dce_clk_mgr_construct(
struct dc_context *ctx,
struct clk_mgr_internal *clk_mgr_dce);
+void dce_clock_read_ss_info(struct clk_mgr_internal *dccg_dce);
+
+int dce12_get_dp_ref_freq_khz(struct clk_mgr *dccg);
+
int dce_set_clock(
struct clk_mgr *clk_mgr_base,
int requested_clk_khz);
@@ -47,4 +51,6 @@ int dce_set_clock(
void dce_clk_mgr_destroy(struct clk_mgr **clk_mgr);
+unsigned int dentist_get_divider_from_did(unsigned int did);
+
#endif /* _DCE_CLK_MGR_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c
index 2157761c3b4b..3da0c220d17f 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c
@@ -101,6 +101,65 @@ int dce112_set_clock(struct clk_mgr *clk_mgr_base, int requested_clk_khz)
return actual_clock;
}
+int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz)
+{
+ struct bp_set_dce_clock_parameters dce_clk_params;
+ struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
+ struct dc *dc = clk_mgr->base.ctx->dc;
+ struct dmcu *dmcu = dc->res_pool->dmcu;
+ int actual_clock;
+ /* Prepare to program display clock*/
+ memset(&dce_clk_params, 0, sizeof(dce_clk_params));
+
+ /* Make sure requested clock isn't lower than minimum threshold*/
+ if (requested_clk_khz > 0)
+ requested_clk_khz = max(requested_clk_khz,
+ clk_mgr->base.dentist_vco_freq_khz / 62);
+
+ dce_clk_params.target_clock_frequency = requested_clk_khz;
+ dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
+ dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK;
+
+ bp->funcs->set_dce_clock(bp, &dce_clk_params);
+ actual_clock = dce_clk_params.target_clock_frequency;
+
+ if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
+ if (clk_mgr->dfs_bypass_disp_clk != actual_clock)
+ dmcu->funcs->set_psr_wait_loop(dmcu,
+ actual_clock / 1000 / 7);
+ }
+
+ clk_mgr->dfs_bypass_disp_clk = actual_clock;
+ return actual_clock;
+
+}
+
+int dce112_set_dprefclk(struct clk_mgr_internal *clk_mgr)
+{
+ struct bp_set_dce_clock_parameters dce_clk_params;
+ struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
+
+ memset(&dce_clk_params, 0, sizeof(dce_clk_params));
+
+ /*Program DP ref Clock*/
+ /*VBIOS will determine DPREFCLK frequency, so we don't set it*/
+ dce_clk_params.target_clock_frequency = 0;
+ dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
+ dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK;
+ if (!((clk_mgr->base.ctx->asic_id.chip_family == FAMILY_AI) &&
+ ASICREV_IS_VEGA20_P(clk_mgr->base.ctx->asic_id.hw_internal_rev)))
+ dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK =
+ (dce_clk_params.pll_id ==
+ CLOCK_SOURCE_COMBO_DISPLAY_PLL0);
+ else
+ dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false;
+
+ bp->funcs->set_dce_clock(bp, &dce_clk_params);
+
+ /* Returns the dp_refclk that was set */
+ return dce_clk_params.target_clock_frequency;
+}
+
static void dce112_update_clocks(struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.h
index 766b73c19365..dfb06db118e1 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.h
@@ -26,8 +26,6 @@
#ifndef DAL_DC_DCE_DCE112_CLK_MGR_H_
#define DAL_DC_DCE_DCE112_CLK_MGR_H_
-/* dce112_set_dispclk and dce112_set_dprefclk are declared here. */
-#include "dcn10/dcn10_clk_mgr.h"
void dce112_clk_mgr_construct(
struct dc_context *ctx,
@@ -35,5 +33,7 @@ void dce112_clk_mgr_construct(
/* functions shared with other clk mgr */
int dce112_set_clock(struct clk_mgr *clk_mgr_base, int requested_clk_khz);
+int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz);
+int dce112_set_dprefclk(struct clk_mgr_internal *clk_mgr);
#endif /* DAL_DC_DCE_DCE112_CLK_MGR_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.c
index 75d5c90e7707..172bba20a156 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.c
@@ -7,7 +7,7 @@
#include "dal_asic_id.h"
#include "dcn10_clk_mgr.h"
-unsigned int dentist_get_divider_from_did(unsigned int did)
+unsigned int dcn10_dentist_get_divider_from_did(unsigned int did)
{
if (did < DENTIST_BASE_DID_1)
did = DENTIST_BASE_DID_1;
@@ -41,7 +41,7 @@ unsigned int dentist_get_divider_from_did(unsigned int did)
(should not be case with CIK) then SW should program all rates
generated according to average value (case as with previous ASICs)
*/
-int dce_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_ref_clk_khz)
+int dcn10_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_ref_clk_khz)
{
if (clk_mgr_dce->ss_on_dprefclk && clk_mgr_dce->dprefclk_ss_divider != 0) {
struct fixed31_32 ss_percentage = dc_fixpt_div_int(
@@ -56,14 +56,14 @@ int dce_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_r
return dp_ref_clk_khz;
}
-int dce12_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
+int dcn10_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
{
struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base);
- return dce_adjust_dp_ref_freq_for_ss(clk_mgr_dce, clk_mgr_base->dprefclk_khz);
+ return dcn10_adjust_dp_ref_freq_for_ss(clk_mgr_dce, clk_mgr_base->dprefclk_khz);
}
-void dce_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce)
+void dcn10_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce)
{
struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios;
int ss_info_num = bp->funcs->get_ss_entry_number(
@@ -121,7 +121,7 @@ void dce_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce)
}
}
-int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz)
+int dcn10_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz)
{
struct bp_set_dce_clock_parameters dce_clk_params;
struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
@@ -154,7 +154,7 @@ int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz)
}
-int dce112_set_dprefclk(struct clk_mgr_internal *clk_mgr)
+int dcn10_set_dprefclk(struct clk_mgr_internal *clk_mgr)
{
struct bp_set_dce_clock_parameters dce_clk_params;
struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.h
index e27486db4b62..99beafbf0092 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/dcn10_clk_mgr.h
@@ -14,16 +14,16 @@ struct clk_mgr_internal;
/*
* Shared clock helpers referenced by both the DCE and DCN clock managers.
*/
-int dce_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_ref_clk_khz);
+int dcn10_adjust_dp_ref_freq_for_ss(struct clk_mgr_internal *clk_mgr_dce, int dp_ref_clk_khz);
-void dce_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce);
+void dcn10_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce);
-int dce12_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base);
+int dcn10_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base);
-unsigned int dentist_get_divider_from_did(unsigned int did);
+unsigned int dcn10_dentist_get_divider_from_did(unsigned int did);
-int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz);
+int dcn10_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz);
-int dce112_set_dprefclk(struct clk_mgr_internal *clk_mgr);
+int dcn10_set_dprefclk(struct clk_mgr_internal *clk_mgr);
#endif /* __DCN10_CLK_MGR_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
index 06a51f47aed7..9450b1733f60 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
@@ -26,8 +26,7 @@
#include "core_types.h"
#include "clk_mgr_internal.h"
#include "rv1_clk_mgr.h"
-#include "dce100/dce_clk_mgr.h"
-#include "dce112/dce112_clk_mgr.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "rv1_clk_mgr_vbios_smu.h"
#include "rv1_clk_mgr_clk.h"
@@ -303,14 +302,14 @@ static void rv1_enable_pme_wa(struct clk_mgr *clk_mgr_base)
static struct clk_mgr_funcs rv1_clk_funcs = {
.init_clocks = rv1_init_clocks,
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = rv1_update_clocks,
.enable_pme_wa = rv1_enable_pme_wa,
};
static struct clk_mgr_internal_funcs rv1_clk_internal_funcs = {
.set_dispclk = rv1_vbios_smu_set_dispclk,
- .set_dprefclk = dce112_set_dprefclk
+ .set_dprefclk = dcn10_set_dprefclk
};
void rv1_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_mgr, struct pp_smu_funcs *pp_smu)
@@ -342,7 +341,7 @@ void rv1_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_
if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE)
clk_mgr->dfs_bypass_enabled = true;
- dce_clock_read_ss_info(clk_mgr);
+ dcn10_clock_read_ss_info(clk_mgr);
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv2_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv2_clk_mgr.c
index b9ba6dbc2b46..3a9849b4df74 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv2_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv2_clk_mgr.c
@@ -27,11 +27,11 @@
#include "clk_mgr_internal.h"
#include "rv1_clk_mgr.h"
#include "rv2_clk_mgr.h"
-#include "dce112/dce112_clk_mgr.h"
+#include "dcn10/dcn10_clk_mgr.h"
static struct clk_mgr_internal_funcs rv2_clk_internal_funcs = {
- .set_dispclk = dce112_set_dispclk,
- .set_dprefclk = dce112_set_dprefclk
+ .set_dispclk = dcn10_set_dispclk,
+ .set_dprefclk = dcn10_set_dprefclk
};
void rv2_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_mgr, struct pp_smu_funcs *pp_smu)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index cbd989b6a3df..86f3f32768e3 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -26,7 +26,7 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-#include "dce100/dce_clk_mgr.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20_clk_mgr.h"
#include "reg_helper.h"
#include "core_types.h"
@@ -436,8 +436,8 @@ void dcn2_read_clocks_from_hw_dentist(struct clk_mgr *clk_mgr_base)
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider);
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, &dppclk_wdivider);
- disp_divider = dentist_get_divider_from_did(dispclk_wdivider);
- dpp_divider = dentist_get_divider_from_did(dppclk_wdivider);
+ disp_divider = dcn10_dentist_get_divider_from_did(dispclk_wdivider);
+ dpp_divider = dcn10_dentist_get_divider_from_did(dppclk_wdivider);
if (disp_divider && dpp_divider) {
/* Calculate the current DFS clock, in kHz.*/
@@ -518,7 +518,7 @@ static void dcn2_notify_link_rate_change(struct clk_mgr *clk_mgr_base, struct dc
}
static struct clk_mgr_funcs dcn2_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = dcn2_update_clocks,
.init_clocks = dcn2_init_clocks,
.enable_pme_wa = dcn2_enable_pme_wa,
@@ -558,7 +558,7 @@ void dcn20_clk_mgr_construct(
/* DFS Slice 2 should be used for DPREFCLK */
dprefclk_did = REG_READ(CLK3_CLK2_DFS_CNTL);
/* Convert DPREFCLK DFS Slice DID to actual divider */
- target_div = dentist_get_divider_from_did(dprefclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dprefclk_did);
/* get FbMult value */
pll_req_reg = REG_READ(CLK3_CLK_PLL_REQ);
@@ -588,5 +588,5 @@ void dcn20_clk_mgr_construct(
//Also there is no plan for now that DFS BYPASS will be used on NV10/12/14.
clk_mgr->dfs_bypass_enabled = false;
- dce_clock_read_ss_info(clk_mgr);
+ dcn10_clock_read_ss_info(clk_mgr);
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c
index 76c612ecfe3c..7ab548e41b40 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c
@@ -28,8 +28,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
#include "dcn201_clk_mgr.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20/dcn20_clk_mgr.h"
-#include "dce100/dce_clk_mgr.h"
#include "dm_helpers.h"
#include "dm_services.h"
@@ -170,7 +170,7 @@ static void dcn201_update_clocks(struct clk_mgr *clk_mgr_base,
}
static struct clk_mgr_funcs dcn201_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = dcn201_update_clocks,
.init_clocks = dcn201_init_clocks,
.get_clock = dcn2_get_clock,
@@ -213,5 +213,5 @@ void dcn201_clk_mgr_construct(struct dc_context *ctx,
if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE)
clk_mgr->dfs_bypass_enabled = true;
- dce_clock_read_ss_info(clk_mgr);
+ dcn10_clock_read_ss_info(clk_mgr);
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
index b5378344d2bc..488ae92d24fa 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
@@ -26,6 +26,7 @@
#include "dccg.h"
#include "rn_clk_mgr.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20/dcn20_clk_mgr.h"
#include "dml/dcn20/dcn20_fpu.h"
@@ -565,7 +566,7 @@ static void rn_notify_link_rate_change(struct clk_mgr *clk_mgr_base, struct dc_l
}
static struct clk_mgr_funcs dcn21_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = rn_update_clocks,
.init_clocks = rn_init_clocks,
.enable_pme_wa = rn_enable_pme_wa,
@@ -770,7 +771,7 @@ void rn_clk_mgr_construct(
rn_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info);
clk_mgr->base.dprefclk_khz = 600000;
- dce_clock_read_ss_info(clk_mgr);
+ dcn10_clock_read_ss_info(clk_mgr);
clk_mgr->base.bw_params = &rn_bw_params;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
index 5641f9089b0b..80bdaf762a23 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
@@ -26,8 +26,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
#include "dcn30_clk_mgr_smu_msg.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20/dcn20_clk_mgr.h"
-#include "dce100/dce_clk_mgr.h"
#include "dcn30/dcn30_clk_mgr.h"
#include "dml/dcn30/dcn30_fpu.h"
#include "dcn30/dcn30m_clk_mgr.h"
@@ -493,7 +493,7 @@ static void dcn30_notify_link_rate_change(struct clk_mgr *clk_mgr_base, struct d
}
static struct clk_mgr_funcs dcn3_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = dcn3_update_clocks,
.init_clocks = dcn3_init_clocks,
.notify_wm_ranges = dcn3_notify_wm_ranges,
@@ -517,7 +517,7 @@ static void dcn3_init_clocks_fpga(struct clk_mgr *clk_mgr)
}
struct clk_mgr_funcs dcn3_fpga_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = dcn2_update_clocks_fpga,
.init_clocks = dcn3_init_clocks_fpga,
};
@@ -567,7 +567,7 @@ void dcn3_clk_mgr_construct(
clk_mgr->smu_present = false;
- dce_clock_read_ss_info(clk_mgr);
+ dcn10_clock_read_ss_info(clk_mgr);
clk_mgr->base.bw_params = kzalloc_obj(*clk_mgr->base.bw_params);
if (!clk_mgr->base.bw_params) {
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
index e40bbc495fc4..ace3ceb228c6 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
@@ -26,8 +26,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
@@ -482,7 +482,7 @@ static bool vg_are_clock_states_equal(struct dc_clocks *a,
static struct clk_mgr_funcs vg_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = vg_update_clocks,
.init_clocks = vg_init_clocks,
.enable_pme_wa = vg_enable_pme_wa,
@@ -748,7 +748,7 @@ void vg_clk_mgr_construct(
vg_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info);
clk_mgr->base.base.dprefclk_khz = 600000;
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
clk_mgr->base.base.bw_params = &vg_bw_params;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
index ff47af3854b6..938bc2bbe6d7 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
@@ -28,8 +28,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
@@ -666,7 +666,7 @@ int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base)
}
static struct clk_mgr_funcs dcn31_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn31_update_clocks,
.init_clocks = dcn31_init_clocks,
@@ -744,9 +744,9 @@ void dcn31_clk_mgr_construct(
clk_mgr->base.base.dprefclk_khz = 600000;
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
/*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/
- //clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(clk_mgr_internal, clk_mgr->base.base.dprefclk_khz);
+ //clk_mgr->base.dccg->ref_dtbclk_khz = dcn10_adjust_dp_ref_freq_for_ss(clk_mgr_internal, clk_mgr->base.base.dprefclk_khz);
clk_mgr->base.base.bw_params = &dcn31_bw_params;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
index 24f6304011ae..2aa3e8e66cb7 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
@@ -31,8 +31,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
@@ -200,7 +200,7 @@ void dcn314_init_clocks(struct clk_mgr *clk_mgr)
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
if (dcn314_is_spll_ssc_enabled(clk_mgr))
clk_mgr->dp_dto_source_clock_in_khz =
- dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
+ dcn10_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
else
clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz;
}
@@ -766,7 +766,7 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
}
static struct clk_mgr_funcs dcn314_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn314_update_clocks,
.init_clocks = dcn314_init_clocks,
@@ -861,7 +861,7 @@ void dcn314_clk_mgr_construct(
clk_mgr->base.base.dprefclk_khz = 600000;
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
dcn314_read_ss_info_from_lut(&clk_mgr->base);
/*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
index 75d39cb26dba..6ba7cff2ce05 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
@@ -28,8 +28,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
#include "dcn31/dcn31_clk_mgr.h"
@@ -600,7 +600,7 @@ static void dcn315_enable_pme_wa(struct clk_mgr *clk_mgr_base)
}
static struct clk_mgr_funcs dcn315_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn315_update_clocks,
.init_clocks = dcn31_init_clocks,
@@ -675,8 +675,8 @@ void dcn315_clk_mgr_construct(
clk_mgr->base.base.dprefclk_khz = 600000;
clk_mgr->base.base.dprefclk_khz = dcn315_smu_get_dpref_clk(&clk_mgr->base);
clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
- dce_clock_read_ss_info(&clk_mgr->base);
- clk_mgr->base.base.clks.ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
+ clk_mgr->base.base.clks.ref_dtbclk_khz = dcn10_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);
clk_mgr->base.base.bw_params = &dcn315_bw_params;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
index c7fecbdfda2c..96bd653a9b71 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
@@ -28,8 +28,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
#include "dcn31/dcn31_clk_mgr.h"
@@ -576,7 +576,7 @@ static void dcn316_clk_mgr_helper_populate_bw_params(
static struct clk_mgr_funcs dcn316_funcs = {
.enable_pme_wa = dcn316_enable_pme_wa,
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn316_update_clocks,
.init_clocks = dcn31_init_clocks,
@@ -659,9 +659,9 @@ void dcn316_clk_mgr_construct(
clk_mgr->base.base.dprefclk_khz = 600000;
clk_mgr->base.base.dprefclk_khz = dcn316_smu_get_dpref_clk(&clk_mgr->base);
clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
/*clk_mgr->base.dccg->ref_dtbclk_khz =
- dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);*/
+ dcn10_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);*/
clk_mgr->base.base.bw_params = &dcn316_bw_params;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
index f9886a0eca92..22dfca6efba6 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
@@ -26,8 +26,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
#include "dcn32/dcn32_clk_mgr_smu_msg.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20/dcn20_clk_mgr.h"
-#include "dce100/dce_clk_mgr.h"
#include "dcn31/dcn31_clk_mgr.h"
#include "dcn32/dcn32_clk_mgr.h"
#include "reg_helper.h"
@@ -409,7 +409,7 @@ static void dcn32_update_clocks_update_dentist(
}
} else if (new_dispclk_wdivider == 127 && old_dispclk_wdivider != 127) {
/* request clock with 126 divider first */
- uint32_t temp_disp_divider = dentist_get_divider_from_did(126);
+ uint32_t temp_disp_divider = dcn10_dentist_get_divider_from_did(126);
uint32_t temp_dispclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / temp_disp_divider;
if (clk_mgr->smu_present)
@@ -490,7 +490,7 @@ static int dcn32_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
unsigned int disp_divider;
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider);
- disp_divider = dentist_get_divider_from_did(dispclk_wdivider);
+ disp_divider = dcn10_dentist_get_divider_from_did(dispclk_wdivider);
/* Return DISPCLK freq in Khz */
if (disp_divider)
@@ -922,31 +922,31 @@ static void dcn32_dump_clk_registers(struct clk_state_registers_and_bypass *regs
}
/* Convert DISPCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dispclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dispclk_did);
//Get dispclk in khz
regs_and_bypass->dispclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DISPCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dppclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dppclk_did);
//Get dppclk in khz
regs_and_bypass->dppclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DPREFCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dprefclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dprefclk_did);
//Get dprefclk in khz
regs_and_bypass->dprefclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DCFCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dcfclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dcfclk_did);
//Get dcfclk in khz
regs_and_bypass->dcfclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DTBCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dtbclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dtbclk_did);
//Get dtbclk in khz
regs_and_bypass->dtbclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
@@ -1139,7 +1139,7 @@ static void dcn32_set_min_memclk(struct clk_mgr *clk_mgr_base, unsigned int memc
}
static struct clk_mgr_funcs dcn32_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn32_update_clocks,
.dump_clk_registers = dcn32_dump_clk_registers,
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 a69824e1eb26..990c362623d8 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
@@ -29,8 +29,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
@@ -758,7 +758,7 @@ void dcn35_init_clocks(struct clk_mgr *clk_mgr)
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
if (dcn35_is_spll_ssc_enabled(clk_mgr))
clk_mgr->dp_dto_source_clock_in_khz =
- dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
+ dcn10_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
else
clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz;
@@ -1346,7 +1346,7 @@ static unsigned int dcn35_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum c
}
static struct clk_mgr_funcs dcn35_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn35_update_clocks,
.init_clocks = dcn35_init_clocks,
@@ -1360,7 +1360,7 @@ static struct clk_mgr_funcs dcn35_funcs = {
};
struct clk_mgr_funcs dcn35_fpga_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = dcn35_update_clocks_fpga,
.init_clocks = dcn35_init_clocks_fpga,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
@@ -1499,7 +1499,7 @@ void dcn35_clk_mgr_construct(
clk_mgr->base.base.dprefclk_khz = dcn35_smu_get_dprefclk(&clk_mgr->base);
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
/*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
dcn35_read_ss_info_from_lut(&clk_mgr->base);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 6ee3da89d058..6d791a5d9776 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -5,8 +5,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
#include "dcn401/dcn401_clk_mgr_smu_msg.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20/dcn20_clk_mgr.h"
-#include "dce100/dce_clk_mgr.h"
#include "dcn31/dcn31_clk_mgr.h"
#include "dcn32/dcn32_clk_mgr.h"
#include "dcn401/dcn401_clk_mgr.h"
@@ -358,37 +358,37 @@ static void dcn401_dump_clk_registers(struct clk_state_registers_and_bypass *reg
fclk_did = REG_READ(CLK2_CLK2_DFS_CNTL);
/* Convert DISPCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dispclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dispclk_did);
//Get dispclk in khz
regs_and_bypass->dispclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DISPCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dppclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dppclk_did);
//Get dppclk in khz
regs_and_bypass->dppclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DPREFCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dprefclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dprefclk_did);
//Get dprefclk in khz
regs_and_bypass->dprefclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DCFCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dcfclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dcfclk_did);
//Get dcfclk in khz
regs_and_bypass->dcfclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DTBCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(dtbclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(dtbclk_did);
//Get dtbclk in khz
regs_and_bypass->dtbclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
/* Convert DTBCLK DFS Slice DID to divider*/
- target_div = dentist_get_divider_from_did(fclk_did);
+ target_div = dcn10_dentist_get_divider_from_did(fclk_did);
//Get fclk in khz
regs_and_bypass->fclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
@@ -1552,7 +1552,7 @@ static int dcn401_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
unsigned int disp_divider;
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider);
- disp_divider = dentist_get_divider_from_did(dispclk_wdivider);
+ disp_divider = dcn10_dentist_get_divider_from_did(dispclk_wdivider);
/* Return DISPCLK freq in Khz */
if (disp_divider)
@@ -1599,7 +1599,7 @@ static void dcn401_execute_clk_mgr_block_sequence_bls(struct clk_mgr *clk_mgr_ba
}
static struct clk_mgr_funcs dcn401_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn401_get_dtb_ref_freq_khz,
.update_clocks = dcn401_update_clocks,
.dump_clk_registers = dcn401_dump_clk_registers,
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
index 19ef0b92e8e6..a2ecde8362a5 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
@@ -7,8 +7,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
@@ -625,7 +625,7 @@ void dcn42_init_clocks(struct clk_mgr *clk_mgr_base)
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
if (dcn42_is_spll_ssc_enabled(clk_mgr_base))
clk_mgr_base->dp_dto_source_clock_in_khz =
- dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr_base->dprefclk_khz);
+ dcn10_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr_base->dprefclk_khz);
else
clk_mgr_base->dp_dto_source_clock_in_khz = clk_mgr_base->dprefclk_khz;
@@ -912,7 +912,7 @@ int dcn42_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
unsigned int disp_divider;
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider);
- disp_divider = dentist_get_divider_from_did(dispclk_wdivider);
+ disp_divider = dcn10_dentist_get_divider_from_did(dispclk_wdivider);
/* Return DISPCLK freq in Khz */
if (disp_divider)
@@ -1074,7 +1074,7 @@ void dcn42_request_dtbclk(struct clk_mgr *clk_mgr_base, bool enable)
}
}
static struct clk_mgr_funcs dcn42_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn42_update_clocks,
.init_clocks = dcn42_init_clocks,
@@ -1091,7 +1091,7 @@ static struct clk_mgr_funcs dcn42_funcs = {
};
struct clk_mgr_funcs dcn42_fpga_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.update_clocks = dcn42_update_clocks_fpga,
.init_clocks = dcn42_init_clocks_fpga,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
@@ -1153,7 +1153,7 @@ void dcn42_clk_mgr_construct(
/* Saved clocks configured at boot for debug purposes */
dcn42_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
/*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
dcn42_read_ss_info_from_lut(&clk_mgr->base);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
index 770b2351c631..90cc2c3aabe4 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
@@ -9,8 +9,8 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-// For dce12_get_dp_ref_freq_khz
-#include "dce100/dce_clk_mgr.h"
+// For dcn10_get_dp_ref_freq_khz
+#include "dcn10/dcn10_clk_mgr.h"
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
@@ -234,7 +234,7 @@ void dcn42b_init_clocks(struct clk_mgr *clk_mgr_base)
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
if (dcn42_is_spll_ssc_enabled(clk_mgr_base))
clk_mgr_base->dp_dto_source_clock_in_khz =
- dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr_base->dprefclk_khz);
+ dcn10_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr_base->dprefclk_khz);
else
clk_mgr_base->dp_dto_source_clock_in_khz = clk_mgr_base->dprefclk_khz;
@@ -418,7 +418,7 @@ static void dcn42b_update_clocks(struct clk_mgr *clk_mgr_base,
}
static struct clk_mgr_funcs dcn42b_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn42b_update_clocks,
.init_clocks = dcn42b_init_clocks,
@@ -657,7 +657,7 @@ void dcn42b_clk_mgr_construct(
/* Saved clocks configured at boot for debug purposes */
dcn42b_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
- dce_clock_read_ss_info(&clk_mgr->base);
+ dcn10_clock_read_ss_info(&clk_mgr->base);
/*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
dcn42b_read_ss_info_from_lut(&clk_mgr->base);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
index 267e5060c6b1..40e975e8a550 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
@@ -6,7 +6,7 @@
#include "clk_mgr_internal.h"
#include "dcn60/dcn60_clk_mgr_smu_msg.h"
#include "hw_sequencer.h"
-#include "dce100/dce_clk_mgr.h"
+#include "dcn10/dcn10_clk_mgr.h"
#include "dcn20/dcn20_clk_mgr.h"
#include "dcn401/dcn401_clk_mgr.h"
#include "dcn60/dcn60_clk_mgr.h"
@@ -1584,7 +1584,7 @@ static void dcn60_execute_clk_mgr_block_sequence_bls(struct clk_mgr *clk_mgr_bas
}
static struct clk_mgr_funcs dcn60_funcs = {
- .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .get_dp_ref_clk_frequency = dcn10_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn60_get_dtb_ref_freq_khz,
.update_clocks = dcn60_update_clocks,
.dump_clk_registers = dcn60_dump_clk_registers,
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 05/24] drm/amd/display: Add utm_support capability flag
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (3 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 04/24] drm/amd/display: Rename carried dce clock manager functions for dcn10 James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 06/24] drm/amd/display: Guard against empty DCN6 UTM QoS table James Lin
` (18 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Wenjing Liu, Alvin Lee,
James Lin
From: Wenjing Liu <wenjing.liu@amd.com>
[Why]
Expose whether the ASIC supports Universal Traffic Management so
upper layers can query the capability instead of assuming support.
[How]
Add a new bool capability field to dc_caps, defaulting to false,
and set it to true during DCN6 resource construction.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dc.h | 1 +
drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index c23299d3f36a..edd6a113cfee 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -432,6 +432,7 @@ struct dc_caps {
uint8_t num_of_dpias_per_host_router;
/* limit of the ODM only, could be limited by other factors (like pipe count)*/
uint8_t max_odm_combine_factor;
+ bool utm_support;
};
struct dc_bug_wa {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
index 2dac5f7486d9..7171b237c427 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
@@ -2037,6 +2037,7 @@ static bool dcn60_resource_construct(
dc->caps.edp_dsc_support = true;
dc->caps.extended_aux_timeout_support = true;
dc->caps.dmcub_support = true;
+ dc->caps.utm_support = true;
dc->caps.max_v_total = (1 << 15) - 1;
if (ASICREV_IS_GC_12_0_1_A0(dc->ctx->asic_id.hw_internal_rev))
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 06/24] drm/amd/display: Guard against empty DCN6 UTM QoS table
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (4 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 05/24] drm/amd/display: Add utm_support capability flag James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 07/24] drm/amd/display: Add DC_BLS command James Lin
` (17 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Wenjing Liu, Alvin Lee,
James Lin
From: Wenjing Liu <wenjing.liu@amd.com>
[Why]
The UTM QoS model population indexed into a firmware-provided
table without checking whether it reported any load levels or
SOPs, leaving a malformed table treated as valid instead of absent.
[How]
Bail out early and clear the output model pointer when the load
level count or SOP count is zero.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
index 40e975e8a550..218856c5fe09 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
@@ -625,6 +625,11 @@ static void dcn60_populate_utm_qos_model(
const SocUtmTable_t *utm_table = &init_table->UtmTable;
unsigned int ll, sop;
+ if (utm_table->Header.LoadLevelCount == 0 || utm_table->Header.SopCount == 0) {
+ *qos_model = NULL;
+ return;
+ }
+
memset(dchub, 0, sizeof(*dchub));
dchub->load_level_count = (uint8_t)utm_table->Header.LoadLevelCount;
dchub->sop_count = (uint8_t)utm_table->Header.SopCount;
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 07/24] drm/amd/display: Add DC_BLS command
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (5 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 06/24] drm/amd/display: Guard against empty DCN6 UTM QoS table James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 08/24] drm/amd/display: Notify DMU to allow DCHVM<->rIOMMU SDP port disconnection for DCN42 James Lin
` (16 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Ovidiu Bunea,
Nicholas Kazlauskas, James Lin
From: Ovidiu Bunea <ovidiu.bunea@amd.com>
[why & how]
In the future, DC will off-load block-level initialization to DMUB.
In preparation, update dmub_cmd.h with the command for better tracking.
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 36 +++++++++++++++++++
1 file changed, 36 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 f0231f355fa7..c273d97ec88d 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -1169,6 +1169,16 @@ enum dmub_ips_comand_type {
DMUB_CMD__IPS_QUERY_RESIDENCY_INFO = 1,
};
+/**
+ * enum dmub_dc_bls_command_type - DC_BLS subcommands.
+ */
+enum dmub_dc_bls_command_type {
+ /**
+ * Placeholder for block-level initialization of the DCHVM
+ */
+ DMUB_CMD__DC_BLS_DCHVM_INIT = 0,
+};
+
/**
* enum dmub_cursor_offload_comand_type - Cursor offload subcommands.
*/
@@ -2008,6 +2018,11 @@ enum dmub_cmd_type {
*/
DMUB_CMD__PANEL_POLARITY = 97,
+ /**
+ * Command type used for all DC_BLS commands.
+ */
+ DMUB_CMD__DC_BLS = 98,
+
/**
* Command type use for VBIOS shared commands.
*/
@@ -2940,6 +2955,25 @@ struct dmub_rb_cmd_idle_opt_dcn_notify_idle {
struct dmub_dcn_notify_idle_cntl_data cntl_data;
};
+/**
+ * Data passed from driver to FW in a DMUB_CMD__DC_BLS_DCHVM_INIT command.
+ */
+struct dmub_cmd_dc_bls_dchvm_init_data {
+ /**
+ * The value to program to rIOMMU PCTRL register. x86 cannot access this SMN
+ * register, so the write is performed by DMCUB on the driver's behalf.
+ */
+ uint32_t riommu_pctrl_val; /* r */
+};
+
+/**
+ * Definition of a DMUB_CMD__DC_BLS_DCHVM_INIT command.
+ */
+struct dmub_rb_cmd_dc_bls_dchvm_init {
+ struct dmub_cmd_header header;
+ struct dmub_cmd_dc_bls_dchvm_init_data data;
+};
+
/**
* enum dmub_idle_opt_dc_power_state - DC power states.
*/
@@ -7988,6 +8022,8 @@ union dmub_rb_cmd {
struct dmub_rb_cmd_panel_polarity_enable panel_polarity_enable;
struct dmub_rb_cmd_panel_polarity_get_bias panel_polarity_get_bias;
struct dmub_rb_cmd_panel_polarity_reset panel_polarity_reset;
+
+ struct dmub_rb_cmd_dc_bls_dchvm_init dc_bls_dchvm_init;
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 08/24] drm/amd/display: Notify DMU to allow DCHVM<->rIOMMU SDP port disconnection for DCN42
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (6 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 07/24] drm/amd/display: Add DC_BLS command James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 09/24] drm/amd/display: Send DPM0 clock values to DMU James Lin
` (15 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Ovidiu Bunea,
Nicholas Kazlauskas, James Lin
From: Ovidiu Bunea <ovidiu.bunea@amd.com>
[why & how]
Allowing the DCHVM<->rIOMMU SDP port to disconnect during IPS1 cycling
can cause extra credits
to be released to rIOMMU. In turn, this will let the rIOMMU issue more
outstanding table walk requests
at once, overflowing the downstream request FIFO. This results in
dropped/orphaned
requests with no method of recovery. This typically manifests as an
invalidation hang error
in the main IOMMU.
As a workaround, dis-allow the SDP port from disconnecting from IPS1 exit
up until after
powerstatus=1. This ensures that rIOMMU does not have the chance to request
credits multiple
times during the powerstatus 0->1 transition.
Since x86 driver cannot access rIOMMU register space, send a command to DMU
to do it.
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 18 ++++++++++++++++++
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 12 ++++++++++++
.../amd/display/dc/hubbub/dcn35/dcn35_hubbub.c | 7 +++++++
3 files changed, 37 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 01864fe816a3..4723e0974647 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -2527,3 +2527,21 @@ bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, ui
return ret;
}
+
+void dc_dmub_srv_hubbub_set_riommu_pctrl(const struct dc_context *ctx, uint32_t value)
+{
+ union dmub_rb_cmd cmd;
+
+ if (!(ctx->dce_version == DCN_VERSION_4_2 || ctx->dce_version == DCN_VERSION_4_2B))
+ return;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.dc_bls_dchvm_init.header.type = DMUB_CMD__DC_BLS;
+ cmd.dc_bls_dchvm_init.header.sub_type = DMUB_CMD__DC_BLS_DCHVM_INIT;
+ cmd.dc_bls_dchvm_init.header.payload_bytes = sizeof(struct dmub_cmd_dc_bls_dchvm_init_data);
+
+ cmd.dc_bls_dchvm_init.data.riommu_pctrl_val = value;
+
+ dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index ec5387aedf46..ab026847e38b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -451,4 +451,16 @@ void dc_dmub_srv_panel_polarity_reset(struct dc_dmub_srv *dc_dmub_srv, uint8_t p
*/
bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst, int32_t *polarity);
+/**
+ * dc_dmub_srv_hubbub_set_riommu_pctrl() - Program the RIOMMU PCTRL register via DMCUB.
+ *
+ * The RIOMMU PCTRL register (SMN address 0x16B0A100) controls the SDP port
+ * disconnection hysteresis between rIOMMU & DCHVM. It is not accessible from
+ * x86, so the write is offloaded to DMCUB.
+ *
+ * @ctx: dc context
+ * @value: value to program into the register (e.g. 0x20)
+ */
+void dc_dmub_srv_hubbub_set_riommu_pctrl(const struct dc_context *ctx, uint32_t value);
+
#endif /* _DMUB_DC_SRV_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
index 5e5a7a74346d..53744b000f5d 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
@@ -31,6 +31,7 @@
#include "dcn35_hubbub.h"
#include "dm_services.h"
#include "reg_helper.h"
+#include "dc_dmub_srv.h"
#define CTX \
@@ -580,7 +581,13 @@ void dcn35_dchvm_init(struct hubbub *hubbub)
//Reflect the power status of DCHUBBUB
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
+ udelay(5);
+ }
+
+ // generically re-allow the DCHVM<->rIOMMU SDP port to disconnect after powerstatus=1
+ dc_dmub_srv_hubbub_set_riommu_pctrl(hubbub->ctx, 0x20);
+ if (riommu_active) {
//Start rIOMMU prefetching
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 09/24] drm/amd/display: Send DPM0 clock values to DMU
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (7 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 08/24] drm/amd/display: Notify DMU to allow DCHVM<->rIOMMU SDP port disconnection for DCN42 James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 10/24] drm/amd/display: Refactor HUBP_WAIT_FOR_DCC_META_PROP to drop pipe_ctx James Lin
` (14 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Ovidiu Bunea, Leo Chen,
James Lin
From: Ovidiu Bunea <ovidiu.bunea@amd.com>
[why & how]
Z8 Retention requires clocks to be put into bypass for the PLL
to be powered down.
Notify DMU of the DPM0 clock values, which is likely always going
to be running of a bypass clock.
Reviewed-by: Leo Chen <leo.chen@amd.com>
Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c | 12 ++++++++++++
.../drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h | 5 +++++
.../amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c | 1 +
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 3 +++
4 files changed, 21 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
index a2ecde8362a5..c62be9f25dae 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
@@ -214,6 +214,7 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
{
union dmub_rb_cmd cmd;
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ struct clk_mgr_dcn42 *clk_mgr_dcn42 = TO_CLK_MGR_DCN42(clk_mgr);
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
struct dc *dc = clk_mgr_base->ctx->dc;
bool update_dppclk = false;
@@ -364,6 +365,16 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
clk_mgr_base->clks.dcfclk_deep_sleep_khz;
cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+ /* Communicate the minimum (DPM0) clocks and bypass ceiling so DMUB does not
+ * assume hardcoded per-ASIC values (e.g. for Z8-Retention clock lowering).
+ * DPM0 is the lowest populated DPM level (entries[0]); 0 when the SMU DPM
+ * table is unavailable, in which case DMUB falls back to its own defaults.
+ */
+ cmd.notify_clocks.clocks.dpm0_dispclk_khz =
+ clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz * 1000;
+ cmd.notify_clocks.clocks.dpm0_dppclk_khz =
+ clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz * 1000;
+ cmd.notify_clocks.clocks.max_bypass_clk_khz = clk_mgr_dcn42->max_bypass_clk_khz;
dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
@@ -1113,6 +1124,7 @@ void dcn42_clk_mgr_construct(
clk_mgr->base.dccg = dccg;
clk_mgr->base.dfs_bypass_disp_clk = 0;
+ clk_mgr->max_bypass_clk_khz = 0;
clk_mgr->base.dprefclk_ss_percentage = 0;
clk_mgr->base.dprefclk_ss_divider = 1000;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h
index f90c6e2e85c2..f64c1ccee8c3 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h
@@ -44,6 +44,11 @@ struct dcn42_ss_info_table {
struct clk_mgr_dcn42 {
struct clk_mgr_internal base;
struct dcn42_smu_watermark_set smu_wm_set;
+ /* Max dispclk/dppclk (kHz) that can run on a bypass source with the PLL
+ * powered down. Communicated to DMUB for Z8-Retention clock lowering.
+ * SMU does not expose this, so it is a fixed per-ASIC value set at construct.
+ */
+ uint32_t max_bypass_clk_khz;
};
bool dcn42_are_clock_states_equal(struct dc_clocks *a,
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
index 90cc2c3aabe4..3420edcf4ffb 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
@@ -618,6 +618,7 @@ void dcn42b_clk_mgr_construct(
clk_mgr->base.dccg = dccg;
clk_mgr->base.dfs_bypass_disp_clk = 0;
+ clk_mgr->max_bypass_clk_khz = 0;
clk_mgr->base.dprefclk_ss_percentage = 0;
clk_mgr->base.dprefclk_ss_divider = 1000;
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 c273d97ec88d..1d10fe8f1998 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -3009,6 +3009,9 @@ struct dmub_clocks {
uint32_t dppclk_khz; /**< dppclk kHz */
uint32_t dcfclk_khz; /**< dcfclk kHz */
uint32_t dcfclk_deep_sleep_khz; /**< dcfclk deep sleep kHz */
+ uint32_t dpm0_dispclk_khz; /**< DPM0 (minimum) dispclk kHz from SMU DPM table, 0 if unknown */
+ uint32_t dpm0_dppclk_khz; /**< DPM0 (minimum) dppclk kHz from SMU DPM table, 0 if unknown */
+ uint32_t max_bypass_clk_khz; /**< max dispclk/dppclk achievable on a bypass source (no PLL) kHz, 0 if unknown */
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 10/24] drm/amd/display: Refactor HUBP_WAIT_FOR_DCC_META_PROP to drop pipe_ctx
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (8 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 09/24] drm/amd/display: Send DPM0 clock values to DMU James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 11/24] drm/amd/display: add wait stream regen event James Lin
` (13 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Tomasz Siemek, Alvin Lee,
James Lin
From: Tomasz Siemek <tomasz.siemek@amd.com>
[why]
Pipe_ctx shouldn't be passed as block sequence block parameter.
[how]
Precalculate delay during building stage instead during execution.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Tomasz Siemek <tomasz.siemek@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +-
.../drm/amd/display/dc/core/dc_hw_sequencer.c | 47 +++++++++++--------
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 24 ++--------
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 3 +-
.../drm/amd/display/dc/hwss/hw_sequencer.h | 11 ++---
5 files changed, 36 insertions(+), 53 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index bc2207d29954..6f7b715d4717 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4967,9 +4967,7 @@ static void commit_planes_for_stream(struct dc *dc,
top_pipe_to_program->stream_res.tg);
}
- if (dc->hwss.wait_for_dcc_meta_propagation) {
- dc->hwss.wait_for_dcc_meta_propagation(dc, top_pipe_to_program);
- }
+ hwss_hubp_wait_for_dcc_meta_prop(dc, top_pipe_to_program);
if (dc->hwseq->funcs.wait_for_pipe_update_if_needed)
dc->hwseq->funcs.wait_for_pipe_update_if_needed(dc, top_pipe_to_program, update_type < UPDATE_TYPE_FULL);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index bfb598a22c26..a8ff59f619c5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -1142,6 +1142,22 @@ void hwss_build_post_unlock_full_sequence(struct dc *dc,
}
}
+static uint32_t get_dcc_meta_propagation_delay(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+ /* check if any surfaces are updating address while using flip immediate and dcc */
+ while (pipe_ctx != NULL) {
+ if (pipe_ctx->plane_state &&
+ pipe_ctx->plane_state->dcc.enable &&
+ pipe_ctx->plane_state->flip_immediate &&
+ pipe_ctx->plane_state->update_bits.addr_update) {
+ return dc->debug.dcc_meta_propagation_delay_us;
+ }
+ /* check next pipe */
+ pipe_ctx = pipe_ctx->bottom_pipe;
+ }
+ return 0;
+}
+
void hwss_build_fast_sequence(struct dc *dc,
struct dc_dmub_cmd *dc_dmub_cmd,
unsigned int dmub_cmd_count,
@@ -1165,8 +1181,7 @@ void hwss_build_fast_sequence(struct dc *dc,
return;
if (dc->hwss.wait_for_dcc_meta_propagation) {
- block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.dc = dc;
- block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.top_pipe_to_program = pipe_ctx;
+ block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.delay = get_dcc_meta_propagation_delay(dc, pipe_ctx);
block_sequence[*num_steps].func = HUBP_WAIT_FOR_DCC_META_PROP;
(*num_steps)++;
}
@@ -1756,9 +1771,7 @@ void hwss_execute_sequence(struct dc *dc,
hwss_subvp_save_surf_addr(params);
break;
case HUBP_WAIT_FOR_DCC_META_PROP:
- dc->hwss.wait_for_dcc_meta_propagation(
- params->wait_for_dcc_meta_propagation_params.dc,
- params->wait_for_dcc_meta_propagation_params.top_pipe_to_program);
+ dc->hwss.wait_for_dcc_meta_propagation(params->wait_for_dcc_meta_propagation_params.delay);
break;
case DMUB_HW_CONTROL_LOCK_FAST:
dc->hwss.dmub_hw_control_lock_fast(params);
@@ -2471,21 +2484,6 @@ void hwss_add_dmub_subvp_save_surf_addr(struct block_sequence_state *seq_state,
}
}
-/*
- * Helper function to add HUBP wait for DCC meta propagation to block sequence
- */
-void hwss_add_hubp_wait_for_dcc_meta_prop(struct block_sequence_state *seq_state,
- struct dc *dc,
- struct pipe_ctx *top_pipe_to_program)
-{
- if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
- seq_state->steps[*seq_state->num_steps].params.wait_for_dcc_meta_propagation_params.dc = dc;
- seq_state->steps[*seq_state->num_steps].params.wait_for_dcc_meta_propagation_params.top_pipe_to_program = top_pipe_to_program;
- seq_state->steps[*seq_state->num_steps].func = HUBP_WAIT_FOR_DCC_META_PROP;
- (*seq_state->num_steps)++;
- }
-}
-
/*
* Helper function to add HUBP wait pipe read start to block sequence
*/
@@ -6189,3 +6187,12 @@ void get_refresh_rate_confirm_color(struct pipe_ctx *pipe_ctx, struct tg_color *
pipe_ctx->visual_confirm_color.color_b_cb = (uint16_t)color_value;
}
}
+
+void hwss_hubp_wait_for_dcc_meta_prop(struct dc *dc, struct pipe_ctx *top_pipe_to_program)
+{
+ if (dc->hwss.wait_for_dcc_meta_propagation) {
+ uint32_t delay = get_dcc_meta_propagation_delay(dc, top_pipe_to_program);
+ dc->hwss.wait_for_dcc_meta_propagation(delay);
+ }
+}
+
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 f20a7b99d20c..42b2fbb8a4ae 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
@@ -1333,28 +1333,10 @@ bool dcn401_apply_idle_power_optimizations(struct dc *dc, bool enable)
return true;
}
-void dcn401_wait_for_dcc_meta_propagation(const struct dc *dc,
- const struct pipe_ctx *top_pipe)
+void dcn401_wait_for_dcc_meta_propagation(uint32_t delay)
{
- bool is_wait_needed = false;
- const struct pipe_ctx *pipe_ctx = top_pipe;
-
- /* check if any surfaces are updating address while using flip immediate and dcc */
- while (pipe_ctx != NULL) {
- if (pipe_ctx->plane_state &&
- pipe_ctx->plane_state->dcc.enable &&
- pipe_ctx->plane_state->flip_immediate &&
- pipe_ctx->plane_state->update_bits.addr_update) {
- is_wait_needed = true;
- break;
- }
-
- /* check next pipe */
- pipe_ctx = pipe_ctx->bottom_pipe;
- }
-
- if (is_wait_needed && dc->debug.dcc_meta_propagation_delay_us > 0) {
- udelay(dc->debug.dcc_meta_propagation_delay_us);
+ if (delay > 0) {
+ udelay(delay);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
index 69c7dc73a29a..2e3392c963d0 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
@@ -57,8 +57,7 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx);
bool dcn401_apply_idle_power_optimizations(struct dc *dc, bool enable);
-void dcn401_wait_for_dcc_meta_propagation(const struct dc *dc,
- const struct pipe_ctx *top_pipe_to_program);
+void dcn401_wait_for_dcc_meta_propagation(uint32_t delay);
void dcn401_prepare_bandwidth(struct dc *dc,
struct dc_state *context);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index 129120ac6d9e..bf63281a8cd2 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -182,8 +182,7 @@ struct subvp_save_surf_addr {
};
struct wait_for_dcc_meta_propagation_params {
- const struct dc *dc;
- const struct pipe_ctx *top_pipe_to_program;
+ uint32_t delay;
};
struct dmub_hw_control_lock_fast_params {
@@ -1654,8 +1653,7 @@ struct hw_sequencer_funcs {
bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
const struct dc_state *cur_ctx,
const struct dc_state *new_ctx);
- void (*wait_for_dcc_meta_propagation)(const struct dc *dc,
- const struct pipe_ctx *top_pipe_to_program);
+ void (*wait_for_dcc_meta_propagation)(uint32_t delay);
void (*dmub_hw_control_lock)(struct dc *dc,
struct dc_state *context,
bool lock);
@@ -2119,6 +2117,8 @@ void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
void hwss_disable_audio_stream(struct dc *dc, union block_sequence_params *params);
+void hwss_hubp_wait_for_dcc_meta_prop(struct dc *dc, struct pipe_ctx *top_pipe_to_program);
+
void hwss_add_optc_pipe_control_lock(struct block_sequence_state *seq_state,
struct dc *dc, struct pipe_ctx *pipe_ctx, bool lock);
@@ -2166,9 +2166,6 @@ void hwss_add_dmub_send_dmcub_cmd(struct block_sequence_state *seq_state,
void hwss_add_dmub_subvp_save_surf_addr(struct block_sequence_state *seq_state,
struct dc_dmub_srv *dc_dmub_srv, struct dc_plane_address *addr, uint8_t subvp_index);
-void hwss_add_hubp_wait_for_dcc_meta_prop(struct block_sequence_state *seq_state,
- struct dc *dc, struct pipe_ctx *top_pipe_to_program);
-
void hwss_add_hubp_wait_pipe_read_start(struct block_sequence_state *seq_state,
struct hubp *hubp);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 11/24] drm/amd/display: add wait stream regen event
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (9 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 10/24] drm/amd/display: Refactor HUBP_WAIT_FOR_DCC_META_PROP to drop pipe_ctx James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 12/24] drm/amd/display: Use mpcc_id instead of hubp instance James Lin
` (12 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Peichen Huang, Leon Huang,
James Lin
From: Peichen Huang <PeiChen.Huang@amd.com>
[WHY & HOW]
Add event to wait stream regen flag.
Reviewed-by: Leon Huang <leon.huang1@amd.com>
Signed-off-by: Peichen Huang <PeiChen.Huang@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/modules/inc/mod_power.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h
index 02bee3b1956d..5d1275b7cd46 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h
@@ -174,6 +174,7 @@ enum replay_event {
replay_event_os_request_force_ffu = 0x2000000,
replay_event_os_override_hold = 0x4000000,
replay_event_crc_window_active = 0x8000000,
+ replay_event_waiting_stream_regen = 0x10000000,
};
enum replay_enable_option {
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 12/24] drm/amd/display: Use mpcc_id instead of hubp instance
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (10 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 11/24] drm/amd/display: add wait stream regen event James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 13/24] drm/amd/display: Add opt-out for DCN6 OutstandingRequests mode-support check James Lin
` (11 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Tomasz Siemek, Alvin Lee,
James Lin
From: Tomasz Siemek <tomasz.siemek@amd.com>
[why]
Hubp pointer is not initialized for older asics.
[how]
Use mpcc_id field from plane resources instead of instance number
by dereferencing hupb pointer.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Tomasz Siemek <tomasz.siemek@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index a8ff59f619c5..b3f3f7362663 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -1537,7 +1537,7 @@ void hwss_build_fast_sequence(struct dc *dc,
params->dpp = current_mpc_pipe->plane_res.dpp;
params->mpc = dc->res_pool->mpc;
params->xfm = current_mpc_pipe->plane_res.xfm;
- params->mpcc_id = current_mpc_pipe->plane_res.hubp->inst;
+ params->mpcc_id = current_mpc_pipe->plane_res.mpcc_inst;
params->plane = current_mpc_pipe->plane_state;
params->stream = current_mpc_pipe->stream;
params->is_top_pipe = current_mpc_pipe->top_pipe == NULL;
@@ -1582,7 +1582,7 @@ void hwss_build_fast_sequence(struct dc *dc,
otf_params->dpp = current_mpc_pipe->plane_res.dpp;
otf_params->xfm = current_mpc_pipe->plane_res.xfm;
otf_params->mpc = dc->res_pool->mpc;
- otf_params->mpcc_id = current_mpc_pipe->plane_res.hubp->inst;
+ otf_params->mpcc_id = current_mpc_pipe->plane_res.mpcc_inst;
otf_params->is_top_pipe = resource_is_pipe_type(current_mpc_pipe, OPP_HEAD);
otf_params->stream = current_mpc_pipe->stream;
block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC;
@@ -2306,7 +2306,7 @@ void hwss_add_dpp_program_gamut_remap(struct block_sequence_state *seq_state,
params->xfm = pipe_ctx->plane_res.xfm;
params->dpp = pipe_ctx->plane_res.dpp;
params->mpc = pipe_ctx->stream->ctx->dc->res_pool->mpc;
- params->mpcc_id = pipe_ctx->plane_res.hubp->inst;
+ params->mpcc_id = pipe_ctx->plane_res.mpcc_inst;
params->plane = pipe_ctx->plane_state;
params->stream = pipe_ctx->stream;
params->is_top_pipe = pipe_ctx->top_pipe == NULL;
@@ -2352,7 +2352,7 @@ void hwss_add_dpp_set_output_transfer_func(struct block_sequence_state *seq_stat
.xfm = pipe_ctx->plane_res.xfm,
.dpp = pipe_ctx->plane_res.dpp,
.mpc = dc->res_pool->mpc,
- .mpcc_id = pipe_ctx->plane_res.hubp->inst,
+ .mpcc_id = pipe_ctx->plane_res.mpcc_inst,
.is_top_pipe = resource_is_pipe_type(pipe_ctx, OPP_HEAD),
.stream = pipe_ctx->stream,
};
@@ -2369,8 +2369,7 @@ void hwss_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx)
.xfm = pipe_ctx->plane_res.xfm,
.dpp = pipe_ctx->plane_res.dpp,
.mpc = dc->res_pool->mpc,
- .mpcc_id = pipe_ctx->plane_res.hubp ?
- pipe_ctx->plane_res.hubp->inst : 0,
+ .mpcc_id = pipe_ctx->plane_res.mpcc_inst,
.is_top_pipe = resource_is_pipe_type(pipe_ctx, OPP_HEAD),
.stream = pipe_ctx->stream,
}
@@ -4317,7 +4316,7 @@ void hwss_program_gamut_remap(struct pipe_ctx *pipe_ctx)
.xfm = pipe_ctx->plane_res.xfm,
.dpp = pipe_ctx->plane_res.dpp,
.mpc = dc->res_pool->mpc,
- .mpcc_id = pipe_ctx->plane_res.hubp->inst,
+ .mpcc_id = pipe_ctx->plane_res.mpcc_inst,
.stream = pipe_ctx->stream,
.plane = pipe_ctx->plane_state,
.is_top_pipe = pipe_ctx->top_pipe == NULL,
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 13/24] drm/amd/display: Add opt-out for DCN6 OutstandingRequests mode-support check
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (11 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 12/24] drm/amd/display: Use mpcc_id instead of hubp instance James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 14/24] drm/amd/display: Make Struct In DCN42 SOC BB Header Static James Lin
` (10 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Jun Lei, Dillon Varone,
James Lin
From: Jun Lei <Jun.Lei@amd.com>
The OutstandingRequestsSupport check fails a mode when the
outstanding-request
buffer window (max_outstanding_reqs * request_size / (DCFCLK *
return_bus_width))
is shorter than the average urgent request latency. Because DCFCLK is
derived
from the SOP's bandwidth, a higher-bandwidth SOP raises DCFCLK, shrinks
that
window, and perversely makes the mode unsupported - so "too much bandwidth"
becomes a failure reason, which defies common sense.
When the ROB size / request limit is not yet fixed, the
SOP bandwidth/latency values are tuned to a family maximum and the check
mis-fires. Add a per-display-config override
outstanding_requests_check_disable
(overrides.hw, matching the existing *_check_disable idiom) that early-outs
the
dcn6 check with both flags left supported. Default off, so existing
behavior is
unchanged. Also wire the flag through the DML JSON translation.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h | 1 +
.../src/dml2_core/dml2_core_dcn6_funcs_mode_support.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
index f402bb933f7d..27ffe7ed11c7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
@@ -487,6 +487,7 @@ struct dml2_display_cfg {
bool mode_support_check_disable;
bool mcache_admissibility_check_disable;
bool surface_viewport_size_check_disable;
+ bool outstanding_requests_check_disable;
double dlg_ref_clk_mhz;
double dispclk_mhz;
double dcfclk_mhz;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c
index d83c7eea462b..cb3cff316b0e 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c
@@ -2380,6 +2380,13 @@ static void dcn6_ms_check_average_latency_supports(
DML_LOG_FUNC_ENTER();
outputs->support.OutstandingRequestsSupport = true;
outputs->support.OutstandingRequestsUrgencyAvoidance = true;
+ /* An SOP being capable of high bandwidth drives DCFCLK up, which shrinks the outstanding-request
+ * buffer window below the request latency and (perversely) fails this check. For analysis of future
+ * SoCs the ROB size / request limit is not yet fixed, so allow the check to be opted out. */
+ if (display_cfg->overrides.hw.outstanding_requests_check_disable) {
+ DML_LOG_FUNC_EXIT();
+ return;
+ }
for (k = 0; k < display_cfg->num_planes; k++) {
outstanding_latency_us = soc_bb->max_outstanding_reqs
* inputs->support.request_size_bytes_luma[k]
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 14/24] drm/amd/display: Make Struct In DCN42 SOC BB Header Static
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (12 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 13/24] drm/amd/display: Add opt-out for DCN6 OutstandingRequests mode-support check James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 15/24] drm/amd/display: Refactor Per-DPM Derate Logic James Lin
` (9 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Austin Zheng, Dillon Varone,
James Lin
From: Austin Zheng <Austin.Zheng@amd.com>
[Why/How]
Make dcn42_ddr5_power_management_parameters struct static to avoid
having multiple declarations of the structure
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
index 51cae3efe310..b21beebc52bd 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
@@ -219,7 +219,7 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
};
/* DCN42 params for DDR5 */
-struct dml2_soc_power_management_parameters dcn42_ddr5_power_management_parameters = {
+static struct dml2_soc_power_management_parameters dcn42_ddr5_power_management_parameters = {
.dram_clk_change_blackout_us = 36,
.fclk_change_blackout_us = 0,
.g7_ppt_blackout_us = 0,
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 15/24] drm/amd/display: Refactor Per-DPM Derate Logic
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (13 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 14/24] drm/amd/display: Make Struct In DCN42 SOC BB Header Static James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 16/24] drm/amd/display: Update Derates And Set Default Per-DPM Derates James Lin
` (8 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Austin Zheng, Dillon Varone,
James Lin
From: Austin Zheng <Austin.Zheng@amd.com>
[Why/How]
1. DPMM also needs to consider the per-DPM derate when calculating the
clocks
that will be used by mode programming.
Otherwise DPMM calculations can result in rounding up to the next DPM
anyways.
clk index value used by mode support is not reliable when trying to
determine the actual
per-dpm derate.
2. Also update how per-dpm derates are stored so each derate applies until
an upper bound.
Upperbound of 0 signifies this derate is used for the remaining DPMs.
To simplify logic, all derates for all clocks should have the same number
of entries
and the last entry should have an upperbound of 0.
3. Deprecate system_active_average derates from the derate table and move
them to the per-DPM structure
The remaining derates (urgent, dcn_mall, system idle) are unchanged
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../dml21/inc/bounding_boxes/dcn42_soc_bb.h | 25 ++---
.../dml21/inc/bounding_boxes/dcn42b_soc_bb.h | 25 ++---
.../dml21/inc/bounding_boxes/dcn4_soc_bb.h | 25 ++---
.../dml21/inc/dml_top_soc_parameter_types.h | 44 +++++++-
.../src/dml2_core/dml2_core_dcn4_calcs.c | 19 ++--
.../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 106 +++++++++++++++++-
.../src/inc/dml2_internal_shared_types.h | 1 +
7 files changed, 181 insertions(+), 64 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
index b21beebc52bd..52f906e41fb4 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
@@ -16,13 +16,6 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
- .system_active_average = {
- .dram_derate_percent_pixel = 30,
- .dram_derate_percent_vm = 30,
- .dram_derate_percent_pixel_and_vm = 30,
- .fclk_derate_percent = 60,
- .dcfclk_derate_percent = 60,
- },
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
@@ -45,6 +38,17 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
.dcfclk_derate_percent = 60,
},
},
+ .derate_table_per_dpm = {
+ .dram_per_dpm_derate_pixel = {
+ {.derate_percent = 30, .clk_upperbound_threshold_khz = 0},
+ },
+ .fclk_per_dpm_derate = {
+ {.derate_percent = 60, .clk_upperbound_threshold_khz = 0},
+ },
+ .dcfclk_per_dpm_derate = {
+ {.derate_percent = 60, .clk_upperbound_threshold_khz = 0},
+ },
+ },
.writeback = {
.base_latency_us = 12,
.scaling_factor_us = 0,
@@ -134,13 +138,6 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
- .system_active_average = {
- .dram_derate_percent_pixel = 30,
- .dram_derate_percent_vm = 30,
- .dram_derate_percent_pixel_and_vm = 30,
- .fclk_derate_percent = 60,
- .dcfclk_derate_percent = 60,
- },
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h
index 5d844ff4b671..33eb583e3365 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h
@@ -17,13 +17,6 @@ static const struct dml2_soc_qos_parameters dml_dcn42b_variant_a_soc_qos_params
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
- .system_active_average = {
- .dram_derate_percent_pixel = 30,
- .dram_derate_percent_vm = 30,
- .dram_derate_percent_pixel_and_vm = 30,
- .fclk_derate_percent = 60,
- .dcfclk_derate_percent = 60,
- },
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
@@ -46,6 +39,17 @@ static const struct dml2_soc_qos_parameters dml_dcn42b_variant_a_soc_qos_params
.dcfclk_derate_percent = 60,
},
},
+ .derate_table_per_dpm = {
+ .dram_per_dpm_derate_pixel = {
+ {.derate_percent = 30, .clk_upperbound_threshold_khz = 0},
+ },
+ .fclk_per_dpm_derate = {
+ {.derate_percent = 60, .clk_upperbound_threshold_khz = 0},
+ },
+ .dcfclk_per_dpm_derate = {
+ {.derate_percent = 60, .clk_upperbound_threshold_khz = 0},
+ },
+ },
.writeback = {
.base_latency_us = 12,
.scaling_factor_us = 0,
@@ -134,13 +138,6 @@ static const struct dml2_soc_bb dml2_socbb_dcn42b = {
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
- .system_active_average = {
- .dram_derate_percent_pixel = 30,
- .dram_derate_percent_vm = 30,
- .dram_derate_percent_pixel_and_vm = 30,
- .fclk_derate_percent = 60,
- .dcfclk_derate_percent = 60,
- },
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h
index 16a4f97bca4e..f26366ebeeda 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h
@@ -16,13 +16,6 @@ static const struct dml2_soc_qos_parameters dml_dcn4_variant_a_soc_qos_params =
.fclk_derate_percent = 76,
.dcfclk_derate_percent = 100,
},
- .system_active_average = {
- .dram_derate_percent_pixel = 17,
- .dram_derate_percent_vm = 0,
- .dram_derate_percent_pixel_and_vm = 0,
- .fclk_derate_percent = 57,
- .dcfclk_derate_percent = 75,
- },
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 40,
.dram_derate_percent_vm = 0,
@@ -45,6 +38,17 @@ static const struct dml2_soc_qos_parameters dml_dcn4_variant_a_soc_qos_params =
.dcfclk_derate_percent = 100,
},
},
+ .derate_table_per_dpm = {
+ .dram_per_dpm_derate_pixel = {
+ {.derate_percent = 17, .clk_upperbound_threshold_khz = 0},
+ },
+ .fclk_per_dpm_derate = {
+ {.derate_percent = 57, .clk_upperbound_threshold_khz = 0},
+ },
+ .dcfclk_per_dpm_derate = {
+ {.derate_percent = 75, .clk_upperbound_threshold_khz = 0},
+ },
+ },
.writeback = {
.base_latency_us = 12,
.scaling_factor_us = 0,
@@ -142,13 +146,6 @@ static const struct dml2_soc_bb dml2_socbb_dcn401 = {
.fclk_derate_percent = 76,
.dcfclk_derate_percent = 100,
},
- .system_active_average = {
- .dram_derate_percent_pixel = 15,
- .dram_derate_percent_vm = 0,
- .dram_derate_percent_pixel_and_vm = 0,
- .fclk_derate_percent = 57,
- .dcfclk_derate_percent = 75,
- },
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 40,
.dram_derate_percent_vm = 0,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
index b830e95b27c8..45208f804d2b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
@@ -20,7 +20,6 @@ struct dml2_soc_derate_values {
struct dml2_soc_derates {
struct dml2_soc_derate_values system_active_urgent;
- struct dml2_soc_derate_values system_active_average;
struct dml2_soc_derate_values dcn_mall_prefetch_urgent;
struct dml2_soc_derate_values dcn_mall_prefetch_average;
struct dml2_soc_derate_values system_idle_average;
@@ -71,8 +70,22 @@ enum dml2_qos_param_type {
dml2_qos_param_type_dcn4x
};
-//Indicies mapped to DPM level
-// Unpopulated indicies should fallback to the global derate value.
+// Per-DPM derate structure: each element pairs a derate percentage with its clock threshold
+// Requirements:
+// - Index 0 must always be populated (the base/default derate)
+// - Last populated entry must have clk_upperbound_threshold_khz = 0
+// - All clock arrays within a power state should have the same number of entries
+// - If a non-zero DPM index has derate_percent = 0, fall back to index 0
+// Unpopulated derates should fallback to the global derate value.
+// Each element pairs a derate percentage with its threshold
+struct dml2_soc_derate_values_per_dpm_v2 {
+ unsigned int derate_percent;
+ unsigned int clk_upperbound_threshold_khz;
+};
+
+// Legacy structure - for backward compatibility as driver debug values can override the values. (will temporarily break driver overrides)
+// Per-DPM derate arrays for system_active_average (the only power state that varies by DPM)
+// Urgent derates are constant across DPMs and come from derate_table.system_active_urgent
struct dml2_soc_derate_values_per_dpm {
unsigned int dram_derate_percent_pixel[DML_MAX_CLK_TABLE_SIZE];
unsigned int fclk_derate_percent[DML_MAX_CLK_TABLE_SIZE];
@@ -80,12 +93,31 @@ struct dml2_soc_derate_values_per_dpm {
};
struct dml2_soc_derates_per_dpm {
- struct dml2_soc_derate_values_per_dpm system_active_derates_per_dpm;
+ // Union allows both layouts to coexist without increasing struct size
+ // Anonymous structs allow direct member access without .v1 or .v2 prefix
+ union {
+ // Legacy layout - used by soc_and_ip_translator (unchanged access pattern)
+ // TODO: Remove after soc_and_ip_translator migration is complete
+ struct {
+ struct dml2_soc_derate_values_per_dpm system_active_derates_per_dpm;
+ unsigned int min_uclk_khz_threshold[DML_MAX_CLK_TABLE_SIZE];
+ unsigned int min_fclk_khz_threshold[DML_MAX_CLK_TABLE_SIZE];
+ unsigned int min_dcfclk_khz_threshold[DML_MAX_CLK_TABLE_SIZE];
+ };
+
+ // New layout - used by DML internally
+ // Arrays of derate/threshold pairs, one per DPM level
+ struct {
+ struct dml2_soc_derate_values_per_dpm_v2 dram_per_dpm_derate_pixel[DML_MAX_CLK_TABLE_SIZE];
+ struct dml2_soc_derate_values_per_dpm_v2 fclk_per_dpm_derate[DML_MAX_CLK_TABLE_SIZE];
+ struct dml2_soc_derate_values_per_dpm_v2 dcfclk_per_dpm_derate[DML_MAX_CLK_TABLE_SIZE];
+ };
+ };
};
struct dml2_soc_qos_parameters {
- struct dml2_soc_derates derate_table;
- struct dml2_soc_derates_per_dpm derate_table_per_dpm;
+ struct dml2_soc_derates derate_table; // Single-value derates (source of truth for urgent, idle, mall_prefetch)
+ struct dml2_soc_derates_per_dpm derate_table_per_dpm; // Per-DPM derates for system_active_average only
struct {
unsigned int base_latency_us;
unsigned int scaling_factor_us;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index d943cc8bf60e..475bdeb39d21 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -2739,16 +2739,15 @@ static double dml_get_return_bandwidth_available(
derate_fabric_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.fclk_derate_percent / 100.0;
derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100.0;
} else { // just assume sys_active
- // use per dpm derates if the values are populated. Otherwise use global derates
- derate_sdp_factor = soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dcfclk_derate_percent[uclk_dpm_level] != 0 ?
- soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dcfclk_derate_percent[uclk_dpm_level] / 100.0 :
- soc->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100.0;
- derate_fabric_factor = soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.fclk_derate_percent[uclk_dpm_level] != 0 ?
- soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.fclk_derate_percent[uclk_dpm_level] / 100.0 :
- soc->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100.0;
- derate_dram_factor = soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dram_derate_percent_pixel[uclk_dpm_level] != 0 ?
- soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dram_derate_percent_pixel[uclk_dpm_level] / 100.0 :
- soc->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100.0;
+ derate_sdp_factor = (soc->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[uclk_dpm_level].derate_percent != 0 ?
+ soc->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[uclk_dpm_level].derate_percent :
+ soc->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[0].derate_percent) / 100.0;
+ derate_fabric_factor = (soc->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[uclk_dpm_level].derate_percent != 0 ?
+ soc->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[uclk_dpm_level].derate_percent :
+ soc->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[0].derate_percent) / 100.0;
+ derate_dram_factor = (soc->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[uclk_dpm_level].derate_percent != 0 ?
+ soc->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[uclk_dpm_level].derate_percent :
+ soc->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[0].derate_percent) / 100.0;
}
} else { // urgent bw
if (state_type == dml2_core_internal_soc_state_svp_prefetch) {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
index 22c757cdac07..54a1f9c13dbf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
@@ -6,6 +6,8 @@
#include "dml2_internal_shared_types.h"
#include "dml_top_types.h"
#include "lib_float_math.h"
+#include "dml2_debug.h"
+
static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const struct dml2_dram_params *dram_config, struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table)
{
@@ -55,16 +57,101 @@ static unsigned long dml_round_up(double a)
return (unsigned long)a;
}
+/* Calculate DPM index to use for per-DPM derates
+ * Iterates through DPM levels - if calculated clocks exceed thresholds increment to next DPM level
+ */
+static void calculate_derate_index(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
+{
+ const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
+ double required_bw_dram_kbps, required_bw_sdp_kbps;
+ int i;
+
+ /* Default to DPM 0 (lowest power state) */
+ in_out->derate_dpm_index = 0;
+
+ /* Get required bandwidths from mode support */
+ required_bw_dram_kbps = mode_support_result->global.active.average_bw_dram_kbps;
+ required_bw_sdp_kbps = mode_support_result->global.active.average_bw_sdp_kbps;
+
+ /* Iterate through DPM levels from lowest to highest to find the first level
+ * whose available bandwidth can satisfy the requirements.
+ */
+ for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) {
+ unsigned int dram_threshold = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[i].clk_upperbound_threshold_khz;
+ unsigned int fclk_threshold = in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[i].clk_upperbound_threshold_khz;
+ unsigned int dcfclk_threshold = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[i].clk_upperbound_threshold_khz;
+ unsigned int uclk_derate = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[i].derate_percent;
+ unsigned int fclk_derate = in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[i].derate_percent;
+ unsigned int dcfclk_derate = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[i].derate_percent;
+ double max_dram_bw_for_dpm = 0, max_fclk_bw_for_dpm = 0, max_dcfclk_bw_for_dpm = 0;
+
+ /* Skip entries with 0 derate (use fallback logic) */
+ if (uclk_derate == 0 || fclk_derate == 0 || dcfclk_derate == 0) {
+ DML_ASSERT(0); // derate should be populated (at least 1 entry in the per_dpm table that can be applied for all DPMs
+ }
+
+ /* Threshold of 0 indicates last entry - this DPM level handles all higher bandwidths */
+ if (dram_threshold == 0 && fclk_threshold == 0 && dcfclk_threshold == 0) {
+ in_out->derate_dpm_index = i;
+ break;
+ }
+
+ /* Calculate maximum available bandwidth at this DPM level
+ * Available BW = max_clock_at_threshold * derate * conversion_factor */
+
+ /* For DRAM: convert threshold clock to bandwidth */
+ if (!in_out->soc_bb->clk_table.dram_config.alt_clock_bw_conversion) {
+ unsigned long uclk_bytes_per_tick = in_out->soc_bb->clk_table.dram_config.channel_count
+ * in_out->soc_bb->clk_table.dram_config.channel_width_bytes
+ * in_out->soc_bb->clk_table.dram_config.transactions_per_clock;
+ max_dram_bw_for_dpm = (double)dram_threshold * uclk_bytes_per_tick * ((double)uclk_derate / 100.0);
+ } else {
+ /* use pre-computed table - find bandwidth at threshold clock */
+ for (unsigned int j = 0; j < in_out->min_clk_table->dram_bw_table.num_entries; j++) {
+ if (in_out->min_clk_table->dram_bw_table.entries[j].min_uclk_khz >= dram_threshold) {
+ max_dram_bw_for_dpm = (double)in_out->min_clk_table->dram_bw_table.entries[j].pre_derate_dram_bw_kbps;
+ break;
+ }
+ }
+ }
+
+ max_fclk_bw_for_dpm = (double)fclk_threshold
+ * in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes
+ * ((double)fclk_derate / 100.0);
+
+ max_dcfclk_bw_for_dpm = (double)dcfclk_threshold
+ * in_out->soc_bb->return_bus_width_bytes
+ * ((double)dcfclk_derate / 100.0);
+
+ /* Check if this DPM level's available bandwidth satisfies all requirements
+ * All bandwidth paths must be satisfied to use this DPM level */
+ if (((dram_threshold == 0) || (required_bw_dram_kbps <= max_dram_bw_for_dpm)) &&
+ ((fclk_threshold == 0) || (required_bw_sdp_kbps <= max_fclk_bw_for_dpm)) &&
+ ((dcfclk_threshold == 0) || (required_bw_sdp_kbps <= max_dcfclk_bw_for_dpm))) {
+ in_out->derate_dpm_index = i;
+ break;
+ }
+ }
+}
+
static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
{
double min_uclk_avg, min_uclk_urgent, min_uclk_bw;
double min_fclk_avg, min_fclk_urgent, min_fclk_bw;
double min_dcfclk_avg, min_dcfclk_urgent, min_dcfclk_bw;
double min_uclk_latency, min_fclk_latency, min_dcfclk_latency;
+ int dpm_index, uclk_avg_derate_percent, fclk_avg_derate_percent, dcfclk_avg_derate_percent;
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
+ dpm_index = in_out->derate_dpm_index;
+
+ /* Get average derates from system_active_average per-DPM table */
+ uclk_avg_derate_percent = (in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[dpm_index].derate_percent != 0 || dpm_index == 0) ?
+ in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[dpm_index].derate_percent :
+ in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[0].derate_percent;
+
min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.average_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)),
+ / ((double)uclk_avg_derate_percent / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
if (in_out->display_cfg->display_config.hostvm_enable)
@@ -78,16 +165,22 @@ static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dp
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
+ fclk_avg_derate_percent = (in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[dpm_index].derate_percent != 0 || dpm_index == 0) ?
+ in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[dpm_index].derate_percent :
+ in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[0].derate_percent;
min_fclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
- min_fclk_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100);
+ min_fclk_avg = (double)min_fclk_avg / ((double)fclk_avg_derate_percent / 100);
min_fclk_urgent = (double)mode_support_result->global.active.urgent_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
min_fclk_urgent = (double)min_fclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.fclk_derate_percent / 100);
min_fclk_bw = min_fclk_urgent > min_fclk_avg ? min_fclk_urgent : min_fclk_avg;
+ dcfclk_avg_derate_percent = (in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[dpm_index].derate_percent != 0 || dpm_index == 0) ?
+ in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[dpm_index].derate_percent :
+ in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[0].derate_percent;
min_dcfclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->return_bus_width_bytes;
- min_dcfclk_avg = (double)min_dcfclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100);
+ min_dcfclk_avg = (double)min_dcfclk_avg / ((double)dcfclk_avg_derate_percent / 100);
min_dcfclk_urgent = (double)mode_support_result->global.active.urgent_bw_sdp_kbps / in_out->soc_bb->return_bus_width_bytes;
min_dcfclk_urgent = (double)min_dcfclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dcfclk_derate_percent / 100);
@@ -145,7 +238,7 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
/* assumes DF throttling is disabled */
min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)),
+ / ((double)in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[in_out->derate_dpm_index].derate_percent / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
@@ -155,7 +248,7 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
min_fclk_avg = (double)mode_support_result->global.svp_prefetch.average_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
- min_fclk_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100);
+ min_fclk_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[in_out->derate_dpm_index].derate_percent / 100);
min_fclk_urgent = (double)mode_support_result->global.svp_prefetch.urgent_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
min_fclk_urgent = (double)min_fclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.fclk_derate_percent / 100);
@@ -163,7 +256,7 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
min_fclk_bw = min_fclk_urgent > min_fclk_avg ? min_fclk_urgent : min_fclk_avg;
min_dcfclk_avg = (double)mode_support_result->global.svp_prefetch.average_bw_sdp_kbps / in_out->soc_bb->return_bus_width_bytes;
- min_dcfclk_avg = (double)min_dcfclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100);
+ min_dcfclk_avg = (double)min_dcfclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[in_out->derate_dpm_index].derate_percent / 100);
min_dcfclk_urgent = (double)mode_support_result->global.svp_prefetch.urgent_bw_sdp_kbps / in_out->soc_bb->return_bus_width_bytes;
min_dcfclk_urgent = (double)min_dcfclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dcfclk_derate_percent / 100);
@@ -633,6 +726,7 @@ static bool map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_o
double dispclk_khz;
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
+ calculate_derate_index(in_out);
calculate_system_active_minimums(in_out);
calculate_svp_prefetch_minimums(in_out);
calculate_idle_minimums(in_out);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
index a18f067fe53f..8ddf58da2eed 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
@@ -246,6 +246,7 @@ struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out {
* Output
*/
struct dml2_display_cfg_programming *programming;
+ int derate_dpm_index;
};
struct dml2_dpmm_map_watermarks_params_in_out {
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 16/24] drm/amd/display: Update Derates And Set Default Per-DPM Derates
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (14 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 15/24] drm/amd/display: Refactor Per-DPM Derate Logic James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 17/24] drm/amd/display: Unify CalculateFlipSchedule Logic James Lin
` (7 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Austin Zheng, Dillon Varone,
James Lin
From: Austin Zheng <Austin.Zheng@amd.com>
[Why/How]
Adjusted derates to allow DPM0 to be used on certain display configs.
For DCN42, MALL derates are not relevant so they can be modified to
prevent DPMM from rounding up to the next DPM level.
Also set the default DPM0 derates that can be used.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
index 52f906e41fb4..04c5f09499ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
@@ -11,7 +11,7 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
.derate_table = {
.system_active_urgent = {
.dram_derate_percent_pixel = 65,
- .dram_derate_percent_vm = 30,
+ .dram_derate_percent_vm = 50,
.dram_derate_percent_pixel_and_vm = 60,
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
@@ -24,11 +24,11 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
.dcfclk_derate_percent = 80,
},
.dcn_mall_prefetch_average = {
- .dram_derate_percent_pixel = 30,
+ .dram_derate_percent_pixel = 33,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
- .fclk_derate_percent = 60,
- .dcfclk_derate_percent = 60,
+ .fclk_derate_percent = 66,
+ .dcfclk_derate_percent = 66,
},
.system_idle_average = {
.dram_derate_percent_pixel = 30,
@@ -39,13 +39,17 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
},
},
.derate_table_per_dpm = {
+ // DPM0 can have slightly higher derate values. Rest of the DPMs should match the global values.
.dram_per_dpm_derate_pixel = {
+ {.derate_percent = 33, .clk_upperbound_threshold_khz = 400000},
{.derate_percent = 30, .clk_upperbound_threshold_khz = 0},
},
.fclk_per_dpm_derate = {
+ {.derate_percent = 66, .clk_upperbound_threshold_khz = 400000},
{.derate_percent = 60, .clk_upperbound_threshold_khz = 0},
},
.dcfclk_per_dpm_derate = {
+ {.derate_percent = 66, .clk_upperbound_threshold_khz = 200000},
{.derate_percent = 60, .clk_upperbound_threshold_khz = 0},
},
},
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 17/24] drm/amd/display: Unify CalculateFlipSchedule Logic
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (15 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 16/24] drm/amd/display: Update Derates And Set Default Per-DPM Derates James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 18/24] drm/amd/display: Skip eDP teardown while forced PSR is active James Lin
` (6 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Austin Zheng, Dillon Varone,
James Lin
From: Austin Zheng <Austin.Zheng@amd.com>
[Why]
CalculateFlipSchedule has slightly different calculations depending on
if it was called by mode support or mode programming.
Mode support calculates the lower bound of the required bandwidth for
immediate flips.
This takes into the account of the register limits to ensure it is still
programmable.
Mode programming uses the required bandwidth for immediate flips on a
per-plane basis
to calculate the number of dst_y lines needed to achieve this bandwidth.
Usually the immediate flip bandwidth per plane determined by mode
programming is above the lower bound
calculated by mode support.
However, mode programming can fail if that isn't the case since a bandwidth
lower than the lower bound will
end up exceeding the register limit used by hardware.
e.g. The proportion of a single plane's flip bandwidth w.r.t to the total
bandwidth available for all planes
can result in one of the planes having a lower BW than the lower bound
calculated in mode support
[How]
Update function to always use the use_lb_flip_bw path.
Add calculations for dst_y_per_vm/row_flip lines.
Consolidate calculation of lb_flip_bw by having it consider register
limits:
Instead of doing two steps of:
1. Taking the max of the bandwidths without considering register limits.
2. Taking the max of itself with the bandwidths with register limits
accounted for.
Do it in one step as it is easy to miss either step 1 or 2.
Also add some local variables for intermediate values and remove no longer
referenced inputs to improve readability.
Also increase DCN401 max_flip_time_lines by 2 lines to ensure previously
supported configs remain supported as worst-case
bandwidth can increase compared to before.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../dml21/inc/bounding_boxes/dcn4_soc_bb.h | 2 +-
.../src/dml2_core/dml2_core_dcn4_calcs.c | 164 +++++++-----------
.../src/dml2_core/dml2_core_shared_types.h | 3 +
3 files changed, 66 insertions(+), 103 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h
index f26366ebeeda..ed82ef55b651 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h
@@ -342,7 +342,7 @@ static const struct dml2_ip_capabilities dml2_dcn401_max_ip_caps = {
.compressed_buffer_segment_size_in_kbytes = 64,
.cursor_buffer_size = 24,
.max_flip_time_us = 80,
- .max_flip_time_lines = 32,
+ .max_flip_time_lines = 34,
.hostvm_mode = 0,
.subvp_drr_scheduling_margin_us = 100,
.subvp_prefetch_end_to_mall_start_us = 15,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index 475bdeb39d21..5a1b710b9ec8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -6555,7 +6555,6 @@ static void CalculateFlipSchedule(
bool GPUVMEnable,
double vm_bytes, // vm_bytes
double DPTEBytesPerRow, // dpte_row_bytes
- double BandwidthAvailableForImmediateFlip,
unsigned int TotImmediateFlipBytes,
enum dml2_source_format_class SourcePixelFormat,
double LineTime,
@@ -6567,7 +6566,6 @@ static void CalculateFlipSchedule(
bool use_one_row_for_frame_flip,
unsigned int max_flip_time_us,
unsigned int max_flip_time_lines,
- unsigned int per_pipe_flip_bytes,
unsigned int meta_row_bytes,
unsigned int meta_row_height,
unsigned int meta_row_height_chroma,
@@ -6589,7 +6587,6 @@ static void CalculateFlipSchedule(
DML_LOG_VERBOSE("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
DML_LOG_VERBOSE("DML::%s: ip.max_flip_time_us = %d\n", __func__, max_flip_time_us);
DML_LOG_VERBOSE("DML::%s: ip.max_flip_time_lines = %d\n", __func__, max_flip_time_lines);
- DML_LOG_VERBOSE("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
DML_LOG_VERBOSE("DML::%s: TotImmediateFlipBytes = %u\n", __func__, TotImmediateFlipBytes);
DML_LOG_VERBOSE("DML::%s: use_lb_flip_bw = %u\n", __func__, use_lb_flip_bw);
DML_LOG_VERBOSE("DML::%s: iflip_enable = %u\n", __func__, iflip_enable);
@@ -6637,104 +6634,71 @@ static void CalculateFlipSchedule(
#endif
DML_ASSERT(l->min_row_time > 0);
- if (use_lb_flip_bw) {
- // For mode check, calculation the flip bw requirement with worst case flip time
- l->max_flip_time = math_min2(math_min2(l->min_row_time, (double)max_flip_time_lines * LineTime / VRatio),
- math_max2(Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded, (double)max_flip_time_us));
-
- //The lower bound on flip bandwidth
- // Note: The get_urgent_bandwidth_required already consider dpte_row_bw and meta_row_bw in bandwidth calculation, so leave final_flip_bw = 0 if iflip not required
- l->lb_flip_bw = 0;
-
- if (iflip_enable) {
- l->hvm_scaled_vm_bytes = vm_bytes * HostVMInefficiencyFactor;
- l->num_rows = 2;
- l->hvm_scaled_row_bytes = (l->num_rows * l->dpte_row_bytes * HostVMInefficiencyFactor + l->num_rows * meta_row_bytes);
- l->hvm_scaled_vm_row_bytes = l->hvm_scaled_vm_bytes + l->hvm_scaled_row_bytes;
- l->lb_flip_bw = math_max3(
- l->hvm_scaled_vm_row_bytes / (l->max_flip_time - Tno_bw_flip),
- l->hvm_scaled_vm_bytes / (l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded),
- l->hvm_scaled_row_bytes / (l->max_flip_time - Tvm_trips_flip_rounded));
-#ifdef __DML_VBA_DEBUG__
- DML_LOG_VERBOSE("DML::%s: max_flip_time = %f\n", __func__, l->max_flip_time);
- DML_LOG_VERBOSE("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_bytes);
- DML_LOG_VERBOSE("DML::%s: total row bytes (%f row, hvm ineff scaled) = %f\n", __func__, l->num_rows, l->hvm_scaled_row_bytes);
- DML_LOG_VERBOSE("DML::%s: total vm+row bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_row_bytes);
- DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm and row = %f\n", __func__, l->hvm_scaled_vm_row_bytes / (l->max_flip_time - Tno_bw_flip));
- DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm = %f\n", __func__, l->hvm_scaled_vm_bytes / (l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded));
- DML_LOG_VERBOSE("DML::%s: lb_flip_bw for row = %f\n", __func__, l->hvm_scaled_row_bytes / (l->max_flip_time - Tvm_trips_flip_rounded));
-
- if (l->lb_flip_bw > 0) {
- DML_LOG_VERBOSE("DML::%s: mode_support est Tvm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw);
- DML_LOG_VERBOSE("DML::%s: mode_support est Tr0_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / l->num_rows);
- DML_LOG_VERBOSE("DML::%s: mode_support est dst_y_per_vm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw / LineTime);
- DML_LOG_VERBOSE("DML::%s: mode_support est dst_y_per_row_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / LineTime / l->num_rows);
- DML_LOG_VERBOSE("DML::%s: Tvm_trips_flip_rounded + 2*Tr0_trips_flip_rounded = %f\n", __func__, (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded));
- }
-#endif
- l->lb_flip_bw = math_max3(l->lb_flip_bw,
- l->hvm_scaled_vm_bytes / (31 * LineTime) - Tno_bw_flip,
- (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15 * LineTime));
-
-#ifdef __DML_VBA_DEBUG__
- DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm reg limit = %f\n", __func__, l->hvm_scaled_vm_bytes / (31 * LineTime) - Tno_bw_flip);
- DML_LOG_VERBOSE("DML::%s: lb_flip_bw for row reg limit = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15 * LineTime));
-#endif
- }
-
- *final_flip_bw = l->lb_flip_bw;
-
- *dst_y_per_vm_flip = 1; // not used
- *dst_y_per_row_flip = 1; // not used
- *ImmediateFlipSupportedForPipe = l->min_row_time >= (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded);
- } else {
- if (iflip_enable) {
- l->ImmediateFlipBW = (double)per_pipe_flip_bytes * BandwidthAvailableForImmediateFlip / (double)TotImmediateFlipBytes; // flip_bw(i)
-
-#ifdef __DML_VBA_DEBUG__
- DML_LOG_VERBOSE("DML::%s: per_pipe_flip_bytes = %d\n", __func__, per_pipe_flip_bytes);
- DML_LOG_VERBOSE("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
- DML_LOG_VERBOSE("DML::%s: ImmediateFlipBW = %f\n", __func__, l->ImmediateFlipBW);
- DML_LOG_VERBOSE("DML::%s: portion of flip bw = %f\n", __func__, (double)per_pipe_flip_bytes / (double)TotImmediateFlipBytes);
-#endif
- if (l->ImmediateFlipBW == 0) {
- l->Tvm_flip = 0;
- l->Tr0_flip = 0;
- } else {
- l->Tvm_flip = math_max3(Tvm_trips_flip,
- Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->ImmediateFlipBW,
- LineTime / 4.0);
-
- l->Tr0_flip = math_max3(Tr0_trips_flip,
- (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / l->ImmediateFlipBW,
- LineTime / 4.0);
- }
-#ifdef __DML_VBA_DEBUG__
- DML_LOG_VERBOSE("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, vm_bytes * HostVMInefficiencyFactor);
- DML_LOG_VERBOSE("DML::%s: total row bytes (hvm ineff scaled, one row) = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes));
-
- DML_LOG_VERBOSE("DML::%s: Tvm_flip = %f (bw-based), Tvm_trips_flip = %f (latency-based)\n", __func__, Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->ImmediateFlipBW, Tvm_trips_flip);
- DML_LOG_VERBOSE("DML::%s: Tr0_flip = %f (bw-based), Tr0_trips_flip = %f (latency-based)\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / l->ImmediateFlipBW, Tr0_trips_flip);
-#endif
- *dst_y_per_vm_flip = math_ceil2(4.0 * (l->Tvm_flip / LineTime), 1.0) / 4.0;
- *dst_y_per_row_flip = math_ceil2(4.0 * (l->Tr0_flip / LineTime), 1.0) / 4.0;
-
- *final_flip_bw = math_max2(vm_bytes * HostVMInefficiencyFactor / (*dst_y_per_vm_flip * LineTime),
- (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (*dst_y_per_row_flip * LineTime));
-
- if (*dst_y_per_vm_flip >= 32 || *dst_y_per_row_flip >= 16 || l->Tvm_flip + 2 * l->Tr0_flip > l->min_row_time) {
- *ImmediateFlipSupportedForPipe = false;
- } else {
- *ImmediateFlipSupportedForPipe = iflip_enable;
- }
+ // For mode check, calculation the flip bw requirement with worst case flip time
+ l->max_flip_time = math_min2(math_min2(l->min_row_time, (double)max_flip_time_lines * LineTime / VRatio),
+ math_max2(Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded, (double)max_flip_time_us));
+
+ //The lower bound on flip bandwidth
+ // Note: The get_urgent_bandwidth_required already consider dpte_row_bw and meta_row_bw in bandwidth calculation, so leave final_flip_bw = 0 if iflip not required
+ l->lb_flip_bw = 0;
+
+ l->vm_and_row_time_budget = l->max_flip_time - Tno_bw_flip;
+ l->vm_time_budget = l->max_flip_time - Tno_bw_flip - 2 * Tr0_trips_flip_rounded;
+ l->row_time_budget = l->max_flip_time - Tvm_trips_flip_rounded;
+
+ if (iflip_enable) {
+ l->hvm_scaled_vm_bytes = vm_bytes * HostVMInefficiencyFactor;
+ l->num_rows = 2;
+ l->hvm_scaled_row_bytes = (l->num_rows * l->dpte_row_bytes * HostVMInefficiencyFactor + l->num_rows * meta_row_bytes);
+ l->hvm_scaled_vm_row_bytes = l->hvm_scaled_vm_bytes + l->hvm_scaled_row_bytes;
+ l->lb_flip_bw = math_max3(
+ l->hvm_scaled_vm_row_bytes / l->vm_and_row_time_budget,
+ l->hvm_scaled_vm_bytes / math_min2(l->vm_time_budget, 31.75 * LineTime - Tno_bw_flip),
+ l->dpte_row_bytes * HostVMInefficiencyFactor / math_min2(l->row_time_budget, 15.75 * LineTime));
+#ifdef __DML_VBA_DEBUG__
+ DML_LOG_VERBOSE("DML::%s: max_flip_time = %f\n", __func__, l->max_flip_time);
+ DML_LOG_VERBOSE("DML::%s: total vm bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_bytes);
+ DML_LOG_VERBOSE("DML::%s: total row bytes (%f row, hvm ineff scaled) = %f\n", __func__, l->num_rows, l->hvm_scaled_row_bytes);
+ DML_LOG_VERBOSE("DML::%s: total vm+row bytes (hvm ineff scaled) = %f\n", __func__, l->hvm_scaled_vm_row_bytes);
+ DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm and row = %f\n", __func__, l->hvm_scaled_vm_row_bytes / l->vm_and_row_time_budget);
+ DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm = %f\n", __func__, l->hvm_scaled_vm_bytes / l->vm_time_budget);
+ DML_LOG_VERBOSE("DML::%s: lb_flip_bw for row = %f\n", __func__, l->hvm_scaled_row_bytes / l->row_time_budget);
+ DML_LOG_VERBOSE("DML::%s: lb_flip_bw for vm reg limit = %f\n", __func__, l->hvm_scaled_vm_bytes / (31.75 * LineTime - Tno_bw_flip));
+ DML_LOG_VERBOSE("DML::%s: lb_flip_bw for row reg limit = %f\n", __func__, (l->dpte_row_bytes * HostVMInefficiencyFactor + meta_row_bytes) / (15.75 * LineTime));
+#endif
+ }
+
+ *final_flip_bw = l->lb_flip_bw;
+
+ if (l->lb_flip_bw > 0) {
+ DML_LOG_VERBOSE("DML::%s: mode_support est Tvm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw);
+ DML_LOG_VERBOSE("DML::%s: mode_support est Tr0_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / l->num_rows);
+ DML_LOG_VERBOSE("DML::%s: mode_support est dst_y_per_vm_flip = %f (bw-based)\n", __func__, Tno_bw_flip + l->hvm_scaled_vm_bytes / l->lb_flip_bw / LineTime);
+ DML_LOG_VERBOSE("DML::%s: mode_support est dst_y_per_row_flip = %f (bw-based)\n", __func__, l->hvm_scaled_row_bytes / l->lb_flip_bw / LineTime / l->num_rows);
+ DML_LOG_VERBOSE("DML::%s: Tvm_trips_flip_rounded + 2*Tr0_trips_flip_rounded = %f\n", __func__, (Tvm_trips_flip_rounded + 2 * Tr0_trips_flip_rounded));
+
+ l->Tvm_flip = math_max3(Tvm_trips_flip,
+ Tno_bw_flip + vm_bytes * HostVMInefficiencyFactor / l->lb_flip_bw,
+ LineTime / 4.0);
+ l->Tr0_flip = math_max3(Tr0_trips_flip,
+ l->dpte_row_bytes * HostVMInefficiencyFactor / l->lb_flip_bw,
+ LineTime / 4.0);
+
+ *dst_y_per_vm_flip = math_ceil2(4.0 * l->Tvm_flip / LineTime, 1.0) / 4.0;
+ *dst_y_per_row_flip = math_ceil2(4.0 * l->Tr0_flip / LineTime, 1.0) / 4.0;
+
+ if (*dst_y_per_vm_flip >= 32 || *dst_y_per_row_flip >= 16 || l->Tvm_flip + 2 * l->Tr0_flip > l->min_row_time) {
+ *ImmediateFlipSupportedForPipe = false;
} else {
- l->Tvm_flip = 0;
- l->Tr0_flip = 0;
- *dst_y_per_vm_flip = 0;
- *dst_y_per_row_flip = 0;
- *final_flip_bw = 0;
*ImmediateFlipSupportedForPipe = iflip_enable;
}
+ } else {
+ l->Tvm_flip = 0;
+ l->Tr0_flip = 0;
+ *dst_y_per_vm_flip = 0;
+ *dst_y_per_row_flip = 0;
+ *final_flip_bw = 0;
+ *ImmediateFlipSupportedForPipe = iflip_enable;
}
} else {
l->Tvm_flip = 0;
@@ -7891,7 +7855,6 @@ static noinline_for_stack void dml_core_ms_prefetch_check(struct dml2_core_inter
display_cfg->gpuvm_enable,
mode_lib->ms.vm_bytes[k],
mode_lib->ms.DPTEBytesPerRow[k],
- mode_lib->ms.BandwidthAvailableForImmediateFlip,
mode_lib->ms.TotImmediateFlipBytes,
display_cfg->plane_descriptors[k].pixel_format,
(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)),
@@ -7903,7 +7866,6 @@ static noinline_for_stack void dml_core_ms_prefetch_check(struct dml2_core_inter
mode_lib->ms.use_one_row_for_frame_flip[k],
mode_lib->ip.max_flip_time_us,
mode_lib->ip.max_flip_time_lines,
- s->per_pipe_flip_bytes[k],
mode_lib->ms.meta_row_bytes[k],
s->meta_row_height_luma[k],
s->meta_row_height_chroma[k],
@@ -11684,7 +11646,6 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
display_cfg->gpuvm_enable,
mode_lib->mp.vm_bytes[k],
mode_lib->mp.PixelPTEBytesPerRow[k],
- mode_lib->mp.BandwidthAvailableForImmediateFlip,
mode_lib->mp.TotImmediateFlipBytes,
display_cfg->plane_descriptors[k].pixel_format,
display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
@@ -11696,7 +11657,6 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.use_one_row_for_frame_flip[k],
mode_lib->ip.max_flip_time_us,
mode_lib->ip.max_flip_time_lines,
- s->per_pipe_flip_bytes[k],
mode_lib->mp.meta_row_bytes[k],
mode_lib->mp.meta_row_height[k],
mode_lib->mp.meta_row_height_chroma[k],
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
index 0f1f58471cff..55118fd484ce 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -1658,6 +1658,9 @@ struct dml2_core_shared_CalculateFlipSchedule_locals {
double num_rows;
double hvm_scaled_row_bytes;
double hvm_scaled_vm_row_bytes;
+ double vm_time_budget;
+ double row_time_budget;
+ double vm_and_row_time_budget;
bool dual_plane;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 18/24] drm/amd/display: Skip eDP teardown while forced PSR is active
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (16 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 17/24] drm/amd/display: Unify CalculateFlipSchedule Logic James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 19/24] drm/amd/display: Update soc_and_ip_translator To Use Updated Per-DPM Derate Organization James Lin
` (5 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Karthi Kandasamy, James Lin
From: Karthi Kandasamy <karthi.kandasamy@amd.com>
[Why & How]
During the HDR<->SDR toggle when the eDP link is held in a forced PSR
(freeze) state,
the normal stream/link teardown re-programming the panel would blank the
frozen frame
and disrupt the freeze; to prevent this, gate the eDP teardown path,
keeping the link
and PSR/Replay state intact for the duration of the forced PSR hold.
The blank_stream and disable_link_output gates already exist.
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Karthi Kandasamy <karthi.kandasamy@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../amd/display/dc/hwss/dce110/dce110_hwseq.c | 7 +++++--
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 19 +++++++++++++------
.../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 17 ++++++++++++-----
.../amd/display/dc/hwss/dcn314/dcn314_hwseq.c | 8 +++++---
.../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 7 +++++--
.../amd/display/dc/hwss/dcn60/dcn60_hwseq.c | 8 ++++++--
6 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 8b47cdeeb1fb..ff0c6e64c2b4 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -3605,8 +3605,11 @@ void dce110_disable_link_output(struct dc_link *link,
else if (dmcu != NULL && dmcu->funcs->lock_phy)
dmcu->funcs->lock_phy(dmcu);
- link_hwss->disable_link_output(link, link_res, signal);
- link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ if (!(signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
/*
* Add the logic to extract BOTH power up and power down sequences
* from enable/disable link output and only call edp panel control
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 850639b6fd9b..2739f7acce98 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
@@ -1346,7 +1346,12 @@ static void dcn10_reset_back_end_for_pipe(
* screen only, the dpms_off would be true but
* VBIOS lit up eDP, so check link status too.
*/
- if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+ if (link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active) {
+ /* forced psr is active for seamless switch; skip dpms-off. */
+ if (pipe_ctx->stream_res.audio)
+ dc->hwss.disable_audio_stream(pipe_ctx);
+ } else if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
dc->link_srv->set_dpms_off(pipe_ctx);
else if (pipe_ctx->stream_res.audio)
dc->hwss.disable_audio_stream(pipe_ctx);
@@ -1370,13 +1375,15 @@ static void dcn10_reset_back_end_for_pipe(
* parent pipe.
*/
if (pipe_ctx->top_pipe == NULL) {
+ if (!(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ if (pipe_ctx->stream_res.abm)
+ dc->hwss.set_abm_immediate_disable(pipe_ctx);
- if (pipe_ctx->stream_res.abm)
- dc->hwss.set_abm_immediate_disable(pipe_ctx);
+ pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
- pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
-
- pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ }
set_drr_and_clear_adjust_pending(pipe_ctx, pipe_ctx->stream, NULL);
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 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 16bb6f678567..66e2a6eb41c0 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
@@ -2849,7 +2849,12 @@ void dcn20_reset_back_end_for_pipe(
* screen only, the dpms_off would be true but
* VBIOS lit up eDP, so check link status too.
*/
- if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+ if (link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active) {
+ /* forced psr is active for seamless switch; skip dpms-off. */
+ if (pipe_ctx->stream_res.audio)
+ dc->hwss.disable_audio_stream(pipe_ctx);
+ } else if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
dc->link_srv->set_dpms_off(pipe_ctx);
else if (pipe_ctx->stream_res.audio)
dc->hwss.disable_audio_stream(pipe_ctx);
@@ -2874,12 +2879,14 @@ void dcn20_reset_back_end_for_pipe(
* parent pipe.
*/
if (pipe_ctx->top_pipe == NULL) {
+ if (!(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ dc->hwss.set_abm_immediate_disable(pipe_ctx);
- dc->hwss.set_abm_immediate_disable(pipe_ctx);
-
- pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
+ pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
- pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ }
if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
index 6ddc678bacf9..56d41c6fa3ee 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
@@ -517,9 +517,11 @@ void dcn314_disable_link_output(struct dc_link *link,
link->dc->hwss.edp_backlight_control(link, false);
else if (dmcu != NULL && dmcu->funcs->lock_phy)
dmcu->funcs->lock_phy(dmcu);
-
- link_hwss->disable_link_output(link, link_res, signal);
- link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ if (!(signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
/*
* Add the logic to extract BOTH power up and power down sequences
* from enable/disable link output and only call edp panel control
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 51fd2b3fe106..e188796cf272 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
@@ -1432,8 +1432,11 @@ void dcn32_disable_link_output(struct dc_link *link,
else if (dmcu != NULL && dmcu->funcs->lock_phy)
dmcu->funcs->lock_phy(dmcu);
- link_hwss->disable_link_output(link, link_res, signal);
- link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ if (!(signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
/*
* Add the logic to extract BOTH power up and power down sequences
* from enable/disable link output and only call edp panel control
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
index b9a046584740..8ee9791b2c46 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
@@ -291,7 +291,9 @@ enum dc_status dcn60_apply_single_controller_ctx_to_hw(
dc_is_virtual_signal(pipe_ctx->stream->signal)))
dc->link_srv->set_dsc_enable(pipe_ctx, true);
}
- if (!stream->dpms_off)
+ if (!stream->dpms_off &&
+ !(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active))
dc->link_srv->set_dpms_on(context, pipe_ctx);
/* DCN3.1 FPGA Workaround
@@ -310,7 +312,9 @@ enum dc_status dcn60_apply_single_controller_ctx_to_hw(
* is constructed with the same sink). Make sure not to override
* and link programming on the main.
*/
- if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) {
+ if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM &&
+ !(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 19/24] drm/amd/display: Update soc_and_ip_translator To Use Updated Per-DPM Derate Organization
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (17 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 18/24] drm/amd/display: Skip eDP teardown while forced PSR is active James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 20/24] drm/amd/display: Relax frame size limit for dcn5/6 DML core funcs files James Lin
` (4 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Austin Zheng, Dillon Varone,
James Lin
From: Austin Zheng <Austin.Zheng@amd.com>
[Why/How]
Transitioning to use the new per-DPM fields so the old ones can be
deprecated.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../dcn401/dcn401_soc_and_ip_translator.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.c b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.c
index 0c8e652c3532..c3dfcf2a73e3 100644
--- a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.c
+++ b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.c
@@ -278,11 +278,11 @@ void dcn401_update_soc_bb_with_values_from_software_policy(struct dml2_soc_bb *s
* bits 16-23: dcfclk_derate_percent
*/
for (unsigned int i = 0; i < dc->debug.dml21_custom_derate_num_dpms; i++) {
- soc_bb->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dram_derate_percent_pixel[i]
+ soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[i].derate_percent
= dc->debug.dml21_custom_derate_at_dpm[i] & 0xFF;
- soc_bb->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.fclk_derate_percent[i]
+ soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[i].derate_percent
= (dc->debug.dml21_custom_derate_at_dpm[i] >> 8) & 0xFF;
- soc_bb->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dcfclk_derate_percent[i]
+ soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[i].derate_percent
= (dc->debug.dml21_custom_derate_at_dpm[i] >> 16) & 0xFF;
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 20/24] drm/amd/display: Relax frame size limit for dcn5/6 DML core funcs files
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (18 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 19/24] drm/amd/display: Update soc_and_ip_translator To Use Updated Per-DPM Derate Organization James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 21/24] drm/amd/display: [FW Promotion] Release 0.1.71.0 James Lin
` (3 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Dillon Varone, James Lin
From: Ivan Lipski <ivan.lipski@amd.com>
[Why]
During compilation with allmodconfig with KASAN, there appears a Werror:
dml2_core_dcn5_funcs_mode_programming.c:11:13: error: stack frame size
(2400) exceeds limit (2048) in 'dcn5_mode_programming'
[-Werror,-Wframe-larger-than]
The dcn5/dcn6 dml2_core_*_funcs_mode_{programming,support} files were
split out of dml2_core_dcn4_calcs.o, which carries a relaxed
-Wframe-larger-than limit via $(frame_warn_flag) (2056 normally, or
4096 for clang + KASAN/KCSAN + COMPILE_TEST). The split-out files were
never added to the per-file CFLAGS override list, so they inherited the
strict global default of 2048. This is why these files trip the frame
size warning under KASAN while the larger dml2_core_dcn4_calcs.o does
not.
[How]
Apply the same $(frame_warn_flag) and CFLAGS_REMOVE handling used for
dml2_core_dcn4_calcs.o to the split-out files:
- dml2_core_dcn5_funcs_mode_programming.o
- dml2_core_dcn5_funcs_mode_support.o
- dml2_core_dcn6_funcs_mode_programming.o
- dml2_core_dcn6_funcs_mode_support.o
Fixes: 04d9a88decbc ("drm/amd/display: Add new sources for DCN6")
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dml2_0/Makefile | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile b/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
index 35d697872a9a..5388bf094fbc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
@@ -75,11 +75,19 @@ $(foreach obj,$(DML2_RELATIVE_O_FILES),$(eval CFLAGS_REMOVE_$(AMDDALPATH)/$(obj)
CFLAGS_$(AMDDALPATH)/dc/dml2_0/display_mode_core.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.o := $(dml2_ccflags) $(frame_warn_flag)
+CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.o := $(dml2_ccflags) $(frame_warn_flag)
+CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_support.o := $(dml2_ccflags) $(frame_warn_flag)
+CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_programming.o := $(dml2_ccflags) $(frame_warn_flag)
+CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml2_wrapper.o := $(dml2_rcflags)
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/dml21_wrapper.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/display_mode_core.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.o := $(dml2_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.o := $(dml2_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_support.o := $(dml2_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_programming.o := $(dml2_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml2_wrapper.o := $(dml2_ccflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/dml21_wrapper.o := $(dml2_ccflags)
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 21/24] drm/amd/display: [FW Promotion] Release 0.1.71.0
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (19 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 20/24] drm/amd/display: Relax frame size limit for dcn5/6 DML core funcs files James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 22/24] drm/amd/display: set base.enable in cursor mode tests James Lin
` (2 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Taimur Hassan, James Lin
From: Taimur Hassan <Syed.Hassan@amd.com>
[why & how]
update DMUB_CMD__DC_BLS_DCHVM_INIT definitions
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Taimur Hassan <Syed.Hassan@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
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 1d10fe8f1998..105a0f8762e8 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -2955,25 +2955,6 @@ struct dmub_rb_cmd_idle_opt_dcn_notify_idle {
struct dmub_dcn_notify_idle_cntl_data cntl_data;
};
-/**
- * Data passed from driver to FW in a DMUB_CMD__DC_BLS_DCHVM_INIT command.
- */
-struct dmub_cmd_dc_bls_dchvm_init_data {
- /**
- * The value to program to rIOMMU PCTRL register. x86 cannot access this SMN
- * register, so the write is performed by DMCUB on the driver's behalf.
- */
- uint32_t riommu_pctrl_val; /* r */
-};
-
-/**
- * Definition of a DMUB_CMD__DC_BLS_DCHVM_INIT command.
- */
-struct dmub_rb_cmd_dc_bls_dchvm_init {
- struct dmub_cmd_header header;
- struct dmub_cmd_dc_bls_dchvm_init_data data;
-};
-
/**
* enum dmub_idle_opt_dc_power_state - DC power states.
*/
@@ -7225,6 +7206,25 @@ struct dmub_rb_cmd_ips_residency_cntl {
struct dmub_cmd_ips_residency_cntl_data cntl_data;
};
+/**
+ * Data passed from driver to FW in a DMUB_CMD__DC_BLS_DCHVM_INIT command.
+ */
+struct dmub_cmd_dc_bls_dchvm_init_data {
+ /**
+ * The value to program to rIOMMU PCTRL register. x86 cannot access this SMN
+ * register, so the write is performed by DMCUB on the driver's behalf.
+ */
+ uint32_t riommu_pctrl_val;
+};
+
+/**
+ * Definition of a DMUB_CMD__DC_BLS_DCHVM_INIT command.
+ */
+struct dmub_rb_cmd_dc_bls_dchvm_init {
+ struct dmub_cmd_header header;
+ struct dmub_cmd_dc_bls_dchvm_init_data data;
+};
+
/**
* Data passed from FW to driver in a DMUB_CMD__IPS_QUERY_RESIDENCY_INFO command.
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 22/24] drm/amd/display: set base.enable in cursor mode tests
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (20 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 21/24] drm/amd/display: [FW Promotion] Release 0.1.71.0 James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 23/24] drm/amd/display: test native cursor mode on a disabled CRTC James Lin
2026-08-10 21:28 ` [PATCH 24/24] drm/amd/display: Promote DC to 3.2.394 James Lin
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, James Lin
From: Tom Chung <chiahsuan.chung@amd.com>
[why]
The CRTC state in the amdgpu_dm_crtc_get_cursor_mode() tests is
zero-initialised, so base.enable is false in all of them. Nothing in the
function reads it today, so they pass, but they are not describing the
case they mean to describe: each one is meant to exercise an enabled CRTC
driving real planes.
[how]
Set base.enable in the shared fixture, and in the no_change test which
builds its own CRTC state instead of using the fixture. No functional
change, since the function does not look at base.enable yet.
Reviewed-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c
index f085eb1a616d..9e76dfa887ea 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c
@@ -147,6 +147,7 @@ static struct dm_cursor_mode_fixture dm_test_alloc_cursor_mode_fixture(struct ku
fixture.state->planes[1].old_state = fixture.old_primary_state;
fixture.state->planes[1].new_state = fixture.primary_state;
fixture.dm_crtc_state->base.crtc = fixture.crtc;
+ fixture.dm_crtc_state->base.enable = true;
fixture.dm_crtc_state->base.plane_mask = drm_plane_mask(fixture.cursor) |
drm_plane_mask(fixture.primary);
fixture.dm_crtc_state->base.zpos_changed = true;
@@ -535,6 +536,7 @@ static void dm_test_crtc_get_cursor_mode_no_change(struct kunit *test)
dm_crtc_state = kunit_kzalloc(test, sizeof(*dm_crtc_state), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, dm_crtc_state);
state->dev = &adev->ddev;
+ dm_crtc_state->base.enable = true;
dm_crtc_state->cursor_mode = DM_CURSOR_OVERLAY_MODE;
ret = amdgpu_dm_crtc_get_cursor_mode(adev, state, dm_crtc_state, &cursor_mode);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 23/24] drm/amd/display: test native cursor mode on a disabled CRTC
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (21 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 22/24] drm/amd/display: set base.enable in cursor mode tests James Lin
@ 2026-08-10 21:28 ` James Lin
2026-08-10 21:28 ` [PATCH 24/24] drm/amd/display: Promote DC to 3.2.394 James Lin
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, James Lin
From: Tom Chung <chiahsuan.chung@amd.com>
[why]
Upstream has no KUnit coverage for amdgpu_dm_crtc_get_cursor_mode(),
which is why the fix in the previous commit came with no test. The
disabled-CRTC path is easy to regress again: it has already been lost
once to a refactor.
[how]
Add a test whose plane setup would otherwise select overlay mode, and
check that a disabled CRTC still reports native mode. Reverting the
previous commit makes only this test fail.
Reviewed-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
.../amdgpu_dm/tests/amdgpu_dm_cursor_test.c | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c
index 9e76dfa887ea..efd16575896e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_cursor_test.c
@@ -499,6 +499,27 @@ static void dm_test_plane_color_pipeline_ignores_other_plane(struct kunit *test)
/* Tests for amdgpu_dm_crtc_get_cursor_mode() */
+/**
+ * dm_test_crtc_get_cursor_mode_disabled_crtc - Test a disabled CRTC uses native cursor
+ * @test: The KUnit test context
+ *
+ * A disabled CRTC must report native mode regardless of what the planes look
+ * like, so that a commit disabling the CRTC is not rejected. The plane setup
+ * here would otherwise select overlay mode.
+ */
+static void dm_test_crtc_get_cursor_mode_disabled_crtc(struct kunit *test)
+{
+ struct dm_cursor_mode_fixture fixture = dm_test_alloc_cursor_mode_fixture(test);
+ enum amdgpu_dm_cursor_mode cursor_mode = DM_CURSOR_OVERLAY_MODE;
+
+ fixture.dm_crtc_state->base.enable = false;
+ fixture.old_primary_state->crtc_w = 1280;
+ fixture.primary_state->crtc_w = 1280;
+
+ KUNIT_EXPECT_EQ(test, dm_test_get_cursor_mode(&fixture, &cursor_mode), 0);
+ KUNIT_EXPECT_EQ(test, cursor_mode, DM_CURSOR_NATIVE_MODE);
+}
+
/**
* dm_test_crtc_get_cursor_mode_new_hardware - Test new hardware always uses native mode
* @test: The KUnit test context
@@ -925,6 +946,7 @@ static struct kunit_case amdgpu_dm_cursor_tests[] = {
KUNIT_CASE(dm_test_plane_color_pipeline_active),
KUNIT_CASE(dm_test_plane_color_pipeline_ignores_other_plane),
/* amdgpu_dm_crtc_get_cursor_mode */
+ KUNIT_CASE(dm_test_crtc_get_cursor_mode_disabled_crtc),
KUNIT_CASE(dm_test_crtc_get_cursor_mode_new_hardware),
KUNIT_CASE(dm_test_crtc_get_cursor_mode_no_change),
KUNIT_CASE(dm_test_crtc_get_cursor_mode_disabled_cursor),
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 24/24] drm/amd/display: Promote DC to 3.2.394
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
` (22 preceding siblings ...)
2026-08-10 21:28 ` [PATCH 23/24] drm/amd/display: test native cursor mode on a disabled CRTC James Lin
@ 2026-08-10 21:28 ` James Lin
23 siblings, 0 replies; 25+ messages in thread
From: James Lin @ 2026-08-10 21:28 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, James Lin, Chenyu Chen, Taimur Hassan, James Lin
From: Taimur Hassan <Syed.Hassan@amd.com>
This DC patchset brings improvements in multiple areas. In summary, we
have:
* Reworked per-DPM derate handling: refactor the per-DPM derate logic,
update derates with default per-DPM values, and move the
soc_and_ip_translator onto the new per-DPM organization
* DCN6 mode-support and UTM work: opt-out for the OutstandingRequests
check, a utm_support capability flag, and a guard against an empty
DCN6 UTM QoS table
* More DMU/DMUB offload: send DPM0 clock values for Z8 retention, allow
DCHVM<->rIOMMU SDP port disconnection on DCN42, and add the DC_BLS
command
* HWSS block-sequence cleanups: move periodic interrupt calculations
to HWSS, drop pipe_ctx from HUBP_WAIT_FOR_DCC_META_PROP, use mpcc_id
instead of the hubp instance, and add a wait stream regen event
* DML updates: unify CalculateFlipSchedule logic and relax the frame
size limit for the dcn5/6 core funcs files
* clk_mgr refactor renaming carried DCE clock manager functions for
dcn10, plus a missing-prototype build fix and a static DCN42 SOC BB
struct
* Expanded IGT/KUnit validation: CACP ACE curve area debugfs and cursor
mode tests on disabled CRTCs
* eDP fix to skip teardown while a forced PSR is active
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Taimur Hassan <Syed.Hassan@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
---
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 edd6a113cfee..1355ce2b4970 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -66,7 +66,7 @@ struct dcn_dsc_reg_state;
struct dcn_optc_reg_state;
struct dcn_dccg_reg_state;
-#define DC_VER "3.2.393"
+#define DC_VER "3.2.394"
/**
* MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-08-11 15:52 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 21:28 [PATCH 00/24] DC Patches Aug 17 2026 James Lin
2026-08-10 21:28 ` [PATCH 01/24] drm/amd/display: Add CACP ACE curve area debugfs for IGT validation James Lin
2026-08-10 21:28 ` [PATCH 02/24] drm/amd/display: Move periodic interrupt calculations to HWSS James Lin
2026-08-10 21:28 ` [PATCH 03/24] drm/amd/display: Add missing prototype for amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags James Lin
2026-08-10 21:28 ` [PATCH 04/24] drm/amd/display: Rename carried dce clock manager functions for dcn10 James Lin
2026-08-10 21:28 ` [PATCH 05/24] drm/amd/display: Add utm_support capability flag James Lin
2026-08-10 21:28 ` [PATCH 06/24] drm/amd/display: Guard against empty DCN6 UTM QoS table James Lin
2026-08-10 21:28 ` [PATCH 07/24] drm/amd/display: Add DC_BLS command James Lin
2026-08-10 21:28 ` [PATCH 08/24] drm/amd/display: Notify DMU to allow DCHVM<->rIOMMU SDP port disconnection for DCN42 James Lin
2026-08-10 21:28 ` [PATCH 09/24] drm/amd/display: Send DPM0 clock values to DMU James Lin
2026-08-10 21:28 ` [PATCH 10/24] drm/amd/display: Refactor HUBP_WAIT_FOR_DCC_META_PROP to drop pipe_ctx James Lin
2026-08-10 21:28 ` [PATCH 11/24] drm/amd/display: add wait stream regen event James Lin
2026-08-10 21:28 ` [PATCH 12/24] drm/amd/display: Use mpcc_id instead of hubp instance James Lin
2026-08-10 21:28 ` [PATCH 13/24] drm/amd/display: Add opt-out for DCN6 OutstandingRequests mode-support check James Lin
2026-08-10 21:28 ` [PATCH 14/24] drm/amd/display: Make Struct In DCN42 SOC BB Header Static James Lin
2026-08-10 21:28 ` [PATCH 15/24] drm/amd/display: Refactor Per-DPM Derate Logic James Lin
2026-08-10 21:28 ` [PATCH 16/24] drm/amd/display: Update Derates And Set Default Per-DPM Derates James Lin
2026-08-10 21:28 ` [PATCH 17/24] drm/amd/display: Unify CalculateFlipSchedule Logic James Lin
2026-08-10 21:28 ` [PATCH 18/24] drm/amd/display: Skip eDP teardown while forced PSR is active James Lin
2026-08-10 21:28 ` [PATCH 19/24] drm/amd/display: Update soc_and_ip_translator To Use Updated Per-DPM Derate Organization James Lin
2026-08-10 21:28 ` [PATCH 20/24] drm/amd/display: Relax frame size limit for dcn5/6 DML core funcs files James Lin
2026-08-10 21:28 ` [PATCH 21/24] drm/amd/display: [FW Promotion] Release 0.1.71.0 James Lin
2026-08-10 21:28 ` [PATCH 22/24] drm/amd/display: set base.enable in cursor mode tests James Lin
2026-08-10 21:28 ` [PATCH 23/24] drm/amd/display: test native cursor mode on a disabled CRTC James Lin
2026-08-10 21:28 ` [PATCH 24/24] drm/amd/display: Promote DC to 3.2.394 James Lin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.