1 关键字

HDMI;OpenHarmony;drm;plane

 

2 问题描述

开发板型号:FireFly AIO-3399J

芯片:RK3399

内核版本: FireFly原生Linux4.19内核

OH版本:OpenHarmony3.1-Release

问题现象:OpenHarmony3.1-Release版本适配AIO-3399j,外接HDMI显示屏,出现显示屏无法点亮问题。

测试步骤:

  1. 编译系统,OpenHarmony3.1Release版本按照ROC-RK3568的适配文档操作,烧录系统原生内核boot.img,OHOS system.img/vendor.img/userdata.img等到单板。

  2. 外接HDMI显示器,显示屏无法点亮。

  3. 使用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属性,底层驱动和上层接口属性不匹配,造成显示屏无法点亮的情况。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐