.. | .. |
---|
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), |
---|