hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c
....@@ -20,6 +20,8 @@
2020 #include <linux/uaccess.h>
2121 #include <linux/regmap.h>
2222 #include <linux/proc_fs.h>
23
+#include <linux/mfd/syscon.h>
24
+#include <linux/rockchip/cpu.h>
2325 #include <soc/rockchip/pm_domains.h>
2426
2527 #include "mpp_debug.h"
....@@ -57,6 +59,9 @@
5759 /* NOTE: Don't enable it or decoding AVC would meet problem at rk3288 */
5860 #define VDPU1_REG_DEC_EN 0x008
5961 #define VDPU1_CLOCK_GATE_EN BIT(10)
62
+
63
+#define VDPU1_REG_SOFT_RESET 0x194
64
+#define VDPU1_REG_SOFT_RESET_INDEX (101)
6065
6166 #define VDPU1_REG_SYS_CTRL 0x00c
6267 #define VDPU1_REG_SYS_CTRL_INDEX (3)
....@@ -387,6 +392,7 @@
387392 u32 i;
388393 u32 reg_en;
389394 struct vdpu_task *task = to_vdpu_task(mpp_task);
395
+ u32 timing_en = mpp->srv->timing_en;
390396
391397 mpp_debug_enter();
392398
....@@ -401,12 +407,21 @@
401407
402408 mpp_write_req(mpp, task->reg, s, e, reg_en);
403409 }
410
+
411
+ /* flush tlb before starting hardware */
412
+ mpp_iommu_flush_tlb(mpp->iommu_info);
413
+
404414 /* init current task */
405415 mpp->cur_task = mpp_task;
416
+
417
+ mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
418
+
406419 /* Flush the register before the start the device */
407420 wmb();
408421 mpp_write(mpp, VDPU1_REG_DEC_INT_EN,
409422 task->reg[reg_en] | VDPU1_DEC_START);
423
+
424
+ mpp_task_run_end(mpp_task, timing_en);
410425
411426 mpp_debug_leave();
412427
....@@ -503,6 +518,10 @@
503518 dec->procfs = NULL;
504519 return -EIO;
505520 }
521
+
522
+ /* for common mpp_dev options */
523
+ mpp_procfs_create_common(dec->procfs, mpp);
524
+
506525 mpp_procfs_create_u32("aclk", 0644,
507526 dec->procfs, &dec->aclk_info.debug_rate_hz);
508527 mpp_procfs_create_u32("session_buffers", 0644,
....@@ -663,21 +682,35 @@
663682 return IRQ_HANDLED;
664683 }
665684
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
+
666696 static int vdpu_reset(struct mpp_dev *mpp)
667697 {
668698 struct vdpu_dev *dec = to_vdpu_dev(mpp);
699
+ u32 ret = 0;
669700
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) {
671704 mpp_debug(DEBUG_RESET, "reset in\n");
672705
673706 /* 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);
675708 mpp_safe_reset(dec->rst_a);
676709 mpp_safe_reset(dec->rst_h);
677710 udelay(5);
678711 mpp_safe_unreset(dec->rst_a);
679712 mpp_safe_unreset(dec->rst_h);
680
- rockchip_pmu_idle_request(mpp->dev, false);
713
+ mpp_pmu_idle_request(mpp, false);
681714
682715 mpp_debug(DEBUG_RESET, "reset out\n");
683716 }
....@@ -774,12 +807,10 @@
774807 .data = &vdpu_3368_data,
775808 },
776809 #endif
777
-#ifdef CONFIG_CPU_RK3328
778810 {
779811 .compatible = "rockchip,avs-plus-decoder",
780812 .data = &avsd_plus_data,
781813 },
782
-#endif
783814 {},
784815 };
785816
....@@ -864,12 +895,53 @@
864895 dev_err(dev, "wait total running time out\n");
865896 }
866897
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
+
867938 struct platform_driver rockchip_vdpu1_driver = {
868939 .probe = vdpu_probe,
869940 .remove = vdpu_remove,
870941 .shutdown = vdpu_shutdown,
871942 .driver = {
872943 .name = VDPU1_DRIVER_NAME,
944
+ .pm = &vdpu_pm_ops,
873945 .of_match_table = of_match_ptr(mpp_vdpu1_dt_match),
874946 },
875947 };