| .. | .. |
|---|
| 69 | 69 | #define VDPU2_DEC_CLOCK_GATE_EN BIT(4) |
|---|
| 70 | 70 | #define VDPU2_DEC_START BIT(0) |
|---|
| 71 | 71 | |
|---|
| 72 | +#define VDPU2_REG_SOFT_RESET 0x0e8 |
|---|
| 73 | +#define VDPU2_REG_SOFT_RESET_INDEX (58) |
|---|
| 74 | + |
|---|
| 72 | 75 | #define VDPU2_REG_DIR_MV_BASE 0x0f8 |
|---|
| 73 | 76 | #define VDPU2_REG_DIR_MV_BASE_INDEX (62) |
|---|
| 74 | 77 | |
|---|
| .. | .. |
|---|
| 224 | 227 | offset = task->reg[idx] >> 10 << 4; |
|---|
| 225 | 228 | } |
|---|
| 226 | 229 | mem_region = mpp_task_attach_fd(&task->mpp_task, fd); |
|---|
| 227 | | - if (IS_ERR(mem_region)) |
|---|
| 230 | + if (IS_ERR(mem_region)) { |
|---|
| 231 | + mpp_err("reg[%3d]: %08x fd %d attach failed\n", |
|---|
| 232 | + idx, task->reg[idx], fd); |
|---|
| 228 | 233 | return -EFAULT; |
|---|
| 234 | + } |
|---|
| 229 | 235 | |
|---|
| 230 | 236 | iova = mem_region->iova; |
|---|
| 231 | 237 | mpp_debug(DEBUG_IOMMU, "DMV[%3d]: %3d => %pad + offset %10d\n", |
|---|
| .. | .. |
|---|
| 340 | 346 | u32 i; |
|---|
| 341 | 347 | u32 reg_en; |
|---|
| 342 | 348 | struct vdpu_task *task = to_vdpu_task(mpp_task); |
|---|
| 349 | + u32 timing_en = mpp->srv->timing_en; |
|---|
| 343 | 350 | |
|---|
| 344 | 351 | mpp_debug_enter(); |
|---|
| 345 | 352 | |
|---|
| .. | .. |
|---|
| 354 | 361 | |
|---|
| 355 | 362 | mpp_write_req(mpp, task->reg, s, e, reg_en); |
|---|
| 356 | 363 | } |
|---|
| 364 | + |
|---|
| 365 | + /* flush tlb before starting hardware */ |
|---|
| 366 | + mpp_iommu_flush_tlb(mpp->iommu_info); |
|---|
| 367 | + |
|---|
| 357 | 368 | /* init current task */ |
|---|
| 358 | 369 | mpp->cur_task = mpp_task; |
|---|
| 370 | + |
|---|
| 371 | + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); |
|---|
| 372 | + |
|---|
| 359 | 373 | /* Flush the registers */ |
|---|
| 360 | 374 | wmb(); |
|---|
| 361 | 375 | mpp_write(mpp, VDPU2_REG_DEC_EN, |
|---|
| 362 | 376 | task->reg[reg_en] | VDPU2_DEC_START); |
|---|
| 363 | 377 | |
|---|
| 378 | + mpp_task_run_end(mpp_task, timing_en); |
|---|
| 379 | + |
|---|
| 364 | 380 | mpp_debug_leave(); |
|---|
| 365 | 381 | |
|---|
| 366 | 382 | return 0; |
|---|
| 383 | +} |
|---|
| 384 | + |
|---|
| 385 | +static int vdpu_px30_run(struct mpp_dev *mpp, |
|---|
| 386 | + struct mpp_task *mpp_task) |
|---|
| 387 | +{ |
|---|
| 388 | + mpp_iommu_flush_tlb(mpp->iommu_info); |
|---|
| 389 | + return vdpu_run(mpp, mpp_task); |
|---|
| 367 | 390 | } |
|---|
| 368 | 391 | |
|---|
| 369 | 392 | static int vdpu_finish(struct mpp_dev *mpp, |
|---|
| .. | .. |
|---|
| 456 | 479 | dec->procfs = NULL; |
|---|
| 457 | 480 | return -EIO; |
|---|
| 458 | 481 | } |
|---|
| 482 | + |
|---|
| 483 | + /* for common mpp_dev options */ |
|---|
| 484 | + mpp_procfs_create_common(dec->procfs, mpp); |
|---|
| 485 | + |
|---|
| 459 | 486 | mpp_procfs_create_u32("aclk", 0644, |
|---|
| 460 | 487 | dec->procfs, &dec->aclk_info.debug_rate_hz); |
|---|
| 461 | 488 | mpp_procfs_create_u32("session_buffers", 0644, |
|---|
| .. | .. |
|---|
| 596 | 623 | return IRQ_HANDLED; |
|---|
| 597 | 624 | } |
|---|
| 598 | 625 | |
|---|
| 626 | +static int vdpu_soft_reset(struct mpp_dev *mpp) |
|---|
| 627 | +{ |
|---|
| 628 | + u32 val; |
|---|
| 629 | + u32 ret; |
|---|
| 630 | + |
|---|
| 631 | + mpp_write(mpp, VDPU2_REG_SOFT_RESET, 1); |
|---|
| 632 | + ret = readl_relaxed_poll_timeout(mpp->reg_base + VDPU2_REG_SOFT_RESET, |
|---|
| 633 | + val, !val, 0, 5); |
|---|
| 634 | + return ret; |
|---|
| 635 | +} |
|---|
| 636 | + |
|---|
| 599 | 637 | static int vdpu_reset(struct mpp_dev *mpp) |
|---|
| 600 | 638 | { |
|---|
| 601 | 639 | struct vdpu_dev *dec = to_vdpu_dev(mpp); |
|---|
| 640 | + u32 ret = 0; |
|---|
| 602 | 641 | |
|---|
| 603 | 642 | mpp_write(mpp, VDPU2_REG_DEC_EN, 0); |
|---|
| 604 | 643 | mpp_write(mpp, VDPU2_REG_DEC_INT, 0); |
|---|
| 605 | | - if (dec->rst_a && dec->rst_h) { |
|---|
| 644 | + |
|---|
| 645 | + /* soft reset first */ |
|---|
| 646 | + ret = vdpu_soft_reset(mpp); |
|---|
| 647 | + if (ret && dec->rst_a && dec->rst_h) { |
|---|
| 606 | 648 | /* Don't skip this or iommu won't work after reset */ |
|---|
| 607 | | - rockchip_pmu_idle_request(mpp->dev, true); |
|---|
| 649 | + mpp_err("soft reset failed, use cru reset!\n"); |
|---|
| 650 | + mpp_debug(DEBUG_RESET, "reset in\n"); |
|---|
| 651 | + mpp_pmu_idle_request(mpp, true); |
|---|
| 608 | 652 | mpp_safe_reset(dec->rst_a); |
|---|
| 609 | 653 | mpp_safe_reset(dec->rst_h); |
|---|
| 610 | 654 | udelay(5); |
|---|
| 611 | 655 | mpp_safe_unreset(dec->rst_a); |
|---|
| 612 | 656 | mpp_safe_unreset(dec->rst_h); |
|---|
| 613 | | - rockchip_pmu_idle_request(mpp->dev, false); |
|---|
| 657 | + mpp_pmu_idle_request(mpp, false); |
|---|
| 658 | + mpp_debug(DEBUG_RESET, "reset out\n"); |
|---|
| 614 | 659 | } |
|---|
| 615 | 660 | |
|---|
| 616 | 661 | return 0; |
|---|
| .. | .. |
|---|
| 645 | 690 | .free_task = vdpu_free_task, |
|---|
| 646 | 691 | }; |
|---|
| 647 | 692 | |
|---|
| 693 | +static struct mpp_dev_ops vdpu_px30_dev_ops = { |
|---|
| 694 | + .alloc_task = vdpu_alloc_task, |
|---|
| 695 | + .run = vdpu_px30_run, |
|---|
| 696 | + .irq = vdpu_irq, |
|---|
| 697 | + .isr = vdpu_isr, |
|---|
| 698 | + .finish = vdpu_finish, |
|---|
| 699 | + .result = vdpu_result, |
|---|
| 700 | + .free_task = vdpu_free_task, |
|---|
| 701 | +}; |
|---|
| 702 | + |
|---|
| 648 | 703 | static const struct mpp_dev_var vdpu_v2_data = { |
|---|
| 649 | 704 | .device_type = MPP_DEVICE_VDPU2, |
|---|
| 650 | 705 | .hw_info = &vdpu_v2_hw_info, |
|---|
| .. | .. |
|---|
| 658 | 713 | .hw_info = &vdpu_v2_hw_info, |
|---|
| 659 | 714 | .trans_info = vdpu_v2_trans, |
|---|
| 660 | 715 | .hw_ops = &vdpu_px30_hw_ops, |
|---|
| 661 | | - .dev_ops = &vdpu_v2_dev_ops, |
|---|
| 716 | + .dev_ops = &vdpu_px30_dev_ops, |
|---|
| 662 | 717 | }; |
|---|
| 663 | 718 | |
|---|
| 664 | 719 | static const struct of_device_id mpp_vdpu2_dt_match[] = { |
|---|
| .. | .. |
|---|
| 687 | 742 | dec = devm_kzalloc(dev, sizeof(struct vdpu_dev), GFP_KERNEL); |
|---|
| 688 | 743 | if (!dec) |
|---|
| 689 | 744 | return -ENOMEM; |
|---|
| 690 | | - platform_set_drvdata(pdev, dec); |
|---|
| 691 | | - |
|---|
| 692 | 745 | mpp = &dec->mpp; |
|---|
| 746 | + platform_set_drvdata(pdev, mpp); |
|---|
| 693 | 747 | |
|---|
| 694 | 748 | if (pdev->dev.of_node) { |
|---|
| 695 | 749 | match = of_match_node(mpp_vdpu2_dt_match, |
|---|
| 696 | 750 | pdev->dev.of_node); |
|---|
| 697 | 751 | if (match) |
|---|
| 698 | 752 | mpp->var = (struct mpp_dev_var *)match->data; |
|---|
| 753 | + |
|---|
| 754 | + mpp->core_id = of_alias_get_id(pdev->dev.of_node, "vdpu"); |
|---|
| 699 | 755 | } |
|---|
| 700 | 756 | |
|---|
| 701 | 757 | ret = mpp_dev_probe(mpp, pdev); |
|---|
| .. | .. |
|---|
| 731 | 787 | static int vdpu_remove(struct platform_device *pdev) |
|---|
| 732 | 788 | { |
|---|
| 733 | 789 | struct device *dev = &pdev->dev; |
|---|
| 734 | | - struct vdpu_dev *dec = platform_get_drvdata(pdev); |
|---|
| 790 | + struct mpp_dev *mpp = dev_get_drvdata(dev); |
|---|
| 735 | 791 | |
|---|
| 736 | 792 | dev_info(dev, "remove device\n"); |
|---|
| 737 | | - mpp_dev_remove(&dec->mpp); |
|---|
| 738 | | - vdpu_procfs_remove(&dec->mpp); |
|---|
| 793 | + mpp_dev_remove(mpp); |
|---|
| 794 | + vdpu_procfs_remove(mpp); |
|---|
| 739 | 795 | |
|---|
| 740 | 796 | return 0; |
|---|
| 741 | | -} |
|---|
| 742 | | - |
|---|
| 743 | | -static void vdpu_shutdown(struct platform_device *pdev) |
|---|
| 744 | | -{ |
|---|
| 745 | | - int ret; |
|---|
| 746 | | - int val; |
|---|
| 747 | | - struct device *dev = &pdev->dev; |
|---|
| 748 | | - struct vdpu_dev *dec = platform_get_drvdata(pdev); |
|---|
| 749 | | - struct mpp_dev *mpp = &dec->mpp; |
|---|
| 750 | | - |
|---|
| 751 | | - dev_info(dev, "shutdown device\n"); |
|---|
| 752 | | - |
|---|
| 753 | | - atomic_inc(&mpp->srv->shutdown_request); |
|---|
| 754 | | - ret = readx_poll_timeout(atomic_read, |
|---|
| 755 | | - &mpp->task_count, |
|---|
| 756 | | - val, val == 0, 20000, 200000); |
|---|
| 757 | | - if (ret == -ETIMEDOUT) |
|---|
| 758 | | - dev_err(dev, "wait total running time out\n"); |
|---|
| 759 | 797 | } |
|---|
| 760 | 798 | |
|---|
| 761 | 799 | struct platform_driver rockchip_vdpu2_driver = { |
|---|
| 762 | 800 | .probe = vdpu_probe, |
|---|
| 763 | 801 | .remove = vdpu_remove, |
|---|
| 764 | | - .shutdown = vdpu_shutdown, |
|---|
| 802 | + .shutdown = mpp_dev_shutdown, |
|---|
| 765 | 803 | .driver = { |
|---|
| 766 | 804 | .name = VDPU2_DRIVER_NAME, |
|---|
| 767 | 805 | .of_match_table = of_match_ptr(mpp_vdpu2_dt_match), |
|---|