From: Dillon Varone <[email protected]>

[WHY&HOW]
DML2.1 wrapper was lacking translation for DWB. This change adds the
necessary translation for DWB validation and programming support.

Reviewed-by: Austin Zheng <[email protected]>
Signed-off-by: Dillon Varone <[email protected]>
Signed-off-by: Wayne Lin <[email protected]>
---
 .../dml2_0/dml21/dml21_translation_helper.c   | 56 +++++++++++++++
 .../amd/display/dc/dml2_0/dml21/dml21_utils.c | 17 +++++
 .../amd/display/dc/dml2_0/dml21/dml21_utils.h |  5 ++
 .../dc/dml2_0/dml21/dml21_wrapper_fpu.c       | 10 +++
 .../dc/dml2_0/dml21/inc/dml_top_types.h       |  2 +
 .../dml21/src/dml2_core/dml2_core_dcn4.c      | 34 +++++++++-
 .../src/dml2_core/dml2_core_dcn4_calcs.c      | 68 ++++++++++++++++---
 .../src/dml2_core/dml2_core_dcn4_calcs.h      |  2 +
 .../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c      | 21 ++++++
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
index 51260369cd8a..a76dcde1efbf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
@@ -267,6 +267,61 @@ static void 
populate_dml21_output_config_from_stream_state(struct dml2_link_outp
        // output->validate_output
 }
 
+static void populate_dml21_writeback_config_from_stream_state(struct 
dml2_writeback_cfg *writeback,
+               const struct dc_stream_state *stream)
+{
+       if (stream->num_wb_info > 0) {
+               writeback->active_writebacks_per_stream = stream->num_wb_info 
<= DML2_MAX_WRITEBACK ?
+                               stream->num_wb_info : DML2_MAX_WRITEBACK;
+
+               ASSERT(stream->num_wb_info <= DML2_MAX_WRITEBACK);
+
+               for (unsigned int wb_index = 0; wb_index < stream->num_wb_info; 
wb_index++) {
+                       const struct dc_writeback_info *dc_wb_info = 
&stream->writeback_info[wb_index];
+                       struct dml2_writeback_info *wb_info = 
&writeback->writeback_stream[wb_index];
+
+                       switch 
(dc_wb_info->dwb_params.cnv_params.fc_out_format) {
+                       case DWB_OUT_FORMAT_64BPP_ARGB:
+                       case DWB_OUT_FORMAT_64BPP_RGBA:
+                               wb_info->pixel_format = dml2_444_64;
+                               break;
+                       case DWB_OUT_FORMAT_32BPP_ARGB:
+                       case DWB_OUT_FORMAT_32BPP_RGBA:
+                       default:
+                               wb_info->pixel_format = dml2_444_32;
+                               break;
+                       }
+
+                       wb_info->input_width = 
dc_wb_info->dwb_params.cnv_params.crop_en ?
+                                       
dc_wb_info->dwb_params.cnv_params.crop_width :
+                                       
dc_wb_info->dwb_params.cnv_params.src_width;
+                       wb_info->input_height = 
dc_wb_info->dwb_params.cnv_params.crop_en ?
+                                       
dc_wb_info->dwb_params.cnv_params.crop_height :
+                                       
dc_wb_info->dwb_params.cnv_params.src_height;
+                       wb_info->output_width = 
dc_wb_info->dwb_params.dest_width;
+                       wb_info->output_height = 
dc_wb_info->dwb_params.dest_height;
+                       wb_info->v_taps = 
dc_wb_info->dwb_params.scaler_taps.v_taps > 0 ?
+                                       
dc_wb_info->dwb_params.scaler_taps.v_taps : 1;
+                       wb_info->h_taps = 
dc_wb_info->dwb_params.scaler_taps.h_taps > 0 ?
+                                       
dc_wb_info->dwb_params.scaler_taps.h_taps : 1;
+                       wb_info->v_taps_chroma = 
dc_wb_info->dwb_params.scaler_taps.v_taps_c > 0 ?
+                                       
dc_wb_info->dwb_params.scaler_taps.v_taps_c : 1;
+                       wb_info->h_taps_chroma = 
dc_wb_info->dwb_params.scaler_taps.h_taps_c > 0 ?
+                                       
dc_wb_info->dwb_params.scaler_taps.h_taps_c : 1;
+                       wb_info->h_ratio = 
dc_wb_info->dwb_params.cnv_params.crop_en ?
+                                       
(double)dc_wb_info->dwb_params.cnv_params.crop_width /
+                                       
(double)dc_wb_info->dwb_params.dest_width :
+                                       
(double)dc_wb_info->dwb_params.cnv_params.src_width /
+                                       
(double)dc_wb_info->dwb_params.dest_width;
+                       wb_info->v_ratio = 
dc_wb_info->dwb_params.cnv_params.crop_en ?
+                                       
(double)dc_wb_info->dwb_params.cnv_params.crop_height /
+                                       
(double)dc_wb_info->dwb_params.dest_height :
+                                       
(double)dc_wb_info->dwb_params.cnv_params.src_height /
+                                       
(double)dc_wb_info->dwb_params.dest_height;
+               }
+       }
+}
+
 static void populate_dml21_stream_overrides_from_stream_state(
                struct dml2_stream_parameters *stream_desc,
                struct dc_stream_state *stream,
@@ -826,6 +881,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct 
dc *in_dc, struct dc_s
                ASSERT(disp_cfg_stream_location >= 0 && 
disp_cfg_stream_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
                
populate_dml21_timing_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing,
 context->streams[stream_index], otg_master_pipe, dml_ctx);
                
populate_dml21_output_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].output,
 context->streams[stream_index], otg_master_pipe);
+               
populate_dml21_writeback_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].writeback,
 context->streams[stream_index]);
                
populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location],
 context->streams[stream_index], &context->stream_status[stream_index]);
 
                
dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.fclk_pstate
 = dml2_twait_budgeting_setting_if_needed;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
index 835fece1d46a..16e1315da2fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
@@ -532,3 +532,20 @@ bool dml21_is_plane1_enabled(enum dml2_source_format_class 
source_format)
 {
        return source_format >= dml2_420_8 && source_format <= dml2_rgbe_alpha;
 }
+
+void dml21_program_dc_mcif_arb_params(struct dml2_context *dml_ctx,
+               struct dc_state *context,
+               struct dml2_per_stream_programming *stream_prog,
+               unsigned int wb_index,
+               unsigned int dwb_inst)
+{
+       /* DC struct contains global reg for every WB instance */
+       
memcpy(&context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[dwb_inst].dcn4x.global_regs,
+                       
&dml_ctx->v21.mode_programming.programming->mcif_global_regs,
+                       sizeof(struct dml2_mcif_global_register_set));
+
+       /* copy per-DWB pipe registers */
+       
memcpy(&context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[dwb_inst].dcn4x.inst_regs,
+                       stream_prog->mcif_regs[wb_index],
+                       sizeof(struct dml2_mcif_per_pipe_register_set));
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h
index bff945a4ab3a..7312c33143c6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.h
@@ -48,4 +48,9 @@ void dml21_build_fams2_programming(const struct dc *dc,
                struct dc_state *context,
                struct dml2_context *dml_ctx);
 bool dml21_is_plane1_enabled(enum dml2_source_format_class source_format);
+void dml21_program_dc_mcif_arb_params(struct dml2_context *dml_ctx,
+               struct dc_state *context,
+               struct dml2_per_stream_programming *stream_prog,
+               unsigned int wb_index,
+               unsigned int dwb_inst);
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c
index 11fc0b1cd152..a975d36ce15d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c
@@ -60,6 +60,7 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc 
*dc, struct dc_sta
        struct pipe_ctx *dc_phantom_pipes[__DML2_WRAPPER_MAX_STREAMS_PLANES__] 
= {0};
        int num_pipes;
        unsigned int dml_phantom_prog_idx;
+       unsigned int stream_wb_idx;
 
        context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
 
@@ -102,6 +103,15 @@ static void dml21_calculate_rq_and_dlg_params(const struct 
dc *dc, struct dc_sta
                        }
                }
 
+               /* program WB */
+               for (stream_wb_idx = 0; stream_wb_idx < 
stream_prog->stream_descriptor->writeback.active_writebacks_per_stream; 
stream_wb_idx++) {
+                       dml21_program_dc_mcif_arb_params(in_ctx,
+                                       context,
+                                       stream_prog,
+                                       stream_wb_idx,
+                                       
dc_main_pipes[0]->stream->writeback_info[stream_wb_idx].dwb_pipe_inst);
+               }
+
                /* copy per plane mcache allocation */
                
memcpy(&context->bw_ctx.bw.dcn.mcache_allocations[dml_prog_idx], 
&pln_prog->mcache_allocation, sizeof(struct dml2_mcache_surface_allocation));
                if (pln_prog->phantom_plane.valid) {
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 bd0d7549d20f..f00ca2983ff5 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
@@ -279,6 +279,8 @@ struct dml2_per_stream_programming {
 
        enum dml2_pstate_method uclk_pstate_method;
 
+       struct dml2_mcif_per_pipe_register_set *mcif_regs[DML2_MAX_WRITEBACK];
+
        struct {
                bool enabled;
                struct dml2_stream_parameters descriptor;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
index c983869e0fa3..727b01ca18bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
@@ -368,9 +368,10 @@ static void expand_implict_subvp(const struct 
display_configuation_with_meta *di
 static void pack_mode_programming_params_with_implicit_subvp(struct 
dml2_core_instance *core, const struct display_configuation_with_meta 
*display_cfg,
        const struct dml2_display_cfg *svp_expanded_display_cfg, struct 
dml2_display_cfg_programming *programming, struct dml2_core_scratch *scratch)
 {
-       unsigned int stream_index, plane_index, pipe_offset, 
stream_already_populated_mask, main_plane_index, mcache_index;
+       unsigned int stream_index, plane_index, pipe_offset, 
stream_already_populated_mask, main_plane_index, mcache_index, dwb_index;
        unsigned int total_main_mcaches_required = 0;
        int total_pipe_regs_copied = 0;
+       int total_dwb_regs_copied = 0;
        int dml_internal_pipe_index = 0;
        const struct dml2_plane_parameters *main_plane;
        const struct dml2_plane_parameters *phantom_plane;
@@ -386,6 +387,8 @@ static void 
pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
        // display config
        dml2_core_calcs_get_watermarks(&display_cfg->display_config, 
&core->clean_me_up.mode_lib, &programming->global_regs.wm_regs[0]);
 
+       dml2_core_calcs_get_mcif_arb_params(&core->clean_me_up.mode_lib, 
&programming->mcif_global_regs);
+
        // Check if FAMS2 is required
        if (display_cfg->stage3.performed && display_cfg->stage3.success) {
                programming->fams2_required = 
display_cfg->stage3.fams2_required;
@@ -470,6 +473,19 @@ static void 
pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
                                        
programming->stream_programming[main_plane->stream_index].uclk_pstate_method,
                                        plane_index);
 
+                               /* populate DWB */
+                               for (dwb_index = 0; dwb_index < 
svp_expanded_display_cfg->stream_descriptors[main_plane->stream_index].writeback.active_writebacks_per_stream;
 dwb_index++) {
+                                       
programming->stream_programming[main_plane->stream_index].mcif_regs[dwb_index] 
= &programming->mcif_regs[total_dwb_regs_copied];
+                                       
memset(programming->stream_programming[main_plane->stream_index].mcif_regs[dwb_index],
 0, sizeof(struct dml2_mcif_per_pipe_register_set));
+                                       total_dwb_regs_copied++;
+
+                                       
dml2_core_calcs_get_per_dwb_params(svp_expanded_display_cfg,
+                                                       
&core->clean_me_up.mode_lib,
+                                                       
programming->stream_programming[main_plane->stream_index].mcif_regs[dwb_index],
+                                                       
main_plane->stream_index,
+                                                       dwb_index);
+                               }
+
                                stream_already_populated_mask |= (0x1 << 
main_plane->stream_index);
                        }
                        dml_internal_pipe_index++;
@@ -661,10 +677,12 @@ bool core_dcn4_mode_programming(struct 
dml2_core_mode_programming_in_out *in_out
        unsigned int pipe_offset;
        int dml_internal_pipe_index;
        int total_pipe_regs_copied = 0;
+       int total_dwb_regs_copied = 0;
        int stream_already_populated_mask = 0;
 
        int main_stream_index;
        unsigned int plane_index;
+       unsigned int dwb_index;
 
        expand_implict_subvp(in_out->display_cfg, &l->svp_expanded_display_cfg, 
&core->scratch);
 
@@ -688,6 +706,8 @@ bool core_dcn4_mode_programming(struct 
dml2_core_mode_programming_in_out *in_out
                        
dml2_core_calcs_get_arb_params(&l->svp_expanded_display_cfg, 
&core->clean_me_up.mode_lib, &in_out->programming->global_regs.arb_regs);
                        
dml2_core_calcs_get_watermarks(&l->svp_expanded_display_cfg, 
&core->clean_me_up.mode_lib, &in_out->programming->global_regs.wm_regs[0]);
 
+                       
dml2_core_calcs_get_mcif_arb_params(&core->clean_me_up.mode_lib, 
&in_out->programming->mcif_global_regs);
+
                        dml_internal_pipe_index = 0;
 
                        for (plane_index = 0; plane_index < 
in_out->programming->display_config.num_planes; plane_index++) {
@@ -733,6 +753,18 @@ bool core_dcn4_mode_programming(struct 
dml2_core_mode_programming_in_out *in_out
                                                
in_out->programming->stream_programming[main_stream_index].num_odms_required = 
in_out->cfg_support_info->stream_support_info[main_stream_index].odms_used;
                                                
dml2_core_calcs_get_stream_programming(&core->clean_me_up.mode_lib, 
&in_out->programming->stream_programming[main_stream_index], 
dml_internal_pipe_index);
 
+                                               for (dwb_index = 0; dwb_index < 
l->svp_expanded_display_cfg.stream_descriptors[main_stream_index].writeback.active_writebacks_per_stream;
 dwb_index++) {
+                                                       
in_out->programming->stream_programming[main_stream_index].mcif_regs[dwb_index] 
= &in_out->programming->mcif_regs[total_dwb_regs_copied];
+                                                       
memset(in_out->programming->stream_programming[main_stream_index].mcif_regs[dwb_index],
 0, sizeof(struct dml2_mcif_per_pipe_register_set));
+                                                       total_dwb_regs_copied++;
+
+                                                       
dml2_core_calcs_get_per_dwb_params(&l->svp_expanded_display_cfg,
+                                                                       
&core->clean_me_up.mode_lib,
+                                                                       
in_out->programming->stream_programming[main_stream_index].mcif_regs[dwb_index],
+                                                                       
main_stream_index,
+                                                                       
dwb_index);
+                                               }
+
                                                stream_already_populated_mask 
|= (0x1 << main_stream_index);
                                        }
                                        dml_internal_pipe_index++;
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 b667fc9ad75f..fa78016b32fc 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
@@ -6741,6 +6741,25 @@ static void CalculateFlipSchedule(
 #endif
 }
 
+static double calculate_writeback_latency_hiding_us(
+               const struct dml2_display_cfg *display_cfg,
+               unsigned int writeback_buffer_size_bytes,
+               unsigned int stream_index,
+               unsigned int dwb_index)
+{
+       double line_time_us = 
(double)display_cfg->stream_descriptors[stream_index].timing.h_total /
+                       
(double)display_cfg->stream_descriptors[stream_index].timing.pixel_clock_khz / 
1000.0;
+
+       double writeback_latency_hiding_us = 
(double)writeback_buffer_size_bytes /
+                       
((double)display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].output_height
 *
+                       
(double)display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].output_width
 /
+                       
((double)display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].input_height
 *
+                       line_time_us) * 4.0);
+
+       return 
display_cfg->stream_descriptors[stream_index].writeback.writeback_stream[dwb_index].pixel_format
 == dml2_444_64 ?
+                       writeback_latency_hiding_us / 2 : 
writeback_latency_hiding_us;
+}
+
 static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
        struct dml2_core_internal_scratch *scratch,
        struct 
dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *p)
@@ -6905,13 +6924,10 @@ static void 
CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                        p->VActiveLatencyHidingUs[k] = 
s->ActiveClockChangeLatencyHiding;
 
                if 
(p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream
 > 0) {
-                       s->WritebackLatencyHiding = 
(double)p->WritebackInterfaceBufferSize * 1024.0
-                               / 
((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[0].output_height
-                                       * 
(double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[0].output_width
-                                       / 
((double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[0].input_height
 * (double)h_total / pixel_clock_mhz) * 4.0);
-                       if 
(p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[0].pixel_format
 == dml2_444_64) {
-                               s->WritebackLatencyHiding = 
s->WritebackLatencyHiding / 2;
-                       }
+                       s->WritebackLatencyHiding = 
calculate_writeback_latency_hiding_us(p->display_cfg,
+                                       p->WritebackInterfaceBufferSize * 1024,
+                                       
p->display_cfg->plane_descriptors[k].stream_index,
+                                       0);
                        s->WritebackDRAMClockChangeLatencyMargin = 
s->WritebackLatencyHiding - p->Watermark->WritebackDRAMClockChangeWatermark;
 
                        s->WritebackFCLKChangeLatencyMargin = 
s->WritebackLatencyHiding - p->Watermark->WritebackFCLKChangeWatermark;
@@ -8693,6 +8709,7 @@ static bool dml_core_mode_support(struct 
dml2_core_calcs_mode_support_ex *in_out
        s->TotalNumberOfActiveWriteback = 0;
        memset(s->stream_visited, 0, DML2_MAX_PLANES * sizeof(bool));
 
+       mode_lib->ms.support.EnoughWritebackUnits = true;
        for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
                if (!dml_is_phantom_pipe(&display_cfg->plane_descriptors[k])) {
                        if 
(!s->stream_visited[display_cfg->plane_descriptors[k].stream_index]) {
@@ -8701,6 +8718,10 @@ static bool dml_core_mode_support(struct 
dml2_core_calcs_mode_support_ex *in_out
                                if 
(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream
 > 0)
                                        s->TotalNumberOfActiveWriteback = 
s->TotalNumberOfActiveWriteback + 1;
 
+                               /* >1 writeback per stream is currently not 
supported */
+                               if 
(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream
 > 1)
+                                       
mode_lib->ms.support.EnoughWritebackUnits = false;
+
                                s->TotalNumberOfActiveOTG = 
s->TotalNumberOfActiveOTG + 1;
                                if 
(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder
 == dml2_hdmifrl)
                                        s->TotalNumberOfActiveHDMIFRL = 
s->TotalNumberOfActiveHDMIFRL + 1;
@@ -8716,10 +8737,10 @@ static bool dml_core_mode_support(struct 
dml2_core_calcs_mode_support_ex *in_out
        }
 
        /* Writeback Mode Support Check */
-       mode_lib->ms.support.EnoughWritebackUnits = 1;
        if (s->TotalNumberOfActiveWriteback > (unsigned 
int)mode_lib->ip.max_num_wb) {
                mode_lib->ms.support.EnoughWritebackUnits = false;
        }
+
        mode_lib->ms.support.NumberOfOTGSupport = (s->TotalNumberOfActiveOTG <= 
(unsigned int)mode_lib->ip.max_num_otg);
        mode_lib->ms.support.NumberOfHDMIFRLSupport = 
(s->TotalNumberOfActiveHDMIFRL <= (unsigned 
int)mode_lib->ip.max_num_hdmi_frl_outputs);
        mode_lib->ms.support.NumberOfDP2p0Support = 
(s->TotalNumberOfActiveDP2p0 <= (unsigned 
int)mode_lib->ip.max_num_dp2p0_streams && s->TotalNumberOfActiveDP2p0Outputs <= 
(unsigned int)mode_lib->ip.max_num_dp2p0_outputs);
@@ -12831,6 +12852,14 @@ void dml2_core_calcs_get_arb_params(const struct 
dml2_display_cfg *display_cfg,
        rq_dlg_get_arb_params(display_cfg, mode_lib, out);
 }
 
+void dml2_core_calcs_get_mcif_arb_params(const struct 
dml2_core_internal_display_mode_lib *mode_lib, struct 
dml2_mcif_global_register_set *out)
+{
+       out->wm_regs[0].fclk_pstate = (unsigned 
int)(mode_lib->mp.Watermark.WritebackFCLKChangeWatermark * 1000.0);
+       out->wm_regs[0].uclk_pstate = (unsigned 
int)(mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark * 1000.0);
+       out->wm_regs[0].urgent = (unsigned 
int)(mode_lib->mp.Watermark.WritebackUrgentWatermark * 1000.0);
+       out->wm_regs[0].temp_read_or_ppt = (unsigned 
int)(mode_lib->mp.Watermark.writeback_temp_read_or_ppt_watermark_us * 1000.0);
+}
+
 void dml2_core_calcs_get_pipe_regs(const struct dml2_display_cfg *display_cfg,
        struct dml2_core_internal_display_mode_lib *mode_lib,
        struct dml2_dchub_per_pipe_register_set *out, int pipe_index)
@@ -12854,6 +12883,29 @@ void dml2_core_calcs_get_stream_programming(const 
struct dml2_core_internal_disp
        dml2_core_calcs_get_global_sync_programming(mode_lib, 
&out->global_sync, pipe_index);
 }
 
+void dml2_core_calcs_get_per_dwb_params(const struct dml2_display_cfg 
*display_cfg,
+               const struct dml2_core_internal_display_mode_lib *mode_lib,
+               struct dml2_mcif_per_pipe_register_set *out,
+               int stream_index,
+               int dwb_index)
+{
+       double writeback_latency_hiding_us = 
calculate_writeback_latency_hiding_us(display_cfg,
+                                       
mode_lib->ip.writeback_interface_buffer_size_kbytes * 1024,
+                                       stream_index,
+                                       dwb_index);
+
+       out->max_scaled_time_ns = (unsigned int)math_max2(
+                       (writeback_latency_hiding_us - 
mode_lib->mp.Watermark.WritebackUrgentWatermark) * 1000.0,
+                       0.0);
+
+       /* 1024ps units in U6.6 format */
+       out->time_per_pixel = (unsigned int)((1000000.0 * math_pow(2, 6)) /
+                       
(double)display_cfg->stream_descriptors[stream_index].timing.pixel_clock_khz);
+
+       out->slice_lines = 31;
+       out->arbitration_slice = 2;
+}
+
 void dml2_core_calcs_get_global_fams2_programming(const struct 
dml2_core_internal_display_mode_lib *mode_lib,
                const struct display_configuation_with_meta *display_cfg,
                struct dmub_cmd_fams2_global_config *fams2_global_config)
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
index 27ef0e096b25..3249f6bcf7bc 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h
@@ -19,6 +19,7 @@ struct display_configuation_with_meta;
 unsigned int dml2_core_calcs_mode_support_ex(struct 
dml2_core_calcs_mode_support_ex *in_out_params);
 bool dml2_core_calcs_mode_programming_ex(struct 
dml2_core_calcs_mode_programming_ex *in_out_params);
 void dml2_core_calcs_get_watermarks(const struct dml2_display_cfg 
*display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, 
struct dml2_dchub_watermark_regs *out);
+void dml2_core_calcs_get_mcif_arb_params(const struct 
dml2_core_internal_display_mode_lib *mode_lib, struct 
dml2_mcif_global_register_set *out);
 void dml2_core_calcs_get_arb_params(const struct dml2_display_cfg 
*display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, 
struct dml2_display_arb_regs *out);
 void dml2_core_calcs_get_pipe_regs(const struct dml2_display_cfg 
*dml2_display_cfg, struct dml2_core_internal_display_mode_lib *mode_lib, struct 
dml2_dchub_per_pipe_register_set *out, int pipe_index);
 void dml2_core_calcs_get_stream_programming(const struct 
dml2_core_internal_display_mode_lib *mode_lib, struct 
dml2_per_stream_programming *out, int pipe_index);
@@ -30,6 +31,7 @@ void dml2_core_calcs_get_stream_support_info(const struct 
dml2_display_cfg *disp
 void dml2_core_calcs_get_mall_allocation(struct 
dml2_core_internal_display_mode_lib *mode_lib, unsigned int *out, int 
pipe_index);
 void dml2_core_calcs_get_stream_fams2_programming(const struct 
dml2_core_internal_display_mode_lib *mode_lib, const struct 
display_configuation_with_meta *display_cfg, union dmub_cmd_fams2_config 
*fams2_base_programming, union dmub_cmd_fams2_config *fams2_sub_programming, 
enum dml2_pstate_method pstate_method, int plane_index);
 void dml2_core_calcs_get_global_fams2_programming(const struct 
dml2_core_internal_display_mode_lib *mode_lib, const struct 
display_configuation_with_meta *display_cfg, struct 
dmub_cmd_fams2_global_config *fams2_global_config);
+void dml2_core_calcs_get_per_dwb_params(const struct dml2_display_cfg 
*display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, 
struct dml2_mcif_per_pipe_register_set *out, int stream_index, int dwb_index);
 
 void dml2_core_calcs_get_dpte_row_height(unsigned int *dpte_row_height, struct 
dml2_core_internal_display_mode_lib *mode_lib, bool is_plane1, enum 
dml2_source_format_class SourcePixelFormat, enum dml2_swizzle_mode 
SurfaceTiling, enum dml2_rotation_angle ScanDirection, unsigned int pitch, 
unsigned int GPUVMMinPageSizeKBytes);
 void dml2_core_calcs_cursor_dlg_reg(struct dml2_cursor_dlg_regs 
*cursor_dlg_regs, const struct dml2_get_cursor_dlg_reg *p);
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 5ffe211a6643..c60a1faf2d5d 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
@@ -779,6 +779,25 @@ bool dpmm_dcn4_map_mode_to_soc_dpm(struct 
dml2_dpmm_map_mode_to_soc_dpm_params_i
        return result;
 }
 
+static void dpmm_dcn4_map_mcif_watermarks(struct 
dml2_dpmm_map_watermarks_params_in_out *in_out)
+{
+       const struct dml2_core_internal_display_mode_lib *mode_lib = 
&in_out->core->clean_me_up.mode_lib;
+       struct dml2_mcif_global_register_set *mcif_regs = 
&in_out->programming->mcif_global_regs;
+
+       /* MCIF */
+       mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].urgent = (int 
unsigned)(mode_lib->mp.Watermark.WritebackUrgentWatermark * 1000.0);
+       mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].uclk_pstate = (int 
unsigned)(mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark * 1000.0);
+       mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].fclk_pstate = (int 
unsigned)(mode_lib->mp.Watermark.WritebackFCLKChangeWatermark * 1000.0);
+       mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].temp_read_or_ppt = (int 
unsigned)(mode_lib->mp.Watermark.writeback_temp_read_or_ppt_watermark_us * 
1000.0);
+
+       /* replicate sets A through D */
+       memcpy(&mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B], 
&mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A], 
sizeof(mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A]));
+       memcpy(&mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_C], 
&mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A], 
sizeof(mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A]));
+       memcpy(&mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_D], 
&mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A], 
sizeof(mcif_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A]));
+
+       mcif_regs->num_watermark_sets = 4;
+}
+
 bool dpmm_dcn4_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out 
*in_out)
 {
        const struct dml2_display_cfg *display_cfg = 
&in_out->display_cfg->display_config;
@@ -821,6 +840,8 @@ bool dpmm_dcn4_map_watermarks(struct 
dml2_dpmm_map_watermarks_params_in_out *in_
 
        dchubbub_regs->num_watermark_sets = 2;
 
+       dpmm_dcn4_map_mcif_watermarks(in_out);
+
        return true;
 }
 bool dpmm_dcn42_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out 
*in_out)
-- 
2.43.0

Reply via email to