Skip to content

Commit

Permalink
driver: rknpu: Update rknpu driver, version: 0.9.6
Browse files Browse the repository at this point in the history
* Add rknpu iommu domain switch support

Signed-off-by: Felix Zeng <felix.zeng@rock-chips.com>
Change-Id: Ifa756eee01d2d7002ca78a0e1f36ba92a01f4454
  • Loading branch information
Felix Zeng authored and RadxaStephen committed Jun 3, 2024
1 parent 7ae184f commit 769a605
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 63 deletions.
11 changes: 9 additions & 2 deletions drivers/rknpu/include/rknpu_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@

#define DRIVER_NAME "rknpu"
#define DRIVER_DESC "RKNPU driver"
#define DRIVER_DATE "20240226"
#define DRIVER_DATE "20240322"
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 9
#define DRIVER_PATCHLEVEL 5
#define DRIVER_PATCHLEVEL 6

#define LOG_TAG "RKNPU"

Expand All @@ -53,6 +53,8 @@
#define LOG_DEV_DEBUG(dev, fmt, args...) dev_dbg(dev, LOG_TAG ": " fmt, ##args)
#define LOG_DEV_ERROR(dev, fmt, args...) dev_err(dev, LOG_TAG ": " fmt, ##args)

#define RKNPU_MAX_IOMMU_DOMAIN_NUM 16

struct rknpu_irqs_data {
const char *name;
irqreturn_t (*irq_hdl)(int irq, void *ctx);
Expand Down Expand Up @@ -120,6 +122,7 @@ struct rknpu_device {
spinlock_t irq_lock;
struct mutex power_lock;
struct mutex reset_lock;
struct mutex domain_lock;
struct rknpu_subcore_data subcore_datas[RKNPU_MAX_CORES];
const struct rknpu_config *config;
void __iomem *bw_priority_base;
Expand Down Expand Up @@ -163,6 +166,10 @@ struct rknpu_device {
void __iomem *nbuf_base_io;
struct rknpu_mm *sram_mm;
unsigned long power_put_delay;
struct iommu_group *iommu_group;
int iommu_domain_num;
int iommu_domain_id;
struct iommu_domain *iommu_domains[RKNPU_MAX_IOMMU_DOMAIN_NUM];
};

struct rknpu_session {
Expand Down
4 changes: 3 additions & 1 deletion drivers/rknpu/include/rknpu_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct rknpu_gem_object {
struct page **pages;
struct sg_table *sgt;
struct drm_mm_node mm_node;
int iommu_domain_id;
};

enum rknpu_cache_type {
Expand All @@ -71,7 +72,8 @@ enum rknpu_cache_type {
struct rknpu_gem_object *rknpu_gem_object_create(struct drm_device *dev,
unsigned int flags,
unsigned long size,
unsigned long sram_size);
unsigned long sram_size,
int iommu_domain_id);

/* destroy a buffer with gem object */
void rknpu_gem_object_destroy(struct rknpu_gem_object *rknpu_obj);
Expand Down
12 changes: 10 additions & 2 deletions drivers/rknpu/include/rknpu_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ enum e_rknpu_action {
RKNPU_POWER_OFF = 21,
RKNPU_GET_TOTAL_SRAM_SIZE = 22,
RKNPU_GET_FREE_SRAM_SIZE = 23,
RKNPU_GET_IOMMU_DOMAIN_ID = 24,
RKNPU_SET_IOMMU_DOMAIN_ID = 25,
};

/**
Expand All @@ -142,6 +144,8 @@ enum e_rknpu_action {
* @dma_addr: dma address that access by rknpu.
* @sram_size: user-desired sram memory allocation size.
* - this size value would be page-aligned internally.
* @iommu_domain_id: iommu domain id
* @reserved: just padding to be 64-bit aligned.
*/
struct rknpu_mem_create {
__u32 handle;
Expand All @@ -150,6 +154,8 @@ struct rknpu_mem_create {
__u64 obj_addr;
__u64 dma_addr;
__u64 sram_size;
__s32 iommu_domain_id;
__u32 reserved;
};

/**
Expand Down Expand Up @@ -244,7 +250,8 @@ struct rknpu_subcore_task {
* @task_counter: task counter
* @priority: submit priority
* @task_obj_addr: address of task object
* @regcfg_obj_addr: address of register config object
* @iommu_domain_id: iommu domain id
* @reserved: just padding to be 64-bit aligned.
* @task_base_addr: task base address
* @hw_elapse_time: hardware elapse time
* @core_mask: core mask of rknpu
Expand All @@ -260,7 +267,8 @@ struct rknpu_submit {
__u32 task_counter;
__s32 priority;
__u64 task_obj_addr;
__u64 regcfg_obj_addr;
__u32 iommu_domain_id;
__u32 reserved;
__u64 task_base_addr;
__s64 hw_elapse_time;
__u32 core_mask;
Expand Down
8 changes: 8 additions & 0 deletions drivers/rknpu/include/rknpu_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,12 @@ dma_addr_t rknpu_iommu_dma_alloc_iova(struct iommu_domain *domain, size_t size,
void rknpu_iommu_dma_free_iova(struct rknpu_iommu_dma_cookie *cookie,
dma_addr_t iova, size_t size);

int rknpu_iommu_init_domain(struct rknpu_device *rknpu_dev);
int rknpu_iommu_switch_domain(struct rknpu_device *rknpu_dev, int domain_id);
void rknpu_iommu_free_domains(struct rknpu_device *rknpu_dev);

#if KERNEL_VERSION(5, 10, 0) < LINUX_VERSION_CODE
int iommu_get_dma_cookie(struct iommu_domain *domain);
#endif

#endif
1 change: 1 addition & 0 deletions drivers/rknpu/include/rknpu_job.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct rknpu_job {
ktime_t hw_recoder_time;
ktime_t hw_elapse_time;
atomic_t submit_count[RKNPU_MAX_CORES];
int iommu_domain_id;
};

irqreturn_t rknpu_core0_irq_handler(int irq, void *data);
Expand Down
8 changes: 4 additions & 4 deletions drivers/rknpu/include/rknpu_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ struct rknpu_mem_object {
unsigned int owner;
};

int rknpu_mem_create_ioctl(struct rknpu_device *rknpu_dev, unsigned long data,
struct file *file);
int rknpu_mem_destroy_ioctl(struct rknpu_device *rknpu_dev, unsigned long data,
struct file *file);
int rknpu_mem_create_ioctl(struct rknpu_device *rknpu_dev, struct file *file,
unsigned int cmd, unsigned long data);
int rknpu_mem_destroy_ioctl(struct rknpu_device *rknpu_dev, struct file *file,
unsigned long data);
int rknpu_mem_sync_ioctl(struct rknpu_device *rknpu_dev, unsigned long data);

#endif
49 changes: 36 additions & 13 deletions drivers/rknpu/rknpu_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "rknpu_drv.h"
#include "rknpu_gem.h"
#include "rknpu_devfreq.h"
#include "rknpu_iommu.h"

#ifdef CONFIG_ROCKCHIP_RKNPU_DRM_GEM
#include <drm/drm_device.h>
Expand Down Expand Up @@ -375,6 +376,15 @@ static int rknpu_action(struct rknpu_device *rknpu_dev,
args->value = 0;
ret = 0;
break;
case RKNPU_GET_IOMMU_DOMAIN_ID:
args->value = rknpu_dev->iommu_domain_id;
ret = 0;
break;
case RKNPU_SET_IOMMU_DOMAIN_ID: {
ret = rknpu_iommu_switch_domain(rknpu_dev,
*(int32_t *)&args->value);
break;
}
default:
ret = -EINVAL;
break;
Expand Down Expand Up @@ -464,7 +474,7 @@ static int rknpu_action_ioctl(struct rknpu_device *rknpu_dev,
return ret;
}

static long rknpu_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
static long rknpu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret = -EINVAL;
struct rknpu_device *rknpu_dev = NULL;
Expand All @@ -476,22 +486,22 @@ static long rknpu_ioctl(struct file *file, uint32_t cmd, unsigned long arg)

rknpu_power_get(rknpu_dev);

switch (cmd) {
case IOCTL_RKNPU_ACTION:
switch (_IOC_NR(cmd)) {
case RKNPU_ACTION:
ret = rknpu_action_ioctl(rknpu_dev, arg);
break;
case IOCTL_RKNPU_SUBMIT:
case RKNPU_SUBMIT:
ret = rknpu_submit_ioctl(rknpu_dev, arg);
break;
case IOCTL_RKNPU_MEM_CREATE:
ret = rknpu_mem_create_ioctl(rknpu_dev, arg, file);
case RKNPU_MEM_CREATE:
ret = rknpu_mem_create_ioctl(rknpu_dev, file, cmd, arg);
break;
case RKNPU_MEM_MAP:
break;
case IOCTL_RKNPU_MEM_DESTROY:
ret = rknpu_mem_destroy_ioctl(rknpu_dev, arg, file);
case RKNPU_MEM_DESTROY:
ret = rknpu_mem_destroy_ioctl(rknpu_dev, file, arg);
break;
case IOCTL_RKNPU_MEM_SYNC:
case RKNPU_MEM_SYNC:
ret = rknpu_mem_sync_ioctl(rknpu_dev, arg);
break;
default:
Expand Down Expand Up @@ -1171,7 +1181,11 @@ static int rknpu_probe(struct platform_device *pdev)
rknpu_dev->dev = dev;

rknpu_dev->iommu_en = rknpu_is_iommu_enable(dev);
if (!rknpu_dev->iommu_en) {
if (rknpu_dev->iommu_en) {
rknpu_dev->iommu_group = iommu_group_get(dev);
if (!rknpu_dev->iommu_group)
return -EINVAL;
} else {
/* Initialize reserved memory resources */
ret = of_reserved_mem_device_init(dev);
if (!ret) {
Expand Down Expand Up @@ -1226,6 +1240,7 @@ static int rknpu_probe(struct platform_device *pdev)
spin_lock_init(&rknpu_dev->irq_lock);
mutex_init(&rknpu_dev->power_lock);
mutex_init(&rknpu_dev->reset_lock);
mutex_init(&rknpu_dev->domain_lock);
for (i = 0; i < config->num_irqs; i++) {
INIT_LIST_HEAD(&rknpu_dev->subcore_datas[i].todo_list);
init_waitqueue_head(&rknpu_dev->subcore_datas[i].job_done_wq);
Expand Down Expand Up @@ -1365,6 +1380,9 @@ static int rknpu_probe(struct platform_device *pdev)
rknpu_dev->config->nbuf_size > 0)
rknpu_find_nbuf_resource(rknpu_dev);

if (rknpu_dev->iommu_en)
rknpu_iommu_init_domain(rknpu_dev);

rknpu_power_off(rknpu_dev);
atomic_set(&rknpu_dev->power_refcount, 0);
atomic_set(&rknpu_dev->cmdline_power_refcount, 0);
Expand Down Expand Up @@ -1401,9 +1419,6 @@ static int rknpu_remove(struct platform_device *pdev)
cancel_delayed_work_sync(&rknpu_dev->power_off_work);
destroy_workqueue(rknpu_dev->power_off_wq);

if (IS_ENABLED(CONFIG_ROCKCHIP_RKNPU_SRAM) && rknpu_dev->sram_mm)
rknpu_mm_destroy(rknpu_dev->sram_mm);

rknpu_debugger_remove(rknpu_dev);
rknpu_cancel_timer(rknpu_dev);

Expand All @@ -1412,6 +1427,14 @@ static int rknpu_remove(struct platform_device *pdev)
WARN_ON(!list_empty(&rknpu_dev->subcore_datas[i].todo_list));
}

if (IS_ENABLED(CONFIG_ROCKCHIP_RKNPU_SRAM) && rknpu_dev->sram_mm)
rknpu_mm_destroy(rknpu_dev->sram_mm);

if (rknpu_dev->iommu_en) {
rknpu_iommu_free_domains(rknpu_dev);
iommu_group_put(rknpu_dev->iommu_group);
}

#ifdef CONFIG_ROCKCHIP_RKNPU_DRM_GEM
rknpu_drm_remove(rknpu_dev);
#endif
Expand Down
Loading

0 comments on commit 769a605

Please sign in to comment.