飞道的博客

RK3399 探索之旅 / Display 子系统 / 基础概念

478人阅读  评论(0)

Linux 下的许多驱动框架其实都挺复杂,大多都是许多国内外的牛人经过多年的完善而积累下来的代码。

学习驱动开发需要找准自己的定位,先全局把握再适当地去填充细节,不要总想着深入到驱动框架里,站在一个使用者的角度去思考如何应用这些驱动框架或许会有更好的效果。

这里我是以一个菜鸟的身份记录下自己的一些想法和学习心得,欢迎纠正我。

一、基础概念

1. Linux 的 2 种显示方案

包括:

  • FBDEV: Framebuffer Device

  • DRM/KMS: Direct Rendering Manager / Kernel Mode Setting

它们有什么区别?

  • FBDEV:

    • 传统的显示框架;

    • 简单,但是只能提供最基础的显示功能;

    • 无法满足当前上层应用和底层硬件的显示需求;

  • DRM/KMS:

    • 目前主流的显示方案;

    • 为了适应当前日益更新的显示硬件;

    • 软件上能支持更多高级的控制和特性;

2. DRM/KMS 基础概念

DRM subsystem 图:

点击查看大图

虽然经常用 DRM/KMS 来指代整个 DRM subsystem,但是 KMS 和 DRM driver 只是 整个 DRM subsystem 的其中 2 个部分。

KMS (Kernel Mode Setting) 是内核提供给应用层的 DRM API 的其中一部分,应用层一般通过 libdrm 来访问这些 API。

对于驱动工程师而言,重点关注 DRM driver,这里负责使能 Display engine,可以理解为加强版的 FBDEV。

KMS 里的几个重要组件:

  • Planes:图层,例如在 rockchip 平台里对应 SOC 内部 VOP 模块的 win 图层;

  • CRTC:显示控制器,例如在 rockchip 平台里对应 SOC 内部的 VOP 模块;

  • Encoder:输出转换器,指 RGB、LVDS、DSI、eDP、HDMI、CVBS、VGA 等显示接口;

  • Connector:连接器,指 encoder 和 panel 之间交互的接口部分;

  • Bridge:桥接设备,一般用于注册 encoder 后面另外再接的转换芯片,如 DSI2HDMI 转换芯片;

  • Panel:泛指屏,各种 LCD、HDMI 等显示设备的抽象;

这些组件组合成 display pipeline:

点击查看大图

3. 驱动视角看 DRM/KMS

下面以 Allwinner 芯片的 DRM driver 为例进行展示。

DRM subsystem:

点击查看大图

这里为了便于理解,将 DRM DSI Core / DRM Panel Core / DRM Bridge Core 从 DRM Core 里单独划分出来了,但是其实它们都属于 DRM Core。

DRM driver:

点击查看大图

二、了解硬件信息

1. 查阅芯片手册

Rockchip 平台的 LCD Controller 称为 VOP(Video Output Processor),芯片中一般集 成 1~2 个 VOP。只有支持两个 VOP 的芯片,才能支持双屏异显。

RK3399 有 2 个 VOP:

  • Video Output Processor(VOP_BIG)

  • Video Output Processor(VOP_LIT)

支持的显示接口:

  • One or Two MIPI-DSI port

  • One eDP port

  • One DP port

  • One HDMI port

点击查看大图

2. 确定单板的显示接口

NanoPC T4:

  • LCD Interface: 一个eDP 1.3(4 线,10.8Gbps),一个或2个4线 MIPI-DSI;

  • DP on Type-C: DisplayPort 1.2 Alt Mode on USB Type-C;

  • HDMI: HDMI 2.0a,支持4K@60Hz显示,支持HDCP 1.4/2.2;

驱动工程师的职责:根据上层业务的需求,使能连接在上述接口上的各种 Panel,包括单独使能某个屏幕、双屏异显、双屏同显等。

三、查看单板的设备树

下面是 NanoPC-T4 设备树里和 display 相关的信息。

1. 相关节点及其状态

点击查看大图

2. 各节点的作用

display-subsystem:

  • 配置 Rockchip 的 display engine;

  • 通过 route 表将各组件(plane / crct / encoder / connector) 关联在一起,以便对应的驱动构建出 display pipe;

vopl: vop@ff8f0000:

  • 配置 VOP little;

  • 子节点 port 里有 5 个 endpoint,名字分别为 vopl_out_dsi / vopl_out_edp 等,它们是数据输出端,即 output endpoint;

  • 每个 endpoint 都会连接到某个 remote-endpoint,VOP 的 remote-endpoint 连接的就是各种显示 Encoder的 endpoint,例如 vopl_out_dsi ---> dsi_in_vopl;

vopb: vop@ff900000:

  • 省略

edp: edp@ff970000:

  • 配置 edp 控制器,大致包括基地址、中断、时钟、子节点 port;

  • 2 个 input endpoint,分别连接到 VOPL 和 VOPB;

  • 1 个 output endpoint 连接到了 epd panel 上;

  • 有 3 条连接:

    • vopb_out_edp ---> edp_in_vopb

    • vopl_out_edp ---> edp_in_vopl

    • edp_out ---> edp_panel

panel: edp-panel:

  • 配置某一款具体的 edp 屏;

  • 有 1 条连接:

    • edp_out ---> edp_panel

hdmi: hdmi@ff940000:

  • 配置 hdmi 控制器,大致包括引脚、基地址、中断、时钟、子节点 port;

  • 有 2 条连接:

    • vopb_out_hdmi ---> hdmi_in_vopb

    • vopl_out_hdmi ---> hdmi_in_vopl

dsi: dsi@ff960000  dsi1: dsi@ff968000:

  • 配置 mipi dsi,类似 edp / hdmi;

mipi_dphy_tx1rx1: mipi-dphy-tx1rx1@ff968000:

  • 配置 mipi dphy;

四、查看 Rockchip 的 DRM Driver

点击查看大图

1. 驱动路径

功能 驱动路径
DRM master device driver drivers/gpu/drm/rockchip/rockchip_drm_drv.c
Framebuffer driver drivers/gpu/drm/rockchip/rockchip_drm_fb.c

drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
GEM Driver drivers/gpu/drm/rockchip/rockchip_drm_gem.c
VOP Driver drivers/gpu/drm/rockchip/rockchip_drm_vop.c  

drivers/gpu/drm/rockchip/rockchip_vop_reg.c
LVDS Driver drivers/gpu/drm/rockchip/rockchip_lvds.c

drivers/phy/rockchip/phy-rockchip-inno-video-phy.c
RGA Ddriver drivers/gpu/drm/rockchip/rockchip_drm_rga.c
MIPI Driver drivers/gpu/drm/rockchip/dw-mipi-dsi.c
HDMI Driver drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c

drivers/gpu/drm/bridge/dw-hdmi.c
inno HDMI Driver drivers/gpu/drm/rockchip/inno_hdmi.c

drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c
eDP Driver drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

drivers/gpu/drm/bridge/analogix/analogix_dp_core.c

drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c

drivers/phy/rockchip/phy-rockchip-dp.c
DP Driver drivers/gpu/drm/rockchip/cdn-dp-core.c

drivers/gpu/drm/rockchip/cdn-dp-reg.c
TVE/CVBS Driver drivers/gpu/drm/rockchip/rockchip_drm_tve.c

2. Rockchip DRM driver 的 probe 流程

点击查看大图

这张图是 Rockchip 官方提供的,非常好的一张图。

有了这张图相当于有了一张源码分析的地图,后续我们可以参考它来进行更细致地源码分析。

简单说明一下:

  1. 各种 Encoder driver 和 CRCT driver 被 probe,然后通过 component_add() 注册进系统;

  2. Rockchip DRM Master device 被 probe:

  • 将各种 Encoder driver 和 CRCT driver 通过 component_match_add() 注册进 component match list;

  • component_master_add_with_match() 触发各种Encoder 和 CRCT component 的bind 操作,例如 vop_bind()、dw_hdmi_rockchip_bind() 等。

  • bind 的含义就是将 DRM 框架里的组件关联在一起,以 vop_bind() 为例:

    • VOP Driver 对应 CRCT driver, CRTC 负责连接 Planes 和 Encoder;

    • vop_create_crtc() -> drm_crtc_init_with_planes() 创建了 CRTC 对象,并和 Planes 关联在一起;

  • 剩下的就是边边角角的工作,例如注册 framebuffer 以兼容 FBDEV,显示 logo等。

  • 五、辅助调试的工具

    1. sysfs

    查看当前的显示状态,下面是只接了 HDMI 的情况:

    
         
    1. $ cat /sys/kernel/debug/dri/ 0/summary
    2. VOP [ff900000.vop]: ACTIVE
    3.     Connector: HDMI-A
    4.         overlay_mode[ 0] bus_format[ 100a] output_mode[f] color_space[ 0]
    5.     Display mode:  1920x1080p60
    6.         clk[ 148500] real_clk[ 148500type[ 48] flag[ 5]
    7.         H:  1920  2008  2052  2200
    8.         V:  1080  1084  1089  1125
    9.     win0 -0: ACTIVE
    10.         format: XR24 little-endian ( 0x34325258) SDR[ 0] color_space[ 0]
    11.         csc: y2r[ 0] r2r[ 0] r2y[ 0] csc mode[ 0]
    12.         zpos:  0
    13.         src: pos[ 0x0] rect[ 1920x1080]
    14.         dst: pos[ 0x0] rect[ 1920x1080]
    15.         buf[ 0]: addr:  0x0000000000000000 pitch:  7680 offset:  0
    16.     win1 -0: DISABLED
    17.     win2 -0: DISABLED
    18.     win2 -1: DISABLED
    19.     win2 -2: DISABLED
    20.     win2 -3: DISABLED
    21.     win3 -0: DISABLED
    22.     win3 -1: DISABLED
    23.     win3 -2: DISABLED
    24.     win3 -3: DISABLED
    25.     post: sdr2hdr[ 0] hdr2sdr[ 0]
    26.     pre : sdr2hdr[ 0]
    27.     post CSC: r2y[ 0] y2r[ 0] CSC mode[ 1]
    28. VOP [ff8f0000.vop]: DISABLED

    查看某个具体的显示设备:

    
         
    1. $ ls /sys/class/drm/
    2. card0  card0-DP -1  card0-eDP -1  card0-HDMI-A -1  controlD64  renderD128  version

    2. 调整 DRM log 等级

    /sys/module/drm/parameters/debug
    

    debug 里的每一个 bit 的含义:

    • Bit 0: enable CORE messages (drm core code)

    • Bit 1: enable DRIVER messages (drm controller code)

    • Bit 2: enable KMS messages (modesetting code)

    • Bit 3: enable PRIME messages (prime code)

    • Bit 4: enable ATOMIC messages (atomic code)

    • Bit 5: enable VBL messages (vblank code) (int)

    3. libdrm/modetest

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

    
         
    1. $ git clone https: //gitlab.freedesktop.org/mesa/drm
    2. $ apt-get install meson
    3. $ meson builddir/
    4. $ ninja -C builddir/ install
    5. $ ./builddir/tests/modetest/modetest -h
    6. usage: ./builddir/tests/modetest/modetest [-acDdefMPpsCvrw]
    7. ...

    六、参考

    • Linux kernel Documentation

    • Rockchip RK3399 Datasheet V2.1-20200323.pdf

    • Rockchip_Introduction_DRM_Integration_Helper_CN.pdf

    • Rockchip DRM Display Driver Development Guide V1.0.pdf

    • Rockchip_Developer_Guide_DRM_Panel_Porting_CN.pdf

    • The DRM/KMS subsystem from a newbie’s point of view.pdf

    思考技术,也思考人生

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

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

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

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


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