- 显示驱动框架DRM框架介绍
rk3658在kernel4.4开始使用的显示驱动框架是基于DRM的,DRM是一个内核级的设备驱动,具体的说是显卡驱动的一种架构。
DRM全称是Direct Rendering Manager,管理进行显示输出的buffer分配、帧缓冲。libdrm库提供了一系列友好的控制封装, 使用户可以方便的进行显示的控制, modetest是libdrm源码自带的调试工具, 可以对drm进行一些基础的调试,但并不是只能通过libdrm库来控制drm, 用户可以直接操作drm的ioctl或者是使用framebuffer的 接口实现显示操作。这里不对其驱动进行详细介绍和研究,一般是知道如何使用即可。
- 设备节点以及操作
DRM 框架会创建的诸多节点文件。
DRM 框架创建设备节点或者GPU设备文件,如下所示:
/dev/dri/cardX, X为0-15的数值,默认使用的是/dev/dri/card0,这个文件同时支持绘图和显示,例如实现显示器显示帧缓冲功能,用户可以使用open操作并调用KMS接口完成,这里不详细介绍。
/dev/dri/renderDX,X可以为128,129等的数值,这个文件只支持绘图功能,用户可以open操作并调用EGL+GBM做OpenGL绘制,这里不详细介绍。
DRM 框架创建创建 sysfs 节点,如下所示:
sysfs可简单完成对设备的功能控制,目前SPE设备只具有HDMI功能,使用ls /sys/class/drm/ 命令查看显示屏名称,如上图所示,可以看到具有HDMI设备,名为card0-HDMI-A-1,故以HDMI功能叙述:
查看当前支持的可用显示分辨率列表:
cat /sys/class/drm/card0-HDMI-A-1/modes
查看当前分辨率(该功能不支持):
cat /sys/class/drm/card0-HDMI-A-1/mode
打开hdmiout显示:
echo on > /sys/class/drm/card0-HDMI-A-1/status
关闭hdmiout显示:
echo off > /sys/class/drm/card0-HDMI-A-1/status
查看hdmiout显示状态:打开是connected,关闭是disconnected
cat /sys/class/drm/card0-HDMI-A-1/status
重新检测HDMI连接
echo detect > /sys/class/drm/card0-HDMI-A-1/status
注:在设置HDMI分辨率的时候,如果设置为自适应模式(Auto)的时候,就去设置status为detect,如果设置HDMI为固定分辨率的时候(如1080p)就设置HDMI的状态为on,即让它一直为输出HDMI信号的状态。
查看 hdmi 的edid数据或者将DP/HDMI接口的EDID数据转化为十六进制原始数据保存为.bin文件
安卓下:
adb pull /sys/class/drm/card0-HDMI-A-1/edid d:/log/
Linux下:
cat /sys/class/drm/card0-DP-1/edid > /data/edid.bin
cat /sys/class/drm/card0-HDMI-A-1/edid > /data/edid.bin
注:EDID:全称是Extended Display Identification Data (外部显示设备标识数据);VGA、DVI的EDID由主块128字节组成,HDMI的EDID增加扩展块(128字节),扩展块的内容主要是和音频属性相关的,DVI和VGA没有音频,HDMI自带音频,扩展块数据规范按照CEA-861x标准定义,未来可能增加到512或256的整数倍。
其中包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、颜色设置、厂商预设置、频率范围的限制以及显示器名和序列号的字符串等等。形象地说,EDID就是显示器的身份证、户口本、技能证书等证件的集合,目的就是告诉别人我是谁,我从哪来,我能干什么。
使用 EDID Manager打开edid.bin文件,会看到edid的详细解析,如下图所示:
控制LVDS设备为 /sys/class/drm/card0-LVDS-1,控制eDP设备为 /sys/class/drm/card0-eDP-1,的命令相似,再次不再赘述。
DRM 框架创建创建 debugfs 节点为/sys/kernel/debug/dri/0,一般用于信息查询。
查看去驱动名字
cat /sys/kernel/debug/dri/0/name
查看屏幕信息(当前的输出分辨率和帧率)
cat /sys/kernel/debug/dri/0/ummary
上图中给出了显示模式为1920x1080p60 代表当前分辨率为1920x1080,帧率为60帧。
libdrm的调试工具modetest
modetest是libdrm源码自带的调试工具, 可以对drm进行一些基础的调试,目前SDK中路径为:external/libdrm/tests,编译得到modetest,路径为 out/target/product/rk356x/symbols/system/bin/modetest和out/target/product/rk356x/system/bin/modetest,其可以查询显示设备的支持状况,进行基本的显示测试,以及设置显示的模式,目前设备上暂未支持。
使用如下:
./modetest --help
usage: /home/alarm/workspace/linux/libdrm-2.4.100/tests/modetest/.libs/lt-modetest [-acDdefMPpsCvw]
Query options:
-c list connectors
-e list encoders
-f list framebuffers
-p list CRTCs and planes (pipes)
Test options:
-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>] set a plane
-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>] set a mode
-C test hw cursor
-v test vsynced page flipping
-w <obj_id>:<prop_name>:<value> set property
-a use atomic API
-F pattern1,pattern2 specify fill patterns
Generic options:
-d drop master after mode set
-M module use the given driver
-D device use the given device
Default is to dump all info.
首先这里给出一组显示示例,命令参数如下:
./modetest -M vc4 -D 0 -a -s 32@140:1920x1080 -P 173@140:1920x1080 -Ftiles
命令执行的console输出:
程序运行效果如下,通过HDM连接的显示器整屏的显示了渐变的斜条纹: