本文从如下几个部分介绍
1. DRM 概念介绍
DRM 是Direct Render Manager的缩写:
- Linux 显示子系统结构框架
- 向上提供标准API给到应用使用
- 管理GPU和Display模块
- 相较于原来的framebuffer结构,DRM将更多的硬件模块抽象并管理起来,所以更加的灵活方便;
包含如下模块:
- GEM(Graphics Execution Manager) 用于管理显示buffer的申请和释放
- DUMB:只支持连续的物理内存,基于Linux底层的CMA内存管理实现,多用于小分辨率的场景
- PRIME:可以支持连续 & 非连续内存,基于DMA-BU机制,可以实现buffer共享,多用于大内存复杂场景
- FENCE:buffer同步机制,基于dma_fence实现,解决buffer控制不同步而出现的撕裂、抖帧、回帧等现象
- KMS (Kernel Mode Sstting)用于设置显示相关配置,显示画面
- 硬件模块划分
- CRTC:配置timing、resolution等参数
- ENCODER:将data数据转换为输出数据格式的模块
- Connector:连接器,显示数据传输模块,比如LVDS TX / MIPI DSI / HDMI
- Panels:物理屏幕,同时也包含硬件模块中Overlay的图层;
- 其他相关概念
- framebuffer:显示buffer中的数据,一般是GPU渲染的数据或者camera输入数据;
- VBLANK:DRM框架中显示同步信号,以DPU中vsync信号触发;
- page flip:当前framebuffer中数据填充已经完成,可以送显信号;
- property:drm框架中的通用配置项,用于补充上述无法包含的内容信息‘
- 硬件模块划分
如图所示,相较于原始FB结构,DRM device结构,将相关的硬件模块都抽象出来对象进行管理,则可以更加灵活的配置
2. 对比HW结构分析
这里是一个显示模块的大体框架结构:
上图仅描述数据path(控制部分未添加):
- DPU从framebuffer中读取数据
- 经控制合成缩放等处理后输出给到LVDS Encoder模块
- Encoder 模块将数据转换为物理线路信号发送到PHY上输出;
可以看到数据输出path为:DPU – LVDS – TX,与DRM中抽象概念可以一一对应起来:
- CRTC 对应DPU
- Encoder 对应 LVDS Encoder
- Connector对应PHY或者线路,不涉及过多控制,可以在code中不用特别体现
详细来看DPU的内部结构:
- Display Engine中包含我们之前叙述的Overlay模块,以及后边的合成模块;
- Output Engine中配置Display timing相关配置;
- 支持旋转、缩放、PQ等处理;
此部分硬件支持功能可以灵活地在DRM中添加控制;
3. code分析
首先来看维基百科上的DRM Architecture图示:
- 实现libdrm库,用于在user层提供标准API来操作 DRM device ,并获取其中的各个组件(CRTC、Connector、Encoder)
- 实现kernel层中core管理:
- 对接上层libdrm结构
- 提供注册接口,实际实现drv时通过此类接口注册crtc、encoder、connector等
- 对应物理设备操作的ioctl也与实际drv进行链接
- kernel中的GEM管理