From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 03:04:41 +0000
Subject: [PATCH] rk3568 rt init

---
 kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c |   82 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c b/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c
index a14f102..537c6a2 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c
@@ -20,6 +20,8 @@
 #include <linux/uaccess.h>
 #include <linux/regmap.h>
 #include <linux/proc_fs.h>
+#include <linux/mfd/syscon.h>
+#include <linux/rockchip/cpu.h>
 #include <soc/rockchip/pm_domains.h>
 
 #include "mpp_debug.h"
@@ -57,6 +59,9 @@
 /* NOTE: Don't enable it or decoding AVC would meet problem at rk3288 */
 #define VDPU1_REG_DEC_EN		0x008
 #define	VDPU1_CLOCK_GATE_EN		BIT(10)
+
+#define VDPU1_REG_SOFT_RESET		0x194
+#define VDPU1_REG_SOFT_RESET_INDEX	(101)
 
 #define VDPU1_REG_SYS_CTRL		0x00c
 #define VDPU1_REG_SYS_CTRL_INDEX	(3)
@@ -387,6 +392,7 @@
 	u32 i;
 	u32 reg_en;
 	struct vdpu_task *task = to_vdpu_task(mpp_task);
+	u32 timing_en = mpp->srv->timing_en;
 
 	mpp_debug_enter();
 
@@ -401,12 +407,21 @@
 
 		mpp_write_req(mpp, task->reg, s, e, reg_en);
 	}
+
+	/* flush tlb before starting hardware */
+	mpp_iommu_flush_tlb(mpp->iommu_info);
+
 	/* init current task */
 	mpp->cur_task = mpp_task;
+
+	mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
+
 	/* Flush the register before the start the device */
 	wmb();
 	mpp_write(mpp, VDPU1_REG_DEC_INT_EN,
 		  task->reg[reg_en] | VDPU1_DEC_START);
+
+	mpp_task_run_end(mpp_task, timing_en);
 
 	mpp_debug_leave();
 
@@ -503,6 +518,10 @@
 		dec->procfs = NULL;
 		return -EIO;
 	}
+
+	/* for common mpp_dev options */
+	mpp_procfs_create_common(dec->procfs, mpp);
+
 	mpp_procfs_create_u32("aclk", 0644,
 			      dec->procfs, &dec->aclk_info.debug_rate_hz);
 	mpp_procfs_create_u32("session_buffers", 0644,
@@ -663,21 +682,35 @@
 	return IRQ_HANDLED;
 }
 
+static int vdpu_soft_reset(struct mpp_dev *mpp)
+{
+	u32 val;
+
+	mpp_write(mpp, VDPU1_REG_SOFT_RESET, 1);
+	udelay(2);
+	val = mpp_read(mpp, VDPU1_REG_SOFT_RESET);
+
+	return val;
+}
+
 static int vdpu_reset(struct mpp_dev *mpp)
 {
 	struct vdpu_dev *dec = to_vdpu_dev(mpp);
+	u32 ret = 0;
 
-	if (dec->rst_a && dec->rst_h) {
+	/* soft reset first */
+	ret = vdpu_soft_reset(mpp);
+	if (ret && dec->rst_a && dec->rst_h) {
 		mpp_debug(DEBUG_RESET, "reset in\n");
 
 		/* Don't skip this or iommu won't work after reset */
-		rockchip_pmu_idle_request(mpp->dev, true);
+		mpp_pmu_idle_request(mpp, true);
 		mpp_safe_reset(dec->rst_a);
 		mpp_safe_reset(dec->rst_h);
 		udelay(5);
 		mpp_safe_unreset(dec->rst_a);
 		mpp_safe_unreset(dec->rst_h);
-		rockchip_pmu_idle_request(mpp->dev, false);
+		mpp_pmu_idle_request(mpp, false);
 
 		mpp_debug(DEBUG_RESET, "reset out\n");
 	}
@@ -774,12 +807,10 @@
 		.data = &vdpu_3368_data,
 	},
 #endif
-#ifdef CONFIG_CPU_RK3328
 	{
 		.compatible = "rockchip,avs-plus-decoder",
 		.data = &avsd_plus_data,
 	},
-#endif
 	{},
 };
 
@@ -864,12 +895,53 @@
 		dev_err(dev, "wait total running time out\n");
 }
 
+static int vdpu_runtime_suspend(struct device *dev)
+{
+	struct mpp_dev *mpp = dev_get_drvdata(dev);
+	struct mpp_grf_info *info = mpp->grf_info;
+	struct mpp_taskqueue *queue = mpp->queue;
+
+	if (cpu_is_rk3528() && info && info->mem_offset) {
+		mutex_lock(&queue->ref_lock);
+		if (!atomic_dec_if_positive(&queue->runtime_cnt)) {
+			regmap_write(info->grf, info->mem_offset,
+				     info->val_mem_off);
+		}
+		mutex_unlock(&queue->ref_lock);
+	}
+
+	return 0;
+}
+
+static int vdpu_runtime_resume(struct device *dev)
+{
+	struct mpp_dev *mpp = dev_get_drvdata(dev);
+	struct mpp_grf_info *info = mpp->grf_info;
+	struct mpp_taskqueue *queue = mpp->queue;
+
+	if (cpu_is_rk3528() && info && info->mem_offset) {
+		mutex_lock(&queue->ref_lock);
+		regmap_write(info->grf, info->mem_offset,
+			     info->val_mem_on);
+		atomic_inc(&queue->runtime_cnt);
+		mutex_unlock(&queue->ref_lock);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops vdpu_pm_ops = {
+	.runtime_suspend		= vdpu_runtime_suspend,
+	.runtime_resume			= vdpu_runtime_resume,
+};
+
 struct platform_driver rockchip_vdpu1_driver = {
 	.probe = vdpu_probe,
 	.remove = vdpu_remove,
 	.shutdown = vdpu_shutdown,
 	.driver = {
 		.name = VDPU1_DRIVER_NAME,
+		.pm = &vdpu_pm_ops,
 		.of_match_table = of_match_ptr(mpp_vdpu1_dt_match),
 	},
 };

--
Gitblit v1.6.2