mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
147 lines
5.4 KiB
Diff
147 lines
5.4 KiB
Diff
From e41a90ac22dea18394bf08c84ad06fdf3acc627e Mon Sep 17 00:00:00 2001
|
|
From: Alex Bee <knaerzche@gmail.com>
|
|
Date: Sun, 10 Aug 2025 21:24:35 +0000
|
|
Subject: [PATCH 048/110] FROMLIST(v3): media: rkvdec: Disable QoS for HEVC and
|
|
VP9 on RK3328
|
|
|
|
The RK3328 VDEC has a HW quirk that require QoS to be disabled when HEVC
|
|
or VP9 is decoded, otherwise the decoded picture may become corrupted.
|
|
|
|
Add a RK3328 variant with a quirk flag to disable QoS when before
|
|
decoding is started.
|
|
|
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
.../platform/rockchip/rkvdec/rkvdec-hevc.c | 3 +++
|
|
.../platform/rockchip/rkvdec/rkvdec-regs.h | 2 ++
|
|
.../platform/rockchip/rkvdec/rkvdec-vp9.c | 4 ++++
|
|
.../media/platform/rockchip/rkvdec/rkvdec.c | 24 +++++++++++++++++++
|
|
.../media/platform/rockchip/rkvdec/rkvdec.h | 5 ++++
|
|
5 files changed, 38 insertions(+)
|
|
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
|
|
index 9b5cf70188db..fc7e6a260b0a 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
|
|
@@ -789,6 +789,9 @@ static int rkvdec_hevc_run(struct rkvdec_ctx *ctx)
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
|
|
|
|
+ if (rkvdec->variant->quirks & RKVDEC_QUIRK_DISABLE_QOS)
|
|
+ rkvdec_quirks_disable_qos(ctx);
|
|
+
|
|
/* Start decoding! */
|
|
reg = (run.pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) ?
|
|
0 : RKVDEC_WR_DDR_ALIGN_EN;
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
|
|
index 540c8bdf24e4..c627b6b6f53a 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
|
|
@@ -219,6 +219,8 @@
|
|
#define RKVDEC_REG_H264_ERR_E 0x134
|
|
#define RKVDEC_H264_ERR_EN_HIGHBITS(x) ((x) & 0x3fffffff)
|
|
|
|
+#define RKVDEC_REG_QOS_CTRL 0x18C
|
|
+
|
|
#define RKVDEC_REG_PREF_LUMA_CACHE_COMMAND 0x410
|
|
#define RKVDEC_REG_PREF_CHR_CACHE_COMMAND 0x450
|
|
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
|
|
index 0e7e16f20eeb..b4bf01e839ef 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
|
|
@@ -824,6 +824,10 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx)
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
|
|
|
|
writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
|
|
+
|
|
+ if (rkvdec->variant->quirks & RKVDEC_QUIRK_DISABLE_QOS)
|
|
+ rkvdec_quirks_disable_qos(ctx);
|
|
+
|
|
/* Start decoding! */
|
|
writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E |
|
|
RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E,
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
|
|
index 918ac6d38950..ef0ad92600f3 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
|
|
@@ -902,6 +902,18 @@ void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run)
|
|
v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl);
|
|
}
|
|
|
|
+void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx)
|
|
+{
|
|
+ struct rkvdec_dev *rkvdec = ctx->dev;
|
|
+ u32 reg;
|
|
+
|
|
+ /* Set undocumented swreg_block_gating_e field */
|
|
+ reg = readl(rkvdec->regs + RKVDEC_REG_QOS_CTRL);
|
|
+ reg &= GENMASK(31, 16);
|
|
+ reg |= 0xEFFF;
|
|
+ writel(reg, rkvdec->regs + RKVDEC_REG_QOS_CTRL);
|
|
+}
|
|
+
|
|
static void rkvdec_device_run(void *priv)
|
|
{
|
|
struct rkvdec_ctx *ctx = priv;
|
|
@@ -1226,6 +1238,14 @@ static const struct rkvdec_variant rk3288_rkvdec_variant = {
|
|
.capabilities = RKVDEC_CAPABILITY_HEVC,
|
|
};
|
|
|
|
+static const struct rkvdec_variant rk3328_rkvdec_variant = {
|
|
+ .num_regs = 109,
|
|
+ .capabilities = RKVDEC_CAPABILITY_HEVC |
|
|
+ RKVDEC_CAPABILITY_H264 |
|
|
+ RKVDEC_CAPABILITY_VP9,
|
|
+ .quirks = RKVDEC_QUIRK_DISABLE_QOS,
|
|
+};
|
|
+
|
|
static const struct rkvdec_variant rk3399_rkvdec_variant = {
|
|
.num_regs = 78,
|
|
.capabilities = RKVDEC_CAPABILITY_HEVC |
|
|
@@ -1238,6 +1258,10 @@ static const struct of_device_id of_rkvdec_match[] = {
|
|
.compatible = "rockchip,rk3288-vdec",
|
|
.data = &rk3288_rkvdec_variant,
|
|
},
|
|
+ {
|
|
+ .compatible = "rockchip,rk3328-vdec",
|
|
+ .data = &rk3328_rkvdec_variant,
|
|
+ },
|
|
{
|
|
.compatible = "rockchip,rk3399-vdec",
|
|
.data = &rk3399_rkvdec_variant,
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
|
|
index d2e17eb2cca6..892d2380b59d 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
|
|
@@ -26,6 +26,8 @@
|
|
#define RKVDEC_CAPABILITY_H264 BIT(1)
|
|
#define RKVDEC_CAPABILITY_VP9 BIT(2)
|
|
|
|
+#define RKVDEC_QUIRK_DISABLE_QOS BIT(0)
|
|
+
|
|
struct rkvdec_ctx;
|
|
|
|
struct rkvdec_ctrl_desc {
|
|
@@ -70,6 +72,7 @@ vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf)
|
|
struct rkvdec_variant {
|
|
unsigned int num_regs;
|
|
unsigned int capabilities;
|
|
+ unsigned int quirks;
|
|
};
|
|
|
|
struct rkvdec_coded_fmt_ops {
|
|
@@ -149,6 +152,8 @@ struct rkvdec_aux_buf {
|
|
void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
|
|
void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
|
|
|
|
+void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx);
|
|
+
|
|
extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
|
|
extern const struct rkvdec_coded_fmt_ops rkvdec_hevc_fmt_ops;
|
|
extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
|
|
--
|
|
2.34.1
|
|
|