RK3588 移植NPU 0.9.8版本

###### 本文件主要记录在移植3588 NPU 0.9.8版本的过程中,遇到的问题以及解决办法 ######

1.下载NPU 0.9.8版本NPU

rknpu-driver/rknpu_driver_0.9.8_20241009.tar.bz2 · 虾米/rknn-llm - 码云 - 开源中国

2.替换旧版本NPU驱动

将rknpu_driver_0.9.8_20241009/drivers/rknpu 拷贝到 3588/OK3588_Linux_fs/kernel/drivers/rknpu 下

3.编译遇到的问题

3.1 错误信息如下:

./include/soc/rockchip/rockchip_system_monitor.h:90:26: error: field 'max_temp_freq_req' has incomplete type
   90 |  struct freq_qos_request max_temp_freq_req;

解决办法:在rockchip_system_monitor.h下添加以下内容

#include <linux/pm_opp.h>
#include <linux/pm_qos.h>
#include <linux/regulator/consumer.h>
 3.2 错误信息如下:

drivers/rknpu/rknpu_gem.c:18:10: fatal error: linux/version_compat_defs.h: No such file or directory
   18 | #include <linux/version_compat_defs.h>

解决办法:在include/linux下创建version_compat_defs.h,内容如下:

/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *
 * (C) COPYRIGHT 2022-2023 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#ifndef _VERSION_COMPAT_DEFS_H_
#define _VERSION_COMPAT_DEFS_H_

#include <linux/version.h>

#if KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE
typedef unsigned int __poll_t;
#endif

#if KERNEL_VERSION(4, 9, 78) >= LINUX_VERSION_CODE

#ifndef EPOLLHUP
#define EPOLLHUP POLLHUP
#endif

#ifndef EPOLLERR
#define EPOLLERR POLLERR
#endif

#ifndef EPOLLIN
#define EPOLLIN POLLIN
#endif

#ifndef EPOLLRDNORM
#define EPOLLRDNORM POLLRDNORM
#endif

#endif

#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
/* This is defined inside kbase for matching the default to kernel's
 * mmap_min_addr, used inside file mali_kbase_mmap.c.
 * Note: the value is set at compile time, matching a kernel's configuration
 * value. It would not be able to track any runtime update of mmap_min_addr.
 */
#ifdef CONFIG_MMU
#define kbase_mmap_min_addr CONFIG_DEFAULT_MMAP_MIN_ADDR

#ifdef CONFIG_LSM_MMAP_MIN_ADDR
#if (CONFIG_LSM_MMAP_MIN_ADDR > CONFIG_DEFAULT_MMAP_MIN_ADDR)
/* Replace the default definition with CONFIG_LSM_MMAP_MIN_ADDR */
#undef kbase_mmap_min_addr
#define kbase_mmap_min_addr CONFIG_LSM_MMAP_MIN_ADDR
#pragma message "kbase_mmap_min_addr compiled to CONFIG_LSM_MMAP_MIN_ADDR, no runtime update!"
#endif /* (CONFIG_LSM_MMAP_MIN_ADDR > CONFIG_DEFAULT_MMAP_MIN_ADDR) */
#endif /* CONFIG_LSM_MMAP_MIN_ADDR */

#if (kbase_mmap_min_addr == CONFIG_DEFAULT_MMAP_MIN_ADDR)
#pragma message "kbase_mmap_min_addr compiled to CONFIG_DEFAULT_MMAP_MIN_ADDR, no runtime update!"
#endif

#else /* CONFIG_MMU */
#define kbase_mmap_min_addr (0UL)
#pragma message "kbase_mmap_min_addr compiled to (0UL), no runtime update!"
#endif /* CONFIG_MMU */
#endif /* KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE */

#include <linux/mm.h>
#if !((KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE) || \
      ((KERNEL_VERSION(6, 1, 25) <= LINUX_VERSION_CODE) && defined(__ANDROID_COMMON_KERNEL__)))
static inline void vm_flags_set(struct vm_area_struct *vma, vm_flags_t flags)
{
	vma->vm_flags |= flags;
}
static inline void vm_flags_clear(struct vm_area_struct *vma, vm_flags_t flags)
{
	vma->vm_flags &= ~flags;
}
#endif

#endif /* _VERSION_COMPAT_DEFS_H_ */
 3.2 错误信息如下: 

drivers/rknpu/rknpu_devfreq.c:22:10: error: 'MONITOR_TYPE_DEV' undeclared here (not in a function); did you mean 'MONITOR_TPYE_DEV'?
   22 |  .type = MONITOR_TYPE_DEV,

解决办法:在rknpu_devfreq.c 第22行,将MONITOR_TYPE_DEV修改为MONITOR_TPYE_DEV

 3.3 错误信息如下: 

drivers/rknpu/rknpu_devfreq.c:732:2: error: implicit declaration of function 'rockchip_uninit_opp_table'; did you mean 'rockchip_init_opp_table'? [-Werror=implicit-function-declaration]  732 |  rockchip_uninit_opp_table(dev, &rknpu_dev->opp_info);

解决办法:在rockchip_opp_select.h下添加以下内容

/*
 * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
 *
 * SPDX-License-Identifier: GPL-2.0+
 */
#ifndef __SOC_ROCKCHIP_OPP_SELECT_H
#define __SOC_ROCKCHIP_OPP_SELECT_H

#define VOLT_RM_TABLE_END	~1

#define OPP_INTERMEDIATE_MASK	0x3f
#define OPP_INTERMEDIATE_RATE	BIT(0)
#define OPP_SCALING_UP_RATE	BIT(1)
#define OPP_SCALING_UP_INTER	(OPP_INTERMEDIATE_RATE | OPP_SCALING_UP_RATE)
#define OPP_SCALING_DOWN_INTER	OPP_INTERMEDIATE_RATE
#define OPP_LENGTH_LOW		BIT(2)

struct rockchip_opp_info;

struct volt_rm_table {
	int volt;
	int rm;
};

struct rockchip_opp_data {
	int (*get_soc_info)(struct device *dev, struct device_node *np,
			    int *bin, int *process);
	int (*set_soc_info)(struct device *dev, struct device_node *np,
			    int bin, int process, int volt_sel);
	int (*set_read_margin)(struct device *dev,
			       struct rockchip_opp_info *opp_info,
			       u32 rm);
};

struct pvtpll_opp_table {
	unsigned long rate;
	unsigned long u_volt;
	unsigned long u_volt_min;
	unsigned long u_volt_max;
	unsigned long u_volt_mem;
	unsigned long u_volt_mem_min;
	unsigned long u_volt_mem_max;
};

struct rockchip_opp_info {
	struct device *dev;
	struct pvtpll_opp_table *opp_table;
	const struct rockchip_opp_data *data;
	struct volt_rm_table *volt_rm_tbl;
	struct regmap *grf;
	struct regmap *dsu_grf;
	struct clk_bulk_data *clks;
	struct clk *scmi_clk;
	/* The threshold frequency for set intermediate rate */
	unsigned long intermediate_threshold_freq;
	unsigned int pvtpll_avg_offset;
	unsigned int pvtpll_min_rate;
	unsigned int pvtpll_volt_step;
	int num_clks;
	/* The read margin for low voltage */
	u32 low_rm;
	u32 current_rm;
	u32 target_rm;
};

#if IS_ENABLED(CONFIG_ROCKCHIP_OPP)
int rockchip_of_get_leakage(struct device *dev, char *lkg_name, int *leakage);
void rockchip_of_get_lkg_sel(struct device *dev, struct device_node *np,
			     char *lkg_name, int process,
			     int *volt_sel, int *scale_sel);
void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info);
void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
			      char *reg_name, int bin, int process,
			      int *volt_sel, int *scale_sel);
void rockchip_of_get_bin_sel(struct device *dev, struct device_node *np,
			     int bin, int *scale_sel);
void rockchip_of_get_bin_volt_sel(struct device *dev, struct device_node *np,
				  int bin, int *bin_volt_sel);
int rockchip_nvmem_cell_read_u8(struct device_node *np, const char *cell_id,
				u8 *val);
int rockchip_nvmem_cell_read_u16(struct device_node *np, const char *cell_id,
				 u16 *val);
int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np,
			       char *porp_name, struct volt_rm_table **table);
void rockchip_get_opp_data(const struct of_device_id *matches,
			   struct rockchip_opp_info *info);
int rockchip_get_soc_info(struct device *dev, struct device_node *np, int *bin,
			  int *process);
void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
				 char *reg_name, int bin, int process,
				 int *scale, int *volt_sel);
struct opp_table *rockchip_set_opp_prop_name(struct device *dev, int process,
					     int volt_sel);
struct opp_table *rockchip_set_opp_supported_hw(struct device *dev,
						struct device_node *np,
						int bin, int volt_sel);
int rockchip_adjust_power_scale(struct device *dev, int scale);
int rockchip_get_read_margin(struct device *dev,
			     struct rockchip_opp_info *opp_info,
			     unsigned long volt, u32 *target_rm);
int rockchip_set_read_margin(struct device *dev,
			     struct rockchip_opp_info *opp_info, u32 rm,
			     bool is_set_rm);
int rockchip_init_read_margin(struct device *dev,
			      struct rockchip_opp_info *opp_info,
			      char *reg_name);
int rockchip_set_intermediate_rate(struct device *dev,
				   struct rockchip_opp_info *opp_info,
				   struct clk *clk, unsigned long old_freq,
				   unsigned long new_freq, bool is_scaling_up,
				   bool is_set_clk);
int rockchip_init_opp_table(struct device *dev,
			    struct rockchip_opp_info *info,
			    char *lkg_name, char *reg_name);

void rockchip_uninit_opp_table(struct device *dev,
	struct rockchip_opp_info *info);
int rockchip_opp_dump_cur_state(struct device *dev);

#else
static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name,
					  int *leakage)
{
	return -EOPNOTSUPP;
}

static inline void rockchip_of_get_lkg_sel(struct device *dev,
					   struct device_node *np,
					   char *lkg_name, int process,
					   int *volt_sel, int *scale_sel)
{
}

static inline void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info)
{
}

static inline void rockchip_of_get_pvtm_sel(struct device *dev,
					    struct device_node *np,
					    char *reg_name, int bin, int process,
					    int *volt_sel, int *scale_sel)
{
}

static inline void rockchip_of_get_bin_sel(struct device *dev,
					   struct device_node *np, int bin,
					   int *scale_sel)
{
}

static inline void rockchip_of_get_bin_volt_sel(struct device *dev,
						struct device_node *np,
						int bin, int *bin_volt_sel)
{
}

static inline int rockchip_nvmem_cell_read_u8(struct device_node *np,
					      const char *cell_id, u8 *val)
{
	return -EOPNOTSUPP;
}

static inline int rockchip_nvmem_cell_read_u16(struct device_node *np,
					       const char *cell_id, u16 *val)
{
	return -EOPNOTSUPP;
}

static inline int rockchip_get_volt_rm_table(struct device *dev,
					     struct device_node *np,
					     char *porp_name,
					     struct volt_rm_table **table)
{
	return -EOPNOTSUPP;

}

static inline void rockchip_get_opp_data(const struct of_device_id *matches,
					 struct rockchip_opp_info *info)
{
}
static inline int rockchip_get_soc_info(struct device *dev,
					struct device_node *np, int *bin,
					int *process)
{
	return -EOPNOTSUPP;
}

static inline void rockchip_get_scale_volt_sel(struct device *dev,
					       char *lkg_name, char *reg_name,
					       int bin, int process, int *scale,
					       int *volt_sel)
{
}

static inline struct opp_table *rockchip_set_opp_prop_name(struct device *dev,
							   int process,
							   int volt_sel)
{
	return ERR_PTR(-EOPNOTSUPP);
}

static inline struct opp_table *rockchip_set_opp_supported_hw(struct device *dev,
							      struct device_node *np,
							      int bin, int volt_sel)
{
	return ERR_PTR(-EOPNOTSUPP);
}

static inline int rockchip_adjust_power_scale(struct device *dev, int scale)
{
	return -EOPNOTSUPP;
}

static inline int rockchip_get_read_margin(struct device *dev,
					   struct rockchip_opp_info *opp_info,
					   unsigned long volt, u32 *target_rm)
{
	return -EOPNOTSUPP;
}
static inline int rockchip_set_read_margin(struct device *dev,
					   struct rockchip_opp_info *opp_info,
					   u32 rm, bool is_set_rm)
{
	return -EOPNOTSUPP;
}

static inline int rockchip_init_read_margin(struct device *dev,
					    struct rockchip_opp_info *opp_info,
					    char *reg_name)
{
	return -EOPNOTSUPP;
}

static inline int
rockchip_set_intermediate_rate(struct device *dev,
			       struct rockchip_opp_info *opp_info,
			       struct clk *clk, unsigned long old_freq,
			       unsigned long new_freq, bool is_scaling_up,
			       bool is_set_clk)
{
	return -EOPNOTSUPP;
}

static inline int rockchip_init_opp_table(struct device *dev,
					  struct rockchip_opp_info *info,
					  char *lkg_name, char *reg_name)
{
	return -EOPNOTSUPP;
}

static inline int rockchip_opp_dump_cur_state(struct device *dev)
{
	return -EOPNOTSUPP;
}

static inline void rockchip_uninit_opp_table(struct device *dev,
					     struct rockchip_opp_info *info)
{
}

#endif /* CONFIG_ROCKCHIP_OPP */

#endif

在rockchip_opp_select.c下添加以下内容

void rockchip_uninit_opp_table(struct device *dev, struct rockchip_opp_info *info)
{
	struct opp_table *opp_table;

	if (info) {
		kfree(info->opp_table);
		info->opp_table = NULL;
		devm_kfree(dev, info->clks);
		info->clks = NULL;
		devm_kfree(dev, info->volt_rm_tbl);
		info->volt_rm_tbl = NULL;
	}

	opp_table = dev_pm_opp_get_opp_table(dev);
	if (IS_ERR(opp_table))
		return;
	dev_pm_opp_of_remove_table(dev);
	if (opp_table->prop_name)
		dev_pm_opp_put_prop_name(opp_table);
	if (opp_table->supported_hw)
		dev_pm_opp_put_supported_hw(opp_table);
	dev_pm_opp_put_opp_table(opp_table);
}
EXPORT_SYMBOL(rockchip_uninit_opp_table);

4.验证版本信息

如图所示,NPU版本为0.9.8,SDK版本是2.3.0

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值