FireFly-AIO-3399J 显示屏不亮问题分析报告
1 关键字 HDMI;OpenHarmony;drm;plane 2 问题描述 开发板型号:FireFly AIO-3399J 芯片:RK3399 内核版本: FireFly原生Linux4.19内核 OH版本:OpenHarmony3.1-Release 问题现象:OpenHarmony3.1-Release版本适配AIO-3399j,外接HDMI显示屏,出现显示屏无法点亮问题。 测试步骤: 编
1 关键字
HDMI;OpenHarmony;drm;plane
2 问题描述
开发板型号:FireFly AIO-3399J
芯片:RK3399
内核版本: FireFly原生Linux4.19内核
OH版本:OpenHarmony3.1-Release
问题现象:OpenHarmony3.1-Release版本适配AIO-3399j,外接HDMI显示屏,出现显示屏无法点亮问题。
测试步骤:
-
编译系统,OpenHarmony3.1Release版本按照ROC-RK3568的适配文档操作,烧录系统原生内核boot.img,OHOS system.img/vendor.img/userdata.img等到单板。
-
外接HDMI显示器,显示屏无法点亮。
-
使用modetest工具,显示屏可以显示。
3 问题原因
3.1 正常机制
外接HDMI显示器,显示屏点亮正常显示。
3.2 异常机制
外接HDMI显示器,显示屏未正常显示,使用modetest工具,屏幕测试正常。
4 解决方案
-
重新适配Display HDI接口,使用OpenHarmony3.1beta版本的相关接口实现。
-
因aio-3399j和rk3568的gpu不同,无法使用相同的gpu接口,因此使用cpu渲染。
5 定位过程
5.1 日志代码追踪
Hilog报错信息:
行 5766: 01-19 02:52:10.612 481 481 D 01400/DISP: [Init@drm_crtc.cpp:39]
行 5767: 01-19 02:52:10.612 481 481 E 01400/DISP: [Init@drm_crtc.cpp:58] Failed to get plane_mask property
行 5768: 01-19 02:52:10.612 481 481 D 01400/DISP: [Init@drm_crtc.cpp:39]
行 5769: 01-19 02:52:10.612 481 481 E 01400/DISP: [Init@drm_crtc.cpp:58] Failed to get plane_mask property
device\hihope\hardware\display\src\display_device\drm_crtc.cpp
int32_t DrmCrtc::Init(DrmDevice &drmDevice)
{
DISPLAY_DEBUGLOG();
int32_t ret;
DrmProperty prop;
ret = drmDevice.GetCrtcProperty(*this, PROP_MODEID, prop);
mModePropId = prop.propId;
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not get mode prop id"));
ret = drmDevice.GetCrtcProperty(*this, PROP_OUTFENCE, prop);
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get out fence prop id"));
mOutFencePropId = prop.propId;
ret = drmDevice.GetCrtcProperty(*this, PROP_ACTIVE, prop);
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get out fence prop id"));
mActivePropId = prop.propId;
// Plane mask
mPlaneMask = 0;
ret = drmDevice.GetCrtcProperty(*this, "PLANE_MASK", prop);
if (ret != DISPLAY_SUCCESS) {
DISPLAY_LOGE("Failed to get plane_mask property");
} else {
for (int i = 0; i < static_cast<int>(ARRAY_SIZE(planeMaskNames)); i++) {
for (auto &drmEnum : prop.enums) {
if (!strncmp(drmEnum.name.c_str(), (const char*)planeMaskNames[i].name,
strlen(drmEnum.name.c_str())) && (prop.value & (1LL << drmEnum.value)) > 0) {
mPlaneMask |= static_cast<int>(planeMaskNames[i].mask);
DISPLAY_LOGI("crtc id %{public}d, plane name %{public}s value %{public}llx",
GetId(), (const char*)planeMaskNames[i].name,
(long long)planeMaskNames[i].mask);
}
}
}
}
return DISPLAY_SUCCESS;
}
device\hihope\hardware\display\src\display_device\drm_device.cpp
int32_t DrmDevice::GetPlaneProperty(const DrmPlane &plane, const std::string &name, DrmProperty &prop)
{
return GetProperty(plane.GetId(), DRM_MODE_OBJECT_PLANE, name, prop);
}
int32_t DrmDevice::GetProperty(uint32_t objId, uint32_t objType, const std::string &name, DrmProperty &prop)
{
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(GetDrmFd(), objId, objType);
DISPLAY_CHK_RETURN((!props), DISPLAY_FAILURE, DISPLAY_LOGE("can not get properties"));
bool found = false;
for (uint32_t i = 0; i < props->count_props; i++) {
drmModePropertyPtr p = drmModeGetProperty(GetDrmFd(), props->props[i]);
if (strcmp(p->name, name.c_str()) == 0) {
found = true;
prop.propId = p->prop_id;
prop.value = props->prop_values[i];
prop.name = p->name;
prop.flags = p->flags;
根据代码信息显示无法获取drm crtc的PLANE_MASK属性,无法找到drm plane。
5.2 PLANE_MASK属性追踪
modetest显示drm crtc和plane信息,没有相关PLANE_MASK属性。
# modetest -p
trying to open device 'i915'...failed
trying to open device 'amdgpu'...failed
trying to open device 'radeon'...failed
trying to open device 'nouveau'...failed
trying to open device 'vmwgfx'...failed
trying to open device 'omapdrm'...failed
trying to open device 'exynos'...failed
trying to open device 'tilcdc'...failed
trying to open device 'msm'...failed
trying to open device 'sti'...failed
trying to open device 'tegra'...failed
trying to open device 'imx-drm'...failed
trying to open device 'rockchip'...done
CRTCs:
id fb pos size
56 0 (0,0) (0x0)
#0 nan 0 0 0 0 0 0 0 0 0 flags: ; type:
props:
41 left margin:
flags: range
values: 0 100
value: 100
42 right margin:
flags: range
values: 0 100
value: 100
43 top margin:
flags: range
values: 0 100
value: 100
44 bottom margin:
flags: range
values: 0 100
value: 100
54 FEATURE:
flags: immutable bitmask
values: afbdc=0x1
value: 0
26 GAMMA_LUT:
flags: blob
blobs:
value:
27 GAMMA_LUT_SIZE:
flags: immutable range
values: 0 4294967295
value: 256
64 0 (0,0) (1920x1080)
#0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
props:
41 left margin:
flags: range
values: 0 100
value: 100
42 right margin:
flags: range
values: 0 100
value: 100
43 top margin:
flags: range
values: 0 100
value: 100
44 bottom margin:
flags: range
values: 0 100
value: 100
61 FEATURE:
flags: immutable bitmask
values: afbdc=0x1
value: 1
26 GAMMA_LUT:
flags: blob
blobs:
value:
27 GAMMA_LUT_SIZE:
flags: immutable range
values: 0 4294967295
value: 1024
Planes:
id crtc fb CRTC x,y x,y gamma size possible crtcs
55 0 0 0,0 0,0 0 0x00000001
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 1
53 FEATURE:
flags: immutable bitmask
values: scale=0x1 alpha=0x2 hdr2sdr=0x4 sdr2hdr=0x8 afbdc=0x10
value: 18
57 0 0 0,0 0,0 0 0x00000001
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YUYV
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
53 FEATURE:
flags: immutable bitmask
values: scale=0x1 alpha=0x2 hdr2sdr=0x4 sdr2hdr=0x8 afbdc=0x10
value: 19
58 rotation:
flags: bitmask
values: rotate-0=0x1 reflect-x=0x10 reflect-y=0x20
value: 1
62 0 0 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YUYV
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 1
60 FEATURE:
flags: immutable bitmask
values: scale=0x1 alpha=0x2 hdr2sdr=0x4 sdr2hdr=0x8 afbdc=0x10
value: 19
63 0 0 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 2
60 FEATURE:
flags: immutable bitmask
values: scale=0x1 alpha=0x2 hdr2sdr=0x4 sdr2hdr=0x8 afbdc=0x10
value: 18
65 0 0 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YUYV
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
60 FEATURE:
flags: immutable bitmask
values: scale=0x1 alpha=0x2 hdr2sdr=0x4 sdr2hdr=0x8 afbdc=0x10
value: 19
66 rotation:
flags: bitmask
values: rotate-0=0x1 reflect-x=0x10 reflect-y=0x20
value: 1
67 0 0 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
60 FEATURE:
flags: immutable bitmask
values: scale=0x1 alpha=0x2 hdr2sdr=0x4 sdr2hdr=0x8 afbdc=0x10
value: 18
68 rotation:
flags: bitmask
values: rotate-0=0x1 reflect-y=0x20
value: 1
在OHOS3.1-Release代码中全局搜索plane_mask,找到以下代码
kernel\linux\patches\linux-5.10\rk3568_patch\kernel.patch
+ vop_out_node = of_get_child_by_name(dev->of_node, "ports");
+ if (vop_out_node) {
+ struct device_node *child;
+
+ for_each_child_of_node(vop_out_node, child) {
+ u32 plane_mask = 0;
+ u32 primary_plane_phy_id = 0;
+ u32 vp_id = 0;
+
+ of_property_read_u32(child, "rockchip,plane-mask", &plane_mask);
+ of_property_read_u32(child, "rockchip,primary-plane", &primary_plane_phy_id);
+ of_property_read_u32(child, "reg", &vp_id);
+
+ vop2->vps[vp_id].plane_mask = plane_mask;
+ if (plane_mask)
+ vop2->vps[vp_id].primary_plane_phy_id = primary_plane_phy_id;
+ else
+ vop2->vps[vp_id].primary_plane_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
+
+ DRM_DEV_INFO(dev, "vp%d assign plane mask: 0x%x, primary plane phy id: %d\n",
+ vp_id, vop2->vps[vp_id].plane_mask,
+ vop2->vps[vp_id].primary_plane_phy_id);
+ }
+ }
+
out\kernel\src_tmp\linux-5.10\drivers\gpu\drm\rockchip\rockchip_drm_vop2.c
vop_out_node = of_get_child_by_name(dev->of_node, "ports");
if (vop_out_node) {
struct device_node *child;
for_each_child_of_node(vop_out_node, child) {
u32 plane_mask = 0;
u32 primary_plane_phy_id = 0;
u32 vp_id = 0;
of_property_read_u32(child, "rockchip,plane-mask", &plane_mask);
of_property_read_u32(child, "rockchip,primary-plane", &primary_plane_phy_id);
of_property_read_u32(child, "reg", &vp_id);
vop2->vps[vp_id].plane_mask = plane_mask;
if (plane_mask)
vop2->vps[vp_id].primary_plane_phy_id = primary_plane_phy_id;
else
vop2->vps[vp_id].primary_plane_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
DRM_DEV_INFO(dev, "vp%d assign plane mask: 0x%x, primary plane phy id: %d\n",
vp_id, vop2->vps[vp_id].plane_mask,
vop2->vps[vp_id].primary_plane_phy_id);
}
}
在OHOS自带的Linux5.10内核中,通过rk3568的patch支持plane mask属性。
FireFly AIO-3399J能以OHOS3.1Beta+原生Linux4.19内核启动,对比OHOS3.1Release和OHOS3.1Beta的Display HDI接口,发现beta版本的确没有使用PLANE_MASK属性。
5.3 去掉PLANE MASK属性
使用3.1Beta版本的display HDI接口替换3.1Release版本的display HDI接口。
编译运行Hilog出现一下问题:
行 20017: 01-19 15:45:50.939 437 437 I 01400/OHOS::ROSEN: RsDebug RSHardwareProcessor::ProcessSurface start node id:1868310773761 available buffer:0 name:[main window0]
行 20018: 01-19 15:45:50.939 437 437 I 01400/OHOS::ROSEN: RsDebug RSProcessor::ProcessSurface have no Available Buffer andNode have no buffer node id:1868310773761
行 20019: 01-19 15:45:50.939 437 437 I 01400/OHOS::ROSEN: RsDebug RSHardwareProcessor::ProcessSurface consume buffer fail
行 20021: 01-19 15:45:50.939 437 437 I 01400/OHOS::ROSEN: RsDebug mainLoop end
行 22478: 01-19 15:45:52.091 435 435 I 01400/OHOS::ROSEN: RSSurfaceOhosGl: create and Init EglSurface (nil)
行 22479: 01-19 15:45:52.091 435 435 E 01400/OHOS::ROSEN: RSSurfaceOhosGl: Invalid eglSurface, return
行 23249: 01-19 15:45:52.452 435 435 E 01400/OHOS::ROSEN: RSSurfaceOhosGl: Invalid eglSurface, return
因芯片GPU不同,GPU渲染失败,使用CPU渲染,编译运行,显示屏正常显示。
使用CPU渲染,修改foundation\graphic\standard\graphic_config.gni
if ("${product_name}" == "watchos" || "${product_name}" == "Hi3516DV300" ||
"${product_name}" == "ohos-arm64" || "${product_name}" == "ohos-sdk" ||
"${product_name}" == "qemu-arm-linux-min") {
gpu_defines = [ "ACE_DISABLE_GL" ]
ace_enable_gpu = false
libgl = []
} else if ("${product_name}" == "rk3566" || "${product_name}" == "rk3568") {
gpu_defines = [ "ACE_DISABLE_GL" ]
ace_enable_gpu = false
libgl = []
} else {
gpu_defines = [ "ACE_ENABLE_GL" ]
ace_enable_gpu = true
libgl = [ "//device/hisilicon/hardware/gpu:gpu_libs" ]
}
6 知识分享
Firefly原生Linux4.19内核的drm相关驱动不支持PLANE_MASK属性,而OpenHarmony3.1Release版本的Hihope rk3568 display HDI接口使用PLANE_MASK属性,底层驱动和上层接口属性不匹配,造成显示屏无法点亮的情况。
更多推荐
所有评论(0)