From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/rknpu/rknpu_drv.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 200 insertions(+), 28 deletions(-)
diff --git a/kernel/drivers/rknpu/rknpu_drv.c b/kernel/drivers/rknpu/rknpu_drv.c
index 30dfc38..eb31273 100644
--- a/kernel/drivers/rknpu/rknpu_drv.c
+++ b/kernel/drivers/rknpu/rknpu_drv.c
@@ -79,36 +79,29 @@
MODULE_PARM_DESC(bypass_soft_reset,
"bypass RKNPU soft reset if set it to 1, disabled by default");
-struct npu_irqs_data {
+struct rknpu_irqs_data {
const char *name;
irqreturn_t (*irq_hdl)(int irq, void *ctx);
};
-static const struct npu_irqs_data rk356x_npu_irqs[] = {
+static const struct rknpu_irqs_data rknpu_irqs[] = {
{ "npu_irq", rknpu_core0_irq_handler }
};
-static const struct npu_irqs_data rk3588_npu_irqs[] = {
+static const struct rknpu_irqs_data rk3588_npu_irqs[] = {
{ "npu0_irq", rknpu_core0_irq_handler },
{ "npu1_irq", rknpu_core1_irq_handler },
{ "npu2_irq", rknpu_core2_irq_handler }
};
-static const struct npu_irqs_data rv110x_npu_irqs[] = {
- { "npu_irq", rknpu_core0_irq_handler }
-};
+static const struct rknpu_reset_data rknpu_resets[] = { { "srst_a",
+ "srst_h" } };
-static const struct npu_reset_data rk356x_npu_resets[] = { { "srst_a",
- "srst_h" } };
-
-static const struct npu_reset_data rk3588_npu_resets[] = {
+static const struct rknpu_reset_data rk3588_npu_resets[] = {
{ "srst_a0", "srst_h0" },
{ "srst_a1", "srst_h1" },
{ "srst_a2", "srst_h2" }
};
-
-static const struct npu_reset_data rv110x_npu_resets[] = { { "srst_a",
- "srst_h" } };
static const struct rknpu_config rk356x_rknpu_config = {
.bw_priority_addr = 0xfe180008,
@@ -117,11 +110,15 @@
.pc_data_amount_scale = 1,
.pc_task_number_bits = 12,
.pc_task_number_mask = 0xfff,
+ .pc_task_status_offset = 0x3c,
+ .pc_dma_ctrl = 0,
.bw_enable = 1,
- .irqs = rk356x_npu_irqs,
- .resets = rk356x_npu_resets,
- .num_irqs = ARRAY_SIZE(rk356x_npu_irqs),
- .num_resets = ARRAY_SIZE(rk356x_npu_resets)
+ .irqs = rknpu_irqs,
+ .resets = rknpu_resets,
+ .num_irqs = ARRAY_SIZE(rknpu_irqs),
+ .num_resets = ARRAY_SIZE(rknpu_resets),
+ .nbuf_phyaddr = 0,
+ .nbuf_size = 0
};
static const struct rknpu_config rk3588_rknpu_config = {
@@ -131,11 +128,15 @@
.pc_data_amount_scale = 2,
.pc_task_number_bits = 12,
.pc_task_number_mask = 0xfff,
+ .pc_task_status_offset = 0x3c,
+ .pc_dma_ctrl = 0,
.bw_enable = 0,
.irqs = rk3588_npu_irqs,
.resets = rk3588_npu_resets,
.num_irqs = ARRAY_SIZE(rk3588_npu_irqs),
- .num_resets = ARRAY_SIZE(rk3588_npu_resets)
+ .num_resets = ARRAY_SIZE(rk3588_npu_resets),
+ .nbuf_phyaddr = 0,
+ .nbuf_size = 0
};
static const struct rknpu_config rv1106_rknpu_config = {
@@ -145,11 +146,33 @@
.pc_data_amount_scale = 2,
.pc_task_number_bits = 16,
.pc_task_number_mask = 0xffff,
+ .pc_task_status_offset = 0x3c,
+ .pc_dma_ctrl = 0,
.bw_enable = 1,
- .irqs = rv110x_npu_irqs,
- .resets = rv110x_npu_resets,
- .num_irqs = ARRAY_SIZE(rv110x_npu_irqs),
- .num_resets = ARRAY_SIZE(rv110x_npu_resets)
+ .irqs = rknpu_irqs,
+ .resets = rknpu_resets,
+ .num_irqs = ARRAY_SIZE(rknpu_irqs),
+ .num_resets = ARRAY_SIZE(rknpu_resets),
+ .nbuf_phyaddr = 0,
+ .nbuf_size = 0
+};
+
+static const struct rknpu_config rk3562_rknpu_config = {
+ .bw_priority_addr = 0x0,
+ .bw_priority_length = 0x0,
+ .dma_mask = DMA_BIT_MASK(40),
+ .pc_data_amount_scale = 2,
+ .pc_task_number_bits = 16,
+ .pc_task_number_mask = 0xffff,
+ .pc_task_status_offset = 0x48,
+ .pc_dma_ctrl = 1,
+ .bw_enable = 1,
+ .irqs = rknpu_irqs,
+ .resets = rknpu_resets,
+ .num_irqs = ARRAY_SIZE(rknpu_irqs),
+ .num_resets = ARRAY_SIZE(rknpu_resets),
+ .nbuf_phyaddr = 0xfe400000,
+ .nbuf_size = 256 * 1024
};
/* driver probe and init */
@@ -169,6 +192,10 @@
{
.compatible = "rockchip,rv1106-rknpu",
.data = &rv1106_rknpu_config,
+ },
+ {
+ .compatible = "rockchip,rk3562-rknpu",
+ .data = &rk3562_rknpu_config,
},
{},
};
@@ -245,13 +272,17 @@
ret = rknpu_get_drv_version(&args->value);
break;
case RKNPU_GET_FREQ:
+#ifndef FPGA_PLATFORM
args->value = clk_get_rate(rknpu_dev->clks[0].clk);
+#endif
ret = 0;
break;
case RKNPU_SET_FREQ:
break;
case RKNPU_GET_VOLT:
+#ifndef FPGA_PLATFORM
args->value = regulator_get_voltage(rknpu_dev->vdd);
+#endif
ret = 0;
break;
case RKNPU_SET_VOLT:
@@ -330,11 +361,56 @@
#ifdef CONFIG_ROCKCHIP_RKNPU_DMA_HEAP
static int rknpu_open(struct inode *inode, struct file *file)
{
+ struct rknpu_device *rknpu_dev =
+ container_of(file->private_data, struct rknpu_device, miscdev);
+ struct rknpu_session *session = NULL;
+
+ session = kzalloc(sizeof(*session), GFP_KERNEL);
+ if (!session) {
+ LOG_ERROR("rknpu session alloc failed\n");
+ return -ENOMEM;
+ }
+
+ session->rknpu_dev = rknpu_dev;
+ INIT_LIST_HEAD(&session->list);
+
+ file->private_data = (void *)session;
+
return nonseekable_open(inode, file);
}
static int rknpu_release(struct inode *inode, struct file *file)
{
+ struct rknpu_mem_object *entry;
+ struct rknpu_session *session = file->private_data;
+ struct rknpu_device *rknpu_dev = session->rknpu_dev;
+ LIST_HEAD(local_list);
+
+ spin_lock(&rknpu_dev->lock);
+ list_replace_init(&session->list, &local_list);
+ file->private_data = NULL;
+ spin_unlock(&rknpu_dev->lock);
+
+ while (!list_empty(&local_list)) {
+ entry = list_first_entry(&local_list, struct rknpu_mem_object,
+ head);
+
+ LOG_DEBUG(
+ "Fd close free rknpu_obj: %#llx, rknpu_obj->dma_addr: %#llx\n",
+ (__u64)(uintptr_t)entry, (__u64)entry->dma_addr);
+
+ vunmap(entry->kv_addr);
+ entry->kv_addr = NULL;
+
+ if (!entry->owner)
+ dma_buf_put(entry->dmabuf);
+
+ list_del(&entry->head);
+ kfree(entry);
+ }
+
+ kfree(session);
+
return 0;
}
@@ -366,8 +442,12 @@
static long rknpu_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
{
long ret = -EINVAL;
- struct rknpu_device *rknpu_dev =
- container_of(file->private_data, struct rknpu_device, miscdev);
+ struct rknpu_device *rknpu_dev = NULL;
+
+ if (!file->private_data)
+ return -EINVAL;
+
+ rknpu_dev = ((struct rknpu_session *)file->private_data)->rknpu_dev;
rknpu_power_get(rknpu_dev);
@@ -379,12 +459,12 @@
ret = rknpu_submit_ioctl(rknpu_dev, arg);
break;
case IOCTL_RKNPU_MEM_CREATE:
- ret = rknpu_mem_create_ioctl(rknpu_dev, arg);
+ ret = rknpu_mem_create_ioctl(rknpu_dev, arg, file);
break;
case RKNPU_MEM_MAP:
break;
case IOCTL_RKNPU_MEM_DESTROY:
- ret = rknpu_mem_destroy_ioctl(rknpu_dev, arg);
+ ret = rknpu_mem_destroy_ioctl(rknpu_dev, arg, file);
break;
case IOCTL_RKNPU_MEM_SYNC:
ret = rknpu_mem_sync_ioctl(rknpu_dev, arg);
@@ -802,7 +882,7 @@
#ifndef FPGA_PLATFORM
static struct monitor_dev_profile npu_mdevp = {
- .type = MONITOR_TPYE_DEV,
+ .type = MONITOR_TYPE_DEV,
.low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
.high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
@@ -1107,6 +1187,66 @@
};
#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
+static int rk3588_npu_get_soc_info(struct device *dev, struct device_node *np,
+ int *bin, int *process)
+{
+ int ret = 0;
+ u8 value = 0;
+
+ if (!bin)
+ return 0;
+
+ if (of_property_match_string(np, "nvmem-cell-names",
+ "specification_serial_number") >= 0) {
+ ret = rockchip_nvmem_cell_read_u8(
+ np, "specification_serial_number", &value);
+ if (ret) {
+ LOG_DEV_ERROR(
+ dev,
+ "Failed to get specification_serial_number\n");
+ return ret;
+ }
+ /* RK3588M */
+ if (value == 0xd)
+ *bin = 1;
+ /* RK3588J */
+ else if (value == 0xa)
+ *bin = 2;
+ }
+ if (*bin < 0)
+ *bin = 0;
+ LOG_DEV_INFO(dev, "bin=%d\n", *bin);
+
+ return ret;
+}
+
+static int rk3588_npu_set_soc_info(struct device *dev, struct device_node *np,
+ int bin, int process, int volt_sel)
+{
+ struct opp_table *opp_table;
+ u32 supported_hw[2];
+
+ if (volt_sel < 0)
+ return 0;
+ if (bin < 0)
+ bin = 0;
+
+ if (!of_property_read_bool(np, "rockchip,supported-hw"))
+ return 0;
+
+ /* SoC Version */
+ supported_hw[0] = BIT(bin);
+ /* Speed Grade */
+ supported_hw[1] = BIT(volt_sel);
+ opp_table = dev_pm_opp_set_supported_hw(dev, supported_hw, 2);
+ if (IS_ERR(opp_table)) {
+ LOG_DEV_ERROR(dev, "failed to set supported opp\n");
+ return PTR_ERR(opp_table);
+ }
+
+ return 0;
+}
+
static int rk3588_npu_set_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
u32 rm)
@@ -1139,6 +1279,8 @@
}
static const struct rockchip_opp_data rk3588_npu_opp_data = {
+ .get_soc_info = rk3588_npu_get_soc_info,
+ .set_soc_info = rk3588_npu_set_soc_info,
.set_read_margin = rk3588_npu_set_read_margin,
};
@@ -1518,6 +1660,31 @@
return 0;
}
+static int rknpu_find_nbuf_resource(struct rknpu_device *rknpu_dev)
+{
+ struct device *dev = rknpu_dev->dev;
+
+ if (rknpu_dev->config->nbuf_size == 0)
+ return -EINVAL;
+
+ rknpu_dev->nbuf_start = rknpu_dev->config->nbuf_phyaddr;
+ rknpu_dev->nbuf_size = rknpu_dev->config->nbuf_size;
+ rknpu_dev->nbuf_base_io =
+ devm_ioremap(dev, rknpu_dev->nbuf_start, rknpu_dev->nbuf_size);
+ if (IS_ERR(rknpu_dev->nbuf_base_io)) {
+ LOG_DEV_ERROR(dev, "failed to remap nbuf base io!\n");
+ rknpu_dev->nbuf_base_io = NULL;
+ }
+
+ rknpu_dev->nbuf_end = rknpu_dev->nbuf_start + rknpu_dev->nbuf_size;
+
+ LOG_DEV_INFO(dev, "nbuf region: [%pa, %pa), nbuf size: %#x\n",
+ &rknpu_dev->nbuf_start, &rknpu_dev->nbuf_end,
+ rknpu_dev->nbuf_size);
+
+ return 0;
+}
+
static int rknpu_probe(struct platform_device *pdev)
{
struct resource *res = NULL;
@@ -1734,7 +1901,8 @@
INIT_DEFERRABLE_WORK(&rknpu_dev->power_off_work,
rknpu_power_off_delay_work);
- if (IS_ENABLED(CONFIG_ROCKCHIP_RKNPU_SRAM) && rknpu_dev->iommu_en) {
+ if (IS_ENABLED(CONFIG_NO_GKI) &&
+ IS_ENABLED(CONFIG_ROCKCHIP_RKNPU_SRAM) && rknpu_dev->iommu_en) {
if (!rknpu_find_sram_resource(rknpu_dev)) {
ret = rknpu_mm_create(rknpu_dev->sram_size, PAGE_SIZE,
&rknpu_dev->sram_mm);
@@ -1745,6 +1913,10 @@
}
}
+ if (IS_ENABLED(CONFIG_NO_GKI) && rknpu_dev->iommu_en &&
+ rknpu_dev->config->nbuf_size > 0)
+ rknpu_find_nbuf_resource(rknpu_dev);
+
rknpu_power_off(rknpu_dev);
atomic_set(&rknpu_dev->power_refcount, 0);
atomic_set(&rknpu_dev->cmdline_power_refcount, 0);
--
Gitblit v1.6.2