From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 19 Dec 2024 01:47:39 +0000
Subject: [PATCH] add wifi6 8852be driver

---
 kernel/drivers/video/rockchip/mpp/mpp_iep2.c |   95 ++++++++++++++++++++++++++++-------------------
 1 files changed, 56 insertions(+), 39 deletions(-)

diff --git a/kernel/drivers/video/rockchip/mpp/mpp_iep2.c b/kernel/drivers/video/rockchip/mpp/mpp_iep2.c
index 92ec40e..8d19269 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_iep2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_iep2.c
@@ -266,8 +266,8 @@
 
 		mem_region = mpp_task_attach_fd(&task->mpp_task, usr_fd);
 		if (IS_ERR(mem_region)) {
-			mpp_debug(DEBUG_IOMMU, "reg[%3d]: %08x failed\n",
-				  iep2_addr_rnum[i], paddr[i]);
+			mpp_err("reg[%03d]: %08x failed\n",
+				iep2_addr_rnum[i], paddr[i]);
 			return PTR_ERR(mem_region);
 		}
 
@@ -389,12 +389,13 @@
 		| IEP2_REG_DIL_OSD_EN
 		| IEP2_REG_DIL_PD_EN
 		| IEP2_REG_DIL_FF_EN
-		| IEP2_REG_DIL_MD_PRE_EN
 		| IEP2_REG_DIL_FIELD_ORDER(cfg->dil_field_order)
 		| IEP2_REG_DIL_OUT_MODE(cfg->dil_out_mode)
 		| IEP2_REG_DIL_MODE(cfg->dil_mode);
 	if (cfg->roi_en)
 		reg |= IEP2_REG_DIL_ROI_EN;
+	if (cfg->md_lambda < 8)
+		reg |= IEP2_REG_DIL_MD_PRE_EN;
 	mpp_write_relaxed(mpp, IEP2_REG_DIL_CONFIG0, reg);
 
 	if (cfg->dil_mode != ROCKCHIP_IEP2_DIL_MODE_PD) {
@@ -437,6 +438,9 @@
 		mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTUV, bot->cbcr);
 		mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTV, bot->cr);
 	}
+
+	reg = IEP2_REG_TIMEOUT_CFG_EN | 0x3ffffff;
+	mpp_write_relaxed(mpp, IEP2_REG_TIMEOUT_CFG, reg);
 
 	mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREY, cfg->src[2].y);
 	mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREUV, cfg->src[2].cbcr);
@@ -580,6 +584,7 @@
 		    struct mpp_task *mpp_task)
 {
 	struct iep_task *task = NULL;
+	u32 timing_en = mpp->srv->timing_en;
 
 	mpp_debug_enter();
 
@@ -598,12 +603,20 @@
 	mpp_write_relaxed(mpp, IEP2_REG_INT_EN,
 			  IEP2_REG_FRM_DONE_EN
 			  | IEP2_REG_OSD_MAX_EN
-			  | IEP2_REG_BUS_ERROR_EN);
+			  | IEP2_REG_BUS_ERROR_EN
+			  | IEP2_REG_TIMEOUT_EN);
+
+	/* flush tlb before starting hardware */
+	mpp_iommu_flush_tlb(mpp->iommu_info);
+
+	mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
 
 	/* Last, flush the registers */
 	wmb();
 	/* start iep2 */
 	mpp_write(mpp, IEP2_REG_FRM_START, 1);
+
+	mpp_task_run_end(mpp_task, timing_en);
 
 	mpp_debug_leave();
 
@@ -612,6 +625,10 @@
 
 static int iep2_irq(struct mpp_dev *mpp)
 {
+	u32 work_mode = mpp_read(mpp, IEP2_REG_WORK_MODE);
+
+	if (work_mode && !(work_mode & IEP2_REG_IEP2_MODE))
+		return IRQ_NONE;
 	mpp->irq_status = mpp_read(mpp, IEP2_REG_INT_STS);
 	mpp_write(mpp, IEP2_REG_INT_CLR, 0xffffffff);
 
@@ -640,7 +657,8 @@
 	mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n",
 		  task->irq_status);
 
-	if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status))
+	if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status) ||
+	    IEP2_REG_RO_TIMEOUT_STS(task->irq_status))
 		atomic_inc(&mpp->reset_request);
 
 	mpp_task_finish(mpp_task->session, mpp_task);
@@ -769,6 +787,10 @@
 		iep->procfs = NULL;
 		return -EIO;
 	}
+
+	/* for common mpp_dev options */
+	mpp_procfs_create_common(iep->procfs, mpp);
+
 	mpp_procfs_create_u32("aclk", 0644,
 			      iep->procfs, &iep->aclk_info.debug_rate_hz);
 	mpp_procfs_create_u32("session_buffers", 0644,
@@ -870,17 +892,29 @@
 {
 	struct iep2_dev *iep = to_iep2_dev(mpp);
 
-	if (iep->rst_a && iep->rst_h && iep->rst_s) {
-		/* Don't skip this or iommu won't work after reset */
-		rockchip_pmu_idle_request(mpp->dev, true);
-		mpp_safe_reset(iep->rst_a);
-		mpp_safe_reset(iep->rst_h);
-		mpp_safe_reset(iep->rst_s);
-		udelay(5);
-		mpp_safe_unreset(iep->rst_a);
-		mpp_safe_unreset(iep->rst_h);
-		mpp_safe_unreset(iep->rst_s);
-		rockchip_pmu_idle_request(mpp->dev, false);
+	int ret = 0;
+	u32 rst_status = 0;
+
+	/* soft rest first */
+	mpp_write(mpp, IEP2_REG_IEP_CONFIG0, IEP2_REG_ACLK_SRESET_P);
+	ret = readl_relaxed_poll_timeout(mpp->reg_base + IEP2_REG_STATUS,
+					 rst_status,
+					 rst_status & IEP2_REG_ARST_FINISH_DONE,
+					 0, 5);
+	if (ret) {
+		mpp_err("soft reset timeout, use cru reset\n");
+		if (iep->rst_a && iep->rst_h && iep->rst_s) {
+			/* Don't skip this or iommu won't work after reset */
+			mpp_pmu_idle_request(mpp, true);
+			mpp_safe_reset(iep->rst_a);
+			mpp_safe_reset(iep->rst_h);
+			mpp_safe_reset(iep->rst_s);
+			udelay(5);
+			mpp_safe_unreset(iep->rst_a);
+			mpp_safe_unreset(iep->rst_h);
+			mpp_safe_unreset(iep->rst_s);
+			mpp_pmu_idle_request(mpp, false);
+		}
 	}
 
 	return 0;
@@ -943,7 +977,7 @@
 		return -ENOMEM;
 
 	mpp = &iep->mpp;
-	platform_set_drvdata(pdev, iep);
+	platform_set_drvdata(pdev, mpp);
 
 	if (pdev->dev.of_node) {
 		match = of_match_node(mpp_iep2_match, pdev->dev.of_node);
@@ -979,39 +1013,22 @@
 static int iep2_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct iep2_dev *iep = platform_get_drvdata(pdev);
+	struct mpp_dev *mpp = dev_get_drvdata(dev);
+	struct iep2_dev *iep = to_iep2_dev(mpp);
 
 	dma_free_coherent(dev, iep->roi.size, iep->roi.vaddr, iep->roi.iova);
 
 	dev_info(dev, "remove device\n");
-	mpp_dev_remove(&iep->mpp);
-	iep2_procfs_remove(&iep->mpp);
+	mpp_dev_remove(mpp);
+	iep2_procfs_remove(mpp);
 
 	return 0;
-}
-
-static void iep2_shutdown(struct platform_device *pdev)
-{
-	int ret;
-	int val;
-	struct device *dev = &pdev->dev;
-	struct iep2_dev *iep = platform_get_drvdata(pdev);
-	struct mpp_dev *mpp = &iep->mpp;
-
-	dev_info(dev, "shutdown device\n");
-
-	atomic_inc(&mpp->srv->shutdown_request);
-	ret = readx_poll_timeout(atomic_read,
-				 &mpp->task_count,
-				 val, val == 0, 20000, 200000);
-	if (ret == -ETIMEDOUT)
-		dev_err(dev, "wait total running time out\n");
 }
 
 struct platform_driver rockchip_iep2_driver = {
 	.probe = iep2_probe,
 	.remove = iep2_remove,
-	.shutdown = iep2_shutdown,
+	.shutdown = mpp_dev_shutdown,
 	.driver = {
 		.name = IEP2_DRIVER_NAME,
 		.of_match_table = of_match_ptr(mpp_iep2_match),

--
Gitblit v1.6.2