drm/amd/display: fix system hang when PSR exits
authorDavid Zhang <dingchen.zhang@amd.com>
Tue, 3 May 2022 14:49:52 +0000 (10:49 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 6 Jun 2022 18:42:08 +0000 (14:42 -0400)
[why]
When DC driver send PSR exit dmub command to DMUB FW, it might not
wait until PSR exit. Then it may hit the following deadlock situation.
1. DC driver send HW LOCK command to DMUB FW due to frame update
2. DMUB FW Set the HW lock
3. DMUB execute PSR exit sequence and stuck at polling DPG Pending
register due to the HW Lock is set
4. DC driver ask DMUB FW to unlock HW lock, but DMUB FW is polling
DPG pending register

[how]
The reason why DC driver doesn't wait until PSR exit is because some of
the PSR state machine state is not update the dc driver. So when DC
driver read back the PSR state, it take the state for PSR inactive.

Signed-off-by: David Zhang <dingchen.zhang@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@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 119ce8b7a55589abc38d3ec98904387148586092..144c387010c236634290c4be50200dcfc7b6d2c1 100644 (file)
@@ -657,10 +657,17 @@ enum dc_psr_state {
        PSR_STATE4b,
        PSR_STATE4c,
        PSR_STATE4d,
+       PSR_STATE4_FULL_FRAME,
+       PSR_STATE4a_FULL_FRAME,
+       PSR_STATE4b_FULL_FRAME,
+       PSR_STATE4c_FULL_FRAME,
+       PSR_STATE4_FULL_FRAME_POWERUP,
        PSR_STATE5,
        PSR_STATE5a,
        PSR_STATE5b,
        PSR_STATE5c,
+       PSR_STATE_HWLOCK_MGR,
+       PSR_STATE_POLLVUPDATE,
        PSR_STATE_INVALID = 0xFF
 };
 
index c2d65756ce5d083249de520268ada9c97e96f0a5..e784002fe312f5a4cd77fa616e59a73d254263a4 100644 (file)
@@ -74,6 +74,22 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state)
                state = PSR_STATE5b;
        else if (raw_state == 0x53)
                state = PSR_STATE5c;
+       else if (raw_state == 0x4A)
+               state = PSR_STATE4_FULL_FRAME;
+       else if (raw_state == 0x4B)
+               state = PSR_STATE4a_FULL_FRAME;
+       else if (raw_state == 0x4C)
+               state = PSR_STATE4b_FULL_FRAME;
+       else if (raw_state == 0x4D)
+               state = PSR_STATE4c_FULL_FRAME;
+       else if (raw_state == 0x4E)
+               state = PSR_STATE4_FULL_FRAME_POWERUP;
+       else if (raw_state == 0x60)
+               state = PSR_STATE_HWLOCK_MGR;
+       else if (raw_state == 0x61)
+               state = PSR_STATE_POLLVUPDATE;
+       else
+               state = PSR_STATE_INVALID;
 
        return state;
 }