From 4588f28c362bf9e6efe8aa116e7cfedda10efcc2 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 24 Jun 2024 21:02:45 +0000
Subject: [PATCH 334/484] WIP: rkvdec: flush iotlb to reconfigure iommu

---
 drivers/staging/media/rkvdec/rkvdec.c | 17 +++++++++++++++++
 drivers/staging/media/rkvdec/rkvdec.h |  1 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index 977f175eb7a5..433bcee3aaa0 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/interrupt.h>
+#include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -911,6 +912,19 @@ static void rkvdec_device_run(void *priv)
 	if (WARN_ON(!desc))
 		return;
 
+	/*
+	 * The hw decoder block may reset IOMMU when there is an error,
+	 * flush entire iotlb to reconfigure the IOMMU.
+	 */
+	if (rkvdec->flush_iommu) {
+		struct iommu_domain *domain;
+
+		domain = iommu_get_domain_for_dev(rkvdec->dev);
+		if (domain)
+			iommu_flush_iotlb_all(domain);
+		rkvdec->flush_iommu = false;
+	}
+
 	ret = pm_runtime_resume_and_get(rkvdec->dev);
 	if (ret < 0) {
 		rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR);
@@ -1171,6 +1185,9 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
 	state = (status & RKVDEC_RDY_STA) ?
 		VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
 
+	if (state == VB2_BUF_STATE_ERROR || (status & RKVDEC_SOFTRESET_RDY))
+		rkvdec->flush_iommu = true;
+
 	writel(RKVDEC_CONFIG_DEC_CLK_GATE_E, rkvdec->regs + RKVDEC_REG_INTERRUPT);
 	if (cancel_delayed_work(&rkvdec->watchdog_work)) {
 		struct rkvdec_ctx *ctx;
diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h
index 1d5d405da56c..65b45ed3312a 100644
--- a/drivers/staging/media/rkvdec/rkvdec.h
+++ b/drivers/staging/media/rkvdec/rkvdec.h
@@ -124,6 +124,7 @@ struct rkvdec_dev {
 	struct delayed_work watchdog_work;
 	unsigned int capabilities;
 	unsigned int quirks;
+	bool flush_iommu;
 };
 
 struct rkvdec_ctx {
-- 
2.49.0

