小言_互联网的博客

RK3399探索之旅 / Display子系统 / 从modetest 到 DRM driver

335人阅读  评论(0)

modetest 是由 libdrm 提供的测试程序,可以查询显示设备的特性,进行基本的显示测试,以及设置显示的模式。

我们可以借助该工具来学习 Linux DRM 应用编程,另外为了深入分析 Rockchip DRM driver,有必要先了解一下这个工具的使用方法和内部实现。

本文目录:


   
  1. 一、准备工作
  2. 二、modetest 使用示例
  3.   1. 查看帮助信息
  4.   2. 查看组件的信息
  5.   3. 在 HDMI 上显示
  6.   4. 在 eDP 上显示
  7. 三、编写最简单的 DRM 应用
  8. 四、DRM 应用如何呼叫到 Rockchip DRM driver?
  9. 五、相关参考

一、准备工作

在 NanoPC T4 + Linux-4.4 上

  • 接好 eDP 屏以及 HDMI 显示器;

  • 退出所有占用 /dev/dri/card0 的程序;

  • 编译 modetest


   
  1. $ git clone https: //gitlab.freedesktop.org/mesa/drm
  2. $ apt-get install meson
  3. $ meson builddir/
  4. $ ninja -C builddir/ install

二、modetest 使用示例

1. 查看帮助信息


   
  1. $ modetest -h
  2. usage: modetest [-acDdefMPpsCvrw]
  3. Query options:
  4. -c      list connectors
  5. -e      list encoders
  6. -f      list framebuffers
  7. -p      list CRTCs and planes (pipes)
  8. Test options:
  9.     ...
  10. Generic options:
  11. -d      drop master after mode set
  12. -M module       use the given driver
  13. -D device       use the given device
  14. Default is to dump all info.

2. 查看组件的信息


   
  1. $ modetest -M rockchip
  2. Encoders:
  3. id      crtc     type    possible crtcs  possible clones
  4. 76       54      TMDS     0x00000001       0x00000000
  5. 78       0       TMDS     0x00000003       0x00000000
  6. 80       65      TMDS     0x00000002       0x00000000
  7. Connectors:
  8.     ...

参数说明:

  • -M:用于指定访问 rockchip DRM driver

关键内容:

  • Encoders / Connectors / CRTCs / Planes 的 id,modetest 通过 id 来用于引用这些组件。

  • Connectors 的 modes/props:

    • prop: 任何你想设置的参数,都可以做成 property,是 DRM 驱动中最灵活、最方便的 Mode setting 机制;

    • modes: 显示模式,mode 里包含分辨率/刷新率等显示相关的信息;

  • CRTCs 的 props;

  • Planes 的 formats/props;

各组件的 id:


   
  1. $ modetest -M rockchip | cut -f1 | grep -E ^[ 0 -9A-Z]\|id
  2. Encoders:
  3.  id
  4.   90, edp encoder
  5.   92, hdmi encoder
  6.   100, dp encoder
  7. Connectors:
  8.  id
  9.   91, edp connector
  10.   93, hdmi connector
  11.   101, dp connector
  12. CRTCs:
  13.  id
  14.   64, vop crtc
  15.   83, vop crtc
  16. Planes:
  17.  id
  18.   58
  19.   61
  20.   65
  21.   68
  22.   80
  23.   84
  24. Frame buffers:
  25.  id

3. 在 HDMI 上显示


   
  1. $ modetest -M rockchip -s  93@ 64: 1920x1080
  2. $ modetest -M rockchip -s  93@ 64:# 1    // 相同的效果

参数说明:

  • -s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]:用于在指定的 pipeline 上以某个 mode 显示某个 pattern 的画面。

  • 93:HDMI connector id

  • 64:某个 VOP 的 crtc id

  • 1920x1080:显示 mode;

HDMI connector 下其他可选的 mode:


   
  1. # 0  1920x1080  60.00
  2. # 1  1920x1080  59.94
  3. # 2  1920x1080i  30.00
  4. # 3  1920x1080i  29.97
  5. ...
  6. # 24  640x480  60.00
  7. # 25  640x480  59.94
  8. # 26  720x400  70.08

显示效果:

点击查看大图

4. 在 eDP 上显示

$ modetest -M rockchip -s 91@83:1920x1080

参数说明:

  • 91:eDP connector id

  • 83:另外一个 VOP 的 crtc id

  • 1920x1080:显示 mode;

显示效果:

点击查看大图

三、编写最简单的 DRM 应用

主程序:


   
  1. int main( int argc, char **argv)
  2. {
  3.   int fd;
  4.  drmModeConnector *conn;
  5.  drmModeRes *res;
  6.  uint32_t conn_id;
  7.  uint32_t crtc_id;
  8.      // 1. 打开设备
  9.  fd = open( "/dev/dri/card0", O_RDWR | O_CLOEXEC);
  10.      // 2. 获得 crtc 和 connector 的 id
  11.  res = drmModeGetResources(fd);
  12.  crtc_id = res->crtcs[ 0];
  13.  conn_id = res->connectors[ 0];
  14.      // 3. 获得 connector
  15.  conn = drmModeGetConnector(fd, conn_id);
  16.  buf.width = conn->modes[ 0].hdisplay;
  17.  buf.height = conn->modes[ 0].vdisplay;
  18.      // 4. 创建 framebuffer
  19.  modeset_create_fb(fd, &buf);
  20.      // 5. Sets a CRTC configuration,这之后就会开始在 crtc0 + connector0 pipeline 上进行以 mode0 输出显示
  21.  drmModeSetCrtc(fd, crtc_id, buf.fb_id,  00, &conn_id,  1, &conn->modes[ 0]);
  22.  getchar();
  23.   // 6. cleanup
  24.  ...
  25.   return  0;
  26. }

modeset_create_fb():

该函数用于分配 framebuffer,目前不需要太关心,大致就是 3 个步骤:

  • Allocating memory;

  • Preparing a mapping;

  • Mapping memory;

运行效果:

程序运行后,eDP 屏显示全屏白色,等待用户输入按键;当用户按下任意按键后,程序退出,显示黑屏。

四、DRM 应用如何呼叫到 Rockchip DRM driver?

drmModeSetCrtc() 到 CRTC driver:

点击查看大图

每一个 DRM CRTC Driver(例如 Rockchip VOP driver) 里都会定义一个 struct drm_crtc_funcs 结构体,其中的 .set_config 都指向 drm_atomic_helper_set_config(),接下来就是 DRM core 开始工作了。

五、相关参考

思考技术,也思考人生

要学习技术,更要学习如何生活

你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。

嵌入式系统 (Linux、RTOS、OpenWrt、Android) 和 开源软件 感兴趣,关注公众号:嵌入式Hacker

觉得文章对你有价值,不妨点个 在看和赞


转载:https://blog.csdn.net/wuweidonggmail/article/details/112057675
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场