From: Ovidiu Bunea <[email protected]> [why & how] Out-of-urgent bandwidth delivery to DCN is very poor under workloads. Even after asserting urgent, empirical data shows urgent return BW delays of up to 100 μs. Override the value when programming watermarks to avoid modifying mode support. Maintain the DML's calculated value as a floor.
Signed-off-by: Ovidiu Bunea <[email protected]> Signed-off-by: Fangzhi Zuo <[email protected]> Reviewed-by: Nicholas Kazlauskas <[email protected]> --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../display/dc/hubbub/dcn42/dcn42_hubbub.c | 41 +++++++++++-------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 9c8e55715e47..b7c04d7cea3b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1314,6 +1314,7 @@ struct dc_debug_options { unsigned int auxless_alpm_lfps_t1t2_us; short auxless_alpm_lfps_t1t2_offset_us; bool disable_stutter_for_wm_program; + unsigned int urgent_watermark_override; bool enable_block_sequence_programming; uint32_t custom_psp_footer_size; bool disable_deferred_minimal_transitions; diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c index 036276c17562..244f3f2824ed 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c @@ -30,15 +30,24 @@ static bool hubbub42_program_urgent_watermarks( bool safe_to_lower) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); + const unsigned int urgent_floor = hubbub->ctx->dc->debug.urgent_watermark_override; + const unsigned int urgent_a = max(urgent_floor, + watermarks->dcn4x.a.urgent); + const unsigned int urgent_b = max(urgent_floor, + watermarks->dcn4x.b.urgent); + const unsigned int urgent_c = max(urgent_floor, + watermarks->dcn4x.c.urgent); + const unsigned int urgent_d = max(urgent_floor, + watermarks->dcn4x.d.urgent); bool wm_pending = false; /* Repeat for water mark set A, B, C and D. */ /* clock state A */ - if (safe_to_lower || watermarks->dcn4x.a.urgent > hubbub2->watermarks.dcn4x.a.urgent) { - hubbub2->watermarks.dcn4x.a.urgent = watermarks->dcn4x.a.urgent; + if (safe_to_lower || urgent_a > hubbub2->watermarks.dcn4x.a.urgent) { + hubbub2->watermarks.dcn4x.a.urgent = urgent_a; REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, watermarks->dcn4x.a.urgent); - } else if (watermarks->dcn4x.a.urgent < hubbub2->watermarks.dcn4x.a.urgent) + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, urgent_a); + } else if (urgent_a < hubbub2->watermarks.dcn4x.a.urgent) wm_pending = true; /* determine the transfer time for a quantity of data for a particular requestor.*/ @@ -64,11 +73,11 @@ static bool hubbub42_program_urgent_watermarks( wm_pending = true; /* clock state B */ - if (safe_to_lower || watermarks->dcn4x.b.urgent > hubbub2->watermarks.dcn4x.b.urgent) { - hubbub2->watermarks.dcn4x.b.urgent = watermarks->dcn4x.b.urgent; + if (safe_to_lower || urgent_b > hubbub2->watermarks.dcn4x.b.urgent) { + hubbub2->watermarks.dcn4x.b.urgent = urgent_b; REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, watermarks->dcn4x.b.urgent); - } else if (watermarks->dcn4x.b.urgent < hubbub2->watermarks.dcn4x.b.urgent) + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, urgent_b); + } else if (urgent_b < hubbub2->watermarks.dcn4x.b.urgent) wm_pending = true; /* determine the transfer time for a quantity of data for a particular requestor.*/ @@ -94,11 +103,11 @@ static bool hubbub42_program_urgent_watermarks( wm_pending = true; /* clock state C */ - if (safe_to_lower || watermarks->dcn4x.c.urgent > hubbub2->watermarks.dcn4x.c.urgent) { - hubbub2->watermarks.dcn4x.c.urgent = watermarks->dcn4x.c.urgent; + if (safe_to_lower || urgent_c > hubbub2->watermarks.dcn4x.c.urgent) { + hubbub2->watermarks.dcn4x.c.urgent = urgent_c; REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, watermarks->dcn4x.c.urgent); - } else if (watermarks->dcn4x.c.urgent < hubbub2->watermarks.dcn4x.c.urgent) + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, urgent_c); + } else if (urgent_c < hubbub2->watermarks.dcn4x.c.urgent) wm_pending = true; /* determine the transfer time for a quantity of data for a particular requestor.*/ @@ -124,11 +133,11 @@ static bool hubbub42_program_urgent_watermarks( wm_pending = true; /* clock state D */ - if (safe_to_lower || watermarks->dcn4x.d.urgent > hubbub2->watermarks.dcn4x.d.urgent) { - hubbub2->watermarks.dcn4x.d.urgent = watermarks->dcn4x.d.urgent; + if (safe_to_lower || urgent_d > hubbub2->watermarks.dcn4x.d.urgent) { + hubbub2->watermarks.dcn4x.d.urgent = urgent_d; REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, watermarks->dcn4x.d.urgent); - } else if (watermarks->dcn4x.d.urgent < hubbub2->watermarks.dcn4x.d.urgent) + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, urgent_d); + } else if (urgent_d < hubbub2->watermarks.dcn4x.d.urgent) wm_pending = true; /* determine the transfer time for a quantity of data for a particular requestor.*/ -- 2.53.0
