|
16 | 16 |
|
17 | 17 | #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" |
18 | 18 | #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" |
| 19 | +#define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin" |
| 20 | +#define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin" |
19 | 21 | #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 |
20 | 22 | #define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 |
21 | 23 | #define NPU_DUMP_SIZE 512 |
@@ -103,6 +105,16 @@ enum { |
103 | 105 | QDMA_WAN_PON_XDSL, |
104 | 106 | }; |
105 | 107 |
|
| 108 | +struct airoha_npu_fw { |
| 109 | + const char *name; |
| 110 | + int max_size; |
| 111 | +}; |
| 112 | + |
| 113 | +struct airoha_npu_soc_data { |
| 114 | + struct airoha_npu_fw fw_rv32; |
| 115 | + struct airoha_npu_fw fw_data; |
| 116 | +}; |
| 117 | + |
106 | 118 | #define MBOX_MSG_FUNC_ID GENMASK(14, 11) |
107 | 119 | #define MBOX_MSG_STATIC_BUF BIT(5) |
108 | 120 | #define MBOX_MSG_STATUS GENMASK(4, 2) |
@@ -182,49 +194,53 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, |
182 | 194 | return ret; |
183 | 195 | } |
184 | 196 |
|
185 | | -static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, |
186 | | - struct resource *res) |
| 197 | +static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, |
| 198 | + const struct airoha_npu_fw *fw_info) |
187 | 199 | { |
188 | 200 | const struct firmware *fw; |
189 | | - void __iomem *addr; |
190 | 201 | int ret; |
191 | 202 |
|
192 | | - ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); |
| 203 | + ret = request_firmware(&fw, fw_info->name, dev); |
193 | 204 | if (ret) |
194 | 205 | return ret == -ENOENT ? -EPROBE_DEFER : ret; |
195 | 206 |
|
196 | | - if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { |
| 207 | + if (fw->size > fw_info->max_size) { |
197 | 208 | dev_err(dev, "%s: fw size too overlimit (%zu)\n", |
198 | | - NPU_EN7581_FIRMWARE_RV32, fw->size); |
| 209 | + fw_info->name, fw->size); |
199 | 210 | ret = -E2BIG; |
200 | 211 | goto out; |
201 | 212 | } |
202 | 213 |
|
203 | | - addr = devm_ioremap_resource(dev, res); |
204 | | - if (IS_ERR(addr)) { |
205 | | - ret = PTR_ERR(addr); |
206 | | - goto out; |
207 | | - } |
208 | | - |
209 | 214 | memcpy_toio(addr, fw->data, fw->size); |
| 215 | +out: |
210 | 216 | release_firmware(fw); |
211 | 217 |
|
212 | | - ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); |
213 | | - if (ret) |
214 | | - return ret == -ENOENT ? -EPROBE_DEFER : ret; |
| 218 | + return ret; |
| 219 | +} |
215 | 220 |
|
216 | | - if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) { |
217 | | - dev_err(dev, "%s: fw size too overlimit (%zu)\n", |
218 | | - NPU_EN7581_FIRMWARE_DATA, fw->size); |
219 | | - ret = -E2BIG; |
220 | | - goto out; |
221 | | - } |
| 221 | +static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, |
| 222 | + struct resource *res) |
| 223 | +{ |
| 224 | + const struct airoha_npu_soc_data *soc; |
| 225 | + void __iomem *addr; |
| 226 | + int ret; |
222 | 227 |
|
223 | | - memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); |
224 | | -out: |
225 | | - release_firmware(fw); |
| 228 | + soc = of_device_get_match_data(dev); |
| 229 | + if (!soc) |
| 230 | + return -EINVAL; |
226 | 231 |
|
227 | | - return ret; |
| 232 | + addr = devm_ioremap_resource(dev, res); |
| 233 | + if (IS_ERR(addr)) |
| 234 | + return PTR_ERR(addr); |
| 235 | + |
| 236 | + /* Load rv32 npu firmware */ |
| 237 | + ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32); |
| 238 | + if (ret) |
| 239 | + return ret; |
| 240 | + |
| 241 | + /* Load data npu firmware */ |
| 242 | + return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, |
| 243 | + &soc->fw_data); |
228 | 244 | } |
229 | 245 |
|
230 | 246 | static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) |
@@ -597,8 +613,31 @@ void airoha_npu_put(struct airoha_npu *npu) |
597 | 613 | } |
598 | 614 | EXPORT_SYMBOL_GPL(airoha_npu_put); |
599 | 615 |
|
| 616 | +static const struct airoha_npu_soc_data en7581_npu_soc_data = { |
| 617 | + .fw_rv32 = { |
| 618 | + .name = NPU_EN7581_FIRMWARE_RV32, |
| 619 | + .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE, |
| 620 | + }, |
| 621 | + .fw_data = { |
| 622 | + .name = NPU_EN7581_FIRMWARE_DATA, |
| 623 | + .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE, |
| 624 | + }, |
| 625 | +}; |
| 626 | + |
| 627 | +static const struct airoha_npu_soc_data an7583_npu_soc_data = { |
| 628 | + .fw_rv32 = { |
| 629 | + .name = NPU_AN7583_FIRMWARE_RV32, |
| 630 | + .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE, |
| 631 | + }, |
| 632 | + .fw_data = { |
| 633 | + .name = NPU_AN7583_FIRMWARE_DATA, |
| 634 | + .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE, |
| 635 | + }, |
| 636 | +}; |
| 637 | + |
600 | 638 | static const struct of_device_id of_airoha_npu_match[] = { |
601 | | - { .compatible = "airoha,en7581-npu" }, |
| 639 | + { .compatible = "airoha,en7581-npu", .data = &en7581_npu_soc_data }, |
| 640 | + { .compatible = "airoha,an7583-npu", .data = &an7583_npu_soc_data }, |
602 | 641 | { /* sentinel */ } |
603 | 642 | }; |
604 | 643 | MODULE_DEVICE_TABLE(of, of_airoha_npu_match); |
@@ -737,6 +776,8 @@ module_platform_driver(airoha_npu_driver); |
737 | 776 |
|
738 | 777 | MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); |
739 | 778 | MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); |
| 779 | +MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA); |
| 780 | +MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32); |
740 | 781 | MODULE_LICENSE("GPL"); |
741 | 782 | MODULE_AUTHOR( "Lorenzo Bianconi <[email protected]>"); |
742 | 783 | MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); |
0 commit comments