diff options
| author | Tony Cheng <tony.cheng@amd.com> | 2026-09-22 15:20:44 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-10-27 14:13:13 -0400 |
| commit | 3e968c8a009c2f9c7328d6d54fa43e184b41580a (patch) | |
| tree | cc3666c4af795d6fd6c4bd1217f1c177cb4f7708 | |
| parent | a8df5b1db0ca7d2b954c3abf9c3a0a5d9585ec23 (diff) | |
| download | linux-next-3e968c8a009c2f9c7328d6d54fa43e184b41580a.tar.gz linux-next-3e968c8a009c2f9c7328d6d54fa43e184b41580a.zip | |
drm/amd/display: Add Core 2 Workaround Manager scaffolding
[Why]
Core needs a Layer-2 post-build stage that can edit a built BLS list
for errata before the Executor runs. Inline workarounds stay scattered
until that manager exists.
[How]
Add an empty-registry Workaround Manager over block_sequence_state.
Keep the restore image in BSS so the kernel frame stays small, and
reject growth past MAX_HWSS_BLOCK_SEQUENCE_SIZE. Name the committed
state field current_state so the Linux current macro does not expand
it.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Reviewed-by: Jun Lei <jun.lei@amd.com>
Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
3 files changed, 121 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index 58800522dfd9..7338125b117b 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -86,6 +86,7 @@ FILES += core2/dc_core2_init.o FILES += bls_builder/bls_builder.o FILES += bls_builder/dcn401_init_builder.o FILES += bls_executor/bls_executor.o +FILES += workaround_manager/workaround_manager.o AMD_DISPLAY_FILES += $(addprefix $(AMDDALPATH)/dc/, $(FILES)) diff --git a/drivers/gpu/drm/amd/display/dc/workaround_manager/workaround_manager.c b/drivers/gpu/drm/amd/display/dc/workaround_manager/workaround_manager.c new file mode 100644 index 000000000000..067a7069186b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/workaround_manager/workaround_manager.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2026 Advanced Micro Devices, Inc. + */ + +#include "dm_services.h" +#include "workaround_manager/workaround_manager.h" + +static const struct workaround_manager dc2_wam_empty = { + .registry = NULL, + .count = 0, +}; + +/* BSS, not the stack: 64 block_sequence entries exceed the kernel frame limit. */ +static struct block_sequence dc2_wam_saved_steps[DC2_BLS_MAX_STEPS]; + +const struct workaround_manager *dc2_workaround_manager_get(void) +{ + return &dc2_wam_empty; +} + +enum workaround_manager_result workaround_manager_apply( + const struct workaround_manager *wam, + struct block_sequence_state *bls, + const struct workaround_context *ctx) +{ + struct block_sequence *saved_steps = dc2_wam_saved_steps; + enum workaround_manager_result result; + unsigned int saved_num; + unsigned int i; + + if (!wam || !bls || !bls->steps || !bls->num_steps || !ctx || + *bls->num_steps > MAX_HWSS_BLOCK_SEQUENCE_SIZE || + (wam->count && !wam->registry)) + return WAM_INVALID_INPUT; + + /* Snapshot buffer is DC2_BLS_MAX_STEPS; larger built lists stay unmodified. */ + if (*bls->num_steps > DC2_BLS_MAX_STEPS) { + if (!wam->count) + return WAM_OK; + return WAM_INVALID_INPUT; + } + + saved_num = *bls->num_steps; + memmove(saved_steps, bls->steps, + saved_num * sizeof(saved_steps[0])); + + for (i = 0; i < wam->count; i++) { + const struct workaround *wa = &wam->registry[i]; + + if (!wa->enabled) + continue; + if (!wa->is_applicable || !wa->apply) { + memmove(bls->steps, saved_steps, + saved_num * sizeof(saved_steps[0])); + *bls->num_steps = saved_num; + return WAM_INTERNAL_ERROR; + } + if (!wa->is_applicable(bls, ctx)) + continue; + result = wa->apply(bls, ctx); + if (result != WAM_OK || + *bls->num_steps > MAX_HWSS_BLOCK_SEQUENCE_SIZE) { + memmove(bls->steps, saved_steps, + saved_num * sizeof(saved_steps[0])); + *bls->num_steps = saved_num; + if (result != WAM_OK) + return result; + return WAM_SIZE_EXCEEDED; + } + } + + return WAM_OK; +} diff --git a/drivers/gpu/drm/amd/display/dc/workaround_manager/workaround_manager.h b/drivers/gpu/drm/amd/display/dc/workaround_manager/workaround_manager.h new file mode 100644 index 000000000000..4cbadffd6a8b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/workaround_manager/workaround_manager.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright 2026 Advanced Micro Devices, Inc. + */ + +#pragma once + +#include "bls_builder/bls_builder.h" + +enum workaround_manager_result { + WAM_OK, + WAM_INVALID_INPUT, + WAM_SIZE_EXCEEDED, + WAM_INTERNAL_ERROR, +}; + +struct workaround_context { + const struct dc_state *current_state; + const struct dc_state *target; + enum bls_builder_name builder_name; + unsigned int dcn_version; + const struct dc_bug_wa *bug_wa; + const struct dc_debug_options *debug; +}; + +struct workaround { + const char *name; + bool enabled; + bool (*is_applicable)(const struct block_sequence_state *bls, + const struct workaround_context *ctx); + enum workaround_manager_result (*apply)( + struct block_sequence_state *bls, + const struct workaround_context *ctx); +}; + +struct workaround_manager { + const struct workaround *registry; + unsigned int count; +}; + +const struct workaround_manager *dc2_workaround_manager_get(void); + +enum workaround_manager_result workaround_manager_apply( + const struct workaround_manager *wam, + struct block_sequence_state *bls, + const struct workaround_context *ctx); |
