aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
diff options
context:
space:
mode:
authorNicholas Kazlauskas <[email protected]>2024-04-18 13:51:36 +0000
committerAlex Deucher <[email protected]>2024-04-30 13:57:17 +0000
commit5419a2076de1dd9b0b4a191d0dd07de7c4fa7040 (patch)
tree30e05834d736cf2499133f76d1d0f673598a544f /drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
parentdrm/amd/display: Enable Replay for DCN315 (diff)
downloadkernel-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.c30
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;