1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2025 AIROHA Inc 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 */ 6 7 #include <linux/devcoredump.h> 8 #include <linux/firmware.h> 9 #include <linux/platform_device.h> 10 #include <linux/of_net.h> 11 #include <linux/of_platform.h> 12 #include <linux/of_reserved_mem.h> 13 #include <linux/regmap.h> 14 15 #include "airoha_eth.h" 16 17 #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" 18 #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" 19 #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 20 #define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 21 #define NPU_DUMP_SIZE 512 22 23 #define REG_NPU_LOCAL_SRAM 0x0 24 25 #define NPU_PC_BASE_ADDR 0x305000 26 #define REG_PC_DBG(_n) (0x305000 + ((_n) * 0x100)) 27 28 #define NPU_CLUSTER_BASE_ADDR 0x306000 29 30 #define REG_CR_BOOT_TRIGGER (NPU_CLUSTER_BASE_ADDR + 0x000) 31 #define REG_CR_BOOT_CONFIG (NPU_CLUSTER_BASE_ADDR + 0x004) 32 #define REG_CR_BOOT_BASE(_n) (NPU_CLUSTER_BASE_ADDR + 0x020 + ((_n) << 2)) 33 34 #define NPU_MBOX_BASE_ADDR 0x30c000 35 36 #define REG_CR_MBOX_INT_STATUS (NPU_MBOX_BASE_ADDR + 0x000) 37 #define MBOX_INT_STATUS_MASK BIT(8) 38 39 #define REG_CR_MBOX_INT_MASK(_n) (NPU_MBOX_BASE_ADDR + 0x004 + ((_n) << 2)) 40 #define REG_CR_MBQ0_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x030 + ((_n) << 2)) 41 #define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) 42 #define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) 43 44 #define NPU_WLAN_BASE_ADDR 0x30d000 45 46 #define REG_IRQ_STATUS (NPU_WLAN_BASE_ADDR + 0x030) 47 #define REG_IRQ_RXDONE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 2) + 0x034) 48 #define NPU_IRQ_RX_MASK(_n) ((_n) == 1 ? BIT(17) : BIT(16)) 49 50 #define REG_TX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x080) 51 #define REG_TX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x084) 52 #define REG_TX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x088) 53 #define REG_TX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x08c) 54 55 #define REG_RX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x180) 56 #define REG_RX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x184) 57 #define REG_RX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x188) 58 #define REG_RX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x18c) 59 60 #define NPU_TIMER_BASE_ADDR 0x310100 61 #define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) 62 #define WDT_EN_MASK BIT(25) 63 #define WDT_INTR_MASK BIT(21) 64 65 enum { 66 NPU_OP_SET = 1, 67 NPU_OP_SET_NO_WAIT, 68 NPU_OP_GET, 69 NPU_OP_GET_NO_WAIT, 70 }; 71 72 enum { 73 NPU_FUNC_WIFI, 74 NPU_FUNC_TUNNEL, 75 NPU_FUNC_NOTIFY, 76 NPU_FUNC_DBA, 77 NPU_FUNC_TR471, 78 NPU_FUNC_PPE, 79 }; 80 81 enum { 82 NPU_MBOX_ERROR, 83 NPU_MBOX_SUCCESS, 84 }; 85 86 enum { 87 PPE_FUNC_SET_WAIT, 88 PPE_FUNC_SET_WAIT_HWNAT_INIT, 89 PPE_FUNC_SET_WAIT_HWNAT_DEINIT, 90 PPE_FUNC_SET_WAIT_API, 91 PPE_FUNC_SET_WAIT_FLOW_STATS_SETUP, 92 }; 93 94 enum { 95 PPE2_SRAM_SET_ENTRY, 96 PPE_SRAM_SET_ENTRY, 97 PPE_SRAM_SET_VAL, 98 PPE_SRAM_RESET_VAL, 99 }; 100 101 enum { 102 QDMA_WAN_ETHER = 1, 103 QDMA_WAN_PON_XDSL, 104 }; 105 106 #define MBOX_MSG_FUNC_ID GENMASK(14, 11) 107 #define MBOX_MSG_STATIC_BUF BIT(5) 108 #define MBOX_MSG_STATUS GENMASK(4, 2) 109 #define MBOX_MSG_DONE BIT(1) 110 #define MBOX_MSG_WAIT_RSP BIT(0) 111 112 #define PPE_TYPE_L2B_IPV4 2 113 #define PPE_TYPE_L2B_IPV4_IPV6 3 114 115 struct ppe_mbox_data { 116 u32 func_type; 117 u32 func_id; 118 union { 119 struct { 120 u8 cds; 121 u8 xpon_hal_api; 122 u8 wan_xsi; 123 u8 ct_joyme4; 124 u8 max_packet; 125 u8 rsv[3]; 126 u32 ppe_type; 127 u32 wan_mode; 128 u32 wan_sel; 129 } init_info; 130 struct { 131 u32 func_id; 132 u32 size; 133 u32 data; 134 } set_info; 135 struct { 136 u32 npu_stats_addr; 137 u32 foe_stats_addr; 138 } stats_info; 139 }; 140 }; 141 142 struct wlan_mbox_data { 143 u32 ifindex:4; 144 u32 func_type:4; 145 u32 func_id; 146 DECLARE_FLEX_ARRAY(u8, d); 147 }; 148 149 static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, 150 void *p, int size) 151 { 152 u16 core = 0; /* FIXME */ 153 u32 val, offset = core << 4; 154 dma_addr_t dma_addr; 155 int ret; 156 157 dma_addr = dma_map_single(npu->dev, p, size, DMA_TO_DEVICE); 158 ret = dma_mapping_error(npu->dev, dma_addr); 159 if (ret) 160 return ret; 161 162 spin_lock_bh(&npu->cores[core].lock); 163 164 regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(0) + offset, dma_addr); 165 regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(1) + offset, size); 166 regmap_read(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, &val); 167 regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, val + 1); 168 val = FIELD_PREP(MBOX_MSG_FUNC_ID, func_id) | MBOX_MSG_WAIT_RSP; 169 regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(3) + offset, val); 170 171 ret = regmap_read_poll_timeout_atomic(npu->regmap, 172 REG_CR_MBQ0_CTRL(3) + offset, 173 val, (val & MBOX_MSG_DONE), 174 100, 100 * MSEC_PER_SEC); 175 if (!ret && FIELD_GET(MBOX_MSG_STATUS, val) != NPU_MBOX_SUCCESS) 176 ret = -EINVAL; 177 178 spin_unlock_bh(&npu->cores[core].lock); 179 180 dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE); 181 182 return ret; 183 } 184 185 static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, 186 struct resource *res) 187 { 188 const struct firmware *fw; 189 void __iomem *addr; 190 int ret; 191 192 ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); 193 if (ret) 194 return ret == -ENOENT ? -EPROBE_DEFER : ret; 195 196 if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { 197 dev_err(dev, "%s: fw size too overlimit (%zu)\n", 198 NPU_EN7581_FIRMWARE_RV32, fw->size); 199 ret = -E2BIG; 200 goto out; 201 } 202 203 addr = devm_ioremap_resource(dev, res); 204 if (IS_ERR(addr)) { 205 ret = PTR_ERR(addr); 206 goto out; 207 } 208 209 memcpy_toio(addr, fw->data, fw->size); 210 release_firmware(fw); 211 212 ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); 213 if (ret) 214 return ret == -ENOENT ? -EPROBE_DEFER : ret; 215 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 } 222 223 memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); 224 out: 225 release_firmware(fw); 226 227 return ret; 228 } 229 230 static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) 231 { 232 struct airoha_npu *npu = npu_instance; 233 234 /* clear mbox interrupt status */ 235 regmap_write(npu->regmap, REG_CR_MBOX_INT_STATUS, 236 MBOX_INT_STATUS_MASK); 237 238 /* acknowledge npu */ 239 regmap_update_bits(npu->regmap, REG_CR_MBQ8_CTRL(3), 240 MBOX_MSG_STATUS | MBOX_MSG_DONE, MBOX_MSG_DONE); 241 242 return IRQ_HANDLED; 243 } 244 245 static void airoha_npu_wdt_work(struct work_struct *work) 246 { 247 struct airoha_npu_core *core; 248 struct airoha_npu *npu; 249 void *dump; 250 u32 val[3]; 251 int c; 252 253 core = container_of(work, struct airoha_npu_core, wdt_work); 254 npu = core->npu; 255 256 dump = vzalloc(NPU_DUMP_SIZE); 257 if (!dump) 258 return; 259 260 c = core - &npu->cores[0]; 261 regmap_bulk_read(npu->regmap, REG_PC_DBG(c), val, ARRAY_SIZE(val)); 262 snprintf(dump, NPU_DUMP_SIZE, "PC: %08x SP: %08x LR: %08x\n", 263 val[0], val[1], val[2]); 264 265 dev_coredumpv(npu->dev, dump, NPU_DUMP_SIZE, GFP_KERNEL); 266 } 267 268 static irqreturn_t airoha_npu_wdt_handler(int irq, void *core_instance) 269 { 270 struct airoha_npu_core *core = core_instance; 271 struct airoha_npu *npu = core->npu; 272 int c = core - &npu->cores[0]; 273 u32 val; 274 275 regmap_set_bits(npu->regmap, REG_WDT_TIMER_CTRL(c), WDT_INTR_MASK); 276 if (!regmap_read(npu->regmap, REG_WDT_TIMER_CTRL(c), &val) && 277 FIELD_GET(WDT_EN_MASK, val)) 278 schedule_work(&core->wdt_work); 279 280 return IRQ_HANDLED; 281 } 282 283 static int airoha_npu_ppe_init(struct airoha_npu *npu) 284 { 285 struct ppe_mbox_data *ppe_data; 286 int err; 287 288 ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); 289 if (!ppe_data) 290 return -ENOMEM; 291 292 ppe_data->func_type = NPU_OP_SET; 293 ppe_data->func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT; 294 ppe_data->init_info.ppe_type = PPE_TYPE_L2B_IPV4_IPV6; 295 ppe_data->init_info.wan_mode = QDMA_WAN_ETHER; 296 297 err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, 298 sizeof(*ppe_data)); 299 kfree(ppe_data); 300 301 return err; 302 } 303 304 static int airoha_npu_ppe_deinit(struct airoha_npu *npu) 305 { 306 struct ppe_mbox_data *ppe_data; 307 int err; 308 309 ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); 310 if (!ppe_data) 311 return -ENOMEM; 312 313 ppe_data->func_type = NPU_OP_SET; 314 ppe_data->func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT; 315 316 err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, 317 sizeof(*ppe_data)); 318 kfree(ppe_data); 319 320 return err; 321 } 322 323 static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, 324 dma_addr_t foe_addr, 325 int sram_num_entries) 326 { 327 struct ppe_mbox_data *ppe_data; 328 int err; 329 330 ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); 331 if (!ppe_data) 332 return -ENOMEM; 333 334 ppe_data->func_type = NPU_OP_SET; 335 ppe_data->func_id = PPE_FUNC_SET_WAIT_API; 336 ppe_data->set_info.func_id = PPE_SRAM_RESET_VAL; 337 ppe_data->set_info.data = foe_addr; 338 ppe_data->set_info.size = sram_num_entries; 339 340 err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, 341 sizeof(*ppe_data)); 342 kfree(ppe_data); 343 344 return err; 345 } 346 347 static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, 348 dma_addr_t foe_addr, 349 u32 entry_size, u32 hash, bool ppe2) 350 { 351 struct ppe_mbox_data *ppe_data; 352 int err; 353 354 ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); 355 if (!ppe_data) 356 return -ENOMEM; 357 358 ppe_data->func_type = NPU_OP_SET; 359 ppe_data->func_id = PPE_FUNC_SET_WAIT_API; 360 ppe_data->set_info.data = foe_addr; 361 ppe_data->set_info.size = entry_size; 362 ppe_data->set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY 363 : PPE_SRAM_SET_ENTRY; 364 365 err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, 366 sizeof(*ppe_data)); 367 if (err) 368 goto out; 369 370 ppe_data->set_info.func_id = PPE_SRAM_SET_VAL; 371 ppe_data->set_info.data = hash; 372 ppe_data->set_info.size = sizeof(u32); 373 374 err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, 375 sizeof(*ppe_data)); 376 out: 377 kfree(ppe_data); 378 379 return err; 380 } 381 382 static int airoha_npu_stats_setup(struct airoha_npu *npu, 383 dma_addr_t foe_stats_addr) 384 { 385 int err, size = PPE_STATS_NUM_ENTRIES * sizeof(*npu->stats); 386 struct ppe_mbox_data *ppe_data; 387 388 if (!size) /* flow stats are disabled */ 389 return 0; 390 391 ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); 392 if (!ppe_data) 393 return -ENOMEM; 394 395 ppe_data->func_type = NPU_OP_SET; 396 ppe_data->func_id = PPE_FUNC_SET_WAIT_FLOW_STATS_SETUP; 397 ppe_data->stats_info.foe_stats_addr = foe_stats_addr; 398 399 err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, 400 sizeof(*ppe_data)); 401 if (err) 402 goto out; 403 404 npu->stats = devm_ioremap(npu->dev, 405 ppe_data->stats_info.npu_stats_addr, 406 size); 407 if (!npu->stats) 408 err = -ENOMEM; 409 out: 410 kfree(ppe_data); 411 412 return err; 413 } 414 415 static int airoha_npu_wlan_msg_send(struct airoha_npu *npu, int ifindex, 416 enum airoha_npu_wlan_set_cmd func_id, 417 void *data, int data_len, gfp_t gfp) 418 { 419 struct wlan_mbox_data *wlan_data; 420 int err, len; 421 422 len = sizeof(*wlan_data) + data_len; 423 wlan_data = kzalloc(len, gfp); 424 if (!wlan_data) 425 return -ENOMEM; 426 427 wlan_data->ifindex = ifindex; 428 wlan_data->func_type = NPU_OP_SET; 429 wlan_data->func_id = func_id; 430 memcpy(wlan_data->d, data, data_len); 431 432 err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, len); 433 kfree(wlan_data); 434 435 return err; 436 } 437 438 static int airoha_npu_wlan_msg_get(struct airoha_npu *npu, int ifindex, 439 enum airoha_npu_wlan_get_cmd func_id, 440 void *data, int data_len, gfp_t gfp) 441 { 442 struct wlan_mbox_data *wlan_data; 443 int err, len; 444 445 len = sizeof(*wlan_data) + data_len; 446 wlan_data = kzalloc(len, gfp); 447 if (!wlan_data) 448 return -ENOMEM; 449 450 wlan_data->ifindex = ifindex; 451 wlan_data->func_type = NPU_OP_GET; 452 wlan_data->func_id = func_id; 453 454 err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, len); 455 if (!err) 456 memcpy(data, wlan_data->d, data_len); 457 kfree(wlan_data); 458 459 return err; 460 } 461 462 static int 463 airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, 464 int ifindex, const char *name, 465 enum airoha_npu_wlan_set_cmd func_id) 466 { 467 struct device *dev = npu->dev; 468 struct resource res; 469 int err; 470 u32 val; 471 472 err = of_reserved_mem_region_to_resource_byname(dev->of_node, name, 473 &res); 474 if (err) 475 return err; 476 477 val = res.start; 478 return airoha_npu_wlan_msg_send(npu, ifindex, func_id, &val, 479 sizeof(val), GFP_KERNEL); 480 } 481 482 static int airoha_npu_wlan_init_memory(struct airoha_npu *npu) 483 { 484 enum airoha_npu_wlan_set_cmd cmd = WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU; 485 u32 val = 0; 486 int err; 487 488 err = airoha_npu_wlan_msg_send(npu, 1, cmd, &val, sizeof(val), 489 GFP_KERNEL); 490 if (err) 491 return err; 492 493 cmd = WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR; 494 err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-bufid", cmd); 495 if (err) 496 return err; 497 498 cmd = WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR; 499 err = airoha_npu_wlan_set_reserved_memory(npu, 0, "pkt", cmd); 500 if (err) 501 return err; 502 503 cmd = WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR; 504 err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-pkt", cmd); 505 if (err) 506 return err; 507 508 cmd = WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU; 509 return airoha_npu_wlan_msg_send(npu, 0, cmd, &val, sizeof(val), 510 GFP_KERNEL); 511 } 512 513 static u32 airoha_npu_wlan_queue_addr_get(struct airoha_npu *npu, int qid, 514 bool xmit) 515 { 516 if (xmit) 517 return REG_TX_BASE(qid + 2); 518 519 return REG_RX_BASE(qid); 520 } 521 522 static void airoha_npu_wlan_irq_status_set(struct airoha_npu *npu, u32 val) 523 { 524 regmap_write(npu->regmap, REG_IRQ_STATUS, val); 525 } 526 527 static u32 airoha_npu_wlan_irq_status_get(struct airoha_npu *npu, int q) 528 { 529 u32 val; 530 531 regmap_read(npu->regmap, REG_IRQ_STATUS, &val); 532 return val; 533 } 534 535 static void airoha_npu_wlan_irq_enable(struct airoha_npu *npu, int q) 536 { 537 regmap_set_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); 538 } 539 540 static void airoha_npu_wlan_irq_disable(struct airoha_npu *npu, int q) 541 { 542 regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); 543 } 544 545 struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) 546 { 547 struct platform_device *pdev; 548 struct device_node *np; 549 struct airoha_npu *npu; 550 551 np = of_parse_phandle(dev->of_node, "airoha,npu", 0); 552 if (!np) 553 return ERR_PTR(-ENODEV); 554 555 pdev = of_find_device_by_node(np); 556 557 if (!pdev) { 558 dev_err(dev, "cannot find device node %s\n", np->name); 559 of_node_put(np); 560 return ERR_PTR(-ENODEV); 561 } 562 of_node_put(np); 563 564 if (!try_module_get(THIS_MODULE)) { 565 dev_err(dev, "failed to get the device driver module\n"); 566 npu = ERR_PTR(-ENODEV); 567 goto error_pdev_put; 568 } 569 570 npu = platform_get_drvdata(pdev); 571 if (!npu) { 572 npu = ERR_PTR(-ENODEV); 573 goto error_module_put; 574 } 575 576 if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER)) { 577 dev_err(&pdev->dev, 578 "failed to create device link to consumer %s\n", 579 dev_name(dev)); 580 npu = ERR_PTR(-EINVAL); 581 goto error_module_put; 582 } 583 584 if (stats_addr) { 585 int err; 586 587 err = airoha_npu_stats_setup(npu, *stats_addr); 588 if (err) { 589 dev_err(dev, "failed to allocate npu stats buffer\n"); 590 npu = ERR_PTR(err); 591 goto error_module_put; 592 } 593 } 594 595 return npu; 596 597 error_module_put: 598 module_put(THIS_MODULE); 599 error_pdev_put: 600 platform_device_put(pdev); 601 602 return npu; 603 } 604 EXPORT_SYMBOL_GPL(airoha_npu_get); 605 606 void airoha_npu_put(struct airoha_npu *npu) 607 { 608 module_put(THIS_MODULE); 609 put_device(npu->dev); 610 } 611 EXPORT_SYMBOL_GPL(airoha_npu_put); 612 613 static const struct of_device_id of_airoha_npu_match[] = { 614 { .compatible = "airoha,en7581-npu" }, 615 { /* sentinel */ } 616 }; 617 MODULE_DEVICE_TABLE(of, of_airoha_npu_match); 618 619 static const struct regmap_config regmap_config = { 620 .name = "npu", 621 .reg_bits = 32, 622 .val_bits = 32, 623 .reg_stride = 4, 624 .disable_locking = true, 625 }; 626 627 static int airoha_npu_probe(struct platform_device *pdev) 628 { 629 struct device *dev = &pdev->dev; 630 struct airoha_npu *npu; 631 struct resource res; 632 void __iomem *base; 633 int i, irq, err; 634 635 base = devm_platform_ioremap_resource(pdev, 0); 636 if (IS_ERR(base)) 637 return PTR_ERR(base); 638 639 npu = devm_kzalloc(dev, sizeof(*npu), GFP_KERNEL); 640 if (!npu) 641 return -ENOMEM; 642 643 npu->dev = dev; 644 npu->ops.ppe_init = airoha_npu_ppe_init; 645 npu->ops.ppe_deinit = airoha_npu_ppe_deinit; 646 npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; 647 npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; 648 npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; 649 npu->ops.wlan_send_msg = airoha_npu_wlan_msg_send; 650 npu->ops.wlan_get_msg = airoha_npu_wlan_msg_get; 651 npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; 652 npu->ops.wlan_set_irq_status = airoha_npu_wlan_irq_status_set; 653 npu->ops.wlan_get_irq_status = airoha_npu_wlan_irq_status_get; 654 npu->ops.wlan_enable_irq = airoha_npu_wlan_irq_enable; 655 npu->ops.wlan_disable_irq = airoha_npu_wlan_irq_disable; 656 657 npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); 658 if (IS_ERR(npu->regmap)) 659 return PTR_ERR(npu->regmap); 660 661 err = of_reserved_mem_region_to_resource(dev->of_node, 0, &res); 662 if (err) 663 return err; 664 665 irq = platform_get_irq(pdev, 0); 666 if (irq < 0) 667 return irq; 668 669 err = devm_request_irq(dev, irq, airoha_npu_mbox_handler, 670 IRQF_SHARED, "airoha-npu-mbox", npu); 671 if (err) 672 return err; 673 674 for (i = 0; i < ARRAY_SIZE(npu->cores); i++) { 675 struct airoha_npu_core *core = &npu->cores[i]; 676 677 spin_lock_init(&core->lock); 678 core->npu = npu; 679 680 irq = platform_get_irq(pdev, i + 1); 681 if (irq < 0) 682 return irq; 683 684 err = devm_request_irq(dev, irq, airoha_npu_wdt_handler, 685 IRQF_SHARED, "airoha-npu-wdt", core); 686 if (err) 687 return err; 688 689 INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); 690 } 691 692 /* wlan IRQ lines */ 693 for (i = 0; i < ARRAY_SIZE(npu->irqs); i++) { 694 irq = platform_get_irq(pdev, i + ARRAY_SIZE(npu->cores) + 1); 695 if (irq < 0) 696 return irq; 697 698 npu->irqs[i] = irq; 699 } 700 701 err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); 702 if (err) 703 return err; 704 705 err = airoha_npu_run_firmware(dev, base, &res); 706 if (err) 707 return dev_err_probe(dev, err, "failed to run npu firmware\n"); 708 709 regmap_write(npu->regmap, REG_CR_NPU_MIB(10), 710 res.start + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); 711 regmap_write(npu->regmap, REG_CR_NPU_MIB(11), 0x40000); /* SRAM 256K */ 712 regmap_write(npu->regmap, REG_CR_NPU_MIB(12), 0); 713 regmap_write(npu->regmap, REG_CR_NPU_MIB(21), 1); 714 msleep(100); 715 716 /* setting booting address */ 717 for (i = 0; i < NPU_NUM_CORES; i++) 718 regmap_write(npu->regmap, REG_CR_BOOT_BASE(i), res.start); 719 usleep_range(1000, 2000); 720 721 /* enable NPU cores */ 722 regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xff); 723 regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); 724 msleep(100); 725 726 platform_set_drvdata(pdev, npu); 727 728 return 0; 729 } 730 731 static void airoha_npu_remove(struct platform_device *pdev) 732 { 733 struct airoha_npu *npu = platform_get_drvdata(pdev); 734 int i; 735 736 for (i = 0; i < ARRAY_SIZE(npu->cores); i++) 737 cancel_work_sync(&npu->cores[i].wdt_work); 738 } 739 740 static struct platform_driver airoha_npu_driver = { 741 .probe = airoha_npu_probe, 742 .remove = airoha_npu_remove, 743 .driver = { 744 .name = "airoha-npu", 745 .of_match_table = of_airoha_npu_match, 746 }, 747 }; 748 module_platform_driver(airoha_npu_driver); 749 750 MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); 751 MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); 752 MODULE_LICENSE("GPL"); 753 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 754 MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); 755