DisplayPort
前言
本文主要介绍 Rockchip 平台 DP 接口的使用与调试方法。
产品版本
芯片名称 | 内核版本 |
---|---|
RK3576 | LINUX Kernel 6.1 |
RK3588 | LINUX Kernel 5.10/6.1 |
读者对象
本文档(本指南)主要适用于以下工程师:
技术支持工程师
软件开发工程师
1. Rockchip 平台 DisplayPort 简介
1.1 功能特性
Rochchip RK3576 和 RK3588 DP 接口功能参数如下表格:
功能 | RK3576 | RK3588 |
---|---|---|
Version | 1.4a | 1.4a |
SST | Support | Support |
MST | Support | Not support |
DSC | Not support | Not support |
Max resolution | 4K@120Hz | 8K@30Hz |
Main-Link lanes | 1/2/4 lanes | 1/2/4 lanes |
Main-Link rate | 8.1/5.4/2.7/1.62 Gbps/lane | 8.1/5.4/2.7/1.62 Gbps/lane |
AUX_CH | 1M | 1M |
Color Format | RGB/YUV444/YUV422/YUV420 | RGB/YUV444/YUV422/YUV420 |
Color Depth | 8/10 bit(6bit just for RGB) | 8/10 bit(6bit just for RGB) |
Display Split Mode | Support | Support |
HDCP | HDCP2.2/HDCP1.3 | HDCP2.2/HDCP1.3 |
Type-C support | DP Alternate Mode | DP Alternate Mode |
I2S | Support | Support |
SPDIF | Support | Support |
HDR | Support | Support |
RK3576 只有一个物理 DP 接口,但在 MST 模式下内部能接受3 路显示数据流(为区分物理接口,用Stream-0, Stream-1, Stream-2 表示)。每路的最大输出能力如下:
DP Stream Channel | max width | max height | max pixel clock |
---|---|---|---|
Stream-0 | 4096 | 2160 | 1188MHz |
Stream-1 | 2560 | 1440 | 300MHz |
Stream-2 | 1920 | 1080 | 150MHz |
1.2 DP 与 VOP 连接关系
RK3576 的 VOP 有三个 Video Port, 一个 DP 控制器。在 MST 模式下,DP 控制器支持从 VOP 最多接收3 路的显示数据流。Stream-0/1/2 均可接收来自 Video Port0/1/2的显示数据。其中, 当工作在 SST 模式下时,只能使用 DP 控制器中的 Stream-0。 工作在 MST 模式下时, Stream-0/1/2都可 以使用。
RK3588 的 VOP 有四个 Video Port, 两个 DP 控制器,其中只有 Video Port 0/1/2 可以输出到 DP0/1, 如下图。
如 RK3588 两个 DP 接口不支持 MST 模式,并且内部只能接收一路显示数据 Stream-0。对于这种不支持 MST 的平台,默认 Video Port 输出输出到 DP 接口的 Stream-0。
1.3 DP 输出
根据应用场景的不同,可以设计不同的 DP 输出方式:Type-C 接口输出、DP 标准接口输出、通过其他转接芯片转接输出。
RK3576 在 MST 模式下,最多可以接 3 台显示器,可以通过 MST 显示器通过菊花链的方式串联,如下:
通过菊花链连接的显示器,只有最后一台显示器可以接 SST 显示器,其他的需要 MST 显示器。
另一种方式,可以通过 MST HUB 进行连接,如下:
通过 MST HUB 连接时, DP 显示器可以是 SST 显示器,也可以是 MST 显示器。
1.4 代码路径
U-Boot 驱动代码:
drivers/video/drm/dw-dp.c
drivers/phy/phy-rockchip-usbdp.c
Kernel 驱动代码:
drivers/gpu/drm/rockchip/dw-dp.c
drivers/phy/rockchip/phy-rockchip-usbdp.c
RK3576 参考 DTS 配置:
arch/arm64/boot/dts/rockchip/rk3576-evb1.dtsi
arch/arm64/boot/dts/rockchip/rk3576-test2.dtsi
RK3588 参考 DTS 配置:
arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4.dtsi
arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4.dtsi
arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi
arch/arm64/boot/dts/rockchip/rk3588-nvr-demo.dtsi
1.5 驱动加载
通过下面的log,判断驱动加载是否完成:
RK3576:
[1.991964] rockchip-drm display-subsystem: bound 27e40000.dp (ops 0xffffffc0094a1570) //DP 驱动加载完成
RK3588:
[2.472282] rockchip-drm display-subsystem: bound fde50000.dp (ops dw_dp_component_ops) //DP0 驱动加载完成
[2.472319] rockchip-drm display-subsystem: bound fde60000.dp (ops dw_dp_component_ops) //DP1 驱动加载完成
2. 功能配置
对于 DP 接口,支持 MST 和 不支持 MST 的平台 DTS 节点的基础配置存在差异。
不支持 MST 的平台,如 RK3588, 一个 DP 控制器只支持一路 DP 输出, 只需定义一个 ports 子节点描述这路 DP 可以支持的显示通路即可,DP 节点描述如下:
dp0: dp@fde50000 {
compatible = "rockchip,rk3588-dp";
...
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
dp0_in_vp0: endpoint@0 {
reg = <0>;
remote-endpoint = <&vp0_out_dp0>;
status = "disabled";
};
dp0_in_vp1: endpoint@1 {
reg = <1>;
remote-endpoint = <&vp1_out_dp0>;
status = "disabled";
};
dp0_in_vp2: endpoint@2 {
reg = <2>;
remote-endpoint = <&vp2_out_dp0>;
status = "disabled";
};
};
...
};
};
对于支持 MST的平台,如 RK3576,一个 DP 控制器要支持 3 路显示数据流输出,一个 ports 节点无法描述多个 DP 通道的显示通路,需要通过多个子节点描述, 配置如下:
dp: dp@27e40000 {
compatible = "rockchip,rk3576-dp";
...
dp0: dp0 {
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
dp0_in_vp0: endpoint@0 {
reg = <0>;
remote-endpoint = <&vp0_out_dp0>;
status = "disabled";
};
dp0_in_vp1: endpoint@1 {
reg = <1>;
remote-endpoint = <&vp1_out_dp0>;
status = "disabled";
};
dp0_in_vp2: endpoint@2 {
reg = <2>;
remote-endpoint = <&vp2_out_dp0>;
status = "disabled";
};
};
};
};
dp1: dp1 {
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
dp1_in_vp0: endpoint@0 {
reg = <0>;
remote-endpoint = <&vp0_out_dp1>;
status = "disabled";
};
dp1_in_vp1: endpoint@1 {
reg = <1>;
remote-endpoint = <&vp1_out_dp1>;
status = "disabled";
};
dp1_in_vp2: endpoint@2 {
reg = <2>;
remote-endpoint = <&vp2_out_dp1>;
status = "disabled";
};
};
};
};
dp2: dp2 {
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
dp2_in_vp0: endpoint@0 {
reg = <0>;
remote-endpoint = <&vp0_out_dp2>;
status = "disabled";
};
dp2_in_vp1: endpoint@1 {
reg = <1>;
remote-endpoint = <&vp1_out_dp2>;
status = "disabled";
};
dp2_in_vp2: endpoint@2 {
reg = <2>;
remote-endpoint = <&vp2_out_dp2>;
status = "disabled";
};
};
};
};
};
上述的 dp0/1/2 子节点,分别描述 DP 控制器中 Stream-0/1/2 可以支持的显示通路。
对比 DTS 的配置,支持 MST 的平台上多了一层 DP 通道的子节点。
2.1 使能 DP
DP 和 USB3.0 共用 PHY,PHY lane 的配置根据接口的不同有两种方式,Type-C 模式和非 Type-C 模式。
2.1.1 DP Alt Mode(Type-C)
根据 DisplayPort Alt Mode 协议,通过 PD (Power Delivery) 的状态机和显示器进行通信,进行 lane 的映射和 HPD 信息的传递。通过 PD 协议进入 DP Mode 并通过 attention 指令传递 HPD 信息的流程主要如下图所示。
不支持 MST 的平台,如 RK3588, 配置如下:
&dp0 {
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
在上面的配置中,使能了 DP0 接口,并把 DP0 绑定到 VOP 的 Video Port2,这只是一种参考配置,实际使用过程中,可以根据实际的需求,使能 DP0 或 DP1, 并把 DP0 或 DP1 绑定到期望的 Video Port(0/1/2) 上。
支持 MST 的平台,如 RK3576, 配置如下:
&dp {
status = "okay";
};
&dp0 {
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
可以看到,支持 MST 的平台,需要使能 DP 设备节点,要开启的 DP Stream 通道,以及该通道要绑定的 VOP 上的 Video Port。上述的配置中,即使了 DP 接口的 Stream-0,并把 Stream-0 绑定到 VOP 的Video Port2。
需要注意的是,支持 MST 的平台,因为 SST 模式下一定要使用 DP Steam-0, 所以 dp0 节点是一定要使能的。dp1 和 dp2 根据使用情况进行配置。
PHY 配置如下,支持 MST 和 不支持 MST 的平台无差异,参考如下 RK3588 usbdp phy0 的配置:
&usbdp_phy0 {
status = "okay";
orientation-switch;
/* DP related config */
svid = <0xff01>;
sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
/* DP related config */
port {
#address-cells = <1>;
#size-cells = <0>;
usbdp_phy0_orientation_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_orien_sw>;
};
/* DP related config */
usbdp_phy0_dp_altmode_mux: endpoint@1 {
reg = <1>;
remote-endpoint = <&dp_altmode_mux>;
};
/* DP related config */
};
};
sbu1-dc-gpios 和 sbu2-dc-gpios :
Type-C 的 SBU1 和 SBU2 引脚是和 DP 的 AUX_CH 复用的,在 Type-C 正插时, AUX_CH_P 复用SBU1,AUX_CH_N 复用 SUB2。在 Type-C 反插时,AUX_CH_P 复用 SBU2, AUX_CH_N 复用 SBU1。 根据 DP 协议要求,AUX_CH_P 需要配置为下拉状态,AUX_CH_N 需要配置成上拉状态。Type-C 不同的插入状态(正插和反插) AUX_CH_N 和 AUX_CH_P 的复用配置是不一样的,在 RK 方案上,是通过两个GPIO 来分别控制 SBU1 和 SBU2 的上下拉状态,即 dts 中的 sbu1-dc-gpios 和 sbu2-dc -gpios。因此,在配置 PHY 时,需要配置 sbu1-dc-gpios 和 sbu2-dc-gpios (实际配置这两个 GPIO 的时候要参照硬件设计的原理图,例如下图的 TYPEC0_SBU1_DC 和 TYPEC0_SBU2_DC), PHY 驱动会根据当前的Type-C 正反插状态去调整 GPIO 输出的电平。
svid :
对 DP 来说是固定值 0xff01。
Type-C 接口需要通过 Type-C 的 CC 检测和 PD 协商来配置 lane 和 HPD 的状态, 所以还需要配置 PD芯片:
&i2c2 {
status = "okay";
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio3>;
interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
vbus-supply = <&vbus5v0_typec>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_role_sw: endpoint@0 {
remote-endpoint = <&dwc3_0_role_switch>;
};
};
};
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
<PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
source-pdos =
<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
/* DP related config */
altmodes {
#address-cells = <1>;
#size-cells = <0>;
altmode@0 {
reg = <0>;
svid = <0xff01>;
vdo = <0xffffffff>;
};
};
/* DP related config */
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_orien_sw: endpoint {
remote-endpoint = <&usbdp_phy0_orientation_switch>;
};
};
/* DP related config */
port@1 {
reg = <1>;
dp_altmode_mux: endpoint {
remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
};
};
/* DP related config */
};
};
};
};
altmode@0 节点中, svid 固定配置为 0xff01, vdo 固定配置为 0xffffffff。
Note: 当前支持的 PD 芯片为 fusb302, hub311。fusb302 对应的驱动为/drivers/usb/typec/tcpm/fusb302.c, hub311 对应的驱动为/drivers/usb/typec/tcpm/tcpci_husb311.c。
2.1.2 DP Legacy Mode
非 Type-C 接口输出,无论是 DP 接口,还是通过其他的转接芯片输出,配置流程基本一致,并且都需要配置 HPD Pin。 在实际分配 IO 引脚的时候,可以使用DP_HPD 专用引脚, 这种情况按 IOMUX 进行配置,还可以使用普通的 GPIO 进行检测。
对于不支持 MST 的平台,如 RK3588, 使用 DP_HPD Pin 的时候配置如下:
&dp1 {
pinctrl-0 = <&dp1m2_pins>;
pinctrl-names = "default";
status = "okay";
};
&dp1_in_vp2 {
status = "okay";
};
使用普通 GPIO 作 HPD 检测的时候配置如下:
&dp1 {
pinctrl-names = "default";
pinctrl-0 = <&dp1_hpd>;
hpd-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&dp1_in_vp2 {
status = "okay";
};
&pinctrl {
dp {
dp1_hpd: dp1-hpd {
rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
};
对于支持 MST 的平台,比如RK3576, 使用 DP_HPD Pin 的时候配置如下:
&dp {
pinctrl-0 = <&dp1m2_pins>;
pinctrl-names = "default";
status = "okay";
};
&dp0 {
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
使用普通 GPIO 作 HPD 检测的时候配置如下:
&dp {
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>;
hpd-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&dp0 {
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
&pinctrl {
dp {
dp_hpd: dp-hpd {
rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
};
上述支持 MST 平台和 不支持 MST 平台的配置中,HPD 的配置是属于整个 DP 接口的配置,均配置在设备节点下。
DP 和 USB 3.0 共用 PHY,当 DP 为 非 Type-C 接口输出时,就需要指定 lane 配置给 DP 使用以及对应的 lane 序号,这部分内容在 DTS 中指定。对于 DP PHY lane 的配置,可以配置成 2 lane 模式或 4 lane 模式。
PHY lane 接口的物理编号如下图所示:
对于 DP 配置 4 lane, dtsi 配置属性如下:
rockchip,dp-lane-mux = <x x x x>;
对于 DP 配置 2 lane, dtsi 配置属性如下:
rockchip,dp-lane-mux = <x x>;
其中,索引为 DP 的 lane, 值为 PHY 的 lane。 无论 2 lane 还是 4 lane 配置,硬件设计时一般使用如下的 OPTION1 或 OPTION2 两种中的一种。
对于 DP 4 lane 的 OPTION1 映射关系如下:
其中 DP lane 为 DP 的 lane 的序号。 dts 的配置如下:
&usbdp_phy1 {
rockchip,dp-lane-mux = <0 1 2 3>;
status = "okay";
};
对于 DP 4 lane 的 OPTION2 映射关系如下:
其中 DP lane 为 DP 的 lane 的序号。 dts 的配置如下:
&usbdp_phy1 {
rockchip,dp-lane-mux = <2 3 0 1>;
status = "okay";
};
对于 DP 2 lane 的 OPTION1 映射关系如下:
DP 2 lane 的配置如下:
&usbdp_phy1 {
rockchip,dp-lane-mux = <2 3>;
status = "okay";
};
对于 DP 2 lane 的 OPTION2 映射关系如下:
DP 2 lane 的配置如下:
&usbdp_phy1 {
rockchip,dp-lane-mux = <0 1>;
status = "okay";
};
2.2 DP 接 Panel 外设
使用 DP 接口接 eDP Panel 时,eDP 独有的特性无法支持,比如 PSR, Multi-SST, ALPM。Panel 的配置可以参考如下,并根据实际的硬件设计进行调整:
对于不支持 MST 的平台,如 RK3588 配置:
/{
...
panel-edp {
compatible = "simple-panel";
backlight = <&backlight>;
power-supply = <&vcc3v3_lcd_edp>;
prepare-delay-ms = <120>;
enable-delay-ms = <120>;
unprepare-delay-ms = <120>;
disable-delay-ms = <120>;
width-mm = <120>;
height-mm = <160>;
panel-timing {
clock-frequency = <200000000>;
hactive = <1536>;
vactive = <2048>;
hfront-porch = <12>;
hsync-len = <16>;
hback-porch = <48>;
vfront-porch = <8>;
vsync-len = <4>;
vback-porch = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
port {
panel_in_edp: endpoint {
remote-endpoint = <&dp0_out>;
};
}; };
... };
&dp0 {
force-hpd;
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
&dp0_out {
remote-endpoint = <&panel_in_edp>;
};
&usbdp_phy0 {
rockchip,dp-lane-mux = <0 1 2 3>;
status = "okay";
};
对于支持 MST 的平台,如 RK3576 对应的配置参考如下:
/ {
...
panel-edp {
compatible = "simple-panel";
backlight = <&backlight>;
power-supply = <&vcc3v3_lcd_edp>;
prepare-delay-ms = <120>;
enable-delay-ms = <120>;
unprepare-delay-ms = <120>;
disable-delay-ms = <120>;
width-mm = <120>;
height-mm = <160>;
panel-timing {
clock-frequency = <200000000>;
hactive = <1536>;
vactive = <2048>;
hfront-porch = <12>;
hsync-len = <16>;
hback-porch = <48>;
vfront-porch = <8>;
vsync-len = <4>;
vback-porch = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
port {
panel_in_edp: endpoint {
remote-endpoint = <&dp0_out>;
};
};
};
...
};
&dp0 {
force-hpd;
status = "okay";
};
&dp0 {
status = "okay";
ports {
port@1 {
reg = <1>;
dp0_out_panel: endpoint {
remote-endpoint = <&panel_in_edp>;
};
};
};
};
&dp0_in_vp2 {
status = "okay";
};
&usbdp_phy {
rockchip,dp-lane-mux = <0 1 2 3>;
status = "okay";
};
上述配置中,force-hpd
是描述整个 DP 接口 HPD 的属性,要放在设备节点下。显示通路的配置和具体的 DP 显示通路有关,所以 MST 的平台需要修改具体的显示通路子节点。
对于支持 MST 的平台,目前接 panel 时只能工作在 SST 模式下,所以显示通路只能使用 Stream-0,对应 dp0 节点。
上述的配置中,dp0 节点中的 force-hpd
的属性配置后,驱动默认 eDP panel 都是处于连接的状态,这个属性不是必须的,要根据具体的屏是否有 HPD 引出,HPD 拉高和 AUX 访问是否有时序要求等确认是否要配置 force-hpd
属性。如果 panel 要求 AUX 的访问必须在 HPD 拉高之后,就不能配置 force-hpd
属性,否则有可能出现 HPD 未拉高之前就访问 AUX,导致 AUX 访问失败。如果还是需要配置 HPD 引脚,参考 1.2.1 DP Legacy Mode 的 HPD 的配置。
panel-timing
配置当前支持的 timing,如果 eDP panel 没有 EDID,或者 EDID 读到的 timing 不准,就需要配置 panel-timing
节点,否则可以不用配置,直接通过读 EDID 获取。
上下电时序和背光根据具体的屏幕和硬件设计进行配置。
2.3 DP 开机 logo
配置开机 logo 后,如果在开机前就插入 DP 显示器,即可 在 U-Boot 阶段就开始显示 logo,否则,只能等到系统启动后才能看到应用显示的图像。添加 DP 开机 logo 支持的配置如下:
&route_dp0 {
status = "okay";
connect = <&vp2_out_dp0>;
};
需要注意的是,这里的 connect
属性配置 DP 在 U-Boot 阶段绑定 VOP Port2,所以 dtsi 中的配置要允许 DP 绑定 VOP Port2。
&dp0_in_vp2 {
status = "okay";
};
Note:
- 目前不支持 Type-C 接口的 DP 开机 logo。
- 对于支持 MST 的平台,开机 LOGO 只支持在 SST 模式下显示。
2.4 DP connector-split mode
DP connector-split mode 如图所示,一幅图像被平分成左右两部分,并分别通过 DP0/DP1 接口传输给显示器,下图中 DP0 作为左半屏,DP1 作为右半屏。
配置如下:
&dp0 {
split-mode;
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
&dp1 {
status = "okay";
};
在作为左半屏的 DP 节点加入 split-mode
属性,并绑定要输出的 Video Port,在如上的配置中,即 DP0 作为左边屏,DP1 作为右半屏。在 Split Mode 模式下,两个 DP 当作一个 connector,只有 DP0 和 DP1 同时连接时,这个 connector 才处于连接状态,才会开始显示,只要有一个 DP 接口处于断开状态,connector 即处于断开状态,不会输出显示。在该模式下,两个 DP 接口输出的时序是一样的,建议使用两个一样的显示器。
在用户空间下,通过 modetest
或者 cat dri
的 state 节点(cat /sys/kernel/debug/dri/0/state
),只会看到一个 DP connector。
如果要在 split mode 下显示 U-boot logo,比如 DP0 作左半屏,需要添加的参考配置如下:
&route_dp0 {
split-mode;
status = "okay";
connect = <&vp2_out_dp0>;
};
&route_dp1 {
status = "disabled";
}
Note: RK3576 只有一个接口不支持这种方式的 connector-split mode,后续补充 RK3576 支持的 split mode 功能,如果有 RK3576 上的 split-mode 功能需求,请联系 Rockchip。
2.5 HDR
HDR 功能默认在 SST 模式下支持,驱动不需要配置,MST 下的 HDR 功能暂不支持。
2.6 HDCP
DP 驱动基于 DRM 框架实现 HDCP 功能,用户使用 HDCP 功能需要在 userspace 调用 DRM 的接口实现。
- HDCP1.3 DP 驱动默认支持,无需配置,HDCP Key 的烧录参考《Rockchip_RK3588_Developer_Guide_HDCP_CN》。
- HDCP2.2 有单独的 HDCP2 控制器来控制 HDCP 的认证,使能 HDCP2 控制器需要配置 dts。
在 RK3588 上,DP0/DP1 和 HDCP0 相连,如下图:
使能 DP HDCP2.2 功能,需要使能如下节点:
&hdcp0 {
status = "okay";
};
在 RK3576 上,DP 和 HDCP1 相连,如下下图:
使能 DP HDCP2.2 功能,需要使能如下节点:
&hdcp1 {
status = "okay";
};
使用 HDCP2.2 除了驱动配置外,还需使能 userspace 的 HDCP2.2 的应用程序及生成 HDCP 控制器的固件,参考《Rockchip_RK3588_Developer_Guide_HDCP_CN》。
3. 常用 DEBUG 方法
3.1 查看 connector 状态
在 /sys/class/drm
目录下可以看到驱动注册的各个 card,在如下显示的内容汇总,card0-DP-1
和 card0-DP-2
是 DP 显示设备。
rk3588_s:/ # ls /sys/class/drm/
card0 card0-DP-2 card0-HDMI-A-1 card0-Writeback-1 renderD128 version
card0-DP-1 card0-DSI-1 card0-HDMI-A-2 card1 renderD129
以 card0-DP-1
为例,其目录下有如下内容:
rk3588_s:/ # ls /sys/class/drm/card0-DP-1/
device dpms edid enabled modes power status subsystem uevent
enable 查看使能状态:
rk3588_s:/ # cat /sys/class/drm/card0-DP-1/enabled
disabled
status 查看连接状态:
rk3588_s:/ # cat /sys/class/drm/card0-DP-1/status
disconnected
modes 设备支持的分辨率列表:
rk3588_s:/ # cat /sys/class/drm/card0-DP-1/modes
1440x900
1280x1024
1280x1024
1280x960
1152x864
1024x768
1024x768
832x624
800x600
800x600
640x480
640x480
720x400
edid
设备的 EDID,通过如下命令保存:
rk3588_s:/ # cat /sys/class/drm/card0-DP-1/edid > /data/edid.bin
3.2 强制使能/禁用 DP
# 强制禁用 DP
rk3588_s:/ # echo off > /sys/class/drm/card0-DP-1/status
# 强制使能 DP
rk3588_s:/ # echo on > /sys/class/drm/card0-DP-1/status
# 恢复热插拔检测
rk3588_s:/ # echo detect > /sys/class/drm/card0-DP-1/status
3.3 DPCP 读写
DPCP 通过 AUX_CH 读写,读写节点的实现在 /drivers/gpu/drm/drm_dp_aux_dev.c
。
使用此功能前,先确认相关的编译选项是否已经配置:
CONFIG_DRM_DP_AUX_CHARDEV=y
读取 DPCD 如下:
#if 后面为 aux 节点,当注册两个 DP 接口时,会有 /dev/drm_dp_aux0 和 /dev/drm_dp_aux1
#skip 值为起始的 DPCD 寄存器地址
#count 值为要读取的 DPCD 寄存器的数量
dd if=/dev/drm_dp_aux0 bs=1 skip=$((0x00200)) count=2 status=none | od -tx1
写入 DPCD 寄存器:
#echo 后为要写入的值,如下为需要写入两个 16 进制的值,分别为 0x0a, 0x80
#of 后为 aux 节点,当注册两个 DP 接口时,会有 /dev/drm_dp_aux0 和 /dev/drm_dp_aux1
#seek 后为起始的 DPCD 寄存器地址
#count 值为要写入的 DPCD 寄存器的数量
#如下指令为把 0x0a 和 0x80 两个值写入 0x100 起始的两个 DPCD 寄存器处
echo -e -n "\x0a\x80" | dd of=/dev/drm_dp_aux0 bs=1 seek=$((0x100)) count=2 status=none
3.4 Type-C 接口 Debug
Type-C 接口的 HPD 检测部分由 PD 芯片完成,这部分的软件流程主要由 TCPM 的框架完成,TCPM 检测这部分 log 可以由以下方式获取:
rk3588_s:/ # ls -l /sys/kernel/debug/usb/
total 0
-r--r--r-- 1 root root 0 1970-01-01 00:00 devices
drwxr-xr-x 18 root root 0 1970-01-01 00:00 fc000000.usb
drwxr-xr-x 2 root root 0 1970-01-01 00:00 fc400000.usb
-r--r--r-- 1 root root 0 1970-01-01 00:00 fusb302-2-0022
drwxr-xr-x 4 root root 0 1970-01-01 00:00 ohci
-r--r--r-- 1 root root 0 1970-01-01 00:00 tcpm-2-0022
drwxr-xr-x 2 root root 0 1970-01-01 00:00 usbmon
drwxr-xr-x 2 root root 0 2021-01-01 12:00 uvcvideo
drwxr-xr-x 3 root root 0 1970-01-01 00:00 xhci
在 /sys/kernel/debug/usb/
目录中,可以看到 fusb302-2-0022
和 tcpm-2-0022
,其中 fusb302-2-0022
为 PD 芯片的节点,tcpm-2-0022
为 TCPM 框架的节点,获取 TCPM 框架的 log 命令如下:
cat /sys/kernel/debug/usb/tcpm-2-0022
Note: tcpm-2-0022
,中间的 2
为对应的 i2c 总线,最后的 0022
为 PD 芯片对应的 i2c 地址。
获取 PD 芯片的 log 如下:
cat /sys/kernel/debug/usb/fusb302-2-0022
Note: fusb302-2-0022
,中间的 2
为对应的 i2c 总线,最后的 0022
为 PD 芯片对应的 i2c 地址,上述节点对应 fusb302 芯片,不同芯片节点名称不一样。
除了 log 外,在 Type-C 节点下还可以获取其他的一些信息,Type-C 节点路径如下:
console:/ # ls /sys/class/typec
port0 port0-partner
port0 表示 SoC 这端的 Type-C 接口, port0-partner 表示通过 Type-C 连接设备后设备端的节点目录。
Type-C 连接的正反面信息:
cat /sys/class/typec/port0/orientation
reverse
port0-partner
下可能有多个目录,对于 DP Alt Mode 对应的目录,其对应的目录先会有 displayport
子目录,并且 svid
的值为 0xff01
。
ls -l /sys/class/typec/port0-partner/port0-partner.0/
total 0
-r--r--r-- 1 root root 4096 2022-04-14 14:50 active
-r--r--r-- 1 root root 4096 2022-04-14 14:50 description
drwxr-xr-x 2 root root 0 2022-04-14 14:50 displayport
lrwxrwxrwx 1 root root 0 2022-04-14 14:50 driver ->
../../../../../../../../../bus/typec/drivers/typec_displayport
-r--r--r-- 1 root root 4096 2022-04-14 14:50 mode
drwxr-xr-x 2 root root 0 2022-04-14 14:50 mode1
lrwxrwxrwx 1 root root 0 2022-04-14 14:50 port -> ../../port0.0
drwxr-xr-x 2 root root 0 2022-04-14 14:50 power
lrwxrwxrwx 1 root root 0 2022-04-14 14:50 subsystem ->
../../../../../../../../../bus/typec
-r--r--r-- 1 root root 4096 2022-04-14 14:50 svid
-rw-r--r-- 1 root root 4096 2022-04-14 14:50 uevent
-r--r--r-- 1 root root 4096 2022-04-14 14:50 vdo
cat /sys/class/typec/port0-partner/port0-partner.0/svid
ff01
获取当前的 pin assignment 信息:
cat /sys/class/typec/port0-partner/port0-partner.0/displayport/pin_assignment
C [D]
#当前连接的设备支出 C assignment 和 D assignment, 目前配置的是 D assignment
Note: 以上描述的是使用 TCPM 框架的 PD 芯片的相关信息获取,若搭配使用的 PD 芯片不是基于 TCPM 框架,请同 PD 芯片 vendor 确认相关信息。
3.5 查看 DP 寄存器
RK3588 DP 相关寄存器:
#dp0 控制器
cat /sys/kernel/debug/regmap/fde50000.dp/registers
#usbdp phy0
cmn_reg0000 - cmn_reg015D:
io -4 -r -l 1400 0xfed88000
trsv_reg0200 - trsv_reg03C3:
io -4 -r -l 1808 0xfed88800
trsv_reg0400 - trsv_reg0435:
io -4 -r -l 212 0xfed89000
trsv_reg0600 - trsv_reg07C3:
io -4 -r -l 1808 0xfed89800
trsv_reg0800 - trsv_reg0835:
io -4 -r -l 212 0xfed8A000
#dp1 控制器
cat /sys/kernel/debug/regmap/fde60000.dp/registers
#usbdp phy1
cmn_reg0000 - cmn_reg015D:
io -4 -r -l 1400 0xfed98000
trsv_reg0200 - trsv_reg03C3:
io -4 -r -l 1808 0xfed98800
trsv_reg0400 - trsv_reg0435:
io -4 -r -l 212 0xfed99000
trsv_reg0600 - trsv_reg07C3:
io -4 -r -l 1808 0xfed99800
trsv_reg0800 - trsv_reg0835:
io -4 -r -l 212 0xfed9A000
# vo0_grf
cat /sys/kernel/debug/regmap/dummy-syscon@fd5a6000/registers
RK3576 DP 相关寄存器:
#dp 控制器
cat /sys/kernel/debug/regmap/27e40000.dp/registers
#usbdp phy
cmn_reg0000 - cmn_reg015D:
io -4 -r -l 1400 0x2b018000
trsv_reg0200 - trsv_reg03C3:
io -4 -r -l 1808 0x2b018800
trsv_reg0400 - trsv_reg0435:
io -4 -r -l 212 0x2b019000
trsv_reg0600 - trsv_reg07C3:
io -4 -r -l 1808 0x2b019800
trsv_reg0800 - trsv_reg0835:
io -4 -r -l 212 0x2b01a000
# vo1_grf
cat /sys/kernel/debug/regmap/dummy-syscon@0x0000000026036000/registers
Note: 需要在连接 DP 显示器并正常显示时,才能 dump phy 寄存器。
3.6 查看 VOP 状态
通过如下指令即可查询 VOP 的状态:
cat /sys/kernel/debug/dri/0/summary
获取的 VOP 状态如下图:
Video Portx: 表示当前的 Video Port 的状态
Connector: Video Port 当前连接的输出接口
Display mode: Video Port 当前输出时序
Clusterx-winx(Esmartx-winx): 图层信息
在 Kernel 6.1 及以上版本,获取的信息如下:
root@linaro-alip:/# cat /sys/kernel/debug/dri/0/summary
Video Port0: ACTIVE
Connector:DP-2 Encoder: DP-MST 0
bus_format[100a]: RGB888_1X24
overlay_mode[0] output_mode[f] SDR[0] color-encoding[BT.709] color
range[Limited]
Display mode: 1280x720p60
clk[74250] real_clk[74250] type[0] flag[5]
H: 1280 1390 1430 1650
V: 720 725 730 750
Esmart0-win0: ACTIVE
win_id: 0
format: XR24 little-endian (0x34325258) pixel_blend_mode[0]
glb_alpha[0xff]
color: SDR[0] color-encoding[BT.601] color-range[Limited]
rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
csc: y2r[0] r2y[0] csc mode[0]
zpos: 0
src: pos[0, 0] rect[1280 x 720]
dst: pos[0, 0] rect[1280 x 720]
buf[0]: addr: 0x0000000001017000 pitch: 5120 offset: 0
Video Port1: ACTIVE
Connector:DP-5 Encoder: DP-MST 1
bus_format[100a]: RGB888_1X24
overlay_mode[0] output_mode[f] SDR[0] color-encoding[BT.709] color
range[Limited]
Display mode: 1280x720p60
clk[74250] real_clk[74250] type[0] flag[5]
H: 1280 1390 1430 1650
V: 720 725 730 750
Esmart1-win0: ACTIVE
win_id: 1
format: XR24 little-endian (0x34325258) pixel_blend_mode[0]
glb_alpha[0xff]
color: SDR[0] color-encoding[BT.601] color-range[Limited]
rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
csc: y2r[0] r2y[0] csc mode[0]
zpos: 1
src: pos[0, 0] rect[1280 x 720]
dst: pos[0, 0] rect[1280 x 720]
buf[0]: addr: 0x00000000001e1000 pitch: 5120 offset: 0
Video Port2: ACTIVE
Connector:DP-6 Encoder: DP-MST 2
bus_format[100a]: RGB888_1X24
overlay_mode[0] output_mode[f] SDR[0] color-encoding[BT.709] color
range[Limited]
Display mode: 1280x720p60
clk[74250] real_clk[74250] type[0] flag[5]
H: 1280 1390 1430 1650
V: 720 725 730 750
Esmart2-win0: ACTIVE
win_id: 2
format: XR24 little-endian (0x34325258) pixel_blend_mode[0]
glb_alpha[0xff]
color: SDR[0] color-encoding[BT.601] color-range[Limited]
rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
csc: y2r[0] r2y[0] csc mode[0]
zpos: 2
src: pos[0, 0] rect[1280 x 720]
dst: pos[0, 0] rect[1280 x 720]
buf[0]: addr: 0x00000000015e2000 pitch: 5120 offset: 0
可以看到,Summary 多了 Encoder 信息。
在 RK3576 下,注册了 1 个 SST 模式下的 Encoder 和 3 个 MST 模式下的 Encoder,其中 3 个 MST Encoder 和 DP 3 路的显示数据流对应关系如下:
DP-MST 0 --> Stream-0
DP-MST 1 --> Stream-1
DP-MST 2 --> Stream-2