OpenHarmony标准系统上实现对rk系列芯片NPU的支持(驱动移植)

1.将RKNPU驱动移植到Openharmony内核

本文以rk3568为例,将RKNPU驱动移植到Openharmony使用的kernel 5.10中

开发环境

  • DAYU200 rk3568开发板
  • OpenHarmony 4.1 Release 64位系统
    文档约定:

4.1r_3568为OpenHarmony标准系统源码根目录

1.0 环境准备

1.搭建OpenHarmony标准系统开发环境:https://forums.openharmony.cn/forum.php?mod=viewthread&tid=897

2.hdc工具:https://forums.openharmony.cn/forum.php?mod=viewthread&tid=1458

1.1 移植准备:得到一份完整的kernel代码

OpenHarmony标准系统4.1r使用的是kernel 5.10的内核,在此基线基础上,回合CVE补丁及OpenHarmony特性,作为OpenHarmony Common Kernel基线。针对不同的芯片,各厂商合入对应的板级驱动补丁,完成对OpenHarmony的基线适配。

所以要把npu驱动移植到kernel 5.10,首先得有一份完整的rk3568 kernel5.10代码。所以我们需要手动把4.1r_3568/kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch打进/4.1r_3568/kernel/linux/linux-5.10内核中

javascript 复制代码
cd 4.1r_3568/kernel/linux/linux-5.10

patch -p1 < /home/jiajiahao/OpenHarmony/4.1r_3568/kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch

2.然后注释掉/4.1r_3568/device/board/hihope/rk3568/kernel/build_kernel.sh中的patch -p1 < ${KERNEL_PATCH}

然后就可以在4.1r_3568/kernel/linux/linux-5.10中得到一份完整的rk3568 kernel 5.10代码,在此内核代码基础上进行修改,移植npu的驱动.

1.2 内核移植

1.获取npu驱动源码:https://github.com/rockchip-linux/kernel 选择5.10分支,NPU驱动位于:drivers/rknpu

本样例使用的npu驱动,请查看本目录rknpu

2.修改//kernel/linux/config/linux-5.10/rk3568/arch/arm64_defconfig文件,添加RKNPU的CONFIG配置

javascript 复制代码
#
# RKNPU
#
CONFIG_ROCKCHIP_RKNPU=y
CONFIG_ROCKCHIP_RKNPU_DEBUG_FS=y
CONFIG_ROCKCHIP_RKNPU_DRM_GEM=y

3.将驱动代码drivers/rknpu移植到4.1r_3568/kernel/linux/linux-5.10/drivers目录中

4.修改drivers目录下的Makefile文件,添加如下内容

javascript 复制代码
source "drivers/rknpu/Kconfig"

5.修改drivers目录下的Kconfig文件,添加如下内容

javascript 复制代码
obj-$(CONFIG_ROCKCHIP_RKNPU)    += rknpu/

6.修改kernel/linux/linux-5.10/drivers/iommu/rockchip-iommu.h,修改好的rockchip_iommu.h位于本目录下:rockchip_iommu.h

7.修改kernel/linux/linux-5.10/include/soc/rockchip/rockchip_iommu.c,修改好的rockchip_iommu.c位于本目录下:rockchip-iommu.c

8.修改kernel/linux/linux-5.10/drivers/soc/rockchip/rockchip_opp_select.c,修改好的rockchip_opp_select.c位于本目录下:rockchip_opp_select.c

9.修改kernel/linux/linux-5.10/include/soc/rockchip/rockchip_opp_select.h,修改好的rockchip_opp_select.h位于本目录下:rockchip_opp_select.h

10.kernel/linux/linux-5.10/drivers/rknpu/rknpu_drv.c中将MONITOR_TYPE_DEV改为MONITOR_TPYE_DEV

11.修改kernel/linux/linux-5.10/drivers/rknpu/rknpu_devfreq.c

javascript 复制代码
将
static int rk3588_npu_set_read_margin(struct device *dev,
                      struct rockchip_opp_info *opp_info,
                      u32 rm)
修改为
static int rk3588_npu_set_read_margin(struct device *dev,
                      struct rockchip_opp_info *opp_info,
                      unsigned long rm)

12.在kernel/linux/linux-5.10/arch/arm64/boot/dts/rockchip/rk3568.dtsi设备树文件中将npu注释打开

javascript 复制代码
            /* These power domains are grouped by VD_NPU */
            /*pd_npu@RK3568_PD_NPU {
                reg = <RK3568_PD_NPU>;
                clocks = <&cru ACLK_NPU_PRE>,
                     <&cru HCLK_NPU_PRE>,
                     <&cru PCLK_NPU_PRE>;
                pm_qos = <&qos_npu>;
            };*/

改为

javascript 复制代码
            /* These power domains are grouped by VD_NPU */
            pd_npu@RK3568_PD_NPU {
                reg = <RK3568_PD_NPU>;
                clocks = <&cru ACLK_NPU_PRE>,
                     <&cru HCLK_NPU_PRE>,
                     <&cru PCLK_NPU_PRE>;
                pm_qos = <&qos_npu>;
            };

1.2 npu移植简单验证

1.编译arm64的带有npu驱动的rk3568镜像

javascript 复制代码
./build.sh --product-name rk3568 --ccache --no-prebuilt-sdk--target-cpu arm64

2.编译好的镜像位于/out/rk3568/packages/phone/images下

3.使用RKDevTool工具烧录镜像到DAYU200后,查看开机内核打印,有如下输出则内核npu驱动移植成功。

内核打印太多,通过hdc shell dmesg | grep "RKNPU"可能看不到以下输出

javascript 复制代码
[    7.675214] RKNPU fde40000.npu: Adding to iommu group 0
[    7.676593] RKNPU fde40000.npu: RKNPU: rknpu iommu is enabled, using iommu mode
[    7.677428] RKNPU fde40000.npu: can't request region for resource [mem 0xfde40000-0xfde4ffff]
[    7.679266] [drm] Initialized rknpu 0.8.2 20220829 for fde40000.npu on minor 1
[    7.679856] RKNPU fde40000.npu: Failed to get npu_leakage
[    7.682441] RKNPU fde40000.npu: avs=0
[    7.683024] RKNPU fde40000.npu: l=0 h=2147483647 hyst=5000 l_limit=0 h_limit=0 h_table=0
[    7.683835] RKNPU fde40000.npu: failed to find power_model node
[    7.683881] RKNPU fde40000.npu: RKNPU: failed to initialize power model
[    7.683912] RKNPU fde40000.npu: RKNPU: failed to get dynamic-coefficient