diff options
author | Jun Lei <Jun.Lei@amd.com> | 2019-07-08 15:15:42 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-07-18 14:27:26 -0500 |
commit | 057fc695e934a77bae0c6c7f3be01251774b61cf (patch) | |
tree | 405f1311da2b64d9faa06c11f6173c024160acfc /drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | |
parent | 0488a56465877a48596a874bc0f4f31d6fbf334e (diff) |
drm/amd/display: support "dummy pstate"
[why]
Existing support in DC for pstate only accounts for a single latency. This is sufficient when the
variance of latency is small, or that pstate support isn't necessary for correct ASIC functionality.
Newer ASICs violate both existing assumptions. PState support is mandatory of correct ASIC
functionality, but not all latencies have to be supported. Existing code supports a "full p state" which
allows memory clock to change, but is hard for DCN to support (as it requires very large buffers).
New code will now fall back to a "dummy p state" support when "full p state" cannot be support.
This easy p state support should always be allowed.
[how]
Define a new latency in socBB. Add fallback logic to support it. Note DML is also updated to ensure
that fallback will always work.
Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 346a9b9e7624..ad015290e17b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2427,7 +2427,7 @@ void dcn20_calculate_dlg_params( } } -bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, +static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context, bool fast_validate) { bool out = false; @@ -2479,6 +2479,62 @@ validate_out: return out; } + +bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, + bool fast_validate) +{ + bool voltage_supported = false; + bool full_pstate_supported = false; + bool dummy_pstate_supported = false; + double p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us; + + if (fast_validate) + return dcn20_validate_bandwidth_internal(dc, context, true); + + + // Best case, we support full UCLK switch latency + voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); + full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; + + if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 || + (voltage_supported && full_pstate_supported)) { + context->bw_ctx.bw.dcn.clk.p_state_change_support = true; + goto restore_dml_state; + } + + // Fallback #1: Try to only support G6 temperature read latency + context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us; + + voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); + dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; + + if (voltage_supported && dummy_pstate_supported) { + context->bw_ctx.bw.dcn.clk.p_state_change_support = false; + goto restore_dml_state; + } + + // Fallback #2: Retry with "new" DCN20 to support G6 temperature read latency + memcpy (&context->bw_ctx.dml, &dc->work_arounds.alternate_dml, sizeof (struct display_mode_lib)); + context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us; + + voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); + dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; + + if (voltage_supported && dummy_pstate_supported) { + context->bw_ctx.bw.dcn.clk.p_state_change_support = false; + goto restore_dml_state; + } + + // ERROR: fallback #2 is supposed to always work. + ASSERT(false); + +restore_dml_state: + memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); + context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us; + + return voltage_supported; +} + struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer( struct dc_state *state, const struct resource_pool *pool, @@ -3085,6 +3141,7 @@ static bool construct( } dml_init_instance(&dc->dml, &dcn2_0_soc, &dcn2_0_ip, DML_PROJECT_NAVI10); + dml_init_instance(&dc->work_arounds.alternate_dml, &dcn2_0_soc, &dcn2_0_ip, DML_PROJECT_NAVI10v2); if (!dc->debug.disable_pplib_wm_range) { struct pp_smu_wm_range_sets ranges = {0}; |