From: Dillon Varone <dillon.var...@amd.com>

[WHY&HOW]
Some global configuration options were previously hardcoded in DC, now they are
exported by DML and sent to FW.

Reviewed-by: Martin Leung <martin.le...@amd.com>
Signed-off-by: Jerry Zuo <jerry....@amd.com>
Signed-off-by: Dillon Varone <dillon.var...@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_state.c    |   4 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |  34 ++---
 .../amd/display/dc/dml2/dml21/dml21_utils.c   | 143 ++++++++++--------
 .../dml2/dml21/src/dml2_core/dml2_core_dcn4.c |   1 +
 .../src/dml2_core/dml2_core_dcn4_calcs.c      |  17 ++-
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c |   4 +-
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   2 +-
 7 files changed, 110 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
index 665157f8d4cb..2597e3fd562b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -967,10 +967,10 @@ bool dc_state_is_fams2_in_use(
        bool is_fams2_in_use = false;
 
        if (state)
-               is_fams2_in_use |= state->bw_ctx.bw.dcn.fams2_stream_count > 0;
+               is_fams2_in_use |= 
state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
 
        if (dc->current_state)
-               is_fams2_in_use |= 
dc->current_state->bw_ctx.bw.dcn.fams2_stream_count > 0;
+               is_fams2_in_use |= 
dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
 
        return is_fams2_in_use;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index ded13026c8ff..fb3391854eed 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1672,22 +1672,17 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
        global_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
        global_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - 
sizeof(struct dmub_cmd_header);
 
-       /* send global configuration parameters */
-       global_cmd->config.global.max_allow_delay_us = 100 * 1000; //100ms
-       global_cmd->config.global.lock_wait_time_us = 5000; //5ms
-       global_cmd->config.global.recovery_timeout_us = 5000; //5ms
-       global_cmd->config.global.hwfq_flip_programming_delay_us = 100; //100us
-
-       /* copy static feature configuration */
-       global_cmd->config.global.features.all = dc->debug.fams2_config.all;
+       if (enable) {
+               /* send global configuration parameters */
+               memcpy(&global_cmd->config.global, 
&context->bw_ctx.bw.dcn.fams2_global_config, sizeof(struct 
dmub_cmd_fams2_global_config));
 
-       /* apply feature configuration based on current driver state */
-       global_cmd->config.global.features.bits.enable_visual_confirm = 
dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS2;
-       global_cmd->config.global.features.bits.enable = enable;
+               /* copy static feature configuration overrides */
+               global_cmd->config.global.features.bits.enable_stall_recovery = 
dc->debug.fams2_config.bits.enable_stall_recovery;
+               global_cmd->config.global.features.bits.enable_debug = 
dc->debug.fams2_config.bits.enable_debug;
+               global_cmd->config.global.features.bits.enable_offload_flip = 
dc->debug.fams2_config.bits.enable_offload_flip;
 
-       /* construct per-stream configs */
-       if (enable) {
-               for (i = 0; i < context->bw_ctx.bw.dcn.fams2_stream_count; i++) 
{
+               /* construct per-stream configs */
+               for (i = 0; i < 
context->bw_ctx.bw.dcn.fams2_global_config.num_streams; i++) {
                        struct dmub_rb_cmd_fams2 *stream_cmd = 
&cmd[i+1].fams2_config;
 
                        /* configure command header */
@@ -1702,12 +1697,15 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
                }
        }
 
-       if (enable && context->bw_ctx.bw.dcn.fams2_stream_count) {
+       /* apply feature configuration based on current driver state */
+       global_cmd->config.global.features.bits.enable_visual_confirm = 
dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS2;
+       global_cmd->config.global.features.bits.enable = enable;
+
+       if (enable && 
context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) {
                /* set multi pending for global, and unset for last stream cmd 
*/
-               global_cmd->config.global.num_streams = 
context->bw_ctx.bw.dcn.fams2_stream_count;
                global_cmd->header.multi_cmd_pending = 1;
-               
cmd[context->bw_ctx.bw.dcn.fams2_stream_count].fams2_config.header.multi_cmd_pending
 = 0;
-               num_cmds += context->bw_ctx.bw.dcn.fams2_stream_count;
+               
cmd[context->bw_ctx.bw.dcn.fams2_global_config.num_streams].fams2_config.header.multi_cmd_pending
 = 0;
+               num_cmds += 
context->bw_ctx.bw.dcn.fams2_global_config.num_streams;
        }
 
        dm_execute_dmub_cmd_list(dc->ctx, num_cmds, cmd, 
DM_DMUB_WAIT_TYPE_WAIT);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
index 622c98f4b7fb..e11246e525ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
@@ -461,94 +461,103 @@ void dml21_build_fams2_programming(const struct dc *dc,
                struct dml2_context *dml_ctx)
 {
        int i, j, k;
+       unsigned int num_fams2_streams = 0;
 
        /* reset fams2 data */
-       context->bw_ctx.bw.dcn.fams2_stream_count = 0;
        memset(&context->bw_ctx.bw.dcn.fams2_stream_params, 0, sizeof(struct 
dmub_fams2_stream_static_state) * DML2_MAX_PLANES);
+       memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct 
dmub_cmd_fams2_global_config));
 
-       if (!dml_ctx->v21.mode_programming.programming->fams2_required)
-               return;
+       if (dml_ctx->v21.mode_programming.programming->fams2_required) {
+               for (i = 0; i < context->stream_count; i++) {
+                       int dml_stream_idx;
+                       struct dc_stream_state *phantom_stream;
+                       struct dc_stream_status *phantom_status;
 
-       for (i = 0; i < context->stream_count; i++) {
-               int dml_stream_idx;
-               struct dc_stream_state *phantom_stream;
-               struct dc_stream_status *phantom_status;
+                       struct dmub_fams2_stream_static_state *static_state = 
&context->bw_ctx.bw.dcn.fams2_stream_params[num_fams2_streams];
 
-               struct dmub_fams2_stream_static_state *static_state = 
&context->bw_ctx.bw.dcn.fams2_stream_params[context->bw_ctx.bw.dcn.fams2_stream_count];
+                       struct dc_stream_state *stream = context->streams[i];
 
-               struct dc_stream_state *stream = context->streams[i];
-
-               if (context->stream_status[i].plane_count == 0 ||
-                               
dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == 
SUBVP_PHANTOM) {
-                       /* can ignore blanked or phantom streams */
-                       continue;
-               }
-
-               dml_stream_idx = 
dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
-               if (dml_stream_idx < 0) {
-                       ASSERT(dml_stream_idx >= 0);
-                       continue;
-               }
-
-               /* copy static state from PMO */
-               memcpy(static_state,
-                               
&dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_params,
-                               sizeof(struct dmub_fams2_stream_static_state));
-
-               /* get information from context */
-               static_state->num_planes = 
context->stream_status[i].plane_count;
-               static_state->otg_inst = 
context->stream_status[i].primary_otg_inst;
-
-               /* populate pipe masks for planes */
-               for (j = 0; j < context->stream_status[i].plane_count; j++) {
-                       for (k = 0; k < dc->res_pool->pipe_count; k++) {
-                               if (context->res_ctx.pipe_ctx[k].stream &&
-                                               
context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&
-                                               
context->res_ctx.pipe_ctx[k].plane_state == 
context->stream_status[i].plane_states[j]) {
-                                       static_state->pipe_mask |= (1 << k);
-                                       static_state->plane_pipe_masks[j] |= (1 
<< k);
-                               }
+                       if (context->stream_status[i].plane_count == 0 ||
+                                       
dml_ctx->config.svp_pstate.callbacks.get_stream_subvp_type(context, stream) == 
SUBVP_PHANTOM) {
+                               /* can ignore blanked or phantom streams */
+                               continue;
                        }
-               }
 
-               /* get per method programming */
-               switch (static_state->type) {
-               case FAMS2_STREAM_TYPE_VBLANK:
-               case FAMS2_STREAM_TYPE_VACTIVE:
-               case FAMS2_STREAM_TYPE_DRR:
-                       break;
-               case FAMS2_STREAM_TYPE_SUBVP:
-                       phantom_stream = 
dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
-                       if (!phantom_stream)
-                               break;
+                       dml_stream_idx = 
dml21_helper_find_dml_pipe_idx_by_stream_id(dml_ctx, stream->stream_id);
+                       if (dml_stream_idx < 0) {
+                               ASSERT(dml_stream_idx >= 0);
+                               continue;
+                       }
 
-                       phantom_status = 
dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
+                       /* copy static state from PMO */
+                       memcpy(static_state,
+                                       
&dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_params,
+                                       sizeof(struct 
dmub_fams2_stream_static_state));
 
-                       /* phantom status should always be present */
-                       ASSERT(phantom_status);
-                       static_state->sub_state.subvp.phantom_otg_inst = 
phantom_status->primary_otg_inst;
+                       /* get information from context */
+                       static_state->num_planes = 
context->stream_status[i].plane_count;
+                       static_state->otg_inst = 
context->stream_status[i].primary_otg_inst;
 
-                       /* populate pipe masks for phantom planes */
-                       for (j = 0; j < phantom_status->plane_count; j++) {
+                       /* populate pipe masks for planes */
+                       for (j = 0; j < context->stream_status[i].plane_count; 
j++) {
                                for (k = 0; k < dc->res_pool->pipe_count; k++) {
                                        if (context->res_ctx.pipe_ctx[k].stream 
&&
-                                                       
context->res_ctx.pipe_ctx[k].stream->stream_id == phantom_stream->stream_id &&
-                                                       
context->res_ctx.pipe_ctx[k].plane_state == phantom_status->plane_states[j]) {
-                                               
static_state->sub_state.subvp.phantom_pipe_mask |= (1 << k);
-                                               
static_state->sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
+                                                       
context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&
+                                                       
context->res_ctx.pipe_ctx[k].plane_state == 
context->stream_status[i].plane_states[j]) {
+                                               static_state->pipe_mask |= (1 
<< k);
+                                               
static_state->plane_pipe_masks[j] |= (1 << k);
                                        }
                                }
                        }
-                       break;
-               default:
-                       ASSERT(false);
-                       break;
+
+                       /* get per method programming */
+                       switch (static_state->type) {
+                       case FAMS2_STREAM_TYPE_VBLANK:
+                       case FAMS2_STREAM_TYPE_VACTIVE:
+                       case FAMS2_STREAM_TYPE_DRR:
+                               break;
+                       case FAMS2_STREAM_TYPE_SUBVP:
+                               phantom_stream = 
dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
+                               if (!phantom_stream)
+                                       break;
+
+                               phantom_status = 
dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
+
+                               /* phantom status should always be present */
+                               ASSERT(phantom_status);
+                               static_state->sub_state.subvp.phantom_otg_inst 
= phantom_status->primary_otg_inst;
+
+                               /* populate pipe masks for phantom planes */
+                               for (j = 0; j < phantom_status->plane_count; 
j++) {
+                                       for (k = 0; k < 
dc->res_pool->pipe_count; k++) {
+                                               if 
(context->res_ctx.pipe_ctx[k].stream &&
+                                                               
context->res_ctx.pipe_ctx[k].stream->stream_id == phantom_stream->stream_id &&
+                                                               
context->res_ctx.pipe_ctx[k].plane_state == phantom_status->plane_states[j]) {
+                                                       
static_state->sub_state.subvp.phantom_pipe_mask |= (1 << k);
+                                                       
static_state->sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
+                                               }
+                                       }
+                               }
+                               break;
+                       default:
+                               ASSERT(false);
+                               break;
+                       }
+
+                       num_fams2_streams++;
                }
+       }
+
+       if (num_fams2_streams > 0) {
+               /* copy FAMS2 configuration */
+               memcpy(&context->bw_ctx.bw.dcn.fams2_global_config,
+                               
&dml_ctx->v21.mode_programming.programming->fams2_global_config,
+                               sizeof(struct dmub_cmd_fams2_global_config));
 
-               context->bw_ctx.bw.dcn.fams2_stream_count++;
+               context->bw_ctx.bw.dcn.fams2_global_config.num_streams = 
num_fams2_streams;
        }
 
-       context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = 
context->bw_ctx.bw.dcn.fams2_stream_count > 0;
+       context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = 
context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
 }
 
 bool dml21_is_plane1_enabled(enum dml2_source_format_class source_format)
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
index b7a6f7f4c342..8c803b12404b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
@@ -351,6 +351,7 @@ static void 
pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
                programming->fams2_required = 
display_cfg->stage3.fams2_required;
 
                
dml2_core_calcs_get_global_fams2_programming(&core->clean_me_up.mode_lib, 
display_cfg, &programming->fams2_global_config);
+               programming->fams2_global_config.features.bits.enable = 
display_cfg->stage3.fams2_required;
        }
 
        // Only loop over all the main streams (the implicit svp streams will 
be packed as part of the main stream)
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index 45e43a915fd6..3b1e5c548435 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -12221,12 +12221,19 @@ void 
dml2_core_calcs_get_global_fams2_programming(const struct dml2_core_interna
                const struct display_configuation_with_meta *display_cfg,
                struct dmub_cmd_fams2_global_config *fams2_global_config)
 {
-       fams2_global_config->max_allow_delay_us = 
mode_lib->ip_caps.fams2.max_allow_delay_us;
-       fams2_global_config->lock_wait_time_us = 
mode_lib->ip_caps.fams2.lock_timeout_us;
-       fams2_global_config->recovery_timeout_us = 
mode_lib->ip_caps.fams2.recovery_timeout_us;
-       fams2_global_config->hwfq_flip_programming_delay_us = 
mode_lib->ip_caps.fams2.flip_programming_delay_us;
+       fams2_global_config->features.bits.enable = 
display_cfg->stage3.fams2_required;
 
-       fams2_global_config->num_streams = 
display_cfg->display_config.num_streams;
+       if (fams2_global_config->features.bits.enable) {
+               fams2_global_config->features.bits.enable_stall_recovery = true;
+               fams2_global_config->features.bits.allow_delay_check_mode = 
FAMS2_ALLOW_DELAY_CHECK_FROM_START;
+
+               fams2_global_config->max_allow_delay_us = 
mode_lib->ip_caps.fams2.max_allow_delay_us;
+               fams2_global_config->lock_wait_time_us = 
mode_lib->ip_caps.fams2.lock_timeout_us;
+               fams2_global_config->recovery_timeout_us = 
mode_lib->ip_caps.fams2.recovery_timeout_us;
+               fams2_global_config->hwfq_flip_programming_delay_us = 
mode_lib->ip_caps.fams2.flip_programming_delay_us;
+
+               fams2_global_config->num_streams = 
display_cfg->display_config.num_streams;
+       }
 }
 
 void dml2_core_calcs_get_stream_fams2_programming(const struct 
dml2_core_internal_display_mode_lib *mode_lib,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index d0b4308dca96..f4c1547a368f 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1531,7 +1531,7 @@ void dcn401_fams2_update_config(struct dc *dc, struct 
dc_state *context, bool en
        if (!dc->ctx || !dc->ctx->dmub_srv || 
!dc->debug.fams2_config.bits.enable)
                return;
 
-       fams2_required = context->bw_ctx.bw.dcn.fams2_stream_count > 0;
+       fams2_required = 
context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
 
        dc_dmub_srv_fams2_update_config(dc, context, enable && fams2_required);
 }
@@ -1656,7 +1656,7 @@ void dcn401_hardware_release(struct dc *dc)
         */
        if (dc->current_state) {
                if ((!dc->clk_mgr->clks.p_state_change_support ||
-                               
dc->current_state->bw_ctx.bw.dcn.fams2_stream_count > 0) &&
+                               
dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) &&
                                
dc->res_pool->hubbub->funcs->force_pstate_change_control)
                        
dc->res_pool->hubbub->funcs->force_pstate_change_control(
                                        dc->res_pool->hubbub, true, true);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h 
b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 4c8e6436c7e1..bfb8b8502d20 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -534,8 +534,8 @@ struct dcn_bw_output {
        unsigned int legacy_svp_drr_stream_index;
        bool legacy_svp_drr_stream_index_valid;
        struct dml2_mcache_surface_allocation 
mcache_allocations[DML2_MAX_PLANES];
+       struct dmub_cmd_fams2_global_config fams2_global_config;
        struct dmub_fams2_stream_static_state 
fams2_stream_params[DML2_MAX_PLANES];
-       unsigned fams2_stream_count;
        struct dml2_display_arb_regs arb_regs;
 };
 
-- 
2.34.1

Reply via email to