Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.12 883 lines 20 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2020-2021 NXP 4 */ 5 6#include <linux/init.h> 7#include <linux/interconnect.h> 8#include <linux/ioctl.h> 9#include <linux/list.h> 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/of.h> 13#include <linux/of_address.h> 14#include <linux/platform_device.h> 15#include <linux/slab.h> 16#include <linux/types.h> 17#include <linux/pm_runtime.h> 18#include <linux/pm_domain.h> 19#include <linux/firmware.h> 20#include <linux/vmalloc.h> 21#include "vpu.h" 22#include "vpu_defs.h" 23#include "vpu_core.h" 24#include "vpu_mbox.h" 25#include "vpu_msgs.h" 26#include "vpu_rpc.h" 27#include "vpu_cmds.h" 28 29void csr_writel(struct vpu_core *core, u32 reg, u32 val) 30{ 31 writel(val, core->base + reg); 32} 33 34u32 csr_readl(struct vpu_core *core, u32 reg) 35{ 36 return readl(core->base + reg); 37} 38 39static int vpu_core_load_firmware(struct vpu_core *core) 40{ 41 const struct firmware *pfw = NULL; 42 int ret = 0; 43 44 if (!core->fw.virt) { 45 dev_err(core->dev, "firmware buffer is not ready\n"); 46 return -EINVAL; 47 } 48 49 ret = request_firmware(&pfw, core->res->fwname, core->dev); 50 dev_dbg(core->dev, "request_firmware %s : %d\n", core->res->fwname, ret); 51 if (ret) { 52 dev_err(core->dev, "request firmware %s failed, ret = %d\n", 53 core->res->fwname, ret); 54 return ret; 55 } 56 57 if (core->fw.length < pfw->size) { 58 dev_err(core->dev, "firmware buffer size want %zu, but %d\n", 59 pfw->size, core->fw.length); 60 ret = -EINVAL; 61 goto exit; 62 } 63 64 memset(core->fw.virt, 0, core->fw.length); 65 memcpy(core->fw.virt, pfw->data, pfw->size); 66 core->fw.bytesused = pfw->size; 67 ret = vpu_iface_on_firmware_loaded(core); 68exit: 69 release_firmware(pfw); 70 pfw = NULL; 71 72 return ret; 73} 74 75static int vpu_core_boot_done(struct vpu_core *core) 76{ 77 u32 fw_version; 78 79 fw_version = vpu_iface_get_version(core); 80 dev_info(core->dev, "%s firmware version : %d.%d.%d\n", 81 vpu_core_type_desc(core->type), 82 (fw_version >> 16) & 0xff, 83 (fw_version >> 8) & 0xff, 84 fw_version & 0xff); 85 core->supported_instance_count = vpu_iface_get_max_instance_count(core); 86 if (core->res->act_size) { 87 u32 count = core->act.length / core->res->act_size; 88 89 core->supported_instance_count = min(core->supported_instance_count, count); 90 } 91 if (core->supported_instance_count >= BITS_PER_TYPE(core->instance_mask)) 92 core->supported_instance_count = BITS_PER_TYPE(core->instance_mask); 93 core->fw_version = fw_version; 94 vpu_core_set_state(core, VPU_CORE_ACTIVE); 95 96 return 0; 97} 98 99static int vpu_core_wait_boot_done(struct vpu_core *core) 100{ 101 int ret; 102 103 ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT); 104 if (!ret) { 105 dev_err(core->dev, "boot timeout\n"); 106 return -EINVAL; 107 } 108 return vpu_core_boot_done(core); 109} 110 111static int vpu_core_boot(struct vpu_core *core, bool load) 112{ 113 int ret; 114 115 reinit_completion(&core->cmp); 116 if (load) { 117 ret = vpu_core_load_firmware(core); 118 if (ret) 119 return ret; 120 } 121 122 vpu_iface_boot_core(core); 123 return vpu_core_wait_boot_done(core); 124} 125 126static int vpu_core_shutdown(struct vpu_core *core) 127{ 128 return vpu_iface_shutdown_core(core); 129} 130 131static int vpu_core_restore(struct vpu_core *core) 132{ 133 int ret; 134 135 ret = vpu_core_sw_reset(core); 136 if (ret) 137 return ret; 138 139 vpu_core_boot_done(core); 140 return vpu_iface_restore_core(core); 141} 142 143static int __vpu_alloc_dma(struct device *dev, struct vpu_buffer *buf) 144{ 145 gfp_t gfp = GFP_KERNEL | GFP_DMA32; 146 147 if (!buf->length) 148 return 0; 149 150 buf->virt = dma_alloc_coherent(dev, buf->length, &buf->phys, gfp); 151 if (!buf->virt) 152 return -ENOMEM; 153 154 buf->dev = dev; 155 156 return 0; 157} 158 159void vpu_free_dma(struct vpu_buffer *buf) 160{ 161 if (!buf->virt || !buf->dev) 162 return; 163 164 dma_free_coherent(buf->dev, buf->length, buf->virt, buf->phys); 165 buf->virt = NULL; 166 buf->phys = 0; 167 buf->length = 0; 168 buf->bytesused = 0; 169 buf->dev = NULL; 170} 171 172int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf) 173{ 174 return __vpu_alloc_dma(core->dev, buf); 175} 176 177void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state) 178{ 179 if (state != core->state) 180 vpu_trace(core->dev, "vpu core state change from %d to %d\n", core->state, state); 181 core->state = state; 182 if (core->state == VPU_CORE_DEINIT) 183 core->hang_mask = 0; 184} 185 186static void vpu_core_update_state(struct vpu_core *core) 187{ 188 if (!vpu_iface_get_power_state(core)) { 189 if (core->request_count) 190 vpu_core_set_state(core, VPU_CORE_HANG); 191 else 192 vpu_core_set_state(core, VPU_CORE_DEINIT); 193 194 } else if (core->state == VPU_CORE_ACTIVE && core->hang_mask) { 195 vpu_core_set_state(core, VPU_CORE_HANG); 196 } 197} 198 199static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type) 200{ 201 struct vpu_core *core = NULL; 202 int request_count = INT_MAX; 203 struct vpu_core *c; 204 205 list_for_each_entry(c, &vpu->cores, list) { 206 dev_dbg(c->dev, "instance_mask = 0x%lx, state = %d\n", c->instance_mask, c->state); 207 if (c->type != type) 208 continue; 209 mutex_lock(&c->lock); 210 vpu_core_update_state(c); 211 mutex_unlock(&c->lock); 212 if (c->state == VPU_CORE_DEINIT) { 213 core = c; 214 break; 215 } 216 if (c->state != VPU_CORE_ACTIVE) 217 continue; 218 if (c->request_count < request_count) { 219 request_count = c->request_count; 220 core = c; 221 } 222 if (!request_count) 223 break; 224 } 225 226 return core; 227} 228 229static bool vpu_core_is_exist(struct vpu_dev *vpu, struct vpu_core *core) 230{ 231 struct vpu_core *c; 232 233 list_for_each_entry(c, &vpu->cores, list) { 234 if (c == core) 235 return true; 236 } 237 238 return false; 239} 240 241static void vpu_core_get_vpu(struct vpu_core *core) 242{ 243 core->vpu->get_vpu(core->vpu); 244 if (core->type == VPU_CORE_TYPE_ENC) 245 core->vpu->get_enc(core->vpu); 246 if (core->type == VPU_CORE_TYPE_DEC) 247 core->vpu->get_dec(core->vpu); 248} 249 250static int vpu_core_register(struct device *dev, struct vpu_core *core) 251{ 252 struct vpu_dev *vpu = dev_get_drvdata(dev); 253 int ret = 0; 254 255 dev_dbg(core->dev, "register core %s\n", vpu_core_type_desc(core->type)); 256 if (vpu_core_is_exist(vpu, core)) 257 return 0; 258 259 core->workqueue = alloc_ordered_workqueue("vpu", WQ_MEM_RECLAIM); 260 if (!core->workqueue) { 261 dev_err(core->dev, "fail to alloc workqueue\n"); 262 return -ENOMEM; 263 } 264 INIT_WORK(&core->msg_work, vpu_msg_run_work); 265 INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work); 266 core->msg_buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE); 267 core->msg_buffer = vzalloc(core->msg_buffer_size); 268 if (!core->msg_buffer) { 269 dev_err(core->dev, "failed allocate buffer for fifo\n"); 270 ret = -ENOMEM; 271 goto error; 272 } 273 ret = kfifo_init(&core->msg_fifo, core->msg_buffer, core->msg_buffer_size); 274 if (ret) { 275 dev_err(core->dev, "failed init kfifo\n"); 276 goto error; 277 } 278 279 list_add_tail(&core->list, &vpu->cores); 280 vpu_core_get_vpu(core); 281 282 return 0; 283error: 284 if (core->msg_buffer) { 285 vfree(core->msg_buffer); 286 core->msg_buffer = NULL; 287 } 288 if (core->workqueue) { 289 destroy_workqueue(core->workqueue); 290 core->workqueue = NULL; 291 } 292 return ret; 293} 294 295static void vpu_core_put_vpu(struct vpu_core *core) 296{ 297 if (core->type == VPU_CORE_TYPE_ENC) 298 core->vpu->put_enc(core->vpu); 299 if (core->type == VPU_CORE_TYPE_DEC) 300 core->vpu->put_dec(core->vpu); 301 core->vpu->put_vpu(core->vpu); 302} 303 304static int vpu_core_unregister(struct device *dev, struct vpu_core *core) 305{ 306 list_del_init(&core->list); 307 308 vpu_core_put_vpu(core); 309 core->vpu = NULL; 310 vfree(core->msg_buffer); 311 core->msg_buffer = NULL; 312 313 if (core->workqueue) { 314 cancel_work_sync(&core->msg_work); 315 cancel_delayed_work_sync(&core->msg_delayed_work); 316 destroy_workqueue(core->workqueue); 317 core->workqueue = NULL; 318 } 319 320 return 0; 321} 322 323static int vpu_core_acquire_instance(struct vpu_core *core) 324{ 325 int id; 326 327 id = ffz(core->instance_mask); 328 if (id >= core->supported_instance_count) 329 return -EINVAL; 330 331 set_bit(id, &core->instance_mask); 332 333 return id; 334} 335 336static void vpu_core_release_instance(struct vpu_core *core, int id) 337{ 338 if (id < 0 || id >= core->supported_instance_count) 339 return; 340 341 clear_bit(id, &core->instance_mask); 342} 343 344struct vpu_inst *vpu_inst_get(struct vpu_inst *inst) 345{ 346 if (!inst) 347 return NULL; 348 349 atomic_inc(&inst->ref_count); 350 351 return inst; 352} 353 354void vpu_inst_put(struct vpu_inst *inst) 355{ 356 if (!inst) 357 return; 358 if (atomic_dec_and_test(&inst->ref_count)) { 359 if (inst->release) 360 inst->release(inst); 361 } 362} 363 364struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type) 365{ 366 struct vpu_core *core = NULL; 367 int ret; 368 369 mutex_lock(&vpu->lock); 370 371 core = vpu_core_find_proper_by_type(vpu, type); 372 if (!core) 373 goto exit; 374 375 mutex_lock(&core->lock); 376 pm_runtime_resume_and_get(core->dev); 377 378 if (core->state == VPU_CORE_DEINIT) { 379 if (vpu_iface_get_power_state(core)) 380 ret = vpu_core_restore(core); 381 else 382 ret = vpu_core_boot(core, true); 383 if (ret) { 384 pm_runtime_put_sync(core->dev); 385 mutex_unlock(&core->lock); 386 core = NULL; 387 goto exit; 388 } 389 } 390 391 core->request_count++; 392 393 mutex_unlock(&core->lock); 394exit: 395 mutex_unlock(&vpu->lock); 396 397 return core; 398} 399 400void vpu_release_core(struct vpu_core *core) 401{ 402 if (!core) 403 return; 404 405 mutex_lock(&core->lock); 406 pm_runtime_put_sync(core->dev); 407 if (core->request_count) 408 core->request_count--; 409 mutex_unlock(&core->lock); 410} 411 412int vpu_inst_register(struct vpu_inst *inst) 413{ 414 struct vpu_dev *vpu; 415 struct vpu_core *core; 416 int ret = 0; 417 418 vpu = inst->vpu; 419 core = inst->core; 420 if (!core) { 421 core = vpu_request_core(vpu, inst->type); 422 if (!core) { 423 dev_err(vpu->dev, "there is no vpu core for %s\n", 424 vpu_core_type_desc(inst->type)); 425 return -EINVAL; 426 } 427 inst->core = core; 428 inst->dev = get_device(core->dev); 429 } 430 431 mutex_lock(&core->lock); 432 if (core->state != VPU_CORE_ACTIVE) { 433 dev_err(core->dev, "vpu core is not active, state = %d\n", core->state); 434 ret = -EINVAL; 435 goto exit; 436 } 437 438 if (inst->id >= 0 && inst->id < core->supported_instance_count) 439 goto exit; 440 441 ret = vpu_core_acquire_instance(core); 442 if (ret < 0) 443 goto exit; 444 445 vpu_trace(inst->dev, "[%d] %p\n", ret, inst); 446 inst->id = ret; 447 list_add_tail(&inst->list, &core->instances); 448 ret = 0; 449 if (core->res->act_size) { 450 inst->act.phys = core->act.phys + core->res->act_size * inst->id; 451 inst->act.virt = core->act.virt + core->res->act_size * inst->id; 452 inst->act.length = core->res->act_size; 453 } 454 vpu_inst_create_dbgfs_file(inst); 455exit: 456 mutex_unlock(&core->lock); 457 458 if (ret) 459 dev_err(core->dev, "register instance fail\n"); 460 return ret; 461} 462 463int vpu_inst_unregister(struct vpu_inst *inst) 464{ 465 struct vpu_core *core; 466 467 if (!inst->core) 468 return 0; 469 470 core = inst->core; 471 vpu_clear_request(inst); 472 mutex_lock(&core->lock); 473 if (inst->id >= 0 && inst->id < core->supported_instance_count) { 474 vpu_inst_remove_dbgfs_file(inst); 475 list_del_init(&inst->list); 476 vpu_core_release_instance(core, inst->id); 477 inst->id = VPU_INST_NULL_ID; 478 } 479 vpu_core_update_state(core); 480 if (core->state == VPU_CORE_HANG && !core->instance_mask) { 481 int err; 482 483 dev_info(core->dev, "reset hang core\n"); 484 mutex_unlock(&core->lock); 485 err = vpu_core_sw_reset(core); 486 mutex_lock(&core->lock); 487 if (!err) { 488 vpu_core_set_state(core, VPU_CORE_ACTIVE); 489 core->hang_mask = 0; 490 } 491 } 492 mutex_unlock(&core->lock); 493 494 return 0; 495} 496 497struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index) 498{ 499 struct vpu_inst *inst = NULL; 500 struct vpu_inst *tmp; 501 502 mutex_lock(&core->lock); 503 if (index >= core->supported_instance_count || !test_bit(index, &core->instance_mask)) 504 goto exit; 505 list_for_each_entry(tmp, &core->instances, list) { 506 if (tmp->id == index) { 507 inst = vpu_inst_get(tmp); 508 break; 509 } 510 } 511exit: 512 mutex_unlock(&core->lock); 513 514 return inst; 515} 516 517const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst) 518{ 519 struct vpu_dev *vpu; 520 struct vpu_core *core = NULL; 521 const struct vpu_core_resources *res = NULL; 522 523 if (!inst || !inst->vpu) 524 return NULL; 525 526 if (inst->core && inst->core->res) 527 return inst->core->res; 528 529 vpu = inst->vpu; 530 mutex_lock(&vpu->lock); 531 list_for_each_entry(core, &vpu->cores, list) { 532 if (core->type == inst->type) { 533 res = core->res; 534 break; 535 } 536 } 537 mutex_unlock(&vpu->lock); 538 539 return res; 540} 541 542static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np) 543{ 544 struct device_node *node; 545 struct resource res; 546 int ret; 547 548 if (of_count_phandle_with_args(np, "memory-region", NULL) < 2) { 549 dev_err(core->dev, "need 2 memory-region for boot and rpc\n"); 550 return -ENODEV; 551 } 552 553 node = of_parse_phandle(np, "memory-region", 0); 554 if (!node) { 555 dev_err(core->dev, "boot-region of_parse_phandle error\n"); 556 return -ENODEV; 557 } 558 if (of_address_to_resource(node, 0, &res)) { 559 dev_err(core->dev, "boot-region of_address_to_resource error\n"); 560 of_node_put(node); 561 return -EINVAL; 562 } 563 core->fw.phys = res.start; 564 core->fw.length = resource_size(&res); 565 566 of_node_put(node); 567 568 node = of_parse_phandle(np, "memory-region", 1); 569 if (!node) { 570 dev_err(core->dev, "rpc-region of_parse_phandle error\n"); 571 return -ENODEV; 572 } 573 if (of_address_to_resource(node, 0, &res)) { 574 dev_err(core->dev, "rpc-region of_address_to_resource error\n"); 575 of_node_put(node); 576 return -EINVAL; 577 } 578 core->rpc.phys = res.start; 579 core->rpc.length = resource_size(&res); 580 581 if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) { 582 dev_err(core->dev, "the rpc-region <%pad, 0x%x> is not enough\n", 583 &core->rpc.phys, core->rpc.length); 584 of_node_put(node); 585 return -EINVAL; 586 } 587 588 core->fw.virt = memremap(core->fw.phys, core->fw.length, MEMREMAP_WC); 589 core->rpc.virt = memremap(core->rpc.phys, core->rpc.length, MEMREMAP_WC); 590 memset(core->rpc.virt, 0, core->rpc.length); 591 592 ret = vpu_iface_check_memory_region(core, core->rpc.phys, core->rpc.length); 593 if (ret != VPU_CORE_MEMORY_UNCACHED) { 594 dev_err(core->dev, "rpc region<%pad, 0x%x> isn't uncached\n", 595 &core->rpc.phys, core->rpc.length); 596 of_node_put(node); 597 return -EINVAL; 598 } 599 600 core->log.phys = core->rpc.phys + core->res->rpc_size; 601 core->log.virt = core->rpc.virt + core->res->rpc_size; 602 core->log.length = core->res->fwlog_size; 603 core->act.phys = core->log.phys + core->log.length; 604 core->act.virt = core->log.virt + core->log.length; 605 core->act.length = core->rpc.length - core->res->rpc_size - core->log.length; 606 core->rpc.length = core->res->rpc_size; 607 608 of_node_put(node); 609 610 return 0; 611} 612 613static int vpu_core_probe(struct platform_device *pdev) 614{ 615 struct device *dev = &pdev->dev; 616 struct vpu_core *core; 617 struct vpu_dev *vpu = dev_get_drvdata(dev->parent); 618 struct vpu_shared_addr *iface; 619 u32 iface_data_size; 620 int ret; 621 622 dev_dbg(dev, "probe\n"); 623 if (!vpu) 624 return -EINVAL; 625 core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL); 626 if (!core) 627 return -ENOMEM; 628 629 core->pdev = pdev; 630 core->dev = dev; 631 platform_set_drvdata(pdev, core); 632 core->vpu = vpu; 633 INIT_LIST_HEAD(&core->instances); 634 mutex_init(&core->lock); 635 mutex_init(&core->cmd_lock); 636 init_completion(&core->cmp); 637 init_waitqueue_head(&core->ack_wq); 638 vpu_core_set_state(core, VPU_CORE_DEINIT); 639 640 core->res = of_device_get_match_data(dev); 641 if (!core->res) 642 return -ENODEV; 643 644 core->type = core->res->type; 645 core->id = of_alias_get_id(dev->of_node, "vpu-core"); 646 if (core->id < 0) { 647 dev_err(dev, "can't get vpu core id\n"); 648 return core->id; 649 } 650 dev_info(core->dev, "[%d] = %s\n", core->id, vpu_core_type_desc(core->type)); 651 ret = vpu_core_parse_dt(core, dev->of_node); 652 if (ret) 653 return ret; 654 655 core->base = devm_platform_ioremap_resource(pdev, 0); 656 if (IS_ERR(core->base)) 657 return PTR_ERR(core->base); 658 659 if (!vpu_iface_check_codec(core)) { 660 dev_err(core->dev, "is not supported\n"); 661 return -EINVAL; 662 } 663 664 ret = vpu_mbox_init(core); 665 if (ret) 666 return ret; 667 668 iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL); 669 if (!iface) 670 return -ENOMEM; 671 672 iface_data_size = vpu_iface_get_data_size(core); 673 if (iface_data_size) { 674 iface->priv = devm_kzalloc(dev, iface_data_size, GFP_KERNEL); 675 if (!iface->priv) 676 return -ENOMEM; 677 } 678 679 ret = vpu_iface_init(core, iface, &core->rpc, core->fw.phys); 680 if (ret) { 681 dev_err(core->dev, "init iface fail, ret = %d\n", ret); 682 return ret; 683 } 684 685 vpu_iface_config_system(core, vpu->res->mreg_base, vpu->base); 686 vpu_iface_set_log_buf(core, &core->log); 687 688 pm_runtime_enable(dev); 689 ret = pm_runtime_resume_and_get(dev); 690 if (ret) { 691 pm_runtime_put_noidle(dev); 692 pm_runtime_set_suspended(dev); 693 goto err_runtime_disable; 694 } 695 696 ret = vpu_core_register(dev->parent, core); 697 if (ret) 698 goto err_core_register; 699 core->parent = dev->parent; 700 701 pm_runtime_put_sync(dev); 702 vpu_core_create_dbgfs_file(core); 703 704 return 0; 705 706err_core_register: 707 pm_runtime_put_sync(dev); 708err_runtime_disable: 709 pm_runtime_disable(dev); 710 711 return ret; 712} 713 714static void vpu_core_remove(struct platform_device *pdev) 715{ 716 struct device *dev = &pdev->dev; 717 struct vpu_core *core = platform_get_drvdata(pdev); 718 int ret; 719 720 vpu_core_remove_dbgfs_file(core); 721 ret = pm_runtime_resume_and_get(dev); 722 WARN_ON(ret < 0); 723 724 vpu_core_shutdown(core); 725 pm_runtime_put_sync(dev); 726 pm_runtime_disable(dev); 727 728 vpu_core_unregister(core->parent, core); 729 memunmap(core->fw.virt); 730 memunmap(core->rpc.virt); 731 mutex_destroy(&core->lock); 732 mutex_destroy(&core->cmd_lock); 733} 734 735static int __maybe_unused vpu_core_runtime_resume(struct device *dev) 736{ 737 struct vpu_core *core = dev_get_drvdata(dev); 738 739 return vpu_mbox_request(core); 740} 741 742static int __maybe_unused vpu_core_runtime_suspend(struct device *dev) 743{ 744 struct vpu_core *core = dev_get_drvdata(dev); 745 746 vpu_mbox_free(core); 747 return 0; 748} 749 750static void vpu_core_cancel_work(struct vpu_core *core) 751{ 752 struct vpu_inst *inst = NULL; 753 754 cancel_work_sync(&core->msg_work); 755 cancel_delayed_work_sync(&core->msg_delayed_work); 756 757 mutex_lock(&core->lock); 758 list_for_each_entry(inst, &core->instances, list) 759 cancel_work_sync(&inst->msg_work); 760 mutex_unlock(&core->lock); 761} 762 763static void vpu_core_resume_work(struct vpu_core *core) 764{ 765 struct vpu_inst *inst = NULL; 766 unsigned long delay = msecs_to_jiffies(10); 767 768 queue_work(core->workqueue, &core->msg_work); 769 queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay); 770 771 mutex_lock(&core->lock); 772 list_for_each_entry(inst, &core->instances, list) 773 queue_work(inst->workqueue, &inst->msg_work); 774 mutex_unlock(&core->lock); 775} 776 777static int __maybe_unused vpu_core_resume(struct device *dev) 778{ 779 struct vpu_core *core = dev_get_drvdata(dev); 780 int ret = 0; 781 782 mutex_lock(&core->lock); 783 pm_runtime_resume_and_get(dev); 784 vpu_core_get_vpu(core); 785 786 if (core->request_count) { 787 if (!vpu_iface_get_power_state(core)) 788 ret = vpu_core_boot(core, false); 789 else 790 ret = vpu_core_sw_reset(core); 791 if (ret) { 792 dev_err(core->dev, "resume fail\n"); 793 vpu_core_set_state(core, VPU_CORE_HANG); 794 } 795 } 796 vpu_core_update_state(core); 797 pm_runtime_put_sync(dev); 798 mutex_unlock(&core->lock); 799 800 vpu_core_resume_work(core); 801 return ret; 802} 803 804static int __maybe_unused vpu_core_suspend(struct device *dev) 805{ 806 struct vpu_core *core = dev_get_drvdata(dev); 807 int ret = 0; 808 809 mutex_lock(&core->lock); 810 if (core->request_count) 811 ret = vpu_core_snapshot(core); 812 mutex_unlock(&core->lock); 813 if (ret) 814 return ret; 815 816 vpu_core_cancel_work(core); 817 818 mutex_lock(&core->lock); 819 vpu_core_put_vpu(core); 820 mutex_unlock(&core->lock); 821 return ret; 822} 823 824static const struct dev_pm_ops vpu_core_pm_ops = { 825 SET_RUNTIME_PM_OPS(vpu_core_runtime_suspend, vpu_core_runtime_resume, NULL) 826 SET_SYSTEM_SLEEP_PM_OPS(vpu_core_suspend, vpu_core_resume) 827}; 828 829static struct vpu_core_resources imx8q_enc = { 830 .type = VPU_CORE_TYPE_ENC, 831 .fwname = "amphion/vpu/vpu_fw_imx8_enc.bin", 832 .stride = 16, 833 .max_width = 1920, 834 .max_height = 1920, 835 .min_width = 64, 836 .min_height = 48, 837 .step_width = 2, 838 .step_height = 2, 839 .rpc_size = 0x80000, 840 .fwlog_size = 0x80000, 841 .act_size = 0xc0000, 842}; 843 844static struct vpu_core_resources imx8q_dec = { 845 .type = VPU_CORE_TYPE_DEC, 846 .fwname = "amphion/vpu/vpu_fw_imx8_dec.bin", 847 .stride = 256, 848 .max_width = 8188, 849 .max_height = 8188, 850 .min_width = 16, 851 .min_height = 16, 852 .step_width = 1, 853 .step_height = 1, 854 .rpc_size = 0x80000, 855 .fwlog_size = 0x80000, 856}; 857 858static const struct of_device_id vpu_core_dt_match[] = { 859 { .compatible = "nxp,imx8q-vpu-encoder", .data = &imx8q_enc }, 860 { .compatible = "nxp,imx8q-vpu-decoder", .data = &imx8q_dec }, 861 {} 862}; 863MODULE_DEVICE_TABLE(of, vpu_core_dt_match); 864 865static struct platform_driver amphion_vpu_core_driver = { 866 .probe = vpu_core_probe, 867 .remove_new = vpu_core_remove, 868 .driver = { 869 .name = "amphion-vpu-core", 870 .of_match_table = vpu_core_dt_match, 871 .pm = &vpu_core_pm_ops, 872 }, 873}; 874 875int __init vpu_core_driver_init(void) 876{ 877 return platform_driver_register(&amphion_vpu_core_driver); 878} 879 880void __exit vpu_core_driver_exit(void) 881{ 882 platform_driver_unregister(&amphion_vpu_core_driver); 883}