TODO 列表

本节包含内核 DRM 图形子系统中一些较小的清理任务列表,它们可作为新手项目,或在悠闲的雨天完成。

难度

为了方便起见,任务分为不同等级

入门:DRM 子系统入门的好任务。

中级:需要一些 DRM 子系统工作经验,或一些特定 GPU/显示图形知识的任务。对于调试问题,最好有相关的硬件(或设置好的虚拟驱动程序)可供测试。

高级:需要相当好地理解 DRM 子系统和图形主题的棘手任务。通常需要相关的硬件进行开发和测试。

专家:仅在您已成功完成一些棘手的重构并且是特定领域的专家时才尝试这些任务

子系统范围重构

移除自定义 dumb_map_offset 实现

所有基于 GEM 的驱动程序都应使用 drm_gem_create_mmap_offset()。审查每个单独的驱动程序,确保它能与通用实现配合使用(各种实现中有很多过时的锁定遗留问题),然后将其移除。

联系人:Simona Vetter,相关驱动维护者

级别:中级

将现有 KMS 驱动程序转换为原子模式设置

3.19 版本拥有原子模式设置接口和辅助函数,因此驱动程序现在可以进行转换。Wayland 或 Android 上的 Surfaceflinger 等现代合成器确实需要原子模式设置接口,因此这一切都关乎光明的未来。

有一个原子转换指南[1],您只需一个尚未转换的 GPU 即可。“原子模式设置设计概述”系列[2] [3]在 LWN.net 上可能也会有所帮助。

作为转换的一部分,驱动程序还需要转换为通用平面(这意味着将主平面和光标暴露为正确的平面对象)。但这通过直接使用新的原子辅助驱动回调更容易实现。

联系人:Simona Vetter,相关驱动维护者

级别:高级

清理平面周围的裁剪坐标混淆

我们有一个辅助函数 drm_plane_helper_check_update() 可以正确处理此问题,但它没有被一致使用。这应该得到修复,最好是在原子辅助函数中(然后驱动程序移到裁剪坐标)。可能辅助函数也应该从 drm_plane_helper.c 移到原子辅助函数,以避免混淆——该文件中的其他辅助函数都是已弃用的旧版辅助函数。

联系人:Ville Syrjälä, Simona Vetter, 驱动程序维护者

级别:高级

改进平面 atomic_check 辅助函数

除了上面提到的裁剪坐标外,当前的辅助函数还有一些不理想的地方

  • 无论平面启用还是禁用,都会调用 drm_plane_helper_funcs->atomic_check。充其量这似乎会混淆驱动程序,最坏的情况是当平面在没有 CRTC 的情况下禁用时,它们会崩溃。唯一的特殊处理是重置平面状态结构中的值,这应该移到 drm_plane_funcs->atomic_duplicate_state 函数中。

  • 一旦完成,辅助函数就可以停止为禁用的平面调用 ->atomic_check。

  • 然后我们可以遍历所有驱动程序,并移除对 plane_state->fb 和 plane_state->crtc 或多或少混淆的检查。

联系人:Simona Vetter

级别:高级

将早期原子驱动程序转换为异步提交辅助函数

在原子模式设置辅助功能推出的第一年,它们不支持异步/非阻塞提交,每个驱动程序都必须手动实现。现在这已修复,但仍有一堆现有驱动程序可以轻松转换为新的基础设施。

辅助功能的一个问题是它们要求驱动程序正确处理原子提交的完成事件。但修复这些错误无论如何都是好的。

与此有些相关的是 legacy_cursor_update 技巧,它应该在仍然查看该标志的驱动程序中,用辅助功能中新的 atomic_async_check/commit 功能取代。

联系人:Simona Vetter,相关驱动维护者

级别:高级

重命名 drm_atomic_state

KMS 框架对 state 概念使用了两个略有不同的定义。对于给定对象(平面、CRTC、编码器等,即 drm_$OBJECT_state),状态是该对象的整个状态。然而,在设备级别,drm_atomic_state 指的是有限数量对象的状态更新。

该状态不是整个设备状态,而只是该设备中某些对象的完整状态。这会让新手感到困惑,drm_atomic_state 应该重命名为更清晰的名称,例如 drm_atomic_commit

除了重命名结构本身,这还意味着重命名一些相关函数(drm_atomic_state_allocdrm_atomic_state_getdrm_atomic_state_putdrm_atomic_state_init__drm_atomic_state_free 等)。

联系人:Maxime Ripard <mripard@kernel.org>

级别:高级

原子 KMS 的影响

drm_atomic_helper.c 提供了一批函数,这些函数在新的原子驱动程序接口之上实现了旧版 IOCTL。这对于驱动程序的逐步转换非常有用,但不幸的是语义不匹配有点严重。因此,还需要一些后续工作来调整函数接口以修复这些问题

  • 原子操作需要锁获取上下文。目前,这通过一些糟糕的技巧隐式传递,并且它也在后台用 GFP_NOFAIL 分配。所有旧版路径都需要开始在堆栈上显式分配获取上下文,然后也将其显式传递给驱动程序,以便旧版-在-原子函数可以使用它们。

    除了一些驱动代码,这已经完成。此任务应通过在 drm_modeset_lock_all() 中添加 WARN_ON(!drm_drv_uses_atomic_modeset) 来完成。

  • 许多 vtable 钩子现在位于错误的位置:DRM 在核心 vfunc 表(名为 drm_foo_funcs)之间进行拆分,这些表用于实现用户空间 ABI。然后是辅助库的可选钩子(名为 drm_foo_helper_funcs),它们纯粹用于内部使用。其中一些钩子应该从 _funcs 移到 _helper_funcs,因为它们不属于核心 ABI。在 drm_crtc.h 中,每个此类情况的 kerneldoc 中都有一个 FIXME 注释。

联系人:Simona Vetter

级别:中级

从 GEM 驱动程序中移除 dev->struct_mutex

dev->struct_mutex 是旧版 DRM 大锁,它感染了所有东西。现在在现代驱动程序中,唯一强制使用的部分是序列化 GEM 缓冲区对象销毁。不幸的是,这意味着驱动程序必须根据上下文跟踪该锁并调用 unreferenceunreference_locked

自内核 4.8 以来,核心 GEM 不再需要 struct_mutex,并且对于完全 struct_mutex 免费的驱动程序,有一个 GEM 对象 free 回调。

对于需要 struct_mutex 的驱动程序,它应该替换为驱动程序私有锁。棘手的部分是 BO 自由函数,因为它们不能再可靠地获取该锁。相反,状态需要用合适的从属锁保护,或者一些清理工作推送到工作线程。对于性能关键型驱动程序,使用更细粒度的每缓冲区对象和每上下文锁定方案可能更好。目前只有 msmi915 驱动程序使用 struct_mutex

联系人:Simona Vetter,相关驱动维护者

级别:高级

将缓冲区对象锁定移动到 dma_resv_lock()

许多驱动程序都有自己的每对象锁定方案,通常使用 mutex_lock()。这会导致缓冲区共享出现各种问题,因为取决于哪个驱动程序是导出者和导入者,锁定层次结构是反向的。

为了解决这个问题,我们需要一个标准的每对象锁定机制,即 dma_resv_lock()。此锁需要作为最外层锁调用,并移除所有其他驱动程序特定的每对象锁。问题是,由于 struct dma_buf 缓冲区共享,推出实际的锁定契约更改是一个标志日。

级别:专家

将日志记录转换为带 drm_device 参数的 drm_* 函数

对于可能存在多个实例的驱动程序,有必要在日志中区分它们。由于 DRM_INFO/WARN/ERROR 不这样做,驱动程序使用 dev_info/warn/err 来进行区分。我们现在有 drm 打印函数的 drm_* 变体,因此我们可以开始将这些驱动程序转换回使用 drm 格式的特定日志消息。

在开始此转换之前,请联系相关维护者,以确保您的工作将被合并——并非所有人都同意 DRM dmesg 宏更好。

联系人:Sean Paul,您计划转换的驱动程序的维护者

级别:入门

将驱动程序转换为使用简单模式设置暂停/恢复

大多数使用 drm_atomic_helper_suspend/resume() 的驱动程序(i915 和 nouveau 除外)可能可以转换为使用 drm_mode_config_helper_suspend/resume()。此外,在较旧的原子模式设置驱动程序中,仍然存在开放编码的原子暂停/恢复代码版本。

联系人:您计划转换的驱动程序的维护者

级别:中级

在没有 fbdev 的情况下重新实现 drm_fbdev_fb_ops 中的函数

drm_fbdev_fb_ops 中的许多回调函数可以受益于在不依赖 fbdev 模块的情况下重写。一些辅助函数可以进一步受益于使用 struct iosys_map 而不是原始指针。

联系人:Thomas Zimmermann <tzimmermann@suse.de>,Simona Vetter

级别:高级

基准测试和优化 blitting 和格式转换函数

快速绘制到显示内存对于许多应用程序的性能至关重要。

至少在 x86-64 上,sys_imageblit() 明显比 cfb_imageblit() 慢,尽管两者使用相同的位块传输算法,并且后者是为 I/O 内存编写的。结果表明 cfb_imageblit() 使用 movl 指令,而 sys_imageblit 显然没有。这似乎是 gcc 优化器的问题。DRM 的格式转换辅助函数可能也存在类似问题。

基准测试并优化 fbdev 的 sys_() 辅助函数和 DRM 的格式转换辅助函数。在可以进一步优化的情况下,也许可以实现不同的算法。对于微优化,显式使用 movl/movq 指令。这可能需要特定于架构的辅助函数(例如,storel() storeq())。

联系人:Thomas Zimmermann <tzimmermann@suse.de>

级别:中级

drm_framebuffer_funcs 和 drm_mode_config_funcs.fb_create 清理

更多的驱动程序可以切换到 drm_gem_framebuffer 辅助函数。各种障碍

  • 首先需要切换到使用 drm_atomic_helper_dirtyfb 的通用脏跟踪代码(例如 qxl)。

  • 需要切换到 drm_fbdev_generic_setup(),否则许多自定义 fb 设置代码无法删除。

  • 需要切换到 drm_gem_fb_create(),因为现在 drm_gem_fb_create() 会检查原子驱动程序的有效格式。

  • 许多驱动程序子类化了 drm_framebuffer,我们需要一个与各种 drm_gem_fb_create 函数兼容的嵌入版本。可能根据需要命名为 drm_gem_fb_create/_with_dirty/_with_funcs。

联系人:Simona Vetter

级别:中级

通用 fbdev defio 支持

fbdev 核心中的 defio 支持代码有一些非常具体的要求,这意味着驱动程序需要有一个用于 fbdev 的特殊帧缓冲。主要问题是它使用了 struct page 本身中的一些字段,这会破坏 shmem gem 对象(以及其他东西)。为了支持 defio,受影响的驱动程序需要使用影子缓冲区,这可能会增加 CPU 和内存开销。

可能的解决方案是在 drm fbdev 仿真中编写我们自己的 defio mmap 代码。它需要完全封装现有的 mmap ops,在完成写保护/mkwrite 技巧后转发所有内容

  • 在 drm_fbdev_fb_mmap 辅助函数中,如果我们需要 defio,则将默认页面保护更改为写保护,如下所示

    vma->vm_page_prot = pgprot_wrprotect(vma->vm_page_prot);
    
  • 设置 mkwrite 和 fsync 回调,其实现类似于核心 fbdev defio 内容。这些都应该在纯 ptes 上工作,它们实际上不需要 struct page。uff。这些都应该在纯 ptes 上工作,它们实际上不需要 struct page。

  • 在单独的结构中跟踪脏页(每个页面一位的位域应该可以),以避免破坏 struct page。

最好也为此添加一些 igt 测试用例。

联系人:Simona Vetter,Noralf Tronnes

级别:高级

连接器注册/注销修复

  • 对于大多数连接器,直接从驱动代码调用 drm_connector_register/unregister 是无操作的,drm_dev_register/unregister 已经处理了这个问题。我们可以删除所有这些调用。

  • 对于 dp 驱动程序来说,情况有点复杂,因为我们在调用 drm_dp_aux_register 时需要注册连接器。通过改为调用 drm_dp_aux_init,并将实际注册移动到 kerneldoc 中建议的 late_register 回调来解决此问题。

级别:中级

移除加载/卸载回调

结构体 &drm_driver 中的 load/unload 回调函数非常像中间层,此外由于历史原因,它们在设置 &drm_driver 结构和调用 drm_dev_register() 之间弄错了顺序(而且我们无法修复)。

  • 重新设计驱动程序,使其不再使用加载/卸载回调,而是将加载/卸载序列直接编码到驱动程序的 probe 函数中。

  • 一旦所有驱动程序都已转换,就移除加载/卸载回调。

联系人:Simona Vetter

级别:中级

将 drm_detect_hdmi_monitor() 替换为 drm_display_info.is_hdmi

一旦 EDID 被解析,显示器的 HDMI 支持信息就可以通过 drm_display_info.is_hdmi 获得。许多驱动程序仍然调用 drm_detect_hdmi_monitor() 来获取相同的信息,效率较低。

审计每个调用 drm_detect_hdmi_monitor() 的驱动程序,并在适用时切换到 drm_display_info.is_hdmi。

联系人:Laurent Pinchart,相关驱动维护者

级别:中级

合并自定义驱动模式设置属性

在原子模式设置出现之前,许多驱动程序都在创建自己的属性。原子模式设置带来了其中一个要求,即不应使用自定义的、特定于驱动程序的属性。

对于此任务,我们的目标是引入核心辅助函数或重用现有函数(如果可用)

一个未经确认的快速示例列表。

引入核心辅助函数:- 音频 (amdgpu, intel, gma500, radeon) - 亮度, 对比度等 (armada, nouveau) - 仅叠加层 (?) - 广播 rgb (gma500, intel) - 色度键 (armada, nouveau, rcar) - 仅叠加层 (?) - 抖动 (amdgpu, nouveau, radeon) - 驱动程序之间不同 - underscan 系列 (amdgpu, radeon, nouveau)

已在核心中:- 色彩空间 (sti) - 电视格式名称,增强 (gma500, intel) - 电视过扫描,边距等 (gma500, intel) - zorder (omapdrm) - 与 zpos 相同 (?)

联系人:Emil Velikov,相关驱动维护者

级别:中级

在整个代码库中使用 struct iosys_map

指向共享设备内存的指针存储在 struct iosys_map 中。每个实例都知道它是指向系统内存还是 I/O 内存。大多数 DRM 范围的接口已转换为使用 struct iosys_map,但实现通常仍使用原始指针。

任务是在合理的地方使用 struct iosys_map

联系人:Thomas Zimmermann <tzimmermann@suse.de>,Christian König,Simona Vetter

级别:中级

审查所有驱动程序,确保 struct drm_mode_config.{max_width,max_height} 设置正确

struct drm_mode_config.{max_width,max_height} 中的值描述了支持的最大帧缓冲大小。它是虚拟屏幕大小,但许多驱动程序将其视为物理分辨率的限制。

最大宽度取决于硬件的最大扫描线间距。最大高度取决于可寻址视频内存的数量。审查所有驱动程序,以将字段初始化为正确的值。

联系人:Thomas Zimmermann <tzimmermann@suse.de>

级别:中级

在所有 fbdev 驱动程序中请求内存区域

旧/古老的 fbdev 驱动程序没有正确请求它们的内存。遍历这些驱动程序并添加代码以请求驱动程序使用的内存区域。这需要添加对 request_mem_region()、pci_request_region() 或类似函数的调用。尽可能使用辅助函数进行托管清理。有问题的地方包括具有 VGA 等独占范围的硬件。VGA16fb 不按预期请求范围。驱动程序在这方面非常糟糕,并且过去 DRM 和 fbdev 驱动程序之间存在冲突。尽管如此,这是正确的做法。

联系人:Thomas Zimmermann <tzimmermann@suse.de>

级别:入门

移除驱动程序对 FB_DEVICE 的依赖

许多 fbdev 驱动程序通过 sysfs 提供属性,因此依赖于 CONFIG_FB_DEVICE 的选择。审查每个驱动程序,并尝试使任何对 CONFIG_FB_DEVICE 的依赖可选。至少,驱动程序中的相应代码可以通过 ifdef CONFIG_FB_DEVICE 进行条件化。并非所有驱动程序都能够删除 CONFIG_FB_DEVICE。

联系人:Thomas Zimmermann <tzimmermann@suse.de>

级别:入门

移除 panel-simple 和 panel-edp 中 remove/shutdown 中的 disable/unprepare

commit d2aacaf07395(“drm/panel: 在 drm_panel 中检查是否已准备/启用”)开始,我们在 drm_panel 核心中有一个检查,以确保没有人重复调用 prepare/enable/disable/unprepare。最终,这可能应该变成 WARN_ON() 或以某种方式使其更响亮。

目前,我们预计在使用 panel-simple 和 panel-edp 时,仍然可能会在 drm_panel 核心中遇到警告。由于这些面板驱动程序与许多不同的 DRM 模式设置驱动程序一起使用,因此它们在关闭时仍然会额外努力地禁用/取消准备面板本身。具体来说,如果面板驱动程序在 DRM 模式设置驱动程序 _之前_ 关闭,并且 DRM 模式设置驱动程序在其自己的 shutdown() 回调中正确调用 drm_atomic_helper_shutdown(),我们仍然可能会遇到这些警告。在这种情况下,可以通过使用类似设备链接的东西来避免警告,以确保面板在 DRM 模式设置驱动程序之后关闭。

一旦所有 DRM 模式设置驱动程序都已知会正确关闭,就应该移除 panel-simple 和 panel-edp 中 remove/shutdown 中多余的 disable/unprepare 调用,并将此 TODO 项标记为完成。

联系人:Douglas Anderson <dianders@chromium.org>

级别:中级

逐步淘汰 mipi_dsi_*_write_seq()

mipi_dsi_generic_write_seq() 和 mipi_dsi_dcs_write_seq() 不直观,因为如果出现错误,它们会从调用者的函数中返回。我们应该将所有调用者改为使用 mipi_dsi_generic_write_seq_multi()mipi_dsi_dcs_write_seq_multi() 宏。

一旦所有调用者都已转换,这些宏及其调用的函数 mipi_dsi_generic_write_chatty()mipi_dsi_dcs_write_buffer_chatty() 可能就可以移除了。或者,如果有人觉得 _multi() 变体对于某些用例来说过于冗余,我们可以保留 mipi_dsi_*_write_seq() 变体,但更改它们不再从调用者处返回。

联系人:Douglas Anderson <dianders@chromium.org>

级别:入门

核心重构

使 panic 处理工作

这是一项非常多样的任务,包含许多小部分

  • 恐慌路径目前无法测试,导致不断中断。这里的主要问题是恐慌可能从 hardirq 上下文触发,因此所有与恐慌相关的回调都可以在 hardirq 上下文运行。如果我们可以通过 drm debugfs 文件触发调用来测试 fbdev 辅助代码和驱动程序代码,那就太棒了。hardirq 上下文可以通过使用 IPI 到本地处理器来实现。

  • 不同恐慌处理程序之间存在巨大混乱。DRM fbdev 仿真辅助程序有自己的(早已移除),但除此之外,fbcon 代码本身也有一个。我们需要确保它们停止相互干扰。这通过在 DRM fbdev 仿真辅助程序的各种入口点检查 oops_in_progress 来解决。这里更干净的方法是将 fbcon 切换到 线程 printk 支持

  • drm_can_sleep() 是一团糟。它在正常操作中隐藏了真正的 bug,并且不是恐慌路径的完整解决方案。我们需要确保它只在真正发生恐慌时才返回 true,并修复所有后续问题。

  • 恐慌处理程序绝不能休眠,这也意味着它永远不能 mutex_lock()。它也不能无条件地获取任何其他锁,甚至自旋锁(因为 NMI 和 hardirq 也会导致恐慌)。我们需要确保不调用此类路径,或者尝试锁定所有内容。这确实很棘手。

  • 一个干净的解决方案是在 KMS 中完全独立的恐慌输出支持,绕过当前的 fbcon 支持。参见 [PATCH v2 0/3] drm: Add panic handling

  • 将实际的 oops 和前面的 dmesg 编码到 QR 码中可能有助于解决令人头疼的“重要内容已滚动过去”问题。参见 [RFC][PATCH] Oops messages transfer using QR codes 以获取可重用的一些示例代码。

联系人:Simona Vetter

级别:高级

清理 debugfs 支持

它存在一些问题

  • 将驱动程序转换为支持 drm_debugfs_add_files() 函数而不是 drm_debugfs_create_files() 函数。

  • 通过为连接器和 CRTC 也推出相同的 debugfs 预注册基础设施来改进后期注册 debugfs。这样,驱动程序就不再需要将其设置代码分成 init 和 register。

  • 我们可能希望在核心中直接支持 crtc/连接器以及其他 kms 对象上的 debugfs 文件。这些对象的 func 中甚至有 drm_print 支持来转储 kms 状态,所以一切都在那里。然后 ->show() 函数显然应该为您提供指向正确对象的指针。

  • 我们拥有的 drm_driver->debugfs_init 钩子只是旧中间层加载序列的遗物。DRM debugfs 应该更像 sysfs,您可以在任何时候为对象创建属性/文件,核心负责在注册/注销时发布/取消发布所有文件。驱动程序不应该担心这些技术细节,修复此问题(以及 drm_minor->drm_device 移动)将允许我们移除 debugfs_init。

联系人:Simona Vetter

级别:中级

对象生命周期修复

这里有两个相关问题

  • 清理各种 ->destroy 回调,这些回调通常都是相同的简单代码。

  • 许多驱动程序错误地使用 devm_kzalloc 分配 DRM 模式设置对象,这导致驱动程序卸载时出现使用后释放问题。即使对于集成在 SoC 上的硬件驱动程序,由于 EPROBE_DEFERRED 回退,这也可能是严重的问题。

这两个问题都可以通过切换到 drmm_kzalloc() 以及提供的各种便捷包装器来解决,例如 drmm_crtc_alloc_with_planes()drmm_universal_plane_alloc() 等等。

联系人:Simona Vetter

级别:中级

从 dma-buf 导入中移除自动页面映射

导入 dma-bufs 时,dma-buf 和 PRIME 框架会自动将导入的页面映射到导入者的 DMA 区域。drm_gem_prime_fd_to_handle()drm_gem_prime_handle_to_fd() 要求导入者即使从不执行实际的设备 DMA,而只通过 dma_buf_vmap() 进行 CPU 访问,也要调用 dma_buf_attach()。这对于不支持 DMA 操作的 USB 设备来说是一个问题。

为了解决这个问题,应从缓冲区共享代码中移除自动页面映射。修复这个问题有点复杂,因为导入/导出缓存也与 &drm_gem_object.import_attach 绑定。同时,只要 USB 主机控制器设备支持 DMA,我们就可以通过找出 USB 主机控制器设备来解决 USB 设备的问题。否则,导入仍然可能不必要地失败。

联系人:Thomas Zimmermann <tzimmermann@suse.de>,Simona Vetter

级别:高级

更好的测试

使用内核单元测试 (KUnit) 框架添加单元测试

KUnit 为 Linux 内核中的单元测试提供了一个通用框架。拥有一套测试套件可以更早地发现回归。

第一个单元测试的好候选者是 drm_format_helper.c 中的格式转换辅助函数。

联系人:Javier Martinez Canillas <javierm@redhat.com>

级别:中级

清理和文档化以前的 selftests 套件

一些 KUnit 测试套件(drm_buddy、drm_cmdline_parser、drm_damage_helper、drm_format、drm_framebuffer、drm_dp_mst_helper、drm_mm、drm_plane_helper 和 drm_rect)是以前的 selftest 套件,它们在 KUnit 首次引入时就已转换为 KUnit。

这些套件文档不足,并且目标与单元测试可能有所不同。尝试识别这些套件中的每个测试实际测试什么,是否适合单元测试,如果不是则删除,如果是则文档化,这将非常有帮助。

联系人:Maxime Ripard <mripard@kernel.org>

级别:中级

为 DRM 启用 trinity

并修复其产生的问题。应该会非常有趣……

级别:高级

使 i-g-t 中的 KMS 测试通用化

i915 驱动团队为 i915 DRM 驱动维护了一个广泛的测试套件,包括大量针对模式设置 API 边缘情况的测试用例。如果这些测试(至少那些不依赖于 Intel 特定 GEM 功能的测试)能够运行在任何 KMS 驱动程序上,那将是极好的。

在非 i915 上运行 i-g-t 测试的基础工作已经完成,现在缺少的是大规模转换。对于模式设置测试,我们还需要一些基础设施来使用哑缓冲区进行无平铺缓冲区,以便能够运行所有非 i915 特定模式设置测试。

级别:高级

扩展虚拟测试驱动程序 (VKMS)

更多详细信息请参阅 VKMS 文档。这是一个理想的实习任务,因为它只需要一个虚拟机,并且可以根据可用时间进行调整。

级别:详见

背光重构

背光驱动有三重启用/禁用状态,这有点过度。计划修复此问题

  1. 在所有地方推出 backlight_enable()backlight_disable() 辅助函数。这已经开始了。

  2. 总而言之,只看上述辅助函数设置的三个状态位中的一个。

  3. 移除另外两个状态位。

联系人:Simona Vetter

级别:中级

驱动程序特定

AMD DC 显示驱动程序

AMD DC 是从 Vega 开始的 AMD 设备的显示驱动程序。清理工作已经取得了很大进展,但仍有大量工作要做。

任务详情请参阅 drivers/gpu/drm/amd/display/TODO。

联系人:Harry Wentland,Alex Deucher

启动画面

现在已经有支持内部 DRM 客户端的机制,这使得可以继续进行之前因针对 fbdev 编写而被拒绝的启动画面工作。

联系人:Sam Ravnborg

级别:高级

多内部面板设备的亮度处理

在 x86/ACPI 设备上,可以有多个背光固件接口:(ACPI)视频、供应商特定和其他。以及 KMS 驱动程序直接/本机(PWM)寄存器编程。

为了处理这个问题,在 x86/ACPI 上使用的背光驱动程序会调用 acpi_video_get_backlight_type(),它具有启发式(+怪癖)来选择要使用的背光接口;并且与返回类型不匹配的背光驱动程序将不会注册自己,以便只注册一个背光设备(在单个 GPU 设置中,见下文)。

目前这或多或少地假设系统上只有一个(内部)面板。

在具有 2 个面板的系统上,这可能是一个问题,具体取决于 acpi_video_get_backlight_type() 选择的接口

  1. 原生:在这种情况下,KMS 驱动程序应该知道哪个背光设备属于哪个输出,因此一切都应该正常工作。

  2. 视频:这确实支持控制多个背光,但需要做一些工作才能获得输出 <-> 背光设备映射

以上假设两个面板都需要相同的背光接口类型。在具有多个面板的系统上,如果两个面板需要不同类型的控制,情况就会崩溃。例如,一个面板需要 ACPI 视频背光控制,而另一个面板使用原生背光控制。目前在这种情况下,根据 acpi_video_get_backlight_type() 的返回值,只会注册两个所需背光设备中的一个。

如果这种情况(理论上)出现,那么支持它将需要一些工作。一个可能的解决方案是将设备和连接器名称传递给 acpi_video_get_backlight_type(),以便它可以处理这个问题。

注意,在某种程度上,我们已经有用户空间看到两个面板的情况,在带有多路复用器的双 GPU 笔记本电脑设置中。在这些系统上,我们可能会看到两个原生背光设备;或两个原生背光设备。

用户空间已经有代码可以处理这个问题,通过检测相关面板是否活跃(即 GPU 和面板之间的多路复用器指向哪个方向),然后使用该背光设备。然而,这里的用户空间非常假设只有一个面板。它只选择两个背光设备中的一个,然后只使用那一个。

请注意,我所知道的所有用户空间代码目前都硬编码为假设单个面板。

在最近更改为不为一个面板(在单个 GPU 笔记本电脑上)注册多个(例如,视频 + 本机)/sys/class/backlight 设备之前,用户空间会看到多个背光设备都在控制同一个背光。

为了解决这个问题,用户空间必须始终在 /sys/class/backlight 下选择一个首选设备,并忽略其他设备。因此,为了支持多个面板上的亮度控制,用户空间也需要更新。

目前计划通过向 drm_connector 面板对象添加“显示亮度”属性,允许通过 KMS API 进行亮度控制。这解决了 /sys/class/backlight API 的许多问题,包括无法将 sysfs 背光设备映射到特定连接器。任何用于在具有多个面板的设备上添加亮度支持的用户空间更改都应该基于这种新的 KMS 属性。

联系人:Hans de Goede

级别:高级

缓冲区龄或其他缓冲区损伤累积算法

进行每缓冲区上传的驱动程序需要缓冲区损伤处理(而不是像进行每平面或每 CRTC 上传的驱动程序那样的帧损伤),但目前没有支持获取缓冲区龄或任何其他损伤累积算法。

因此,如果附加到平面的帧缓冲自上次翻页以来发生更改,损伤辅助函数就会回退到完整的平面更新。驱动程序将 &drm_plane_state.ignore_damage_clips 设置为 true,以指示 drm_atomic_helper_damage_iter_init()drm_atomic_helper_damage_iter_next() 辅助函数应忽略损伤裁剪。

这应该得到改进,以便在执行每缓冲区上传的驱动程序上正确跟踪损伤。

有关损伤跟踪的更多信息以及学习材料的参考,请参阅 损伤跟踪属性

联系人:Javier Martinez Canillas <javierm@redhat.com>

级别:高级

从 drm_syncobj 查询错误

drm_syncobj 容器可以由与驱动程序无关的代码用于发出提交完成信号。

一个仍缺少的小功能是用于查询二进制和时间线 drm_syncobj 错误状态的通用 DRM IOCTL。

这应该通过实现必要的内核接口并在用户空间堆栈中添加支持来改进。

联系人:Christian König

级别:入门

DRM 之外

将 fbdev 驱动程序转换为 DRM

有大量针对旧硬件的 fbdev 驱动程序。有些硬件已经过时,但有些仍然提供良好(足够)的帧缓冲。仍然有用的驱动程序应该转换为 DRM,然后从 fbdev 中移除。

非常简单的 fbdev 驱动程序最好通过从新的 DRM 驱动程序开始进行转换。简单的 KMS 辅助函数和 SHMEM 应该能够处理任何现有硬件。新驱动程序的回调函数是从现有 fbdev 代码中填充的。

更复杂的 fbdev 驱动程序可以借助 DRM fbconv 辅助函数 [4] 逐步重构为 DRM 驱动程序。这些辅助函数提供了 DRM 核心基础设施和 fbdev 驱动程序接口之间的转换层。在 fbconv 辅助函数之上创建新的 DRM 驱动程序,复制 fbdev 驱动程序,并将其连接到 DRM 代码。Thomas Zimmermann 的 fbconv 树中提供了几个 fbdev 驱动程序的示例 [4],以及此过程的教程 [5]。结果是一个可以运行 X11 和 Weston 的原始 DRM 驱动程序。

联系人:Thomas Zimmermann <tzimmermann@suse.de>

级别:高级