Skip to content

Commit

Permalink
drm/amd/display: Revert "Support for reg inbox0 for host->DMUB CMDs"
Browse files Browse the repository at this point in the history
This reverts commit 15d1c2e.

Reason: Cursor movement causes system to hang.

Reviewed-by: Aric Cyr <aric.cyr@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>
  • Loading branch information
Dillon Varone authored and Alex Deucher committed Mar 18, 2025
1 parent 52af17e commit b3d5826
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 496 deletions.
185 changes: 85 additions & 100 deletions drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,20 @@ void dc_dmub_srv_destroy(struct dc_dmub_srv **dmub_srv)
}
}

bool dc_dmub_srv_wait_for_pending(struct dc_dmub_srv *dc_dmub_srv)
void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv)
{
struct dmub_srv *dmub;
struct dc_context *dc_ctx;
struct dmub_srv *dmub = dc_dmub_srv->dmub;
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
enum dmub_status status;

if (!dc_dmub_srv || !dc_dmub_srv->dmub)
return false;

dc_ctx = dc_dmub_srv->ctx;
dmub = dc_dmub_srv->dmub;

do {
status = dmub_srv_wait_for_pending(dmub, 100000);
status = dmub_srv_wait_for_idle(dmub, 100000);
} while (dc_dmub_srv->ctx->dc->debug.disable_timeout && status != DMUB_STATUS_OK);

if (status != DMUB_STATUS_OK) {
DC_ERROR("Error waiting for DMUB idle: status=%d\n", status);
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
}

return status == DMUB_STATUS_OK;
}

void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dc_dmub_srv)
Expand Down Expand Up @@ -134,49 +126,7 @@ void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dc_dmub_srv,
}
}

static bool dc_dmub_srv_reg_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
unsigned int count,
union dmub_rb_cmd *cmd_list)
{
struct dc_context *dc_ctx;
struct dmub_srv *dmub;
enum dmub_status status = DMUB_STATUS_OK;
int i;

if (!dc_dmub_srv || !dc_dmub_srv->dmub)
return false;

dc_ctx = dc_dmub_srv->ctx;
dmub = dc_dmub_srv->dmub;

for (i = 0 ; i < count; i++) {
/* confirm no messages pending */
do {
status = dmub_srv_wait_for_idle(dmub, 100000);
} while (dc_dmub_srv->ctx->dc->debug.disable_timeout && status != DMUB_STATUS_OK);

/* queue command */
if (status == DMUB_STATUS_OK)
status = dmub_srv_reg_cmd_execute(dmub, &cmd_list[i]);

/* check for errors */
if (status != DMUB_STATUS_OK) {
break;
}
}

if (status != DMUB_STATUS_OK) {
if (status != DMUB_STATUS_POWER_STATE_D3) {
DC_ERROR("Error starting DMUB execution: status=%d\n", status);
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
}
return false;
}

return true;
}

static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
unsigned int count,
union dmub_rb_cmd *cmd_list)
{
Expand All @@ -193,16 +143,11 @@ static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_sr

for (i = 0 ; i < count; i++) {
// Queue command
if (!cmd_list[i].cmd_common.header.multi_cmd_pending ||
dmub_rb_num_free(&dmub->inbox1.rb) >= count - i) {
status = dmub_srv_fb_cmd_queue(dmub, &cmd_list[i]);
} else {
status = DMUB_STATUS_QUEUE_FULL;
}
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);

if (status == DMUB_STATUS_QUEUE_FULL) {
/* Execute and wait for queue to become empty again. */
status = dmub_srv_fb_cmd_execute(dmub);
status = dmub_srv_cmd_execute(dmub);
if (status == DMUB_STATUS_POWER_STATE_D3)
return false;

Expand All @@ -211,7 +156,7 @@ static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_sr
} while (dc_dmub_srv->ctx->dc->debug.disable_timeout && status != DMUB_STATUS_OK);

/* Requeue the command. */
status = dmub_srv_fb_cmd_queue(dmub, &cmd_list[i]);
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
}

if (status != DMUB_STATUS_OK) {
Expand All @@ -223,7 +168,7 @@ static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_sr
}
}

status = dmub_srv_fb_cmd_execute(dmub);
status = dmub_srv_cmd_execute(dmub);
if (status != DMUB_STATUS_OK) {
if (status != DMUB_STATUS_POWER_STATE_D3) {
DC_ERROR("Error starting DMUB execution: status=%d\n", status);
Expand All @@ -235,23 +180,6 @@ static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_sr
return true;
}

bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
unsigned int count,
union dmub_rb_cmd *cmd_list)
{
bool res = false;

if (dc_dmub_srv && dc_dmub_srv->dmub) {
if (dc_dmub_srv->dmub->inbox_type == DMUB_CMD_INTERFACE_REG) {
res = dc_dmub_srv_reg_cmd_list_queue_execute(dc_dmub_srv, count, cmd_list);
} else {
res = dc_dmub_srv_fb_cmd_list_queue_execute(dc_dmub_srv, count, cmd_list);
}
}

return res;
}

bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv,
enum dm_dmub_wait_type wait_type,
union dmub_rb_cmd *cmd_list)
Expand All @@ -274,18 +202,16 @@ bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv,
DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status);
if (!dmub->debug.timeout_info.timeout_occured) {
dmub->debug.timeout_info.timeout_occured = true;
if (cmd_list)
dmub->debug.timeout_info.timeout_cmd = *cmd_list;
dmub->debug.timeout_info.timeout_cmd = *cmd_list;
dmub->debug.timeout_info.timestamp = dm_get_timestamp(dc_dmub_srv->ctx);
}
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
return false;
}

// Copy data back from ring buffer into command
if (wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY && cmd_list) {
dmub_srv_cmd_get_response(dc_dmub_srv->dmub, cmd_list);
}
if (wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
dmub_rb_get_return_data(&dmub->inbox1_rb, cmd_list);
}

return true;
Expand All @@ -298,10 +224,74 @@ bool dc_dmub_srv_cmd_run(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd

bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int count, union dmub_rb_cmd *cmd_list, enum dm_dmub_wait_type wait_type)
{
if (!dc_dmub_srv_cmd_list_queue_execute(dc_dmub_srv, count, cmd_list))
struct dc_context *dc_ctx;
struct dmub_srv *dmub;
enum dmub_status status;
int i;

if (!dc_dmub_srv || !dc_dmub_srv->dmub)
return false;

dc_ctx = dc_dmub_srv->ctx;
dmub = dc_dmub_srv->dmub;

for (i = 0 ; i < count; i++) {
// Queue command
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);

if (status == DMUB_STATUS_QUEUE_FULL) {
/* Execute and wait for queue to become empty again. */
status = dmub_srv_cmd_execute(dmub);
if (status == DMUB_STATUS_POWER_STATE_D3)
return false;

status = dmub_srv_wait_for_idle(dmub, 100000);
if (status != DMUB_STATUS_OK)
return false;

/* Requeue the command. */
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
}

if (status != DMUB_STATUS_OK) {
if (status != DMUB_STATUS_POWER_STATE_D3) {
DC_ERROR("Error queueing DMUB command: status=%d\n", status);
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
}
return false;
}
}

status = dmub_srv_cmd_execute(dmub);
if (status != DMUB_STATUS_OK) {
if (status != DMUB_STATUS_POWER_STATE_D3) {
DC_ERROR("Error starting DMUB execution: status=%d\n", status);
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
}
return false;
}

// Wait for DMUB to process command
if (wait_type != DM_DMUB_WAIT_TYPE_NO_WAIT) {
if (dc_dmub_srv->ctx->dc->debug.disable_timeout) {
do {
status = dmub_srv_wait_for_idle(dmub, 100000);
} while (status != DMUB_STATUS_OK);
} else
status = dmub_srv_wait_for_idle(dmub, 100000);

return dc_dmub_srv_wait_for_idle(dc_dmub_srv, wait_type, cmd_list);
if (status != DMUB_STATUS_OK) {
DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status);
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
return false;
}

// Copy data back from ring buffer into command
if (wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
dmub_rb_get_return_data(&dmub->inbox1_rb, cmd_list);
}

return true;
}

bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv)
Expand Down Expand Up @@ -1253,7 +1243,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);

dc_dmub_srv_wait_for_idle(dc->ctx->dmub_srv, DM_DMUB_WAIT_TYPE_WAIT, NULL);
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);

memset(&new_signals, 0, sizeof(new_signals));

Expand Down Expand Up @@ -1410,7 +1400,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);

dmub_srv_sync_inboxes(dc->ctx->dmub_srv->dmub);
dmub_srv_sync_inbox1(dc->ctx->dmub_srv->dmub);
}
}

Expand Down Expand Up @@ -1664,8 +1654,7 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
/* fill in generic command header */
global_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
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);
global_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);

if (enable) {
/* send global configuration parameters */
Expand All @@ -1684,13 +1673,11 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
/* configure command header */
stream_base_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
stream_base_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
stream_base_cmd->header.payload_bytes =
sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
stream_base_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
stream_base_cmd->header.multi_cmd_pending = 1;
stream_sub_state_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
stream_sub_state_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
stream_sub_state_cmd->header.payload_bytes =
sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
stream_sub_state_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
stream_sub_state_cmd->header.multi_cmd_pending = 1;
/* copy stream static base state */
memcpy(&stream_base_cmd->config,
Expand Down Expand Up @@ -1736,8 +1723,7 @@ void dc_dmub_srv_fams2_drr_update(struct dc *dc,
cmd.fams2_drr_update.dmub_optc_state_req.v_total_mid_frame_num = vtotal_mid_frame_num;
cmd.fams2_drr_update.dmub_optc_state_req.program_manual_trigger = program_manual_trigger;

cmd.fams2_drr_update.header.payload_bytes =
sizeof(cmd.fams2_drr_update) - sizeof(cmd.fams2_drr_update.header);
cmd.fams2_drr_update.header.payload_bytes = sizeof(cmd.fams2_drr_update) - sizeof(cmd.fams2_drr_update.header);

dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
Expand Down Expand Up @@ -1773,8 +1759,7 @@ void dc_dmub_srv_fams2_passthrough_flip(
/* build command header */
cmds[num_cmds].fams2_flip.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
cmds[num_cmds].fams2_flip.header.sub_type = DMUB_CMD__FAMS2_FLIP;
cmds[num_cmds].fams2_flip.header.payload_bytes =
sizeof(struct dmub_rb_cmd_fams2_flip) - sizeof(struct dmub_cmd_header);
cmds[num_cmds].fams2_flip.header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2_flip);

/* for chaining multiple commands, all but last command should set to 1 */
cmds[num_cmds].fams2_flip.header.multi_cmd_pending = 1;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct dc_dmub_srv {
bool needs_idle_wake;
};

bool dc_dmub_srv_wait_for_pending(struct dc_dmub_srv *dc_dmub_srv);
void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv);

bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/display/dc/dc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ void reg_sequence_wait_done(const struct dc_context *ctx)
if (offload &&
ctx->dc->debug.dmub_offload_enabled &&
!ctx->dc->debug.dmcub_emulation) {
dc_dmub_srv_wait_for_idle(ctx->dmub_srv, DM_DMUB_WAIT_TYPE_WAIT, NULL);
dc_dmub_srv_wait_idle(ctx->dmub_srv);
}
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,7 @@ bool dmub_abm_save_restore(
cmd.abm_save_restore.abm_init_config_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
cmd.abm_save_restore.abm_init_config_data.panel_mask = panel_mask;

cmd.abm_save_restore.header.payload_bytes =
sizeof(struct dmub_rb_cmd_abm_save_restore) - sizeof(struct dmub_cmd_header);
cmd.abm_save_restore.header.payload_bytes = sizeof(struct dmub_rb_cmd_abm_save_restore);

dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);

Expand Down
19 changes: 6 additions & 13 deletions drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,7 @@ static void dmub_replay_set_power_opt_and_coasting_vtotal(struct dmub_replay *dm
memset(&cmd, 0, sizeof(cmd));
pCmd->header.type = DMUB_CMD__REPLAY;
pCmd->header.sub_type = DMUB_CMD__REPLAY_SET_POWER_OPT_AND_COASTING_VTOTAL;
pCmd->header.payload_bytes =
sizeof(struct dmub_rb_cmd_replay_set_power_opt_and_coasting_vtotal) -
sizeof(struct dmub_cmd_header);
pCmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_replay_set_power_opt_and_coasting_vtotal);
pCmd->replay_set_power_opt_data.power_opt = power_opt;
pCmd->replay_set_power_opt_data.panel_inst = panel_inst;
pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF);
Expand Down Expand Up @@ -321,8 +319,7 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub,
cmd.replay_set_timing_sync.header.sub_type =
DMUB_CMD__REPLAY_SET_TIMING_SYNC_SUPPORTED;
cmd.replay_set_timing_sync.header.payload_bytes =
sizeof(struct dmub_rb_cmd_replay_set_timing_sync) -
sizeof(struct dmub_cmd_header);
sizeof(struct dmub_rb_cmd_replay_set_timing_sync);
//Cmd Body
cmd.replay_set_timing_sync.replay_set_timing_sync_data.panel_inst =
cmd_element->sync_data.panel_inst;
Expand All @@ -334,8 +331,7 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub,
cmd.replay_set_frameupdate_timer.header.sub_type =
DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER;
cmd.replay_set_frameupdate_timer.header.payload_bytes =
sizeof(struct dmub_rb_cmd_replay_set_frameupdate_timer) -
sizeof(struct dmub_cmd_header);
sizeof(struct dmub_rb_cmd_replay_set_frameupdate_timer);
//Cmd Body
cmd.replay_set_frameupdate_timer.data.panel_inst =
cmd_element->panel_inst;
Expand All @@ -349,8 +345,7 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub,
cmd.replay_set_pseudo_vtotal.header.sub_type =
DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL;
cmd.replay_set_pseudo_vtotal.header.payload_bytes =
sizeof(struct dmub_rb_cmd_replay_set_pseudo_vtotal) -
sizeof(struct dmub_cmd_header);
sizeof(struct dmub_rb_cmd_replay_set_pseudo_vtotal);
//Cmd Body
cmd.replay_set_pseudo_vtotal.data.panel_inst =
cmd_element->pseudo_vtotal_data.panel_inst;
Expand All @@ -362,8 +357,7 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub,
cmd.replay_disabled_adaptive_sync_sdp.header.sub_type =
DMUB_CMD__REPLAY_DISABLED_ADAPTIVE_SYNC_SDP;
cmd.replay_disabled_adaptive_sync_sdp.header.payload_bytes =
sizeof(struct dmub_rb_cmd_replay_disabled_adaptive_sync_sdp) -
sizeof(struct dmub_cmd_header);
sizeof(struct dmub_rb_cmd_replay_disabled_adaptive_sync_sdp);
//Cmd Body
cmd.replay_disabled_adaptive_sync_sdp.data.panel_inst =
cmd_element->disabled_adaptive_sync_sdp_data.panel_inst;
Expand All @@ -375,8 +369,7 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub,
cmd.replay_set_general_cmd.header.sub_type =
DMUB_CMD__REPLAY_SET_GENERAL_CMD;
cmd.replay_set_general_cmd.header.payload_bytes =
sizeof(struct dmub_rb_cmd_replay_set_general_cmd) -
sizeof(struct dmub_cmd_header);
sizeof(struct dmub_rb_cmd_replay_set_general_cmd);
//Cmd Body
cmd.replay_set_general_cmd.data.panel_inst =
cmd_element->set_general_cmd_data.panel_inst;
Expand Down
Loading

0 comments on commit b3d5826

Please sign in to comment.