diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 01864fe816a3..4723e0974647 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -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); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index ec5387aedf46..ab026847e38b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -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_ */ diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c index 5e5a7a74346d..53744b000f5d 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c @@ -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);