mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 07:33:19 +02:00
drm/amd/display: dynamically clock gate before and after prefetch
[Why] An invalidation request arriving during prefetch can potentially hang the system if dynamic clock gating is enabled and memory power requests are disabled. [How] • Disable clock gating and enable memory power requests for the duration of the prefetch. • Turn on clock gating and disable memory power requests again after prefetch is complete. Limit the scope for DCN35 and DCN42 only. Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Leo Chen <leo.chen@amd.com> Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
b6fffcc453
commit
401f8f33ad
|
|
@ -933,8 +933,8 @@ int hubbub31_init_dchub_sys_ctx(struct hubbub *hubbub,
|
|||
|
||||
dcn20_vmid_setup(&hubbub2->vmid[15], &phys_config);
|
||||
}
|
||||
|
||||
dcn21_dchvm_init(hubbub);
|
||||
if (hubbub->funcs->dchvm_init)
|
||||
hubbub->funcs->dchvm_init(hubbub);
|
||||
|
||||
return NUM_VMID;
|
||||
}
|
||||
|
|
@ -1071,7 +1071,8 @@ 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,
|
||||
.hubbub_read_reg_state = hubbub3_read_reg_state
|
||||
.hubbub_read_reg_state = hubbub3_read_reg_state,
|
||||
.dchvm_init = dcn21_dchvm_init
|
||||
};
|
||||
|
||||
void hubbub31_construct(struct dcn20_hubbub *hubbub31,
|
||||
|
|
|
|||
|
|
@ -549,6 +549,55 @@ void hubbub35_init(struct hubbub *hubbub)
|
|||
memset(&hubbub2->watermarks.a.cstate_pstate, 0, sizeof(hubbub2->watermarks.a.cstate_pstate));
|
||||
}
|
||||
|
||||
void dcn35_dchvm_init(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t riommu_active;
|
||||
int i;
|
||||
|
||||
//Init DCHVM block
|
||||
REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);
|
||||
|
||||
//Poll until RIOMMU_ACTIVE = 1
|
||||
for (i = 0; i < 100; i++) {
|
||||
REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active);
|
||||
|
||||
if (riommu_active)
|
||||
break;
|
||||
else
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
if (riommu_active) {
|
||||
// Disable gating and memory power requests
|
||||
REG_UPDATE(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, 1);
|
||||
REG_UPDATE_4(DCHVM_CLK_CTRL,
|
||||
HVM_DISPCLK_R_GATE_DIS, 1,
|
||||
HVM_DISPCLK_G_GATE_DIS, 1,
|
||||
HVM_DCFCLK_R_GATE_DIS, 1,
|
||||
HVM_DCFCLK_G_GATE_DIS, 1);
|
||||
|
||||
//Reflect the power status of DCHUBBUB
|
||||
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
|
||||
|
||||
//Start rIOMMU prefetching
|
||||
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);
|
||||
|
||||
//Poll until HOSTVM_PREFETCH_DONE = 1
|
||||
REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);
|
||||
|
||||
//Enable memory power requests
|
||||
REG_UPDATE(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, 0);
|
||||
// Enable dynamic clock gating
|
||||
REG_UPDATE_4(DCHVM_CLK_CTRL,
|
||||
HVM_DISPCLK_R_GATE_DIS, 0,
|
||||
HVM_DISPCLK_G_GATE_DIS, 0,
|
||||
HVM_DCFCLK_R_GATE_DIS, 0,
|
||||
HVM_DCFCLK_G_GATE_DIS, 0);
|
||||
hubbub->riommu_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*static void hubbub35_set_request_limit(struct hubbub *hubbub,
|
||||
int memory_channel_count,
|
||||
int words_per_channel)
|
||||
|
|
@ -589,7 +638,8 @@ static const struct hubbub_funcs hubbub35_funcs = {
|
|||
.hubbub_read_state = hubbub2_read_state,
|
||||
.force_usr_retraining_allow = hubbub32_force_usr_retraining_allow,
|
||||
.dchubbub_init = hubbub35_init,
|
||||
.hubbub_read_reg_state = hubbub3_read_reg_state
|
||||
.hubbub_read_reg_state = hubbub3_read_reg_state,
|
||||
.dchvm_init = dcn35_dchvm_init
|
||||
};
|
||||
|
||||
void hubbub35_construct(struct dcn20_hubbub *hubbub2,
|
||||
|
|
|
|||
|
|
@ -168,4 +168,5 @@ void dcn35_program_compbuf_size(struct hubbub *hubbub,
|
|||
unsigned int compbuf_size_kb, bool safe_to_increase);
|
||||
void dcn35_init_crb(struct hubbub *hubbub);
|
||||
void hubbub35_init(struct hubbub *hubbub);
|
||||
void dcn35_dchvm_init(struct hubbub *hubbub);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -252,6 +252,8 @@ struct hubbub_funcs {
|
|||
void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase);
|
||||
void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst);
|
||||
bool (*program_arbiter)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower);
|
||||
void (*dchvm_init)(struct hubbub *hubbub);
|
||||
|
||||
struct hubbub_perfmon_funcs {
|
||||
void (*reset)(struct hubbub *hubbub);
|
||||
void (*start_measuring_max_memory_latency_ns)(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user