Commit 05d3dfd3 authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher

drm/amd/display: Wait before sending idle allow and after idle disallow

[Why]
We want acknowledgment of the driver idle disallow from DMCUB before
continuing with any further programming.

For idle allow we want to minimize the chance of DMCUB actively
interacing with other firmware components on the system (eg. PMFW)
at the same time.

[How]
Ensure that DMCUB isn't in the middle of processing other command
submissions prior to allowing idle and after disallowing idle by
inserting a wait before the allow and by changing the wait type for
the idle disallow.
Reviewed-by: default avatarCharlene Liu <charlene.liu@amd.com>
Acked-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6bd09606
...@@ -1195,6 +1195,9 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) ...@@ -1195,6 +1195,9 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
if (dc->debug.dmcub_emulation) if (dc->debug.dmcub_emulation)
return; return;
if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub)
return;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.idle_opt_notify_idle.header.type = DMUB_CMD__IDLE_OPT; cmd.idle_opt_notify_idle.header.type = DMUB_CMD__IDLE_OPT;
cmd.idle_opt_notify_idle.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE; cmd.idle_opt_notify_idle.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE;
...@@ -1205,13 +1208,15 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) ...@@ -1205,13 +1208,15 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
cmd.idle_opt_notify_idle.cntl_data.driver_idle = allow_idle; cmd.idle_opt_notify_idle.cntl_data.driver_idle = allow_idle;
if (allow_idle) { if (allow_idle) {
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
if (dc->hwss.set_idle_state) if (dc->hwss.set_idle_state)
dc->hwss.set_idle_state(dc, true); dc->hwss.set_idle_state(dc, true);
} }
/* NOTE: This does not use the "wake" interface since this is part of the wake path. */ /* NOTE: This does not use the "wake" interface since this is part of the wake path. */
/* We also do not perform a wait since DMCUB could enter idle after the notification. */ /* We also do not perform a wait since DMCUB could enter idle after the notification. */
dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT); dm_execute_dmub_cmd(dc->ctx, &cmd, allow_idle ? DM_DMUB_WAIT_TYPE_NO_WAIT : DM_DMUB_WAIT_TYPE_WAIT);
} }
static void dc_dmub_srv_exit_low_power_state(const struct dc *dc) static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment