diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c
index 4fc167b42cf0c74fcc7adad5b867d9d7cd8af29b..85ca4a8967cebda4b0524fa3905e1a7390407dd3 100644
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
+++ b/drivers/staging/media/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,		\
@@ -839,46 +840,43 @@ static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
 	       sizeof(scaling->scaling_list_8x8));
 }
 
-/*
- * dpb poc related registers table
- */
-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 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 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 rkvdec_write_regs(struct rkvdec_dev *dev, struct rkvdec_regs *regs)
+{
+#ifdef CONFIG_ARM64
+	__iowrite32_copy(dev->regs, regs, sizeof(*regs) / 4);
+#else
+	memcpy_toio(dev->regs, regs, sizeof(*regs));
+#endif
+}
 
 static void config_registers(struct rkvdec_ctx *ctx,
 			     struct rkvdec_h264_run *run)
@@ -893,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;
@@ -902,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;
+
+	memset(regs, 0, sizeof(*regs));
 
-	reg = RKVDEC_MODE(RKVDEC_MODE_H264);
-	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL);
+	regs->common.reg02.dec_mode = RKVDEC_MODE_H264;
 
 	f = &ctx->decoded_fmt;
 	dst_fmt = &f->fmt.pix_mp;
@@ -920,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
@@ -962,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 = &regs->h264.ref0_14_base[i];
 		else
-			writel_relaxed(refer_addr,
-				       rkvdec->regs + RKVDEC_REG_H264_BASE_REFER15);
-	}
+			base = &regs->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_write_regs(rkvdec, regs);
 }
 
 #define RKVDEC_H264_MAX_DEPTH_IN_BYTES		2
@@ -1162,8 +1140,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/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h
index 15b9bee92016cfd85689368c83c7f271f1bd727f..541c5cb6f4bb1f08d8ae06cde6d8062b5182df73 100644
--- a/drivers/staging/media/rkvdec/rkvdec-regs.h
+++ b/drivers/staging/media/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)
@@ -29,195 +34,381 @@
 #define RKVDEC_FORCE_SOFTRESET_VALID			BIT(21)
 #define RKVDEC_SOFTRESET_RDY				BIT(22)
 
-#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)
+/*
+ * Cache configuration is not covered in the rang 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_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_PREF_LUMA_CACHE_COMMAND		0x410
-#define RKVDEC_REG_PREF_CHR_CACHE_COMMAND		0x450
+/* 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;
+		struct rkvdec_vp9_regs  vp9;
+	};
+} __packed;
 
 #endif /* RKVDEC_REGS_H_ */
diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c
index 0e7e16f20eeb08f4d54bfa8378247b59dec1bf8f..d33b9ecceefe3a9c42305aae6aa9af133f313238 100644
--- a/drivers/staging/media/rkvdec/rkvdec-vp9.c
+++ b/drivers/staging/media/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);
+	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;
 
-	if (!ref_reg->reg_yuv_stride)
-		return;
-
-	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);
+	regs->vp9.reg20_27[segid].segid_frame_skip_en =
+		v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid);
 
-	if (!segid &&
-	    (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
-		val |= RKVDEC_SEGID_ABS_DELTA(1);
-
-	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,
@@ -513,6 +472,15 @@ static void update_ctx_last_info(struct rkvdec_vp9_ctx *vp9_ctx)
 	vp9_ctx->last = vp9_ctx->cur;
 }
 
+static void rkvdec_write_regs(struct rkvdec_dev *dev, struct rkvdec_regs *regs)
+{
+#ifdef CONFIG_ARM64
+	__iowrite32_copy(dev->regs, regs, sizeof(*regs) / 4);
+#else
+	memcpy_toio(dev->regs, regs, sizeof(*regs));
+#endif
+}
+
 static void config_registers(struct rkvdec_ctx *ctx,
 			     const struct rkvdec_vp9_run *run)
 {
@@ -521,7 +489,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 +516,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 +528,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 +553,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 +573,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;
-
-	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.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_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY))
-		last_frame_info |= RKVDEC_LAST_INTRA_ONLY;
+	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 &&
-	    last->vp9.width == dst->vp9.width &&
-	    last->vp9.height == dst->vp9.height)
-		last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR;
+	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);
 
-	writel_relaxed(last_frame_info,
-		       rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME);
+	regs->vp9.reg33.last_widthheight_eqcur =
+		vp9_ctx->last.valid &&
+		last->vp9.width == dst->vp9.width &&
+		last->vp9.height == dst->vp9.height;
 
-	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 +631,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 +661,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);
+
+	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;
 
-	writel_relaxed(ctx->decoded_fmt.fmt.pix_mp.width |
-		       (ctx->decoded_fmt.fmt.pix_mp.height << 16),
-		       rkvdec->regs + RKVDEC_REG_PERFORMANCE_CYCLE);
+	rkvdec_write_regs(rkvdec, regs);
 }
 
 static int validate_dec_params(struct rkvdec_ctx *ctx,
@@ -823,7 +801,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);
 	/* Start decoding! */
 	writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E |
 	       RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E,
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index 2a44406d397f8c2b9ec26206794bfa5b612aa77c..8d36411b663b825201a878e5d583b033a3d8809e 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -999,7 +999,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);
 	}
 }