drm/amd/display: Move mcache allocation programming from DML to resource
authorKarthi Kandasamy <karthi.kandasamy@amd.com>
Mon, 3 Mar 2025 22:15:10 +0000 (23:15 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 16 May 2025 17:38:36 +0000 (13:38 -0400)
[Why]
mcache allocation programming is not part of DML's core responsibilities.
Keeping this logic in DML leads to poor separation of concerns and complicates maintenance.

[How]
Refactored code to move mcache parameter preparation and mcache ID assignment
into the resource file.

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Karthi Kandasamy <karthi.kandasamy@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@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/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.h
drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
drivers/gpu/drm/amd/display/dc/inc/core_types.h
drivers/gpu/drm/amd/display/dc/inc/resource.h

index 15ef1f26864f951b4e48d7ee957f658c232e1863..3da25bd8b5788acf4ad20d56d20cfc2c9bf3405c 100644 (file)
@@ -5525,6 +5525,14 @@ struct dscl_prog_data *resource_get_dscl_prog_data(struct pipe_ctx *pipe_ctx)
        return &pipe_ctx->plane_res.scl_data.dscl_prog_data;
 }
 
+static bool resource_allocate_mcache(struct dc_state *context, const struct  dc_mcache_params *mcache_params)
+{
+       if (context->clk_mgr->ctx->dc->res_pool->funcs->program_mcache_pipe_config)
+               context->clk_mgr->ctx->dc->res_pool->funcs->program_mcache_pipe_config(context, mcache_params);
+
+       return true;
+}
+
 void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options)
 {
        dml2_options->callbacks.dc = dc;
@@ -5544,6 +5552,7 @@ void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuratio
        dml2_options->callbacks.get_stream_status = &dc_state_get_stream_status;
        dml2_options->callbacks.get_stream_from_id = &dc_state_get_stream_from_id;
        dml2_options->callbacks.get_max_flickerless_instant_vtotal_increase = &dc_stream_get_max_flickerless_instant_vtotal_increase;
+       dml2_options->callbacks.allocate_mcache = &resource_allocate_mcache;
 
        dml2_options->svp_pstate.callbacks.dc = dc;
        dml2_options->svp_pstate.callbacks.add_phantom_plane = &dc_state_add_phantom_plane;
index 199938311b322e311dd80220b8356e6e1e9b8bbe..d47cacfdb6955e8df3a4f6352fdc190c2ac0233b 100644 (file)
@@ -952,7 +952,7 @@ static unsigned int map_stream_to_dml21_display_cfg(const struct dml2_context *d
        return location;
 }
 
-static unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id,
+unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id,
                const struct dc_plane_state *plane, const struct dc_state *context)
 {
        unsigned int plane_id;
index 069b939c672a9bb6900e82059a02d2f475b9d81e..73a013be1e48c52578ed8fabca4d76a467ce9217 100644 (file)
@@ -11,6 +11,7 @@ struct dc_state;
 struct dcn_watermarks;
 union dcn_watermark_set;
 struct pipe_ctx;
+struct dc_plane_state;
 
 struct dml2_context;
 struct dml2_configuration_options;
@@ -25,4 +26,5 @@ void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_se
 void dml21_map_hw_resources(struct dml2_context *dml_ctx);
 void dml21_get_pipe_mcache_config(struct dc_state *context, struct pipe_ctx *pipe_ctx, struct dml2_per_plane_programming *pln_prog, struct dml2_pipe_configuration_descriptor *mcache_pipe_config);
 void dml21_set_dc_p_state_type(struct pipe_ctx *pipe_ctx, struct dml2_per_stream_programming *stream_programming, bool sub_vp_enabled);
+unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id, const struct dc_plane_state *plane, const struct dc_state *context);
 #endif
index ed6584535e898ed1377d46d308a348f093128e7d..208d3651b6bafbbf9460ed0a30cc6cf19237d2c9 100644 (file)
@@ -12,6 +12,8 @@
 #include "dml21_translation_helper.h"
 #include "dml2_dc_resource_mgmt.h"
 
+#define INVALID -1
+
 static bool dml21_allocate_memory(struct dml2_context **dml_ctx)
 {
        *dml_ctx = vzalloc(sizeof(struct dml2_context));
@@ -208,10 +210,40 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta
        }
 }
 
+static void dml21_prepare_mcache_params(struct dml2_context *dml_ctx, struct dc_state *context, struct dc_mcache_params *mcache_params)
+{
+       int dc_plane_idx = 0;
+       int dml_prog_idx, stream_idx, plane_idx;
+       struct dml2_per_plane_programming *pln_prog = NULL;
+
+       for (stream_idx = 0; stream_idx < context->stream_count; stream_idx++) {
+               for (plane_idx = 0; plane_idx < context->stream_status[stream_idx].plane_count; plane_idx++) {
+                       dml_prog_idx = map_plane_to_dml21_display_cfg(dml_ctx, context->streams[stream_idx]->stream_id, context->stream_status[stream_idx].plane_states[plane_idx], context);
+                       if (dml_prog_idx == INVALID) {
+                               continue;
+                       }
+                       pln_prog = &dml_ctx->v21.mode_programming.programming->plane_programming[dml_prog_idx];
+                       mcache_params[dc_plane_idx].valid = pln_prog->mcache_allocation.valid;
+                       mcache_params[dc_plane_idx].num_mcaches_plane0 = pln_prog->mcache_allocation.num_mcaches_plane0;
+                       mcache_params[dc_plane_idx].num_mcaches_plane1 = pln_prog->mcache_allocation.num_mcaches_plane1;
+                       mcache_params[dc_plane_idx].requires_dedicated_mall_mcache = pln_prog->mcache_allocation.requires_dedicated_mall_mcache;
+                       mcache_params[dc_plane_idx].last_slice_sharing.plane0_plane1 = pln_prog->mcache_allocation.last_slice_sharing.plane0_plane1;
+                       memcpy(mcache_params[dc_plane_idx].mcache_x_offsets_plane0,
+                               pln_prog->mcache_allocation.mcache_x_offsets_plane0,
+                               sizeof(int) * (DML2_MAX_MCACHES + 1));
+                       memcpy(mcache_params[dc_plane_idx].mcache_x_offsets_plane1,
+                               pln_prog->mcache_allocation.mcache_x_offsets_plane1,
+                               sizeof(int) * (DML2_MAX_MCACHES + 1));
+                       dc_plane_idx++;
+               }
+       }
+}
+
 static bool dml21_mode_check_and_programming(const struct dc *in_dc, struct dc_state *context, struct dml2_context *dml_ctx)
 {
        bool result = false;
        struct dml2_build_mode_programming_in_out *mode_programming = &dml_ctx->v21.mode_programming;
+       struct dc_mcache_params mcache_params[MAX_PLANES] = {0};
 
        memset(&dml_ctx->v21.display_config, 0, sizeof(struct dml2_display_cfg));
        memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
@@ -246,6 +278,14 @@ static bool dml21_mode_check_and_programming(const struct dc *in_dc, struct dc_s
                dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, in_dc->current_state);
                /* if subvp phantoms are present, expand them into dc context */
                dml21_handle_phantom_streams_planes(in_dc, context, dml_ctx);
+
+               if (in_dc->res_pool->funcs->program_mcache_pipe_config) {
+                       //Prepare mcache params for each plane based on mcache output from DML
+                       dml21_prepare_mcache_params(dml_ctx, context, mcache_params);
+
+                       //populate mcache regs to each pipe
+                       dml_ctx->config.callbacks.allocate_mcache(context, mcache_params);
+               }
        }
 
        /* Copy DML CLK, WM and REG outputs to bandwidth context */
index b2075b8c363b5cd4e72baf522c9b3a1811c20938..42e715024bc91842f29d53b92ec042ed163ee22b 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "os_types.h"
 #include "dml_top_soc_parameter_types.h"
+#include "dml_top_display_cfg_types.h"
 
 struct dc;
 struct dc_state;
@@ -65,4 +66,67 @@ struct socbb_ip_params_external {
        struct dml2_ip_capabilities ip_params;
        struct dml2_soc_bb soc_bb;
 };
+
+/*mcache parameters decided by dml*/
+struct dc_mcache_params {
+       bool valid;
+       /*
+       * For iMALL, dedicated mall mcaches are required (sharing of last
+       * slice possible), for legacy phantom or phantom without return
+       * the only mall mcaches need to be valid.
+       */
+       bool requires_dedicated_mall_mcache;
+       unsigned int num_mcaches_plane0;
+       unsigned int num_mcaches_plane1;
+       /*
+       * Generally, plane0/1 slices must use a disjoint set of caches
+       * but in some cases the final segement of the two planes can
+       * use the same cache. If plane0_plane1 is set, then this is
+       * allowed.
+       *
+       * Similarly, the caches allocated to MALL prefetcher are generally
+       * disjoint, but if mall_prefetch is set, then the final segment
+       * between the main and the mall pixel requestor can use the same
+       * cache.
+       *
+       * Note that both bits may be set at the same time.
+       */
+       struct {
+               bool mall_comb_mcache_p0;
+               bool mall_comb_mcache_p1;
+               bool plane0_plane1;
+       } last_slice_sharing;
+       /*
+       * A plane is divided into vertical slices of mcaches,
+       * which wrap on the surface width.
+       *
+       * For example, if the surface width is 7680, and split into
+       * three slices of equal width, the boundary array would contain
+       * [2560, 5120, 7680]
+       *
+       * The assignments are
+       * 0 = [0 .. 2559]
+       * 1 = [2560 .. 5119]
+       * 2 = [5120 .. 7679]
+       * 0 = [7680 .. INF]
+       * The final element implicitly is the same as the first, and
+       * at first seems invalid since it is never referenced (since)
+       * it is outside the surface. However, its useful when shifting
+       * (see below).
+       *
+       * For any given valid mcache assignment, a shifted version, wrapped
+       * on the surface width boundary is also assumed to be valid.
+       *
+       * For example, shifting [2560, 5120, 7680] by -50 results in
+       * [2510, 5170, 7630].
+       *
+       * The assignments are now:
+       * 0 = [0 .. 2509]
+       * 1 = [2510 .. 5169]
+       * 2 = [5170 .. 7629]
+       * 0 = [7630 .. INF]
+       */
+       int mcache_x_offsets_plane0[DML2_MAX_MCACHES + 1];
+       int mcache_x_offsets_plane1[DML2_MAX_MCACHES + 1];
+};
 #endif
index 785226945699dd57953ba381bfec0cd892fb54ea..5100f269368e794b7c5b2f6c79e87eb0ea10f6a6 100644 (file)
@@ -40,6 +40,7 @@ struct dc_sink;
 struct dc_stream_state;
 struct resource_context;
 struct display_stream_compressor;
+struct dc_mcache_params;
 
 // Configuration of the MALL on the SoC
 struct dml2_soc_mall_info {
@@ -107,6 +108,7 @@ struct dml2_dc_callbacks {
        unsigned int (*get_max_flickerless_instant_vtotal_increase)(
                        struct dc_stream_state *stream,
                        bool is_gaming);
+       bool (*allocate_mcache)(struct dc_state *context, const struct dc_mcache_params *mcache_params);
 };
 
 struct dml2_dc_svp_callbacks {
index faa1b4e619de6568fdbdc89ce85bea20dbdaa5d0..0cf349cafb3e56b70315dc048daf5902cf585d60 100644 (file)
@@ -65,6 +65,7 @@ struct resource_pool;
 struct dc_state;
 struct resource_context;
 struct clk_bw_params;
+struct dc_mcache_params;
 
 struct resource_funcs {
        enum engine_id (*get_preferred_eng_id_dpia)(unsigned int dpia_index);
@@ -220,6 +221,8 @@ struct resource_funcs {
        unsigned int (*get_max_hw_cursor_size)(const struct dc *dc,
                        struct dc_state *state,
                        const struct dc_stream_state *stream);
+       bool (*program_mcache_pipe_config)(struct dc_state *context,
+               const struct dc_mcache_params *mcache_params);
 };
 
 struct audio_support{
index 7a87a7c07c1bac6ffa6d5bb4425928a68bc1848a..a890f581f4e897ddc94ad56a537d3ac6d4269a2e 100644 (file)
@@ -32,6 +32,7 @@
 
 #define MEMORY_TYPE_MULTIPLIER_CZ 4
 #define MEMORY_TYPE_HBM 2
+#define MAX_MCACHES 8
 
 
 #define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0)
@@ -65,6 +66,13 @@ struct resource_straps {
        uint32_t audio_stream_number;
 };
 
+struct dc_mcache_allocations {
+       int global_mcache_ids_plane0[MAX_MCACHES + 1];
+       int global_mcache_ids_plane1[MAX_MCACHES + 1];
+       int global_mcache_ids_mall_plane0[MAX_MCACHES + 1];
+       int global_mcache_ids_mall_plane1[MAX_MCACHES + 1];
+};
+
 struct resource_create_funcs {
        void (*read_dce_straps)(
                        struct dc_context *ctx, struct resource_straps *straps);