mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
1442 lines
47 KiB
Diff
1442 lines
47 KiB
Diff
From 782a01dbdaf289bfdd63b55c67a984956239d362 Mon Sep 17 00:00:00 2001
|
|
From: Detlev Casanova <detlev.casanova@collabora.com>
|
|
Date: Tue, 27 May 2025 11:00:22 -0400
|
|
Subject: [PATCH 067/110] DETLEV(v3): media: rkvdec: Switch to using structs
|
|
instead of writel
|
|
|
|
In an effort to merge the rkvdec2 driver [1] with this one, switch from
|
|
writel() calls to using structs to represent the register mappings.
|
|
|
|
This is done in order to have all supported decoders use the same format
|
|
in the future and ease reading of the code.
|
|
|
|
Using structs also improves stability as the hardware is tested and
|
|
validated downstream using a similar method.
|
|
It was noticed, on decoders, that:
|
|
- Some registers require to be writen in increasing order [2]
|
|
- Some registers, even if unrelated, need to be written to their reset
|
|
values (it was the case here for axi_ddr_[rw]data).
|
|
|
|
Using structs can also help improving performance later when, e.g.
|
|
multicore support is added on RK3588.
|
|
|
|
Performance seems to be slightly improved, but at least, not made worse.
|
|
Running fluster's JVT-AVC_V1 test suite with GStreamer on the Radxa ROCK
|
|
PI 4 SE gives the following times:
|
|
|
|
Before this patch:
|
|
|
|
- --jobs 1: Ran 129/135 tests successfully in 77.167 secs
|
|
- --jobs 6: Ran 129/135 tests successfully in 23.046 secs
|
|
|
|
With this patch:
|
|
- --jobs 1: Ran 129/135 tests successfully in 70.698 secs
|
|
- --jobs 6: Ran 129/135 tests successfully in 22.917 secs
|
|
|
|
This also shows that the fluster score hasn't changed.
|
|
|
|
[1]: https://lore.kernel.org/all/20250325213303.826925-1-detlev.casanova@collabora.com/
|
|
[2]: https://lore.kernel.org/all/20200127143009.15677-5-andrzej.p@collabora.com/
|
|
|
|
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
|
|
---
|
|
.../platform/rockchip/rkvdec/rkvdec-h264.c | 165 +++--
|
|
.../platform/rockchip/rkvdec/rkvdec-hevc.c | 66 +-
|
|
.../platform/rockchip/rkvdec/rkvdec-regs.h | 571 ++++++++++++------
|
|
.../platform/rockchip/rkvdec/rkvdec-vp9.c | 231 +++----
|
|
.../media/platform/rockchip/rkvdec/rkvdec.c | 10 +-
|
|
.../media/platform/rockchip/rkvdec/rkvdec.h | 1 +
|
|
6 files changed, 589 insertions(+), 455 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
|
|
index d14b4d173448..1adb2e1f5f0e 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
|
|
@@ -115,6 +115,7 @@ struct rkvdec_h264_run {
|
|
struct rkvdec_h264_ctx {
|
|
struct rkvdec_aux_buf priv_tbl;
|
|
struct rkvdec_h264_reflists reflists;
|
|
+ struct rkvdec_regs regs;
|
|
};
|
|
|
|
#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n, \
|
|
@@ -841,45 +842,41 @@ static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
|
|
}
|
|
|
|
/*
|
|
- * dpb poc related registers table
|
|
+ * Set the ref POC in the correct register.
|
|
+ *
|
|
+ * The 32 registers are spread across 3 regions, each alternating top and bottom ref POCs:
|
|
+ * - 1: ref 0 to 14 contain top 0 to 7 and bottoms 0 to 6
|
|
+ * - 2: ref 15 to 29 contain top 8 to 14 and bottoms 7 to 14
|
|
+ * - 3: ref 30 and 31 which correspond to top 15 and bottom 15 respectively.
|
|
*/
|
|
-static const u32 poc_reg_tbl_top_field[16] = {
|
|
- RKVDEC_REG_H264_POC_REFER0(0),
|
|
- RKVDEC_REG_H264_POC_REFER0(2),
|
|
- RKVDEC_REG_H264_POC_REFER0(4),
|
|
- RKVDEC_REG_H264_POC_REFER0(6),
|
|
- RKVDEC_REG_H264_POC_REFER0(8),
|
|
- RKVDEC_REG_H264_POC_REFER0(10),
|
|
- RKVDEC_REG_H264_POC_REFER0(12),
|
|
- RKVDEC_REG_H264_POC_REFER0(14),
|
|
- RKVDEC_REG_H264_POC_REFER1(1),
|
|
- RKVDEC_REG_H264_POC_REFER1(3),
|
|
- RKVDEC_REG_H264_POC_REFER1(5),
|
|
- RKVDEC_REG_H264_POC_REFER1(7),
|
|
- RKVDEC_REG_H264_POC_REFER1(9),
|
|
- RKVDEC_REG_H264_POC_REFER1(11),
|
|
- RKVDEC_REG_H264_POC_REFER1(13),
|
|
- RKVDEC_REG_H264_POC_REFER2(0)
|
|
-};
|
|
-
|
|
-static const u32 poc_reg_tbl_bottom_field[16] = {
|
|
- RKVDEC_REG_H264_POC_REFER0(1),
|
|
- RKVDEC_REG_H264_POC_REFER0(3),
|
|
- RKVDEC_REG_H264_POC_REFER0(5),
|
|
- RKVDEC_REG_H264_POC_REFER0(7),
|
|
- RKVDEC_REG_H264_POC_REFER0(9),
|
|
- RKVDEC_REG_H264_POC_REFER0(11),
|
|
- RKVDEC_REG_H264_POC_REFER0(13),
|
|
- RKVDEC_REG_H264_POC_REFER1(0),
|
|
- RKVDEC_REG_H264_POC_REFER1(2),
|
|
- RKVDEC_REG_H264_POC_REFER1(4),
|
|
- RKVDEC_REG_H264_POC_REFER1(6),
|
|
- RKVDEC_REG_H264_POC_REFER1(8),
|
|
- RKVDEC_REG_H264_POC_REFER1(10),
|
|
- RKVDEC_REG_H264_POC_REFER1(12),
|
|
- RKVDEC_REG_H264_POC_REFER1(14),
|
|
- RKVDEC_REG_H264_POC_REFER2(1)
|
|
-};
|
|
+static void set_poc_reg(struct rkvdec_regs *regs, uint32_t poc, int id, bool bottom)
|
|
+{
|
|
+ if (!bottom) {
|
|
+ switch (id) {
|
|
+ case 0 ... 7:
|
|
+ regs->h264.ref0_14_poc[id * 2] = poc;
|
|
+ break;
|
|
+ case 8 ... 14:
|
|
+ regs->h264.ref15_29_poc[(id - 8) * 2 + 1] = poc;
|
|
+ break;
|
|
+ case 15:
|
|
+ regs->h264.ref30_poc = poc;
|
|
+ break;
|
|
+ }
|
|
+ } else {
|
|
+ switch (id) {
|
|
+ case 0 ... 6:
|
|
+ regs->h264.ref0_14_poc[id * 2 + 1] = poc;
|
|
+ break;
|
|
+ case 7 ... 14:
|
|
+ regs->h264.ref15_29_poc[(id - 7) * 2] = poc;
|
|
+ break;
|
|
+ case 15:
|
|
+ regs->h264.ref31_poc = poc;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
|
|
static void config_registers(struct rkvdec_ctx *ctx,
|
|
struct rkvdec_h264_run *run)
|
|
@@ -894,6 +891,7 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
|
|
struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
|
|
const struct v4l2_format *f;
|
|
+ struct rkvdec_regs *regs = &h264_ctx->regs;
|
|
dma_addr_t rlc_addr;
|
|
dma_addr_t refer_addr;
|
|
u32 rlc_len;
|
|
@@ -903,10 +901,11 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
u32 yuv_virstride = 0;
|
|
u32 offset;
|
|
dma_addr_t dst_addr;
|
|
- u32 reg, i;
|
|
+ u32 i;
|
|
|
|
- reg = RKVDEC_MODE(RKVDEC_MODE_H264);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL);
|
|
+ memset(regs, 0, sizeof(*regs));
|
|
+
|
|
+ regs->common.reg02.dec_mode = RKVDEC_MODE_H264;
|
|
|
|
f = &ctx->decoded_fmt;
|
|
dst_fmt = &f->fmt.pix_mp;
|
|
@@ -921,39 +920,35 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
else if (sps->chroma_format_idc == 2)
|
|
yuv_virstride = 2 * y_virstride;
|
|
|
|
- reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) |
|
|
- RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) |
|
|
- RKVDEC_SLICE_NUM_HIGHBIT |
|
|
- RKVDEC_SLICE_NUM_LOWBITS(0x7ff);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_PICPAR);
|
|
+ regs->common.reg03.uv_hor_virstride = hor_virstride / 16;
|
|
+ regs->common.reg03.y_hor_virstride = hor_virstride / 16;
|
|
+ regs->common.reg03.slice_num_highbit = 1;
|
|
+ regs->common.reg03.slice_num_lowbits = 0x7ff;
|
|
|
|
/* config rlc base address */
|
|
rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
|
|
- writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
|
|
- writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_RLCWRITE_BASE);
|
|
+ regs->common.strm_rlc_base = rlc_addr;
|
|
+ regs->h264.rlcwrite_base = rlc_addr;
|
|
|
|
rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
|
|
- reg = RKVDEC_STRM_LEN(rlc_len);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN);
|
|
+ regs->common.stream_len = rlc_len;
|
|
|
|
/* config cabac table */
|
|
offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
|
|
+ regs->common.cabactbl_base = priv_start_addr + offset;
|
|
|
|
/* config output base address */
|
|
dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
|
|
- writel_relaxed(dst_addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
|
|
+ regs->common.decout_base = dst_addr;
|
|
|
|
- reg = RKVDEC_Y_VIRSTRIDE(y_virstride / 16);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
|
|
+ regs->common.reg08.y_virstride = y_virstride / 16;
|
|
|
|
- reg = RKVDEC_YUV_VIRSTRIDE(yuv_virstride / 16);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
|
|
+ regs->common.reg09.yuv_virstride = yuv_virstride / 16;
|
|
|
|
/* config ref pic address & poc */
|
|
for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
|
|
struct vb2_buffer *vb_buf = run->ref_buf[i];
|
|
+ struct ref_base *base;
|
|
|
|
/*
|
|
* If a DPB entry is unused or invalid, address of current destination
|
|
@@ -963,54 +958,36 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
vb_buf = &dst_buf->vb2_buf;
|
|
refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
|
|
|
|
- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
|
- refer_addr |= RKVDEC_COLMV_USED_FLAG_REF;
|
|
- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)
|
|
- refer_addr |= RKVDEC_FIELD_REF;
|
|
-
|
|
- if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF)
|
|
- refer_addr |= RKVDEC_TOPFIELD_USED_REF;
|
|
- if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)
|
|
- refer_addr |= RKVDEC_BOTFIELD_USED_REF;
|
|
-
|
|
- writel_relaxed(dpb[i].top_field_order_cnt,
|
|
- rkvdec->regs + poc_reg_tbl_top_field[i]);
|
|
- writel_relaxed(dpb[i].bottom_field_order_cnt,
|
|
- rkvdec->regs + poc_reg_tbl_bottom_field[i]);
|
|
-
|
|
if (i < V4L2_H264_NUM_DPB_ENTRIES - 1)
|
|
- writel_relaxed(refer_addr,
|
|
- rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i));
|
|
+ base = ®s->h264.ref0_14_base[i];
|
|
else
|
|
- writel_relaxed(refer_addr,
|
|
- rkvdec->regs + RKVDEC_REG_H264_BASE_REFER15);
|
|
- }
|
|
+ base = ®s->h264.ref15_base;
|
|
|
|
- reg = RKVDEC_CUR_POC(dec_params->top_field_order_cnt);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0);
|
|
+ base->field_ref = !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD);
|
|
+ base->colmv_used_flag_ref = !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE);
|
|
+ base->topfield_used_ref = !!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF);
|
|
+ base->botfield_used_ref = !!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF);
|
|
+ base->base_addr = refer_addr >> 4;
|
|
|
|
- reg = RKVDEC_CUR_POC(dec_params->bottom_field_order_cnt);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC1);
|
|
+ set_poc_reg(regs, dpb[i].top_field_order_cnt, i, false);
|
|
+ set_poc_reg(regs, dpb[i].bottom_field_order_cnt, i, true);
|
|
+ }
|
|
+
|
|
+ regs->h264.cur_poc = dec_params->top_field_order_cnt;
|
|
+ regs->h264.cur_poc1 = dec_params->bottom_field_order_cnt;
|
|
|
|
/* config hw pps address */
|
|
offset = offsetof(struct rkvdec_h264_priv_tbl, param_set);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_PPS_BASE);
|
|
+ regs->h264.pps_base = priv_start_addr + offset;
|
|
|
|
/* config hw rps address */
|
|
offset = offsetof(struct rkvdec_h264_priv_tbl, rps);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_RPS_BASE);
|
|
-
|
|
- reg = RKVDEC_AXI_DDR_RDATA(0);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_RDATA);
|
|
-
|
|
- reg = RKVDEC_AXI_DDR_WDATA(0);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_WDATA);
|
|
+ regs->h264.rps_base = priv_start_addr + offset;
|
|
|
|
offset = offsetof(struct rkvdec_h264_priv_tbl, err_info);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_H264_ERRINFO_BASE);
|
|
+ regs->h264.errorinfo_base = priv_start_addr + offset;
|
|
+
|
|
+ rkvdec_memcpy_toio(rkvdec->regs, regs, sizeof(*regs));
|
|
}
|
|
|
|
#define RKVDEC_H264_MAX_DEPTH_IN_BYTES 2
|
|
@@ -1181,8 +1158,6 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
|
|
|
|
schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
|
|
|
|
- writel(0, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
|
|
- writel(0, rkvdec->regs + RKVDEC_REG_H264_ERR_E);
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
|
|
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
|
|
index fc7e6a260b0a..4de4a75f0f44 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
|
|
@@ -129,6 +129,7 @@ struct rkvdec_hevc_run {
|
|
struct rkvdec_hevc_ctx {
|
|
struct rkvdec_aux_buf priv_tbl;
|
|
struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix_cache;
|
|
+ struct rkvdec_regs regs;
|
|
};
|
|
|
|
struct scaling_factor {
|
|
@@ -548,6 +549,7 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
const struct v4l2_ctrl_hevc_slice_params *sl_params = &run->slices_params[0];
|
|
const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
|
|
struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
|
|
+ struct rkvdec_regs *regs = &hevc_ctx->regs;
|
|
dma_addr_t priv_start_addr = hevc_ctx->priv_tbl.dma;
|
|
const struct v4l2_pix_format_mplane *dst_fmt;
|
|
struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
|
|
@@ -564,8 +566,9 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
dma_addr_t dst_addr;
|
|
u32 reg, i;
|
|
|
|
- reg = RKVDEC_MODE(RKVDEC_MODE_HEVC);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL);
|
|
+ memset(regs, 0, sizeof(*regs));
|
|
+
|
|
+ regs->common.reg02.dec_mode = RKVDEC_MODE_HEVC;
|
|
|
|
f = &ctx->decoded_fmt;
|
|
dst_fmt = &f->fmt.pix_mp;
|
|
@@ -580,33 +583,27 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
else if (sps->chroma_format_idc == 2)
|
|
yuv_virstride = 2 * y_virstride;
|
|
|
|
- reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) |
|
|
- RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) |
|
|
- RKVDEC_SLICE_NUM_LOWBITS(run->num_slices);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_PICPAR);
|
|
+ regs->common.reg03.slice_num_lowbits = run->num_slices;
|
|
+ regs->common.reg03.uv_hor_virstride = hor_virstride / 16;
|
|
+ regs->common.reg03.y_hor_virstride = hor_virstride / 16;
|
|
|
|
/* config rlc base address */
|
|
rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
|
|
- writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
|
|
+ regs->common.strm_rlc_base = rlc_addr;
|
|
|
|
rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
|
|
- reg = RKVDEC_STRM_LEN(round_up(rlc_len, 16) + 64);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN);
|
|
+ regs->common.stream_len = round_up(rlc_len, 16) + 64;
|
|
|
|
/* config cabac table */
|
|
offset = offsetof(struct rkvdec_hevc_priv_tbl, cabac_table);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
|
|
+ regs->common.cabactbl_base = priv_start_addr + offset;
|
|
|
|
/* config output base address */
|
|
dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
|
|
- writel_relaxed(dst_addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
|
|
-
|
|
- reg = RKVDEC_Y_VIRSTRIDE(y_virstride / 16);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
|
|
+ regs->common.decout_base = dst_addr;
|
|
|
|
- reg = RKVDEC_YUV_VIRSTRIDE(yuv_virstride / 16);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
|
|
+ regs->common.reg08.y_virstride = y_virstride / 16;
|
|
+ regs->common.reg09.yuv_virstride = yuv_virstride / 16;
|
|
|
|
/* config ref pic address */
|
|
for (i = 0; i < 15; i++) {
|
|
@@ -620,33 +617,30 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
}
|
|
|
|
refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
|
|
- writel_relaxed(refer_addr | reg,
|
|
- rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i));
|
|
-
|
|
- reg = RKVDEC_POC_REFER(i < decode_params->num_active_dpb_entries ?
|
|
- dpb[i].pic_order_cnt_val : 0);
|
|
- writel_relaxed(reg,
|
|
- rkvdec->regs + RKVDEC_REG_H264_POC_REFER0(i));
|
|
+ //writel_relaxed(refer_addr | reg,
|
|
+ // rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i));
|
|
+ regs->h264.ref0_14_base[i].base_addr = refer_addr >> 4;
|
|
+ regs->h264.ref0_14_base[i].field_ref = !!(reg & 1);
|
|
+ regs->h264.ref0_14_base[i].topfield_used_ref = !!(reg & 2);
|
|
+ regs->h264.ref0_14_base[i].botfield_used_ref = !!(reg & 4);
|
|
+ regs->h264.ref0_14_base[i].colmv_used_flag_ref = !!(reg & 8);
|
|
+
|
|
+ regs->h264.ref0_14_poc[i] = i < decode_params->num_active_dpb_entries
|
|
+ ? dpb[i].pic_order_cnt_val
|
|
+ : 0;
|
|
}
|
|
|
|
- reg = RKVDEC_CUR_POC(sl_params->slice_pic_order_cnt);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0);
|
|
+ regs->h264.cur_poc = sl_params->slice_pic_order_cnt;
|
|
|
|
/* config hw pps address */
|
|
offset = offsetof(struct rkvdec_hevc_priv_tbl, param_set);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_PPS_BASE);
|
|
+ regs->h264.pps_base = priv_start_addr + offset;
|
|
|
|
/* config hw rps address */
|
|
offset = offsetof(struct rkvdec_hevc_priv_tbl, rps);
|
|
- writel_relaxed(priv_start_addr + offset,
|
|
- rkvdec->regs + RKVDEC_REG_RPS_BASE);
|
|
-
|
|
- reg = RKVDEC_AXI_DDR_RDATA(0);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_RDATA);
|
|
+ regs->h264.rps_base = priv_start_addr + offset;
|
|
|
|
- reg = RKVDEC_AXI_DDR_WDATA(0);
|
|
- writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_WDATA);
|
|
+ rkvdec_memcpy_toio(rkvdec->regs, regs, sizeof(*regs));
|
|
}
|
|
|
|
#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES 2
|
|
@@ -784,8 +778,6 @@ static int rkvdec_hevc_run(struct rkvdec_ctx *ctx)
|
|
|
|
schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
|
|
|
|
- writel(0, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
|
|
- writel(0, rkvdec->regs + RKVDEC_REG_H264_ERR_E);
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
|
|
writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
|
|
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
|
|
index c627b6b6f53a..2d6ba5f1df9a 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
|
|
@@ -3,7 +3,12 @@
|
|
#ifndef RKVDEC_REGS_H_
|
|
#define RKVDEC_REGS_H_
|
|
|
|
-/* rkvcodec registers */
|
|
+#include <linux/types.h>
|
|
+
|
|
+/*
|
|
+ * REG_INTERRUPT is accessed via writel to enable the decoder after
|
|
+ * configuring it and clear interrupt strmd_error_status
|
|
+ */
|
|
#define RKVDEC_REG_INTERRUPT 0x004
|
|
#define RKVDEC_INTERRUPT_DEC_E BIT(0)
|
|
#define RKVDEC_CONFIG_DEC_CLK_GATE_E BIT(1)
|
|
@@ -30,198 +35,384 @@
|
|
#define RKVDEC_SOFTRESET_RDY BIT(22)
|
|
#define RKVDEC_WR_DDR_ALIGN_EN BIT(23)
|
|
|
|
-#define RKVDEC_REG_SYSCTRL 0x008
|
|
-#define RKVDEC_IN_ENDIAN BIT(0)
|
|
-#define RKVDEC_IN_SWAP32_E BIT(1)
|
|
-#define RKVDEC_IN_SWAP64_E BIT(2)
|
|
-#define RKVDEC_STR_ENDIAN BIT(3)
|
|
-#define RKVDEC_STR_SWAP32_E BIT(4)
|
|
-#define RKVDEC_STR_SWAP64_E BIT(5)
|
|
-#define RKVDEC_OUT_ENDIAN BIT(6)
|
|
-#define RKVDEC_OUT_SWAP32_E BIT(7)
|
|
-#define RKVDEC_OUT_CBCR_SWAP BIT(8)
|
|
-#define RKVDEC_RLC_MODE_DIRECT_WRITE BIT(10)
|
|
-#define RKVDEC_RLC_MODE BIT(11)
|
|
-#define RKVDEC_STRM_START_BIT(x) (((x) & 0x7f) << 12)
|
|
-#define RKVDEC_MODE(x) (((x) & 0x03) << 20)
|
|
-#define RKVDEC_MODE_HEVC 0
|
|
-#define RKVDEC_MODE_H264 1
|
|
-#define RKVDEC_MODE_VP9 2
|
|
-#define RKVDEC_RPS_MODE BIT(24)
|
|
-#define RKVDEC_STRM_MODE BIT(25)
|
|
-#define RKVDEC_H264_STRM_LASTPKT BIT(26)
|
|
-#define RKVDEC_H264_FIRSTSLICE_FLAG BIT(27)
|
|
-#define RKVDEC_H264_FRAME_ORSLICE BIT(28)
|
|
-#define RKVDEC_BUSPR_SLOT_DIS BIT(29)
|
|
-
|
|
-#define RKVDEC_REG_PICPAR 0x00C
|
|
-#define RKVDEC_Y_HOR_VIRSTRIDE(x) ((x) & 0x1ff)
|
|
-#define RKVDEC_SLICE_NUM_HIGHBIT BIT(11)
|
|
-#define RKVDEC_UV_HOR_VIRSTRIDE(x) (((x) & 0x1ff) << 12)
|
|
-#define RKVDEC_SLICE_NUM_LOWBITS(x) (((x) & 0x7ff) << 21)
|
|
-
|
|
-#define RKVDEC_REG_STRM_RLC_BASE 0x010
|
|
-
|
|
-#define RKVDEC_REG_STRM_LEN 0x014
|
|
-#define RKVDEC_STRM_LEN(x) ((x) & 0x7ffffff)
|
|
-
|
|
-#define RKVDEC_REG_CABACTBL_PROB_BASE 0x018
|
|
-#define RKVDEC_REG_DECOUT_BASE 0x01C
|
|
-
|
|
-#define RKVDEC_REG_Y_VIRSTRIDE 0x020
|
|
-#define RKVDEC_Y_VIRSTRIDE(x) ((x) & 0xfffff)
|
|
-
|
|
-#define RKVDEC_REG_YUV_VIRSTRIDE 0x024
|
|
-#define RKVDEC_YUV_VIRSTRIDE(x) ((x) & 0x1fffff)
|
|
-#define RKVDEC_REG_H264_BASE_REFER(i) (((i) * 0x04) + 0x028)
|
|
-
|
|
-#define RKVDEC_REG_H264_BASE_REFER15 0x0C0
|
|
-#define RKVDEC_FIELD_REF BIT(0)
|
|
-#define RKVDEC_TOPFIELD_USED_REF BIT(1)
|
|
-#define RKVDEC_BOTFIELD_USED_REF BIT(2)
|
|
-#define RKVDEC_COLMV_USED_FLAG_REF BIT(3)
|
|
-
|
|
-#define RKVDEC_REG_VP9_LAST_FRAME_BASE 0x02c
|
|
-#define RKVDEC_REG_VP9_GOLDEN_FRAME_BASE 0x030
|
|
-#define RKVDEC_REG_VP9_ALTREF_FRAME_BASE 0x034
|
|
-
|
|
-#define RKVDEC_REG_VP9_CPRHEADER_OFFSET 0x028
|
|
-#define RKVDEC_VP9_CPRHEADER_OFFSET(x) ((x) & 0xffff)
|
|
-
|
|
-#define RKVDEC_REG_VP9_REFERLAST_BASE 0x02C
|
|
-#define RKVDEC_REG_VP9_REFERGOLDEN_BASE 0x030
|
|
-#define RKVDEC_REG_VP9_REFERALFTER_BASE 0x034
|
|
-
|
|
-#define RKVDEC_REG_VP9COUNT_BASE 0x038
|
|
-#define RKVDEC_VP9COUNT_UPDATE_EN BIT(0)
|
|
-
|
|
-#define RKVDEC_REG_VP9_SEGIDLAST_BASE 0x03C
|
|
-#define RKVDEC_REG_VP9_SEGIDCUR_BASE 0x040
|
|
-#define RKVDEC_REG_VP9_FRAME_SIZE(i) ((i) * 0x04 + 0x044)
|
|
-#define RKVDEC_VP9_FRAMEWIDTH(x) (((x) & 0xffff) << 0)
|
|
-#define RKVDEC_VP9_FRAMEHEIGHT(x) (((x) & 0xffff) << 16)
|
|
-
|
|
-#define RKVDEC_VP9_SEGID_GRP(i) ((i) * 0x04 + 0x050)
|
|
-#define RKVDEC_SEGID_ABS_DELTA(x) ((x) & 0x1)
|
|
-#define RKVDEC_SEGID_FRAME_QP_DELTA_EN(x) (((x) & 0x1) << 1)
|
|
-#define RKVDEC_SEGID_FRAME_QP_DELTA(x) (((x) & 0x1ff) << 2)
|
|
-#define RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(x) (((x) & 0x1) << 11)
|
|
-#define RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(x) (((x) & 0x7f) << 12)
|
|
-#define RKVDEC_SEGID_REFERINFO_EN(x) (((x) & 0x1) << 19)
|
|
-#define RKVDEC_SEGID_REFERINFO(x) (((x) & 0x03) << 20)
|
|
-#define RKVDEC_SEGID_FRAME_SKIP_EN(x) (((x) & 0x1) << 22)
|
|
-
|
|
-#define RKVDEC_VP9_CPRHEADER_CONFIG 0x070
|
|
-#define RKVDEC_VP9_TX_MODE(x) ((x) & 0x07)
|
|
-#define RKVDEC_VP9_FRAME_REF_MODE(x) (((x) & 0x03) << 3)
|
|
-
|
|
-#define RKVDEC_VP9_REF_SCALE(i) ((i) * 0x04 + 0x074)
|
|
-#define RKVDEC_VP9_REF_HOR_SCALE(x) ((x) & 0xffff)
|
|
-#define RKVDEC_VP9_REF_VER_SCALE(x) (((x) & 0xffff) << 16)
|
|
-
|
|
-#define RKVDEC_VP9_REF_DELTAS_LASTFRAME 0x080
|
|
-#define RKVDEC_REF_DELTAS_LASTFRAME(pos, val) (((val) & 0x7f) << ((pos) * 7))
|
|
-
|
|
-#define RKVDEC_VP9_INFO_LASTFRAME 0x084
|
|
-#define RKVDEC_MODE_DELTAS_LASTFRAME(pos, val) (((val) & 0x7f) << ((pos) * 7))
|
|
-#define RKVDEC_SEG_EN_LASTFRAME BIT(16)
|
|
-#define RKVDEC_LAST_SHOW_FRAME BIT(17)
|
|
-#define RKVDEC_LAST_INTRA_ONLY BIT(18)
|
|
-#define RKVDEC_LAST_WIDHHEIGHT_EQCUR BIT(19)
|
|
-#define RKVDEC_COLOR_SPACE_LASTKEYFRAME(x) (((x) & 0x07) << 20)
|
|
-
|
|
-#define RKVDEC_VP9_INTERCMD_BASE 0x088
|
|
-
|
|
-#define RKVDEC_VP9_INTERCMD_NUM 0x08C
|
|
-#define RKVDEC_INTERCMD_NUM(x) ((x) & 0xffffff)
|
|
-
|
|
-#define RKVDEC_VP9_LASTTILE_SIZE 0x090
|
|
-#define RKVDEC_LASTTILE_SIZE(x) ((x) & 0xffffff)
|
|
-
|
|
-#define RKVDEC_VP9_HOR_VIRSTRIDE(i) ((i) * 0x04 + 0x094)
|
|
-#define RKVDEC_HOR_Y_VIRSTRIDE(x) ((x) & 0x1ff)
|
|
-#define RKVDEC_HOR_UV_VIRSTRIDE(x) (((x) & 0x1ff) << 16)
|
|
-
|
|
-#define RKVDEC_REG_H264_POC_REFER0(i) (((i) * 0x04) + 0x064)
|
|
-#define RKVDEC_REG_H264_POC_REFER1(i) (((i) * 0x04) + 0x0C4)
|
|
-#define RKVDEC_REG_H264_POC_REFER2(i) (((i) * 0x04) + 0x120)
|
|
-#define RKVDEC_POC_REFER(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_CUR_POC0 0x0A0
|
|
-#define RKVDEC_REG_CUR_POC1 0x128
|
|
-#define RKVDEC_CUR_POC(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_RLCWRITE_BASE 0x0A4
|
|
-#define RKVDEC_REG_PPS_BASE 0x0A8
|
|
-#define RKVDEC_REG_RPS_BASE 0x0AC
|
|
-
|
|
-#define RKVDEC_REG_STRMD_ERR_EN 0x0B0
|
|
-#define RKVDEC_STRMD_ERR_EN(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_STRMD_ERR_STA 0x0B4
|
|
-#define RKVDEC_STRMD_ERR_STA(x) ((x) & 0xfffffff)
|
|
-#define RKVDEC_COLMV_ERR_REF_PICIDX(x) (((x) & 0x0f) << 28)
|
|
-
|
|
-#define RKVDEC_REG_STRMD_ERR_CTU 0x0B8
|
|
-#define RKVDEC_STRMD_ERR_CTU(x) ((x) & 0xff)
|
|
-#define RKVDEC_STRMD_ERR_CTU_YOFFSET(x) (((x) & 0xff) << 8)
|
|
-#define RKVDEC_STRMFIFO_SPACE2FULL(x) (((x) & 0x7f) << 16)
|
|
-#define RKVDEC_VP9_ERR_EN_CTU0 BIT(24)
|
|
-
|
|
-#define RKVDEC_REG_SAO_CTU_POS 0x0BC
|
|
-#define RKVDEC_SAOWR_XOFFSET(x) ((x) & 0x1ff)
|
|
-#define RKVDEC_SAOWR_YOFFSET(x) (((x) & 0x3ff) << 16)
|
|
-
|
|
-#define RKVDEC_VP9_LAST_FRAME_YSTRIDE 0x0C0
|
|
-#define RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE 0x0C4
|
|
-#define RKVDEC_VP9_ALTREF_FRAME_YSTRIDE 0x0C8
|
|
-#define RKVDEC_VP9_REF_YSTRIDE(x) (((x) & 0xfffff) << 0)
|
|
-
|
|
-#define RKVDEC_VP9_LAST_FRAME_YUVSTRIDE 0x0CC
|
|
-#define RKVDEC_VP9_REF_YUVSTRIDE(x) (((x) & 0x1fffff) << 0)
|
|
-
|
|
-#define RKVDEC_VP9_REF_COLMV_BASE 0x0D0
|
|
-
|
|
-#define RKVDEC_REG_PERFORMANCE_CYCLE 0x100
|
|
-#define RKVDEC_PERFORMANCE_CYCLE(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_AXI_DDR_RDATA 0x104
|
|
-#define RKVDEC_AXI_DDR_RDATA(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_AXI_DDR_WDATA 0x108
|
|
-#define RKVDEC_AXI_DDR_WDATA(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_FPGADEBUG_RESET 0x10C
|
|
-#define RKVDEC_BUSIFD_RESETN BIT(0)
|
|
-#define RKVDEC_CABAC_RESETN BIT(1)
|
|
-#define RKVDEC_DEC_CTRL_RESETN BIT(2)
|
|
-#define RKVDEC_TRANSD_RESETN BIT(3)
|
|
-#define RKVDEC_INTRA_RESETN BIT(4)
|
|
-#define RKVDEC_INTER_RESETN BIT(5)
|
|
-#define RKVDEC_RECON_RESETN BIT(6)
|
|
-#define RKVDEC_FILER_RESETN BIT(7)
|
|
-
|
|
-#define RKVDEC_REG_PERFORMANCE_SEL 0x110
|
|
-#define RKVDEC_PERF_SEL_CNT0(x) ((x) & 0x3f)
|
|
-#define RKVDEC_PERF_SEL_CNT1(x) (((x) & 0x3f) << 8)
|
|
-#define RKVDEC_PERF_SEL_CNT2(x) (((x) & 0x3f) << 16)
|
|
-
|
|
-#define RKVDEC_REG_PERFORMANCE_CNT(i) ((i) * 0x04 + 0x114)
|
|
-#define RKVDEC_PERF_CNT(x) ((x) & 0xffffffff)
|
|
-
|
|
-#define RKVDEC_REG_H264_ERRINFO_BASE 0x12C
|
|
-
|
|
-#define RKVDEC_REG_H264_ERRINFO_NUM 0x130
|
|
-#define RKVDEC_SLICEDEC_NUM(x) ((x) & 0x3fff)
|
|
-#define RKVDEC_STRMD_DECT_ERR_FLAG BIT(15)
|
|
-#define RKVDEC_ERR_PKT_NUM(x) (((x) & 0x3fff) << 16)
|
|
-
|
|
-#define RKVDEC_REG_H264_ERR_E 0x134
|
|
-#define RKVDEC_H264_ERR_EN_HIGHBITS(x) ((x) & 0x3fffffff)
|
|
-
|
|
#define RKVDEC_REG_QOS_CTRL 0x18C
|
|
|
|
+/*
|
|
+ * Cache configuration is not covered in the range of the register struct
|
|
+ */
|
|
#define RKVDEC_REG_PREF_LUMA_CACHE_COMMAND 0x410
|
|
#define RKVDEC_REG_PREF_CHR_CACHE_COMMAND 0x450
|
|
|
|
+/*
|
|
+ * Define the mode values
|
|
+ */
|
|
+#define RKVDEC_MODE_HEVC 0
|
|
+#define RKVDEC_MODE_H264 1
|
|
+#define RKVDEC_MODE_VP9 2
|
|
+
|
|
+/* rkvcodec registers */
|
|
+struct rkvdec_common_regs {
|
|
+ struct rkvdec_id {
|
|
+ u32 minor_ver : 8;
|
|
+ u32 level : 1;
|
|
+ u32 dec_support : 3;
|
|
+ u32 profile : 1;
|
|
+ u32 reserved0 : 1;
|
|
+ u32 codec_flag : 1;
|
|
+ u32 reserved1 : 1;
|
|
+ u32 prod_num : 16;
|
|
+ } reg00;
|
|
+
|
|
+ struct rkvdec_int {
|
|
+ u32 dec_e : 1;
|
|
+ u32 dec_clkgate_e : 1;
|
|
+ u32 reserved0 : 1;
|
|
+ u32 timeout_mode : 1;
|
|
+ u32 dec_irq_dis : 1;
|
|
+ u32 dec_timeout_e : 1;
|
|
+ u32 buf_empty_en : 1;
|
|
+ u32 stmerror_waitdecfifo_empty : 1;
|
|
+ u32 dec_irq : 1;
|
|
+ u32 dec_irq_raw : 1;
|
|
+ u32 reserved2 : 2;
|
|
+ u32 dec_rdy_sta : 1;
|
|
+ u32 dec_bus_sta : 1;
|
|
+ u32 dec_error_sta : 1;
|
|
+ u32 dec_timeout_sta : 1;
|
|
+ u32 dec_empty_sta : 1;
|
|
+ u32 colmv_ref_error_sta : 1;
|
|
+ u32 cabu_end_sta : 1;
|
|
+ u32 h264orvp9_error_mode : 1;
|
|
+ u32 softrst_en_p : 1;
|
|
+ u32 force_softreset_valid : 1;
|
|
+ u32 softreset_rdy : 1;
|
|
+ u32 reserved1 : 9;
|
|
+ } reg01;
|
|
+
|
|
+ struct rkvdec_sysctrl {
|
|
+ u32 in_endian : 1;
|
|
+ u32 in_swap32_e : 1;
|
|
+ u32 in_swap64_e : 1;
|
|
+ u32 str_endian : 1;
|
|
+ u32 str_swap32_e : 1;
|
|
+ u32 str_swap64_e : 1;
|
|
+ u32 out_endian : 1;
|
|
+ u32 out_swap32_e : 1;
|
|
+ u32 out_cbcr_swap : 1;
|
|
+ u32 reserved0 : 1;
|
|
+ u32 rlc_mode_direct_write : 1;
|
|
+ u32 rlc_mode : 1;
|
|
+ u32 strm_start_bit : 7;
|
|
+ u32 reserved1 : 1;
|
|
+ u32 dec_mode : 2;
|
|
+ u32 reserved2 : 2;
|
|
+ u32 rps_mode : 1;
|
|
+ u32 stream_mode : 1;
|
|
+ u32 stream_lastpacket : 1;
|
|
+ u32 firstslice_flag : 1;
|
|
+ u32 frame_orslice : 1;
|
|
+ u32 buspr_slot_disable : 1;
|
|
+ u32 reserved3 : 2;
|
|
+ } reg02;
|
|
+
|
|
+ struct rkvdec_picpar {
|
|
+ u32 y_hor_virstride : 9;
|
|
+ u32 reserved : 2;
|
|
+ u32 slice_num_highbit : 1;
|
|
+ u32 uv_hor_virstride : 9;
|
|
+ u32 slice_num_lowbits : 11;
|
|
+ } reg03;
|
|
+
|
|
+ u32 strm_rlc_base;
|
|
+ u32 stream_len;
|
|
+ u32 cabactbl_base;
|
|
+ u32 decout_base;
|
|
+
|
|
+ struct rkvdec_y_virstride {
|
|
+ u32 y_virstride : 20;
|
|
+ u32 reserved0 : 12;
|
|
+ } reg08;
|
|
+
|
|
+ struct rkvdec_yuv_virstride {
|
|
+ u32 yuv_virstride : 21;
|
|
+ u32 reserved0 : 11;
|
|
+ } reg09;
|
|
+} __packed;
|
|
+
|
|
+struct ref_base {
|
|
+ u32 field_ref : 1;
|
|
+ u32 topfield_used_ref : 1;
|
|
+ u32 botfield_used_ref : 1;
|
|
+ u32 colmv_used_flag_ref : 1;
|
|
+ u32 base_addr : 28;
|
|
+};
|
|
+
|
|
+struct rkvdec_h264_regs {
|
|
+ struct ref_base ref0_14_base[15];
|
|
+ u32 ref0_14_poc[15];
|
|
+
|
|
+ u32 cur_poc;
|
|
+ u32 rlcwrite_base;
|
|
+ u32 pps_base;
|
|
+ u32 rps_base;
|
|
+
|
|
+ u32 strmd_error_e;
|
|
+
|
|
+ struct {
|
|
+ u32 strmd_error_status : 28;
|
|
+ u32 colmv_error_ref_picidx : 4;
|
|
+ } reg45;
|
|
+
|
|
+ struct {
|
|
+ u32 strmd_error_ctu_xoffset : 8;
|
|
+ u32 strmd_error_ctu_yoffset : 8;
|
|
+ u32 streamfifo_space2full : 7;
|
|
+ u32 reserved0 : 1;
|
|
+ u32 vp9_error_ctu0_en : 1;
|
|
+ u32 reserved1 : 7;
|
|
+ } reg46;
|
|
+
|
|
+ struct {
|
|
+ u32 saowr_xoffet : 9;
|
|
+ u32 reserved0 : 7;
|
|
+ u32 saowr_yoffset : 10;
|
|
+ u32 reserved1 : 6;
|
|
+ } reg47;
|
|
+
|
|
+ struct ref_base ref15_base;
|
|
+
|
|
+ u32 ref15_29_poc[15];
|
|
+
|
|
+ u32 performance_cycle;
|
|
+ u32 axi_ddr_rdata;
|
|
+ u32 axi_ddr_wdata;
|
|
+
|
|
+ struct {
|
|
+ u32 busifd_resetn : 1;
|
|
+ u32 cabac_resetn : 1;
|
|
+ u32 dec_ctrl_resetn : 1;
|
|
+ u32 transd_resetn : 1;
|
|
+ u32 intra_resetn : 1;
|
|
+ u32 inter_resetn : 1;
|
|
+ u32 recon_resetn : 1;
|
|
+ u32 filer_resetn : 1;
|
|
+ u32 reserved0 : 24;
|
|
+ } reg67;
|
|
+
|
|
+ struct {
|
|
+ u32 perf_cnt0_sel : 6;
|
|
+ u32 reserved0 : 2;
|
|
+ u32 perf_cnt1_sel : 6;
|
|
+ u32 reserved1 : 2;
|
|
+ u32 perf_cnt2_sel : 6;
|
|
+ u32 reserved2 : 10;
|
|
+ } reg68;
|
|
+
|
|
+ u32 perf_cnt0;
|
|
+ u32 perf_cnt1;
|
|
+ u32 perf_cnt2;
|
|
+ u32 ref30_poc;
|
|
+ u32 ref31_poc;
|
|
+ u32 cur_poc1;
|
|
+ u32 errorinfo_base;
|
|
+
|
|
+ struct {
|
|
+ u32 slicedec_num : 14;
|
|
+ u32 reserved0 : 1;
|
|
+ u32 strmd_detect_error_flag : 1;
|
|
+ u32 error_packet_num : 14;
|
|
+ u32 reserved1 : 2;
|
|
+ } reg76;
|
|
+
|
|
+ struct {
|
|
+ u32 error_en_highbits : 30;
|
|
+ u32 reserved : 2;
|
|
+ } reg77;
|
|
+} __packed;
|
|
+
|
|
+struct rkvdec_vp9_regs {
|
|
+ struct cprheader_offset {
|
|
+ u32 cprheader_offset : 16;
|
|
+ u32 reserved : 16;
|
|
+ } reg10;
|
|
+
|
|
+ u32 refer_bases[3];
|
|
+ u32 count_base;
|
|
+ u32 segidlast_base;
|
|
+ u32 segidcur_base;
|
|
+
|
|
+ struct frame_sizes {
|
|
+ u32 framewidth : 16;
|
|
+ u32 frameheight : 16;
|
|
+ } reg17_19[3];
|
|
+
|
|
+ struct segid_grp {
|
|
+ u32 segid_abs_delta : 1;
|
|
+ u32 segid_frame_qp_delta_en : 1;
|
|
+ u32 segid_frame_qp_delta : 9;
|
|
+ u32 segid_frame_loopfilter_value_en : 1;
|
|
+ u32 segid_frame_loopfilter_value : 7;
|
|
+ u32 segid_referinfo_en : 1;
|
|
+ u32 segid_referinfo : 2;
|
|
+ u32 segid_frame_skip_en : 1;
|
|
+ u32 reserved : 9;
|
|
+ } reg20_27[8];
|
|
+
|
|
+ struct cprheader_config {
|
|
+ u32 tx_mode : 3;
|
|
+ u32 frame_reference_mode : 2;
|
|
+ u32 reserved : 27;
|
|
+ } reg28;
|
|
+
|
|
+ struct ref_scale {
|
|
+ u32 ref_hor_scale : 16;
|
|
+ u32 ref_ver_scale : 16;
|
|
+ } reg29_31[3];
|
|
+
|
|
+ struct ref_deltas_lastframe {
|
|
+ u32 ref_deltas_lastframe0 : 7;
|
|
+ u32 ref_deltas_lastframe1 : 7;
|
|
+ u32 ref_deltas_lastframe2 : 7;
|
|
+ u32 ref_deltas_lastframe3 : 7;
|
|
+ u32 reserved : 4;
|
|
+ } reg32;
|
|
+
|
|
+ struct info_lastframe {
|
|
+ u32 mode_deltas_lastframe0 : 7;
|
|
+ u32 mode_deltas_lastframe1 : 7;
|
|
+ u32 reserved0 : 2;
|
|
+ u32 segmentation_enable_lstframe : 1;
|
|
+ u32 last_show_frame : 1;
|
|
+ u32 last_intra_only : 1;
|
|
+ u32 last_widthheight_eqcur : 1;
|
|
+ u32 color_space_lastkeyframe : 3;
|
|
+ u32 reserved1 : 9;
|
|
+ } reg33;
|
|
+
|
|
+ u32 intercmd_base;
|
|
+
|
|
+ struct intercmd_num {
|
|
+ u32 intercmd_num : 24;
|
|
+ u32 reserved : 8;
|
|
+ } reg35;
|
|
+
|
|
+ struct lasttile_size {
|
|
+ u32 lasttile_size : 24;
|
|
+ u32 reserved : 8;
|
|
+ } reg36;
|
|
+
|
|
+ struct hor_virstride {
|
|
+ u32 y_hor_virstride : 9;
|
|
+ u32 reserved0 : 7;
|
|
+ u32 uv_hor_virstride : 9;
|
|
+ u32 reserved1 : 7;
|
|
+ } reg37_39[3];
|
|
+
|
|
+ u32 cur_poc;
|
|
+
|
|
+ struct rlcwrite_base {
|
|
+ u32 reserved : 3;
|
|
+ u32 rlcwrite_base : 29;
|
|
+ } reg41;
|
|
+
|
|
+ struct pps_base {
|
|
+ u32 reserved : 4;
|
|
+ u32 pps_base : 28;
|
|
+ } reg42;
|
|
+
|
|
+ struct rps_base {
|
|
+ u32 reserved : 4;
|
|
+ u32 rps_base : 28;
|
|
+ } reg43;
|
|
+
|
|
+ struct strmd_error_en {
|
|
+ u32 strmd_error_e : 28;
|
|
+ u32 reserved : 4;
|
|
+ } reg44;
|
|
+
|
|
+ u32 vp9_error_info0;
|
|
+
|
|
+ struct strmd_error_ctu {
|
|
+ u32 strmd_error_ctu_xoffset : 8;
|
|
+ u32 strmd_error_ctu_yoffset : 8;
|
|
+ u32 streamfifo_space2full : 7;
|
|
+ u32 reserved0 : 1;
|
|
+ u32 error_ctu0_en : 1;
|
|
+ u32 reserved1 : 7;
|
|
+ } reg46;
|
|
+
|
|
+ struct sao_ctu_position {
|
|
+ u32 saowr_xoffet : 9;
|
|
+ u32 reserved0 : 7;
|
|
+ u32 saowr_yoffset : 10;
|
|
+ u32 reserved1 : 6;
|
|
+ } reg47;
|
|
+
|
|
+ struct ystride {
|
|
+ u32 virstride : 20;
|
|
+ u32 reserved : 12;
|
|
+ } reg48_50[3];
|
|
+
|
|
+ struct lastref_yuvstride {
|
|
+ u32 lastref_yuv_virstride : 21;
|
|
+ u32 reserved : 11;
|
|
+ } reg51;
|
|
+
|
|
+ u32 refcolmv_base;
|
|
+
|
|
+ u32 reserved0[11];
|
|
+
|
|
+ u32 performance_cycle;
|
|
+ u32 axi_ddr_rdata;
|
|
+ u32 axi_ddr_wdata;
|
|
+
|
|
+ struct fpgadebug_reset {
|
|
+ u32 busifd_resetn : 1;
|
|
+ u32 cabac_resetn : 1;
|
|
+ u32 dec_ctrl_resetn : 1;
|
|
+ u32 transd_resetn : 1;
|
|
+ u32 intra_resetn : 1;
|
|
+ u32 inter_resetn : 1;
|
|
+ u32 recon_resetn : 1;
|
|
+ u32 filer_resetn : 1;
|
|
+ u32 reserved : 24;
|
|
+ } reg67;
|
|
+
|
|
+ struct performance_sel {
|
|
+ u32 perf_cnt0_sel : 6;
|
|
+ u32 reserved0 : 2;
|
|
+ u32 perf_cnt1_sel : 6;
|
|
+ u32 reserved1 : 2;
|
|
+ u32 perf_cnt2_sel : 6;
|
|
+ u32 reserved : 10;
|
|
+ } reg68;
|
|
+
|
|
+ u32 perf_cnt0;
|
|
+ u32 perf_cnt1;
|
|
+ u32 perf_cnt2;
|
|
+
|
|
+ u32 reserved1[3];
|
|
+
|
|
+ u32 vp9_error_info1;
|
|
+
|
|
+ struct error_ctu1 {
|
|
+ u32 vp9_error_ctu1_x : 6;
|
|
+ u32 reserved0 : 2;
|
|
+ u32 vp9_error_ctu1_y : 6;
|
|
+ u32 reserved1 : 1;
|
|
+ u32 vp9_error_ctu1_en : 1;
|
|
+ u32 reserved2 : 16;
|
|
+ } reg76;
|
|
+
|
|
+ u32 reserved2;
|
|
+} __packed;
|
|
+
|
|
+struct rkvdec_regs {
|
|
+ struct rkvdec_common_regs common;
|
|
+ union {
|
|
+ struct rkvdec_h264_regs h264; //TODO: rename to h26x
|
|
+ struct rkvdec_vp9_regs vp9;
|
|
+ };
|
|
+} __packed;
|
|
+
|
|
#endif /* RKVDEC_REGS_H_ */
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
|
|
index b4bf01e839ef..e1f6957ccdac 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
|
|
@@ -163,6 +163,7 @@ struct rkvdec_vp9_ctx {
|
|
struct v4l2_vp9_frame_context frame_context[4];
|
|
struct rkvdec_vp9_frame_info cur;
|
|
struct rkvdec_vp9_frame_info last;
|
|
+ struct rkvdec_regs regs;
|
|
};
|
|
|
|
static void write_coeff_plane(const u8 coef[6][6][3], u8 *coeff_plane)
|
|
@@ -347,38 +348,6 @@ static void init_probs(struct rkvdec_ctx *ctx,
|
|
init_inter_probs(ctx, run);
|
|
}
|
|
|
|
-struct rkvdec_vp9_ref_reg {
|
|
- u32 reg_frm_size;
|
|
- u32 reg_hor_stride;
|
|
- u32 reg_y_stride;
|
|
- u32 reg_yuv_stride;
|
|
- u32 reg_ref_base;
|
|
-};
|
|
-
|
|
-static struct rkvdec_vp9_ref_reg ref_regs[] = {
|
|
- {
|
|
- .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(0),
|
|
- .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(0),
|
|
- .reg_y_stride = RKVDEC_VP9_LAST_FRAME_YSTRIDE,
|
|
- .reg_yuv_stride = RKVDEC_VP9_LAST_FRAME_YUVSTRIDE,
|
|
- .reg_ref_base = RKVDEC_REG_VP9_LAST_FRAME_BASE,
|
|
- },
|
|
- {
|
|
- .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(1),
|
|
- .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(1),
|
|
- .reg_y_stride = RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE,
|
|
- .reg_yuv_stride = 0,
|
|
- .reg_ref_base = RKVDEC_REG_VP9_GOLDEN_FRAME_BASE,
|
|
- },
|
|
- {
|
|
- .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(2),
|
|
- .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(2),
|
|
- .reg_y_stride = RKVDEC_VP9_ALTREF_FRAME_YSTRIDE,
|
|
- .reg_yuv_stride = 0,
|
|
- .reg_ref_base = RKVDEC_REG_VP9_ALTREF_FRAME_BASE,
|
|
- }
|
|
-};
|
|
-
|
|
static struct rkvdec_decoded_buffer *
|
|
get_ref_buf(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp)
|
|
{
|
|
@@ -412,18 +381,17 @@ static dma_addr_t get_mv_base_addr(struct rkvdec_decoded_buffer *buf)
|
|
static void config_ref_registers(struct rkvdec_ctx *ctx,
|
|
const struct rkvdec_vp9_run *run,
|
|
struct rkvdec_decoded_buffer *ref_buf,
|
|
- struct rkvdec_vp9_ref_reg *ref_reg)
|
|
+ int i)
|
|
{
|
|
unsigned int aligned_pitch, aligned_height, y_len, yuv_len;
|
|
- struct rkvdec_dev *rkvdec = ctx->dev;
|
|
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
|
|
+ struct rkvdec_regs *regs = &vp9_ctx->regs;
|
|
|
|
aligned_height = round_up(ref_buf->vp9.height, 64);
|
|
- writel_relaxed(RKVDEC_VP9_FRAMEWIDTH(ref_buf->vp9.width) |
|
|
- RKVDEC_VP9_FRAMEHEIGHT(ref_buf->vp9.height),
|
|
- rkvdec->regs + ref_reg->reg_frm_size);
|
|
+ regs->vp9.reg17_19[i].frameheight = ref_buf->vp9.height;
|
|
+ regs->vp9.reg17_19[i].framewidth = ref_buf->vp9.width;
|
|
|
|
- writel_relaxed(vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0),
|
|
- rkvdec->regs + ref_reg->reg_ref_base);
|
|
+ regs->vp9.refer_bases[i] = vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0);
|
|
|
|
if (&ref_buf->base.vb == run->base.bufs.dst)
|
|
return;
|
|
@@ -432,59 +400,50 @@ static void config_ref_registers(struct rkvdec_ctx *ctx,
|
|
y_len = aligned_height * aligned_pitch;
|
|
yuv_len = (y_len * 3) / 2;
|
|
|
|
- writel_relaxed(RKVDEC_HOR_Y_VIRSTRIDE(aligned_pitch / 16) |
|
|
- RKVDEC_HOR_UV_VIRSTRIDE(aligned_pitch / 16),
|
|
- rkvdec->regs + ref_reg->reg_hor_stride);
|
|
- writel_relaxed(RKVDEC_VP9_REF_YSTRIDE(y_len / 16),
|
|
- rkvdec->regs + ref_reg->reg_y_stride);
|
|
-
|
|
- if (!ref_reg->reg_yuv_stride)
|
|
- return;
|
|
+ regs->vp9.reg37_39[i].y_hor_virstride = aligned_pitch / 16;
|
|
+ regs->vp9.reg37_39[i].uv_hor_virstride = aligned_pitch / 16;
|
|
+ regs->vp9.reg48_50[i].virstride = y_len / 16;
|
|
|
|
- writel_relaxed(RKVDEC_VP9_REF_YUVSTRIDE(yuv_len / 16),
|
|
- rkvdec->regs + ref_reg->reg_yuv_stride);
|
|
+ if (!i)
|
|
+ regs->vp9.reg51.lastref_yuv_virstride = yuv_len / 16;
|
|
}
|
|
|
|
static void config_seg_registers(struct rkvdec_ctx *ctx, unsigned int segid)
|
|
{
|
|
struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
|
|
+ struct rkvdec_regs *regs = &vp9_ctx->regs;
|
|
const struct v4l2_vp9_segmentation *seg;
|
|
- struct rkvdec_dev *rkvdec = ctx->dev;
|
|
s16 feature_val;
|
|
int feature_id;
|
|
- u32 val = 0;
|
|
|
|
seg = vp9_ctx->last.valid ? &vp9_ctx->last.seg : &vp9_ctx->cur.seg;
|
|
feature_id = V4L2_VP9_SEG_LVL_ALT_Q;
|
|
if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
|
|
feature_val = seg->feature_data[segid][feature_id];
|
|
- val |= RKVDEC_SEGID_FRAME_QP_DELTA_EN(1) |
|
|
- RKVDEC_SEGID_FRAME_QP_DELTA(feature_val);
|
|
+ regs->vp9.reg20_27[segid].segid_frame_qp_delta_en = 1;
|
|
+ regs->vp9.reg20_27[segid].segid_frame_qp_delta = feature_val;
|
|
}
|
|
|
|
feature_id = V4L2_VP9_SEG_LVL_ALT_L;
|
|
if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
|
|
feature_val = seg->feature_data[segid][feature_id];
|
|
- val |= RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(1) |
|
|
- RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(feature_val);
|
|
+ regs->vp9.reg20_27[segid].segid_frame_loopfilter_value_en = 1;
|
|
+ regs->vp9.reg20_27[segid].segid_frame_loopfilter_value = feature_val;
|
|
}
|
|
|
|
feature_id = V4L2_VP9_SEG_LVL_REF_FRAME;
|
|
if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
|
|
feature_val = seg->feature_data[segid][feature_id];
|
|
- val |= RKVDEC_SEGID_REFERINFO_EN(1) |
|
|
- RKVDEC_SEGID_REFERINFO(feature_val);
|
|
+ regs->vp9.reg20_27[segid].segid_referinfo_en = 1;
|
|
+ regs->vp9.reg20_27[segid].segid_referinfo = feature_val;
|
|
}
|
|
|
|
feature_id = V4L2_VP9_SEG_LVL_SKIP;
|
|
- if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid))
|
|
- val |= RKVDEC_SEGID_FRAME_SKIP_EN(1);
|
|
-
|
|
- if (!segid &&
|
|
- (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
|
|
- val |= RKVDEC_SEGID_ABS_DELTA(1);
|
|
+ regs->vp9.reg20_27[segid].segid_frame_skip_en =
|
|
+ v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid);
|
|
|
|
- writel_relaxed(val, rkvdec->regs + RKVDEC_VP9_SEGID_GRP(segid));
|
|
+ regs->vp9.reg20_27[segid].segid_abs_delta = !segid &&
|
|
+ (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE);
|
|
}
|
|
|
|
static void update_dec_buf_info(struct rkvdec_decoded_buffer *buf,
|
|
@@ -521,7 +480,8 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
struct rkvdec_decoded_buffer *ref_bufs[3];
|
|
struct rkvdec_decoded_buffer *dst, *last, *mv_ref;
|
|
struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
|
|
- u32 val, last_frame_info = 0;
|
|
+ struct rkvdec_regs *regs = &vp9_ctx->regs;
|
|
+ u32 val;
|
|
const struct v4l2_vp9_segmentation *seg;
|
|
struct rkvdec_dev *rkvdec = ctx->dev;
|
|
dma_addr_t addr;
|
|
@@ -547,8 +507,7 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
|
|
V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
|
|
|
|
- writel_relaxed(RKVDEC_MODE(RKVDEC_MODE_VP9),
|
|
- rkvdec->regs + RKVDEC_REG_SYSCTRL);
|
|
+ regs->common.reg02.dec_mode = RKVDEC_MODE_VP9;
|
|
|
|
bit_depth = dec_params->bit_depth;
|
|
aligned_height = round_up(ctx->decoded_fmt.fmt.pix_mp.height, 64);
|
|
@@ -560,17 +519,14 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
uv_len = y_len / 2;
|
|
yuv_len = y_len + uv_len;
|
|
|
|
- writel_relaxed(RKVDEC_Y_HOR_VIRSTRIDE(aligned_pitch / 16) |
|
|
- RKVDEC_UV_HOR_VIRSTRIDE(aligned_pitch / 16),
|
|
- rkvdec->regs + RKVDEC_REG_PICPAR);
|
|
- writel_relaxed(RKVDEC_Y_VIRSTRIDE(y_len / 16),
|
|
- rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
|
|
- writel_relaxed(RKVDEC_YUV_VIRSTRIDE(yuv_len / 16),
|
|
- rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
|
|
+ regs->common.reg03.y_hor_virstride = aligned_pitch / 16;
|
|
+ regs->common.reg03.uv_hor_virstride = aligned_pitch / 16;
|
|
+ regs->common.reg08.y_virstride = y_len / 16;
|
|
+ regs->common.reg09.yuv_virstride = yuv_len / 16;
|
|
|
|
stream_len = vb2_get_plane_payload(&run->base.bufs.src->vb2_buf, 0);
|
|
- writel_relaxed(RKVDEC_STRM_LEN(stream_len),
|
|
- rkvdec->regs + RKVDEC_REG_STRM_LEN);
|
|
+
|
|
+ regs->common.stream_len = stream_len;
|
|
|
|
/*
|
|
* Reset count buffer, because decoder only output intra related syntax
|
|
@@ -588,14 +544,13 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
vp9_ctx->cur.segmapid++;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ref_bufs); i++)
|
|
- config_ref_registers(ctx, run, ref_bufs[i], &ref_regs[i]);
|
|
+ config_ref_registers(ctx, run, ref_bufs[i], i);
|
|
|
|
for (i = 0; i < 8; i++)
|
|
config_seg_registers(ctx, i);
|
|
|
|
- writel_relaxed(RKVDEC_VP9_TX_MODE(vp9_ctx->cur.tx_mode) |
|
|
- RKVDEC_VP9_FRAME_REF_MODE(dec_params->reference_mode),
|
|
- rkvdec->regs + RKVDEC_VP9_CPRHEADER_CONFIG);
|
|
+ regs->vp9.reg28.tx_mode = vp9_ctx->cur.tx_mode;
|
|
+ regs->vp9.reg28.frame_reference_mode = dec_params->reference_mode;
|
|
|
|
if (!intra_only) {
|
|
const struct v4l2_vp9_loop_filter *lf;
|
|
@@ -609,43 +564,56 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
val = 0;
|
|
for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) {
|
|
delta = lf->ref_deltas[i];
|
|
- val |= RKVDEC_REF_DELTAS_LASTFRAME(i, delta);
|
|
+ switch (i) {
|
|
+ case 0:
|
|
+ regs->vp9.reg32.ref_deltas_lastframe0 = delta;
|
|
+ break;
|
|
+ case 1:
|
|
+ regs->vp9.reg32.ref_deltas_lastframe1 = delta;
|
|
+ break;
|
|
+ case 2:
|
|
+ regs->vp9.reg32.ref_deltas_lastframe2 = delta;
|
|
+ break;
|
|
+ case 3:
|
|
+ regs->vp9.reg32.ref_deltas_lastframe3 = delta;
|
|
+ break;
|
|
+ }
|
|
}
|
|
|
|
- writel_relaxed(val,
|
|
- rkvdec->regs + RKVDEC_VP9_REF_DELTAS_LASTFRAME);
|
|
-
|
|
for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) {
|
|
delta = lf->mode_deltas[i];
|
|
- last_frame_info |= RKVDEC_MODE_DELTAS_LASTFRAME(i,
|
|
- delta);
|
|
+ switch (i) {
|
|
+ case 0:
|
|
+ regs->vp9.reg33.mode_deltas_lastframe0 = delta;
|
|
+ break;
|
|
+ case 1:
|
|
+ regs->vp9.reg33.mode_deltas_lastframe1 = delta;
|
|
+ break;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
- if (vp9_ctx->last.valid && !intra_only &&
|
|
- vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED)
|
|
- last_frame_info |= RKVDEC_SEG_EN_LASTFRAME;
|
|
+ regs->vp9.reg33.segmentation_enable_lstframe =
|
|
+ vp9_ctx->last.valid && !intra_only &&
|
|
+ vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED;
|
|
|
|
- if (vp9_ctx->last.valid &&
|
|
- vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME)
|
|
- last_frame_info |= RKVDEC_LAST_SHOW_FRAME;
|
|
+ regs->vp9.reg33.last_show_frame =
|
|
+ vp9_ctx->last.valid &&
|
|
+ vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME;
|
|
|
|
- if (vp9_ctx->last.valid &&
|
|
- vp9_ctx->last.flags &
|
|
- (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY))
|
|
- last_frame_info |= RKVDEC_LAST_INTRA_ONLY;
|
|
+ regs->vp9.reg33.last_intra_only =
|
|
+ vp9_ctx->last.valid &&
|
|
+ vp9_ctx->last.flags &
|
|
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
|
|
|
|
- if (vp9_ctx->last.valid &&
|
|
- last->vp9.width == dst->vp9.width &&
|
|
- last->vp9.height == dst->vp9.height)
|
|
- last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR;
|
|
+ regs->vp9.reg33.last_widthheight_eqcur =
|
|
+ vp9_ctx->last.valid &&
|
|
+ last->vp9.width == dst->vp9.width &&
|
|
+ last->vp9.height == dst->vp9.height;
|
|
|
|
- writel_relaxed(last_frame_info,
|
|
- rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME);
|
|
-
|
|
- writel_relaxed(stream_len - dec_params->compressed_header_size -
|
|
- dec_params->uncompressed_header_size,
|
|
- rkvdec->regs + RKVDEC_VP9_LASTTILE_SIZE);
|
|
+ regs->vp9.reg36.lasttile_size =
|
|
+ stream_len - dec_params->compressed_header_size -
|
|
+ dec_params->uncompressed_header_size;
|
|
|
|
for (i = 0; !intra_only && i < ARRAY_SIZE(ref_bufs); i++) {
|
|
unsigned int refw = ref_bufs[i]->vp9.width;
|
|
@@ -654,29 +622,28 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
|
|
hscale = (refw << 14) / dst->vp9.width;
|
|
vscale = (refh << 14) / dst->vp9.height;
|
|
- writel_relaxed(RKVDEC_VP9_REF_HOR_SCALE(hscale) |
|
|
- RKVDEC_VP9_REF_VER_SCALE(vscale),
|
|
- rkvdec->regs + RKVDEC_VP9_REF_SCALE(i));
|
|
+
|
|
+ regs->vp9.reg29_31[i].ref_hor_scale = hscale;
|
|
+ regs->vp9.reg29_31[i].ref_ver_scale = vscale;
|
|
}
|
|
|
|
addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0);
|
|
- writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
|
|
+ regs->common.decout_base = addr;
|
|
addr = vb2_dma_contig_plane_dma_addr(&run->base.bufs.src->vb2_buf, 0);
|
|
- writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
|
|
- writel_relaxed(vp9_ctx->priv_tbl.dma +
|
|
- offsetof(struct rkvdec_vp9_priv_tbl, probs),
|
|
- rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
|
|
- writel_relaxed(vp9_ctx->count_tbl.dma,
|
|
- rkvdec->regs + RKVDEC_REG_VP9COUNT_BASE);
|
|
-
|
|
- writel_relaxed(vp9_ctx->priv_tbl.dma +
|
|
- offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
|
|
- (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid),
|
|
- rkvdec->regs + RKVDEC_REG_VP9_SEGIDCUR_BASE);
|
|
- writel_relaxed(vp9_ctx->priv_tbl.dma +
|
|
- offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
|
|
- (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid)),
|
|
- rkvdec->regs + RKVDEC_REG_VP9_SEGIDLAST_BASE);
|
|
+ regs->common.strm_rlc_base = addr;
|
|
+
|
|
+ regs->common.cabactbl_base = vp9_ctx->priv_tbl.dma +
|
|
+ offsetof(struct rkvdec_vp9_priv_tbl, probs);
|
|
+
|
|
+ regs->vp9.count_base = vp9_ctx->count_tbl.dma;
|
|
+
|
|
+ regs->vp9.segidlast_base = vp9_ctx->priv_tbl.dma +
|
|
+ offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
|
|
+ (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid));
|
|
+
|
|
+ regs->vp9.segidcur_base = vp9_ctx->priv_tbl.dma +
|
|
+ offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
|
|
+ (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid);
|
|
|
|
if (!intra_only &&
|
|
!(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
|
|
@@ -685,12 +652,14 @@ static void config_registers(struct rkvdec_ctx *ctx,
|
|
else
|
|
mv_ref = dst;
|
|
|
|
- writel_relaxed(get_mv_base_addr(mv_ref),
|
|
- rkvdec->regs + RKVDEC_VP9_REF_COLMV_BASE);
|
|
+ regs->vp9.refcolmv_base = get_mv_base_addr(mv_ref);
|
|
|
|
- writel_relaxed(ctx->decoded_fmt.fmt.pix_mp.width |
|
|
- (ctx->decoded_fmt.fmt.pix_mp.height << 16),
|
|
- rkvdec->regs + RKVDEC_REG_PERFORMANCE_CYCLE);
|
|
+ regs->vp9.performance_cycle = ctx->decoded_fmt.fmt.pix_mp.width |
|
|
+ (ctx->decoded_fmt.fmt.pix_mp.height << 16);
|
|
+
|
|
+ regs->vp9.reg44.strmd_error_e = 0xe;
|
|
+
|
|
+ rkvdec_memcpy_toio(rkvdec->regs, regs, sizeof(*regs));
|
|
}
|
|
|
|
static int validate_dec_params(struct rkvdec_ctx *ctx,
|
|
@@ -823,8 +792,6 @@ static int rkvdec_vp9_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);
|
|
|
|
- writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
|
|
-
|
|
if (rkvdec->variant->quirks & RKVDEC_QUIRK_DISABLE_QOS)
|
|
rkvdec_quirks_disable_qos(ctx);
|
|
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
|
|
index ef0ad92600f3..540d549ec08d 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
|
|
@@ -914,6 +914,15 @@ void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx)
|
|
writel(reg, rkvdec->regs + RKVDEC_REG_QOS_CTRL);
|
|
}
|
|
|
|
+void rkvdec_memcpy_toio(void __iomem *dst, void *src, size_t len)
|
|
+{
|
|
+#ifdef CONFIG_ARM64
|
|
+ __iowrite32_copy(dst, src, len / 4);
|
|
+#else
|
|
+ memcpy_toio(dst, src, len);
|
|
+#endif
|
|
+}
|
|
+
|
|
static void rkvdec_device_run(void *priv)
|
|
{
|
|
struct rkvdec_ctx *ctx = priv;
|
|
@@ -1228,7 +1237,6 @@ static void rkvdec_watchdog_func(struct work_struct *work)
|
|
if (ctx) {
|
|
dev_err(rkvdec->dev, "Frame processing timed out!\n");
|
|
writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT);
|
|
- writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL);
|
|
rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
|
|
}
|
|
}
|
|
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
|
|
index 892d2380b59d..9ffc3060ce25 100644
|
|
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
|
|
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
|
|
@@ -151,6 +151,7 @@ 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_memcpy_toio(void __iomem *dst, void *src, size_t len);
|
|
|
|
void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx);
|
|
|
|
--
|
|
2.34.1
|
|
|