显示核心调试工具

在本节中,你将找到关于从显示角度调试 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 版本在每个 DCN 组件的 DC 文件夹中都有其文件(例如,开发人员可能希望专注于具有 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

计时器

0x800

HW LOCK MGR

0x1000

INBOX1

0x2000

PHY SEQ

0x4000

PSR STATE

0x8000

ZSTATE

0x10000

发射器 CTL

0x20000

面板 CNTL

0x40000

FAMS

0x80000

DPIA

0x100000

SUBVP

0x200000

INBOX0

0x400000

SDP

0x4000000

重放

0x8000000

重放驻留

0x20000000

光标信息

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 等功能相关的错误时,请考虑在重现问题之前启用掩码中的相关位,并在你创建的任何错误报告中附加你从跟踪缓冲区获得的日志。