diff options
| author | Nicholas Kazlauskas <[email protected]> | 2024-04-18 13:51:36 +0000 |
|---|---|---|
| committer | Alex Deucher <[email protected]> | 2024-04-30 13:57:17 +0000 |
| commit | 5419a2076de1dd9b0b4a191d0dd07de7c4fa7040 (patch) | |
| tree | 30e05834d736cf2499133f76d1d0f673598a544f /drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | |
| parent | drm/amd/display: Enable Replay for DCN315 (diff) | |
| download | kernel-5419a2076de1dd9b0b4a191d0dd07de7c4fa7040.tar.gz kernel-5419a2076de1dd9b0b4a191d0dd07de7c4fa7040.zip | |
drm/amd/display: Notify idle link detection through shared state
[Why]
We can hang in IPS2 checking DMCUB_SCRATCH0 for link detection state.
[How]
Replace the HW access with a check on the shared state bit. This will
work the same way as the SCRATCH0 but won't require a wake in the case
where link detection isn't required.
Reviewed-by: Duncan Ma <[email protected]>
Acked-by: Wayne Lin <[email protected]>
Signed-off-by: Nicholas Kazlauskas <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
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.c | 30 |
1 files changed, 30 insertions, 0 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 33d3307f5c1c..364ef9ae32f1 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -1460,6 +1460,36 @@ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_c dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3); } +bool dc_dmub_srv_should_detect(struct dc_dmub_srv *dc_dmub_srv) +{ + volatile const struct dmub_shared_state_ips_fw *ips_fw; + bool reallow_idle = false, should_detect = false; + + if (!dc_dmub_srv || !dc_dmub_srv->dmub) + return false; + + if (dc_dmub_srv->dmub->shared_state && + dc_dmub_srv->dmub->meta_info.feature_bits.bits.shared_state_link_detection) { + ips_fw = &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_FW].data.ips_fw; + return ips_fw->signals.bits.detection_required; + } + + /* Detection may require reading scratch 0 - exit out of idle prior to the read. */ + if (dc_dmub_srv->idle_allowed) { + dc_dmub_srv_apply_idle_power_optimizations(dc_dmub_srv->ctx->dc, false); + reallow_idle = true; + } + + should_detect = dmub_srv_should_detect(dc_dmub_srv->dmub); + + /* Re-enter idle if we're not about to immediately redetect links. */ + if (!should_detect && reallow_idle && dc_dmub_srv->idle_exit_counter == 0 && + !dc_dmub_srv->ctx->dc->debug.disable_dmub_reallow_idle) + dc_dmub_srv_apply_idle_power_optimizations(dc_dmub_srv->ctx->dc, true); + + return should_detect; +} + void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle) { struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv; |
