Display中的DRM模块介绍
DRM概述:
DRM全称 Direct Rendering Manager(直接渲染管理器),进行显示输出管理、 buffer 分配、 帧缓冲, 是device-independent内核级别驱动,内核提供直接访问硬件的权限, 原本是设计提供给PC使用来支持复杂的图形设备,后来也用于嵌入式系统上。PC一般都有显卡并且有自己的video memory,而嵌入式系统没有。DRM的设备节点为 “/dev/dri/cardX”
userspace 库为 libdrm,, libdrm 库提供了一系列友好的控制封装, 使用户可以方便的进行显示的控制和 buffer 申请。
DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬件。比如FB原生不支持多层合成,不支持VSYNC,不支持DMA-BUF,不支持异步更新,不支持fence机制等等,而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动,使得软件架构更为统一,方便管理和维护。
DRM代码:
uboot 部分 :uboot-px30/drivers/video/drm/
kernel部分: drivers/gpu/drm/rockchip/
drivers/gpu/drm/bridge/analogix/
drivers/gpu/drm/bridge/synopsys/
drivers/phy/rockchip/
整体框架如图:
DRM组成:
- libdrm: 底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装。
- KMS(Kernel Mode Setting): 主要两件事:更新画面和设置显示参数。
更新画面:显示buffer的切换,多图层的合成方式,以及每个图层的显示位置。
设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等。 - GEM(Graphics Execution Manager): 图形执行管理器,主要负责显示buffer的分配和释放,类似 android 下的 ion。也是GPU唯一用到DRM的地方。
KMS包括:CRTC,ENCODER,CONNECTOR,PLANE,FB,VBLANK,property
元素 | 说明 |
---|---|
CRTC | 对显示buffer进行扫描,并产生时序信号的硬件模块,通常指Display Controller显示控制器, 在 rockchip 平台是 SOC 内部 VOP(部分文档也称为 LCDC)模块的抽象; |
ENCODER | 负责将CRTC输出的timing时序转换成外部设备所需要的信号的模块,如HDMI转换器或DSI Controller, 指 RGB、 LVDS、 DSI、 eDP、 HDMI、 CVBS、 VGA 等显示接口; |
CONNECTOR | 连接物理显示设备的连接器,如HDMI、DisplayPort、DSI总线,通常和Encoder驱动绑定在一起 |
PLANE | 硬件图层,有的Display硬件支持多层合成显示,但所有的Display Controller至少要有1个plane |
FB | Framebuffer,单个图层的显示内容,唯一一个和硬件无关的基本元素 |
VBLANK | 软件和硬件的同步机制,RGB时序中的垂直消影区,软件通常使用硬件VSYNC来实现 |
property | 任何你想设置的参数,都可以做成property,是DRM驱动中最灵活、最方便的Mode setting机制 |
GEM:DUMB、PRIME、fence
元素 | 说明 |
---|---|
DUMB | 只支持连续物理内存,基于kernel中通用CMA API实现,多用于小分辨率简单场景 |
PRIME | 连续、非连续物理内存都支持,基于DMA-BUF机制,可以实现buffer共享,多用于大内存复杂场景 |
fence | buffer同步机制,基于内核dma_fence机制实现,用于防止显示内容出现异步问题 |
各模块框架位置如下图:
以瑞芯微平台为列子:
-
Fb:
内存信息如宽,高,bpp等。
代码中由 struct drm_framebuffer 表示,
在rockchip_drm_fbdev_create()@rockchip_drm_fbdev.c中创建。 -
CRTC:
之前代表的是CRT controller,目前主要用于显示控制,如用于display timings,
resolution的配置,将framebuffer内容送到display,更新framebuffer等。
在代码中由struct drm_crtc_funcs 和 struct drm_crtc_helper_funcs两个结构来表示。
在vop_create_crtc()@rockchip_drm_vop.c中创建。 -
Encoder:
将数据转换成合适的格式,送给connector,比如HDMI需要TMDS信息, encoder就将数据转成HDMI需要的TMDS格式。
在代码中由struct drm_encoder_funcs和struct drm_encoder_helper_funcs两个结构表示。
因为和connnector有相当紧密的关系,所以它的注册放在各个connector的驱动文件中,如rockchip_dp_drm_create_encoder()@analogix_dp-rockchip.c -
Connector:
代表具体外部接口,如edp, hdmi, mipi等。用于传输信号给外部硬件显示设备,探测外部显示设备接入。
在代码中由struct drm_connector_funcs 和 struct drm_connector_helper_funcs表示。
目前有rockchip_lvds.c, analogix_dp-rockchip.c, cdn-dp-core.c , dw-mipi-dsi.c, dw_hdmi-rockchip.c这几个驱动文件。
analogix_dp-rockchip.c的注册放在了analogix_dp_core.c 中,会通过rockchip_dp_bind()间接调用到。 -
Planes:
一个Plane代表一个image layer, 最终的image由一个或者多个Planes组成。
代码中由struct drm_plane_funcs 表示。
在vop_plane_init()@Rockchip_drm_vop.c中创建注册。
不同类型的Planes:- DRM_PLANE_TYPE_PRIMARY(主要图层,通常用于仅支持RGB格式的简单图层): 一定要有,由于显示背景或者图像内容。
- DRM_PLANE_TYPE_OVERLAY(叠加图层,通常用于YUV格式的视频图层): 用于显示Overlay
- DRM_PLANE_TYPE_CURSOR(光标图层,一般用于PC系统,用于显示鼠标): 用于显示鼠标
1. Plane的历史
随着软件技术的不断更新,对硬件的性能要求越来越高,在满足功能正常使用的前提下,对功耗的要求也越来越苛刻。本来GPU可以处理所有图形任务,但是由于它运行时的功耗实在太高,
设计者们决定将一部分简单的任务交给Display Controller去处理(比如合成),而让GPU专注于绘图(即渲染)这一主要任务,减轻GPU的负担,从而达到降低功耗提升性能的目的。
于是,Plane(硬件图层单元)就诞生了。
2. Plane的功能
Plane是连接FB与CRTC的纽带,是内存的搬运工。
Plane的参数含义:
当 SRC_X/Y 和 CRTC_X/Y 不相等时,就实现了平移的效果;
当 SRC_W/H 和 CRTC_W/H 不相等时,就实现了缩放的效果;
当 SRC_W/H 和 FB_W/H 不相等时,就实现了裁剪的效果;
- drm device:
处理用户空间的请求。
在代码中由struct drm_driver表示执行。
在rockchip_drm_bind()@Rockchip_drm_drv.c 创建和注册。
参考:https://blog.csdn.net/hexiaolong2009/article/details/83720940