显示核心调试工具

在本节中,您将找到有关从显示角度调试 amdgpu 驱动程序的有用信息。本页介绍了调试机制和步骤,以帮助您确定某些问题是否与显示代码相关。

缩小显示问题范围

由于显示器是驱动程序的视觉组件,因此通常会看到用户将问题报告为显示问题,而实际上是另一个组件导致的问题。本节旨在帮助用户确定特定问题是由显示组件还是驱动程序的另一部分引起的。

DC dmesg 重要消息

dmesg 日志是要检查的第一个信息来源,amdgpu 通过记录一些有价值的信息来利用此功能。在查找与 amdgpu 相关的问题时,请记住驱动程序的每个组件(例如,smu、PSP、dm 等)都是逐个加载的,并且可以在 dmesg 日志中找到此信息。从这个意义上讲,请查找如下日志片段所示的日志部分

[    4.254295] [drm] initializing kernel modesetting (IP DISCOVERY 0x1002:0x744C 0x1002:0x0E3B 0xC8).
[    4.254718] [drm] register mmio base: 0xFCB00000
[    4.254918] [drm] register mmio size: 1048576
[    4.260095] [drm] add ip block number 0 <soc21_common>
[    4.260318] [drm] add ip block number 1 <gmc_v11_0>
[    4.260510] [drm] add ip block number 2 <ih_v6_0>
[    4.260696] [drm] add ip block number 3 <psp>
[    4.260878] [drm] add ip block number 4 <smu>
[    4.261057] [drm] add ip block number 5 <dm>
[    4.261231] [drm] add ip block number 6 <gfx_v11_0>
[    4.261402] [drm] add ip block number 7 <sdma_v6_0>
[    4.261568] [drm] add ip block number 8 <vcn_v4_0>
[    4.261729] [drm] add ip block number 9 <jpeg_v4_0>
[    4.261887] [drm] add ip block number 10 <mes_v11_0>

从上面的示例中,您可以看到报告 <dm>显示管理器)已加载的行,这意味着显示可能是问题的一部分。如果您没有看到该行,则可能在 amdgpu 加载显示组件之前出现了其他问题,表明我们没有显示问题。

在您确定 DM 已正确加载后,您可以检查正在使用的硬件的显示版本,该版本可以通过使用以下命令从 dmesg 日志中检索

dmesg | grep -i 'display core'

此命令会显示如下消息

[    4.655828] [drm] Display Core v3.2.285 initialized on DCN 3.2

此消息包含两个关键信息

  • DC 版本(例如,v3.2.285):显示开发人员每周都会发布新的 DC 版本,如果用户/开发人员必须根据经过测试的显示代码版本找到一个好的点和一个坏的点,此信息可能是有利的。请记住,从 显示核心页面得知,每周都会使用 IGT 和手动测试对新的显示补丁进行严格测试。

  • DCN 版本(例如,DCN 3.2):DCN 块与硬件世代相关联,DCN 版本传达驱动程序当前正在运行的硬件世代。此信息有助于缩小代码调试范围,因为每个 DCN 版本在 DC 文件夹中都有其每个 DCN 组件的文件(例如,从示例中,开发人员可能希望专注于具有 dcn32 标签的文件/文件夹/函数/结构)。但是,请记住,DC 在不同的 DCN 版本之间重用代码;例如,预计在一个 DCN 中设置的一些回调与另一个 DCN 中的回调相同。总之,仅将 DCN 版本用作指导。

从 dmesg 文件中,也可以通过使用以下命令来获取 ATOM bios 代码

dmesg  | grep -i 'ATOM BIOS'

这将生成如下所示的输出

[    4.274534] amdgpu: ATOM BIOS: 113-D7020100-102

此类信息对于报告非常有用。

避免加载显示核心

有时,可能很难弄清楚是驱动程序的哪个部分导致了问题;如果您怀疑显示不是问题的一部分,并且您的错误场景很简单(例如,某些桌面配置),您可以尝试从等式中删除显示组件。首先,您需要从 dmesg 日志中识别 dm ID;例如,搜索以下日志

[    4.254295] [drm] initializing kernel modesetting (IP DISCOVERY 0x1002:0x744C 0x1002:0x0E3B 0xC8).
[..]
[    4.260095] [drm] add ip block number 0 <soc21_common>
[    4.260318] [drm] add ip block number 1 <gmc_v11_0>
[..]
[    4.261057] [drm] add ip block number 5 <dm>

从上面的示例中可以看出,此特定硬件的 dm id 为 5。接下来,您需要运行以下二进制运算以识别 IP 块掩码

0xffffffff & ~(1 << [DM ID])

在我们的示例中,IP 掩码为

0xffffffff & ~(1 << 5) = 0xffffffdf

最后,要禁用 DC,您只需在引导加载程序中设置以下参数

amdgpu.ip_block_mask = 0xffffffdf

如果您可以在禁用 DC 的情况下启动系统并仍然看到该问题,则意味着您可以将 DC 从等式中排除。但是,如果错误消失,您仍然需要考虑问题中的 DC 部分,并继续缩小问题的范围。在某些情况下,禁用 DC 是不可能的,因为它可能需要使用显示组件来重现问题(例如,玩游戏)。

注意:这可能会导致没有显示输出。

显示闪烁

显示闪烁可能有多种原因;其中之一是 GPU 电源不足或 DPM 开关出现问题。一个很好的第一个通用验证是将 GPU 设置为使用高电压

bash -c "echo high > /sys/class/drm/card0/device/power_dpm_force_performance_level"

上面的命令将 GPU/APU 设置为使用允许的最大功率,这会禁用 DPM 开关。如果强制将 DPM 级别设置为高电平不能解决问题,则问题与电源管理相关的可能性较小。如果问题消失,则很可能涉及到其他组件,并且不应忽略显示,因为这可能是 DPM 问题。从显示方面来看,如果功率增加解决了问题,则值得调试时钟配置和特定配置中使用的管道分割策略。

显示伪像

用户可能会看到一些屏幕伪像,这些伪像可以分为两种不同的类型:局部伪像和一般伪像。局部伪像发生在某些特定区域,例如 UI 窗口的角落周围;如果您看到此类问题,则很有可能是用户空间问题,可能是 Mesa 或类似的问题。一般伪像通常发生在整个屏幕上。它们可能是由于显示参数的驱动程序级别配置错误引起的,但是用户空间也可能导致此问题。识别问题来源的一种方法是在问题发生时拍摄屏幕截图或制作桌面视频捕获;在检查屏幕截图/视频录制后,如果您没有看到任何伪像,则意味着该问题很可能在驱动程序端。如果仍然可以在收集到的数据中看到该问题,则可能是渲染过程中发生的问题,并且显示代码只是获得了已损坏的帧缓冲区。

禁用/启用特定功能

DC 有一个名为 dc_debug_options 的结构,该结构由所有 DCE/DCN 组件根据特定的硬件特性进行静态初始化。此结构通常会方便启动阶段,因为开发人员可以从许多禁用的功能开始,然后单独启用它们。这也是一个重要的调试功能,因为用户可以在调试特定问题时更改它。

例如,dGPU 用户有时会看到一个问题,即在屏幕的某些特定部分会出现水平闪烁的细丝。这可能表明存在子视口问题;在用户确定目标 DCN 后,他们可以将静态初始化的 dc_debug_options 版本中的 force_disable_subvp 字段设置为 true,以查看是否解决了该问题。同样,用户/开发人员也可以尝试关闭 fams2_configenable_single_display_2to1_odm_policy。总之,dc_debug_options 是识别问题的一种有趣形式。

DC 可视确认

显示核心提供了一个名为可视确认的功能,这是一组由驱动程序在扫描输出时添加的条,用于传达某些特定信息。通常,您可以通过使用以下命令来启用此调试选项

echo <N> > /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm

其中 N 是开发人员想要启用的某些特定场景的整数。您将在以下小节中看到其中一些调试案例。

多平面调试

如果要在特定的用户空间应用程序中启用或调试多个平面,则可以利用名为可视确认的调试功能。要启用它,您将需要

echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm

您需要重新加载 GUI 才能看到可视确认。当平面配置更改或发生完全更新时,将在屏幕上绘制的每个硬件平面的底部显示一个彩色条。

  • 颜色指示格式 - 例如,红色是 AR24,绿色是 NV12

  • 条的高度指示平面的索引

  • 如果两个高度不同的条覆盖同一平面,则可以观察到管道分割

考虑视频播放的情况,其中在一个特定平面中播放视频,而桌面在另一个平面中绘制。根据管道分割配置,视频平面的底部应具有一个或两个绿色条。

  • 应该没有任何视觉损坏

  • 应该没有任何下溢或屏幕闪烁

  • 应该没有任何黑屏

  • 应该没有任何光标损坏

  • 在窗口切换或调整大小时,多个平面可能会短暂禁用,但在操作完成后应该会恢复。

管线分割调试

有时我们需要调试DCN是否正确分割管线,可视化确认在这种情况下也很方便。类似于MPO的情况,您可以使用以下命令启用可视化确认。

echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm

在这种情况下,如果您有管线分割,您会在显示器底部看到一个小的红色条,覆盖整个显示宽度,另一个条覆盖第二个管线。换句话说,您将在第二个管线中看到一个稍高的条。

DTN 调试

DC (DCN) 提供了广泛的日志,其中转储了我们硬件配置的多个详细信息。通过debugfs,您可以使用显示测试下一步 (DTN) 日志捕获这些状态值,该日志可以通过debugfs使用以下方式捕获:

cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log

由于此日志会根据DCN状态进行更新,您还可以使用类似以下命令实时跟踪更改:

sudo watch -d cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log

当报告与DC相关的错误时,请考虑在重现错误之前和之后附加此日志。

收集固件信息

报告问题时,固件信息非常重要,因为它有助于调试。要获取所有固件信息,请使用以下命令:

cat /sys/kernel/debug/dri/0/amdgpu_firmware_info

从显示的角度来看,请注意DMCU和DMCUB的固件。

DMUB 固件调试

有时,dmesg 日志是不够的。如果某个功能主要在 DMUB 固件中实现,则尤其如此。在这种情况下,当出现问题时,我们在 dmesg 中看到的只是一些通用的超时错误。因此,为了获得更多相关信息,我们可以通过启用 amdgpu_dm_dmub_trace_mask 中的相关位来跟踪 DMUB 命令。

目前,我们支持跟踪以下组

跟踪组

名称

掩码值

信息

0x1

IRQ SVC

0x2

VBIOS

0x4

寄存器

0x8

PHY DBG

0x10

PSR

0x20

AUX

0x40

SMU

0x80

MALL

0x100

ABM

0x200

ALPM

0x400

TIMER

0x800

HW LOCK MGR

0x1000

INBOX1

0x2000

PHY SEQ

0x4000

PSR STATE

0x8000

ZSTATE

0x10000

TRANSMITTER CTL

0x20000

PANEL CNTL

0x40000

FAMS

0x80000

DPIA

0x100000

SUBVP

0x200000

INBOX0

0x400000

SDP

0x4000000

REPLAY

0x8000000

REPLAY RESIDENCY

0x20000000

CURSOR INFO

0x80000000

IPS

0x100000000

注意:并非所有 ASIC 都支持所有列出的跟踪组

因此,要仅启用 PSR 跟踪,您可以使用以下命令:

# echo 0x8020 > /sys/kernel/debug/dri/0/amdgpu_dm_dmub_trace_mask

然后,您需要启用将跟踪事件记录到缓冲区,您可以使用以下命令执行此操作:

# echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en

最后,在您能够重现您尝试调试的问题之后,您可以使用以下命令禁用跟踪并读取跟踪日志:

# echo 0 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
# cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_tracebuffer

因此,当报告与 PSR 和 ABM 等功能相关的错误时,请考虑在重现问题之前在掩码中启用相关位,并在您创建的任何错误报告中附加从跟踪缓冲区获得的日志。