Skip to content

Commit

Permalink
drm/amd/display: Export additional FAMS2 global configuration options…
Browse files Browse the repository at this point in the history
… from DML

[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.leung@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Dillon Varone <dillon.varone@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Dillon Varone authored and Alex Deucher committed Jul 23, 2024
1 parent b8d3782 commit 08cbe68
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 95 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/display/dc/core/dc_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
34 changes: 16 additions & 18 deletions drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand Down
143 changes: 76 additions & 67 deletions drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/display/dc/inc/core_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down

0 comments on commit 08cbe68

Please sign in to comment.