diff options
author | Alvin Lee <alvin.lee2@amd.com> | 2023-08-10 11:50:52 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2023-08-30 14:59:14 -0400 |
commit | 0b9dc439f4046ef9e43f54989f6c3ff6cddc6d1b (patch) | |
tree | 0097a2d4ffa00fc469b78031cb49856593ac84c3 /drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | |
parent | ec4247823bbc88a7ee81fec579d1b4408bba686d (diff) |
drm/amd/display: Write flip addr to scratch reg for subvp
[Description]
SubVP needs to "calculate" the earliest in use META address
by using the current primary / meta addresses, but this leads
to a race condition where FW and driver can read/write the
address at the same time and intermittently produce inconsistent
address offsets. To mitigate this issue without locking (too slow),
save each surface flip addr into scratch registers and use this
to keep track of the earliest in use META addres.
Reviewed-by: Jun Lei <jun.lei@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c index 8f427047ac40..2daa1e0c8061 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -27,6 +27,7 @@ #include "dmub_reg.h" #include "dmub_dcn32.h" #include "dc/dc_types.h" +#include "dc_hw_types.h" #include "dcn/dcn_3_2_0_offset.h" #include "dcn/dcn_3_2_0_sh_mask.h" @@ -506,3 +507,32 @@ uint32_t dmub_dcn32_read_inbox0_ack_register(struct dmub_srv *dmub) { return REG_READ(DMCUB_SCRATCH17); } + +void dmub_dcn32_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index) +{ + uint32_t index = 0; + + if (subvp_index == 0) { + index = REG_READ(DMCUB_SCRATCH15); + if (index) { + REG_WRITE(DMCUB_SCRATCH9, addr->grph.addr.low_part); + REG_WRITE(DMCUB_SCRATCH11, addr->grph.meta_addr.low_part); + } else { + REG_WRITE(DMCUB_SCRATCH12, addr->grph.addr.low_part); + REG_WRITE(DMCUB_SCRATCH13, addr->grph.meta_addr.low_part); + } + REG_WRITE(DMCUB_SCRATCH15, !index); + } else if (subvp_index == 1) { + index = REG_READ(DMCUB_SCRATCH23); + if (index) { + REG_WRITE(DMCUB_SCRATCH18, addr->grph.addr.low_part); + REG_WRITE(DMCUB_SCRATCH19, addr->grph.meta_addr.low_part); + } else { + REG_WRITE(DMCUB_SCRATCH20, addr->grph.addr.low_part); + REG_WRITE(DMCUB_SCRATCH22, addr->grph.meta_addr.low_part); + } + REG_WRITE(DMCUB_SCRATCH23, !index); + } else { + return; + } +} |