From: Alvin Lee <[email protected]>

[Why & How]
- When calculating the required LSDMA bandwidth, it must be capped to the
  global maximum LSDMA BW.
- Also check the calculated bandwidth against what is available in the
  SOP
- Rework code to only compute alt-ch params if alt-ch is in use
- Also remove some unused fields
- Fix whitespace errors

Reviewed-by: Wenjing Liu <[email protected]>
Signed-off-by: Alvin Lee <[email protected]>
Signed-off-by: Ray Wu <[email protected]>
---
 .../dml21/inc/bounding_boxes/dcn6_soc_bb.h    | 12 ++++++
 .../dml21/inc/dml_top_soc_parameter_types.h   |  1 +
 .../dc/dml2_0/dml21/inc/dml_top_types.h       |  1 +
 .../dml2_core/dml2_core_dcn6_calcs_dchub.c    | 33 ++++++++++++++++-
 .../dml2_core_dcn6_funcs_mode_support.c       | 37 +++++++++++--------
 .../src/dml2_core/dml2_core_shared_types.h    |  3 +-
 .../dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c    |  7 ++++
 .../src/inc/dml2_internal_shared_types.h      |  1 +
 8 files changed, 77 insertions(+), 18 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h
index 19d43e5b7cc2..04292e77698b 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h
@@ -206,6 +206,18 @@ static inline void 
dcn6_test_initialize_v3_sop_latencies_all_levels(
                                df_response_time_ps);
 }
 
+/**
+ * dcn6_test_override_lsdma_bandwidth_v3 - Debug / test interface that
+ * can be used to override the LSDMA bandwidth as needed for any LL and SOP.
+ * @dchub: DCN6 flat UTM QoS v3 table to modify
+ */
+static inline void dcn6_test_override_lsdma_bandwidth_v3(
+               struct utm_qos_model_dchub_v3 *dchub)
+{
+       /* Implement override as needed */
+       (void)dchub;
+}
+
 static inline void dcn6_test_initialize_utm_qos_model_v3(
                struct utm_qos_model *qos_model,
                struct utm_qos_model_dchub_v3 *dchub)
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 422833548aa6..80d652bab5e3 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
@@ -172,6 +172,7 @@ struct dml2_soc_bb {
        double lower_bound_bandwidth_dchub;
        double fraction_of_urgent_bandwidth_nominal_target;
        double fraction_of_urgent_bandwidth_flip_target;
+       unsigned int max_lsdma_bandwidth_kbps;
        unsigned int dprefclk_mhz;
        unsigned int xtalclk_mhz;
        unsigned int pcie_refclk_mhz;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
index c04a4af1f3ea..c241ecaf4d7a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
@@ -402,6 +402,7 @@ struct dml2_memory_path_bandwidth {
                struct {
                        double urgent_bandwidth_kbps; // kbytes per sec
                        double non_urgent_bandwidth_kbps; // kbytes per sec
+                       double lsdma_bandwidth_kbps; // kbytes per sec
                } dcn5;
        };
 };
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
index ba0082e216d5..125ad095c2bb 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
@@ -458,6 +458,37 @@ void dcn6_calculate_alternate_params(struct 
dml2_core_calcs_calculate_alternate_
        unsigned int fw_delay;
        struct swath_params swath_params;
 
+       /* the alternate channel outputs are only meaningful when the alternate 
channel is in use;
+        * otherwise zero all outputs and return early */
+       if (!p->alt_chan_in_use) {
+               *p->svp0_max_bytes = 0;
+               *p->svp1_max_bytes = 0;
+               *p->lsdma_bw_req_for_alt_kbps = 0;
+
+               for (i = 0; i < p->display_cfg->num_planes; i++) {
+                       p->svp0_max_bytes_per_dpp[i] = 0;
+                       p->svp0_max_bytes_per_dpp_c[i] = 0;
+                       p->svp1_max_bytes_per_dpp[i] = 0;
+                       p->svp1_max_bytes_per_dpp_c[i] = 0;
+                       p->total_swaths[i] = 0;
+                       p->total_swaths_c[i] = 0;
+                       p->prefetch_swaths[i] = 0;
+                       p->prefetch_swaths_c[i] = 0;
+                       p->prefetch_hdl_delta[i] = 0;
+                       p->recout_hdl_delta[i] = 0;
+                       p->prefetch_hdl_delta_c[i] = 0;
+                       p->recout_hdl_delta_c[i] = 0;
+               }
+
+               for (i = 0; i < p->display_cfg->num_streams; i++) {
+                       p->nom_req_limit_alt[i] = 0;
+                       p->min_lead_dst_lines[i] = 0;
+                       p->max_prefetch_in_lines[i] = 0;
+               }
+
+               return;
+       }
+
        *p->svp0_max_bytes = 0;
        *p->svp1_max_bytes = 0;
        svp_max_bytes[0] = 0;
@@ -518,7 +549,7 @@ void dcn6_calculate_alternate_params(struct 
dml2_core_calcs_calculate_alternate_
 
        *p->svp0_max_bytes = svp_max_bytes[0];
        *p->svp1_max_bytes = svp_max_bytes[1];
-       *p->lsdma_bw_req_for_alt_kbps = p->dcn_non_urgent_bandwidth_kbps;
+       *p->lsdma_bw_req_for_alt_kbps = 
math_min2(p->dcn_non_urgent_bandwidth_kbps, p->max_lsdma_bandwidth_kbps);
        copy_time_us = 
p->display_cfg->overrides.hw.force_alt_chan_copy_time.enable ? 
p->display_cfg->overrides.hw.force_alt_chan_copy_time.copy_time_us : 
calculate_alt_copy_time_us(p);
        fw_delay =  p->display_cfg->overrides.hw.force_alt_chan_fw_delay.enable 
? p->display_cfg->overrides.hw.force_alt_chan_fw_delay.fw_delay_us : 
p->alt_chan_fw_delay_us;
        for (i = 0; i < p->display_cfg->num_streams; i++) {
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 5de84d6c73c0..de81815f098a 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
@@ -2242,8 +2242,19 @@ static void dcn6_ms_calculate_alternate_params(const 
struct dml2_core_calculate_
        const struct dml2_utm_soc_bb *soc_bb = ctx->soc_bb;
        struct dml2_core_internal_mode_support *inputs = states;
        struct dml2_core_internal_mode_support *outputs = states;
+       unsigned int i;
+       bool is_alternate_pstate_required = false;
 
        DML_LOG_FUNC_ENTER();
+
+       for (i = 0; i < ctx->display_cfg->num_planes; i++) {
+               if 
(ctx->display_cfg->plane_descriptors[i].overrides.uclk_pstate_change_strategy ==
+                               
dml2_uclk_pstate_change_strategy_force_alternate) {
+                       is_alternate_pstate_required = true;
+                       break;
+               }
+       }
+
        p->display_cfg = ctx->display_cfg;
        p->dst_y_prefetch = inputs->dst_y_prefetch;
        p->SwathHeightY = inputs->SwathHeightY;
@@ -2271,16 +2282,17 @@ static void dcn6_ms_calculate_alternate_params(const 
struct dml2_core_calculate_
        p->NoOfDPP = inputs->NoOfDPP;
        p->max_num_dpp = ctx->ip->max_num_dpp;
        p->dram_blackout_us = 
soc_bb->power_management_parameters.dram_clk_change_blackout_us;
-       p->VActiveLatencyHidingUs = inputs->VActiveLatencyHidingUs;
        p->svp0_dst_lines = inputs->svp0_dst_lines;
        p->svp1_dst_lines = inputs->svp1_dst_lines;
        p->svp_req_limit = inputs->svp_req_limit;
-       p->dcn_non_urgent_bandwidth_kbps = 
inputs->support.bandwidth_upper_bound.dcn5.non_urgent_bandwidth_kbps;
+       p->dcn_non_urgent_bandwidth_kbps = 
**inputs->support.non_urg_bandwidth_required_flip * 1000;
+       p->max_lsdma_bandwidth_kbps = soc_bb->max_lsdma_bandwidth_kbps;
        p->alt_chan_fw_delay_us = ctx->ip->alt_chan_fw_delay_us;
        p->dst_y_per_vm_vblank = inputs->LinesForVM;
        p->dst_y_per_row_vblank = inputs->LinesForDPTERow;
        p->DSTYAfterScaler = inputs->DSTYAfterScaler;
        p->ODMMode = inputs->ODMMode;
+       p->alt_chan_in_use = is_alternate_pstate_required;
 
        p->svp0_max_bytes = &outputs->svp0_max_bytes;
        p->svp1_max_bytes = &outputs->svp1_max_bytes;
@@ -3217,8 +3229,11 @@ static void 
dcn6_ms_calculate_bandwidth_upper_bound(const struct dml2_core_calcu
                math_max3(**inputs->support.urg_bandwidth_required_flip,
                        **inputs->support.non_urg_bandwidth_required / 
ctx->soc_bb->fraction_of_urgent_bandwidth_nominal_target,
                        **inputs->support.non_urg_bandwidth_required_flip / 
ctx->soc_bb->fraction_of_urgent_bandwidth_flip_target) * 1000;
+       outputs->support.bandwidth_upper_bound.dcn5.lsdma_bandwidth_kbps = 
inputs->lsdma_bw_req_for_alt_kbps;
+
        
DML_LOG_DEBUG_DOUBLE(outputs->support.bandwidth_upper_bound.dcn5.non_urgent_bandwidth_kbps);
        
DML_LOG_DEBUG_DOUBLE(outputs->support.bandwidth_upper_bound.dcn5.urgent_bandwidth_kbps);
+       
DML_LOG_DEBUG_DOUBLE(outputs->support.bandwidth_upper_bound.dcn5.lsdma_bandwidth_kbps);
        DML_LOG_FUNC_EXIT();
 }
 
@@ -3650,8 +3665,6 @@ static void dcn6_ms_check_alternate_channel_size_support(
                const struct dml2_core_calculate_ms_context *ctx,
                struct dml2_core_internal_mode_support *states)
 {
-       unsigned int i;
-       bool alt_chan_in_use = false;
        const struct dml2_utm_soc_bb *soc_bb = ctx->soc_bb;
        struct dml2_core_internal_mode_support *inputs = states;
        struct dml2_core_internal_mode_support *outputs = states;
@@ -3661,16 +3674,8 @@ static void dcn6_ms_check_alternate_channel_size_support(
        DML_LOG_FUNC_ENTER();
        outputs->support.alternate_channel_size_support = true;
 
-       //Alternate Channel Size Support Check - only fail if alternate 
channels are used AND exceed carveout limit
-       for (i = 0; i < ctx->display_cfg->num_planes; i++) {
-               if 
(ctx->display_cfg->plane_descriptors[i].overrides.uclk_pstate_change_strategy 
== dml2_uclk_pstate_change_strategy_force_alternate) {
-                       alt_chan_in_use = true;
-                       break;
-               }
-       }
-
-       if (alt_chan_in_use && (inputs->svp0_max_bytes > 
alternate_carveout_size_bytes ||
-                                       inputs->svp1_max_bytes > 
alternate_carveout_size_bytes)) {
+       if (inputs->svp0_max_bytes > alternate_carveout_size_bytes ||
+                       inputs->svp1_max_bytes > alternate_carveout_size_bytes) 
{
                outputs->support.alternate_channel_size_support = false;
        }
 
@@ -4081,6 +4086,8 @@ static enum dml2_status dcn6_ms_validate_prefetch(
 
                dcn6_ms_calculate_peak_bandwidth_required(ctx, states);
 
+               dcn6_ms_calculate_alternate_params(ctx, states);
+
                dcn6_ms_calculate_bandwidth_upper_bound(ctx, states);
 
                dcn6_ms_check_qos_bandwidth_support(ctx, states);
@@ -4095,8 +4102,6 @@ static enum dml2_status dcn6_ms_validate_prefetch(
 
                dcn6_ms_calculate_vactive_det_fill_latency(ctx, states);
 
-               dcn6_ms_calculate_alternate_params(ctx, states);
-
                dcn6_ms_check_alternate_channel_size_support(ctx, states);
 
                dcn6_ms_calculate_pstate_schedule_windows(ctx, states);
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 df552eac0006..289ed250f477 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
@@ -2309,16 +2309,17 @@ struct dml2_core_calcs_calculate_alternate_params {
        unsigned int *NoOfDPP;
        unsigned int max_num_dpp;
        double dram_blackout_us;
-       double *VActiveLatencyHidingUs;
        unsigned int *svp0_dst_lines;
        unsigned int *svp1_dst_lines;
        unsigned int *svp_req_limit;
        double dcn_non_urgent_bandwidth_kbps;
+       double max_lsdma_bandwidth_kbps;
        unsigned int alt_chan_fw_delay_us;
        double *dst_y_per_vm_vblank;
        double *dst_y_per_row_vblank;
        unsigned int *DSTYAfterScaler;
        enum dml2_odm_mode *ODMMode;
+       bool alt_chan_in_use;
 
        /* output params */
        unsigned int *svp0_max_bytes;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
index 9c6892edca8a..937205f1f086 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
@@ -181,6 +181,8 @@ static bool 
dcn6_v3_sop_table_is_bandwidth_supported_at_index(
                        &dchub->sops[UTM_QOS_MODEL_V3_LOAD_LEVEL_IDLE][index];
        const struct utm_qos_model_dchub_v3_sop_entry *active_entry =
                        
&dchub->sops[UTM_QOS_MODEL_V3_LOAD_LEVEL_ACTIVE_ALTERNATE_PSTATE][highest_sop_index];
+       const struct utm_qos_model_dchub_v3_sop_entry *pstate_entry =
+                       
&dchub->sops[UTM_QOS_MODEL_V3_LOAD_LEVEL_ACTIVE_ALTERNATE_PSTATE][index];
 
        if (bw->dcn5.non_urgent_bandwidth_kbps > 
idle_entry->nominal_bandwidth_KBps
                        || bw->dcn5.urgent_bandwidth_kbps > 
idle_entry->urgent_bandwidth_KBps)
@@ -190,6 +192,10 @@ static bool 
dcn6_v3_sop_table_is_bandwidth_supported_at_index(
                        || bw->dcn5.urgent_bandwidth_kbps > 
active_entry->urgent_bandwidth_KBps)
                return false;
 
+       /* check if the requested lsdma bandwidth fits within the current sop's 
alt-pstate lsdma budget */
+       if (bw->dcn5.lsdma_bandwidth_kbps > pstate_entry->lsdma_bandwidth_KBps)
+               return false;
+
        return true;
 }
 
@@ -321,6 +327,7 @@ static void dcn6_initialize_from_soc_bb(struct 
dml2_utm_soc_bb *utm_soc_bb,
        utm_soc_bb->lower_bound_bandwidth_dchub = 
soc_bb->lower_bound_bandwidth_dchub;
        utm_soc_bb->fraction_of_urgent_bandwidth_nominal_target = 
soc_bb->fraction_of_urgent_bandwidth_nominal_target;
        utm_soc_bb->fraction_of_urgent_bandwidth_flip_target = 
soc_bb->fraction_of_urgent_bandwidth_flip_target;
+       utm_soc_bb->max_lsdma_bandwidth_kbps = soc_bb->max_lsdma_bandwidth_kbps;
 }
 
 static void dcn6_initialize_from_qos_model(struct dml2_utm_soc_bb *utm_soc_bb,
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 8ddf58da2eed..4289f7f998ff 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
@@ -117,6 +117,7 @@ struct dml2_utm_soc_bb {
        double lower_bound_bandwidth_dchub;
        double fraction_of_urgent_bandwidth_nominal_target;
        double fraction_of_urgent_bandwidth_flip_target;
+       unsigned int max_lsdma_bandwidth_kbps;
        unsigned int dchub_refclk_mhz;
        unsigned int max_outstanding_reqs;
        unsigned long return_bus_width_bytes;
-- 
2.43.0

Reply via email to