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

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 driverdrivers/gpu/drm/rockchip/rockchip_drm_drv.c
Framebuffer driverdrivers/gpu/drm/rockchip/rockchip_drm_fb.c

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

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

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

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

drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c
eDP Driverdrivers/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 Driverdrivers/gpu/drm/rockchip/cdn-dp-core.c

drivers/gpu/drm/rockchip/cdn-dp-reg.c
TVE/CVBS Driverdrivers/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 的情况:

    $ cat /sys/kernel/debug/dri/0/summary
    VOP [ff900000.vop]: ACTIVE
        Connector: HDMI-A
            overlay_mode[0] bus_format[100a] output_mode[f] color_space[0]
        Display mode: 1920x1080p60
            clk[148500] real_clk[148500] type[48] flag[5]
            H: 1920 2008 2052 2200
            V: 1080 1084 1089 1125
        win0-0: ACTIVE
            format: XR24 little-endian (0x34325258) SDR[0] color_space[0]
            csc: y2r[0] r2r[0] r2y[0] csc mode[0]
            zpos: 0
            src: pos[0x0] rect[1920x1080]
            dst: pos[0x0] rect[1920x1080]
            buf[0]: addr: 0x0000000000000000 pitch: 7680 offset: 0
        win1-0: DISABLED
        win2-0: DISABLED
        win2-1: DISABLED
        win2-2: DISABLED
        win2-3: DISABLED
        win3-0: DISABLED
        win3-1: DISABLED
        win3-2: DISABLED
        win3-3: DISABLED
        post: sdr2hdr[0] hdr2sdr[0]
        pre : sdr2hdr[0]
        post CSC: r2y[0] y2r[0] CSC mode[1]
    VOP [ff8f0000.vop]: DISABLED
    

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

    $ ls /sys/class/drm/
    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 提供的测试程序,可以查询显示设备的支持状况,进行基本的显示测试,以及设置显示的模式。

    $ git clone https://gitlab.freedesktop.org/mesa/drm
    $ apt-get install meson
    $ meson builddir/
    $ ninja -C builddir/ install
    $ ./builddir/tests/modetest/modetest -h
    usage: ./builddir/tests/modetest/modetest [-acDdefMPpsCvrw]
    ...
    

    六、参考

    • 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值