From: Roman Li <[email protected]>

DML support for DCN 4.2

Signed-off-by: Roman Li <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
---
 .../gpu/drm/amd/display/dc/dml2_0/Makefile    |   3 +
 .../dml2_0/dml21/dml21_translation_helper.c   |  13 ++
 .../dc/dml2_0/dml21/inc/dml_top_types.h       |   1 +
 .../dml21/src/dml2_core/dml2_core_dcn4.c      | 111 ++++++++++++++++++
 .../dml21/src/dml2_core/dml2_core_dcn4.h      |   1 +
 .../dml21/src/dml2_core/dml2_core_factory.c   |   8 ++
 .../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c      |  34 ++++++
 .../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h      |   1 +
 .../dml21/src/dml2_dpmm/dml2_dpmm_factory.c   |   5 +
 .../dml21/src/dml2_mcg/dml2_mcg_dcn42.c       |  76 ++++++++++++
 .../dml21/src/dml2_mcg/dml2_mcg_dcn42.h       |  11 ++
 .../dml21/src/dml2_mcg/dml2_mcg_factory.c     |   5 +
 .../dml21/src/dml2_top/dml2_top_interfaces.c  |   1 +
 13 files changed, 270 insertions(+)
 create mode 100644 
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.c
 create mode 100644 
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.h

diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile 
b/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
index 30cfc0848792..70d9f2cd0b60 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
@@ -90,6 +90,7 @@ 
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_factory.o := $(dml2
 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.o := 
$(dml2_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.o := 
$(dml2_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn4.o := 
$(dml2_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.o := 
$(dml2_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.o := 
$(dml2_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn3.o := 
$(dml2_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.o := 
$(dml2_ccflags)
@@ -107,6 +108,7 @@ 
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_top/dml2_top_soc15.o := $(d
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.o := 
$(dml2_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.o 
:= $(dml2_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn4.o := 
$(dml2_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.o := 
$(dml2_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.o := 
$(dml2_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn3.o := 
$(dml2_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.o 
:= $(dml2_rcflags)
@@ -124,6 +126,7 @@ DML21 += src/dml2_core/dml2_core_dcn4_calcs.o
 DML21 += src/dml2_dpmm/dml2_dpmm_dcn4.o
 DML21 += src/dml2_dpmm/dml2_dpmm_factory.o
 DML21 += src/dml2_mcg/dml2_mcg_dcn4.o
+DML21 += src/dml2_mcg/dml2_mcg_dcn42.o
 DML21 += src/dml2_mcg/dml2_mcg_factory.o
 DML21 += src/dml2_pmo/dml2_pmo_dcn3.o
 DML21 += src/dml2_pmo/dml2_pmo_factory.o
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 cd12b7a6da65..6cc03391fff6 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
@@ -45,6 +45,9 @@ static enum dml2_project_id 
dml21_dcn_revision_to_dml2_project_id(enum dce_versi
        case DCN_VERSION_4_01:
                project_id = dml2_project_dcn4x_stage2_auto_drr_svp;
                break;
+       case DCN_VERSION_4_2:
+               project_id = dml2_project_dcn42;
+               break;
        default:
                project_id = dml2_project_invalid;
                DC_ERR("unsupported dcn version for DML21!");
@@ -615,6 +618,13 @@ static void 
populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
                case DC_CM2_GPU_MEM_SIZE_171717:
                        plane->tdlut.tdlut_width_mode = 
dml2_tdlut_width_17_cube;
                        break;
+               case DC_CM2_GPU_MEM_SIZE_333333:
+                       plane->tdlut.tdlut_width_mode = 
dml2_tdlut_width_33_cube;
+                       break;
+               // handling when use case and HW support available
+               case DC_CM2_GPU_MEM_SIZE_454545:
+               case DC_CM2_GPU_MEM_SIZE_656565:
+                       break;
                case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
                default:
                        //plane->tdlut.tdlut_width_mode = 
dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined
@@ -824,6 +834,9 @@ void dml21_copy_clocks_to_dc_state(struct dml2_context 
*in_ctx, struct dc_state
        context->bw_ctx.bw.dcn.clk.subvp_prefetch_fclk_khz = 
in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz;
        context->bw_ctx.bw.dcn.clk.stutter_efficiency.base_efficiency = 
in_ctx->v21.mode_programming.programming->stutter.base_percent_efficiency;
        context->bw_ctx.bw.dcn.clk.stutter_efficiency.low_power_efficiency = 
in_ctx->v21.mode_programming.programming->stutter.low_power_percent_efficiency;
+       context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_efficiency = 
in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_efficiency;
+       context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_period = 
in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_period;
+       context->bw_ctx.bw.dcn.clk.zstate_support = 
in_ctx->v21.mode_programming.programming->z8_stutter.supported_in_blank; 
/*ignore meets_eco since it is not used*/
 }
 
 static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union 
dcn_watermark_set *watermarks, const enum dml2_dchub_watermark_reg_set_index 
wm_index)
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 943fd3f040c3..c854515b49a3 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
@@ -19,6 +19,7 @@ enum dml2_project_id {
        dml2_project_dcn4x_stage1,
        dml2_project_dcn4x_stage2,
        dml2_project_dcn4x_stage2_auto_drr_svp,
+       dml2_project_dcn42,
 };
 
 enum dml2_pstate_change_support {
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 eba948e187c1..23ede1107340 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
@@ -78,6 +78,86 @@ struct dml2_core_ip_params core_dcn4_ip_caps_base = {
        .subvp_swath_height_margin_lines = 16,
 };
 
+struct dml2_core_ip_params core_dcn42_ip_caps_base = {
+.vblank_nom_default_us = 668,
+.remote_iommu_outstanding_translations = 256,
+.rob_buffer_size_kbytes = 64,
+.config_return_buffer_size_in_kbytes = 1792,
+.config_return_buffer_segment_size_in_kbytes = 64,
+.compressed_buffer_segment_size_in_kbytes = 64,
+.dpte_buffer_size_in_pte_reqs_luma = 68,
+.dpte_buffer_size_in_pte_reqs_chroma = 36,
+.pixel_chunk_size_kbytes = 8,
+.alpha_pixel_chunk_size_kbytes = 4,
+.min_pixel_chunk_size_bytes = 1024,
+.writeback_chunk_size_kbytes = 8,
+.line_buffer_size_bits = 1171920,
+.max_line_buffer_lines = 32,
+.writeback_interface_buffer_size_kbytes = 90,
+
+//Number of pipes after DCN Pipe harvesting
+.max_num_dpp = 4,
+.max_num_otg = 4,
+.max_num_opp = 4,
+.max_num_wb = 1,
+.max_dchub_pscl_bw_pix_per_clk = 4,
+.max_pscl_lb_bw_pix_per_clk = 2,
+.max_lb_vscl_bw_pix_per_clk = 4,
+.max_vscl_hscl_bw_pix_per_clk = 4,
+.max_hscl_ratio = 6,
+.max_vscl_ratio = 6,
+.max_hscl_taps = 8,
+.max_vscl_taps = 8,
+.dispclk_ramp_margin_percent = 1,
+.dppclk_delay_subtotal = 47,
+.dppclk_delay_scl = 50,
+.dppclk_delay_scl_lb_only = 16,
+.dppclk_delay_cnvc_formatter = 28,
+.dppclk_delay_cnvc_cursor = 6,
+.cursor_buffer_size = 42,
+.cursor_chunk_size = 2,
+.dispclk_delay_subtotal = 125,
+.max_inter_dcn_tile_repeaters = 8,
+.writeback_max_hscl_ratio = 1,
+.writeback_max_vscl_ratio = 1,
+.writeback_min_hscl_ratio = 1,
+.writeback_min_vscl_ratio = 1,
+.writeback_max_hscl_taps = 1,
+.writeback_max_vscl_taps = 1,
+.writeback_line_buffer_buffer_size = 0,
+.num_dsc = 4,
+.maximum_dsc_bits_per_component = 12,
+.maximum_pixels_per_line_per_dsc_unit = 5760,
+.dsc422_native_support = true,
+.dcc_supported = true,
+.ptoi_supported = false,
+
+.cursor_64bpp_support = true,
+.dynamic_metadata_vm_enabled = false,
+
+.max_num_hdmi_frl_outputs = 0,
+.max_num_dp2p0_outputs = 2,
+.max_num_dp2p0_streams = 4,
+.imall_supported = 1,
+.max_flip_time_us = 110,
+.max_flip_time_lines = 50,
+.words_per_channel = 16,
+
+.subvp_fw_processing_delay_us = 15,
+.subvp_pstate_allow_width_us = 20,
+.subvp_swath_height_margin_lines = 16,
+
+.dcn_mrq_present = 1,
+.zero_size_buffer_entries = 512,
+.compbuf_reserved_space_zs = 64,
+.dcc_meta_buffer_size_bytes = 6272,
+.meta_chunk_size_kbytes = 2,
+.min_meta_chunk_size_bytes = 256,
+
+.dchub_arb_to_ret_delay = 102,
+.hostvm_mode = 1,
+};
+
 static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities 
*ip_caps, const struct dml2_core_ip_params *ip_params)
 {
        ip_caps->pipe_count = ip_params->max_num_dpp;
@@ -153,6 +233,37 @@ bool core_dcn4_initialize(struct 
dml2_core_initialize_in_out *in_out)
        return true;
 }
 
+bool core_dcn42_initialize(struct dml2_core_initialize_in_out *in_out)
+{
+struct dml2_core_instance *core = in_out->instance;
+
+if (!in_out->minimum_clock_table)
+return false;
+
+core->minimum_clock_table = in_out->minimum_clock_table;
+
+if (in_out->explicit_ip_bb && in_out->explicit_ip_bb_size > 0) {
+memcpy(&core->clean_me_up.mode_lib.ip, in_out->explicit_ip_bb, 
in_out->explicit_ip_bb_size);
+
+// FIXME_STAGE2:
+// DV still uses stage1 ip_param_st for each variant, need to patch the 
ip_caps with ip_param info
+// Should move DV to use ip_caps but need move more overrides to ip_caps
+patch_ip_caps_with_explicit_ip_params(in_out->ip_caps, in_out->explicit_ip_bb);
+core->clean_me_up.mode_lib.ip.subvp_pstate_allow_width_us = 
core_dcn4_ip_caps_base.subvp_pstate_allow_width_us;
+core->clean_me_up.mode_lib.ip.subvp_fw_processing_delay_us = 
core_dcn4_ip_caps_base.subvp_pstate_allow_width_us;
+core->clean_me_up.mode_lib.ip.subvp_swath_height_margin_lines = 
core_dcn4_ip_caps_base.subvp_swath_height_margin_lines;
+} else {
+memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn42_ip_caps_base, sizeof(struct 
dml2_core_ip_params));
+patch_ip_params_with_ip_caps(&core->clean_me_up.mode_lib.ip, in_out->ip_caps);
+core->clean_me_up.mode_lib.ip.imall_supported = false;
+}
+
+memcpy(&core->clean_me_up.mode_lib.soc, in_out->soc_bb, sizeof(struct 
dml2_soc_bb));
+memcpy(&core->clean_me_up.mode_lib.ip_caps, in_out->ip_caps, sizeof(struct 
dml2_ip_capabilities));
+
+return true;
+}
+
 static void create_phantom_stream_from_main_stream(struct 
dml2_stream_parameters *phantom, const struct dml2_stream_parameters *main,
        const struct dml2_implicit_svp_meta *meta)
 {
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.h 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.h
index a68bb001a346..5c26d819a673 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.h
@@ -5,6 +5,7 @@
 #ifndef __DML2_CORE_DCN4_H__
 #define __DML2_CORE_DCN4_H__
 bool core_dcn4_initialize(struct dml2_core_initialize_in_out *in_out);
+bool core_dcn42_initialize(struct dml2_core_initialize_in_out *in_out);
 bool core_dcn4_mode_support(struct dml2_core_mode_support_in_out *in_out);
 bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out 
*in_out);
 bool core_dcn4_populate_informative(struct 
dml2_core_populate_informative_in_out *in_out);
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_factory.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_factory.c
index cc4f0663c6d6..67e307fa4310 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_factory.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_factory.c
@@ -30,6 +30,14 @@ bool dml2_core_create(enum dml2_project_id project_id, 
struct dml2_core_instance
                out->calculate_mcache_allocation = 
&core_dcn4_calculate_mcache_allocation;
                result = true;
                break;
+       case dml2_project_dcn42:
+               out->initialize = &core_dcn42_initialize;
+               out->mode_support = &core_dcn4_mode_support;
+               out->mode_programming = &core_dcn4_mode_programming;
+               out->populate_informative = &core_dcn4_populate_informative;
+               out->calculate_mcache_allocation = 
&core_dcn4_calculate_mcache_allocation;
+               result = true;
+               break;
        case dml2_project_invalid:
        default:
                break;
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 9d7741fd0adb..037272d2c2e6 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
@@ -802,3 +802,37 @@ bool dpmm_dcn4_map_watermarks(struct 
dml2_dpmm_map_watermarks_params_in_out *in_
 
        return true;
 }
+
+bool dpmm_dcn42_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;
+       const struct dml2_core_internal_display_mode_lib *mode_lib = 
&in_out->core->clean_me_up.mode_lib;
+       struct dml2_dchub_global_register_set *dchubbub_regs = 
&in_out->programming->global_regs;
+
+       double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz 
> 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : 
mode_lib->soc.dchub_refclk_mhz;
+
+       /* set A */
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].fclk_pstate = (int 
unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_enter = (int 
unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * 
refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_exit = (int 
unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_enter_z8 = (int 
unsigned)(mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark * 
refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_exit_z8 = (int 
unsigned)(mode_lib->mp.Watermark.Z8StutterExitWatermark * refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].temp_read_or_ppt = 
(int unsigned)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * 
refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].uclk_pstate = (int 
unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].urgent = (int 
unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].usr = (int 
unsigned)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz);
+       
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].refcyc_per_trip_to_mem = 
(unsigned int)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz);
+       
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].refcyc_per_meta_trip_to_mem 
= (unsigned int)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].frac_urg_bw_flip = 
(unsigned int)(mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip * 1000);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].frac_urg_bw_nom = 
(unsigned int)(mode_lib->mp.FractionOfUrgentBandwidth * 1000);
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].frac_urg_bw_mall = 
(unsigned int)(mode_lib->mp.FractionOfUrgentBandwidthMALL * 1000);
+
+       /* set B */
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B] = 
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A];
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_C] = 
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A];
+       dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_D] = 
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A];
+
+       dchubbub_regs->num_watermark_sets = 4;
+
+       return true;
+}
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
index e7b58f2efda4..5fbd07e238a8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
@@ -10,5 +10,6 @@
 bool dpmm_dcn3_map_mode_to_soc_dpm(struct 
dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out);
 bool dpmm_dcn4_map_mode_to_soc_dpm(struct 
dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out);
 bool dpmm_dcn4_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out 
*in_out);
+bool dpmm_dcn42_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out 
*in_out);
 
 #endif
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
index dfd01440737d..80d4932bf154 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
@@ -41,6 +41,11 @@ bool dml2_dpmm_create(enum dml2_project_id project_id, 
struct dml2_dpmm_instance
                out->map_watermarks = &dpmm_dcn4_map_watermarks;
                result = true;
                break;
+       case dml2_project_dcn42:
+               out->map_mode_to_soc_dpm = &dpmm_dcn4_map_mode_to_soc_dpm;
+               out->map_watermarks = &dpmm_dcn42_map_watermarks;
+               result = true;
+               break;
        case dml2_project_invalid:
        default:
                break;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.c
new file mode 100644
index 000000000000..1f67cbc2c236
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2026 Advanced Micro Devices, Inc.
+
+#include "dml2_mcg_dcn42.h"
+#include "dml_top_soc_parameter_types.h"
+
+static unsigned long long uclk_to_dram_bw_kbps(unsigned long uclk_khz, const 
struct dml2_dram_params *dram_config, unsigned long wck_ratio)
+{
+       unsigned long long bw_kbps = 0;
+
+       bw_kbps = (unsigned long long) uclk_khz * dram_config->channel_count * 
dram_config->channel_width_bytes * wck_ratio * 2;
+       return bw_kbps;
+}
+
+static bool build_min_clk_table_coarse_grained(const struct dml2_soc_bb 
*soc_bb, struct dml2_mcg_min_clock_table *min_table)
+{
+       int i;
+
+       for (i = 0; i < soc_bb->clk_table.fclk.num_clk_values; i++) {
+               if (i < soc_bb->clk_table.uclk.num_clk_values) {
+                       
min_table->dram_bw_table.entries[i].pre_derate_dram_bw_kbps =
+                                       
uclk_to_dram_bw_kbps(soc_bb->clk_table.uclk.clk_values_khz[i], 
&soc_bb->clk_table.dram_config, soc_bb->clk_table.wck_ratio.clk_values_khz[i]);
+                       min_table->dram_bw_table.entries[i].min_uclk_khz = 
soc_bb->clk_table.uclk.clk_values_khz[i];
+               } else {
+                       
min_table->dram_bw_table.entries[i].pre_derate_dram_bw_kbps = 
min_table->dram_bw_table.entries[soc_bb->clk_table.uclk.num_clk_values - 
1].pre_derate_dram_bw_kbps;
+                       min_table->dram_bw_table.entries[i].min_uclk_khz = 
soc_bb->clk_table.uclk.clk_values_khz[soc_bb->clk_table.uclk.num_clk_values - 
1];
+               }
+
+               min_table->dram_bw_table.entries[i].min_dcfclk_khz = 
soc_bb->clk_table.dcfclk.clk_values_khz[i];
+               min_table->dram_bw_table.entries[i].min_fclk_khz = 
soc_bb->clk_table.fclk.clk_values_khz[i];
+       }
+       min_table->dram_bw_table.num_entries = 
soc_bb->clk_table.fclk.num_clk_values;
+
+       return true;
+}
+
+static bool build_min_clock_table(const struct dml2_soc_bb *soc_bb, struct 
dml2_mcg_min_clock_table *min_table)
+{
+       bool result;
+
+       if (!soc_bb || !min_table)
+               return false;
+
+
+       if (soc_bb->clk_table.uclk.num_clk_values > DML_MCG_MAX_CLK_TABLE_SIZE)
+               return false;
+
+       min_table->fixed_clocks_khz.amclk = 0;
+       min_table->fixed_clocks_khz.dprefclk = soc_bb->dprefclk_mhz * 1000;
+       min_table->fixed_clocks_khz.pcierefclk = soc_bb->pcie_refclk_mhz * 1000;
+       min_table->fixed_clocks_khz.dchubrefclk = soc_bb->dchub_refclk_mhz * 
1000;
+       min_table->fixed_clocks_khz.xtalclk = soc_bb->xtalclk_mhz * 1000;
+
+       min_table->max_clocks_khz.dispclk = 
soc_bb->clk_table.dispclk.clk_values_khz[soc_bb->clk_table.dispclk.num_clk_values
 - 1];
+       min_table->max_clocks_khz.dppclk = 
soc_bb->clk_table.dppclk.clk_values_khz[soc_bb->clk_table.dppclk.num_clk_values 
- 1];
+       min_table->max_clocks_khz.dscclk = 
soc_bb->clk_table.dscclk.clk_values_khz[soc_bb->clk_table.dscclk.num_clk_values 
- 1];
+       min_table->max_clocks_khz.dtbclk = 
soc_bb->clk_table.dtbclk.clk_values_khz[soc_bb->clk_table.dtbclk.num_clk_values 
- 1];
+       min_table->max_clocks_khz.phyclk = 
soc_bb->clk_table.phyclk.clk_values_khz[soc_bb->clk_table.phyclk.num_clk_values 
- 1];
+
+       min_table->max_ss_clocks_khz.dispclk = (unsigned 
int)((double)min_table->max_clocks_khz.dispclk / (1.0 + 
soc_bb->dcn_downspread_percent / 100.0));
+       min_table->max_ss_clocks_khz.dppclk = (unsigned 
int)((double)min_table->max_clocks_khz.dppclk / (1.0 + 
soc_bb->dcn_downspread_percent / 100.0));
+       min_table->max_ss_clocks_khz.dtbclk = (unsigned 
int)((double)min_table->max_clocks_khz.dtbclk / (1.0 + 
soc_bb->dcn_downspread_percent / 100.0));
+
+       min_table->max_clocks_khz.dcfclk = 
soc_bb->clk_table.dcfclk.clk_values_khz[soc_bb->clk_table.dcfclk.num_clk_values 
- 1];
+       min_table->max_clocks_khz.fclk = 
soc_bb->clk_table.fclk.clk_values_khz[soc_bb->clk_table.fclk.num_clk_values - 
1];
+
+       result = build_min_clk_table_coarse_grained(soc_bb, min_table);
+
+       return result;
+}
+
+bool mcg_dcn42_build_min_clock_table(struct 
dml2_mcg_build_min_clock_table_params_in_out *in_out)
+{
+       return build_min_clock_table(in_out->soc_bb, in_out->min_clk_table);
+}
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.h 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.h
new file mode 100644
index 000000000000..ad8a847a0a17
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright 2026 Advanced Micro Devices, Inc. */
+
+#ifndef __DML2_MCG_DCN42_H__
+#define __DML2_MCG_DCN42_H__
+
+#include "dml2_internal_shared_types.h"
+
+bool mcg_dcn42_build_min_clock_table(struct 
dml2_mcg_build_min_clock_table_params_in_out *in_out);
+
+#endif
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
index c60b8fe90819..1cff62b63e72 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
@@ -4,6 +4,7 @@
 
 #include "dml2_mcg_factory.h"
 #include "dml2_mcg_dcn4.h"
+#include "dml2_mcg_dcn42.h"
 #include "dml2_external_lib_deps.h"
 
 static bool dummy_build_min_clock_table(struct 
dml2_mcg_build_min_clock_table_params_in_out *in_out)
@@ -30,6 +31,10 @@ bool dml2_mcg_create(enum dml2_project_id project_id, struct 
dml2_mcg_instance *
                out->build_min_clock_table = &mcg_dcn4_build_min_clock_table;
                result = true;
                break;
+       case dml2_project_dcn42:
+               out->build_min_clock_table = &mcg_dcn42_build_min_clock_table;
+               result = true;
+               break;
        case dml2_project_invalid:
        default:
                break;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_interfaces.c
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_interfaces.c
index 5a33e2f357f4..04860b6790df 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_interfaces.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_interfaces.c
@@ -17,6 +17,7 @@ bool dml2_initialize_instance(struct 
dml2_initialize_instance_in_out *in_out)
        case dml2_project_dcn4x_stage1:
        case dml2_project_dcn4x_stage2:
        case dml2_project_dcn4x_stage2_auto_drr_svp:
+       case dml2_project_dcn42:
                return dml2_top_soc15_initialize_instance(in_out);
        case dml2_project_invalid:
        default:
-- 
2.43.0

Reply via email to