Commit 26ec3cca authored by Rodrigo Siqueira's avatar Rodrigo Siqueira Committed by Alex Deucher

drm/amd/display: Fix warning caused by an attempt to configure a non-otg master

When booting the system with DCN401, the driver adds the following dmesg
warning:

WARNING: CPU: 8 PID: 175 at
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_resource.c:1923
resource_get_opp_heads_for_otg_master+0x13/0x70 [amdgpu]

Modules linked in: amdgpu(+) hid_generic amdxcp i2c_algo_bit
drm_ttm_helper ttm drm_exec gpu_sched drm_suballoc_helper drm_buddy
drm_display_helper drm_kms_helper usbhid hid drm i2c_piix4 ahci igc
libahci video wmi

CPU: 8 PID: 175 Comm: systemd-udevd Not tainted 6.8.0-EXTRA-PROMO-MAY-29+ #66
Hardware name: ASUS System Product Name/TUF GAMING X570-PRO (WI-FI),
BIOS 4021 08/10/2021

RIP: 0010:resource_get_opp_heads_for_otg_master+0x13/0x70 [amdgpu]
Code: 8b 66 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 0f 1f 44 00 00 55 48 83 bf f8 07 00 00 00 48 89 e5 74 0c <0f> 0b 31
f6 89 f0 5d e9 0c 65 01 e5 48 83 bf e0 07 00 00 00 75 ea

RSP: 0018:ffffa5f000816ed8 EFLAGS: 00010246
[...]
PKRU: 55555554
Call Trace:
 <TASK>
 ? show_regs+0x65/0x70
 ? __warn+0x85/0x160
 ? resource_get_opp_heads_for_otg_master+0x13/0x70 [amdgpu]
 ? report_bug+0x192/0x1c0
 ? handle_bug+0x44/0x90
 ? exc_invalid_op+0x18/0x70
[...]

This warning is triggered by a check in the function
resource_get_opp_heads_for_otg_master that validates if the request
operation is in a master OTG pipe; if not, the warning above is
displayed. In other words, another part of the code might be calling
this function in a non-OTG master pipe context, resulting in the log
message.

The reason the ASSERT was triggered is that the current state wasn't
updated after applying the context to the hardware. This means that the
update_dsc_for_odm_change might be called from a non-OTG-MASTER. To
prevent this, it's crucial to check if the current reference is pointing
to an OTG master before operate in the old OTG master reference. If it's
not, the function must set the old OTG reference to NULL and avoid
calling resource_get_opp_heads_for_otg_master before the context is
updated.
Reviewed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Co-developed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b62ec97d
...@@ -1561,16 +1561,28 @@ static void update_dsc_for_odm_change(struct dc *dc, struct dc_state *context, ...@@ -1561,16 +1561,28 @@ static void update_dsc_for_odm_change(struct dc *dc, struct dc_state *context,
struct pipe_ctx *new_pipe; struct pipe_ctx *new_pipe;
struct pipe_ctx *old_opp_heads[MAX_PIPES]; struct pipe_ctx *old_opp_heads[MAX_PIPES];
struct dccg *dccg = dc->res_pool->dccg; struct dccg *dccg = dc->res_pool->dccg;
struct pipe_ctx *old_otg_master = struct pipe_ctx *old_otg_master;
&dc->current_state->res_ctx.pipe_ctx[otg_master->pipe_idx]; int old_opp_head_count = 0;
int old_opp_head_count = resource_get_opp_heads_for_otg_master(
old_otg_master, &dc->current_state->res_ctx, old_otg_master = &dc->current_state->res_ctx.pipe_ctx[otg_master->pipe_idx];
old_opp_heads);
if (resource_is_pipe_type(old_otg_master, OTG_MASTER)) {
old_opp_head_count = resource_get_opp_heads_for_otg_master(old_otg_master,
&dc->current_state->res_ctx,
old_opp_heads);
} else {
// DC cannot assume that the current state and the new state
// share the same OTG pipe since this is not true when called
// in the context of a commit stream not checked. Hence, set
// old_otg_master to NULL to skip the DSC configuration.
old_otg_master = NULL;
}
if (otg_master->stream_res.dsc) if (otg_master->stream_res.dsc)
dcn32_update_dsc_on_stream(otg_master, dcn32_update_dsc_on_stream(otg_master,
otg_master->stream->timing.flags.DSC); otg_master->stream->timing.flags.DSC);
if (old_otg_master->stream_res.dsc) { if (old_otg_master && old_otg_master->stream_res.dsc) {
for (i = 0; i < old_opp_head_count; i++) { for (i = 0; i < old_opp_head_count; i++) {
old_pipe = old_opp_heads[i]; old_pipe = old_opp_heads[i];
new_pipe = &context->res_ctx.pipe_ctx[old_pipe->pipe_idx]; new_pipe = &context->res_ctx.pipe_ctx[old_pipe->pipe_idx];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment