drm/amd/display: Notify DMU to allow DCHVM<->rIOMMU SDP port disconnection for DCN42

[why & how]
Allowing the DCHVM<->rIOMMU SDP port to disconnect during IPS1 cycling
can cause extra credits
to be released to rIOMMU. In turn, this will let the rIOMMU issue more
outstanding table walk requests
at once, overflowing the downstream request FIFO. This results in
dropped/orphaned
requests with no method of recovery. This typically manifests as an
invalidation hang error
in the main IOMMU.

As a workaround, dis-allow the SDP port from disconnecting from IPS1 exit
up until after
powerstatus=1. This ensures that rIOMMU does not have the chance to request
credits multiple
times during the powerstatus 0->1 transition.

Since x86 driver cannot access rIOMMU register space, send a command to DMU
to do it.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Ovidiu Bunea 2026-08-04 16:06:34 -04:00 committed by Alex Deucher
parent ee14b1dc90
commit 322a0695ac
3 changed files with 37 additions and 0 deletions

View File

@ -2527,3 +2527,21 @@ bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, ui
return ret;
}
void dc_dmub_srv_hubbub_set_riommu_pctrl(const struct dc_context *ctx, uint32_t value)
{
union dmub_rb_cmd cmd;
if (!(ctx->dce_version == DCN_VERSION_4_2 || ctx->dce_version == DCN_VERSION_4_2B))
return;
memset(&cmd, 0, sizeof(cmd));
cmd.dc_bls_dchvm_init.header.type = DMUB_CMD__DC_BLS;
cmd.dc_bls_dchvm_init.header.sub_type = DMUB_CMD__DC_BLS_DCHVM_INIT;
cmd.dc_bls_dchvm_init.header.payload_bytes = sizeof(struct dmub_cmd_dc_bls_dchvm_init_data);
cmd.dc_bls_dchvm_init.data.riommu_pctrl_val = value;
dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}

View File

@ -451,4 +451,16 @@ void dc_dmub_srv_panel_polarity_reset(struct dc_dmub_srv *dc_dmub_srv, uint8_t p
*/
bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, uint8_t panel_inst, int32_t *polarity);
/**
* dc_dmub_srv_hubbub_set_riommu_pctrl() - Program the RIOMMU PCTRL register via DMCUB.
*
* The RIOMMU PCTRL register (SMN address 0x16B0A100) controls the SDP port
* disconnection hysteresis between rIOMMU & DCHVM. It is not accessible from
* x86, so the write is offloaded to DMCUB.
*
* @ctx: dc context
* @value: value to program into the register (e.g. 0x20)
*/
void dc_dmub_srv_hubbub_set_riommu_pctrl(const struct dc_context *ctx, uint32_t value);
#endif /* _DMUB_DC_SRV_H_ */

View File

@ -31,6 +31,7 @@
#include "dcn35_hubbub.h"
#include "dm_services.h"
#include "reg_helper.h"
#include "dc_dmub_srv.h"
#define CTX \
@ -580,7 +581,13 @@ void dcn35_dchvm_init(struct hubbub *hubbub)
//Reflect the power status of DCHUBBUB
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
udelay(5);
}
// generically re-allow the DCHVM<->rIOMMU SDP port to disconnect after powerstatus=1
dc_dmub_srv_hubbub_set_riommu_pctrl(hubbub->ctx, 0x20);
if (riommu_active) {
//Start rIOMMU prefetching
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);