FILE
vpu_core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/amphion/vpu_core.c
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_reserved_mem.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 unsigned int buffer_size; 254 int ret = 0; 255 256 dev_dbg(core->dev, "register core %s\n", vpu_core_type_desc(core->type)); 257 if (vpu_core_is_exist(vpu, core)) 258 return 0; 259 260 core->workqueue = alloc_ordered_workqueue("vpu", WQ_MEM_RECLAIM); 261 if (!core->workqueue) { 262 dev_err(core->dev, "fail to alloc workqueue\n"); 263 return -ENOMEM; 264 } 265 INIT_WORK(&core->msg_work, vpu_msg_run_work); 266 INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work); 267 buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE); 268 core->msg_buffer = vzalloc(buffer_size); 269 if (!core->msg_buffer) { 270 dev_err(core->dev, "failed allocate buffer for fifo\n"); 271 ret = -ENOMEM; 272 goto error; 273 } 274 ret = kfifo_init(&core->msg_fifo, core->msg_buffer, buffer_size); 275 if (ret) { 276 dev_err(core->dev, "failed init kfifo\n"); 277 goto error; 278 } 279 280 list_add_tail(&core->list, &vpu->cores); 281 vpu_core_get_vpu(core); 282 283 return 0; 284error: 285 if (core->msg_buffer) { 286 vfree(core->msg_buffer); 287 core->msg_buffer = NULL; 288 } 289 if (core->workqueue) { 290 destroy_workqueue(core->workqueue); 291 core->workqueue = NULL; 292 } 293 return ret; 294} 295 296static void vpu_core_put_vpu(struct vpu_core *core) 297{ 298 if (core->type == VPU_CORE_TYPE_ENC) 299 core->vpu->put_enc(core->vpu); 300 if (core->type == VPU_CORE_TYPE_DEC) 301 core->vpu->put_dec(core->vpu); 302 core->vpu->put_vpu(core->vpu); 303} 304 305static int vpu_core_unregister(struct device *dev, struct vpu_core *core) 306{ 307 list_del_init(&core->list); 308 309 vpu_core_put_vpu(core); 310 core->vpu = NULL; 311 vfree(core->msg_buffer); 312 core->msg_buffer = NULL; 313 314 if (core->workqueue) { 315 cancel_work_sync(&core->msg_work); 316 cancel_delayed_work_sync(&core->msg_delayed_work); 317 destroy_workqueue(core->workqueue); 318 core->workqueue = NULL; 319 } 320 321 return 0; 322} 323 324static int vpu_core_acquire_instance(struct vpu_core *core) 325{ 326 int id; 327 328 id = ffz(core->instance_mask); 329 if (id >= core->supported_instance_count) 330 return -EINVAL; 331 332 set_bit(id, &core->instance_mask); 333 334 return id; 335} 336 337static void vpu_core_release_instance(struct vpu_core *core, int id) 338{ 339 if (id < 0 || id >= core->supported_instance_count) 340 return; 341 342 clear_bit(id, &core->instance_mask); 343} 344 345struct vpu_inst *vpu_inst_get(struct vpu_inst *inst) 346{ 347 if (!inst) 348 return NULL; 349 350 atomic_inc(&inst->ref_count); 351 352 return inst; 353} 354 355void vpu_inst_put(struct vpu_inst *inst) 356{ 357 if (!inst) 358 return; 359 if (atomic_dec_and_test(&inst->ref_count)) { 360 if (inst->release) 361 inst->release(inst); 362 } 363} 364 365struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type) 366{ 367 struct vpu_core *core = NULL; 368 int ret; 369 370 mutex_lock(&vpu->lock); 371 372 core = vpu_core_find_proper_by_type(vpu, type); 373 if (!core) 374 goto exit; 375 376 mutex_lock(&core->lock); 377 pm_runtime_resume_and_get(core->dev); 378 379 if (core->state == VPU_CORE_DEINIT) { 380 if (vpu_iface_get_power_state(core)) 381 ret = vpu_core_restore(core); 382 else 383 ret = vpu_core_boot(core, true); 384 if (ret) { 385 pm_runtime_put_sync(core->dev); 386 mutex_unlock(&core->lock); 387 core = NULL; 388 goto exit; 389 } 390 } 391 392 core->request_count++; 393 394 mutex_unlock(&core->lock); 395exit: 396 mutex_unlock(&vpu->lock); 397 398 return core; 399} 400 401void vpu_release_core(struct vpu_core *core) 402{ 403 if (!core) 404 return; 405 406 mutex_lock(&core->lock); 407 pm_runtime_put_sync(core->dev); 408 if (core->request_count) 409 core->request_count--; 410 mutex_unlock(&core->lock); 411} 412 413int vpu_inst_register(struct vpu_inst *inst) 414{ 415 struct vpu_dev *vpu; 416 struct vpu_core *core; 417 int ret = 0; 418 419 vpu = inst->vpu; 420 core = inst->core; 421 if (!core) { 422 core = vpu_request_core(vpu, inst->type); 423 if (!core) { 424 dev_err(vpu->dev, "there is no vpu core for %s\n", 425 vpu_core_type_desc(inst->type)); 426 return -EINVAL; 427 } 428 inst->core = core; 429 inst->dev = get_device(core->dev); 430 } 431 432 mutex_lock(&core->lock); 433 if (core->state != VPU_CORE_ACTIVE) { 434 dev_err(core->dev, "vpu core is not active, state = %d\n", core->state); 435 ret = -EINVAL; 436 goto exit; 437 } 438 439 if (inst->id >= 0 && inst->id < core->supported_instance_count) 440 goto exit; 441 442 ret = vpu_core_acquire_instance(core); 443 if (ret < 0) 444 goto exit; 445 446 vpu_trace(inst->dev, "[%d] %p\n", ret, inst); 447 inst->id = ret; 448 list_add_tail(&inst->list, &core->instances); 449 ret = 0; 450 if (core->res->act_size) { 451 inst->act.phys = core->act.phys + core->res->act_size * inst->id; 452 inst->act.virt = core->act.virt + core->res->act_size * inst->id; 453 inst->act.length = core->res->act_size; 454 } 455 vpu_inst_create_dbgfs_file(inst); 456exit: 457 mutex_unlock(&core->lock); 458 459 if (ret) 460 dev_err(core->dev, "register instance fail\n"); 461 return ret; 462} 463 464int vpu_inst_unregister(struct vpu_inst *inst) 465{ 466 struct vpu_core *core; 467 468 if (!inst->core) 469 return 0; 470 471 core = inst->core; 472 vpu_clear_request(inst); 473 mutex_lock(&core->lock); 474 if (inst->id >= 0 && inst->id < core->supported_instance_count) { 475 vpu_inst_remove_dbgfs_file(inst); 476 list_del_init(&inst->list); 477 vpu_core_release_instance(core, inst->id); 478 inst->id = VPU_INST_NULL_ID; 479 } 480 vpu_core_update_state(core); 481 if (core->state == VPU_CORE_HANG && !core->instance_mask) { 482 int err; 483 484 dev_info(core->dev, "reset hang core\n"); 485 mutex_unlock(&core->lock); 486 err = vpu_core_sw_reset(core); 487 mutex_lock(&core->lock); 488 if (!err) { 489 vpu_core_set_state(core, VPU_CORE_ACTIVE); 490 core->hang_mask = 0; 491 } 492 } 493 mutex_unlock(&core->lock); 494 495 return 0; 496} 497 498struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index) 499{ 500 struct vpu_inst *inst = NULL; 501 struct vpu_inst *tmp; 502 503 mutex_lock(&core->lock); 504 if (index >= core->supported_instance_count || !test_bit(index, &core->instance_mask)) 505 goto exit; 506 list_for_each_entry(tmp, &core->instances, list) { 507 if (tmp->id == index) { 508 inst = vpu_inst_get(tmp); 509 break; 510 } 511 } 512exit: 513 mutex_unlock(&core->lock); 514 515 return inst; 516} 517 518const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst) 519{ 520 struct vpu_dev *vpu; 521 struct vpu_core *core = NULL; 522 const struct vpu_core_resources *res = NULL; 523 524 if (!inst || !inst->vpu) 525 return NULL; 526 527 if (inst->core && inst->core->res) 528 return inst->core->res; 529 530 vpu = inst->vpu; 531 mutex_lock(&vpu->lock); 532 list_for_each_entry(core, &vpu->cores, list) { 533 if (core->type == inst->type) { 534 res = core->res; 535 break; 536 } 537 } 538 mutex_unlock(&vpu->lock); 539 540 return res; 541} 542 543static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np) 544{ 545 struct resource res; 546 int ret; 547 548 ret = of_reserved_mem_region_to_resource(np, 0, &res); 549 if (ret) { 550 dev_err(core->dev, "Cannot get boot-region\n"); 551 return ret; 552 } 553 554 core->fw.phys = res.start; 555 core->fw.length = resource_size(&res); 556 557 ret = of_reserved_mem_region_to_resource(np, 1, &res); 558 if (ret) { 559 dev_err(core->dev, "Cannot get rpc-region\n"); 560 return ret; 561 } 562 563 core->rpc.phys = res.start; 564 core->rpc.length = resource_size(&res); 565 566 if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) { 567 dev_err(core->dev, "the rpc-region <%pad, 0x%x> is not enough\n", 568 &core->rpc.phys, core->rpc.length); 569 return -EINVAL; 570 } 571 572 core->fw.virt = memremap(core->fw.phys, core->fw.length, MEMREMAP_WC); 573 core->rpc.virt = memremap(core->rpc.phys, core->rpc.length, MEMREMAP_WC); 574 memset(core->rpc.virt, 0, core->rpc.length); 575 576 ret = vpu_iface_check_memory_region(core, core->rpc.phys, core->rpc.length); 577 if (ret != VPU_CORE_MEMORY_UNCACHED) { 578 dev_err(core->dev, "rpc region<%pad, 0x%x> isn't uncached\n", 579 &core->rpc.phys, core->rpc.length); 580 return -EINVAL; 581 } 582 583 core->log.phys = core->rpc.phys + core->res->rpc_size; 584 core->log.virt = core->rpc.virt + core->res->rpc_size; 585 core->log.length = core->res->fwlog_size; 586 core->act.phys = core->log.phys + core->log.length; 587 core->act.virt = core->log.virt + core->log.length; 588 core->act.length = core->rpc.length - core->res->rpc_size - core->log.length; 589 core->rpc.length = core->res->rpc_size; 590 591 return 0; 592} 593 594static int vpu_core_probe(struct platform_device *pdev) 595{ 596 struct device *dev = &pdev->dev; 597 struct vpu_core *core; 598 struct vpu_dev *vpu = dev_get_drvdata(dev->parent); 599 struct vpu_shared_addr *iface; 600 u32 iface_data_size; 601 int ret; 602 603 dev_dbg(dev, "probe\n"); 604 if (!vpu) 605 return -EINVAL; 606 core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL); 607 if (!core) 608 return -ENOMEM; 609 610 core->pdev = pdev; 611 core->dev = dev; 612 platform_set_drvdata(pdev, core); 613 core->vpu = vpu; 614 INIT_LIST_HEAD(&core->instances); 615 mutex_init(&core->lock); 616 mutex_init(&core->cmd_lock); 617 init_completion(&core->cmp); 618 init_waitqueue_head(&core->ack_wq); 619 vpu_core_set_state(core, VPU_CORE_DEINIT); 620 621 core->res = of_device_get_match_data(dev); 622 if (!core->res) 623 return -ENODEV; 624 625 core->type = core->res->type; 626 core->id = of_alias_get_id(dev->of_node, "vpu-core"); 627 if (core->id < 0) { 628 dev_err(dev, "can't get vpu core id\n"); 629 return core->id; 630 } 631 dev_info(core->dev, "[%d] = %s\n", core->id, vpu_core_type_desc(core->type)); 632 ret = vpu_core_parse_dt(core, dev->of_node); 633 if (ret) 634 return ret; 635 636 core->base = devm_platform_ioremap_resource(pdev, 0); 637 if (IS_ERR(core->base)) 638 return PTR_ERR(core->base); 639 640 if (!vpu_iface_check_codec(core)) { 641 dev_err(core->dev, "is not supported\n"); 642 return -EINVAL; 643 } 644 645 ret = vpu_mbox_init(core); 646 if (ret) 647 return ret; 648 649 iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL); 650 if (!iface) 651 return -ENOMEM; 652 653 iface_data_size = vpu_iface_get_data_size(core); 654 if (iface_data_size) { 655 iface->priv = devm_kzalloc(dev, iface_data_size, GFP_KERNEL); 656 if (!iface->priv) 657 return -ENOMEM; 658 } 659 660 ret = vpu_iface_init(core, iface, &core->rpc, core->fw.phys); 661 if (ret) { 662 dev_err(core->dev, "init iface fail, ret = %d\n", ret); 663 return ret; 664 } 665 666 vpu_iface_config_system(core, vpu->res->mreg_base, vpu->base); 667 vpu_iface_set_log_buf(core, &core->log); 668 669 pm_runtime_enable(dev); 670 ret = pm_runtime_resume_and_get(dev); 671 if (ret) { 672 pm_runtime_put_noidle(dev); 673 pm_runtime_set_suspended(dev); 674 goto err_runtime_disable; 675 } 676 677 ret = vpu_core_register(dev->parent, core); 678 if (ret) 679 goto err_core_register; 680 core->parent = dev->parent; 681 682 pm_runtime_put_sync(dev); 683 vpu_core_create_dbgfs_file(core); 684 685 return 0; 686 687err_core_register: 688 pm_runtime_put_sync(dev); 689err_runtime_disable: 690 pm_runtime_disable(dev); 691 692 return ret; 693} 694 695static void vpu_core_remove(struct platform_device *pdev) 696{ 697 struct device *dev = &pdev->dev; 698 struct vpu_core *core = platform_get_drvdata(pdev); 699 int ret; 700 701 vpu_core_remove_dbgfs_file(core); 702 ret = pm_runtime_resume_and_get(dev); 703 WARN_ON(ret < 0); 704 705 vpu_core_shutdown(core); 706 pm_runtime_put_sync(dev); 707 pm_runtime_disable(dev); 708 709 vpu_core_unregister(core->parent, core); 710 memunmap(core->fw.virt); 711 memunmap(core->rpc.virt); 712 mutex_destroy(&core->lock); 713 mutex_destroy(&core->cmd_lock); 714} 715 716static int __maybe_unused vpu_core_runtime_resume(struct device *dev) 717{ 718 struct vpu_core *core = dev_get_drvdata(dev); 719 720 return vpu_mbox_request(core); 721} 722 723static int __maybe_unused vpu_core_runtime_suspend(struct device *dev) 724{ 725 struct vpu_core *core = dev_get_drvdata(dev); 726 727 vpu_mbox_free(core); 728 return 0; 729} 730 731static void vpu_core_cancel_work(struct vpu_core *core) 732{ 733 struct vpu_inst *inst = NULL; 734 735 cancel_work_sync(&core->msg_work); 736 cancel_delayed_work_sync(&core->msg_delayed_work); 737 738 mutex_lock(&core->lock); 739 list_for_each_entry(inst, &core->instances, list) 740 cancel_work_sync(&inst->msg_work); 741 mutex_unlock(&core->lock); 742} 743 744static void vpu_core_resume_work(struct vpu_core *core) 745{ 746 struct vpu_inst *inst = NULL; 747 unsigned long delay = msecs_to_jiffies(10); 748 749 queue_work(core->workqueue, &core->msg_work); 750 queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay); 751 752 mutex_lock(&core->lock); 753 list_for_each_entry(inst, &core->instances, list) 754 queue_work(inst->workqueue, &inst->msg_work); 755 mutex_unlock(&core->lock); 756} 757 758static int __maybe_unused vpu_core_resume(struct device *dev) 759{ 760 struct vpu_core *core = dev_get_drvdata(dev); 761 int ret = 0; 762 763 mutex_lock(&core->lock); 764 pm_runtime_resume_and_get(dev); 765 vpu_core_get_vpu(core); 766 767 if (core->request_count) { 768 if (!vpu_iface_get_power_state(core)) 769 ret = vpu_core_boot(core, false); 770 else 771 ret = vpu_core_sw_reset(core); 772 if (ret) { 773 dev_err(core->dev, "resume fail\n"); 774 vpu_core_set_state(core, VPU_CORE_HANG); 775 } 776 } 777 vpu_core_update_state(core); 778 pm_runtime_put_sync(dev); 779 mutex_unlock(&core->lock); 780 781 vpu_core_resume_work(core); 782 return ret; 783} 784 785static int __maybe_unused vpu_core_suspend(struct device *dev) 786{ 787 struct vpu_core *core = dev_get_drvdata(dev); 788 int ret = 0; 789 790 mutex_lock(&core->lock); 791 if (core->request_count) 792 ret = vpu_core_snapshot(core); 793 mutex_unlock(&core->lock); 794 if (ret) 795 return ret; 796 797 vpu_core_cancel_work(core); 798 799 mutex_lock(&core->lock); 800 vpu_core_put_vpu(core); 801 mutex_unlock(&core->lock); 802 return ret; 803} 804 805static const struct dev_pm_ops vpu_core_pm_ops = { 806 SET_RUNTIME_PM_OPS(vpu_core_runtime_suspend, vpu_core_runtime_resume, NULL) 807 SET_SYSTEM_SLEEP_PM_OPS(vpu_core_suspend, vpu_core_resume) 808}; 809 810static struct vpu_core_resources imx8q_enc = { 811 .type = VPU_CORE_TYPE_ENC, 812 .fwname = "amphion/vpu/vpu_fw_imx8_enc.bin", 813 .stride = 16, 814 .max_width = 1920, 815 .max_height = 1920, 816 .min_width = 64, 817 .min_height = 48, 818 .step_width = 2, 819 .step_height = 2, 820 .rpc_size = 0x80000, 821 .fwlog_size = 0x80000, 822 .act_size = 0xc0000, 823}; 824 825static struct vpu_core_resources imx8q_dec = { 826 .type = VPU_CORE_TYPE_DEC, 827 .fwname = "amphion/vpu/vpu_fw_imx8_dec.bin", 828 .stride = 256, 829 .max_width = 8188, 830 .max_height = 8188, 831 .min_width = 16, 832 .min_height = 16, 833 .step_width = 1, 834 .step_height = 1, 835 .rpc_size = 0x80000, 836 .fwlog_size = 0x80000, 837}; 838 839static const struct of_device_id vpu_core_dt_match[] = { 840 { .compatible = "nxp,imx8q-vpu-encoder", .data = &imx8q_enc }, 841 { .compatible = "nxp,imx8q-vpu-decoder", .data = &imx8q_dec }, 842 {} 843}; 844MODULE_DEVICE_TABLE(of, vpu_core_dt_match); 845 846static struct platform_driver amphion_vpu_core_driver = { 847 .probe = vpu_core_probe, 848 .remove = vpu_core_remove, 849 .driver = { 850 .name = "amphion-vpu-core", 851 .of_match_table = vpu_core_dt_match, 852 .pm = &vpu_core_pm_ops, 853 }, 854}; 855 856int __init vpu_core_driver_init(void) 857{ 858 return platform_driver_register(&hion_vpu_core_driver); 859} 860 861void __exit vpu_core_driver_exit(void) 862{ 863 platform_driver_unregister(&hion_vpu_core_driver); 864}
~/
Read-only file preview.