.. | .. |
---|
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> |
---|
23 | 25 | #include <soc/rockchip/pm_domains.h> |
---|
24 | 26 | |
---|
25 | 27 | #include "mpp_debug.h" |
---|
.. | .. |
---|
57 | 59 | /* NOTE: Don't enable it or decoding AVC would meet problem at rk3288 */ |
---|
58 | 60 | #define VDPU1_REG_DEC_EN 0x008 |
---|
59 | 61 | #define VDPU1_CLOCK_GATE_EN BIT(10) |
---|
| 62 | + |
---|
| 63 | +#define VDPU1_REG_SOFT_RESET 0x194 |
---|
| 64 | +#define VDPU1_REG_SOFT_RESET_INDEX (101) |
---|
60 | 65 | |
---|
61 | 66 | #define VDPU1_REG_SYS_CTRL 0x00c |
---|
62 | 67 | #define VDPU1_REG_SYS_CTRL_INDEX (3) |
---|
.. | .. |
---|
387 | 392 | u32 i; |
---|
388 | 393 | u32 reg_en; |
---|
389 | 394 | struct vdpu_task *task = to_vdpu_task(mpp_task); |
---|
| 395 | + u32 timing_en = mpp->srv->timing_en; |
---|
390 | 396 | |
---|
391 | 397 | mpp_debug_enter(); |
---|
392 | 398 | |
---|
.. | .. |
---|
401 | 407 | |
---|
402 | 408 | mpp_write_req(mpp, task->reg, s, e, reg_en); |
---|
403 | 409 | } |
---|
| 410 | + |
---|
| 411 | + /* flush tlb before starting hardware */ |
---|
| 412 | + mpp_iommu_flush_tlb(mpp->iommu_info); |
---|
| 413 | + |
---|
404 | 414 | /* init current task */ |
---|
405 | 415 | mpp->cur_task = mpp_task; |
---|
| 416 | + |
---|
| 417 | + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); |
---|
| 418 | + |
---|
406 | 419 | /* Flush the register before the start the device */ |
---|
407 | 420 | wmb(); |
---|
408 | 421 | mpp_write(mpp, VDPU1_REG_DEC_INT_EN, |
---|
409 | 422 | task->reg[reg_en] | VDPU1_DEC_START); |
---|
| 423 | + |
---|
| 424 | + mpp_task_run_end(mpp_task, timing_en); |
---|
410 | 425 | |
---|
411 | 426 | mpp_debug_leave(); |
---|
412 | 427 | |
---|
.. | .. |
---|
503 | 518 | dec->procfs = NULL; |
---|
504 | 519 | return -EIO; |
---|
505 | 520 | } |
---|
| 521 | + |
---|
| 522 | + /* for common mpp_dev options */ |
---|
| 523 | + mpp_procfs_create_common(dec->procfs, mpp); |
---|
| 524 | + |
---|
506 | 525 | mpp_procfs_create_u32("aclk", 0644, |
---|
507 | 526 | dec->procfs, &dec->aclk_info.debug_rate_hz); |
---|
508 | 527 | mpp_procfs_create_u32("session_buffers", 0644, |
---|
.. | .. |
---|
663 | 682 | return IRQ_HANDLED; |
---|
664 | 683 | } |
---|
665 | 684 | |
---|
| 685 | +static int vdpu_soft_reset(struct mpp_dev *mpp) |
---|
| 686 | +{ |
---|
| 687 | + u32 val; |
---|
| 688 | + |
---|
| 689 | + mpp_write(mpp, VDPU1_REG_SOFT_RESET, 1); |
---|
| 690 | + udelay(2); |
---|
| 691 | + val = mpp_read(mpp, VDPU1_REG_SOFT_RESET); |
---|
| 692 | + |
---|
| 693 | + return val; |
---|
| 694 | +} |
---|
| 695 | + |
---|
666 | 696 | static int vdpu_reset(struct mpp_dev *mpp) |
---|
667 | 697 | { |
---|
668 | 698 | struct vdpu_dev *dec = to_vdpu_dev(mpp); |
---|
| 699 | + u32 ret = 0; |
---|
669 | 700 | |
---|
670 | | - if (dec->rst_a && dec->rst_h) { |
---|
| 701 | + /* soft reset first */ |
---|
| 702 | + ret = vdpu_soft_reset(mpp); |
---|
| 703 | + if (ret && dec->rst_a && dec->rst_h) { |
---|
671 | 704 | mpp_debug(DEBUG_RESET, "reset in\n"); |
---|
672 | 705 | |
---|
673 | 706 | /* Don't skip this or iommu won't work after reset */ |
---|
674 | | - rockchip_pmu_idle_request(mpp->dev, true); |
---|
| 707 | + mpp_pmu_idle_request(mpp, true); |
---|
675 | 708 | mpp_safe_reset(dec->rst_a); |
---|
676 | 709 | mpp_safe_reset(dec->rst_h); |
---|
677 | 710 | udelay(5); |
---|
678 | 711 | mpp_safe_unreset(dec->rst_a); |
---|
679 | 712 | mpp_safe_unreset(dec->rst_h); |
---|
680 | | - rockchip_pmu_idle_request(mpp->dev, false); |
---|
| 713 | + mpp_pmu_idle_request(mpp, false); |
---|
681 | 714 | |
---|
682 | 715 | mpp_debug(DEBUG_RESET, "reset out\n"); |
---|
683 | 716 | } |
---|
.. | .. |
---|
774 | 807 | .data = &vdpu_3368_data, |
---|
775 | 808 | }, |
---|
776 | 809 | #endif |
---|
777 | | -#ifdef CONFIG_CPU_RK3328 |
---|
778 | 810 | { |
---|
779 | 811 | .compatible = "rockchip,avs-plus-decoder", |
---|
780 | 812 | .data = &avsd_plus_data, |
---|
781 | 813 | }, |
---|
782 | | -#endif |
---|
783 | 814 | {}, |
---|
784 | 815 | }; |
---|
785 | 816 | |
---|
.. | .. |
---|
864 | 895 | dev_err(dev, "wait total running time out\n"); |
---|
865 | 896 | } |
---|
866 | 897 | |
---|
| 898 | +static int vdpu_runtime_suspend(struct device *dev) |
---|
| 899 | +{ |
---|
| 900 | + struct mpp_dev *mpp = dev_get_drvdata(dev); |
---|
| 901 | + struct mpp_grf_info *info = mpp->grf_info; |
---|
| 902 | + struct mpp_taskqueue *queue = mpp->queue; |
---|
| 903 | + |
---|
| 904 | + if (cpu_is_rk3528() && info && info->mem_offset) { |
---|
| 905 | + mutex_lock(&queue->ref_lock); |
---|
| 906 | + if (!atomic_dec_if_positive(&queue->runtime_cnt)) { |
---|
| 907 | + regmap_write(info->grf, info->mem_offset, |
---|
| 908 | + info->val_mem_off); |
---|
| 909 | + } |
---|
| 910 | + mutex_unlock(&queue->ref_lock); |
---|
| 911 | + } |
---|
| 912 | + |
---|
| 913 | + return 0; |
---|
| 914 | +} |
---|
| 915 | + |
---|
| 916 | +static int vdpu_runtime_resume(struct device *dev) |
---|
| 917 | +{ |
---|
| 918 | + struct mpp_dev *mpp = dev_get_drvdata(dev); |
---|
| 919 | + struct mpp_grf_info *info = mpp->grf_info; |
---|
| 920 | + struct mpp_taskqueue *queue = mpp->queue; |
---|
| 921 | + |
---|
| 922 | + if (cpu_is_rk3528() && info && info->mem_offset) { |
---|
| 923 | + mutex_lock(&queue->ref_lock); |
---|
| 924 | + regmap_write(info->grf, info->mem_offset, |
---|
| 925 | + info->val_mem_on); |
---|
| 926 | + atomic_inc(&queue->runtime_cnt); |
---|
| 927 | + mutex_unlock(&queue->ref_lock); |
---|
| 928 | + } |
---|
| 929 | + |
---|
| 930 | + return 0; |
---|
| 931 | +} |
---|
| 932 | + |
---|
| 933 | +static const struct dev_pm_ops vdpu_pm_ops = { |
---|
| 934 | + .runtime_suspend = vdpu_runtime_suspend, |
---|
| 935 | + .runtime_resume = vdpu_runtime_resume, |
---|
| 936 | +}; |
---|
| 937 | + |
---|
867 | 938 | struct platform_driver rockchip_vdpu1_driver = { |
---|
868 | 939 | .probe = vdpu_probe, |
---|
869 | 940 | .remove = vdpu_remove, |
---|
870 | 941 | .shutdown = vdpu_shutdown, |
---|
871 | 942 | .driver = { |
---|
872 | 943 | .name = VDPU1_DRIVER_NAME, |
---|
| 944 | + .pm = &vdpu_pm_ops, |
---|
873 | 945 | .of_match_table = of_match_ptr(mpp_vdpu1_dt_match), |
---|
874 | 946 | }, |
---|
875 | 947 | }; |
---|