summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
diff options
context:
space:
mode:
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2024-06-21 16:11:28 -0400
committerAlex Deucher <alexander.deucher@amd.com>2024-08-27 17:53:51 -0400
commit9793a4a6e5eb8764c7410c361984ed01722bab9f (patch)
tree9fceadd214233770ae99f111d35c0cbfa9f3088a /drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
parent4437936c6b696b98f3fe1d8679a2788c41b4df77 (diff)
downloadlinux-stable-9793a4a6e5eb8764c7410c361984ed01722bab9f.tar.gz
linux-stable-9793a4a6e5eb8764c7410c361984ed01722bab9f.tar.bz2
linux-stable-9793a4a6e5eb8764c7410c361984ed01722bab9f.zip
drm/amd/display: Notify DMCUB of D0/D3 state
[Why] We want to avoid arming the HPD timer in firmware when preparing for S0i3 entry when DC is considered in D3. [How] Notify DMCUB of the power state transitions so it can decide to arm the HPD timer for idle in DCN35 only in D0. Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Ovidiu Bunea <Ovidiu.Bunea@amd.com> Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c30
1 files changed, 28 insertions, 2 deletions
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 b1265124608b..1e7de0f03290 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1476,7 +1476,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
ips2_exit_count);
}
-void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState)
+void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state power_state)
{
struct dmub_srv *dmub;
@@ -1485,12 +1485,38 @@ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_c
dmub = dc_dmub_srv->dmub;
- if (powerState == DC_ACPI_CM_POWER_STATE_D0)
+ if (power_state == DC_ACPI_CM_POWER_STATE_D0)
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D0);
else
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3);
}
+void dc_dmub_srv_notify_fw_dc_power_state(struct dc_dmub_srv *dc_dmub_srv,
+ enum dc_acpi_cm_power_state power_state)
+{
+ union dmub_rb_cmd cmd;
+
+ if (!dc_dmub_srv)
+ return;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.idle_opt_set_dc_power_state.header.type = DMUB_CMD__IDLE_OPT;
+ cmd.idle_opt_set_dc_power_state.header.sub_type = DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE;
+ cmd.idle_opt_set_dc_power_state.header.payload_bytes =
+ sizeof(cmd.idle_opt_set_dc_power_state) - sizeof(cmd.idle_opt_set_dc_power_state.header);
+
+ if (power_state == DC_ACPI_CM_POWER_STATE_D0) {
+ cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_D0;
+ } else if (power_state == DC_ACPI_CM_POWER_STATE_D3) {
+ cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_D3;
+ } else {
+ cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_UNKNOWN;
+ }
+
+ dc_wake_and_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
bool dc_dmub_srv_should_detect(struct dc_dmub_srv *dc_dmub_srv)
{
volatile const struct dmub_shared_state_ips_fw *ips_fw;