一、简介
Linux DRM(Direct Rendering Manager)子系统是内核中管理图形硬件的核心组件,而 CRTC(CRT Controller)又是其中的关键之一。它起源于过去控制阴极射线管(CRT)显示器的控制器概念,如今在现代图形显示中依旧扮演着至关重要的角色。
可以把 CRTC 想象成图形显示管线的指挥中心。它主要负责从帧缓冲区(Framebuffer)中读取图像数据,生成符合特定时序和模式的视频信号,并将其传递给相应的编码器(Encoder)和连接器(Connector),最终输出到显示设备上。
-
核心功能:CRTC 的核心是控制显示时序和模式。这包括生成像素时钟(pixel clock)、水平同步信号(HSync)、垂直同步信号(VSync)等,确保图像按正确的方式扫描并显示在屏幕上。
-
显示管线中的角色:在 DRM 的显示管线 (Plane
-> CRTC -> Encoder -> Connector -> 显示器
) 中,CRTC 是一个承上启下的关键环节。它处理好的图像数据会交给 Encoder 转换成特定的接口协议(如 HDMI、DP),再通过 Connector 物理输出。
二、代码分析
主要包含了drm_crtc.c和drm_crtc_helper.c两个文件
两个代码文件的作用说明
drm_crtc.c 的作用
drm_crtc.c 是 Linux DRM (Direct Rendering Manager) 子系统中处理 CRTC (Cathode Ray Tube Controller) 核心功能的源文件。CRTC 是 DRM 显示管道的核心组件,负责从平面 (planes) 接收像素数据、混合它们,并根据显示模式 (timings) 输出到编码器 (encoders)。这个文件实现了 CRTC 的初始化、注册、清理、配置设置、属性管理以及与用户空间 ioctl 的交互(如获取/设置 CRTC 配置)。它支持遗留模式设置和原子模式设置的过渡,提供标准属性(如 ACTIVE、MODE_ID)和辅助功能(如 fence 创建、CRC 支持)。文件还处理错误检查和资源管理,确保 CRTC 与平面、帧缓冲和连接器的兼容性。该文件是 DRM 核心的一部分,主要用于驱动程序的 CRTC 管理,尤其在非原子驱动中。
drm_crtc_helper.c 的作用
drm_crtc_helper.c 是 DRM 子系统中提供遗留 CRTC 模式设置辅助函数的源文件。它为使用旧式 CRTC 接口的驱动程序提供便利函数,实现模式设置、电源管理 (DPMS)、禁用未使用资源、恢复配置等操作。该文件主要处理遗留模式设置的复杂逻辑,如计算最佳编码器、调整模式、处理 DPMS 状态,并确保配置更改的原子性(尽管不是真正的原子模式)。它与原子模式设置兼容,但强烈建议新驱动使用原子辅助函数。该文件的作用是简化驱动程序的模式设置实现,减少重复代码,但已标记为过时(deprecated),因为现代驱动应转向原子接口。
两个文件的函数及其作用列表
drm_crtc.c 中的函数
- drm_crtc_from_index: 根据索引在 DRM 设备中查找并返回对应的 CRTC 对象。用于 vblank 回调等场景,将索引转换为指针。
- drm_crtc_force_disable: 强制禁用指定 CRTC,通过设置空模式配置实现。用于遗留驱动的电源管理。
- drm_num_crtcs: 计算 DRM 设备中 CRTC 的总数。通过遍历列表实现。
- drm_crtc_register_all: 注册所有 CRTC 到 DRM 核心,包括 debugfs 和 late_register 回调。用于驱动初始化。
- drm_crtc_unregister_all: 注销所有 CRTC,包括 early_unregister 回调和 debugfs 移除。用于驱动卸载。
- drm_crtc_crc_init: 初始化 CRTC 的 CRC (Cyclic Redundancy Check) 支持,包括锁和队列。用于帧校验调试。
- drm_crtc_crc_fini: 结束 CRTC 的 CRC 支持,释放资源。
- fence_to_crtc: 从 DMA fence 结构中提取对应的 CRTC 对象。用于 fence 操作的容器转换。
- drm_crtc_fence_get_driver_name: 返回 fence 的驱动名称。用于 DMA fence 接口。
- drm_crtc_fence_get_timeline_name: 返回 fence 的时间线名称。用于 DMA fence 接口。
- drm_crtc_create_fence: 为 CRTC 创建一个 DMA fence 对象,用于同步操作。
- __drm_crtc_init_with_planes: 内部函数,用于初始化 CRTC 对象,包括锁、ID、属性和标准属性附加。核心初始化逻辑。
- drm_crtc_init_with_planes: 初始化一个新的 CRTC 对象,关联主平面和游标平面。用于驱动创建 CRTC。
- drmm_crtc_alloc_with_planes_cleanup: 清理函数,用于释放 CRTC 资源。通过 drm_crtc_cleanup 调用。
- __drmm_crtc_alloc_with_planes: 分配并初始化一个托管的 CRTC 对象,支持 managed 资源管理。
- drm_crtc_cleanup: 清理 CRTC 对象,包括注销、释放内存和状态销毁。用于 CRTC 销毁。
- drm_mode_getcrtc: 通过 ioctl 获取 CRTC 配置(如 gamma 大小、位置、模式)。用户空间接口。
- __drm_mode_set_config_internal: 内部设置 CRTC 配置,包括帧缓冲 refcounting 和回调调用。
- drm_mode_set_config_internal: 包装设置 CRTC 配置的内部函数,用于遗留驱动。
- drm_crtc_check_viewport: 检查帧缓冲是否足够大以支持 CRTC 的视口(viewport)。用于模式验证。
- drm_mode_setcrtc: 通过 ioctl 设置 CRTC 配置,包括模式、帧缓冲和连接器。用户空间接口。
- drm_mode_crtc_set_obj_prop: 设置 CRTC 对象的属性值。用于遗留属性管理。
- drm_crt