rockchip64-6.16: update new rkvdev driver

This commit is contained in:
Jianfeng Liu
2025-08-21 15:55:15 +08:00
committed by Rolf Leggewie
parent 5ac4ff6ab4
commit 1b767c0584
4 changed files with 13896 additions and 3748 deletions

View File

@@ -0,0 +1,268 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Date: Thu, 8 May 2025 17:00:15 -0400
Subject: media: rkvdec: Restore iommu addresses on errors
On errors, the rkvdec chip self resets. This can clear the addresses
programmed in the iommu. This case is signaled by the
RKVDEC_SOFTRESET_RDY status bit.
Since the iommu framework does not have a restore functionality, and
as recommended by the iommu subsystem maintainers, this patch
restores the iommu programming by attaching and detaching an empty
domain, which will clear and restore the default domain.
Suggested-by: Detlev Casanova <detlev.casanova@collabora.com>
Tested-by: Detlev Casanova <detlev.casanova@collabora.com>
Reviewed-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
---
drivers/staging/media/rkvdec/rkvdec.c | 43 ++++++++--
drivers/staging/media/rkvdec/rkvdec.h | 1 +
2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index 111111111111..222222222222 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/platform_device.h>
@@ -1055,24 +1056,42 @@ static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec)
v4l2_device_unregister(&rkvdec->v4l2_dev);
}
+static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec)
+{
+ if (rkvdec->empty_domain) {
+ /*
+ * To rewrite mapping into the attached IOMMU core, attach a new empty domain that
+ * will program an empty table, then detach it to restore the default domain and
+ * all cached mappings.
+ * This is safely done in this interrupt handler to make sure no memory get mapped
+ * through the IOMMU while the empty domain is attached.
+ */
+ iommu_attach_device(rkvdec->empty_domain, rkvdec->dev);
+ iommu_detach_device(rkvdec->empty_domain, rkvdec->dev);
+ }
+}
+
static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
{
struct rkvdec_dev *rkvdec = priv;
+ struct rkvdec_ctx *ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
enum vb2_buffer_state state;
u32 status;
status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT);
- state = (status & RKVDEC_RDY_STA) ?
- VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
-
writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);
- if (cancel_delayed_work(&rkvdec->watchdog_work)) {
- struct rkvdec_ctx *ctx;
- ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
- rkvdec_job_finish(ctx, state);
+ if (status & RKVDEC_RDY_STA) {
+ state = VB2_BUF_STATE_DONE;
+ } else {
+ state = VB2_BUF_STATE_ERROR;
+ if (status & RKVDEC_SOFTRESET_RDY)
+ rkvdec_iommu_restore(rkvdec);
}
+ if (cancel_delayed_work(&rkvdec->watchdog_work))
+ rkvdec_job_finish(ctx, state);
+
return IRQ_HANDLED;
}
@@ -1140,6 +1159,13 @@ static int rkvdec_probe(struct platform_device *pdev)
return ret;
}
+ if (iommu_get_domain_for_dev(&pdev->dev)) {
+ rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev);
+
+ if (!rkvdec->empty_domain)
+ dev_warn(rkvdec->dev, "cannot alloc new empty domain\n");
+ }
+
vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
irq = platform_get_irq(pdev, 0);
@@ -1179,6 +1205,9 @@ static void rkvdec_remove(struct platform_device *pdev)
rkvdec_v4l2_cleanup(rkvdec);
pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
+
+ if (rkvdec->empty_domain)
+ iommu_domain_free(rkvdec->empty_domain);
}
#ifdef CONFIG_PM
diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h
index 111111111111..222222222222 100644
--- a/drivers/staging/media/rkvdec/rkvdec.h
+++ b/drivers/staging/media/rkvdec/rkvdec.h
@@ -110,6 +110,7 @@ struct rkvdec_dev {
void __iomem *regs;
struct mutex vdev_lock; /* serializes ioctls */
struct delayed_work watchdog_work;
+ struct iommu_domain *empty_domain;
};
struct rkvdec_ctx {
--
Armbian
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Detlev Casanova <detlev.casanova@collabora.com>
Date: Wed, 18 Jun 2025 13:06:36 -0400
Subject: media: rkvdec: Remove TODO file
2 items are present in the TODO file:
- HEVC support
- Evaluate adding helper for rkvdec_request_validate
Missing HEVC support is not a reason for a driver to be in staging,
support for different features of the hardware can be added in drivers
in the main tree.
The rkvdec_request_validate function was simplified in
commit 54676d5f5630 ("media: rkvdec: Do not require all controls to be present in every request")
by not setting controls that have not changed.
As it now basically just calls vb2_request_validate(), there is no need
for a helper.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
drivers/staging/media/rkvdec/TODO | 11 ----------
1 file changed, 11 deletions(-)
diff --git a/drivers/staging/media/rkvdec/TODO b/drivers/staging/media/rkvdec/TODO
deleted file mode 100644
index 111111111111..222222222222
--- a/drivers/staging/media/rkvdec/TODO
+++ /dev/null
@@ -1,11 +0,0 @@
-* Support for HEVC is planned for this driver.
-
- Given the V4L controls for that CODEC will be part of
- the uABI, it will be required to have the driver in staging.
-
- For this reason, we are keeping this driver in staging for now.
-
-* Evaluate introducing a helper to consolidate duplicated
- code in rkvdec_request_validate and cedrus_request_validate.
- The helper needs to the driver private data associated with
- the videobuf2 queue, from a media request.
--
Armbian
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Detlev Casanova <detlev.casanova@collabora.com>
Date: Wed, 18 Jun 2025 13:17:08 -0400
Subject: media: rkvdec: Unstage the driver
The TODO list for unstaging being empty, the driver can now be moved to the
main media folder.
Also add myself as maintainer.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
drivers/media/platform/rockchip/Kconfig | 1 +
drivers/media/platform/rockchip/Makefile | 1 +
drivers/{staging/media => media/platform/rockchip}/rkvdec/Kconfig | 0
drivers/{staging/media => media/platform/rockchip}/rkvdec/Makefile | 0
drivers/{staging/media => media/platform/rockchip}/rkvdec/rkvdec-h264.c | 0
drivers/{staging/media => media/platform/rockchip}/rkvdec/rkvdec-regs.h | 0
drivers/{staging/media => media/platform/rockchip}/rkvdec/rkvdec-vp9.c | 0
drivers/{staging/media => media/platform/rockchip}/rkvdec/rkvdec.c | 0
drivers/{staging/media => media/platform/rockchip}/rkvdec/rkvdec.h | 0
drivers/staging/media/Kconfig | 2 --
drivers/staging/media/Makefile | 1 -
11 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig
index 111111111111..222222222222 100644
--- a/drivers/media/platform/rockchip/Kconfig
+++ b/drivers/media/platform/rockchip/Kconfig
@@ -5,3 +5,4 @@ comment "Rockchip media platform drivers"
source "drivers/media/platform/rockchip/rga/Kconfig"
source "drivers/media/platform/rockchip/rkisp1/Kconfig"
source "drivers/media/platform/rockchip/iep/Kconfig"
+source "drivers/media/platform/rockchip/rkvdec/Kconfig"
diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile
index 111111111111..222222222222 100644
--- a/drivers/media/platform/rockchip/Makefile
+++ b/drivers/media/platform/rockchip/Makefile
@@ -2,3 +2,4 @@
obj-y += rga/
obj-y += rkisp1/
obj-y += iep/
+obj-y += rkvdec/
diff --git a/drivers/staging/media/rkvdec/Kconfig b/drivers/media/platform/rockchip/rkvdec/Kconfig
similarity index 100%
rename from drivers/staging/media/rkvdec/Kconfig
rename to drivers/media/platform/rockchip/rkvdec/Kconfig
diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
similarity index 100%
rename from drivers/staging/media/rkvdec/Makefile
rename to drivers/media/platform/rockchip/rkvdec/Makefile
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
similarity index 100%
rename from drivers/staging/media/rkvdec/rkvdec-h264.c
rename to drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
similarity index 100%
rename from drivers/staging/media/rkvdec/rkvdec-regs.h
rename to drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
similarity index 100%
rename from drivers/staging/media/rkvdec/rkvdec-vp9.c
rename to drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
similarity index 100%
rename from drivers/staging/media/rkvdec/rkvdec.c
rename to drivers/media/platform/rockchip/rkvdec/rkvdec.c
diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
similarity index 100%
rename from drivers/staging/media/rkvdec/rkvdec.h
rename to drivers/media/platform/rockchip/rkvdec/rkvdec.h
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 111111111111..222222222222 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -32,8 +32,6 @@ source "drivers/staging/media/max96712/Kconfig"
source "drivers/staging/media/meson/vdec/Kconfig"
-source "drivers/staging/media/rkvdec/Kconfig"
-
source "drivers/staging/media/starfive/Kconfig"
source "drivers/staging/media/sunxi/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 111111111111..222222222222 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -4,7 +4,6 @@ obj-$(CONFIG_INTEL_ATOMISP) += atomisp/
obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
obj-$(CONFIG_VIDEO_MAX96712) += max96712/
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
-obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive/
obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/
--
Armbian

File diff suppressed because it is too large Load Diff