.. | .. |
---|
20 | 20 | #include <linux/uaccess.h> |
---|
21 | 21 | #include <linux/regmap.h> |
---|
22 | 22 | #include <linux/proc_fs.h> |
---|
23 | | -#include <linux/mfd/syscon.h> |
---|
24 | | -#include <linux/rockchip/cpu.h> |
---|
25 | 23 | #include <soc/rockchip/pm_domains.h> |
---|
26 | 24 | |
---|
27 | 25 | #include "mpp_debug.h" |
---|
.. | .. |
---|
113 | 111 | #endif |
---|
114 | 112 | struct reset_control *rst_a; |
---|
115 | 113 | struct reset_control *rst_h; |
---|
116 | | - struct regmap *grf; |
---|
117 | 114 | }; |
---|
118 | 115 | |
---|
119 | 116 | static struct mpp_hw_info vdpu_v2_hw_info = { |
---|
.. | .. |
---|
230 | 227 | offset = task->reg[idx] >> 10 << 4; |
---|
231 | 228 | } |
---|
232 | 229 | mem_region = mpp_task_attach_fd(&task->mpp_task, fd); |
---|
233 | | - 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); |
---|
234 | 233 | return -EFAULT; |
---|
| 234 | + } |
---|
235 | 235 | |
---|
236 | 236 | iova = mem_region->iova; |
---|
237 | 237 | mpp_debug(DEBUG_IOMMU, "DMV[%3d]: %3d => %pad + offset %10d\n", |
---|
.. | .. |
---|
380 | 380 | mpp_debug_leave(); |
---|
381 | 381 | |
---|
382 | 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); |
---|
383 | 390 | } |
---|
384 | 391 | |
---|
385 | 392 | static int vdpu_finish(struct mpp_dev *mpp, |
---|
.. | .. |
---|
619 | 626 | static int vdpu_soft_reset(struct mpp_dev *mpp) |
---|
620 | 627 | { |
---|
621 | 628 | u32 val; |
---|
| 629 | + u32 ret; |
---|
622 | 630 | |
---|
623 | 631 | mpp_write(mpp, VDPU2_REG_SOFT_RESET, 1); |
---|
624 | | - udelay(2); |
---|
625 | | - val = mpp_read(mpp, VDPU2_REG_SOFT_RESET); |
---|
626 | | - |
---|
627 | | - return val; |
---|
| 632 | + ret = readl_relaxed_poll_timeout(mpp->reg_base + VDPU2_REG_SOFT_RESET, |
---|
| 633 | + val, !val, 0, 5); |
---|
| 634 | + return ret; |
---|
628 | 635 | } |
---|
629 | 636 | |
---|
630 | 637 | static int vdpu_reset(struct mpp_dev *mpp) |
---|
.. | .. |
---|
639 | 646 | ret = vdpu_soft_reset(mpp); |
---|
640 | 647 | if (ret && dec->rst_a && dec->rst_h) { |
---|
641 | 648 | /* Don't skip this or iommu won't work after reset */ |
---|
| 649 | + mpp_err("soft reset failed, use cru reset!\n"); |
---|
642 | 650 | mpp_debug(DEBUG_RESET, "reset in\n"); |
---|
643 | 651 | mpp_pmu_idle_request(mpp, true); |
---|
644 | 652 | mpp_safe_reset(dec->rst_a); |
---|
.. | .. |
---|
682 | 690 | .free_task = vdpu_free_task, |
---|
683 | 691 | }; |
---|
684 | 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 | + |
---|
685 | 703 | static const struct mpp_dev_var vdpu_v2_data = { |
---|
686 | 704 | .device_type = MPP_DEVICE_VDPU2, |
---|
687 | 705 | .hw_info = &vdpu_v2_hw_info, |
---|
.. | .. |
---|
695 | 713 | .hw_info = &vdpu_v2_hw_info, |
---|
696 | 714 | .trans_info = vdpu_v2_trans, |
---|
697 | 715 | .hw_ops = &vdpu_px30_hw_ops, |
---|
698 | | - .dev_ops = &vdpu_v2_dev_ops, |
---|
| 716 | + .dev_ops = &vdpu_px30_dev_ops, |
---|
699 | 717 | }; |
---|
700 | 718 | |
---|
701 | 719 | static const struct of_device_id mpp_vdpu2_dt_match[] = { |
---|
.. | .. |
---|
724 | 742 | dec = devm_kzalloc(dev, sizeof(struct vdpu_dev), GFP_KERNEL); |
---|
725 | 743 | if (!dec) |
---|
726 | 744 | return -ENOMEM; |
---|
727 | | - platform_set_drvdata(pdev, dec); |
---|
728 | | - |
---|
729 | 745 | mpp = &dec->mpp; |
---|
| 746 | + platform_set_drvdata(pdev, mpp); |
---|
730 | 747 | |
---|
731 | 748 | if (pdev->dev.of_node) { |
---|
732 | 749 | match = of_match_node(mpp_vdpu2_dt_match, |
---|
733 | 750 | pdev->dev.of_node); |
---|
734 | 751 | if (match) |
---|
735 | 752 | mpp->var = (struct mpp_dev_var *)match->data; |
---|
| 753 | + |
---|
| 754 | + mpp->core_id = of_alias_get_id(pdev->dev.of_node, "vdpu"); |
---|
736 | 755 | } |
---|
737 | 756 | |
---|
738 | 757 | ret = mpp_dev_probe(mpp, pdev); |
---|
.. | .. |
---|
768 | 787 | static int vdpu_remove(struct platform_device *pdev) |
---|
769 | 788 | { |
---|
770 | 789 | struct device *dev = &pdev->dev; |
---|
771 | | - struct vdpu_dev *dec = platform_get_drvdata(pdev); |
---|
| 790 | + struct mpp_dev *mpp = dev_get_drvdata(dev); |
---|
772 | 791 | |
---|
773 | 792 | dev_info(dev, "remove device\n"); |
---|
774 | | - mpp_dev_remove(&dec->mpp); |
---|
775 | | - vdpu_procfs_remove(&dec->mpp); |
---|
| 793 | + mpp_dev_remove(mpp); |
---|
| 794 | + vdpu_procfs_remove(mpp); |
---|
776 | 795 | |
---|
777 | 796 | return 0; |
---|
778 | 797 | } |
---|
779 | | - |
---|
780 | | -static void vdpu_shutdown(struct platform_device *pdev) |
---|
781 | | -{ |
---|
782 | | - int ret; |
---|
783 | | - int val; |
---|
784 | | - struct device *dev = &pdev->dev; |
---|
785 | | - struct vdpu_dev *dec = platform_get_drvdata(pdev); |
---|
786 | | - struct mpp_dev *mpp = &dec->mpp; |
---|
787 | | - |
---|
788 | | - dev_info(dev, "shutdown device\n"); |
---|
789 | | - |
---|
790 | | - atomic_inc(&mpp->srv->shutdown_request); |
---|
791 | | - ret = readx_poll_timeout(atomic_read, |
---|
792 | | - &mpp->task_count, |
---|
793 | | - val, val == 0, 20000, 200000); |
---|
794 | | - if (ret == -ETIMEDOUT) |
---|
795 | | - dev_err(dev, "wait total running time out\n"); |
---|
796 | | -} |
---|
797 | | - |
---|
798 | | -static int vdpu_runtime_suspend(struct device *dev) |
---|
799 | | -{ |
---|
800 | | - struct mpp_dev *mpp = dev_get_drvdata(dev); |
---|
801 | | - struct mpp_grf_info *info = mpp->grf_info; |
---|
802 | | - struct mpp_taskqueue *queue = mpp->queue; |
---|
803 | | - |
---|
804 | | - if (cpu_is_rk3528() && info && info->mem_offset) { |
---|
805 | | - mutex_lock(&queue->ref_lock); |
---|
806 | | - if (!atomic_dec_if_positive(&queue->runtime_cnt)) { |
---|
807 | | - regmap_write(info->grf, info->mem_offset, |
---|
808 | | - info->val_mem_off); |
---|
809 | | - } |
---|
810 | | - mutex_unlock(&queue->ref_lock); |
---|
811 | | - } |
---|
812 | | - |
---|
813 | | - return 0; |
---|
814 | | -} |
---|
815 | | - |
---|
816 | | -static int vdpu_runtime_resume(struct device *dev) |
---|
817 | | -{ |
---|
818 | | - struct mpp_dev *mpp = dev_get_drvdata(dev); |
---|
819 | | - struct mpp_grf_info *info = mpp->grf_info; |
---|
820 | | - struct mpp_taskqueue *queue = mpp->queue; |
---|
821 | | - |
---|
822 | | - if (cpu_is_rk3528() && info && info->mem_offset) { |
---|
823 | | - mutex_lock(&queue->ref_lock); |
---|
824 | | - regmap_write(info->grf, info->mem_offset, |
---|
825 | | - info->val_mem_on); |
---|
826 | | - atomic_inc(&queue->runtime_cnt); |
---|
827 | | - mutex_unlock(&queue->ref_lock); |
---|
828 | | - } |
---|
829 | | - |
---|
830 | | - return 0; |
---|
831 | | -} |
---|
832 | | - |
---|
833 | | -static const struct dev_pm_ops vdpu_pm_ops = { |
---|
834 | | - .runtime_suspend = vdpu_runtime_suspend, |
---|
835 | | - .runtime_resume = vdpu_runtime_resume, |
---|
836 | | -}; |
---|
837 | 798 | |
---|
838 | 799 | struct platform_driver rockchip_vdpu2_driver = { |
---|
839 | 800 | .probe = vdpu_probe, |
---|
840 | 801 | .remove = vdpu_remove, |
---|
841 | | - .shutdown = vdpu_shutdown, |
---|
| 802 | + .shutdown = mpp_dev_shutdown, |
---|
842 | 803 | .driver = { |
---|
843 | 804 | .name = VDPU2_DRIVER_NAME, |
---|
844 | | - .pm = &vdpu_pm_ops, |
---|
845 | 805 | .of_match_table = of_match_ptr(mpp_vdpu2_dt_match), |
---|
846 | 806 | }, |
---|
847 | 807 | }; |
---|