From 52f2e83e2fe5596862ed0830df1cb340e411cc74 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Fri, 29 May 2020 15:27:06 -0400 Subject: 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 Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 67 ++++++++++++++++++++++ .../gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +- 2 files changed, 68 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display/dc/dcn30') 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; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 783a1d7ae7d3..b132bb7f6704 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2247,7 +2247,7 @@ void dcn30_calculate_wm_and_dlg( /* Set D: * DCFCLK: Min Required * FCLK(proportional to UCLK): 1GHz or Max - * sr_enter_exit = 4, sr_exit = 2us + * MALL stutter, sr_enter_exit = 4, sr_exit = 2us */ /* if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { -- cgit v1.2.3