Commit a4d5df17 authored by Eric Yang's avatar Eric Yang Committed by Alex Deucher

drm/amd/display: add workaround for riommu invalidation request hang

[Why]
When an riommu invalidation request come at the same time as a pipe is
disabled there can be a case where DCN cannot ACK the request if only
one VMID is setup in the inuse list.

[How]
Setup a second unused VMID will work around the issue.
Reviewed-by: default avatarJun Lei <jun.lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarEric Yang <Eric.Yang2@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ba16b22d
......@@ -570,6 +570,12 @@ void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
if (hws->wa.early_riommu_invalidation) {
struct hubbub *hubbub = dc->res_pool->hubbub;
hubbub->funcs->apply_invalidation_req_wa(hubbub, &hubbub->vmid_cache);
}
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
/* In flip immediate with pipe splitting case GSL is used for
......
......@@ -880,6 +880,8 @@ static int hubbub31_init_dchub_sys_ctx(struct hubbub *hubbub,
dcn21_dchvm_init(hubbub);
hubbub->vmid_cache = *pa_config;
return NUM_VMID;
}
......@@ -920,6 +922,23 @@ static void hubbub31_get_dchub_ref_freq(struct hubbub *hubbub,
}
}
static void hubbub31_apply_invalidation_req_wa(struct hubbub *hubbub,
struct dcn_hubbub_phys_addr_config *pa_config)
{
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
struct dcn_vmid_page_table_config phys_config;
if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) {
phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12;
phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12;
phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
phys_config.depth = 0;
phys_config.block_size = 0;
// Program an arbitrary unused VMID
dcn20_vmid_setup(&hubbub1->vmid[15], &phys_config);
}
}
static const struct hubbub_funcs hubbub31_funcs = {
.update_dchub = hubbub2_update_dchub,
.init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,
......@@ -936,6 +955,7 @@ static const struct hubbub_funcs hubbub31_funcs = {
.program_compbuf_size = dcn31_program_compbuf_size,
.init_crb = dcn31_init_crb,
.hubbub_read_state = hubbub2_read_state,
.apply_invalidation_req_wa = hubbub31_apply_invalidation_req_wa
};
void hubbub31_construct(struct dcn20_hubbub *hubbub31,
......
......@@ -166,12 +166,15 @@ struct hubbub_funcs {
void (*program_det_size)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_in_kbyte);
void (*program_compbuf_size)(struct hubbub *hubbub, unsigned compbuf_size_kb, bool safe_to_increase);
void (*init_crb)(struct hubbub *hubbub);
void (*apply_invalidation_req_wa)(struct hubbub *hubbub,
struct dcn_hubbub_phys_addr_config *pa_config);
};
struct hubbub {
const struct hubbub_funcs *funcs;
struct dc_context *ctx;
bool riommu_active;
struct dcn_hubbub_phys_addr_config vmid_cache;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment