drm/amd/display: Fixes for mcache programming in DML21
authorDillon Varone <dillon.varone@amd.com>
Fri, 17 Jan 2025 22:49:41 +0000 (17:49 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 13 Feb 2025 02:03:00 +0000 (21:03 -0500)
[WHY & HOW]
- Fix indexing phantom planes for mcache programming in the wrapper
- Fix phantom mcache allocations to align with HW guidance
- Fix mcache assignment for chroma plane for multi-planar formats

Reviewed-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/inc/dml_top_types.h
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.c

index 1e56d995cd0e76e7b4770c3d8dfac9d3cc3c922a..930e86cdb88a2fc81ca873cee3a8043a0fe25e98 100644 (file)
@@ -232,7 +232,6 @@ void dml21_program_dc_pipe(struct dml2_context *dml_ctx, struct dc_state *contex
                context->bw_ctx.bw.dcn.clk.dppclk_khz = pipe_ctx->plane_res.bw.dppclk_khz;
 
        dml21_populate_mall_allocation_size(context, dml_ctx, pln_prog, pipe_ctx);
-       memcpy(&context->bw_ctx.bw.dcn.mcache_allocations[pipe_ctx->pipe_idx], &pln_prog->mcache_allocation, sizeof(struct dml2_mcache_surface_allocation));
 
        bool sub_vp_enabled = is_sub_vp_enabled(pipe_ctx->stream->ctx->dc, context);
 
index fb80ba9287b66027571a74c6eec49f3a099860b4..be54f0e696ce28929ad8ef2922480cf2054dd878 100644 (file)
@@ -124,6 +124,7 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta
        struct pipe_ctx *dc_main_pipes[__DML2_WRAPPER_MAX_STREAMS_PLANES__];
        struct pipe_ctx *dc_phantom_pipes[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0};
        int num_pipes;
+       unsigned int dml_phantom_prog_idx;
 
        context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
 
@@ -137,6 +138,9 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta
        context->bw_ctx.bw.dcn.mall_ss_psr_active_size_bytes = 0;
        context->bw_ctx.bw.dcn.mall_subvp_size_bytes = 0;
 
+       /* phantom's start after main planes */
+       dml_phantom_prog_idx = in_ctx->v21.mode_programming.programming->display_config.num_planes;
+
        for (dml_prog_idx = 0; dml_prog_idx < DML2_MAX_PLANES; dml_prog_idx++) {
                pln_prog = &in_ctx->v21.mode_programming.programming->plane_programming[dml_prog_idx];
 
@@ -162,6 +166,16 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta
                                dml21_program_dc_pipe(in_ctx, context, dc_phantom_pipes[dc_pipe_index], pln_prog, stream_prog);
                        }
                }
+
+               /* 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) {
+                       memcpy(&context->bw_ctx.bw.dcn.mcache_allocations[dml_phantom_prog_idx],
+                                       &pln_prog->phantom_plane.mcache_allocation,
+                                       sizeof(struct dml2_mcache_surface_allocation));
+
+                       dml_phantom_prog_idx++;
+               }
        }
 
        /* assign global clocks */
index d2d053f2354d00998e8cd656ce7595e67077a612..0ab19cf4d242190f5cc01c005cce0feb8e11ba85 100644 (file)
@@ -245,6 +245,7 @@ struct dml2_per_plane_programming {
        struct {
                bool valid;
                struct dml2_plane_parameters descriptor;
+               struct dml2_mcache_surface_allocation mcache_allocation;
                struct dml2_dchub_per_pipe_register_set *pipe_regs[DML2_MAX_PLANES];
        } phantom_plane;
 };
index d68b4567e218aabc0bf7c35658e257e2c8e1567c..ec0beb139200d25ffccafe6ee19e8aa0b280273b 100644 (file)
@@ -254,7 +254,8 @@ 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;
+       unsigned int stream_index, plane_index, pipe_offset, stream_already_populated_mask, main_plane_index, mcache_index;
+       unsigned int total_main_mcaches_required = 0;
        int total_pipe_regs_copied = 0;
        int dml_internal_pipe_index = 0;
        const struct dml2_plane_parameters *main_plane;
@@ -325,6 +326,13 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
 
                dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index);
 
+               memcpy(&programming->plane_programming[plane_index].mcache_allocation,
+                               &display_cfg->stage2.mcache_allocations[plane_index],
+                               sizeof(struct dml2_mcache_surface_allocation));
+               total_main_mcaches_required += programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane0 +
+                               programming->plane_programming[plane_index].mcache_allocation.num_mcaches_plane1 -
+                               (programming->plane_programming[plane_index].mcache_allocation.last_slice_sharing.plane0_plane1 ? 1 : 0);
+
                for (pipe_offset = 0; pipe_offset < programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) {
                        // Assign storage for this pipe's register values
                        programming->plane_programming[plane_index].pipe_regs[pipe_offset] = &programming->pipe_regs[total_pipe_regs_copied];
@@ -363,6 +371,22 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
                memcpy(&programming->plane_programming[main_plane_index].phantom_plane.descriptor, phantom_plane, sizeof(struct dml2_plane_parameters));
 
                dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &programming->plane_programming[main_plane_index].svp_size_mall_bytes, dml_internal_pipe_index);
+
+               /* generate mcache allocation, phantoms use identical mcache configuration, but in the MALL set and unique mcache ID's beginning after all main ID's */
+               memcpy(&programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation,
+                               &programming->plane_programming[main_plane_index].mcache_allocation,
+                               sizeof(struct dml2_mcache_surface_allocation));
+               for (mcache_index = 0; mcache_index < programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.num_mcaches_plane0; mcache_index++) {
+                       programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index] += total_main_mcaches_required;
+                       programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_mall_plane0[mcache_index] =
+                                       programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane0[mcache_index];
+               }
+               for (mcache_index = 0; mcache_index < programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.num_mcaches_plane1; mcache_index++) {
+                       programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index] += total_main_mcaches_required;
+                       programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_mall_plane1[mcache_index] =
+                                       programming->plane_programming[main_plane_index].phantom_plane.mcache_allocation.global_mcache_ids_plane1[mcache_index];
+               }
+
                for (pipe_offset = 0; pipe_offset < programming->plane_programming[main_plane_index].num_dpps_required; pipe_offset++) {
                        // Assign storage for this pipe's register values
                        programming->plane_programming[main_plane_index].phantom_plane.pipe_regs[pipe_offset] = &programming->pipe_regs[total_pipe_regs_copied];
@@ -572,6 +596,10 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out
 
                                dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &in_out->programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index);
 
+                               memcpy(&in_out->programming->plane_programming[plane_index].mcache_allocation,
+                                               &in_out->display_cfg->stage2.mcache_allocations[plane_index],
+                                               sizeof(struct dml2_mcache_surface_allocation));
+
                                for (pipe_offset = 0; pipe_offset < in_out->programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) {
                                        in_out->programming->plane_programming[plane_index].plane_descriptor = &in_out->programming->display_config.plane_descriptors[plane_index];
 
index e96a13dc43d48fd2f0d8c825ee6c209438137c97..47872c6f657e358b53a9c759ac711df6baf5da98 100644 (file)
@@ -2637,6 +2637,9 @@ static void calculate_mcache_setting(
        // Luma/Chroma combine in the last mcache
        // In the case of Luma/Chroma combine-mCache (with lc_comb_mcache==1), all mCaches except the last segment are filled as much as possible, when stay aligned to mvmpg boundary
        if (*p->lc_comb_mcache && l->is_dual_plane) {
+               /* if luma and chroma planes share an mcache, increase total chroma mcache count */
+               *p->num_mcaches_c = *p->num_mcaches_c + 1;
+
                for (n = 0; n < *p->num_mcaches_l - 1; n++)
                        p->mcache_offsets_l[n] = (n + 1) * l->mvmpg_per_mcache_lb_l * l->mvmpg_access_width_l;
                p->mcache_offsets_l[*p->num_mcaches_l - 1] = l->full_vp_access_width_l;
index a3324f7b9ba68b1fbad539c6d87d2fe4a835c8d4..15c906c42ec45045a72d0714f1268c60c73d4f5c 100644 (file)
@@ -1082,12 +1082,21 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo,
        const struct dml2_fams2_meta *stream_fams2_meta;
        unsigned int microschedule_vlines;
        unsigned int i;
+       unsigned int mcaches_per_plane;
+       unsigned int total_mcaches_required = 0;
 
        unsigned int num_planes_per_stream[DML2_MAX_PLANES] = { 0 };
 
        /* confirm timing it is not a centered timing */
        for (i = 0; i < display_config->display_config.num_planes; i++) {
                plane_descriptor = &display_config->display_config.plane_descriptors[i];
+               mcaches_per_plane = 0;
+
+               if (plane_descriptor->surface.dcc.enable) {
+                       mcaches_per_plane += display_config->stage2.mcache_allocations[i].num_mcaches_plane0 +
+                                       display_config->stage2.mcache_allocations[i].num_mcaches_plane1 -
+                                       (display_config->stage2.mcache_allocations[i].last_slice_sharing.plane0_plane1 ? 1 : 0);
+               }
 
                if (is_bit_set_in_bitfield(mask, (unsigned char)plane_descriptor->stream_index)) {
                        num_planes_per_stream[plane_descriptor->stream_index]++;
@@ -1098,7 +1107,19 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo,
                                        plane_descriptor->composition.rotation_angle != dml2_rotation_0) {
                                return false;
                        }
+
+                       /* phantom requires same number of mcaches as main */
+                       if (plane_descriptor->surface.dcc.enable) {
+                               mcaches_per_plane *= 2;
+                       }
                }
+
+               total_mcaches_required += mcaches_per_plane;
+       }
+
+       if (total_mcaches_required > pmo->soc_bb->num_dcc_mcaches) {
+               /* too many mcaches required */
+               return false;
        }
 
        for (i = 0; i < DML2_MAX_PLANES; i++) {
index a8f58f8448e4279055cfd63accf9c5647aa53f38..dc2ce5e77f5799303d8697b280ec442a711657bc 100644 (file)
@@ -831,7 +831,6 @@ static bool dml2_top_soc15_build_mode_programming(struct dml2_build_mode_program
        bool uclk_pstate_success = false;
        bool vmin_success = false;
        bool stutter_success = false;
-       unsigned int i;
 
        memset(l, 0, sizeof(struct dml2_build_mode_programming_locals));
        memset(in_out->programming, 0, sizeof(struct dml2_display_cfg_programming));
@@ -976,13 +975,6 @@ static bool dml2_top_soc15_build_mode_programming(struct dml2_build_mode_program
                l->base_display_config_with_meta.stage5.success = true;
        }
 
-       /*
-       * Populate mcache programming
-       */
-       for (i = 0; i < in_out->display_config->num_planes; i++) {
-               in_out->programming->plane_programming[i].mcache_allocation = l->base_display_config_with_meta.stage2.mcache_allocations[i];
-       }
-
        /*
        * Call DPMM to map all requirements to minimum clock state
        */