diff options
author | Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> | 2020-05-29 15:27:06 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2020-10-23 15:33:48 -0400 |
commit | 52f2e83e2fe5596862ed0830df1cb340e411cc74 (patch) | |
tree | 4f2e7722d59859ea1abbf96f99ceac602bffb810 /drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | |
parent | 4005809bb1f31fd3c23b42c24c90b15ed72746c0 (diff) |
drm/amdgpu/display: add MALL support (v2)
Enable Memory Access at Last Level (MALL) feature for display.
v2: squash in 64 bit division fixes
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 8eb8e13e1130..f3ae208850b0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -696,6 +696,10 @@ void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx) bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) { + union dmub_rb_cmd cmd; + unsigned int surface_size, refresh_hz, denom; + uint32_t tmr_delay = 0, tmr_scale = 0; + if (!dc->ctx->dmub_srv) return false; @@ -710,12 +714,75 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) /* Fail eligibility on a visible stream */ break; } + + // TODO: remove hard code size + if (surface_size < 128 * 1024 * 1024) { + refresh_hz = div_u64((unsigned long long) dc->current_state->streams[0]->timing.pix_clk_100hz * + 100LL, + (dc->current_state->streams[0]->timing.v_total * + dc->current_state->streams[0]->timing.h_total)); + + /* + * Delay_Us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale + * Delay_Us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale + * (Delay_Us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly + * MallFrameCacheTmrDly = ((Delay_Us / 65.28) / 2^MallFrameCacheTmrScale) - 64 + * = (1000000 / refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64 + * = 1000000 / (refresh * 65.28 * 2^MallFrameCacheTmrScale) - 64 + * = (1000000 * 100) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64 + * + * need to round up the result of the division before the subtraction + */ + denom = refresh_hz * 6528; + tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL; + + /* scale should be increased until it fits into 6 bits */ + while (tmr_delay & ~0x3F) { + tmr_scale++; + + if (tmr_scale > 3) { + /* The delay exceeds the range of the hystersis timer */ + ASSERT(false); + return false; + } + + denom *= 2; + tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL; + } + + /* Enable MALL */ + memset(&cmd, 0, sizeof(cmd)); + cmd.mall.header.type = DMUB_CMD__MALL; + cmd.mall.header.sub_type = + DMUB_CMD__MALL_ACTION_ALLOW; + cmd.mall.header.payload_bytes = + sizeof(cmd.mall) - + sizeof(cmd.mall.header); + cmd.mall.tmr_delay = tmr_delay; + cmd.mall.tmr_scale = tmr_scale; + + dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); + + return true; + } } /* No applicable optimizations */ return false; } + /* Disable MALL */ + memset(&cmd, 0, sizeof(cmd)); + cmd.mall.header.type = DMUB_CMD__MALL; + cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_DISALLOW; + cmd.mall.header.payload_bytes = + sizeof(cmd.mall) - sizeof(cmd.mall.header); + + dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); + dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); + return true; } |