drm/amd/display: Retry getting PSR state if command times out
authorWyatt Wood <wyatt.wood@amd.com>
Fri, 19 Mar 2021 17:44:55 +0000 (13:44 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 9 Apr 2021 20:51:25 +0000 (16:51 -0400)
[Why]
GPINT command to get PSR state from FW times out.

[How]
Add retry to get valid PSR state.

Signed-off-by: Wyatt Wood <wyatt.wood@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c

index b5e875ee9027b1d3857516dfee2bbe5601208b3f..d8912a4de3b108480546b1d39795692ba4490bcb 100644 (file)
@@ -687,7 +687,8 @@ enum dc_psr_state {
        PSR_STATE5,
        PSR_STATE5a,
        PSR_STATE5b,
-       PSR_STATE5c
+       PSR_STATE5c,
+       PSR_STATE_INVALID = 0xFF
 };
 
 struct psr_config {
index 15ed09b7a452e650ef1e5a955dba14fa17ed0eec..28ff059aa7f3739947c594f478fc7f5dfa163e31 100644 (file)
@@ -80,19 +80,26 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state)
 static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state)
 {
        struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
-       uint32_t raw_state;
+       uint32_t raw_state = 0;
+       uint32_t retry_count = 0;
        enum dmub_status status;
 
-       // Send gpint command and wait for ack
-       status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
-
-       if (status == DMUB_STATUS_OK) {
-               // GPINT was executed, get response
-               dmub_srv_get_gpint_response(srv, &raw_state);
-               *state = convert_psr_state(raw_state);
-       } else
-               // Return invalid state when GPINT times out
-               *state = 0xFF;
+       do {
+               // Send gpint command and wait for ack
+               status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
+
+               if (status == DMUB_STATUS_OK) {
+                       // GPINT was executed, get response
+                       dmub_srv_get_gpint_response(srv, &raw_state);
+                       *state = convert_psr_state(raw_state);
+               } else
+                       // Return invalid state when GPINT times out
+                       *state = PSR_STATE_INVALID;
+
+               // Assert if max retry hit
+               if (retry_count >= 1000)
+                       ASSERT(0);
+       } while (++retry_count <= 1000 && *state == PSR_STATE_INVALID);
 }
 
 /*