<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:10pt;color:#0000FF;margin:5pt;" align="Left">
[AMD Official Use Only - General]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);">
Isnt it cleaner to revert the original patch which removed the temporary variable and then instead allocate the clock_limits array on heap, and later freed at the end of the function?
<br>
</div>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="Signature">
<div>
<div></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
--</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Regards,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Jay<br>
</div>
</div>
</div>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Li, Sun peng (Leo) <Sunpeng.Li@amd.com><br>
<b>Sent:</b> Wednesday, June 8, 2022 12:48 PM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Wentland, Harry <Harry.Wentland@amd.com>; Pillai, Aurabindo <Aurabindo.Pillai@amd.com>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; Li, Sun peng (Leo) <Sunpeng.Li@amd.com><br>
<b>Subject:</b> [PATCH] drm/amd/display: Use pre-allocated temp struct for bounding box update</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">From: Leo Li <sunpeng.li@amd.com><br>
<br>
[Why]<br>
<br>
There is a theoretical problem in prior patches for reducing the stack<br>
size of *update_bw_bounding_box() functions.<br>
<br>
By modifying the soc.clock_limits[n] struct directly, this can cause<br>
unintended behavior as the for loop attempts to swap rows in<br>
clock_limits[n]. A temporary struct is still required to make sure we<br>
stay functinoally equivalent.<br>
<br>
[How]<br>
<br>
Add a temporary clock_limits table to the SOC struct, and use it when<br>
swapping rows.<br>
<br>
Signed-off-by: Leo Li <sunpeng.li@amd.com><br>
---<br>
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c  | 33 +++++-----<br>
 .../amd/display/dc/dml/dcn301/dcn301_fpu.c    | 36 ++++++-----<br>
 .../drm/amd/display/dc/dml/dcn31/dcn31_fpu.c  | 64 +++++++++++--------<br>
 .../amd/display/dc/dml/display_mode_structs.h |  5 ++<br>
 4 files changed, 82 insertions(+), 56 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c<br>
index c2fec0d85da4..e247b2270b1d 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c<br>
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c<br>
@@ -2015,9 +2015,8 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params<br>
 <br>
         ASSERT(clk_table->num_entries);<br>
         /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */<br>
-       for (i = 0; i < dcn2_1_soc.num_states + 1; i++) {<br>
-               dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i];<br>
-       }<br>
+       memcpy(&dcn2_1_soc._clock_tmp, &dcn2_1_soc.clock_limits,<br>
+              sizeof(dcn2_1_soc.clock_limits));<br>
 <br>
         for (i = 0; i < clk_table->num_entries; i++) {<br>
                 /* loop backwards*/<br>
@@ -2032,22 +2031,26 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params<br>
                 if (i == 1)<br>
                         k++;<br>
 <br>
-               dcn2_1_soc.clock_limits[k].state = k;<br>
-               dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;<br>
+               dcn2_1_soc._clock_tmp[k].state = k;<br>
+               dcn2_1_soc._clock_tmp[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;<br>
 <br>
-               dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
-               dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
-               dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
-               dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
+               dcn2_1_soc._clock_tmp[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
+               dcn2_1_soc._clock_tmp[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
 <br>
                 k++;<br>
         }<br>
+<br>
+       memcpy(&dcn2_1_soc.clock_limits, &dcn2_1_soc._clock_tmp,<br>
+              sizeof(dcn2_1_soc.clock_limits));<br>
+<br>
         if (clk_table->num_entries) {<br>
                 dcn2_1_soc.num_states = clk_table->num_entries + 1;<br>
                 /* fill in min DF PState */<br>
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c<br>
index 62cf283d9f41..e4863f0bf0f6 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c<br>
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c<br>
@@ -254,6 +254,9 @@ void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param<br>
 <br>
         dc_assert_fp_enabled();<br>
 <br>
+       memcpy(&dcn3_01_soc._clock_tmp, &dcn3_01_soc.clock_limits,<br>
+              sizeof(dcn3_01_soc.clock_limits));<br>
+<br>
         /* Default clock levels are used for diags, which may lead to overclocking. */<br>
         if (!IS_DIAG_DC(dc->ctx->dce_environment)) {<br>
                 dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator;<br>
@@ -270,29 +273,32 @@ void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param<br>
                                 }<br>
                         }<br>
 <br>
-                       dcn3_01_soc.clock_limits[i].state = i;<br>
-                       dcn3_01_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;<br>
-<br>
-                       dcn3_01_soc.clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
-                       dcn3_01_soc.clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
-                       dcn3_01_soc.clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].state = i;<br>
+                       dcn3_01_soc._clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;<br>
+<br>
+                       dcn3_01_soc._clock_tmp[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
+                       dcn3_01_soc._clock_tmp[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
+                       dcn3_01_soc._clock_tmp[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
                 }<br>
 <br>
                 if (clk_table->num_entries) {<br>
                         dcn3_01_soc.num_states = clk_table->num_entries;<br>
                         /* duplicate last level */<br>
-                       dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1];<br>
-                       dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states;<br>
+                       dcn3_01_soc._clock_tmp[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1];<br>
+                       dcn3_01_soc._clock_tmp[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states;<br>
                 }<br>
         }<br>
 <br>
+       memcpy(&dcn3_01_soc.clock_limits, &dcn3_01_soc._clock_tmp,<br>
+              sizeof(dcn3_01_soc.clock_limits));<br>
+<br>
         dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;<br>
         dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;<br>
 <br>
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c<br>
index 6da702923226..7be3476989ce 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c<br>
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c<br>
@@ -580,6 +580,9 @@ void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params<br>
 <br>
         dc_assert_fp_enabled();<br>
 <br>
+       memcpy(&dcn3_1_soc._clock_tmp, &dcn3_1_soc.clock_limits,<br>
+              sizeof(dcn3_1_soc.clock_limits));<br>
+<br>
         // Default clock levels are used for diags, which may lead to overclocking.<br>
         if (!IS_DIAG_DC(dc->ctx->dce_environment)) {<br>
                 int max_dispclk_mhz = 0, max_dppclk_mhz = 0;<br>
@@ -607,32 +610,35 @@ void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params<br>
                                 }<br>
                         }<br>
 <br>
-                       dcn3_1_soc.clock_limits[i].state = i;<br>
+                       dcn3_1_soc._clock_tmp[i].state = i;<br>
 <br>
                         /* Clocks dependent on voltage level. */<br>
-                       dcn3_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
-                       dcn3_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
-                       dcn3_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
-                       dcn3_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;<br>
+                       dcn3_1_soc._clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;<br>
 <br>
                         /* Clocks independent of voltage level. */<br>
-                       dcn3_1_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :<br>
+                       dcn3_1_soc._clock_tmp[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :<br>
                                 dcn3_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;<br>
 <br>
-                       dcn3_1_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :<br>
+                       dcn3_1_soc._clock_tmp[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :<br>
                                 dcn3_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;<br>
 <br>
-                       dcn3_1_soc.clock_limits[i].dram_bw_per_chan_gbps = dcn3_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
-                       dcn3_1_soc.clock_limits[i].dscclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
-                       dcn3_1_soc.clock_limits[i].dtbclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
-                       dcn3_1_soc.clock_limits[i].phyclk_d18_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
-                       dcn3_1_soc.clock_limits[i].phyclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].dram_bw_per_chan_gbps = dcn3_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
+                       dcn3_1_soc._clock_tmp[i].dscclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].dtbclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].phyclk_d18_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
+                       dcn3_1_soc._clock_tmp[i].phyclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
                 }<br>
                 if (clk_table->num_entries) {<br>
                         dcn3_1_soc.num_states = clk_table->num_entries;<br>
                 }<br>
         }<br>
 <br>
+       memcpy(&dcn3_1_soc.clock_limits, &dcn3_1_soc._clock_tmp,<br>
+              sizeof(dcn3_1_soc.clock_limits));<br>
+<br>
         dcn3_1_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;<br>
         dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;<br>
 <br>
@@ -705,6 +711,9 @@ void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param<br>
 <br>
         dc_assert_fp_enabled();<br>
 <br>
+       memcpy(&dcn3_16_soc._clock_tmp, &dcn3_16_soc.clock_limits,<br>
+              sizeof(dcn3_16_soc.clock_limits));<br>
+<br>
         // Default clock levels are used for diags, which may lead to overclocking.<br>
         if (!IS_DIAG_DC(dc->ctx->dce_environment)) {<br>
 <br>
@@ -736,37 +745,40 @@ void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param<br>
                                 closest_clk_lvl = dcn3_16_soc.num_states - 1;<br>
                         }<br>
 <br>
-                       dcn3_16_soc.clock_limits[i].state = i;<br>
+                       dcn3_16_soc._clock_tmp[i].state = i;<br>
 <br>
                         /* Clocks dependent on voltage level. */<br>
-                       dcn3_16_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;<br>
                         if (clk_table->num_entries == 1 &&<br>
-                               dcn3_16_soc.clock_limits[i].dcfclk_mhz < dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {<br>
+                           dcn3_16_soc._clock_tmp[i].dcfclk_mhz < dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {<br>
                                 /*SMU fix not released yet*/<br>
-                               dcn3_16_soc.clock_limits[i].dcfclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;<br>
+                               dcn3_16_soc._clock_tmp[i].dcfclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;<br>
                         }<br>
-                       dcn3_16_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
-                       dcn3_16_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
-                       dcn3_16_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;<br>
+                       dcn3_16_soc._clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;<br>
 <br>
                         /* Clocks independent of voltage level. */<br>
-                       dcn3_16_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :<br>
+                       dcn3_16_soc._clock_tmp[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :<br>
                                 dcn3_16_soc.clock_limits[closest_clk_lvl].dispclk_mhz;<br>
 <br>
-                       dcn3_16_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :<br>
+                       dcn3_16_soc._clock_tmp[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :<br>
                                 dcn3_16_soc.clock_limits[closest_clk_lvl].dppclk_mhz;<br>
 <br>
-                       dcn3_16_soc.clock_limits[i].dram_bw_per_chan_gbps = dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
-                       dcn3_16_soc.clock_limits[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
-                       dcn3_16_soc.clock_limits[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
-                       dcn3_16_soc.clock_limits[i].phyclk_d18_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
-                       dcn3_16_soc.clock_limits[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].dram_bw_per_chan_gbps = dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;<br>
+                       dcn3_16_soc._clock_tmp[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].phyclk_d18_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;<br>
+                       dcn3_16_soc._clock_tmp[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz;<br>
                 }<br>
                 if (clk_table->num_entries) {<br>
                         dcn3_16_soc.num_states = clk_table->num_entries;<br>
                 }<br>
         }<br>
 <br>
+       memcpy(&dcn3_16_soc.clock_limits, &dcn3_16_soc._clock_tmp,<br>
+              sizeof(dcn3_16_soc.clock_limits));<br>
+<br>
         if (max_dispclk_mhz) {<br>
                 dcn3_16_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;<br>
                 dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;<br>
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h<br>
index 74afa10e70f8..2bdf60846762 100644<br>
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h<br>
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h<br>
@@ -161,6 +161,11 @@ struct _vcs_dpi_voltage_scaling_st {<br>
 <br>
 struct _vcs_dpi_soc_bounding_box_st {<br>
         struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];<br>
+       /*<br>
+        * This is a temporary stash for updating @clock_limits with the PMFW<br>
+        * clock table. Do not use outside of *update_bw_boudning_box functions.<br>
+        */<br>
+       struct _vcs_dpi_voltage_scaling_st _clock_tmp[DC__VOLTAGE_STATES];<br>
         unsigned int num_states;<br>
         double sr_exit_time_us;<br>
         double sr_enter_plus_exit_time_us;<br>
-- <br>
2.36.1<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>