[RFC PATCH 3/5] drm/amd/display: invalidate PSR request cache after DMUB reset

David Weber <[email protected]> Wed, 5 Aug 2026 13:52:46 +0200
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <74f249d9212e7ada4c3e6eaa5961d9c54943648d.1785929873.git.weber.aulendorf@gmail.com>
The cached PSR allow-active request is used to suppress redundant
firmware programming. A DMUB reset or resume can discard firmware state
without destroying the corresponding dc_link, leaving that request cache
stale.

Invalidate the allow-active cache whenever DMUB is reset or resumed.
Require a valid cache in direct PSR control so the next request can
reestablish the firmware state.

Preserve cache validity alongside the clock manager's saved PSR request
and do not restore an invalid snapshot. Replay restore remains unchanged;
the PSR validity flag does not describe Replay state.

Fixes: 3c108046e1d6 ("drm/amd/display: Add power module on Linux")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: David Weber <[email protected]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c    | 16 ++++++++++++++++
 drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c |  9 +++++++--
 drivers/gpu/drm/amd/display/dc/core/dc.c         |  6 ++++--
 drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h  |  1 +
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 9c564cd5edee..ee3d65226a69 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1304,6 +1304,19 @@ static  void amdgpu_dm_audio_eld_notify(struct amdgpu_device *adev, int pin)
 	}
 }
 
+static void dm_invalidate_psr_request_caches(struct amdgpu_device *adev)
+{
+	struct dc *dc = adev->dm.dc;
+	int i;
+
+	if (!dc)
+		return;
+
+	for (i = 0; i < dc->link_count; i++)
+		if (dc->links[i])
+			dc->links[i]->psr_settings.psr_allow_active_valid = false;
+}
+
 static int dm_dmub_hw_init(struct amdgpu_device *adev)
 {
 	const struct dmcub_firmware_header_v1_0 *hdr;
@@ -1354,6 +1367,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
 	status = dmub_srv_hw_reset(dmub_srv);
 	if (status != DMUB_STATUS_OK)
 		drm_warn(adev_to_drm(adev), "Error resetting DMUB HW: %d\n", status);
+	dm_invalidate_psr_request_caches(adev);
 
 	hdr = (const struct dmcub_firmware_header_v1_0 *)dmub_fw->data;
 
@@ -1505,6 +1519,8 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
 		return;
 	}
 
+	dm_invalidate_psr_request_caches(adev);
+
 	status = dmub_srv_is_hw_init(dmub_srv, &init);
 	if (status != DMUB_STATUS_OK)
 		drm_warn(adev_to_drm(adev), "DMUB hardware init check failed: %d\n", status);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index 2a1353cb7e7d..2c587cb0f5e1 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -114,6 +114,8 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
 			if (!edp_link->psr_settings.psr_feature_enabled)
 				continue;
 			clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
+			clk_mgr->psr_allow_active_cache_valid =
+				edp_link->psr_settings.psr_allow_active_valid;
 			dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
 			dc->link_srv->edp_set_replay_allow_active(edp_link, &allow_active, false, false, NULL);
 		}
@@ -134,8 +136,11 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
 			edp_link = edp_links[panel_inst];
 			if (!edp_link->psr_settings.psr_feature_enabled)
 				continue;
-			dc->link_srv->edp_set_psr_allow_active(edp_link,
-					&clk_mgr->psr_allow_active_cache, false, false, NULL);
+			if (clk_mgr->psr_allow_active_cache_valid)
+				dc->link_srv->edp_set_psr_allow_active(edp_link,
+						&clk_mgr->psr_allow_active_cache,
+						false, false, NULL);
+			/* PSR cache validity does not describe Replay state. */
 			dc->link_srv->edp_set_replay_allow_active(edp_link,
 					&clk_mgr->psr_allow_active_cache, false, false, NULL);
 		}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e25b94b65dac..8d76101a17a3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -6308,11 +6308,13 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable)
 			continue;
 
 		if (link->psr_settings.psr_feature_enabled) {
-			if (enable && !link->psr_settings.psr_allow_active) {
+			if (enable && (!link->psr_settings.psr_allow_active_valid ||
+				       !link->psr_settings.psr_allow_active)) {
 				allow_active = true;
 				if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL))
 					return false;
-			} else if (!enable && link->psr_settings.psr_allow_active) {
+			} else if (!enable && (!link->psr_settings.psr_allow_active_valid ||
+					      link->psr_settings.psr_allow_active)) {
 				allow_active = false;
 				if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL))
 					return false;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index f829ce3f70e5..e351f3dee8ff 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -412,6 +412,7 @@ struct clk_mgr {
 	struct clk_mgr_funcs *funcs;
 	struct dc_clocks clks;
 	bool psr_allow_active_cache;
+	bool psr_allow_active_cache_valid;
 	bool force_smu_not_present;
 	bool dc_mode_softmax_enabled;
 	int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
-- 
2.54.0