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 | |
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')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 10 |
3 files changed, 47 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 8f427047ac407..2daa1e0c80616 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; + } +} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h index 38e47065e00e4..b0cd8d29402f5 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h @@ -107,6 +107,12 @@ struct dmub_srv; DMUB_SR(DMCUB_SCRATCH15) \ DMUB_SR(DMCUB_SCRATCH16) \ DMUB_SR(DMCUB_SCRATCH17) \ + DMUB_SR(DMCUB_SCRATCH18) \ + DMUB_SR(DMCUB_SCRATCH19) \ + DMUB_SR(DMCUB_SCRATCH20) \ + DMUB_SR(DMCUB_SCRATCH21) \ + DMUB_SR(DMCUB_SCRATCH22) \ + DMUB_SR(DMCUB_SCRATCH23) \ DMUB_SR(DMCUB_GPINT_DATAIN0) \ DMUB_SR(DMCUB_GPINT_DATAIN1) \ DMUB_SR(DMCUB_GPINT_DATAOUT) \ @@ -253,6 +259,7 @@ void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub); void dmub_dcn32_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data); void dmub_dcn32_clear_inbox0_ack_register(struct dmub_srv *dmub); uint32_t dmub_dcn32_read_inbox0_ack_register(struct dmub_srv *dmub); +void dmub_dcn32_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index); void dmub_srv_dcn32_regs_init(struct dmub_srv *dmub, struct dc_context *ctx); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 9780c157196c3..53464c3e49c17 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -278,6 +278,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->send_inbox0_cmd = dmub_dcn32_send_inbox0_cmd; funcs->clear_inbox0_ack_register = dmub_dcn32_clear_inbox0_ack_register; funcs->read_inbox0_ack_register = dmub_dcn32_read_inbox0_ack_register; + funcs->subvp_save_surf_addr = dmub_dcn32_save_surf_addr; funcs->reset = dmub_dcn32_reset; funcs->reset_release = dmub_dcn32_reset_release; funcs->backdoor_load = dmub_dcn32_backdoor_load; @@ -985,3 +986,12 @@ enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub, dmub->hw_funcs.send_inbox0_cmd(dmub, data); return DMUB_STATUS_OK; } + +void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index) +{ + if (dmub->hw_funcs.subvp_save_surf_addr) { + dmub->hw_funcs.subvp_save_surf_addr(dmub, + addr, + subvp_index); + } +} |