mirror of
https://github.com/torvalds/linux.git
synced 2026-11-09 05:34:02 +01:00
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:
parent
ee14b1dc90
commit
322a0695ac
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user