drm/amd/display: Apply (some) policy for DML2 formulation on DCN35/DCN351
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Thu, 5 Dec 2024 19:53:36 +0000 (14:53 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Dec 2024 17:20:05 +0000 (12:20 -0500)
[Why]
Dropping the entirety of dml2_policy_build_synthetic_soc_states exposes
an issue for states that cannot be filled via bbox_overrides and rely on
the default parameters that may or may not be present depending on the
DM.

For amdgpu_dm this results in missing parameters for most of the struct
in higher states:

- sr_exit_time_us
- sr_enter_plus_exit_time_us
- sr_exit_z8_time_us
- sr_enter_plus_exit_z8_time_us
- urgent_latency_pixel_data_only_us
- urgent_latency_pixel_mixed_with_vm_data_us
- urgent_latency_vm_data_only_us
- dram_clock_change_latency_us
- fclk_change_latency_us
- usr_retraining_latency_us
- writeback_latency_us
- urgent_latency_adjustment_fabric_clock_component_us
- urgent_latency_adjustment_fabric_clock_reference_mhz
- dscclk_mhz
- phyclk_mhz
- phyclk_d18_mhz
- phyclk_d32_mhz
- use_ideal_dram_bw_strobe

[How]
Copy from the first state, applying a minimal policy to set max clocks
for SOC independent values.

Then copy the SOC dependent ones from the states modified by
bbox_overrides.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c

index bde4250853b10cf94e6cf55cae897ca3c33a116b..b416320873e11142d4ab390495d563d23dc15cc7 100644 (file)
@@ -553,13 +553,53 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc,
                }
        }
 
-       dml2_policy_build_synthetic_soc_states(s, p);
-       if (dml2->v20.dml_core_ctx.project == dml_project_dcn35) {
-               // Override last out_state with data from last in_state
-               // This will ensure that out_state contains max fclk
-               memcpy(&p->out_states->state_array[p->out_states->num_states - 1],
-                               &p->in_states->state_array[p->in_states->num_states - 1],
-                               sizeof(struct soc_state_bounding_box_st));
+       if (dml2->v20.dml_core_ctx.project == dml_project_dcn35 ||
+           dml2->v20.dml_core_ctx.project == dml_project_dcn351) {
+               int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0,
+                       max_dtbclk_mhz = 0, max_fclk_mhz = 0, max_uclk_mhz = 0, max_socclk_mhz = 0;
+
+               for (i = 0; i < p->in_states->num_states; i++) {
+                       if (p->in_states->state_array[i].dcfclk_mhz > max_dcfclk_mhz)
+                               max_dcfclk_mhz = (int)p->in_states->state_array[i].dcfclk_mhz;
+                       if (p->in_states->state_array[i].fabricclk_mhz > max_fclk_mhz)
+                               max_fclk_mhz = (int)p->in_states->state_array[i].fabricclk_mhz;
+                       if (p->in_states->state_array[i].socclk_mhz > max_socclk_mhz)
+                               max_socclk_mhz = (int)p->in_states->state_array[i].socclk_mhz;
+                       if (p->in_states->state_array[i].dram_speed_mts > max_uclk_mhz)
+                               max_uclk_mhz = (int)p->in_states->state_array[i].dram_speed_mts;
+                       if (p->in_states->state_array[i].dispclk_mhz > max_dispclk_mhz)
+                               max_dispclk_mhz = (int)p->in_states->state_array[i].dispclk_mhz;
+                       if (p->in_states->state_array[i].dppclk_mhz > max_dppclk_mhz)
+                               max_dppclk_mhz = (int)p->in_states->state_array[i].dppclk_mhz;
+                       if (p->in_states->state_array[i].phyclk_mhz > max_phyclk_mhz)
+                               max_phyclk_mhz = (int)p->in_states->state_array[i].phyclk_mhz;
+                       if (p->in_states->state_array[i].dtbclk_mhz > max_dtbclk_mhz)
+                               max_dtbclk_mhz = (int)p->in_states->state_array[i].dtbclk_mhz;
+               }
+
+               for (i = 0; i < p->in_states->num_states; i++) {
+                       /* Independent states - including base (unlisted) parameters from state 0. */
+                       p->out_states->state_array[i] = p->in_states->state_array[0];
+
+                       p->out_states->state_array[i].dispclk_mhz = max_dispclk_mhz;
+                       p->out_states->state_array[i].dppclk_mhz = max_dppclk_mhz;
+                       p->out_states->state_array[i].dtbclk_mhz = max_dtbclk_mhz;
+                       p->out_states->state_array[i].phyclk_mhz = max_phyclk_mhz;
+
+                       p->out_states->state_array[i].dscclk_mhz = max_dispclk_mhz / 3.0;
+                       p->out_states->state_array[i].phyclk_mhz = max_phyclk_mhz;
+                       p->out_states->state_array[i].dtbclk_mhz = max_dtbclk_mhz;
+
+                       /* Dependent states. */
+                       p->out_states->state_array[i].dram_speed_mts = p->in_states->state_array[i].dram_speed_mts;
+                       p->out_states->state_array[i].fabricclk_mhz = p->in_states->state_array[i].fabricclk_mhz;
+                       p->out_states->state_array[i].socclk_mhz = p->in_states->state_array[i].socclk_mhz;
+                       p->out_states->state_array[i].dcfclk_mhz = p->in_states->state_array[i].dcfclk_mhz;
+               }
+
+               p->out_states->num_states = p->in_states->num_states;
+       } else {
+               dml2_policy_build_synthetic_soc_states(s, p);
        }
 }