From 15ade055295d13f95d49e3d99b09f3bbfb4a43e7 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 07:25:24 +0000
Subject: [PATCH] add at24 driver

---
 kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c |   86 +++++++++++++++++++++++++++++++++++++++----
 1 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
index 90cdc13..7d2d7ae 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
@@ -28,6 +28,8 @@
 #include <linux/nospec.h>
 #include <linux/workqueue.h>
 #include <linux/dma-iommu.h>
+#include <linux/mfd/syscon.h>
+#include <linux/rockchip/cpu.h>
 #include <soc/rockchip/pm_domains.h>
 #include <soc/rockchip/rockchip_ipa.h>
 #include <soc/rockchip/rockchip_opp_select.h>
@@ -41,6 +43,7 @@
 
 #define	RKVENC_SESSION_MAX_BUFFERS		40
 #define RKVENC_MAX_CORE_NUM			4
+#define RKVENC_SCLR_DONE_STA			BIT(2)
 
 #define to_rkvenc_info(info)		\
 		container_of(info, struct rkvenc_hw_info, hw)
@@ -187,6 +190,7 @@
 	dma_addr_t sram_iova;
 	u32 sram_enabled;
 	struct page *rcb_page;
+	struct regmap *grf;
 };
 
 
@@ -699,6 +703,7 @@
 	struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
 	struct rkvenc_task *task = to_rkvenc_task(mpp_task);
 	struct rkvenc_hw_info *hw = enc->hw_info;
+	u32 timing_en = mpp->srv->timing_en;
 
 	mpp_debug_enter();
 
@@ -735,11 +740,20 @@
 		}
 	}
 
+	/* 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, enc->hw_info->enc_start_base, start_val);
+
+	mpp_task_run_end(mpp_task, timing_en);
 
 	mpp_debug_leave();
 
@@ -793,6 +807,7 @@
 		if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG))
 			mpp_task_dump_hw_reg(mpp, mpp_task);
 	}
+
 	mpp_task_finish(mpp_task->session, mpp_task);
 
 	mpp_debug_leave();
@@ -1031,6 +1046,10 @@
 		enc->procfs = NULL;
 		return -EIO;
 	}
+
+	/* for common mpp_dev options */
+	mpp_procfs_create_common(enc->procfs, mpp);
+
 	/* for debug */
 	mpp_procfs_create_u32("aclk", 0644,
 			      enc->procfs, &enc->aclk_info.debug_rate_hz);
@@ -1063,7 +1082,7 @@
 	struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
 	int ret = 0;
 
-	mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_RKVENC];
+	mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_RKVENC2];
 
 	/* Get clock info from dtsi */
 	ret = mpp_get_clk_info(mpp, &enc->aclk_info, "aclk_vcodec");
@@ -1097,23 +1116,41 @@
 	return 0;
 }
 
-static int rkvenc_reset(struct mpp_dev *mpp)
+static int rkvenc_soft_reset(struct mpp_dev *mpp)
 {
 	struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
 	struct rkvenc_hw_info *hw = enc->hw_info;
-
-	mpp_debug_enter();
+	u32 rst_status = 0;
+	int ret = 0;
 
 	/* safe reset */
 	mpp_write(mpp, hw->int_mask_base, 0x3FF);
 	mpp_write(mpp, hw->enc_clr_base, 0x1);
-	udelay(5);
+	ret = readl_relaxed_poll_timeout(mpp->reg_base + hw->int_sta_base,
+					 rst_status,
+					 rst_status & RKVENC_SCLR_DONE_STA,
+					 0, 5);
 	mpp_write(mpp, hw->int_clr_base, 0xffffffff);
 	mpp_write(mpp, hw->int_sta_base, 0);
 
+	return ret;
+
+}
+
+static int rkvenc_reset(struct mpp_dev *mpp)
+{
+	struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
+	int ret = 0;
+
+	mpp_debug_enter();
+
+	/* safe reset first*/
+	ret = rkvenc_soft_reset(mpp);
+
 	/* cru reset */
-	if (enc->rst_a && enc->rst_h && enc->rst_core) {
-		rockchip_pmu_idle_request(mpp->dev, true);
+	if (ret && enc->rst_a && enc->rst_h && enc->rst_core) {
+		mpp_err("soft reset timeout, use cru reset\n");
+		mpp_pmu_idle_request(mpp, true);
 		mpp_safe_reset(enc->rst_a);
 		mpp_safe_reset(enc->rst_h);
 		mpp_safe_reset(enc->rst_core);
@@ -1121,7 +1158,7 @@
 		mpp_safe_unreset(enc->rst_a);
 		mpp_safe_unreset(enc->rst_h);
 		mpp_safe_unreset(enc->rst_core);
-		rockchip_pmu_idle_request(mpp->dev, false);
+		mpp_pmu_idle_request(mpp, false);
 	}
 
 	mpp_debug_leave();
@@ -1338,6 +1375,7 @@
 	}
 	mpp->session_max_buffers = RKVENC_SESSION_MAX_BUFFERS;
 	enc->hw_info = to_rkvenc_info(mpp->var->hw_info);
+
 	rkvenc_procfs_init(mpp);
 	mpp_dev_register_srv(mpp, mpp->srv);
 
@@ -1416,12 +1454,44 @@
 	dev_info(dev, "shutdown success\n");
 }
 
+static int rkvenc_runtime_suspend(struct device *dev)
+{
+	struct mpp_dev *mpp = dev_get_drvdata(dev);
+	struct mpp_grf_info *info = mpp->grf_info;
+
+	if (cpu_is_rk3528() && info && info->mem_offset)
+		regmap_write(info->grf,
+			     info->mem_offset,
+			     info->val_mem_off);
+
+	return 0;
+}
+
+static int rkvenc_runtime_resume(struct device *dev)
+{
+	struct mpp_dev *mpp = dev_get_drvdata(dev);
+	struct mpp_grf_info *info = mpp->grf_info;
+
+	if (cpu_is_rk3528() && info && info->mem_offset)
+		regmap_write(info->grf,
+			     info->mem_offset,
+			     info->val_mem_on);
+
+	return 0;
+}
+
+static const struct dev_pm_ops rkvenc_pm_ops = {
+	.runtime_suspend		= rkvenc_runtime_suspend,
+	.runtime_resume			= rkvenc_runtime_resume,
+};
+
 struct platform_driver rockchip_rkvenc2_driver = {
 	.probe = rkvenc_probe,
 	.remove = rkvenc_remove,
 	.shutdown = rkvenc_shutdown,
 	.driver = {
 		.name = RKVENC_DRIVER_NAME,
+		.pm = &rkvenc_pm_ops,
 		.of_match_table = of_match_ptr(mpp_rkvenc_dt_match),
 	},
 };

--
Gitblit v1.6.2