From c753cabc173337e6723bc0795d832c676010eb06 Mon Sep 17 00:00:00 2001 From: Matheus Sampaio Queiroga Date: Thu, 15 Jan 2026 18:37:37 -0300 Subject: [PATCH] net: airoha: Update npu loader firmware Signed-off-by: Matheus Sampaio Queiroga --- drivers/net/ethernet/airoha/airoha_npu.c | 122 +++++++++++----------- include/linux/soc/airoha/airoha_offload.h | 1 + 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 06091666d..4fad00561 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -203,21 +203,11 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, } static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, - const struct airoha_npu_fw *fw_info) + const struct airoha_npu_fw *fw_info, const struct firmware *fw) { - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, fw_info->name, dev); - if (ret) { - switch (ret) { - case -ETIMEDOUT: - case -ENONET: - return -EPROBE_DEFER; - default: - return ret; - } - } + int ret = request_firmware(&fw, fw_info->name, dev); + if (ret) + return ret == -ENOENT ? -EPROBE_DEFER : ret; if (fw->size > fw_info->max_size) { dev_err(dev, "%s: fw size too overlimit (%zu)\n", @@ -233,33 +223,62 @@ static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, return ret; } -static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, - struct reserved_mem *rmem) -{ - const struct airoha_npu_soc_data *soc; +static void new_firmware_loader(const struct firmware *fw, void *priv) { + struct airoha_npu *npu = priv; void __iomem *addr; int ret; - soc = of_device_get_match_data(dev); - if (!soc) - return -EINVAL; - - if (soc->use_memremap) - addr = devm_memremap(dev, rmem->base, rmem->size, MEMREMAP_WB); + if (npu->soc_data->use_memremap) + addr = devm_memremap(npu->dev, npu->rmem->base, npu->rmem->size, MEMREMAP_WB); else - addr = devm_ioremap(dev, rmem->base, rmem->size); + addr = devm_ioremap(npu->dev, npu->rmem->base, npu->rmem->size); - if (IS_ERR(addr)) - return PTR_ERR(addr); + if (IS_ERR(addr)) { + ret = PTR_ERR(addr); + dev_err_probe(npu->dev, ret, "Error on get reserverd memory address\n"); + device_release_driver(npu->dev); + return; + } - /* Load rv32 npu firmware */ - ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32); + ret = airoha_npu_load_firmware(npu->dev, addr, &npu->soc_data->fw_rv32, fw); if (ret) - return ret; + goto err; + + ret = request_firmware(&fw, npu->soc_data->fw_data.name, npu->dev); + if (ret) + goto err; + + ret = airoha_npu_load_firmware(npu->dev, npu->base + REG_NPU_LOCAL_SRAM, &npu->soc_data->fw_data, fw); + if (ret) + goto err; - /* Load data npu firmware */ - return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, - &soc->fw_data); + // Get L2C SRAM Size + u32 l2c_sram_size; + regmap_read(npu->scu_regmap, 0x280, &l2c_sram_size); + dev_info(npu->dev, "L2C sram size: 0x%02x\n", l2c_sram_size); + + // Get FPGA Stage + uint32_t isFPGA = 0; + regmap_read(npu->scu_regmap, 0x9c, &isFPGA); + isFPGA = (isFPGA & 0x1) == 0; + dev_info(npu->dev, "FPGA Stage: %d\n", isFPGA); + + // npu_test_area_base + regmap_write(npu->regmap, REG_CR_NPU_MIB(10), + npu->rmem->base + npu->soc_data->fw_rv32.max_size); + regmap_write(npu->regmap, REG_CR_NPU_MIB(11), l2c_sram_size); // host_l2c_sram_size + regmap_write(npu->regmap, REG_CR_NPU_MIB(12), isFPGA); // fPGA stage + regmap_write(npu->regmap, REG_CR_NPU_MIB(21), 1); + msleep(100); + + /* boot NPU cores */ + npu->soc_data->boot_core(npu); + + return; +err: + dev_err_probe(npu->dev, ret, "Error on loader firmware\n"); + device_release_driver(npu->dev); + return; } static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) @@ -761,17 +780,16 @@ static int airoha_npu_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct airoha_npu *npu; struct device_node *np; - void __iomem *base; int i, irq, err; - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - npu = devm_kzalloc(dev, sizeof(*npu), GFP_KERNEL); if (!npu) return -ENOMEM; + npu->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(npu->base)) + return PTR_ERR(npu->base); + npu->soc_data = (struct airoha_npu_soc_data*)of_device_get_match_data(dev); if (!npu->soc_data) return -ENODEV; @@ -791,7 +809,7 @@ static int airoha_npu_probe(struct platform_device *pdev) npu->ops.wlan_enable_irq = airoha_npu_wlan_irq_enable; npu->ops.wlan_disable_irq = airoha_npu_wlan_irq_disable; - npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); + npu->regmap = devm_regmap_init_mmio(dev, npu->base, ®map_config); if (IS_ERR(npu->regmap)) return PTR_ERR(npu->regmap); @@ -812,17 +830,6 @@ static int airoha_npu_probe(struct platform_device *pdev) if (IS_ERR(npu->scu_regmap)) return PTR_ERR(npu->scu_regmap); - // Get L2C SRAM Size - u32 l2c_sram_size; - regmap_read(npu->scu_regmap, 0x280, &l2c_sram_size); - dev_info(dev, "L2C sram size: 0x%02x\n", l2c_sram_size); - - // Get FPGA Stage - uint32_t isFPGA = 0; - regmap_read(npu->scu_regmap, 0x9c, &isFPGA); - isFPGA = (isFPGA & 0x1) == 0; - dev_info(dev, "FPGA Stage: %d\n", isFPGA); - irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -876,22 +883,11 @@ static int airoha_npu_probe(struct platform_device *pdev) return err; } - err = airoha_npu_run_firmware(dev, base, npu->rmem); + platform_set_drvdata(pdev, npu); + err = request_firmware_nowait(THIS_MODULE, true, npu->soc_data->fw_rv32.name, dev, GFP_KERNEL, npu, new_firmware_loader); if (err) return dev_err_probe(dev, err, "failed to run npu firmware\n"); - // npu_test_area_base - regmap_write(npu->regmap, REG_CR_NPU_MIB(10), - npu->rmem->base + npu->soc_data->fw_rv32.max_size); - regmap_write(npu->regmap, REG_CR_NPU_MIB(11), l2c_sram_size); // host_l2c_sram_size - regmap_write(npu->regmap, REG_CR_NPU_MIB(12), isFPGA); // fPGA stage - regmap_write(npu->regmap, REG_CR_NPU_MIB(21), 1); - msleep(100); - - /* boot NPU cores */ - npu->soc_data->boot_core(npu); - platform_set_drvdata(pdev, npu); - return 0; } diff --git a/include/linux/soc/airoha/airoha_offload.h b/include/linux/soc/airoha/airoha_offload.h index 11ef73c8d..7ec0a98c6 100644 --- a/include/linux/soc/airoha/airoha_offload.h +++ b/include/linux/soc/airoha/airoha_offload.h @@ -168,6 +168,7 @@ struct airoha_npu { struct regmap *regmap; struct regmap *scu_regmap; struct reserved_mem *rmem; + void __iomem *base; struct airoha_npu_soc_data *soc_data; -- 2.52.0