Skip to content

Commit 0f65793

Browse files
Samson Tamalexdeucher
authored andcommitted
drm/amd/display: do not send commands to DMUB if DMUB is inactive from S3
[Why] On resume from S3, may get apply_idle_optimizations call while DMUB is inactive which will just time out. [How] Set and track power state in dmub_srv and check power state before sending commands to DMUB. Add interface in both dmub_srv and dc_dmub_srv Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Acked-by: Wayne Lin <wayne.lin@amd.com> Signed-off-by: Samson Tam <samson.tam@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 7046ca9 commit 0f65793

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,6 +2687,7 @@ static int dm_suspend(void *handle)
26872687
hpd_rx_irq_work_suspend(dm);
26882688

26892689
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
2690+
dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3);
26902691

26912692
return 0;
26922693
}
@@ -2882,6 +2883,7 @@ static int dm_resume(void *handle)
28822883
if (r)
28832884
DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
28842885

2886+
dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0);
28852887
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
28862888

28872889
dc_resume(dm->dc);
@@ -2932,6 +2934,7 @@ static int dm_resume(void *handle)
29322934
}
29332935

29342936
/* power on hardware */
2937+
dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0);
29352938
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
29362939

29372940
/* program HPD filter */

drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,3 +1268,17 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
12681268
ASSERT(0);
12691269
}
12701270

1271+
void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState)
1272+
{
1273+
struct dmub_srv *dmub;
1274+
1275+
if (!dc_dmub_srv)
1276+
return;
1277+
1278+
dmub = dc_dmub_srv->dmub;
1279+
1280+
if (powerState == DC_ACPI_CM_POWER_STATE_D0)
1281+
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D0);
1282+
else
1283+
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3);
1284+
}

drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,6 @@ void dc_dmub_srv_subvp_save_surf_addr(const struct dc_dmub_srv *dc_dmub_srv, con
102102
bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);
103103
void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle);
104104
void dc_dmub_srv_exit_low_power_state(const struct dc *dc);
105+
106+
void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState);
105107
#endif /* _DMUB_DC_SRV_H_ */

drivers/gpu/drm/amd/display/dmub/dmub_srv.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ enum dmub_memory_access_type {
150150
DMUB_MEMORY_ACCESS_DMA
151151
};
152152

153+
/* enum dmub_power_state type - to track DC power state in dmub_srv */
154+
enum dmub_srv_power_state_type {
155+
DMUB_POWER_STATE_UNDEFINED = 0,
156+
DMUB_POWER_STATE_D0 = 1,
157+
DMUB_POWER_STATE_D3 = 8
158+
};
159+
153160
/**
154161
* struct dmub_region - dmub hw memory region
155162
* @base: base address for region, must be 256 byte aligned
@@ -485,6 +492,8 @@ struct dmub_srv {
485492
/* Feature capabilities reported by fw */
486493
struct dmub_feature_caps feature_caps;
487494
struct dmub_visual_confirm_color visual_confirm_color;
495+
496+
enum dmub_srv_power_state_type power_state;
488497
};
489498

490499
/**
@@ -889,6 +898,18 @@ enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub);
889898
*/
890899
void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index);
891900

901+
/**
902+
* dmub_srv_set_power_state() - Track DC power state in dmub_srv
903+
* @dmub: The dmub service
904+
* @power_state: DC power state setting
905+
*
906+
* Store DC power state in dmub_srv. If dmub_srv is in D3, then don't send messages to DMUB
907+
*
908+
* Return:
909+
* void
910+
*/
911+
void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state);
912+
892913
#if defined(__cplusplus)
893914
}
894915
#endif

drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
713713
dmub->hw_funcs.reset_release(dmub);
714714

715715
dmub->hw_init = true;
716+
dmub->power_state = DMUB_POWER_STATE_D0;
716717

717718
return DMUB_STATUS_OK;
718719
}
@@ -766,6 +767,9 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
766767
if (!dmub->hw_init)
767768
return DMUB_STATUS_INVALID;
768769

770+
if (dmub->power_state != DMUB_POWER_STATE_D0)
771+
return DMUB_STATUS_INVALID;
772+
769773
if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity ||
770774
dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {
771775
return DMUB_STATUS_HW_FAILURE;
@@ -784,6 +788,9 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
784788
if (!dmub->hw_init)
785789
return DMUB_STATUS_INVALID;
786790

791+
if (dmub->power_state != DMUB_POWER_STATE_D0)
792+
return DMUB_STATUS_INVALID;
793+
787794
/**
788795
* Read back all the queued commands to ensure that they've
789796
* been flushed to framebuffer memory. Otherwise DMCUB might
@@ -1100,3 +1107,11 @@ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_
11001107
subvp_index);
11011108
}
11021109
}
1110+
1111+
void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state)
1112+
{
1113+
if (!dmub || !dmub->hw_init)
1114+
return;
1115+
1116+
dmub->power_state = dmub_srv_power_state;
1117+
}

0 commit comments

Comments
 (0)