mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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> Tested-by: Diederik de Haas <didi.debian@cknow.org> # Rock64, RockPro64, Quartz64-B, NanoPi R5S Tested-by: Detlev Casanova <detlev.casanova@collabora.com> # RK3399 Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -1225,6 +1237,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 |
|
||||
@@ -1237,6 +1257,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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user