On Fri Jan 9 11:15:20 2026 -0500, Detlev Casanova wrote:
> 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/[email protected]/
> [2]: 
> https://lore.kernel.org/all/[email protected]/
> 
> Tested-by: Diederik de Haas <[email protected]>  # Rock 5B
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Detlev Casanova <[email protected]>
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 .../media/platform/rockchip/rkvdec/rkvdec-h264.c   | 166 +++---
 .../media/platform/rockchip/rkvdec/rkvdec-hevc.c   |  64 +--
 .../media/platform/rockchip/rkvdec/rkvdec-regs.h   | 586 ++++++++++++++-------
 .../media/platform/rockchip/rkvdec/rkvdec-vp9.c    | 232 ++++----
 drivers/media/platform/rockchip/rkvdec/rkvdec.c    |  10 +-
 drivers/media/platform/rockchip/rkvdec/rkvdec.h    |   1 +
 6 files changed, 604 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..68e20cb81a88 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->h26x.ref0_14_poc[id * 2] = poc;
+                       break;
+               case 8 ... 14:
+                       regs->h26x.ref15_29_poc[(id - 8) * 2 + 1] = poc;
+                       break;
+               case 15:
+                       regs->h26x.ref30_poc = poc;
+                       break;
+               }
+       } else {
+               switch (id) {
+               case 0 ... 6:
+                       regs->h26x.ref0_14_poc[id * 2 + 1] = poc;
+                       break;
+               case 7 ... 14:
+                       regs->h26x.ref15_29_poc[(id - 7) * 2] = poc;
+                       break;
+               case 15:
+                       regs->h26x.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->h26x.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,37 @@ 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 = &regs->h26x.ref0_14_base[i];
                else
-                       writel_relaxed(refer_addr,
-                                      rkvdec->regs + 
RKVDEC_REG_H264_BASE_REFER15);
-       }
+                       base = &regs->h26x.ref15_base;
 
-       reg = RKVDEC_CUR_POC(dec_params->top_field_order_cnt);
-       writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0);
+               base->base_addr = refer_addr >> 4;
+               base->field_ref = !!(dpb[i].flags & 
V4L2_H264_DPB_ENTRY_FLAG_FIELD);
+               base->colmv_use_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);
 
-       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->h26x.cur_poc = dec_params->top_field_order_cnt;
+       regs->h26x.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->h26x.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->h26x.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->h26x.errorinfo_base = priv_start_addr + offset;
+
+       rkvdec_memcpy_toio(rkvdec->regs, regs,
+                          MIN(sizeof(*regs), sizeof(u32) * 
rkvdec->variant->num_regs));
 }
 
 #define RKVDEC_H264_MAX_DEPTH_IN_BYTES         2
@@ -1181,8 +1159,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..2d9e0e947a6d 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));
+               regs->h26x.ref0_14_base[i].base_addr = refer_addr >> 4;
+               regs->h26x.ref0_14_base[i].field_ref = !!(reg & 1);
+               regs->h26x.ref0_14_base[i].topfield_used_ref = !!(reg & 2);
+               regs->h26x.ref0_14_base[i].botfield_used_ref = !!(reg & 4);
+               regs->h26x.ref0_14_base[i].colmv_use_flag_ref = !!(reg & 8);
+
+               regs->h26x.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->h26x.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->h26x.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->h26x.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,
+                          MIN(sizeof(*regs), sizeof(u32) * 
rkvdec->variant->num_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..1af66c5f1c9b 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,399 @@
 #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 dec_e_strmd_clkgate_dis     : 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 wr_ddr_align_en             : 1;
+               u32 scl_down_en                 : 1;
+               u32 allow_not_wr_unref_bframe   : 1;
+               u32 reserved1                   : 6;
+       } 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 colmv_mode                  : 1;
+               u32 ycacherd_prior              : 1;
+       } 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_use_flag_ref  : 1;
+       u32 base_addr           : 28;
+};
+
+struct rkvdec_h26x_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 strmd_error_slice_en        : 1;
+               u32 strmd_error_frame_en        : 1;
+       } reg77;
+
+       u32 colmv_cur_base;
+       u32 colmv_ref_base[16];
+       u32 scanlist_addr;
+       u32 reg96_sd_decout_base;
+       u32 sd_y_virstride;
+       u32 sd_hor_stride;
+       u32 qos_ctrl;
+       u32 perf[8];
+       u32 qos1;
+} __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_h26x_regs 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..ba51a7c2fe55 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,7 @@ 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;
        const struct v4l2_vp9_segmentation *seg;
        struct rkvdec_dev *rkvdec = ctx->dev;
        dma_addr_t addr;
@@ -547,8 +506,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 +518,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 +543,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;
@@ -606,46 +560,58 @@ static void config_registers(struct rkvdec_ctx *ctx,
                else
                        lf = &vp9_ctx->cur.lf;
 
-               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 +620,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 +650,15 @@ 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,
+                          MIN(sizeof(*regs), sizeof(u32) * 
rkvdec->variant->num_regs));
 }
 
 static int validate_dec_params(struct rkvdec_ctx *ctx,
@@ -823,8 +791,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 5af9aa5ab353..776149f871b0 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;
@@ -1227,7 +1236,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 566e06fa2b1e..f35f6e80ea2e 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);
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to