|
|
@@ -0,0 +1,136 @@
|
|
|
+From 0850ae496d534847ec2c26744521c1bce04ec59d Mon Sep 17 00:00:00 2001
|
|
|
+From: Lorenzo Bianconi <[email protected]>
|
|
|
+Date: Mon, 13 Oct 2025 15:58:50 +0200
|
|
|
+Subject: [PATCH 2/3] net: airoha: npu: Add airoha_npu_soc_data struct
|
|
|
+
|
|
|
+Introduce airoha_npu_soc_data structure in order to generalize per-SoC
|
|
|
+NPU firmware info. Introduce airoha_npu_load_firmware utility routine.
|
|
|
+This is a preliminary patch in order to introduce AN7583 NPU support.
|
|
|
+
|
|
|
+Signed-off-by: Lorenzo Bianconi <[email protected]>
|
|
|
+Reviewed-by: Simon Horman <[email protected]>
|
|
|
+Link: https://patch.msgid.link/[email protected]
|
|
|
+Signed-off-by: Jakub Kicinski <[email protected]>
|
|
|
+---
|
|
|
+ drivers/net/ethernet/airoha/airoha_npu.c | 77 ++++++++++++++++--------
|
|
|
+ 1 file changed, 51 insertions(+), 26 deletions(-)
|
|
|
+
|
|
|
+--- a/drivers/net/ethernet/airoha/airoha_npu.c
|
|
|
++++ b/drivers/net/ethernet/airoha/airoha_npu.c
|
|
|
+@@ -103,6 +103,16 @@ enum {
|
|
|
+ QDMA_WAN_PON_XDSL,
|
|
|
+ };
|
|
|
+
|
|
|
++struct airoha_npu_fw {
|
|
|
++ const char *name;
|
|
|
++ int max_size;
|
|
|
++};
|
|
|
++
|
|
|
++struct airoha_npu_soc_data {
|
|
|
++ struct airoha_npu_fw fw_rv32;
|
|
|
++ struct airoha_npu_fw fw_data;
|
|
|
++};
|
|
|
++
|
|
|
+ #define MBOX_MSG_FUNC_ID GENMASK(14, 11)
|
|
|
+ #define MBOX_MSG_STATIC_BUF BIT(5)
|
|
|
+ #define MBOX_MSG_STATUS GENMASK(4, 2)
|
|
|
+@@ -182,49 +192,53 @@ static int airoha_npu_send_msg(struct ai
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int airoha_npu_run_firmware(struct device *dev, void __iomem *base,
|
|
|
+- struct reserved_mem *rmem)
|
|
|
++static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr,
|
|
|
++ const struct airoha_npu_fw *fw_info)
|
|
|
+ {
|
|
|
+ const struct firmware *fw;
|
|
|
+- void __iomem *addr;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev);
|
|
|
++ ret = request_firmware(&fw, fw_info->name, dev);
|
|
|
+ if (ret)
|
|
|
+ return ret == -ENOENT ? -EPROBE_DEFER : ret;
|
|
|
+
|
|
|
+- if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) {
|
|
|
++ if (fw->size > fw_info->max_size) {
|
|
|
+ dev_err(dev, "%s: fw size too overlimit (%zu)\n",
|
|
|
+- NPU_EN7581_FIRMWARE_RV32, fw->size);
|
|
|
++ fw_info->name, fw->size);
|
|
|
+ ret = -E2BIG;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+- addr = devm_ioremap(dev, rmem->base, rmem->size);
|
|
|
+- if (IS_ERR(addr)) {
|
|
|
+- ret = PTR_ERR(addr);
|
|
|
+- goto out;
|
|
|
+- }
|
|
|
+-
|
|
|
+ memcpy_toio(addr, fw->data, fw->size);
|
|
|
++out:
|
|
|
+ release_firmware(fw);
|
|
|
+
|
|
|
+- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev);
|
|
|
+- if (ret)
|
|
|
+- return ret == -ENOENT ? -EPROBE_DEFER : ret;
|
|
|
++ return ret;
|
|
|
++}
|
|
|
+
|
|
|
+- if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) {
|
|
|
+- dev_err(dev, "%s: fw size too overlimit (%zu)\n",
|
|
|
+- NPU_EN7581_FIRMWARE_DATA, fw->size);
|
|
|
+- ret = -E2BIG;
|
|
|
+- goto out;
|
|
|
+- }
|
|
|
++static int airoha_npu_run_firmware(struct device *dev, void __iomem *base,
|
|
|
++ struct reserved_mem *rmem)
|
|
|
++{
|
|
|
++ const struct airoha_npu_soc_data *soc;
|
|
|
++ void __iomem *addr;
|
|
|
++ int ret;
|
|
|
+
|
|
|
+- memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size);
|
|
|
+-out:
|
|
|
+- release_firmware(fw);
|
|
|
++ soc = of_device_get_match_data(dev);
|
|
|
++ if (!soc)
|
|
|
++ return -EINVAL;
|
|
|
+
|
|
|
+- return ret;
|
|
|
++ addr = devm_ioremap(dev, rmem->base, rmem->size);
|
|
|
++ if (IS_ERR(addr))
|
|
|
++ return PTR_ERR(addr);
|
|
|
++
|
|
|
++ /* Load rv32 npu firmware */
|
|
|
++ ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32);
|
|
|
++ if (ret)
|
|
|
++ return ret;
|
|
|
++
|
|
|
++ /* Load data npu firmware */
|
|
|
++ return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM,
|
|
|
++ &soc->fw_data);
|
|
|
+ }
|
|
|
+
|
|
|
+ static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance)
|
|
|
+@@ -596,8 +610,19 @@ void airoha_npu_put(struct airoha_npu *n
|
|
|
+ }
|
|
|
+ EXPORT_SYMBOL_GPL(airoha_npu_put);
|
|
|
+
|
|
|
++static const struct airoha_npu_soc_data en7581_npu_soc_data = {
|
|
|
++ .fw_rv32 = {
|
|
|
++ .name = NPU_EN7581_FIRMWARE_RV32,
|
|
|
++ .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE,
|
|
|
++ },
|
|
|
++ .fw_data = {
|
|
|
++ .name = NPU_EN7581_FIRMWARE_DATA,
|
|
|
++ .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE,
|
|
|
++ },
|
|
|
++};
|
|
|
++
|
|
|
+ static const struct of_device_id of_airoha_npu_match[] = {
|
|
|
+- { .compatible = "airoha,en7581-npu" },
|
|
|
++ { .compatible = "airoha,en7581-npu", .data = &en7581_npu_soc_data },
|
|
|
+ { /* sentinel */ }
|
|
|
+ };
|
|
|
+ MODULE_DEVICE_TABLE(of, of_airoha_npu_match);
|