Re: [PATCH v3 2/7] media: rkvdec: Add variants support
From: Jonas Karlman <jonas@kwiboo.se>
Date: 2025-09-09 08:41:35
Also in:
linux-devicetree, linux-media, linux-rockchip, lkml
Hi Detlev, On 9/8/2025 8:32 PM, Detlev Casanova wrote:
Hi Jonas, On 9/5/25 12:19, Jonas Karlman wrote:quoted
From: Alex Bee <redacted> Different versions of the Rockchip VDEC IP exists and one way they can differ is what decoding formats are supported. Add a variant implementation in order to support flagging different capabilities. Signed-off-by: Alex Bee <redacted> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> --- Changes in v3: - Use a reference to rkvdec_variant - Add num_regs fieldWhy are you adding this field ? I don't see it being used in a later patch.
Correct, this was briefly mentioned in the cover letter change log for v3: Add num_regs field to rkvdec_variant, currently not used for anything This addition was mostly to make us aware that there are different number of swregs for the different variants of "rkvdev1".
Would that be useful for writing the right amount of registers later when switching to structs and memcpy ?
Correct, to my knowledge there are 3 different register configurations for "rkvdec1", all are mostly extended with more registers at the end. 68 (rk3288) -> 78 (rk3399) -> 109 (rk3328) Currently there are writel() that are blindly written to regs >68 and
78 regardless of variant. If we are to move to use io memcpy we should
probably ensure to write to the regs that exists for each variant.
I haven't checked how different the register maps are between those different variants.
As mentioned above they mostly differ at the end (more swregs), or use additional previously unused bits of existing swregs. E.g. rk3328 has sw_wr_ddr_align_en, sw_scl_down_en and sw_allow_not_wr_unref_bframe added to swreg1. The added num_regs can be dropped or replaced with proper structs (or something different) if you think that is a better way to signal how the variants regs differs. Regards, Jonas
quoted
- Collect r-b tag Changes in v2: - No change --- .../media/platform/rockchip/rkvdec/rkvdec.c | 22 ++++++++++++++++++- .../media/platform/rockchip/rkvdec/rkvdec.h | 11 ++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-)diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c index c15fc238d6af..daf6d9ab2d1d 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c@@ -14,6 +14,7 @@ #include <linux/iommu.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h>@@ -327,6 +328,7 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { .ops = &rkvdec_hevc_fmt_ops, .num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts), .decoded_fmts = rkvdec_hevc_decoded_fmts, + .capability = RKVDEC_CAPABILITY_HEVC, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE,@@ -343,6 +345,7 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts), .decoded_fmts = rkvdec_h264_decoded_fmts, .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF, + .capability = RKVDEC_CAPABILITY_H264, }, { .fourcc = V4L2_PIX_FMT_VP9_FRAME,@@ -358,6 +361,7 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { .ops = &rkvdec_vp9_fmt_ops, .num_decoded_fmts = ARRAY_SIZE(rkvdec_vp9_decoded_fmts), .decoded_fmts = rkvdec_vp9_decoded_fmts, + .capability = RKVDEC_CAPABILITY_VP9, } };@@ -1186,8 +1190,18 @@ static void rkvdec_watchdog_func(struct work_struct *work) } } +static const struct rkvdec_variant rk3399_rkvdec_variant = { + .num_regs = 78, + .capabilities = RKVDEC_CAPABILITY_HEVC | + RKVDEC_CAPABILITY_H264 | + RKVDEC_CAPABILITY_VP9, +}; + static const struct of_device_id of_rkvdec_match[] = { - { .compatible = "rockchip,rk3399-vdec" }, + { + .compatible = "rockchip,rk3399-vdec", + .data = &rk3399_rkvdec_variant, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, of_rkvdec_match);@@ -1198,16 +1212,22 @@ static const char * const rkvdec_clk_names[] = { static int rkvdec_probe(struct platform_device *pdev) { + const struct rkvdec_variant *variant; struct rkvdec_dev *rkvdec; unsigned int i; int ret, irq; + variant = of_device_get_match_data(&pdev->dev); + if (!variant) + return -EINVAL; + rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL); if (!rkvdec) return -ENOMEM; platform_set_drvdata(pdev, rkvdec); rkvdec->dev = &pdev->dev; + rkvdec->variant = variant; mutex_init(&rkvdec->vdev_lock); INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h index 209dd79ce9bd..c47457c954e5 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h@@ -22,6 +22,10 @@ #include <media/videobuf2-core.h> #include <media/videobuf2-dma-contig.h> +#define RKVDEC_CAPABILITY_HEVC BIT(0) +#define RKVDEC_CAPABILITY_H264 BIT(1) +#define RKVDEC_CAPABILITY_VP9 BIT(2) + struct rkvdec_ctx; struct rkvdec_ctrl_desc {@@ -63,6 +67,11 @@ vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf) base.vb.vb2_buf); } +struct rkvdec_variant { + unsigned int num_regs; + unsigned int capabilities; +}; + struct rkvdec_coded_fmt_ops { int (*adjust_fmt)(struct rkvdec_ctx *ctx, struct v4l2_format *f);@@ -98,6 +107,7 @@ struct rkvdec_coded_fmt_desc { unsigned int num_decoded_fmts; const struct rkvdec_decoded_fmt_desc *decoded_fmts; u32 subsystem_flags; + unsigned int capability; }; struct rkvdec_dev {@@ -111,6 +121,7 @@ struct rkvdec_dev { struct mutex vdev_lock; /* serializes ioctls */ struct delayed_work watchdog_work; struct iommu_domain *empty_domain; + const struct rkvdec_variant *variant; }; struct rkvdec_ctx {Regards, Detlev