cover_image

开源鸿蒙系列:RK平台eDP+DP转HDMI双显适配

TJ/LC 酷派技术团队
2024年07月22日 07:43

前  言


近日,我们顺利完成了某头部金融终端平板与 OpenHarmony 的适配工作。此款平板能够通过拓展的方式连接各类外设,例如 HDMI 显示器。经过数月的努力,我们成功实现了这一新形态的适配,充分展现了酷派在开源鸿蒙领域所具备的创新能力,同时也为开源鸿蒙生态系统注入了专业应用。

本文基于的软硬件信息如下:

RK3588 OpenHarmony 4.0 + Linux 5.10

着重介绍eDP + DP转HDMI双显的适配过程。

RK3588 显示架构

在介绍适配之前,让我们先来了解下RK3588的显示子系统,RK3588采用VOP 2.0设计,硬件架构如下图:

图片

从上图可以看到,整个显示通路的最后端包含了由RGA,GPU和VPU组成的图形显示加速模块用来进⾏图像的⽣成和处理,其中RGA对图像进⾏缩放,旋转,合成等 2D 处理,GPU完成渲染,VPU进行高效视频解码,处理后的数据放到DDR中,然后由VOP(视频输出处理器)读取,根据应用需要进行相应处理后输出到对应的显⽰接口(如HDMI/DP等), 最后送到显⽰器或屏幕上。

VOP 2.0架构下只存在一个 VOP, 但是有多个独立的VP口,如上图有三路VP,可以实现三屏异显。而RK3588有四路VP,两个DP控制器,如下图所示,只有VP0/1/2路可以输出到DP0/1。 

图片

平板显示连接

平板显示由两部分组成:一个是内置eDP屏,另一个是DP通过拓展连接到HDMI显示器,DP转接HDMI输出示意图如下:

图片

本文主要讲解的就是这种双屏显示场景的适配,底版本eDP单显输出正常。


双屏适配


DTS 配置

DP配置有两种模式:一个是type-c模式(DP Alt mode),另一个是非type-c模式(DP legacy mode)。我们这里适配的是DP legacy mode,使用的是第二个DP,在DTS里是dp1,使能配置如下:

&dp1 {        status = "okay";    ......};

配置vp1连接dp1显示接口:

&vp1 {        vp1_out_dp1: endpoint@3 {                reg = <3>;                remote-endpoint = <&dp1_in_vp1>;        };        ......}

连接通路配置是dp1_in_vp1

dp1_in_vp1: endpoint@1 {        reg = <1>;        remote-endpoint = <&vp1_out_dp1>;        status = "okay";};

配置完成查看VOP状态,如下图VP1连接DP-2(也就是DTS的dp1), VP2连接eDP显示:

图片

Linux 驱动移植

底版本内核DRM驱动有如下图红框处问题:

图片

需移植三方驱动,在移植开始前,先了解下整个DRM的显示通路:

图片

这里crtc是显示控制器,对应VOP的video port,encoder/bridge负责显示输出转换,最终通过connector送到显示屏幕上。

在对显示通路有了一个基本的认识后我们来移植DRM驱动,还包含一份phy,代码位于:

drivers/gpu/drm/rockchip/drivers/gpu/drm/bridge/analogix/drivers/gpu/drm/bridge/synopsys/drivers/phy/rockchip/

移植完成后有如下图红框处log表示DP连接成功:

图片

也可以通过sys节点确认:

cat /sys/class/drm/card0-DP-2/statusconnected

此时HDMI仍未点亮,按照惯例,我们使用modetest测试如下图表示内核驱动正常: 

图片

OH 屏幕管理

我们使用 hello_composer 来测试框架层是否正常。hello_composer 的测试内容很广泛,具体包括硬件显示接口后端、垂直同步系统、屏幕管理、输出管理等等。这个测试程序涵盖了从获取屏幕信息、创建图层、申请缓冲区、绘制内容、合成图层到最终显示的整个过程,因此它的正常运行能够验证整个图形显示管线的基本功能完整性。 

图片

经测试,hello_composer 可以正常工作。说明图形显示系统的核心功能链路是正常的。从底层硬件抽象到上层合成和显示,主要模块都在正常工作。 

图片

但是还是出现了两个屏幕都无法正确显示内容的情况。由于单个屏幕可以正常显示,问题发生在连接第二块屏幕之后,因此我们怀疑是 Render Service 中的多屏多窗口管理中的问题。

图片

根据官方文档,Display Manager Server 主要负责 Display 管理,提供 Display 信息、屏幕截图、屏幕亮灭和亮度处理控制,并处理 Display 与 Screen 映射关系。

在分析屏幕初始化代码时,我们注意到一个异常现象:系统能够获取到默认屏幕的screen id(值为2),但在abstractDisplayMap_中却找不到与之对应的项。说明屏幕初始化流程可能有点问题。 

图片

通过仔细研究代码,我们发现abstractDisplayMap_的更新主要发生在BindAloneScreenLocked函数中,该函数通常由OnAbstractScreenConnect触发。然而,根据 hilog,OnAbstractScreenConnect似乎只为后来添加的DP显示器调用了一次,而内置eDP屏幕则根本没有初始化。

eDP 屏幕未初始化导致了未能成功创建 default group。而正常情况下,初始化顺序应该是 eDP屏幕首先创建group,等后续 DP显示器添加时,会查找默认屏幕(eDP)对应的group。然而,当这个顺序颠倒时,DP显示器先创建group,之后eDP屏幕初始化时,就找不到与之对应的group,因此初始化失败。这个顺序的颠倒解释了为什么abstractDisplayMap_中缺少内置屏幕的信息。

RSScreen -> RSScreenManager -> HdiBackend -> HdiDevice -> HdiDeviceImpl -> DisplayComposerVdiImpl -> HdiSession -> DrmDisplay -> DrmDevice

通过研究屏幕信息从 DrmDevice 传递到 RSScreen 中的过程,我们深入探究了颠倒的原因。最终发现可能和屏幕信息存储所使用的数据结构有关,C++ 提供的 unordered_map 只记录映射关系,并不保证顺序。在跨模块传递时,window manager 似乎错误的使用了屏幕信息,并把第一个遍历到的屏幕作为了默认屏幕。

最终,我们考虑了以下几个方向解决问题,实现了双屏同显。

重新评估和调整屏幕初始化的顺序,确保eDP屏幕总是首先初始化。在DP显示器初始化时,增加检查机制,确保默认屏幕(eDP)已经正确初始化。在关键点添加同步机制,确保屏幕和group的创建保持正确的顺序。

支持 DP 热插拔

我们以上所做的双屏适配工作并不包含热插拔内容,重新插拔会导致显示器无法正常工作。首先可以通过 hidumper 查看 rosen 管理的屏幕,确认 rosen 是否收到了热插拔屏幕的信号。

hdc shell hidumper -s RenderService -a screen

结果显示 rosen 并未管理新插入的 DP 屏幕。因此问题可能出现在 HAL 层,Display 没有正确处理内核上报的热插拔事件。

通过分析代码,我们追踪了热插拔事件的处理流程:

1.HdiNetLinkMonitor::MonitorThread 监听netlink消息2.ParseUeventMessage 解析接收到的uevent消息3.HdiSession::HandleHotplug 处理热插拔事件4.DrmDevice::HandleHotplug 在DRM设备层面处理热插拔5.DrmConnector::HandleHotplug 在连接器层面处理热插拔

uevent是Linux内核用于向用户空间报告设备状态变化的机制。当设备状态发生变化时,内核会生成uevent消息。这些消息通过netlink套接字传递给用户空间程序。Netlink是一种用于内核和用户空间进程间通信的特殊套接字家族。

在分析过程中,我发现了一个关键问题:Display HDF 只能处理 HDMI 热插拔事件事件,无法处理 DP 事件。具体来说,ParseUeventMessage函数仅仅解析消息为"STATE=HDMI=0"(或"STATE=HDMI=1")的 uevent 事件。这些字符串被写死在代码中,导致系统无法正确识别和处理DP热插拔事件。

此外,我们还发现了另一个影响系统稳定性的问题。在HdiNetLinkMonitor::MonitorThread函数中,如果没能成功从uevent中解析出DP状态,线程就会直接退出。这使得频繁热插拔测试中屏幕表现得极其不稳定。

在未来的工作中,我们可以考虑进一步优化热插拔处理流程,例如实现更复杂的重试机制,或者支持多种多样的显示协议,如 VGA,eDP 等,使 OpenHarmony 更健壮。

 结 语

在本次双显适配工作中,我们成功解决一系列问题,不仅包括底版本内核驱动存在的缺陷,还有框架层不支持的显示接口以及热插拔场景等,这都有力地证明了我们在系统适配领域的能力。未来,我们会不断的探索和钻研,积极参与开源鸿蒙生态建设,通过实际行动推动硬件生态的发展。

[参考文档] 

Rockchip3588 Linux SDK Docs


技术合作商务联络

袁经理 18956002673(同微信


继续滑动看下一个
酷派技术团队
向上滑动看下一个