From: Ezequiel Garcia <ezequiel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
To: linux-media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Hans Verkuil
<hans.verkuil-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>
Cc: Nicolas Dufresne
<nicolas.dufresne-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>,
Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>,
Jonas Karlman <jonas-uIzNG4q0ceqzQB+pC5nmwQ@public.gmane.org>,
Tomasz Figa <tfiga-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Boris Brezillon
<boris.brezillon-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>,
Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
kernel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org
Subject: [PATCH v6 14/16] rockchip/vpu: Add MPEG2 decoding support to RK3399
Date: Tue, 28 May 2019 14:02:30 -0300 [thread overview]
Message-ID: <20190528170232.2091-15-ezequiel@collabora.com> (raw)
In-Reply-To: <20190528170232.2091-1-ezequiel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
From: Jonas Karlman <jonas-uIzNG4q0ceqzQB+pC5nmwQ@public.gmane.org>
Add the necessary bits to support MPEG2 decoding on RK3399.
Signed-off-by: Jonas Karlman <jonas-uIzNG4q0ceqzQB+pC5nmwQ@public.gmane.org>
Signed-off-by: Boris Brezillon <boris.brezillon-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
---
Changes from v4:
* Stop including rockchip_vpu_common.h
Changes from v3:
* New patch (was part of another patch before)
drivers/staging/media/rockchip/vpu/Makefile | 1 +
.../media/rockchip/vpu/rk3399_vpu_hw.c | 59 +++-
.../rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c | 267 ++++++++++++++++++
.../media/rockchip/vpu/rockchip_vpu_hw.h | 1 +
4 files changed, 327 insertions(+), 1 deletion(-)
create mode 100644 drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c
diff --git a/drivers/staging/media/rockchip/vpu/Makefile b/drivers/staging/media/rockchip/vpu/Makefile
index b3144e4f9d33..c742754a89a5 100644
--- a/drivers/staging/media/rockchip/vpu/Makefile
+++ b/drivers/staging/media/rockchip/vpu/Makefile
@@ -8,5 +8,6 @@ rockchip-vpu-y += \
rk3288_vpu_hw_jpeg_enc.o \
rk3399_vpu_hw.o \
rk3399_vpu_hw_jpeg_enc.o \
+ rk3399_vpu_hw_mpeg2_dec.o \
rockchip_vpu_jpeg.o \
rockchip_vpu_mpeg2.o
diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c
index 5c6c1e8b36d6..2b3689968ef4 100644
--- a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c
+++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c
@@ -55,6 +55,26 @@ static const struct rockchip_vpu_fmt rk3399_vpu_enc_fmts[] = {
},
};
+static const struct rockchip_vpu_fmt rk3399_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = RK_VPU_MODE_NONE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
+ .codec_mode = RK_VPU_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+ .min_width = 48,
+ .max_width = 1920,
+ .step_width = MPEG2_MB_DIM,
+ .min_height = 48,
+ .max_height = 1088,
+ .step_height = MPEG2_MB_DIM,
+ },
+ },
+};
+
static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id)
{
struct rockchip_vpu_dev *vpu = dev_id;
@@ -74,6 +94,24 @@ static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t rk3399_vdpu_irq(int irq, void *dev_id)
+{
+ struct rockchip_vpu_dev *vpu = dev_id;
+ enum vb2_buffer_state state;
+ u32 status;
+
+ status = vdpu_read(vpu, VDPU_REG_INTERRUPT);
+ state = (status & VDPU_REG_INTERRUPT_DEC_IRQ) ?
+ VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
+
+ vdpu_write(vpu, 0, VDPU_REG_INTERRUPT);
+ vdpu_write(vpu, 0, VDPU_REG_AXI_CTRL);
+
+ rockchip_vpu_irq_done(vpu, 0, state);
+
+ return IRQ_HANDLED;
+}
+
static int rk3399_vpu_hw_init(struct rockchip_vpu_dev *vpu)
{
/* Bump ACLK to max. possible freq. to improve performance. */
@@ -90,6 +128,15 @@ static void rk3399_vpu_enc_reset(struct rockchip_vpu_ctx *ctx)
vepu_write(vpu, 0, VEPU_REG_AXI_CTRL);
}
+static void rk3399_vpu_dec_reset(struct rockchip_vpu_ctx *ctx)
+{
+ struct rockchip_vpu_dev *vpu = ctx->dev;
+
+ vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT);
+ vdpu_write(vpu, 0, VDPU_REG_EN_FLAGS);
+ vdpu_write(vpu, 1, VDPU_REG_SOFT_RESET);
+}
+
/*
* Supported codec ops.
*/
@@ -101,6 +148,12 @@ static const struct rockchip_vpu_codec_ops rk3399_vpu_codec_ops[] = {
.init = rockchip_vpu_jpeg_enc_init,
.exit = rockchip_vpu_jpeg_enc_exit,
},
+ [RK_VPU_MODE_MPEG2_DEC] = {
+ .run = rk3399_vpu_mpeg2_dec_run,
+ .reset = rk3399_vpu_dec_reset,
+ .init = rockchip_vpu_mpeg2_dec_init,
+ .exit = rockchip_vpu_mpeg2_dec_exit,
+ },
};
/*
@@ -111,9 +164,13 @@ const struct rockchip_vpu_variant rk3399_vpu_variant = {
.enc_offset = 0x0,
.enc_fmts = rk3399_vpu_enc_fmts,
.num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts),
- .codec = RK_VPU_JPEG_ENCODER,
+ .dec_offset = 0x400,
+ .dec_fmts = rk3399_vpu_dec_fmts,
+ .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
+ .codec = RK_VPU_JPEG_ENCODER | RK_VPU_MPEG2_DECODER,
.codec_ops = rk3399_vpu_codec_ops,
.vepu_irq = rk3399_vepu_irq,
+ .vdpu_irq = rk3399_vdpu_irq,
.init = rk3399_vpu_hw_init,
.clk_names = {"aclk", "hclk"},
.num_clocks = 2
diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c
new file mode 100644
index 000000000000..c4c092c2004a
--- /dev/null
+++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip VPU codec driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/bitfield.h>
+#include <media/v4l2-mem2mem.h>
+#include "rockchip_vpu.h"
+#include "rockchip_vpu_hw.h"
+
+#define VDPU_SWREG(nr) ((nr) * 4)
+
+#define VDPU_REG_DEC_OUT_BASE VDPU_SWREG(63)
+#define VDPU_REG_RLC_VLC_BASE VDPU_SWREG(64)
+#define VDPU_REG_QTABLE_BASE VDPU_SWREG(61)
+#define VDPU_REG_REFER0_BASE VDPU_SWREG(131)
+#define VDPU_REG_REFER2_BASE VDPU_SWREG(134)
+#define VDPU_REG_REFER3_BASE VDPU_SWREG(135)
+#define VDPU_REG_REFER1_BASE VDPU_SWREG(148)
+#define VDPU_REG_DEC_E(v) ((v) ? BIT(0) : 0)
+
+#define VDPU_REG_DEC_ADV_PRE_DIS(v) ((v) ? BIT(11) : 0)
+#define VDPU_REG_DEC_SCMD_DIS(v) ((v) ? BIT(10) : 0)
+#define VDPU_REG_FILTERING_DIS(v) ((v) ? BIT(8) : 0)
+#define VDPU_REG_DEC_LATENCY(v) (((v) << 1) & GENMASK(6, 1))
+
+#define VDPU_REG_INIT_QP(v) (((v) << 25) & GENMASK(30, 25))
+#define VDPU_REG_STREAM_LEN(v) (((v) << 0) & GENMASK(23, 0))
+
+#define VDPU_REG_APF_THRESHOLD(v) (((v) << 17) & GENMASK(30, 17))
+#define VDPU_REG_STARTMB_X(v) (((v) << 8) & GENMASK(16, 8))
+#define VDPU_REG_STARTMB_Y(v) (((v) << 0) & GENMASK(7, 0))
+
+#define VDPU_REG_DEC_MODE(v) (((v) << 0) & GENMASK(3, 0))
+
+#define VDPU_REG_DEC_STRENDIAN_E(v) ((v) ? BIT(5) : 0)
+#define VDPU_REG_DEC_STRSWAP32_E(v) ((v) ? BIT(4) : 0)
+#define VDPU_REG_DEC_OUTSWAP32_E(v) ((v) ? BIT(3) : 0)
+#define VDPU_REG_DEC_INSWAP32_E(v) ((v) ? BIT(2) : 0)
+#define VDPU_REG_DEC_OUT_ENDIAN(v) ((v) ? BIT(1) : 0)
+#define VDPU_REG_DEC_IN_ENDIAN(v) ((v) ? BIT(0) : 0)
+
+#define VDPU_REG_DEC_DATA_DISC_E(v) ((v) ? BIT(22) : 0)
+#define VDPU_REG_DEC_MAX_BURST(v) (((v) << 16) & GENMASK(20, 16))
+#define VDPU_REG_DEC_AXI_WR_ID(v) (((v) << 8) & GENMASK(15, 8))
+#define VDPU_REG_DEC_AXI_RD_ID(v) (((v) << 0) & GENMASK(7, 0))
+
+#define VDPU_REG_RLC_MODE_E(v) ((v) ? BIT(20) : 0)
+#define VDPU_REG_PIC_INTERLACE_E(v) ((v) ? BIT(17) : 0)
+#define VDPU_REG_PIC_FIELDMODE_E(v) ((v) ? BIT(16) : 0)
+#define VDPU_REG_PIC_B_E(v) ((v) ? BIT(15) : 0)
+#define VDPU_REG_PIC_INTER_E(v) ((v) ? BIT(14) : 0)
+#define VDPU_REG_PIC_TOPFIELD_E(v) ((v) ? BIT(13) : 0)
+#define VDPU_REG_FWD_INTERLACE_E(v) ((v) ? BIT(12) : 0)
+#define VDPU_REG_WRITE_MVS_E(v) ((v) ? BIT(10) : 0)
+#define VDPU_REG_DEC_TIMEOUT_E(v) ((v) ? BIT(5) : 0)
+#define VDPU_REG_DEC_CLK_GATE_E(v) ((v) ? BIT(4) : 0)
+
+#define VDPU_REG_PIC_MB_WIDTH(v) (((v) << 23) & GENMASK(31, 23))
+#define VDPU_REG_PIC_MB_HEIGHT_P(v) (((v) << 11) & GENMASK(18, 11))
+#define VDPU_REG_ALT_SCAN_E(v) ((v) ? BIT(6) : 0)
+#define VDPU_REG_TOPFIELDFIRST_E(v) ((v) ? BIT(5) : 0)
+
+#define VDPU_REG_STRM_START_BIT(v) (((v) << 26) & GENMASK(31, 26))
+#define VDPU_REG_QSCALE_TYPE(v) ((v) ? BIT(24) : 0)
+#define VDPU_REG_CON_MV_E(v) ((v) ? BIT(4) : 0)
+#define VDPU_REG_INTRA_DC_PREC(v) (((v) << 2) & GENMASK(3, 2))
+#define VDPU_REG_INTRA_VLC_TAB(v) ((v) ? BIT(1) : 0)
+#define VDPU_REG_FRAME_PRED_DCT(v) ((v) ? BIT(0) : 0)
+
+#define VDPU_REG_ALT_SCAN_FLAG_E(v) ((v) ? BIT(19) : 0)
+#define VDPU_REG_FCODE_FWD_HOR(v) (((v) << 15) & GENMASK(18, 15))
+#define VDPU_REG_FCODE_FWD_VER(v) (((v) << 11) & GENMASK(14, 11))
+#define VDPU_REG_FCODE_BWD_HOR(v) (((v) << 7) & GENMASK(10, 7))
+#define VDPU_REG_FCODE_BWD_VER(v) (((v) << 3) & GENMASK(6, 3))
+#define VDPU_REG_MV_ACCURACY_FWD(v) ((v) ? BIT(2) : 0)
+#define VDPU_REG_MV_ACCURACY_BWD(v) ((v) ? BIT(1) : 0)
+
+#define PICT_TOP_FIELD 1
+#define PICT_BOTTOM_FIELD 2
+#define PICT_FRAME 3
+
+static void
+rk3399_vpu_mpeg2_dec_set_quantization(struct rockchip_vpu_dev *vpu,
+ struct rockchip_vpu_ctx *ctx)
+{
+ struct v4l2_ctrl_mpeg2_quantization *quantization;
+
+ quantization = rockchip_vpu_get_ctrl(ctx,
+ V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
+ rockchip_vpu_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu,
+ quantization);
+ vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma,
+ VDPU_REG_QTABLE_BASE);
+}
+
+static void
+rk3399_vpu_mpeg2_dec_set_buffers(struct rockchip_vpu_dev *vpu,
+ struct rockchip_vpu_ctx *ctx,
+ struct vb2_buffer *src_buf,
+ struct vb2_buffer *dst_buf,
+ const struct v4l2_mpeg2_sequence *sequence,
+ const struct v4l2_mpeg2_picture *picture,
+ const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
+{
+ dma_addr_t forward_addr = 0, backward_addr = 0;
+ dma_addr_t current_addr, addr;
+ struct vb2_queue *vq;
+
+ vq = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
+
+ switch (picture->picture_coding_type) {
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+ backward_addr = rockchip_vpu_get_ref(vq,
+ slice_params->backward_ref_ts);
+ /* fall-through */
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
+ forward_addr = rockchip_vpu_get_ref(vq,
+ slice_params->forward_ref_ts);
+ }
+
+ /* Source bitstream buffer */
+ addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ vdpu_write_relaxed(vpu, addr, VDPU_REG_RLC_VLC_BASE);
+
+ /* Destination frame buffer */
+ addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ current_addr = addr;
+
+ if (picture->picture_structure == PICT_BOTTOM_FIELD)
+ addr += ALIGN(ctx->dst_fmt.width, 16);
+ vdpu_write_relaxed(vpu, addr, VDPU_REG_DEC_OUT_BASE);
+
+ if (!forward_addr)
+ forward_addr = current_addr;
+ if (!backward_addr)
+ backward_addr = current_addr;
+
+ /* Set forward ref frame (top/bottom field) */
+ if (picture->picture_structure == PICT_FRAME ||
+ picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
+ (picture->picture_structure == PICT_TOP_FIELD &&
+ picture->top_field_first) ||
+ (picture->picture_structure == PICT_BOTTOM_FIELD &&
+ !picture->top_field_first)) {
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
+ } else if (picture->picture_structure == PICT_TOP_FIELD) {
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
+ vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER1_BASE);
+ } else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
+ vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER0_BASE);
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
+ }
+
+ /* Set backward ref frame (top/bottom field) */
+ vdpu_write_relaxed(vpu, backward_addr, VDPU_REG_REFER2_BASE);
+ vdpu_write_relaxed(vpu, backward_addr, VDPU_REG_REFER3_BASE);
+}
+
+void rk3399_vpu_mpeg2_dec_run(struct rockchip_vpu_ctx *ctx)
+{
+ struct rockchip_vpu_dev *vpu = ctx->dev;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
+ const struct v4l2_mpeg2_sequence *sequence;
+ const struct v4l2_mpeg2_picture *picture;
+ u32 reg;
+
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+ /* Apply request controls if any */
+ v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
+ &ctx->ctrl_handler);
+
+ slice_params = rockchip_vpu_get_ctrl(ctx,
+ V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
+ sequence = &slice_params->sequence;
+ picture = &slice_params->picture;
+
+ reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
+ VDPU_REG_DEC_SCMD_DIS(0) |
+ VDPU_REG_FILTERING_DIS(1) |
+ VDPU_REG_DEC_LATENCY(0);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(50));
+
+ reg = VDPU_REG_INIT_QP(1) |
+ VDPU_REG_STREAM_LEN(slice_params->bit_size >> 3);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(51));
+
+ reg = VDPU_REG_APF_THRESHOLD(8) |
+ VDPU_REG_STARTMB_X(0) |
+ VDPU_REG_STARTMB_Y(0);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(52));
+
+ reg = VDPU_REG_DEC_MODE(5);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(53));
+
+ reg = VDPU_REG_DEC_STRENDIAN_E(1) |
+ VDPU_REG_DEC_STRSWAP32_E(1) |
+ VDPU_REG_DEC_OUTSWAP32_E(1) |
+ VDPU_REG_DEC_INSWAP32_E(1) |
+ VDPU_REG_DEC_OUT_ENDIAN(1) |
+ VDPU_REG_DEC_IN_ENDIAN(1);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(54));
+
+ reg = VDPU_REG_DEC_DATA_DISC_E(0) |
+ VDPU_REG_DEC_MAX_BURST(16) |
+ VDPU_REG_DEC_AXI_WR_ID(0) |
+ VDPU_REG_DEC_AXI_RD_ID(0);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56));
+
+ reg = VDPU_REG_RLC_MODE_E(0) |
+ VDPU_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
+ VDPU_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
+ VDPU_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
+ VDPU_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
+ VDPU_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
+ VDPU_REG_FWD_INTERLACE_E(0) |
+ VDPU_REG_WRITE_MVS_E(0) |
+ VDPU_REG_DEC_TIMEOUT_E(1) |
+ VDPU_REG_DEC_CLK_GATE_E(1);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(57));
+
+ reg = VDPU_REG_PIC_MB_WIDTH(MPEG2_MB_WIDTH(ctx->dst_fmt.width)) |
+ VDPU_REG_PIC_MB_HEIGHT_P(MPEG2_MB_HEIGHT(ctx->dst_fmt.height)) |
+ VDPU_REG_ALT_SCAN_E(picture->alternate_scan) |
+ VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120));
+
+ reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) |
+ VDPU_REG_QSCALE_TYPE(picture->q_scale_type) |
+ VDPU_REG_CON_MV_E(picture->concealment_motion_vectors) |
+ VDPU_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
+ VDPU_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
+ VDPU_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(122));
+
+ reg = VDPU_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
+ VDPU_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
+ VDPU_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
+ VDPU_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
+ VDPU_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
+ VDPU_REG_MV_ACCURACY_FWD(1) |
+ VDPU_REG_MV_ACCURACY_BWD(1);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136));
+
+ rk3399_vpu_mpeg2_dec_set_quantization(vpu, ctx);
+
+ rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
+ &dst_buf->vb2_buf,
+ sequence, picture, slice_params);
+
+ /* Controls no longer in-use, we can complete them */
+ v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
+ &ctx->ctrl_handler);
+
+ /* Kick the watchdog and start decoding */
+ schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000));
+
+ reg = vdpu_read(vpu, VDPU_SWREG(57)) | VDPU_REG_DEC_E(1);
+ vdpu_write(vpu, reg, VDPU_SWREG(57));
+}
diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h b/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h
index 1bdc5ceb956f..4268c3a8b924 100644
--- a/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h
+++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h
@@ -92,6 +92,7 @@ void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx);
int rockchip_vpu_jpeg_enc_init(struct rockchip_vpu_ctx *ctx);
void rockchip_vpu_jpeg_enc_exit(struct rockchip_vpu_ctx *ctx);
+void rk3399_vpu_mpeg2_dec_run(struct rockchip_vpu_ctx *ctx);
void rockchip_vpu_mpeg2_dec_copy_qtable(u8 *qtable,
const struct v4l2_ctrl_mpeg2_quantization *ctrl);
int rockchip_vpu_mpeg2_dec_init(struct rockchip_vpu_ctx *ctx);
--
2.20.1
WARNING: multiple messages have this Message-ID (diff)
From: Ezequiel Garcia <ezequiel@collabora.com>
To: linux-media@vger.kernel.org, Hans Verkuil <hans.verkuil@cisco.com>
Cc: kernel@collabora.com,
Nicolas Dufresne <nicolas.dufresne@collabora.com>,
Tomasz Figa <tfiga@chromium.org>,
linux-rockchip@lists.infradead.org,
Heiko Stuebner <heiko@sntech.de>, Jonas Karlman <jonas@kwiboo.se>,
Philipp Zabel <p.zabel@pengutronix.de>,
Boris Brezillon <boris.brezillon@collabora.com>
Subject: [PATCH v6 14/16] rockchip/vpu: Add MPEG2 decoding support to RK3399
Date: Tue, 28 May 2019 14:02:30 -0300 [thread overview]
Message-ID: <20190528170232.2091-15-ezequiel@collabora.com> (raw)
In-Reply-To: <20190528170232.2091-1-ezequiel@collabora.com>
From: Jonas Karlman <jonas@kwiboo.se>
Add the necessary bits to support MPEG2 decoding on RK3399.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
Changes from v4:
* Stop including rockchip_vpu_common.h
Changes from v3:
* New patch (was part of another patch before)
drivers/staging/media/rockchip/vpu/Makefile | 1 +
.../media/rockchip/vpu/rk3399_vpu_hw.c | 59 +++-
.../rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c | 267 ++++++++++++++++++
.../media/rockchip/vpu/rockchip_vpu_hw.h | 1 +
4 files changed, 327 insertions(+), 1 deletion(-)
create mode 100644 drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c
diff --git a/drivers/staging/media/rockchip/vpu/Makefile b/drivers/staging/media/rockchip/vpu/Makefile
index b3144e4f9d33..c742754a89a5 100644
--- a/drivers/staging/media/rockchip/vpu/Makefile
+++ b/drivers/staging/media/rockchip/vpu/Makefile
@@ -8,5 +8,6 @@ rockchip-vpu-y += \
rk3288_vpu_hw_jpeg_enc.o \
rk3399_vpu_hw.o \
rk3399_vpu_hw_jpeg_enc.o \
+ rk3399_vpu_hw_mpeg2_dec.o \
rockchip_vpu_jpeg.o \
rockchip_vpu_mpeg2.o
diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c
index 5c6c1e8b36d6..2b3689968ef4 100644
--- a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c
+++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c
@@ -55,6 +55,26 @@ static const struct rockchip_vpu_fmt rk3399_vpu_enc_fmts[] = {
},
};
+static const struct rockchip_vpu_fmt rk3399_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = RK_VPU_MODE_NONE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
+ .codec_mode = RK_VPU_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+ .min_width = 48,
+ .max_width = 1920,
+ .step_width = MPEG2_MB_DIM,
+ .min_height = 48,
+ .max_height = 1088,
+ .step_height = MPEG2_MB_DIM,
+ },
+ },
+};
+
static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id)
{
struct rockchip_vpu_dev *vpu = dev_id;
@@ -74,6 +94,24 @@ static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t rk3399_vdpu_irq(int irq, void *dev_id)
+{
+ struct rockchip_vpu_dev *vpu = dev_id;
+ enum vb2_buffer_state state;
+ u32 status;
+
+ status = vdpu_read(vpu, VDPU_REG_INTERRUPT);
+ state = (status & VDPU_REG_INTERRUPT_DEC_IRQ) ?
+ VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
+
+ vdpu_write(vpu, 0, VDPU_REG_INTERRUPT);
+ vdpu_write(vpu, 0, VDPU_REG_AXI_CTRL);
+
+ rockchip_vpu_irq_done(vpu, 0, state);
+
+ return IRQ_HANDLED;
+}
+
static int rk3399_vpu_hw_init(struct rockchip_vpu_dev *vpu)
{
/* Bump ACLK to max. possible freq. to improve performance. */
@@ -90,6 +128,15 @@ static void rk3399_vpu_enc_reset(struct rockchip_vpu_ctx *ctx)
vepu_write(vpu, 0, VEPU_REG_AXI_CTRL);
}
+static void rk3399_vpu_dec_reset(struct rockchip_vpu_ctx *ctx)
+{
+ struct rockchip_vpu_dev *vpu = ctx->dev;
+
+ vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT);
+ vdpu_write(vpu, 0, VDPU_REG_EN_FLAGS);
+ vdpu_write(vpu, 1, VDPU_REG_SOFT_RESET);
+}
+
/*
* Supported codec ops.
*/
@@ -101,6 +148,12 @@ static const struct rockchip_vpu_codec_ops rk3399_vpu_codec_ops[] = {
.init = rockchip_vpu_jpeg_enc_init,
.exit = rockchip_vpu_jpeg_enc_exit,
},
+ [RK_VPU_MODE_MPEG2_DEC] = {
+ .run = rk3399_vpu_mpeg2_dec_run,
+ .reset = rk3399_vpu_dec_reset,
+ .init = rockchip_vpu_mpeg2_dec_init,
+ .exit = rockchip_vpu_mpeg2_dec_exit,
+ },
};
/*
@@ -111,9 +164,13 @@ const struct rockchip_vpu_variant rk3399_vpu_variant = {
.enc_offset = 0x0,
.enc_fmts = rk3399_vpu_enc_fmts,
.num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts),
- .codec = RK_VPU_JPEG_ENCODER,
+ .dec_offset = 0x400,
+ .dec_fmts = rk3399_vpu_dec_fmts,
+ .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
+ .codec = RK_VPU_JPEG_ENCODER | RK_VPU_MPEG2_DECODER,
.codec_ops = rk3399_vpu_codec_ops,
.vepu_irq = rk3399_vepu_irq,
+ .vdpu_irq = rk3399_vdpu_irq,
.init = rk3399_vpu_hw_init,
.clk_names = {"aclk", "hclk"},
.num_clocks = 2
diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c
new file mode 100644
index 000000000000..c4c092c2004a
--- /dev/null
+++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_mpeg2_dec.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip VPU codec driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/bitfield.h>
+#include <media/v4l2-mem2mem.h>
+#include "rockchip_vpu.h"
+#include "rockchip_vpu_hw.h"
+
+#define VDPU_SWREG(nr) ((nr) * 4)
+
+#define VDPU_REG_DEC_OUT_BASE VDPU_SWREG(63)
+#define VDPU_REG_RLC_VLC_BASE VDPU_SWREG(64)
+#define VDPU_REG_QTABLE_BASE VDPU_SWREG(61)
+#define VDPU_REG_REFER0_BASE VDPU_SWREG(131)
+#define VDPU_REG_REFER2_BASE VDPU_SWREG(134)
+#define VDPU_REG_REFER3_BASE VDPU_SWREG(135)
+#define VDPU_REG_REFER1_BASE VDPU_SWREG(148)
+#define VDPU_REG_DEC_E(v) ((v) ? BIT(0) : 0)
+
+#define VDPU_REG_DEC_ADV_PRE_DIS(v) ((v) ? BIT(11) : 0)
+#define VDPU_REG_DEC_SCMD_DIS(v) ((v) ? BIT(10) : 0)
+#define VDPU_REG_FILTERING_DIS(v) ((v) ? BIT(8) : 0)
+#define VDPU_REG_DEC_LATENCY(v) (((v) << 1) & GENMASK(6, 1))
+
+#define VDPU_REG_INIT_QP(v) (((v) << 25) & GENMASK(30, 25))
+#define VDPU_REG_STREAM_LEN(v) (((v) << 0) & GENMASK(23, 0))
+
+#define VDPU_REG_APF_THRESHOLD(v) (((v) << 17) & GENMASK(30, 17))
+#define VDPU_REG_STARTMB_X(v) (((v) << 8) & GENMASK(16, 8))
+#define VDPU_REG_STARTMB_Y(v) (((v) << 0) & GENMASK(7, 0))
+
+#define VDPU_REG_DEC_MODE(v) (((v) << 0) & GENMASK(3, 0))
+
+#define VDPU_REG_DEC_STRENDIAN_E(v) ((v) ? BIT(5) : 0)
+#define VDPU_REG_DEC_STRSWAP32_E(v) ((v) ? BIT(4) : 0)
+#define VDPU_REG_DEC_OUTSWAP32_E(v) ((v) ? BIT(3) : 0)
+#define VDPU_REG_DEC_INSWAP32_E(v) ((v) ? BIT(2) : 0)
+#define VDPU_REG_DEC_OUT_ENDIAN(v) ((v) ? BIT(1) : 0)
+#define VDPU_REG_DEC_IN_ENDIAN(v) ((v) ? BIT(0) : 0)
+
+#define VDPU_REG_DEC_DATA_DISC_E(v) ((v) ? BIT(22) : 0)
+#define VDPU_REG_DEC_MAX_BURST(v) (((v) << 16) & GENMASK(20, 16))
+#define VDPU_REG_DEC_AXI_WR_ID(v) (((v) << 8) & GENMASK(15, 8))
+#define VDPU_REG_DEC_AXI_RD_ID(v) (((v) << 0) & GENMASK(7, 0))
+
+#define VDPU_REG_RLC_MODE_E(v) ((v) ? BIT(20) : 0)
+#define VDPU_REG_PIC_INTERLACE_E(v) ((v) ? BIT(17) : 0)
+#define VDPU_REG_PIC_FIELDMODE_E(v) ((v) ? BIT(16) : 0)
+#define VDPU_REG_PIC_B_E(v) ((v) ? BIT(15) : 0)
+#define VDPU_REG_PIC_INTER_E(v) ((v) ? BIT(14) : 0)
+#define VDPU_REG_PIC_TOPFIELD_E(v) ((v) ? BIT(13) : 0)
+#define VDPU_REG_FWD_INTERLACE_E(v) ((v) ? BIT(12) : 0)
+#define VDPU_REG_WRITE_MVS_E(v) ((v) ? BIT(10) : 0)
+#define VDPU_REG_DEC_TIMEOUT_E(v) ((v) ? BIT(5) : 0)
+#define VDPU_REG_DEC_CLK_GATE_E(v) ((v) ? BIT(4) : 0)
+
+#define VDPU_REG_PIC_MB_WIDTH(v) (((v) << 23) & GENMASK(31, 23))
+#define VDPU_REG_PIC_MB_HEIGHT_P(v) (((v) << 11) & GENMASK(18, 11))
+#define VDPU_REG_ALT_SCAN_E(v) ((v) ? BIT(6) : 0)
+#define VDPU_REG_TOPFIELDFIRST_E(v) ((v) ? BIT(5) : 0)
+
+#define VDPU_REG_STRM_START_BIT(v) (((v) << 26) & GENMASK(31, 26))
+#define VDPU_REG_QSCALE_TYPE(v) ((v) ? BIT(24) : 0)
+#define VDPU_REG_CON_MV_E(v) ((v) ? BIT(4) : 0)
+#define VDPU_REG_INTRA_DC_PREC(v) (((v) << 2) & GENMASK(3, 2))
+#define VDPU_REG_INTRA_VLC_TAB(v) ((v) ? BIT(1) : 0)
+#define VDPU_REG_FRAME_PRED_DCT(v) ((v) ? BIT(0) : 0)
+
+#define VDPU_REG_ALT_SCAN_FLAG_E(v) ((v) ? BIT(19) : 0)
+#define VDPU_REG_FCODE_FWD_HOR(v) (((v) << 15) & GENMASK(18, 15))
+#define VDPU_REG_FCODE_FWD_VER(v) (((v) << 11) & GENMASK(14, 11))
+#define VDPU_REG_FCODE_BWD_HOR(v) (((v) << 7) & GENMASK(10, 7))
+#define VDPU_REG_FCODE_BWD_VER(v) (((v) << 3) & GENMASK(6, 3))
+#define VDPU_REG_MV_ACCURACY_FWD(v) ((v) ? BIT(2) : 0)
+#define VDPU_REG_MV_ACCURACY_BWD(v) ((v) ? BIT(1) : 0)
+
+#define PICT_TOP_FIELD 1
+#define PICT_BOTTOM_FIELD 2
+#define PICT_FRAME 3
+
+static void
+rk3399_vpu_mpeg2_dec_set_quantization(struct rockchip_vpu_dev *vpu,
+ struct rockchip_vpu_ctx *ctx)
+{
+ struct v4l2_ctrl_mpeg2_quantization *quantization;
+
+ quantization = rockchip_vpu_get_ctrl(ctx,
+ V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
+ rockchip_vpu_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu,
+ quantization);
+ vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma,
+ VDPU_REG_QTABLE_BASE);
+}
+
+static void
+rk3399_vpu_mpeg2_dec_set_buffers(struct rockchip_vpu_dev *vpu,
+ struct rockchip_vpu_ctx *ctx,
+ struct vb2_buffer *src_buf,
+ struct vb2_buffer *dst_buf,
+ const struct v4l2_mpeg2_sequence *sequence,
+ const struct v4l2_mpeg2_picture *picture,
+ const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
+{
+ dma_addr_t forward_addr = 0, backward_addr = 0;
+ dma_addr_t current_addr, addr;
+ struct vb2_queue *vq;
+
+ vq = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
+
+ switch (picture->picture_coding_type) {
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+ backward_addr = rockchip_vpu_get_ref(vq,
+ slice_params->backward_ref_ts);
+ /* fall-through */
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
+ forward_addr = rockchip_vpu_get_ref(vq,
+ slice_params->forward_ref_ts);
+ }
+
+ /* Source bitstream buffer */
+ addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ vdpu_write_relaxed(vpu, addr, VDPU_REG_RLC_VLC_BASE);
+
+ /* Destination frame buffer */
+ addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ current_addr = addr;
+
+ if (picture->picture_structure == PICT_BOTTOM_FIELD)
+ addr += ALIGN(ctx->dst_fmt.width, 16);
+ vdpu_write_relaxed(vpu, addr, VDPU_REG_DEC_OUT_BASE);
+
+ if (!forward_addr)
+ forward_addr = current_addr;
+ if (!backward_addr)
+ backward_addr = current_addr;
+
+ /* Set forward ref frame (top/bottom field) */
+ if (picture->picture_structure == PICT_FRAME ||
+ picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
+ (picture->picture_structure == PICT_TOP_FIELD &&
+ picture->top_field_first) ||
+ (picture->picture_structure == PICT_BOTTOM_FIELD &&
+ !picture->top_field_first)) {
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
+ } else if (picture->picture_structure == PICT_TOP_FIELD) {
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
+ vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER1_BASE);
+ } else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
+ vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER0_BASE);
+ vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
+ }
+
+ /* Set backward ref frame (top/bottom field) */
+ vdpu_write_relaxed(vpu, backward_addr, VDPU_REG_REFER2_BASE);
+ vdpu_write_relaxed(vpu, backward_addr, VDPU_REG_REFER3_BASE);
+}
+
+void rk3399_vpu_mpeg2_dec_run(struct rockchip_vpu_ctx *ctx)
+{
+ struct rockchip_vpu_dev *vpu = ctx->dev;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
+ const struct v4l2_mpeg2_sequence *sequence;
+ const struct v4l2_mpeg2_picture *picture;
+ u32 reg;
+
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+ /* Apply request controls if any */
+ v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
+ &ctx->ctrl_handler);
+
+ slice_params = rockchip_vpu_get_ctrl(ctx,
+ V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
+ sequence = &slice_params->sequence;
+ picture = &slice_params->picture;
+
+ reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
+ VDPU_REG_DEC_SCMD_DIS(0) |
+ VDPU_REG_FILTERING_DIS(1) |
+ VDPU_REG_DEC_LATENCY(0);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(50));
+
+ reg = VDPU_REG_INIT_QP(1) |
+ VDPU_REG_STREAM_LEN(slice_params->bit_size >> 3);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(51));
+
+ reg = VDPU_REG_APF_THRESHOLD(8) |
+ VDPU_REG_STARTMB_X(0) |
+ VDPU_REG_STARTMB_Y(0);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(52));
+
+ reg = VDPU_REG_DEC_MODE(5);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(53));
+
+ reg = VDPU_REG_DEC_STRENDIAN_E(1) |
+ VDPU_REG_DEC_STRSWAP32_E(1) |
+ VDPU_REG_DEC_OUTSWAP32_E(1) |
+ VDPU_REG_DEC_INSWAP32_E(1) |
+ VDPU_REG_DEC_OUT_ENDIAN(1) |
+ VDPU_REG_DEC_IN_ENDIAN(1);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(54));
+
+ reg = VDPU_REG_DEC_DATA_DISC_E(0) |
+ VDPU_REG_DEC_MAX_BURST(16) |
+ VDPU_REG_DEC_AXI_WR_ID(0) |
+ VDPU_REG_DEC_AXI_RD_ID(0);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56));
+
+ reg = VDPU_REG_RLC_MODE_E(0) |
+ VDPU_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
+ VDPU_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
+ VDPU_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
+ VDPU_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
+ VDPU_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
+ VDPU_REG_FWD_INTERLACE_E(0) |
+ VDPU_REG_WRITE_MVS_E(0) |
+ VDPU_REG_DEC_TIMEOUT_E(1) |
+ VDPU_REG_DEC_CLK_GATE_E(1);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(57));
+
+ reg = VDPU_REG_PIC_MB_WIDTH(MPEG2_MB_WIDTH(ctx->dst_fmt.width)) |
+ VDPU_REG_PIC_MB_HEIGHT_P(MPEG2_MB_HEIGHT(ctx->dst_fmt.height)) |
+ VDPU_REG_ALT_SCAN_E(picture->alternate_scan) |
+ VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120));
+
+ reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) |
+ VDPU_REG_QSCALE_TYPE(picture->q_scale_type) |
+ VDPU_REG_CON_MV_E(picture->concealment_motion_vectors) |
+ VDPU_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
+ VDPU_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
+ VDPU_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(122));
+
+ reg = VDPU_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
+ VDPU_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
+ VDPU_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
+ VDPU_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
+ VDPU_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
+ VDPU_REG_MV_ACCURACY_FWD(1) |
+ VDPU_REG_MV_ACCURACY_BWD(1);
+ vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136));
+
+ rk3399_vpu_mpeg2_dec_set_quantization(vpu, ctx);
+
+ rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
+ &dst_buf->vb2_buf,
+ sequence, picture, slice_params);
+
+ /* Controls no longer in-use, we can complete them */
+ v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
+ &ctx->ctrl_handler);
+
+ /* Kick the watchdog and start decoding */
+ schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000));
+
+ reg = vdpu_read(vpu, VDPU_SWREG(57)) | VDPU_REG_DEC_E(1);
+ vdpu_write(vpu, reg, VDPU_SWREG(57));
+}
diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h b/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h
index 1bdc5ceb956f..4268c3a8b924 100644
--- a/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h
+++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h
@@ -92,6 +92,7 @@ void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx);
int rockchip_vpu_jpeg_enc_init(struct rockchip_vpu_ctx *ctx);
void rockchip_vpu_jpeg_enc_exit(struct rockchip_vpu_ctx *ctx);
+void rk3399_vpu_mpeg2_dec_run(struct rockchip_vpu_ctx *ctx);
void rockchip_vpu_mpeg2_dec_copy_qtable(u8 *qtable,
const struct v4l2_ctrl_mpeg2_quantization *ctrl);
int rockchip_vpu_mpeg2_dec_init(struct rockchip_vpu_ctx *ctx);
--
2.20.1
next prev parent reply other threads:[~2019-05-28 17:02 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-28 17:02 [PATCH v6 00/16] Add MPEG-2 decoding to Rockchip VPU Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
[not found] ` <20190528170232.2091-1-ezequiel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-28 17:02 ` [PATCH v6 01/16] media: v4l2-common: Fix v4l2_fill_pixfmt[_mp]() prototypes Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 02/16] media: v4l2-common: Add an helper to apply frmsize constraints Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 03/16] media: v4l2-common: Support custom imagesize in fill_pixfmt() Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
[not found] ` <20190528170232.2091-4-ezequiel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 11:28 ` Mauro Carvalho Chehab
2019-05-29 11:28 ` Mauro Carvalho Chehab
[not found] ` <20190529082809.0b9f3553-qA1ZUp+OV9c@public.gmane.org>
2019-05-29 11:43 ` Hans Verkuil
2019-05-29 11:43 ` Hans Verkuil
[not found] ` <cc51be76-81c3-1c54-2005-1b99d00a8ac1-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
2019-05-29 11:58 ` Mauro Carvalho Chehab
2019-05-29 11:58 ` Mauro Carvalho Chehab
[not found] ` <20190529085854.6c689f8d-qA1ZUp+OV9c@public.gmane.org>
2019-05-29 12:16 ` Boris Brezillon
2019-05-29 12:16 ` Boris Brezillon
[not found] ` <20190529141633.19c5079b-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 12:26 ` Mauro Carvalho Chehab
2019-05-29 12:26 ` Mauro Carvalho Chehab
[not found] ` <20190529092632.779f5f1b-qA1ZUp+OV9c@public.gmane.org>
2019-05-29 12:29 ` Mauro Carvalho Chehab
2019-05-29 12:29 ` Mauro Carvalho Chehab
2019-05-29 12:31 ` Boris Brezillon
2019-05-29 12:31 ` Boris Brezillon
2019-05-29 12:31 ` Hans Verkuil
2019-05-29 12:31 ` Hans Verkuil
[not found] ` <223a757d-f008-398c-64ce-18b0aaf390c5-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
2019-05-29 12:39 ` Boris Brezillon
2019-05-29 12:39 ` Boris Brezillon
2019-05-29 14:04 ` Ezequiel Garcia
2019-05-29 14:04 ` Ezequiel Garcia
[not found] ` <04cb574b530c987a04b098962c93940c49e944d8.camel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 14:06 ` Boris Brezillon
2019-05-29 14:06 ` Boris Brezillon
[not found] ` <20190529160610.169c6e00-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 14:17 ` Boris Brezillon
2019-05-29 14:17 ` Boris Brezillon
[not found] ` <20190529161753.7ffa5276-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 14:47 ` Ezequiel Garcia
2019-05-29 14:47 ` Ezequiel Garcia
2019-05-29 13:54 ` Nicolas Dufresne
2019-05-29 13:54 ` Nicolas Dufresne
[not found] ` <4ef64e22f4035fccf09fbb7f0be04a9778b1230d.camel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 14:02 ` Mauro Carvalho Chehab
2019-05-29 14:02 ` Mauro Carvalho Chehab
2019-05-28 17:02 ` [PATCH v6 04/16] rockchip/vpu: Use v4l2_apply_frmsize_constraints() where appropriate Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 05/16] rockchip/vpu: Open-code media controller register Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 06/16] rockchip/vpu: Support the Request API Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 07/16] rockchip/vpu: Rename rockchip_vpu_common.h into rockchip_vpu_v4l2.h Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 08/16] rockchip/vpu: Move encoder logic to a common place Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 09/16] rockchip/vpu: Provide a helper to reset both src and dst formats Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 10/16] rockchip/vpu: Prepare things to support decoders Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 11/16] rockchip/vpu: Add decoder boilerplate Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 12/16] rockchip/vpu: Add support for non-standard controls Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 13/16] rockchip/vpu: Add infra to support MPEG-2 decoding Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia [this message]
2019-05-28 17:02 ` [PATCH v6 14/16] rockchip/vpu: Add MPEG2 decoding support to RK3399 Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 15/16] rockchip/vpu: Add support for MPEG-2 decoding on RK3288 Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
2019-05-28 17:02 ` [PATCH v6 16/16] rockchip/vpu: Add support for MPEG-2 decoding on RK3328 Ezequiel Garcia
2019-05-28 17:02 ` Ezequiel Garcia
[not found] ` <20190528170232.2091-17-ezequiel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2019-05-29 8:11 ` Hans Verkuil
2019-05-29 8:11 ` Hans Verkuil
[not found] ` <2ef056a2-e9dc-52b1-855b-2bef759af9b6-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
2019-05-29 8:50 ` Jonas Karlman
2019-05-29 8:50 ` Jonas Karlman
[not found] ` <VI1PR03MB42066B8C9F364ACF7CFFF241AC1F0-269e4kb9IIlWSsgAM8bhN8eAHadYHfrlvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2019-05-29 9:00 ` Hans Verkuil
2019-05-29 9:00 ` Hans Verkuil
2019-05-29 14:59 ` Ezequiel Garcia
2019-05-29 14:59 ` Ezequiel Garcia
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190528170232.2091-15-ezequiel@collabora.com \
--to=ezequiel-zgy8ohtn/8qb+jhodadfcq@public.gmane.org \
--cc=boris.brezillon-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org \
--cc=hans.verkuil-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org \
--cc=heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org \
--cc=jonas-uIzNG4q0ceqzQB+pC5nmwQ@public.gmane.org \
--cc=kernel-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org \
--cc=linux-media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=nicolas.dufresne-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org \
--cc=p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
--cc=tfiga-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.