summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
diff options
context:
space:
mode:
authorJun Lei <Jun.Lei@amd.com>2019-07-08 15:15:42 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-07-18 14:27:26 -0500
commit057fc695e934a77bae0c6c7f3be01251774b61cf (patch)
tree405f1311da2b64d9faa06c11f6173c024160acfc /drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
parent0488a56465877a48596a874bc0f4f31d6fbf334e (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.c59
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};