环境:
rk3566 android11
kernel 内核版本,4.19.172
问题描述:
hdmi热插拔相关的问题,当插入HDMI 系统开机启动,并正常运行,HDMI有显示且显示正常,进行热插拔也是没有问题的,当不插入HDMI接口系统启动后,再将HDMI显示接口插入HDMI显示无信号,也无法进行热插拔,无法正常显示画面。当系统启动一端时间后,再插入HDMI插入HDMI能够正常显示,且能够进行热插拔。
问题分析:
首先可以保证我们的HDMI显示驱动是没有问题的,因为我们HDMI是可以正常显示的,那么再来考虑热插拔的问题,以及HDMI中断插入脚是否检测有变化,是否能够检测到我们的HDMI插入变化,再来考虑硬件电路的问题。其逐个排查以上的猜想。
问题解决思路:
由上面的判断,可确认HDMI驱动显示部分是没有问题的,通过与硬件沟通,以及利用示波器量中断脚,当HDMI插入拔出时其HDMI的中断脚有电平的变化,HDMI插入时为高电平,拔出为低电平。分析插入HDMI启动系统与启动时不插入HDMI的kernel完全一样,HDMI的相关LOG完全相同,没有报错,且HDMI初始化正常。。。。。。,说实话到这感觉有点无语,无从下手解决该问题,但是没有办法继续干等着发货,思绪一波,突然发现:(重点)该项目外部显示接口比较多,有edp、hdmi、mipi、lvds显示接口,而rk3566只有一个显示控制器,即VOP,RK356X 平台只有一 VOP,但是分出不同的 PORT,RK3566 有 2 个 PORT 分别为 VP0、VP1。而我的项目上使用的是edp 与HDMI显示是通过VP0,而MIPI 与LVDS 使用的是VP1。而这就是设计到了多屏抢占与热插拔的问题了。而我们本文就是该问题引起的,我发现我的edp屏不管插入或是拔出其状态一直是处于连接状态,而在多屏抢占时,又将EDP设置的优先级设置的最高,这就导致了即使我们插入了HDMI无信号输出,而上面的问题也得以解释了,而上电初始化时,插入HDMI时,系统会优先加载HDMI显示模块,所以的HDMI就会有显示,且处于连接状态。
多屏抢占与热插拔分析:
display_subsystem: display-subsystem {
compatible = "rockchip,display-subsystem";
memory-region = <&drm_logo>, <&drm_cubic_lut>;
memory-region-names = "drm-logo", "drm-cubic-lut";
ports = <&vop_out>;
devfreq = <&dmc>;
route {
route_dsi0: route-dsi0 {
status = "disabled";
logo,uboot = "logo.bmp";
logo,kernel = "logo_kernel.bmp";
logo,mode = "center";
charge_logo,mode = "center";
connect = <&vp0_out_dsi0>;
};
route_dsi1: route-dsi1 {
status = "disabled";
logo,uboot = "logo.bmp";
logo,kernel = "logo_kernel.bmp";
logo,mode = "center";
charge_logo,mode = "center";
connect = <&vp0_out_dsi1>;
};
route_hdmi: route-hdmi {
status = "disabled";
logo,uboot = "logo.bmp";
logo,kernel = "logo_kernel.bmp";
logo,mode = "center";
charge_logo,mode = "center";
connect = <&vp1_out_hdmi>;
};
route_lvds: route-lvds {
status = "disabled";
logo,uboot = "logo.bmp";
logo,kernel = "logo_kernel.bmp";
logo,mode = "center";
charge_logo,mode = "center";
connect = <&vp1_out_lvds>;
};
route_edp: route-edp {
status = "disabled";
logo,uboot = "logo.bmp";
logo,kernel = "logo_kernel.bmp";
logo,mode = "center";
charge_logo,mode = "center";
connect = <&vp0_out_edp>;
};
route_rgb: route-rgb {
status = "disabled";
logo,uboot = "logo.bmp";
logo,kernel = "logo_kernel.bmp";
logo,mode = "center";
charge_logo,mode = "center";
connect = <&vp2_out_rgb>;
};
};
};
抢占:
route的节点是有顺序优先关系的, 如上, route_hdmi在route_mipi之前, 且它们都使用vopb做为显示输出, 当hdmi和mipi同接入时, hdmi会先将vopb抢走, 这样mipi就分配不到vop了, 现象为: hdmi显示, mipi不显示。
热拔插:
如上抢占内容可知, 当hdmi插入时, 现象为hdmi显示, mipi不显示.但当hdmi处于拔出状态时, route_hdmi这一路将不会工作, 也即可以实现;hdmi不显示, mipi显示.由此实现同一配置, 插入hdmi和拔出hdmi启动过程通路状态不同,这里我们将hdmi的抢占优先级设置为最高。
还有个重要的配置口,就是edp (hpd-gpios) 该gpio 属性。
hpd-gpios 对于 Box-to-box Connection,一般需要 HPD功能,需要配置该属性。
&edp {
status = "okay";
//force-hpd;
hpd-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
ports {
port@1 {
reg = <1>;
edp_out_edp: endpoint {
remote-endpoint = <&panel_in_edp>;
};
};
};
};
编译下载,问题得以解决!!
IBOX66:/d/dri/0 # cat summary //该目录下可查看显示连接状态
Video Port0: DISABLED
Video Port1: ACTIVE
Connector: LVDS-1
bus_format[1011]: RGB888_1X7X4_SPWG
overlay_mode[0] output_mode[0] color_space[0]
Display mode: 1280x800p60
clk[71100] real_clk[71100] type[48] flag[a]
H: 1280 1390 1400 1440
V: 800 810 813 823
Cluster0-win0: ACTIVE
win_id: 0
format: AB24 little-endian (0x34324241)[AFBC] SDR[0] color_space[0] glb_alpha[0xff]
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 800]
dst: pos[0, 0] rect[1280 x 800]
buf[0]: addr: 0x00000000017fc000 pitch: 5120 offset: 0
Esmart0-win0: ACTIVE
win_id: 4
format: AB24 little-endian (0x34324241) SDR[0] color_space[0] glb_alpha[0xff]
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 48]
dst: pos[0, 0] rect[1280 x 48]
buf[0]: addr: 0x0000000000bd8000 pitch: 5120 offset: 0
Video Port2: DISABLED