Rockchip DRM Display Driver 开发指南
:::info 文档信息
文档标识:RK-YH-YF-455 · 发布版本:V3.0.0 · 发布日期:2022-03-17 · 页数:34 · 语言:中文
原始文档:Rockchip_Developer_Guide_DRM_Display_Driver_CN.pdf
:::
章节大纲
- Rockchip DRM Display Driver 开发指南(P1)
- DRM 概述(P5)
- 基本概念(P5)
- 显示通路(P5)
- DRM 驱动和 libdrm 的交互过程(P6)
- 驱动文件和加载流程(P6)
- U-Boot 驱动(P7)
- 驱动目录(P7)
- 驱动文件(P7)
- 接口说明(P8)
- kernel 驱动(P8)
- 驱动目录(P8)
- 驱动文件(P8)
- 驱动加载流程(P9)
- U-Boot 驱动(P7)
- Display feature(P10)
- 各平台 VOP 基础特性和支持的显示接口(P10)
- 各平台显示接口最大输出分辨率和协议标准(P11)
- 硬件相关(P13)
- RGB输出/TTL模式硬件连接(P13)
- VOP 1.0 RGB 接口硬件连接方式(P13)
- VOP 2.0 及之后的版本 RGB 接口硬件连接方式(P14)
- 不同 display mode index 对应的软件配置(P15)
- BT.656 和 BT.1120 的硬件连接方式(P15)
- LVDS Data Mapping(P16)
- RGB输出/TTL模式硬件连接(P13)
- 扫描时序说明(P16)
- 常见的扫描时序图(P16)
- DRM 对扫描时序的定义(P17)
- 软件配置的对应关系和转换(P18)
- 查看当前配置的时序(P18)
- 带宽的计算方法(P19)
- 图像的带宽(P19)
- 显示接口的带宽(P20)
- 常用的 debug 手段(P20)
- dump 当前的显示状态(P20)
- 使用命令(P20)
- 参数说明(P21)
- dump当前显示的 buffer(P22)
- 使用说明(P23)
- 调整 DRM 打印 Log 等级抓 Log(P23)
- 查看当前显示时钟(P23)
- 强行开关显示设备(P24)
- 查看 DRM buffer 使用情况(P24)
- 查看 GPIO 状态(P24)
- modetest 的使用(P24)
- 显示进程的暂停、启动(P25)
- 获取 EDID 信息(P25)
- 查看 HDMI 状态(P26)
- 参考例子(P26)
- dump 当前的显示状态(P20)
- FAQ(P26)
- 如何开关 U-Boot logo 显示(P26)
- 如何配置 U-Boot logo 全屏或者居中显示(P26)
- U-Boot logo 要求(P27)
- U-Boot logo 切换到内核 logo 出现闪屏/无法显示问题(P27)
- VOP POST_BUF_EMPTY(P28)
- 显示效果调节(P29)
- 屏无法点亮/休眠唤醒显示异常/不显示问题(P29)
- RK3308 如何打开显示功能(P29)
- 关闭 iommu 的方法(P30)
- 各种接口屏配置(P31)
- RGB/MCU 屏帧率计算问题(P31)
- 如何编写第三方转换芯片驱动(P31)
- VOP2 绑定每个 VP 所使用的图层(P32)
- RK3588 DSC 支持几个 slice,slice width 最大支持多少(P32)
- RK3568 VP 和各显示接口的连接关系(P32)
- RK3588 VP 和各显示接口的连接关系(P33)
- 超过 4kP60 对 aclk 的要求(P34)
- 参考文档(P34)
- DRM 概述(P5)
在线预览
若预览无法显示,请直接下载 PDF 后用本地阅读器打开。
1. DRM 概述
DRM 全称是 Direct Rendering Manager,进行显示输出管理、buffer 分配、帧缓冲。对应 userspace 库为 libdrm,libdrm 库提供了一系列友好的控制封装,使用户可以方便的进行显示的控制和 buffer 申请。DRM 的设备节点为"/dev/dri/cardX", X 为 0-15 的数值,默认使用的是 /dev/dri/card0。
Rockchip 平台从 Linux 4.4 内核开始,显示驱动全部切到 DRM 显示框架。
1.1 基本概念
为了方便管理显示通路上的各种硬件模块,DRM 定义了以下几个概念:
| 基本概 念 | 说明 |
|---|---|
| CRTC | 显示控制器,在 rockchip 平台是 SOC 内部 VOP(部分文档也称为 LCDC)模块或者 VOP2 中 Video Port 的抽象 |
| Plane | 图层,在 rockchip 平台是 SOC 内部 VOP(LCDC)模块 win 图层的抽象 |
| Encoder | 输出转换器,指RGB、LVDS、DSI、eDP、DP、HDMI、CVBS、VGA 等显示接口 |
| Connector | 连接器,指 encoder 和 panel 之间交互的接口部分 |
| Bridge | 桥接设备,一般用于注册 encoder 后面另外再接的转换芯片,如 DSI2HDMI 转换芯片 |
| Panel | 泛指屏,各种 LCD 显示设备的抽象 |
| GEM | DRM 下 buffer 管理和分配,类似 ION、DMA BUFFER |
1.2 显示通路
1.3 DRM 驱动和 libdrm 的交互过程
2. 驱动文件和加载流程
2.1 U-Boot 驱动
2.1.1 驱动目录
drivers/video/drm/
2.1.2 驱动文件
| Driver | File |
|---|---|
| Core | rockchip display.c _ rockchip crtc.c _ rockchip connector.c _ rockchip phy.c _ rockchip panel.c _ rockchip bridge.c _ |
| VOP | rockchip vop.c _ rockchip vop reg.c _ _ rockchip vop2.c _ rockchip vop2 reg.c _ _ |
| RGB | rockchip rgb.c _ inno video combo phy.c _ _ _ |
| LVDS | rockchip lvds.c _ inno video combo phy.c _ _ _ |
| MIPI-DSI | drm mipi dsi.c _ _ dw mipi dsi2.c _ _ inno mipi phy.c _ _ inno video combo phy.c _ _ _ samsung mipi dcphy.c _ _ |
| eDP | rockchip analogix dp.c _ _ rockchip analogix dp reg.c _ _ _ |
| HDMI | dw hdmi.c _ rockchip dw hdmi.c _ _ rockchip-inno-hdmi-phy.c inno hdmi.c _ dw hdmi qp.c _ _ rockchip dw hdmi qp.c _ _ _ phy-rockchip-samsung-hdptx-hdmi.c |
| TVE /CVBS | rockchip drm tve.c _ _ |
| DP | dw-dp.c drm dp helper.c _ _ phy-rockchip-usbdp.c |
以上驱动文件在不同的 U-Boot 版本可能会做些小的调整,但多数驱动文件和框架部分基本不会变化,查阅的时候可以根据实际情况调整。
2.1.3 接口说明
- 显示 U-Boot logo
void rockchip_show_logo(void)
- 显示指定的 bmp 图片,目前主要用于充电 logo 的显示
void rockchip_show_bmp(const char *bmp)
- 将 U-Boot 中确定的一些变量通过修改 dtb 文件传递给内核,包括 kernel logo 的大小、地址、格式、输出扫描时序以及过扫描的配置等信息
void rockchip_display_fixup(void *blob)
2.2 kernel 驱动
2.2.1 驱动目录
drivers/gpu/drm/rockchip/
drivers/gpu/drm/bridge/analogix/
drivers/gpu/drm/bridge/synopsys/
drivers/phy/rockchip/
2.2.2 驱动文件
| Driver | File | Doc |
|---|---|---|
| Core | rockchip drm drv.c _ _ rockchip drm fb.c _ _ rockchip drm fbdev.c _ _ rockchip drm gem.c _ _ rockchip drm logo.c _ _ rockchip drm direct show.c _ _ _ panel-simple.c | rockchip-drm.txt or rockchip-drm.yaml |
| VOP | rockchip drm vop.c _ _ rockchip vop reg.c _ _ rockchip drm vop2.c _ _ rockchip vop2 reg.c _ _ | rockchip-vop.txt or rockchip-vop.yaml |
| RGB | rocckhip rgb.c _ phy-rockchip-inno-video-combo-phy.c | rockchip-rgb.txt |
| LVDS | rockchip lvds.c _ phy-rockchip-inno-video-combo-phy.c | rockchip-lvds.txt |
| MIPI-DSI | dw-mipi-dsi.c phy-rockchip-inno-dsidphy.c phy-rockchip-inno-video-combo-phy.c dw-mipi-dsi2-rockchip.c phy-rockchip-samsung-dcphy.c | dw mipi dsi rockchip.txt _ _ _ phy-rockchip-inno-mipi-dphy.txt |
| eDP | analogix dp core.c _ _ analogix dp-rockchip.c _ analogix dp reg.c _ _ phy-rockchip-dp.c | analogix dp-rockchip.txt _ analogix dp.txt _ rockchip-dp-phy.txt |
| DP | cdn-dp-core.c cdn-dp-reg.c dw-dp.c phy-rockchip-usbdp.c phy-rockchip-samsung-hdptx-hdmi.c | cdn-dp-rockchip.txt |
| HDMI | inno hdmi.c _ dw-hdmi.c dw hdmi-rockchip.c _ phy-rockchip-inno-hdmi-phy.c dw-hdmi-qp.c phy-rockchip-samsung-hdptx-hdmi.c | inno hdmi-rockchip.txt _ dw hdmi-rockchip.txt _ phy-rockchip-inno-hdmi-phy.txt |
| TVE/CVBS | rockchip drm tve.c _ _ | rockchip drm tve.txt _ _ |
以上驱动文件在不同的 kernel 版本可能会做些小的调整,但多数驱动文件和框架部分基本不会变化,查阅的时候可以根据实际情况调整。
2.3 驱动加载流程
3. Display feature
3.1 各平台 VOP 基础特性和支持的显示接口
3.2 各平台显示接口最大输出分辨率和协议标准
| 平台 | 显示 接口 | 最大输出分辨率 | 协议标准 |
|---|---|---|---|
| RK3036 | HDMI | 1920x1080@60hz | 支持 HDMI 1.4a 协议标准 |
| CVBS | 720x480i@60hz/720x576i@50hz | 支持 NTSC/PAL 标准输出 | |
| RK312X/PX3SE | RGB | 1280x800@60hz | 支持 RGB666/sRGB888 |
| LVDS | 1280x800@60hz | 支持 VESA 和 JEIDA LVDS 数据格式 | |
| MIPI | 1280x800@60hz | 支持 DSI v1.0,DCS v1.0,DPHY v1.0 协议标准 | |
| HDMI | 1920x1080@60hz | 支持 HDMI 1.4a 协议标准 | |
| RK322X/RK312XH | HDMI | 4096x2160@60hz | 支持 HDMI 1.4a 和 2.0 协议标准 |
| CVBS | 720x480i@60hz/720x576i@50hz | 支持 NTSC/PAL 标准输出 | |
| RK3288 | RGB | 1920x1080@60hz | 支持 GB888/RGB666/sRGB888 |
| LVDS | 单通道:1280x800@60hz 双通道:1920x1080@60hz | 支持 VESA 和 JEIDA LVDS 数据格式 | |
| eDP | 2560x1600@60hz | 支持 DP1.2a 和 eDP1.3 协议标准 | |
| MIPI | 单通道:1920x1080@60hz 双通道:2560x1600@60hz | 支持 DSI v1.1,DCS v1.1,DPHY v1.1 协议标准 | |
| HDMI | VOP BIG::3840x2160@60hz VOP LIT: 1920x1080@60hz | 支持 HDMI 1.4a 和 2.0 协议标准 | |
| RK3308 | RGB | 1280x800@60hz | 支持 RGB888/RGB666/sRGB888/MCU |
| RK1808 | RGB | 1280x800@60hz | 支持 RGB888/RGB666/sRGB888/MCU |
| MIPI | 1280X800@60hz | 支持 DSI v1.0,DCS v1.0,DPHY v1.0 协议标准 | |
| RK322XH/RK332X | HDMI | 3840x2160@60hz | 支持 HDMI 1.4a 和 2.0 协议标准 |
| CVBS | 720x480i@60hz/720x576i@50hz | 支持 NTSC/PAL 标准输出 | |
| RK3326/px30 | RGB | 1280x800@60hz | 支持 RGB888/RGB666/sRGB888/MCU |
| LVDS | 1280x800@60hz | 支持 VESA 和 JEIDA LVDS 数据格式 | |
| MIPI | 1920x1080@60hz | 支持 DSI v1.0,DCS v1.0,DPHY v1.0 协议标准 | |
| RK3368/PX5 | RGB | 1280x800@60hz | 支持 RGB888/RGB666/sRGB888/MCU |
| LVDS | 1280x800@60hz | 支持 VESA 和 JEIDA LVDS 数据格式 | |
| MIPI | 1920x1080@60hz | 支持 DSI v1.0,DCS v1.0, DPHY v1.0 协议标准 | |
| eDP | 2560x1600@60hz | 支持 DP1.2a 和 eDP1.3 协议标准 | |
| HDMI | 4096x2160@60hz | 支持 HDMI 1.4a 和 2.0 协议标准 | |
| MIPI | 单通道:1280x800@60hz 双通道:2560x1600@60hz | 支持 DSI v1.1,DCS v1.1,DPHY v1.1 协议标准 准 | |
| eDP | 2560x1600@60hz | 支持 DP1.2a 和 eDP1.3 协议标准 | |
| HDMI | VOP BIG: 4096x2160@60hz VOP LIT: 2560x1600@60hz | 支持 HDMI 1.4a 和 2.0a 协议标准 |
| DP | VOP BIG: 3840x2160@60hz VOP LIT: 2560x1600@60hz | 支持 DP 1.3 协议标准 | |
|---|---|---|---|
| RV1109/RV1126 | RGB | 1920x1080@60hz | 支持 RGB888/RGB666/sRGB888/MCU/BT.1120 |
| MIPI | 1920x1080@60hz | 支持 DSI v1.1,DCS v1.1, DPHY v1.2 协议标准 | |
| RK356X | RGB | 1920x1080@60hz | 支持 RGB888/RGB666/sRGB888/MCU/BT.656/BT.1120 |
| MIPI | 单通道:1920x1080@60hz 双通道:2560x1600@60hz | 支持 DSI v1.1,DCS v1.1,DPHY v1.1 协议标准 准 | |
| eDP | 2560x1600@60hz | 支持 DP 1.2a 和 eDP 1.3 协议标准 | |
| HDMI | 4096x2160@60hz | 支持 HDMI 1.4a 和 2.0a 协议标准 | |
| RK3588 | RGB | 1920x1080@60hz | 支持 BT.656/BT.1120 |
| MIPI | 3840x2160@60hz | 支持 DSI v1.1,DCS v1.1, DPHY v2.0,CPHY V1.1 协议标准 | |
| eDP | 3840x2160@60hz | 支持 DP1.2a 和 eDP1.3 协议标准 | |
| HDMI | 7680x4320@60hz | 支持 HDMI 2.1 协议标准 | |
| DP | 7680x4320@30hz | 支持 DP1.4 协议标准 | |
| RV1103/RV1106 | RGB | 1280x720@60hz | 支持 RGB666/sRGB888/MCU/BT.656/BT.1120 |
4. 硬件相关
4.1 RGB输出/TTL模式硬件连接
4.1.1 VOP 1.0 RGB 接口硬件连接方式
-
判断是 VOP 1.0 还是 VOP 2.0 的设计,可以从 3.1 章节的 VOP version 中查询;
-
对于 SOC 支持 24bit RGB 输出的硬件连接方式3. 对于 SOC 支持 18bit RGB 输出的硬件连接方式
-
对于 VOP 1.0 中 MCU 接口 DATA 线连接方式和 RGB parallel 的连接方式一致,需要注意的是,RGB parallel中的 4 个时钟信号复用成 MCU 接口的控制信号,以下是具体的对应关系:
4.1.2 VOP 2.0 及之后的版本 RGB 接口硬件连接方式
4.1.3 不同 display mode index 对应的软件配置
4.1.4 BT.656 和 BT.1120 的硬件连接方式
根据接收端的 Y/U/V 处理顺序不同,如果出现显示颜色不对,还可以在 DTS 中调整不同的 bus_format 来适配,BT.656 和 BT.1120 分别有以下四种配置:
BT.656:
#define MEDIA_BUS_FMT_UYVY8_2X8 0x2006
#define MEDIA_BUS_FMT_VYUY8_2X8 0x2007
#define MEDIA_BUS_FMT_YUYV8_2X8 0x2008
#define MEDIA_BUS_FMT_YVYU8_2X8 0x2009
BT.1120:
#define MEDIA_BUS_FMT_UYVY8_1X16 0x200f
#define MEDIA_BUS_FMT_VYUY8_1X16 0x2010
#define MEDIA_BUS_FMT_YUYV8_1X16 0x2011
#define MEDIA_BUS_FMT_YVYU8_1X16 0x2012
MEDIA_BUS_FMT 的定义可以参考:
./include/uapi/linux/media-bus-format.h
4.2 LVDS Data Mapping
5. 扫描时序说明
5.1 常见的扫描时序图
5.2 DRM 对扫描时序的定义
5.3 软件配置的对应关系和转换
5.4 查看当前配置的时序
6. 带宽的计算方法
6.1 图像的带宽
以 1080P ARGB 格式的图像数据为例:
ARGB 格式一个像素占用的内存大小:4 Byte
1080P ARGB 格式的数据占用内存:1920 x 1080 x 4Byte/pixel = 8,100 Kbyte
如果按 60fps 刷新,占用的带宽是: 8,100 x 60fps = 474.6 Mbyte/s
如果数据格式改成 YUV420SP(NV12):
NV12 格式一个像素占用的内存大小:1.5 Byte
1080P NV12 格式的数据占用内存:1920 x 1080 x 1.5Byte/pixel = 3,037.5 Kbyte
如果按 60fps 新,占用的带宽是: 3,037.5 x 60fps = 178 Mbyte/s
6.2 显示接口的带宽
以上面这张图配置的时序为例,当前这个时序下,按 60帧刷新需要的 dclk 是:131994240 hz,dts 实际按取整132000000 hz 配置:
htotal = hfp + hsync + hbp + hactive = 15 + 2 + 30 + 1080 = 1,127
vtotal = vfp + vsync + vbp + vactive = 15 + 2 + 15 + 1920 = 1,952
dclk = htotal x vtotal x fps = 1127 x 1952 x 60fps = 131,994,240
MIPI 接口上传输的频率是:
132M x 3(RGB) x 8(bpc) / 4(lane) / 0.9 = 880 Mbps
其中:
x3(RGB): 是每一个 pixel 有 RGB 3个分量;
x8(bpc):是每一个分量的位深是 8bit;
/4(lane): 是这么多数据量在 4 lane 上传输,/4 是计算每 lane 的数据量;
/0.9: 是考虑 mipi 时序的传输效率;
7. 常用的 debug 手段
7.1 dump 当前的显示状态
7.1.1 使用命令
cat /sys/kernel/debug/dri/0/summary
7.1.2 参数说明
-
两个红色方框表示两个显示设备使用的 vop 分别是 ff900000.vop 和 ff8f0000.vop;
-
绿色部分表示 connector 信息,两个显示设备分别为 eDP 屏和 MIPI 屏;
-
粉色部分为显示模式,可以知道具体的时序、DCLK 以及帧率,上图中两个设备分别为分辨率为1536x2048p60 的 eDP 屏和分辨率 1280x720p29 的 MIPI 屏;
-
蓝色部分是 VOP 图层信息,第一个显示设备打开 win0 图层,大小为 1536x2048 格式为 XRGB 第二个显示设备打开 win0 图层,大小 1280x720 格式为XRGB, src 和 dst 表示源数据和显示的大小和位置,如果 src 和dst 的大小不一致,VOP 会进行缩放处理,如下图所示: 5. 橙色部分为 VOP HDR、CSC 的一些状态信息;
-
VOP2 平台的 summary 信息基本和之前平台的一致,只是把之前 VOP 改成了 Video Port,图层名字从原来的 winx, 变成了 Cluster-winx 或者 Esmart-winx:
7.2 dump当前显示的 buffer
为了确认应用送到显示的 buffer 是否正常,内核提供了节点用于 dump 当前正在显示的 buffer,需要通过在make menuconfig 打开 CONFIG_ROCKCHIP_DRM_DEBUG 启用该功能。
7.2.1 使用说明
7.3 调整 DRM 打印 Log 等级抓 Log
DRM 根据不同的接口设定以下几个打印等级,可以通过 DRM 的 debug 节点决定开关哪个接口的打印,比如我要查看 ATOMIC 的打印,就你可以输入命令:
echo 0x10 > /sys/module/drm/parameters/debug
如果想看到所有的调试信息,可以输入命令:
echo 0xff > /sys/module/drm/parameters/debug
其中 0x20 Bit5 对应的是 vsync相关的信息,这个打印的内容非常多,如果调试的时候不关注这个信息,一般不要设置这个 bit。
其他更多的打印等级可以查看下面的定义:
Enable debug output, where each bit enables a debug category.
Bit 0 (0x01) will enable CORE messages (drm core code)
Bit 1 (0x02) will enable DRIVER messages (drm controller code)
Bit 2 (0x04) will enable KMS messages (modesetting code)
Bit 3 (0x08) will enable PRIME messages (prime code)
Bit 4 (0x10) will enable ATOMIC messages (atomic code)
Bit 5 (0x20) will enable VBL messages (vblank code)
Bit 7 (0x80) will enable LEASE messages (leasing code)
Bit 8 (0x100) will enable DP messages (displayport code)
7.4 查看当前显示时钟
时钟是影响显示模块的关键因素之一,所以我们经常要获取当前系统提供的时钟是多少,可以通过以下命令获取:
- 获取整个时钟树
cat /sys/kernel/debug/clk/clk_summary
- 如果只关注 VOP 的时钟
cat /sys/kernel/debug/clk/clk_summary | grep vop
对于 HDMI/DP/VGA/CVBS 等显示接口,每个分辨率对应的 DCLK 是有严格的标准要求,如果 DCLK 时钟不对可能会出现无法显示或者出现显示兼容性问题,而对于 eDP/LVDS/MIPI/RGB 等显示接口一般有一定的余量。
7.5 强行开关显示设备
以LVDS为例:
关LVDS: echo off > /sys/class/drm/card0-LVDS-1/status
开LVDS: echo on > /sys/class/drm/card0-LVDS-1/status
7.6 查看 DRM buffer 使用情况
通过下面的命令可以知道通过 DRM GEM 申请的 buffer 使用情况:
cat /sys/kernel/debug/dri/0/mm_dump
7.7 查看 GPIO 状态
在项目刚开始 bring up 点屏阶段,经常需要通过控制 GPIO 的状态来控制屏或者背光的电源,我们可以通过以下命令确认软件配置的 GPIO 状态是否正确:
cat /sys/kernel/debug/gpio
7.8 modetest 的使用
modetest 是集成在 libdrm 中用来测试基于 libdrm 接口的测试程序,可能在以下几个场景中会用到 modetest:
- 芯片 bring up 阶段,显示驱动已经加载完成,上层显示框架或者GPU 未 ready 的时候可以用 modetest 测试显示模块2. 一些场景显示异常,可以通过 modetest 确认是驱动问题还是应用绘制问题3. 需要临时手动修改 drm 一些属性的值
可以参考以下使用说明:
7.9 显示进程的暂停、启动
有时候为了调试方便,希望应用停在某一个固定的场景,我们可以使用下面的命令在暂停和恢复显示进程。
Android Surfaceflinger 进程:
- 暂停进程
kill -STOP `pgrep surfaceflinger`
- 恢复进程
kill -CONT `pgrep surfaceflinger`
Linux weston进程:
- 暂停进程
Kill -STOP `pgrep weston`
- 恢复进程
kill -CONT `pgrep surfaceflinger`
7.10 获取 EDID 信息
以 HDMI 为例:
cat /sys/class/drm/card0-HDMI-A-1/edid > /data/edid.bin
7.11 查看 HDMI 状态
cat /sys/kernel/debug/dw-hdmi/status
7.11.1 参考例子
- dump 一帧当前显示的 buffer
echo dump > /sys/kernel/debug/dri/0/ff900000.vop/vop_dump/dump
- 连续 dump n 帧显示的 buffer
echo dumpn > /sys/kernel/debug/dri/0/ff900000.vop/vop_dump/dump
-
dump 出来的文件保存在 /data/vop_buf/,可以使用 7yuv 软件查看
-
以上路径加粗部分 [ff900000.vop] 在不同平台不一样,具体路径可以和 cat /d/dri/0/summary 节点的VOP/Video Port 对应,比如对于 RK3588 路径会变成:/sys/kernel/debug/dri/0/video_port0/dump
8. FAQ
8.1 如何开关 U-Boot logo 显示
以 MIPI DSI0 为例,可以在 dts 文件里找到 route_dsi0 节点,配置 status 状态:
8.2 如何配置 U-Boot logo 全屏或者居中显示
可以通过 dts route 节点下 logo,mode 配置,默认是 “center” 居中显示,如果是想要全屏显示修改成 “fullscreen”。
8.3 U-Boot logo 要求
- U-Boot logo 和内核 logo 的大小一致,偶数像素对齐;2. 支持 8bit 和 24bit bmp 图片;
8.4 U-Boot logo 切换到内核 logo 出现闪屏/无法显示问题
- 确认 DRM 驱动是否有正常加载
DRM 驱动加载过程中可能会出现一些资源没有准备好,导致 DRM 驱动 bind 失败,可能会出现类似以下log:
[ 1.792387] dw-mipi-dsi2 fde20000.dsi: [drm:dw_mipi_dsi2_bind] *ERROR* Failed to
find panel or bridge: -517
这个 log 说明此时 panel 或者 bridge 没准备好,正常框架会在一段时间后会重新开始 bind,但如果最后出现以下 log 说明此时 drm驱动已经加载成功了,这种情况我们就不需要太在意前面一两次 bind 失败的 log:
[ 2.566831] rockchip-drm display-subsystem: [drm] fb0: rockchipdrmfb frame
buffer device
如果开机 log 一直不停的刷 bind 失败的 log,那可能要检查的你 dts 配置,产品最经常遇到的是 GPIO 口被其他设备先注册、 panel 的 compatible 未正确配置导致 panel 注册失败、backlight 驱动注册失败等。
- DDR 变频导致
(1) 关闭 dts 文件中 DDR 变频节点,保证内核阶段不做 DDR 变频,修改方法如下:
&dmc {
status = “disabled”;
};
(2) 关闭 DDR 变频时对 DCLK 的调整,修改方法如下:
&dmc {
vop-dclk-mode = <1>;
};
- clk tree 变化导致
部分平台 U-Boot 中的 clk tree 配置和内核的 clk tree 配置是独立的,如果两个驱动的 clk 策略不一致,就会出现在 clk 重新初始化的时候出现闪屏问题,以RK3399 为例,可以按如下方法确认:
(1) 在rk3399_clk_init()@kernel/drivers/clk/rockchip/clk-rk3399.c 函数入口处加上 while(1);确认是否会有闪屏问题;
(2) 在rk3399_clk_init()@kernel/drivers/clk/rockchip/clk-rk3399.c 函数结束处加上 while(1),确认是否会有闪屏问题;
(3) 如果步骤 (1) 中无闪屏现象步骤 (2) 中有闪屏现象,那基本可以确认是 clk tree 变化导致闪屏问题,可以直接找对应平台 cru 负责人或者提交 redmine 并说明转给 pll 相关负责人。
- 时钟被关闭导致
有一些流程上的问题或者软件上的 bug 可能存在一些必要的时钟在驱动注册的时候没有被使能,导致这些时钟在内核跑完后被框架自动关闭从而导致显示异常,可以尝试按下面的修改默认不关闭时钟做测试:
在 dts 文件中,找到 chosen 节点,在 bootargs 末尾加上 clk_ignore_unused:如bootargs = "xxxx clk_ignore_unused”;5. U-Boot logo 图片和 kernel logo 图片大小不一致
rockchip 平台有要求 U-Boot logo 和 kernel logo 的图片分辨率大小一样,如果出现 U-Boot logo 显示正常,到内核阶段显示异常,可以确认下 kernel 目录下 logo.bmp 和 logo_kernel.bmp 分辨率是否一致;
- 内核初始化过程一些电源/GPIO 被重新初始化
该问题涉及的可能性很多,总之在新项目 porting 过程中要及时确认显示相关的 GPIO 电源是否和其他模块有冲突;
如果 DTS 确认无误,可以在内核代码搜索串口中的关键字,通过二分法在各个模块加载的位置 while 住,逐步确认导致闪屏问题的点;
- VOP优先级配置问题
如果 VOP 优先级没有被配置最高,有可能在内核加载阶段被其他IP抢占总线导致闪屏问题,该问题一般会在 SDK 发布前 Fix。
- 测试相关电源和信号
如果以上还未找到闪屏问题,请使用示波器抓取 CLK、DATA 和电源等相关信号从 U-Boot 到内核阶段的波形图并提交 redmine。
8.5 VOP POST_BUF_EMPTY
可能会出现类似以下 log:
可能原因有:
- 带宽不够
如果系统带宽不够会导致 VOP 不能及时取到数据,从而报 post buf empty,可以做如下尝试:
(1) 尝试将 ddr 固定最高频率;
(2) 将屏的消隐期加长,提高一行的取数时间;
- iommu 出错
确认是否如下图所示的 iommu pagefault 错误,如果有,请先尝试更新到最新代码测试,如果最新代码还存在该问题,请提交remine系统,并附上相关 log;3. Logic 电压太低
Logic 电压太低会导致 VOP 异常,可以尝试提高 100mv 测试;
- AFBDC/IFBDC 对齐要求
对于 PX30/RK3326、RK3368、RK3399、RK356X、RK3588 平台如果屏的分辨率非 16pixel 对齐可以尝试关闭 afbdc/ifbdc 功能,修改方法参考文档《FAQ-DRM-HWC》 1.3.1 章节。
8.6 显示效果调节
VOP 内部的 BCSH 模块支持亮度、对比度、饱和度、色度的调节,可以通过 modetest 配置 connector 下的对应属性调节,对于android 系统,有实现了基于安卓系统的属性配置默认值是50,N 每次+1。
android 9.0 之前使用命令:
setprop persist.sys.brightness.main val
setprop persist.sys.contrast.main val
setprop persist.sys.saturation.main val
setprop persist.sys.hue.main val
setprop sys.display.timeline N+1
android 9.0 及之后使用命令:
setprop persist.vendor.brightness.main val
setprop persist.vendor.contrast.main val
setprop persist.vendor.saturation.main val
setprop persist.vendor.hue.main val
setprop vendor.display.timeline N+1
从 Android 11 开始 SDK 有集成了整套显示效果调节工具和文档,可以参考 Android SDK 中的以下文档说明:
RKDocs/common/display/Rockchip_Introduction_DisplayAdjust_APK_CN.pdf
8.7 屏无法点亮/休眠唤醒显示异常/不显示问题
按以下几个方面做进一步确认:
- 确认是否有背光;2. 确认屏的相关电源及复位控制是否正常;3. 确认上下电时序是否满足屏的spec要求;
8.8 RK3308 如何打开显示功能
RK3308 默认不支持显示功能,如果需要开显示,需要做以下配置:
- U-Boot 修改2. kernel 修改
RK3308 VOP 不支持 IOMMU,所以分配内存需要从预留的 cma buffer 分配,默认 CMA_SIZE 为 16M,如果出现分配内存失败,可以参考如下方法修改CMA_SIZE:
8.9 关闭 iommu 的方法
关闭 vop iommu 后通过 DRM 申请的内存会从 CMA 内存分配,系统默认 CMA 内存大小16M,需要根据场景需求调整到对应的大小,否则会出现分配内存失败。
8.10 各种接口屏配置
请参考文档《Rockchip_DRM_Panel_Porting_Guide.pdf》、《RK3588_MIPI_DSI2_Developer_Guide_CN.pdf》。
8.11 RGB/MCU 屏帧率计算问题
已知:
htotal = hactive + hback-porch + hfront-porch + hsync-len
vtotal = vactive + vback-porch + vfront-porch + vsync-len
N 是每一个像素需要 N 个 cycly 发送完:
| bus format _ | 一个 Pixel 要 N 个 Cycle 发送 |
|---|---|
| MEDIA BUS FMT RGB888 1X24 _ _ _ _ MEDIA BUS FMT RGB666 1X18 _ _ _ _ MEDIA BUS FMT RGB565 1X16 _ _ _ _ | 1 |
| MEDIA BUS FMT RGB888 3X8 _ _ _ _ | 3 |
| MEDIA BUS FMT RGB888 DUMMY 4X8 _ _ _ _ _ | 4 |
根据以上信息,可以计算帧率:
| 接口类型 | 帧率计算 |
|---|---|
| RGB | fps = dclk / (htotal x vtotal x N) |
| MCU | fps = dclk / (htotal x vtotal x (mcu-pix-total + 1) x N) |
8.12 如何编写第三方转换芯片驱动
有些第三方转换芯片需要软件驱动的,这个时候我们需要借助 DRM 框架 bridge 接口向框架注册 connector,比如RGB2HDMI 的 SII902X 为例,此时 rockchip_rgb.c 充当 encoder 角色,sii902x.c 充当 connector 角色,具体可以参考 SII902X 驱动的实现:
drivers/gpu/drm/bridge/sii902x.c
8.13 VOP2 绑定每个 VP 所使用的图层
由于 VOP2 支持不同的 VP 共享图层,为了充分合理的使用所有图层资源,我们会根据当前产品 dts 配置的接口类型和数量在 U-Boot 中生成了一种默认的图层策略,如果有些产品没有开 U-Boot logo 显示或者对图层使用有特殊的需求,可以参考下面的写法在 dts 根据需求指定:
rockchip,plane-mask:指定当前 VP 使用的图层;
rockchip,primary-plane:指定 primary 图层,当前 VP 的 primary 图层一定是 rockchip,plane-mask 中的一个,我们一般选用 Smart 或者 Esmart 图层。
#include <dt-bindings/display/rockchip_vop.h>
&vp0 {
rockchip,plane-mask = <(1 << ROCKCHIP_VOP2_CLUSTER1 | 1 << ROCKCHIP_VOP2_SMART1)>;
rockchip,primary-plane = <ROCKCHIP_VOP2_SMART1>;
};
&vp1 {
rockchip,plane-mask = <(1 << ROCKCHIP_VOP2_CLUSTER0 | 1 << ROCKCHIP_VOP2_ESMART0 | 1
<< ROCKCHIP_VOP2_SMART0)>;
rockchip,primary-plane = <ROCKCHIP_VOP2_SMART0>;
};
&vp2 {
rockchip,plane-mask = <(1 << ROCKCHIP_VOP2_ESMART1)>;
rockchip,primary-plane = <ROCKCHIP_VOP2_ESMART1>;
};
对于一些 Linux 系统,可能还希望指定鼠标层或者希望 plane 和 crtc 是唯一绑定关系,可以在 VP 节点加入以下配置【如果你不了解这个需求,可以忽略这部分配置】:
&vp0 {
cursor-win-id = <ROCKCHIP_VOP2_CLUSTER0>;
};
&vop {
disable-win-move;
}
8.14 RK3588 DSC 支持几个 slice,slice width 最大支持多少
RK3588 有 2 个 DSC,HDMI0 和 DSI0 使用 DSC0(DSC_8K),最大支持 8 slice,最大的 slice width 是 960;HDMI0 和 DSI1 使用 DSC1(DSC_4K),最大支持 2 slice,最大的 slice width 是 2048。
8.15 RK3568 VP 和各显示接口的连接关系
8.16 RK3588 VP 和各显示接口的连接关系
8.17 超过 4kP60 对 aclk 的要求
对于类似 RK3588 这种支持的分辨率超过 4KP60 的【如 4KP120, 8KP30, 8KP60 等分辨率】,默认的 500M aclk 无法满足这些分辨率的需求,所以需要在 DTS 中设置 aclk 频率为 800M,否则会出现 VOP 性能不够导致的显示横条纹问题,修改方法如下:
&vop {
assigned-clocks = <&cru ACLK_VOP>;
assigned-clock-rates = <800000000>;
};
9. 参考文档
- Rockchip_drm_integration_helper-zh.pdf 2. Rockchip_DRM_Panel_Porting_Guide.pdf 3. Rockchip rk fb development guide.pdf 4. Wikipedia for Direct_Rendering_Manager 5. Linux DRM Developer's Guide