<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Calibri;font-size:10pt;color:#0000FF;margin:5pt;font-style:normal;font-weight:normal;text-decoration:none;" align="Left">
[AMD Official Use Only - AMD Internal Distribution Only]<br>
</p>
<br>
<div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);" class="elementToProof">
Reviewed-by: Wenjing Liu <wenjing.liu@amd.com></div>
<div id="appendonsend"></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<hr style="display: inline-block; width: 98%;">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>From:</b> SHANMUGAM, SRINIVASAN <SRINIVASAN.SHANMUGAM@amd.com><br>
<b>Sent:</b> Friday, August 01, 2025 8:12 AM<br>
<b>To:</b> Hung, Alex <Alex.Hung@amd.com>; Pillai, Aurabindo <Aurabindo.Pillai@amd.com>; Lei, Jun <Jun.Lei@amd.com>; Liu, Wenjing <Wenjing.Liu@amd.com><br>
<b>Cc:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; SHANMUGAM, SRINIVASAN <SRINIVASAN.SHANMUGAM@amd.com>; Strauss, Michael <Michael.Strauss@amd.com>; Lee, Alvin <Alvin.Lee2@amd.com>; LIPSKI, IVAN <IVAN.LIPSKI@amd.com><br>
<b>Subject:</b> [PATCH] drm/amd/display: Move 'audio descriptor' storage from 'stream resource' to 'dc scratch'
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-size: 11pt;">The `stream_resource` structure holds hardware parts and resources that<br>
stay active as long as the display stream or pipe is running. It<br>
represents the hardware state.<br>
<br>
The `audio_output` structure is temporary. It is built and used only<br>
during operations like dc validation and link retraining. It does not<br>
represent permanent hardware resources.<br>
<br>
This patch moves the audio_output descriptor from stream_res to<br>
dc_scratch_space. This keeps temporary data separate from permanent<br>
hardware state<br>
<br>
'Fixes: 571662266db3 ("drm/amd/display: Reduce Stack Usage by moving<br>
'audio_output' into 'stream_res' v4")'<br>
Cc: Michael Strauss <michael.strauss@amd.com><br>
Cc: Alvin Lee <Alvin.Lee2@amd.com><br>
Cc: Jun Lei <Jun.Lei@amd.com><br>
Cc: Wenjing Liu <wenjing.liu@amd.com><br>
Cc: Alex Hung <alex.hung@amd.com><br>
Cc: Ivan Lipski <ivan.lipski@amd.com><br>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com><br>
Suggested-by: Jun Lei <Jun.Lei@amd.com><br>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com><br>
---<br>
 drivers/gpu/drm/amd/display/dc/dc.h           |  3 ++<br>
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 30 +++++++++++--------<br>
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  5 ++--<br>
 .../display/dc/link/accessories/link_dp_cts.c | 13 +++++---<br>
 .../dc/resource/dcn31/dcn31_resource.c        |  5 ++--<br>
 .../dc/resource/dcn31/dcn31_resource.h        |  3 +-<br>
 6 files changed, 36 insertions(+), 23 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h<br>
index 5653c1673aec..c6bfde9d3e98 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/dc.h<br>
+++ b/drivers/gpu/drm/amd/display/dc/dc.h<br>
@@ -47,6 +47,7 @@<br>
 #include "dmub/inc/dmub_cmd.h"<br>
 <br>
 #include "sspl/dc_spl_types.h"<br>
+#include "audio_types.h"<br>
 <br>
 struct abm_save_restore;<br>
 <br>
@@ -1734,6 +1735,8 @@ struct dc {<br>
                 struct dc_stream_state temp_stream; // Used so we don't need to allocate stream on the stack<br>
                 struct dc_link temp_link;<br>
                 bool pipes_to_unlock_first[MAX_PIPES]; /* Any of the pipes indicated here should be unlocked first */<br>
+               /* Pre-allocated buffer for audio_output used in dp_retrain_link_dp_test() */<br>
+               struct audio_output audio_output[MAX_PIPES];<br>
         } scratch;<br>
 <br>
         struct dml2_configuration_options dml2_options;<br>
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<br>
index 153d68375fa3..49ad34734cef 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c<br>
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c<br>
@@ -1586,6 +1586,7 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(<br>
                 struct dc_state *context,<br>
                 struct dc *dc)<br>
 {<br>
+       struct audio_output *audio_output;<br>
         struct dc_stream_state *stream = pipe_ctx->stream;<br>
         struct dc_link *link = stream->link;<br>
         struct drr_params params = {0};<br>
@@ -1595,23 +1596,23 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(<br>
         const struct link_hwss *link_hwss = get_link_hwss(<br>
                         link, &pipe_ctx->link_res);<br>
 <br>
-<br>
         if (hws->funcs.disable_stream_gating) {<br>
                 hws->funcs.disable_stream_gating(dc, pipe_ctx);<br>
         }<br>
 <br>
         if (pipe_ctx->stream_res.audio != NULL) {<br>
-               build_audio_output(context, pipe_ctx, &pipe_ctx->stream_res.audio_output);<br>
+               audio_output = &dc->scratch.audio_output[pipe_ctx->pipe_idx];<br>
+               build_audio_output(context, pipe_ctx, audio_output);<br>
 <br>
-               link_hwss->setup_audio_output(pipe_ctx, &pipe_ctx->stream_res.audio_output,<br>
+               link_hwss->setup_audio_output(pipe_ctx, audio_output,<br>
                                 pipe_ctx->stream_res.audio->inst);<br>
 <br>
                 pipe_ctx->stream_res.audio->funcs->az_configure(<br>
                                 pipe_ctx->stream_res.audio,<br>
                                 pipe_ctx->stream->signal,<br>
-                               &pipe_ctx->stream_res.audio_output.crtc_info,<br>
+                               &audio_output->crtc_info,<br>
                                 &pipe_ctx->stream->audio_info,<br>
-                               &pipe_ctx->stream_res.audio_output.dp_link_info);<br>
+                               &audio_output->dp_link_info);<br>
 <br>
                 if (dc->config.disable_hbr_audio_dp2)<br>
                         if (pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio &&<br>
@@ -2354,6 +2355,7 @@ static void dce110_setup_audio_dto(<br>
                 struct dc_state *context)<br>
 {<br>
         unsigned int i;<br>
+       struct audio_output *audio_output;<br>
 <br>
         /* program audio wall clock. use HDMI as clock source if HDMI<br>
          * audio active. Otherwise, use DP as clock source<br>
@@ -2385,7 +2387,8 @@ static void dce110_setup_audio_dto(<br>
                 if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)<br>
                         continue;<br>
                 if (pipe_ctx->stream_res.audio != NULL) {<br>
-                       build_audio_output(context, pipe_ctx, &pipe_ctx->stream_res.audio_output);<br>
+                       audio_output = &dc->scratch.audio_output[i];<br>
+                       build_audio_output(context, pipe_ctx, audio_output);<br>
 <br>
                         if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {<br>
                                 struct dtbclk_dto_params dto_params = {0};<br>
@@ -2396,14 +2399,14 @@ static void dce110_setup_audio_dto(<br>
                                 pipe_ctx->stream_res.audio->funcs->wall_dto_setup(<br>
                                                 pipe_ctx->stream_res.audio,<br>
                                                 pipe_ctx->stream->signal,<br>
-                                               &pipe_ctx->stream_res.audio_output.crtc_info,<br>
-                                               &pipe_ctx->stream_res.audio_output.pll_info);<br>
+                                               &audio_output->crtc_info,<br>
+                                               &audio_output->pll_info);<br>
                         } else<br>
                                 pipe_ctx->stream_res.audio->funcs->wall_dto_setup(<br>
                                         pipe_ctx->stream_res.audio,<br>
                                         pipe_ctx->stream->signal,<br>
-                                       &pipe_ctx->stream_res.audio_output.crtc_info,<br>
-                                       &pipe_ctx->stream_res.audio_output.pll_info);<br>
+                                       &audio_output->crtc_info,<br>
+                                       &audio_output->pll_info);<br>
                         break;<br>
                 }<br>
         }<br>
@@ -2423,15 +2426,16 @@ static void dce110_setup_audio_dto(<br>
                                 continue;<br>
 <br>
                         if (pipe_ctx->stream_res.audio != NULL) {<br>
+                               audio_output = &dc->scratch.audio_output[i];<br>
                                 build_audio_output(context,<br>
                                                    pipe_ctx,<br>
-                                                  &pipe_ctx->stream_res.audio_output);<br>
+                                                  audio_output);<br>
 <br>
                                 pipe_ctx->stream_res.audio->funcs->wall_dto_setup(<br>
                                         pipe_ctx->stream_res.audio,<br>
                                         pipe_ctx->stream->signal,<br>
-                                       &pipe_ctx->stream_res.audio_output.crtc_info,<br>
-                                       &pipe_ctx->stream_res.audio_output.pll_info);<br>
+                                       &audio_output->crtc_info,<br>
+                                       &audio_output->pll_info);<br>
                                 break;<br>
                         }<br>
                 }<br>
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h<br>
index 4387de044469..df0d72b2c1b0 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h<br>
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h<br>
@@ -228,7 +228,8 @@ struct resource_funcs {<br>
         enum dc_status (*update_dc_state_for_encoder_switch)(struct dc_link *link,<br>
                 struct dc_link_settings *link_setting,<br>
                 uint8_t pipe_count,<br>
-               struct pipe_ctx *pipes);<br>
+               struct pipe_ctx *pipes,<br>
+               struct audio_output *audio_output);<br>
 };<br>
 <br>
 struct audio_support{<br>
@@ -360,8 +361,6 @@ struct stream_resource {<br>
         uint8_t gsl_group;<br>
 <br>
         struct test_pattern_params test_pattern_params;<br>
-<br>
-       struct audio_output audio_output;<br>
 };<br>
 <br>
 struct plane_resource {<br>
diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c<br>
index 23f41c99fa38..4af5fde2e392 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c<br>
+++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c<br>
@@ -35,6 +35,7 @@<br>
 #include "dc_dmub_srv.h"<br>
 #include "dce/dmub_hw_lock_mgr.h"<br>
 #include "clk_mgr.h"<br>
+#include "dc.h"<br>
 <br>
 #define DC_LOGGER \<br>
         link->ctx->logger<br>
@@ -66,6 +67,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link,<br>
                         struct dc_link_settings *link_setting,<br>
                         bool skip_video_pattern)<br>
 {<br>
+       struct dc *dc = (struct dc *)(unsigned long)link->dc;<br>
         struct pipe_ctx *pipes[MAX_PIPES];<br>
         struct dc_state *state = link->dc->current_state;<br>
         struct dc_stream_update stream_update = { 0 };<br>
@@ -79,6 +81,9 @@ static void dp_retrain_link_dp_test(struct dc_link *link,<br>
         struct dc_stream_state *streams_on_link[MAX_PIPES];<br>
         int num_streams_on_link = 0;<br>
 <br>
+       /* Zero out the scratch audio output array */<br>
+       memset((void *)dc->scratch.audio_output, 0, sizeof(dc->scratch.audio_output));<br>
+<br>
         needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) !=<br>
         link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings));<br>
 <br>
@@ -101,7 +106,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link,<br>
         if (needs_divider_update && link->dc->res_pool->funcs->update_dc_state_for_encoder_switch) {<br>
                 link->dc->res_pool->funcs->update_dc_state_for_encoder_switch(link,<br>
                                 link_setting, count,<br>
-                               *pipes);<br>
+                               *pipes, dc->scratch.audio_output);<br>
                 for (i = 0; i < count; i++) {<br>
                         pipes[i]->clock_source->funcs->program_pix_clk(<br>
                                         pipes[i]->clock_source,<br>
@@ -114,15 +119,15 @@ static void dp_retrain_link_dp_test(struct dc_link *link,<br>
                                         link, &pipes[i]->link_res);<br>
 <br>
                                 link_hwss->setup_audio_output(pipes[i],<br>
-                                                             &pipes[i]->stream_res.audio_output,<br>
+                                                             &dc->scratch.audio_output[i],<br>
                                                               pipes[i]->stream_res.audio->inst);<br>
 <br>
                                 pipes[i]->stream_res.audio->funcs->az_configure(<br>
                                                 pipes[i]->stream_res.audio,<br>
                                                 pipes[i]->stream->signal,<br>
-                                               &pipes[i]->stream_res.audio_output.crtc_info,<br>
+                                               &dc->scratch.audio_output[i].crtc_info,<br>
                                                 &pipes[i]->stream->audio_info,<br>
-                                               &pipes[i]->stream_res.audio_output.dp_link_info);<br>
+                                               &dc->scratch.audio_output[i].dp_link_info);<br>
 <br>
                                 if (link->dc->config.disable_hbr_audio_dp2 &&<br>
                                                 pipes[i]->stream_res.audio->funcs->az_disable_hbr_audio &&<br>
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c<br>
index ca17e5d8fdc2..3ed7f50554e2 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c<br>
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c<br>
@@ -2239,7 +2239,8 @@ struct resource_pool *dcn31_create_resource_pool(<br>
 enum dc_status dcn31_update_dc_state_for_encoder_switch(struct dc_link *link,<br>
         struct dc_link_settings *link_setting,<br>
         uint8_t pipe_count,<br>
-       struct pipe_ctx *pipes)<br>
+       struct pipe_ctx *pipes,<br>
+       struct audio_output *audio_output)<br>
 {<br>
         struct dc_state *state = link->dc->current_state;<br>
         int i;<br>
@@ -2254,7 +2255,7 @@ enum dc_status dcn31_update_dc_state_for_encoder_switch(struct dc_link *link,<br>
 <br>
                 // Setup audio<br>
                 if (pipes[i].stream_res.audio != NULL)<br>
-                       build_audio_output(state, &pipes[i], &pipes[i].stream_res.audio_output);<br>
+                       build_audio_output(state, &pipes[i], &audio_output[i]);<br>
         }<br>
 #else<br>
         /* This DCN requires rate divider updates and audio reprogramming to allow DP1<-->DP2 link rate switching,<br>
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h<br>
index 7e8fde65528f..c32c85ef0ba4 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h<br>
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h<br>
@@ -69,7 +69,8 @@ unsigned int dcn31_get_det_buffer_size(<br>
 enum dc_status dcn31_update_dc_state_for_encoder_switch(struct dc_link *link,<br>
         struct dc_link_settings *link_setting,<br>
         uint8_t pipe_count,<br>
-       struct pipe_ctx *pipes);<br>
+       struct pipe_ctx *pipes,<br>
+       struct audio_output *audio_output);<br>
 <br>
 /*temp: B0 specific before switch to dcn313 headers*/<br>
 #ifndef regPHYPLLF_PIXCLK_RESYNC_CNTL<br>
--<br>
2.34.1<br>
<br>
</div>
</div>
</body>
</html>