linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383
@ 2025-08-08 20:03 Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 01/12] media: rkvdec: Switch to using structs instead of writel Detlev Casanova
                   ` (13 more replies)
  0 siblings, 14 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

These variants are found respectively in the RK3588 and RK3576 SoCs.
This patch only adds support for H264 and H265 in both variants.

As there is a considerable part of the code that can be shared with the
already supported rkvdec decoder driver, the support for these variants
is added here rather than writing a new driver.

This patch set uses the newly introduced hevc_ext_sps_[ls]t_rps v4l2
controls for HEVC [1].
Therefore, a patched version of userpace tools is needed for HEVC
support (added for GStreamer[2] and in an early stage for FFmpeg[3]).

This patch set also depends on the preparation patch set sent earlier [4]
as well as the iommu restore fix [5] (already merged in linux-media) and
Nicolas Frattaroli's bitmap patch [6] to support setting registers that
uses upper 16 bits as masks.

[1]: https://lore.kernel.org/all/20250807194327.69900-1-detlev.casanova@collabora.com/
[2]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9355
[3]: https://gitlab.collabora.com/detlev/ffmpeg
[4]: https://lore.kernel.org/all/20250623160722.55938-1-detlev.casanova@collabora.com/
[5]: https://lore.kernel.org/all/20250508-rkvdec-iommu-reset-v1-1-c46b6efa6e9b@collabora.com/
[6]: https://lore.kernel.org/all/20250623-byeword-update-v2-1-cf1fc08a2e1f@collabora.com/

Changes since v1:
 - Add parsing of the short and long term ref frame sets from the new v4l2
   controls
 - Add RPS cache to avoid parsing the same data again
 - Fix HEVC pixel formats selection
 - Fix multiple indentation errors

Detlev Casanova (12):
  media: rkvdec: Switch to using structs instead of writel
  media: rkvdec: Move cabac table to its own source file
  media: rkvdec: Use structs to represent the HW RPS
  media: rkvdec: Move h264 functions to common file
  media: rkvdec: Add per variant configuration
  media: rkvdec: Add RCB and SRAM support
  media: rkvdec: Support per-variant interrupt handler
  media: rkvdec: Enable all clocks without naming them
  media: rkvdec: Add H264 support for the VDPU381 variant
  media: rkvdec: Add H264 support for the VDPU383 variant
  media: rkvdec: Add HEVC support for the VDPU381 variant
  media: rkvdec: Add HEVC support for the VDPU383 variant

 .../media/platform/rockchip/rkvdec/Kconfig    |    1 +
 .../media/platform/rockchip/rkvdec/Makefile   |   13 +-
 .../platform/rockchip/rkvdec/rkvdec-cabac.c   | 3944 +++++++++++++++++
 .../rockchip/rkvdec/rkvdec-h264-common.c      |  253 ++
 .../rockchip/rkvdec/rkvdec-h264-common.h      |   81 +
 .../platform/rockchip/rkvdec/rkvdec-h264.c    |  891 +---
 .../rockchip/rkvdec/rkvdec-hevc-common.c      |  511 +++
 .../rockchip/rkvdec/rkvdec-hevc-common.h      |  101 +
 .../platform/rockchip/rkvdec/rkvdec-rcb.c     |  174 +
 .../platform/rockchip/rkvdec/rkvdec-rcb.h     |   29 +
 .../platform/rockchip/rkvdec/rkvdec-regs.h    |  567 ++-
 .../rockchip/rkvdec/rkvdec-vdpu381-h264.c     |  469 ++
 .../rockchip/rkvdec/rkvdec-vdpu381-hevc.c     |  596 +++
 .../rockchip/rkvdec/rkvdec-vdpu381-regs.h     |  427 ++
 .../rockchip/rkvdec/rkvdec-vdpu383-h264.c     |  582 +++
 .../rockchip/rkvdec/rkvdec-vdpu383-hevc.c     |  688 +++
 .../rockchip/rkvdec/rkvdec-vdpu383-regs.h     |  284 ++
 .../platform/rockchip/rkvdec/rkvdec-vp9.c     |  230 +-
 .../media/platform/rockchip/rkvdec/rkvdec.c   |  569 ++-
 .../media/platform/rockchip/rkvdec/rkvdec.h   |   39 +
 20 files changed, 9260 insertions(+), 1189 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h

-- 
2.50.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 01/12] media: rkvdec: Switch to using structs instead of writel
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 02/12] media: rkvdec: Move cabac table to its own source file Detlev Casanova
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

In an effort to merge the rkvdec2 driver [1] with this one, switch from
writel() calls to using structs to represent the register mappings.

This is done in order to have all supported decoders use the same format
in the future and ease reading of the code.

Using structs also improves stability as the hardware is tested and
validated downstream using a similar method.
It was noticed, on decoders, that:
 - Some registers require to be writen in increasing order [2]
 - Some registers, even if unrelated, need to be written to their reset
   values (it was the case here for axi_ddr_[rw]data).

Using structs can also help improving performance later when, e.g.
multicore support is added on RK3588.

Performance seems to be slightly improved, but at least, not made worse.
Running fluster's JVT-AVC_V1 test suite with GStreamer on the Radxa ROCK
PI 4 SE gives the following times:

Before this patch:

- --jobs 1: Ran 129/135 tests successfully               in 77.167 secs
- --jobs 6: Ran 129/135 tests successfully               in 23.046 secs

With this patch:
- --jobs 1: Ran 129/135 tests successfully               in 70.698 secs
- --jobs 6: Ran 129/135 tests successfully               in 22.917 secs

This also shows that the fluster score hasn't changed.

[1]: https://lore.kernel.org/all/20250325213303.826925-1-detlev.casanova@collabora.com/
[2]: https://lore.kernel.org/all/20200127143009.15677-5-andrzej.p@collabora.com/

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../platform/rockchip/rkvdec/rkvdec-h264.c    | 165 +++--
 .../platform/rockchip/rkvdec/rkvdec-regs.h    | 567 ++++++++++++------
 .../platform/rockchip/rkvdec/rkvdec-vp9.c     | 230 +++----
 .../media/platform/rockchip/rkvdec/rkvdec.c   |  10 +-
 .../media/platform/rockchip/rkvdec/rkvdec.h   |   1 +
 5 files changed, 558 insertions(+), 415 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index d14b4d173448d..1adb2e1f5f0ed 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -115,6 +115,7 @@ struct rkvdec_h264_run {
 struct rkvdec_h264_ctx {
 	struct rkvdec_aux_buf priv_tbl;
 	struct rkvdec_h264_reflists reflists;
+	struct rkvdec_regs regs;
 };
 
 #define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n,		\
@@ -841,45 +842,41 @@ static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
 }
 
 /*
- * dpb poc related registers table
+ * Set the ref POC in the correct register.
+ *
+ * The 32 registers are spread across 3 regions, each alternating top and bottom ref POCs:
+ *  - 1: ref 0 to 14 contain top 0 to 7 and bottoms 0 to 6
+ *  - 2: ref 15 to 29 contain top 8 to 14 and bottoms 7 to 14
+ *  - 3: ref 30 and 31 which correspond to top 15 and bottom 15 respectively.
  */
-static const u32 poc_reg_tbl_top_field[16] = {
-	RKVDEC_REG_H264_POC_REFER0(0),
-	RKVDEC_REG_H264_POC_REFER0(2),
-	RKVDEC_REG_H264_POC_REFER0(4),
-	RKVDEC_REG_H264_POC_REFER0(6),
-	RKVDEC_REG_H264_POC_REFER0(8),
-	RKVDEC_REG_H264_POC_REFER0(10),
-	RKVDEC_REG_H264_POC_REFER0(12),
-	RKVDEC_REG_H264_POC_REFER0(14),
-	RKVDEC_REG_H264_POC_REFER1(1),
-	RKVDEC_REG_H264_POC_REFER1(3),
-	RKVDEC_REG_H264_POC_REFER1(5),
-	RKVDEC_REG_H264_POC_REFER1(7),
-	RKVDEC_REG_H264_POC_REFER1(9),
-	RKVDEC_REG_H264_POC_REFER1(11),
-	RKVDEC_REG_H264_POC_REFER1(13),
-	RKVDEC_REG_H264_POC_REFER2(0)
-};
-
-static const u32 poc_reg_tbl_bottom_field[16] = {
-	RKVDEC_REG_H264_POC_REFER0(1),
-	RKVDEC_REG_H264_POC_REFER0(3),
-	RKVDEC_REG_H264_POC_REFER0(5),
-	RKVDEC_REG_H264_POC_REFER0(7),
-	RKVDEC_REG_H264_POC_REFER0(9),
-	RKVDEC_REG_H264_POC_REFER0(11),
-	RKVDEC_REG_H264_POC_REFER0(13),
-	RKVDEC_REG_H264_POC_REFER1(0),
-	RKVDEC_REG_H264_POC_REFER1(2),
-	RKVDEC_REG_H264_POC_REFER1(4),
-	RKVDEC_REG_H264_POC_REFER1(6),
-	RKVDEC_REG_H264_POC_REFER1(8),
-	RKVDEC_REG_H264_POC_REFER1(10),
-	RKVDEC_REG_H264_POC_REFER1(12),
-	RKVDEC_REG_H264_POC_REFER1(14),
-	RKVDEC_REG_H264_POC_REFER2(1)
-};
+static void set_poc_reg(struct rkvdec_regs *regs, uint32_t poc, int id, bool bottom)
+{
+	if (!bottom) {
+		switch (id) {
+		case 0 ... 7:
+			regs->h264.ref0_14_poc[id * 2] = poc;
+			break;
+		case 8 ... 14:
+			regs->h264.ref15_29_poc[(id - 8) * 2 + 1] = poc;
+			break;
+		case 15:
+			regs->h264.ref30_poc = poc;
+			break;
+		}
+	} else {
+		switch (id) {
+		case 0 ... 6:
+			regs->h264.ref0_14_poc[id * 2 + 1] = poc;
+			break;
+		case 7 ... 14:
+			regs->h264.ref15_29_poc[(id - 7) * 2] = poc;
+			break;
+		case 15:
+			regs->h264.ref31_poc = poc;
+			break;
+		}
+	}
+}
 
 static void config_registers(struct rkvdec_ctx *ctx,
 			     struct rkvdec_h264_run *run)
@@ -894,6 +891,7 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
 	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
 	const struct v4l2_format *f;
+	struct rkvdec_regs *regs = &h264_ctx->regs;
 	dma_addr_t rlc_addr;
 	dma_addr_t refer_addr;
 	u32 rlc_len;
@@ -903,10 +901,11 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	u32 yuv_virstride = 0;
 	u32 offset;
 	dma_addr_t dst_addr;
-	u32 reg, i;
+	u32 i;
 
-	reg = RKVDEC_MODE(RKVDEC_MODE_H264);
-	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL);
+	memset(regs, 0, sizeof(*regs));
+
+	regs->common.reg02.dec_mode = RKVDEC_MODE_H264;
 
 	f = &ctx->decoded_fmt;
 	dst_fmt = &f->fmt.pix_mp;
@@ -921,39 +920,35 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	else if (sps->chroma_format_idc == 2)
 		yuv_virstride = 2 * y_virstride;
 
-	reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) |
-	      RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) |
-	      RKVDEC_SLICE_NUM_HIGHBIT |
-	      RKVDEC_SLICE_NUM_LOWBITS(0x7ff);
-	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_PICPAR);
+	regs->common.reg03.uv_hor_virstride = hor_virstride / 16;
+	regs->common.reg03.y_hor_virstride = hor_virstride / 16;
+	regs->common.reg03.slice_num_highbit = 1;
+	regs->common.reg03.slice_num_lowbits = 0x7ff;
 
 	/* config rlc base address */
 	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
-	writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
-	writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_RLCWRITE_BASE);
+	regs->common.strm_rlc_base = rlc_addr;
+	regs->h264.rlcwrite_base = rlc_addr;
 
 	rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
-	reg = RKVDEC_STRM_LEN(rlc_len);
-	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN);
+	regs->common.stream_len = rlc_len;
 
 	/* config cabac table */
 	offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table);
-	writel_relaxed(priv_start_addr + offset,
-		       rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
+	regs->common.cabactbl_base = priv_start_addr + offset;
 
 	/* config output base address */
 	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
-	writel_relaxed(dst_addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
+	regs->common.decout_base = dst_addr;
 
-	reg = RKVDEC_Y_VIRSTRIDE(y_virstride / 16);
-	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
+	regs->common.reg08.y_virstride = y_virstride / 16;
 
-	reg = RKVDEC_YUV_VIRSTRIDE(yuv_virstride / 16);
-	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
+	regs->common.reg09.yuv_virstride = yuv_virstride / 16;
 
 	/* config ref pic address & poc */
 	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
 		struct vb2_buffer *vb_buf = run->ref_buf[i];
+		struct ref_base *base;
 
 		/*
 		 * If a DPB entry is unused or invalid, address of current destination
@@ -963,54 +958,36 @@ static void config_registers(struct rkvdec_ctx *ctx,
 			vb_buf = &dst_buf->vb2_buf;
 		refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
 
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
-			refer_addr |= RKVDEC_COLMV_USED_FLAG_REF;
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)
-			refer_addr |= RKVDEC_FIELD_REF;
-
-		if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF)
-			refer_addr |= RKVDEC_TOPFIELD_USED_REF;
-		if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)
-			refer_addr |= RKVDEC_BOTFIELD_USED_REF;
-
-		writel_relaxed(dpb[i].top_field_order_cnt,
-			       rkvdec->regs +  poc_reg_tbl_top_field[i]);
-		writel_relaxed(dpb[i].bottom_field_order_cnt,
-			       rkvdec->regs + poc_reg_tbl_bottom_field[i]);
-
 		if (i < V4L2_H264_NUM_DPB_ENTRIES - 1)
-			writel_relaxed(refer_addr,
-				       rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i));
+			base = &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_memcpy_toio(rkvdec->regs, regs, sizeof(*regs));
 }
 
 #define RKVDEC_H264_MAX_DEPTH_IN_BYTES		2
@@ -1181,8 +1158,6 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
 
 	schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
 
-	writel(0, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
-	writel(0, rkvdec->regs + RKVDEC_REG_H264_ERR_E);
 	writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
 	writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
 
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h
index 15b9bee92016c..541c5cb6f4bb1 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)
@@ -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/media/platform/rockchip/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
index 0e7e16f20eeb0..6f81ddab229e9 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c
@@ -163,6 +163,7 @@ struct rkvdec_vp9_ctx {
 	struct v4l2_vp9_frame_context frame_context[4];
 	struct rkvdec_vp9_frame_info cur;
 	struct rkvdec_vp9_frame_info last;
+	struct rkvdec_regs regs;
 };
 
 static void write_coeff_plane(const u8 coef[6][6][3], u8 *coeff_plane)
@@ -347,38 +348,6 @@ static void init_probs(struct rkvdec_ctx *ctx,
 		init_inter_probs(ctx, run);
 }
 
-struct rkvdec_vp9_ref_reg {
-	u32 reg_frm_size;
-	u32 reg_hor_stride;
-	u32 reg_y_stride;
-	u32 reg_yuv_stride;
-	u32 reg_ref_base;
-};
-
-static struct rkvdec_vp9_ref_reg ref_regs[] = {
-	{
-		.reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(0),
-		.reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(0),
-		.reg_y_stride = RKVDEC_VP9_LAST_FRAME_YSTRIDE,
-		.reg_yuv_stride = RKVDEC_VP9_LAST_FRAME_YUVSTRIDE,
-		.reg_ref_base = RKVDEC_REG_VP9_LAST_FRAME_BASE,
-	},
-	{
-		.reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(1),
-		.reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(1),
-		.reg_y_stride = RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE,
-		.reg_yuv_stride = 0,
-		.reg_ref_base = RKVDEC_REG_VP9_GOLDEN_FRAME_BASE,
-	},
-	{
-		.reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(2),
-		.reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(2),
-		.reg_y_stride = RKVDEC_VP9_ALTREF_FRAME_YSTRIDE,
-		.reg_yuv_stride = 0,
-		.reg_ref_base = RKVDEC_REG_VP9_ALTREF_FRAME_BASE,
-	}
-};
-
 static struct rkvdec_decoded_buffer *
 get_ref_buf(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp)
 {
@@ -412,18 +381,17 @@ static dma_addr_t get_mv_base_addr(struct rkvdec_decoded_buffer *buf)
 static void config_ref_registers(struct rkvdec_ctx *ctx,
 				 const struct rkvdec_vp9_run *run,
 				 struct rkvdec_decoded_buffer *ref_buf,
-				 struct rkvdec_vp9_ref_reg *ref_reg)
+				 int i)
 {
 	unsigned int aligned_pitch, aligned_height, y_len, yuv_len;
-	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_regs *regs = &vp9_ctx->regs;
 
 	aligned_height = round_up(ref_buf->vp9.height, 64);
-	writel_relaxed(RKVDEC_VP9_FRAMEWIDTH(ref_buf->vp9.width) |
-		       RKVDEC_VP9_FRAMEHEIGHT(ref_buf->vp9.height),
-		       rkvdec->regs + ref_reg->reg_frm_size);
+	regs->vp9.reg17_19[i].frameheight = ref_buf->vp9.height;
+	regs->vp9.reg17_19[i].framewidth = ref_buf->vp9.width;
 
-	writel_relaxed(vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0),
-		       rkvdec->regs + ref_reg->reg_ref_base);
+	regs->vp9.refer_bases[i] = vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0);
 
 	if (&ref_buf->base.vb == run->base.bufs.dst)
 		return;
@@ -432,59 +400,50 @@ static void config_ref_registers(struct rkvdec_ctx *ctx,
 	y_len = aligned_height * aligned_pitch;
 	yuv_len = (y_len * 3) / 2;
 
-	writel_relaxed(RKVDEC_HOR_Y_VIRSTRIDE(aligned_pitch / 16) |
-		       RKVDEC_HOR_UV_VIRSTRIDE(aligned_pitch / 16),
-		       rkvdec->regs + ref_reg->reg_hor_stride);
-	writel_relaxed(RKVDEC_VP9_REF_YSTRIDE(y_len / 16),
-		       rkvdec->regs + ref_reg->reg_y_stride);
-
-	if (!ref_reg->reg_yuv_stride)
-		return;
+	regs->vp9.reg37_39[i].y_hor_virstride = aligned_pitch / 16;
+	regs->vp9.reg37_39[i].uv_hor_virstride = aligned_pitch / 16;
+	regs->vp9.reg48_50[i].virstride = y_len / 16;
 
-	writel_relaxed(RKVDEC_VP9_REF_YUVSTRIDE(yuv_len / 16),
-		       rkvdec->regs + ref_reg->reg_yuv_stride);
+	if (!i)
+		regs->vp9.reg51.lastref_yuv_virstride = yuv_len / 16;
 }
 
 static void config_seg_registers(struct rkvdec_ctx *ctx, unsigned int segid)
 {
 	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_regs *regs = &vp9_ctx->regs;
 	const struct v4l2_vp9_segmentation *seg;
-	struct rkvdec_dev *rkvdec = ctx->dev;
 	s16 feature_val;
 	int feature_id;
-	u32 val = 0;
 
 	seg = vp9_ctx->last.valid ? &vp9_ctx->last.seg : &vp9_ctx->cur.seg;
 	feature_id = V4L2_VP9_SEG_LVL_ALT_Q;
 	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
 		feature_val = seg->feature_data[segid][feature_id];
-		val |= RKVDEC_SEGID_FRAME_QP_DELTA_EN(1) |
-		       RKVDEC_SEGID_FRAME_QP_DELTA(feature_val);
+		regs->vp9.reg20_27[segid].segid_frame_qp_delta_en = 1;
+		regs->vp9.reg20_27[segid].segid_frame_qp_delta = feature_val;
 	}
 
 	feature_id = V4L2_VP9_SEG_LVL_ALT_L;
 	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
 		feature_val = seg->feature_data[segid][feature_id];
-		val |= RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(1) |
-		       RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(feature_val);
+		regs->vp9.reg20_27[segid].segid_frame_loopfilter_value_en = 1;
+		regs->vp9.reg20_27[segid].segid_frame_loopfilter_value = feature_val;
 	}
 
 	feature_id = V4L2_VP9_SEG_LVL_REF_FRAME;
 	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
 		feature_val = seg->feature_data[segid][feature_id];
-		val |= RKVDEC_SEGID_REFERINFO_EN(1) |
-		       RKVDEC_SEGID_REFERINFO(feature_val);
+		regs->vp9.reg20_27[segid].segid_referinfo_en = 1;
+		regs->vp9.reg20_27[segid].segid_referinfo = feature_val;
 	}
 
 	feature_id = V4L2_VP9_SEG_LVL_SKIP;
-	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid))
-		val |= RKVDEC_SEGID_FRAME_SKIP_EN(1);
-
-	if (!segid &&
-	    (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
-		val |= RKVDEC_SEGID_ABS_DELTA(1);
+	regs->vp9.reg20_27[segid].segid_frame_skip_en =
+		v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid);
 
-	writel_relaxed(val, rkvdec->regs + RKVDEC_VP9_SEGID_GRP(segid));
+	regs->vp9.reg20_27[segid].segid_abs_delta = !segid &&
+		(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE);
 }
 
 static void update_dec_buf_info(struct rkvdec_decoded_buffer *buf,
@@ -521,7 +480,8 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	struct rkvdec_decoded_buffer *ref_bufs[3];
 	struct rkvdec_decoded_buffer *dst, *last, *mv_ref;
 	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
-	u32 val, last_frame_info = 0;
+	struct rkvdec_regs *regs = &vp9_ctx->regs;
+	u32 val;
 	const struct v4l2_vp9_segmentation *seg;
 	struct rkvdec_dev *rkvdec = ctx->dev;
 	dma_addr_t addr;
@@ -547,8 +507,7 @@ static void config_registers(struct rkvdec_ctx *ctx,
 			(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
 			 V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
 
-	writel_relaxed(RKVDEC_MODE(RKVDEC_MODE_VP9),
-		       rkvdec->regs + RKVDEC_REG_SYSCTRL);
+	regs->common.reg02.dec_mode = RKVDEC_MODE_VP9;
 
 	bit_depth = dec_params->bit_depth;
 	aligned_height = round_up(ctx->decoded_fmt.fmt.pix_mp.height, 64);
@@ -560,17 +519,14 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	uv_len = y_len / 2;
 	yuv_len = y_len + uv_len;
 
-	writel_relaxed(RKVDEC_Y_HOR_VIRSTRIDE(aligned_pitch / 16) |
-		       RKVDEC_UV_HOR_VIRSTRIDE(aligned_pitch / 16),
-		       rkvdec->regs + RKVDEC_REG_PICPAR);
-	writel_relaxed(RKVDEC_Y_VIRSTRIDE(y_len / 16),
-		       rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
-	writel_relaxed(RKVDEC_YUV_VIRSTRIDE(yuv_len / 16),
-		       rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
+	regs->common.reg03.y_hor_virstride = aligned_pitch / 16;
+	regs->common.reg03.uv_hor_virstride = aligned_pitch / 16;
+	regs->common.reg08.y_virstride = y_len / 16;
+	regs->common.reg09.yuv_virstride = yuv_len / 16;
 
 	stream_len = vb2_get_plane_payload(&run->base.bufs.src->vb2_buf, 0);
-	writel_relaxed(RKVDEC_STRM_LEN(stream_len),
-		       rkvdec->regs + RKVDEC_REG_STRM_LEN);
+
+	regs->common.stream_len = stream_len;
 
 	/*
 	 * Reset count buffer, because decoder only output intra related syntax
@@ -588,14 +544,13 @@ static void config_registers(struct rkvdec_ctx *ctx,
 		vp9_ctx->cur.segmapid++;
 
 	for (i = 0; i < ARRAY_SIZE(ref_bufs); i++)
-		config_ref_registers(ctx, run, ref_bufs[i], &ref_regs[i]);
+		config_ref_registers(ctx, run, ref_bufs[i], i);
 
 	for (i = 0; i < 8; i++)
 		config_seg_registers(ctx, i);
 
-	writel_relaxed(RKVDEC_VP9_TX_MODE(vp9_ctx->cur.tx_mode) |
-		       RKVDEC_VP9_FRAME_REF_MODE(dec_params->reference_mode),
-		       rkvdec->regs + RKVDEC_VP9_CPRHEADER_CONFIG);
+	regs->vp9.reg28.tx_mode = vp9_ctx->cur.tx_mode;
+	regs->vp9.reg28.frame_reference_mode = dec_params->reference_mode;
 
 	if (!intra_only) {
 		const struct v4l2_vp9_loop_filter *lf;
@@ -609,43 +564,56 @@ static void config_registers(struct rkvdec_ctx *ctx,
 		val = 0;
 		for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) {
 			delta = lf->ref_deltas[i];
-			val |= RKVDEC_REF_DELTAS_LASTFRAME(i, delta);
+			switch (i) {
+			case 0:
+				regs->vp9.reg32.ref_deltas_lastframe0 = delta;
+				break;
+			case 1:
+				regs->vp9.reg32.ref_deltas_lastframe1 = delta;
+				break;
+			case 2:
+				regs->vp9.reg32.ref_deltas_lastframe2 = delta;
+				break;
+			case 3:
+				regs->vp9.reg32.ref_deltas_lastframe3 = delta;
+				break;
+			}
 		}
 
-		writel_relaxed(val,
-			       rkvdec->regs + RKVDEC_VP9_REF_DELTAS_LASTFRAME);
-
 		for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) {
 			delta = lf->mode_deltas[i];
-			last_frame_info |= RKVDEC_MODE_DELTAS_LASTFRAME(i,
-									delta);
+			switch (i) {
+			case 0:
+				regs->vp9.reg33.mode_deltas_lastframe0 = delta;
+				break;
+			case 1:
+				regs->vp9.reg33.mode_deltas_lastframe1 = delta;
+				break;
+			}
 		}
 	}
 
-	if (vp9_ctx->last.valid && !intra_only &&
-	    vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED)
-		last_frame_info |= RKVDEC_SEG_EN_LASTFRAME;
+	regs->vp9.reg33.segmentation_enable_lstframe =
+		vp9_ctx->last.valid && !intra_only &&
+		vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED;
 
-	if (vp9_ctx->last.valid &&
-	    vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME)
-		last_frame_info |= RKVDEC_LAST_SHOW_FRAME;
+	regs->vp9.reg33.last_show_frame =
+		vp9_ctx->last.valid &&
+		vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME;
 
-	if (vp9_ctx->last.valid &&
-	    vp9_ctx->last.flags &
-	    (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY))
-		last_frame_info |= RKVDEC_LAST_INTRA_ONLY;
+	regs->vp9.reg33.last_intra_only =
+		vp9_ctx->last.valid &&
+		vp9_ctx->last.flags &
+		(V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
 
-	if (vp9_ctx->last.valid &&
-	    last->vp9.width == dst->vp9.width &&
-	    last->vp9.height == dst->vp9.height)
-		last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR;
+	regs->vp9.reg33.last_widthheight_eqcur =
+		vp9_ctx->last.valid &&
+		last->vp9.width == dst->vp9.width &&
+		last->vp9.height == dst->vp9.height;
 
-	writel_relaxed(last_frame_info,
-		       rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME);
-
-	writel_relaxed(stream_len - dec_params->compressed_header_size -
-		       dec_params->uncompressed_header_size,
-		       rkvdec->regs + RKVDEC_VP9_LASTTILE_SIZE);
+	regs->vp9.reg36.lasttile_size =
+		stream_len - dec_params->compressed_header_size -
+		dec_params->uncompressed_header_size;
 
 	for (i = 0; !intra_only && i < ARRAY_SIZE(ref_bufs); i++) {
 		unsigned int refw = ref_bufs[i]->vp9.width;
@@ -654,29 +622,28 @@ static void config_registers(struct rkvdec_ctx *ctx,
 
 		hscale = (refw << 14) /	dst->vp9.width;
 		vscale = (refh << 14) / dst->vp9.height;
-		writel_relaxed(RKVDEC_VP9_REF_HOR_SCALE(hscale) |
-			       RKVDEC_VP9_REF_VER_SCALE(vscale),
-			       rkvdec->regs + RKVDEC_VP9_REF_SCALE(i));
+
+		regs->vp9.reg29_31[i].ref_hor_scale = hscale;
+		regs->vp9.reg29_31[i].ref_ver_scale = vscale;
 	}
 
 	addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0);
-	writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
+	regs->common.decout_base = addr;
 	addr = vb2_dma_contig_plane_dma_addr(&run->base.bufs.src->vb2_buf, 0);
-	writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
-	writel_relaxed(vp9_ctx->priv_tbl.dma +
-		       offsetof(struct rkvdec_vp9_priv_tbl, probs),
-		       rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
-	writel_relaxed(vp9_ctx->count_tbl.dma,
-		       rkvdec->regs + RKVDEC_REG_VP9COUNT_BASE);
-
-	writel_relaxed(vp9_ctx->priv_tbl.dma +
-		       offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
-		       (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid),
-		       rkvdec->regs + RKVDEC_REG_VP9_SEGIDCUR_BASE);
-	writel_relaxed(vp9_ctx->priv_tbl.dma +
-		       offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
-		       (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid)),
-		       rkvdec->regs + RKVDEC_REG_VP9_SEGIDLAST_BASE);
+	regs->common.strm_rlc_base = addr;
+
+	regs->common.cabactbl_base = vp9_ctx->priv_tbl.dma +
+		offsetof(struct rkvdec_vp9_priv_tbl, probs);
+
+	regs->vp9.count_base = vp9_ctx->count_tbl.dma;
+
+	regs->vp9.segidlast_base = vp9_ctx->priv_tbl.dma +
+		offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
+		(RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid));
+
+	regs->vp9.segidcur_base = vp9_ctx->priv_tbl.dma +
+		offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
+		(RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid);
 
 	if (!intra_only &&
 	    !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
@@ -685,12 +652,14 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	else
 		mv_ref = dst;
 
-	writel_relaxed(get_mv_base_addr(mv_ref),
-		       rkvdec->regs + RKVDEC_VP9_REF_COLMV_BASE);
+	regs->vp9.refcolmv_base = get_mv_base_addr(mv_ref);
+
+	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_memcpy_toio(rkvdec->regs, regs, sizeof(*regs));
 }
 
 static int validate_dec_params(struct rkvdec_ctx *ctx,
@@ -823,7 +792,6 @@ static int rkvdec_vp9_run(struct rkvdec_ctx *ctx)
 	writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
 	writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
 
-	writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
 	/* Start decoding! */
 	writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E |
 	       RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E,
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index d707088ec0dc1..a71837103b71d 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -795,6 +795,15 @@ void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run)
 		v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl);
 }
 
+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;
@@ -1106,7 +1115,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 f6e8bf38add3a..3451c4bf7cb75 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -137,6 +137,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);
 
 extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
 extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 02/12] media: rkvdec: Move cabac table to its own source file
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 01/12] media: rkvdec: Switch to using structs instead of writel Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 03/12] media: rkvdec: Use structs to represent the HW RPS Detlev Casanova
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

This is in preparation to add support for new variants that will use the
same table.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Makefile   |   6 +-
 .../platform/rockchip/rkvdec/rkvdec-cabac.c   | 509 ++++++++++++++++++
 .../platform/rockchip/rkvdec/rkvdec-h264.c    | 501 +----------------
 3 files changed, 516 insertions(+), 500 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index cb86b429cfaac..164ea06c26c2a 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -1,3 +1,7 @@
 obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o
 
-rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-vp9.o
+rockchip-vdec-y += \
+		   rkvdec.o \
+		   rkvdec-cabac.o \
+		   rkvdec-h264.o \
+		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c
new file mode 100644
index 0000000000000..6ac4b45cdcb73
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Video Decoder CABAC tables
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *	Boris Brezillon <boris.brezillon@collabora.com>
+ */
+
+#include <linux/types.h>
+
+#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n,		\
+	    idc2_m, idc2_n, intra_m, intra_n)			\
+	[0][(ctxidx)] = {idc0_m, idc0_n},			\
+	[1][(ctxidx)] = {idc1_m, idc1_n},			\
+	[2][(ctxidx)] = {idc2_m, idc2_n},			\
+	[3][(ctxidx)] = {intra_m, intra_n}
+
+/*
+ * Constant CABAC table.
+ * Built from the tables described in section '9.3.1.1 Initialisation process
+ * for context variables' of the H264 spec.
+ */
+const s8 rkvdec_h264_cabac_table[4][464][2] = {
+	/* Table 9-12 – Values of variables m and n for ctxIdx from 0 to 10 */
+	CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15),
+	CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54),
+	CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74),
+	CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15),
+	CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54),
+	CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74),
+	CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127),
+	CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104),
+	CABAC_ENTRY(8, -6, 53, -6, 53, -6, 53, -6, 53),
+	CABAC_ENTRY(9, -1, 54, -1, 54, -1, 54, -1, 54),
+	CABAC_ENTRY(10, 7, 51, 7, 51, 7, 51, 7, 51),
+
+	/* Table 9-13 – Values of variables m and n for ctxIdx from 11 to 23 */
+	CABAC_ENTRY(11, 23, 33, 22, 25, 29, 16, 0, 0),
+	CABAC_ENTRY(12, 23, 2, 34, 0, 25, 0, 0, 0),
+	CABAC_ENTRY(13, 21, 0, 16, 0, 14, 0, 0, 0),
+	CABAC_ENTRY(14, 1, 9, -2, 9, -10, 51, 0, 0),
+	CABAC_ENTRY(15, 0, 49, 4, 41, -3, 62, 0, 0),
+	CABAC_ENTRY(16, -37, 118, -29, 118, -27, 99, 0, 0),
+	CABAC_ENTRY(17, 5, 57, 2, 65, 26, 16, 0, 0),
+	CABAC_ENTRY(18, -13, 78, -6, 71, -4, 85, 0, 0),
+	CABAC_ENTRY(19, -11, 65, -13, 79, -24, 102, 0, 0),
+	CABAC_ENTRY(20, 1, 62, 5, 52, 5, 57, 0, 0),
+	CABAC_ENTRY(21, 12, 49, 9, 50, 6, 57, 0, 0),
+	CABAC_ENTRY(22, -4, 73, -3, 70, -17, 73, 0, 0),
+	CABAC_ENTRY(23, 17, 50, 10, 54, 14, 57, 0, 0),
+
+	/* Table 9-14 – Values of variables m and n for ctxIdx from 24 to 39 */
+	CABAC_ENTRY(24, 18, 64, 26, 34, 20, 40, 0, 0),
+	CABAC_ENTRY(25, 9, 43, 19, 22, 20, 10, 0, 0),
+	CABAC_ENTRY(26, 29, 0, 40, 0, 29, 0, 0, 0),
+	CABAC_ENTRY(27, 26, 67, 57, 2, 54, 0, 0, 0),
+	CABAC_ENTRY(28, 16, 90, 41, 36, 37, 42, 0, 0),
+	CABAC_ENTRY(29, 9, 104, 26, 69, 12, 97, 0, 0),
+	CABAC_ENTRY(30, -46, 127, -45, 127, -32, 127, 0, 0),
+	CABAC_ENTRY(31, -20, 104, -15, 101, -22, 117, 0, 0),
+	CABAC_ENTRY(32, 1, 67, -4, 76, -2, 74, 0, 0),
+	CABAC_ENTRY(33, -13, 78, -6, 71, -4, 85, 0, 0),
+	CABAC_ENTRY(34, -11, 65, -13, 79, -24, 102, 0, 0),
+	CABAC_ENTRY(35, 1, 62, 5, 52, 5, 57, 0, 0),
+	CABAC_ENTRY(36, -6, 86, 6, 69, -6, 93, 0, 0),
+	CABAC_ENTRY(37, -17, 95, -13, 90, -14, 88, 0, 0),
+	CABAC_ENTRY(38, -6, 61, 0, 52, -6, 44, 0, 0),
+	CABAC_ENTRY(39, 9, 45, 8, 43, 4, 55, 0, 0),
+
+	/* Table 9-15 – Values of variables m and n for ctxIdx from 40 to 53 */
+	CABAC_ENTRY(40, -3, 69, -2, 69, -11, 89, 0, 0),
+	CABAC_ENTRY(41, -6, 81, -5, 82, -15, 103, 0, 0),
+	CABAC_ENTRY(42, -11, 96, -10, 96, -21, 116, 0, 0),
+	CABAC_ENTRY(43, 6, 55, 2, 59, 19, 57, 0, 0),
+	CABAC_ENTRY(44, 7, 67, 2, 75, 20, 58, 0, 0),
+	CABAC_ENTRY(45, -5, 86, -3, 87, 4, 84, 0, 0),
+	CABAC_ENTRY(46, 2, 88, -3, 100, 6, 96, 0, 0),
+	CABAC_ENTRY(47, 0, 58, 1, 56, 1, 63, 0, 0),
+	CABAC_ENTRY(48, -3, 76, -3, 74, -5, 85, 0, 0),
+	CABAC_ENTRY(49, -10, 94, -6, 85, -13, 106, 0, 0),
+	CABAC_ENTRY(50, 5, 54, 0, 59, 5, 63, 0, 0),
+	CABAC_ENTRY(51, 4, 69, -3, 81, 6, 75, 0, 0),
+	CABAC_ENTRY(52, -3, 81, -7, 86, -3, 90, 0, 0),
+	CABAC_ENTRY(53, 0, 88, -5, 95, -1, 101, 0, 0),
+
+	/* Table 9-16 – Values of variables m and n for ctxIdx from 54 to 59 */
+	CABAC_ENTRY(54, -7, 67, -1, 66, 3, 55, 0, 0),
+	CABAC_ENTRY(55, -5, 74, -1, 77, -4, 79, 0, 0),
+	CABAC_ENTRY(56, -4, 74, 1, 70, -2, 75, 0, 0),
+	CABAC_ENTRY(57, -5, 80, -2, 86, -12, 97, 0, 0),
+	CABAC_ENTRY(58, -7, 72, -5, 72, -7, 50, 0, 0),
+	CABAC_ENTRY(59, 1, 58, 0, 61, 1, 60, 0, 0),
+
+	/* Table 9-17 – Values of variables m and n for ctxIdx from 60 to 69 */
+	CABAC_ENTRY(60, 0, 41, 0, 41, 0, 41, 0, 41),
+	CABAC_ENTRY(61, 0, 63, 0, 63, 0, 63, 0, 63),
+	CABAC_ENTRY(62, 0, 63, 0, 63, 0, 63, 0, 63),
+	CABAC_ENTRY(63, 0, 63, 0, 63, 0, 63, 0, 63),
+	CABAC_ENTRY(64, -9, 83, -9, 83, -9, 83, -9, 83),
+	CABAC_ENTRY(65, 4, 86, 4, 86, 4, 86, 4, 86),
+	CABAC_ENTRY(66, 0, 97, 0, 97, 0, 97, 0, 97),
+	CABAC_ENTRY(67, -7, 72, -7, 72, -7, 72, -7, 72),
+	CABAC_ENTRY(68, 13, 41, 13, 41, 13, 41, 13, 41),
+	CABAC_ENTRY(69, 3, 62, 3, 62, 3, 62, 3, 62),
+
+	/* Table 9-18 – Values of variables m and n for ctxIdx from 70 to 104 */
+	CABAC_ENTRY(70, 0, 45, 13, 15, 7, 34, 0, 11),
+	CABAC_ENTRY(71, -4, 78, 7, 51, -9, 88, 1, 55),
+	CABAC_ENTRY(72, -3, 96, 2, 80, -20, 127, 0, 69),
+	CABAC_ENTRY(73, -27, 126, -39, 127, -36, 127, -17, 127),
+	CABAC_ENTRY(74, -28, 98, -18, 91, -17, 91, -13, 102),
+	CABAC_ENTRY(75, -25, 101, -17, 96, -14, 95, 0, 82),
+	CABAC_ENTRY(76, -23, 67, -26, 81, -25, 84, -7, 74),
+	CABAC_ENTRY(77, -28, 82, -35, 98, -25, 86, -21, 107),
+	CABAC_ENTRY(78, -20, 94, -24, 102, -12, 89, -27, 127),
+	CABAC_ENTRY(79, -16, 83, -23, 97, -17, 91, -31, 127),
+	CABAC_ENTRY(80, -22, 110, -27, 119, -31, 127, -24, 127),
+	CABAC_ENTRY(81, -21, 91, -24, 99, -14, 76, -18, 95),
+	CABAC_ENTRY(82, -18, 102, -21, 110, -18, 103, -27, 127),
+	CABAC_ENTRY(83, -13, 93, -18, 102, -13, 90, -21, 114),
+	CABAC_ENTRY(84, -29, 127, -36, 127, -37, 127, -30, 127),
+	CABAC_ENTRY(85, -7, 92, 0, 80, 11, 80, -17, 123),
+	CABAC_ENTRY(86, -5, 89, -5, 89, 5, 76, -12, 115),
+	CABAC_ENTRY(87, -7, 96, -7, 94, 2, 84, -16, 122),
+	CABAC_ENTRY(88, -13, 108, -4, 92, 5, 78, -11, 115),
+	CABAC_ENTRY(89, -3, 46, 0, 39, -6, 55, -12, 63),
+	CABAC_ENTRY(90, -1, 65, 0, 65, 4, 61, -2, 68),
+	CABAC_ENTRY(91, -1, 57, -15, 84, -14, 83, -15, 84),
+	CABAC_ENTRY(92, -9, 93, -35, 127, -37, 127, -13, 104),
+	CABAC_ENTRY(93, -3, 74, -2, 73, -5, 79, -3, 70),
+	CABAC_ENTRY(94, -9, 92, -12, 104, -11, 104, -8, 93),
+	CABAC_ENTRY(95, -8, 87, -9, 91, -11, 91, -10, 90),
+	CABAC_ENTRY(96, -23, 126, -31, 127, -30, 127, -30, 127),
+	CABAC_ENTRY(97, 5, 54, 3, 55, 0, 65, -1, 74),
+	CABAC_ENTRY(98, 6, 60, 7, 56, -2, 79, -6, 97),
+	CABAC_ENTRY(99, 6, 59, 7, 55, 0, 72, -7, 91),
+	CABAC_ENTRY(100, 6, 69, 8, 61, -4, 92, -20, 127),
+	CABAC_ENTRY(101, -1, 48, -3, 53, -6, 56, -4, 56),
+	CABAC_ENTRY(102, 0, 68, 0, 68, 3, 68, -5, 82),
+	CABAC_ENTRY(103, -4, 69, -7, 74, -8, 71, -7, 76),
+	CABAC_ENTRY(104, -8, 88, -9, 88, -13, 98, -22, 125),
+
+	/* Table 9-19 – Values of variables m and n for ctxIdx from 105 to 165 */
+	CABAC_ENTRY(105, -2, 85, -13, 103, -4, 86, -7, 93),
+	CABAC_ENTRY(106, -6, 78, -13, 91, -12, 88, -11, 87),
+	CABAC_ENTRY(107, -1, 75, -9, 89, -5, 82, -3, 77),
+	CABAC_ENTRY(108, -7, 77, -14, 92, -3, 72, -5, 71),
+	CABAC_ENTRY(109, 2, 54, -8, 76, -4, 67, -4, 63),
+	CABAC_ENTRY(110, 5, 50, -12, 87, -8, 72, -4, 68),
+	CABAC_ENTRY(111, -3, 68, -23, 110, -16, 89, -12, 84),
+	CABAC_ENTRY(112, 1, 50, -24, 105, -9, 69, -7, 62),
+	CABAC_ENTRY(113, 6, 42, -10, 78, -1, 59, -7, 65),
+	CABAC_ENTRY(114, -4, 81, -20, 112, 5, 66, 8, 61),
+	CABAC_ENTRY(115, 1, 63, -17, 99, 4, 57, 5, 56),
+	CABAC_ENTRY(116, -4, 70, -78, 127, -4, 71, -2, 66),
+	CABAC_ENTRY(117, 0, 67, -70, 127, -2, 71, 1, 64),
+	CABAC_ENTRY(118, 2, 57, -50, 127, 2, 58, 0, 61),
+	CABAC_ENTRY(119, -2, 76, -46, 127, -1, 74, -2, 78),
+	CABAC_ENTRY(120, 11, 35, -4, 66, -4, 44, 1, 50),
+	CABAC_ENTRY(121, 4, 64, -5, 78, -1, 69, 7, 52),
+	CABAC_ENTRY(122, 1, 61, -4, 71, 0, 62, 10, 35),
+	CABAC_ENTRY(123, 11, 35, -8, 72, -7, 51, 0, 44),
+	CABAC_ENTRY(124, 18, 25, 2, 59, -4, 47, 11, 38),
+	CABAC_ENTRY(125, 12, 24, -1, 55, -6, 42, 1, 45),
+	CABAC_ENTRY(126, 13, 29, -7, 70, -3, 41, 0, 46),
+	CABAC_ENTRY(127, 13, 36, -6, 75, -6, 53, 5, 44),
+	CABAC_ENTRY(128, -10, 93, -8, 89, 8, 76, 31, 17),
+	CABAC_ENTRY(129, -7, 73, -34, 119, -9, 78, 1, 51),
+	CABAC_ENTRY(130, -2, 73, -3, 75, -11, 83, 7, 50),
+	CABAC_ENTRY(131, 13, 46, 32, 20, 9, 52, 28, 19),
+	CABAC_ENTRY(132, 9, 49, 30, 22, 0, 67, 16, 33),
+	CABAC_ENTRY(133, -7, 100, -44, 127, -5, 90, 14, 62),
+	CABAC_ENTRY(134, 9, 53, 0, 54, 1, 67, -13, 108),
+	CABAC_ENTRY(135, 2, 53, -5, 61, -15, 72, -15, 100),
+	CABAC_ENTRY(136, 5, 53, 0, 58, -5, 75, -13, 101),
+	CABAC_ENTRY(137, -2, 61, -1, 60, -8, 80, -13, 91),
+	CABAC_ENTRY(138, 0, 56, -3, 61, -21, 83, -12, 94),
+	CABAC_ENTRY(139, 0, 56, -8, 67, -21, 64, -10, 88),
+	CABAC_ENTRY(140, -13, 63, -25, 84, -13, 31, -16, 84),
+	CABAC_ENTRY(141, -5, 60, -14, 74, -25, 64, -10, 86),
+	CABAC_ENTRY(142, -1, 62, -5, 65, -29, 94, -7, 83),
+	CABAC_ENTRY(143, 4, 57, 5, 52, 9, 75, -13, 87),
+	CABAC_ENTRY(144, -6, 69, 2, 57, 17, 63, -19, 94),
+	CABAC_ENTRY(145, 4, 57, 0, 61, -8, 74, 1, 70),
+	CABAC_ENTRY(146, 14, 39, -9, 69, -5, 35, 0, 72),
+	CABAC_ENTRY(147, 4, 51, -11, 70, -2, 27, -5, 74),
+	CABAC_ENTRY(148, 13, 68, 18, 55, 13, 91, 18, 59),
+	CABAC_ENTRY(149, 3, 64, -4, 71, 3, 65, -8, 102),
+	CABAC_ENTRY(150, 1, 61, 0, 58, -7, 69, -15, 100),
+	CABAC_ENTRY(151, 9, 63, 7, 61, 8, 77, 0, 95),
+	CABAC_ENTRY(152, 7, 50, 9, 41, -10, 66, -4, 75),
+	CABAC_ENTRY(153, 16, 39, 18, 25, 3, 62, 2, 72),
+	CABAC_ENTRY(154, 5, 44, 9, 32, -3, 68, -11, 75),
+	CABAC_ENTRY(155, 4, 52, 5, 43, -20, 81, -3, 71),
+	CABAC_ENTRY(156, 11, 48, 9, 47, 0, 30, 15, 46),
+	CABAC_ENTRY(157, -5, 60, 0, 44, 1, 7, -13, 69),
+	CABAC_ENTRY(158, -1, 59, 0, 51, -3, 23, 0, 62),
+	CABAC_ENTRY(159, 0, 59, 2, 46, -21, 74, 0, 65),
+	CABAC_ENTRY(160, 22, 33, 19, 38, 16, 66, 21, 37),
+	CABAC_ENTRY(161, 5, 44, -4, 66, -23, 124, -15, 72),
+	CABAC_ENTRY(162, 14, 43, 15, 38, 17, 37, 9, 57),
+	CABAC_ENTRY(163, -1, 78, 12, 42, 44, -18, 16, 54),
+	CABAC_ENTRY(164, 0, 60, 9, 34, 50, -34, 0, 62),
+	CABAC_ENTRY(165, 9, 69, 0, 89, -22, 127, 12, 72),
+
+	/* Table 9-20 – Values of variables m and n for ctxIdx from 166 to 226 */
+	CABAC_ENTRY(166, 11, 28, 4, 45, 4, 39, 24, 0),
+	CABAC_ENTRY(167, 2, 40, 10, 28, 0, 42, 15, 9),
+	CABAC_ENTRY(168, 3, 44, 10, 31, 7, 34, 8, 25),
+	CABAC_ENTRY(169, 0, 49, 33, -11, 11, 29, 13, 18),
+	CABAC_ENTRY(170, 0, 46, 52, -43, 8, 31, 15, 9),
+	CABAC_ENTRY(171, 2, 44, 18, 15, 6, 37, 13, 19),
+	CABAC_ENTRY(172, 2, 51, 28, 0, 7, 42, 10, 37),
+	CABAC_ENTRY(173, 0, 47, 35, -22, 3, 40, 12, 18),
+	CABAC_ENTRY(174, 4, 39, 38, -25, 8, 33, 6, 29),
+	CABAC_ENTRY(175, 2, 62, 34, 0, 13, 43, 20, 33),
+	CABAC_ENTRY(176, 6, 46, 39, -18, 13, 36, 15, 30),
+	CABAC_ENTRY(177, 0, 54, 32, -12, 4, 47, 4, 45),
+	CABAC_ENTRY(178, 3, 54, 102, -94, 3, 55, 1, 58),
+	CABAC_ENTRY(179, 2, 58, 0, 0, 2, 58, 0, 62),
+	CABAC_ENTRY(180, 4, 63, 56, -15, 6, 60, 7, 61),
+	CABAC_ENTRY(181, 6, 51, 33, -4, 8, 44, 12, 38),
+	CABAC_ENTRY(182, 6, 57, 29, 10, 11, 44, 11, 45),
+	CABAC_ENTRY(183, 7, 53, 37, -5, 14, 42, 15, 39),
+	CABAC_ENTRY(184, 6, 52, 51, -29, 7, 48, 11, 42),
+	CABAC_ENTRY(185, 6, 55, 39, -9, 4, 56, 13, 44),
+	CABAC_ENTRY(186, 11, 45, 52, -34, 4, 52, 16, 45),
+	CABAC_ENTRY(187, 14, 36, 69, -58, 13, 37, 12, 41),
+	CABAC_ENTRY(188, 8, 53, 67, -63, 9, 49, 10, 49),
+	CABAC_ENTRY(189, -1, 82, 44, -5, 19, 58, 30, 34),
+	CABAC_ENTRY(190, 7, 55, 32, 7, 10, 48, 18, 42),
+	CABAC_ENTRY(191, -3, 78, 55, -29, 12, 45, 10, 55),
+	CABAC_ENTRY(192, 15, 46, 32, 1, 0, 69, 17, 51),
+	CABAC_ENTRY(193, 22, 31, 0, 0, 20, 33, 17, 46),
+	CABAC_ENTRY(194, -1, 84, 27, 36, 8, 63, 0, 89),
+	CABAC_ENTRY(195, 25, 7, 33, -25, 35, -18, 26, -19),
+	CABAC_ENTRY(196, 30, -7, 34, -30, 33, -25, 22, -17),
+	CABAC_ENTRY(197, 28, 3, 36, -28, 28, -3, 26, -17),
+	CABAC_ENTRY(198, 28, 4, 38, -28, 24, 10, 30, -25),
+	CABAC_ENTRY(199, 32, 0, 38, -27, 27, 0, 28, -20),
+	CABAC_ENTRY(200, 34, -1, 34, -18, 34, -14, 33, -23),
+	CABAC_ENTRY(201, 30, 6, 35, -16, 52, -44, 37, -27),
+	CABAC_ENTRY(202, 30, 6, 34, -14, 39, -24, 33, -23),
+	CABAC_ENTRY(203, 32, 9, 32, -8, 19, 17, 40, -28),
+	CABAC_ENTRY(204, 31, 19, 37, -6, 31, 25, 38, -17),
+	CABAC_ENTRY(205, 26, 27, 35, 0, 36, 29, 33, -11),
+	CABAC_ENTRY(206, 26, 30, 30, 10, 24, 33, 40, -15),
+	CABAC_ENTRY(207, 37, 20, 28, 18, 34, 15, 41, -6),
+	CABAC_ENTRY(208, 28, 34, 26, 25, 30, 20, 38, 1),
+	CABAC_ENTRY(209, 17, 70, 29, 41, 22, 73, 41, 17),
+	CABAC_ENTRY(210, 1, 67, 0, 75, 20, 34, 30, -6),
+	CABAC_ENTRY(211, 5, 59, 2, 72, 19, 31, 27, 3),
+	CABAC_ENTRY(212, 9, 67, 8, 77, 27, 44, 26, 22),
+	CABAC_ENTRY(213, 16, 30, 14, 35, 19, 16, 37, -16),
+	CABAC_ENTRY(214, 18, 32, 18, 31, 15, 36, 35, -4),
+	CABAC_ENTRY(215, 18, 35, 17, 35, 15, 36, 38, -8),
+	CABAC_ENTRY(216, 22, 29, 21, 30, 21, 28, 38, -3),
+	CABAC_ENTRY(217, 24, 31, 17, 45, 25, 21, 37, 3),
+	CABAC_ENTRY(218, 23, 38, 20, 42, 30, 20, 38, 5),
+	CABAC_ENTRY(219, 18, 43, 18, 45, 31, 12, 42, 0),
+	CABAC_ENTRY(220, 20, 41, 27, 26, 27, 16, 35, 16),
+	CABAC_ENTRY(221, 11, 63, 16, 54, 24, 42, 39, 22),
+	CABAC_ENTRY(222, 9, 59, 7, 66, 0, 93, 14, 48),
+	CABAC_ENTRY(223, 9, 64, 16, 56, 14, 56, 27, 37),
+	CABAC_ENTRY(224, -1, 94, 11, 73, 15, 57, 21, 60),
+	CABAC_ENTRY(225, -2, 89, 10, 67, 26, 38, 12, 68),
+	CABAC_ENTRY(226, -9, 108, -10, 116, -24, 127, 2, 97),
+
+	/* Table 9-21 – Values of variables m and n for ctxIdx from 227 to 275 */
+	CABAC_ENTRY(227, -6, 76, -23, 112, -24, 115, -3, 71),
+	CABAC_ENTRY(228, -2, 44, -15, 71, -22, 82, -6, 42),
+	CABAC_ENTRY(229, 0, 45, -7, 61, -9, 62, -5, 50),
+	CABAC_ENTRY(230, 0, 52, 0, 53, 0, 53, -3, 54),
+	CABAC_ENTRY(231, -3, 64, -5, 66, 0, 59, -2, 62),
+	CABAC_ENTRY(232, -2, 59, -11, 77, -14, 85, 0, 58),
+	CABAC_ENTRY(233, -4, 70, -9, 80, -13, 89, 1, 63),
+	CABAC_ENTRY(234, -4, 75, -9, 84, -13, 94, -2, 72),
+	CABAC_ENTRY(235, -8, 82, -10, 87, -11, 92, -1, 74),
+	CABAC_ENTRY(236, -17, 102, -34, 127, -29, 127, -9, 91),
+	CABAC_ENTRY(237, -9, 77, -21, 101, -21, 100, -5, 67),
+	CABAC_ENTRY(238, 3, 24, -3, 39, -14, 57, -5, 27),
+	CABAC_ENTRY(239, 0, 42, -5, 53, -12, 67, -3, 39),
+	CABAC_ENTRY(240, 0, 48, -7, 61, -11, 71, -2, 44),
+	CABAC_ENTRY(241, 0, 55, -11, 75, -10, 77, 0, 46),
+	CABAC_ENTRY(242, -6, 59, -15, 77, -21, 85, -16, 64),
+	CABAC_ENTRY(243, -7, 71, -17, 91, -16, 88, -8, 68),
+	CABAC_ENTRY(244, -12, 83, -25, 107, -23, 104, -10, 78),
+	CABAC_ENTRY(245, -11, 87, -25, 111, -15, 98, -6, 77),
+	CABAC_ENTRY(246, -30, 119, -28, 122, -37, 127, -10, 86),
+	CABAC_ENTRY(247, 1, 58, -11, 76, -10, 82, -12, 92),
+	CABAC_ENTRY(248, -3, 29, -10, 44, -8, 48, -15, 55),
+	CABAC_ENTRY(249, -1, 36, -10, 52, -8, 61, -10, 60),
+	CABAC_ENTRY(250, 1, 38, -10, 57, -8, 66, -6, 62),
+	CABAC_ENTRY(251, 2, 43, -9, 58, -7, 70, -4, 65),
+	CABAC_ENTRY(252, -6, 55, -16, 72, -14, 75, -12, 73),
+	CABAC_ENTRY(253, 0, 58, -7, 69, -10, 79, -8, 76),
+	CABAC_ENTRY(254, 0, 64, -4, 69, -9, 83, -7, 80),
+	CABAC_ENTRY(255, -3, 74, -5, 74, -12, 92, -9, 88),
+	CABAC_ENTRY(256, -10, 90, -9, 86, -18, 108, -17, 110),
+	CABAC_ENTRY(257, 0, 70, 2, 66, -4, 79, -11, 97),
+	CABAC_ENTRY(258, -4, 29, -9, 34, -22, 69, -20, 84),
+	CABAC_ENTRY(259, 5, 31, 1, 32, -16, 75, -11, 79),
+	CABAC_ENTRY(260, 7, 42, 11, 31, -2, 58, -6, 73),
+	CABAC_ENTRY(261, 1, 59, 5, 52, 1, 58, -4, 74),
+	CABAC_ENTRY(262, -2, 58, -2, 55, -13, 78, -13, 86),
+	CABAC_ENTRY(263, -3, 72, -2, 67, -9, 83, -13, 96),
+	CABAC_ENTRY(264, -3, 81, 0, 73, -4, 81, -11, 97),
+	CABAC_ENTRY(265, -11, 97, -8, 89, -13, 99, -19, 117),
+	CABAC_ENTRY(266, 0, 58, 3, 52, -13, 81, -8, 78),
+	CABAC_ENTRY(267, 8, 5, 7, 4, -6, 38, -5, 33),
+	CABAC_ENTRY(268, 10, 14, 10, 8, -13, 62, -4, 48),
+	CABAC_ENTRY(269, 14, 18, 17, 8, -6, 58, -2, 53),
+	CABAC_ENTRY(270, 13, 27, 16, 19, -2, 59, -3, 62),
+	CABAC_ENTRY(271, 2, 40, 3, 37, -16, 73, -13, 71),
+	CABAC_ENTRY(272, 0, 58, -1, 61, -10, 76, -10, 79),
+	CABAC_ENTRY(273, -3, 70, -5, 73, -13, 86, -12, 86),
+	CABAC_ENTRY(274, -6, 79, -1, 70, -9, 83, -13, 90),
+	CABAC_ENTRY(275, -8, 85, -4, 78, -10, 87, -14, 97),
+
+	/* Table 9-22 – Values of variables m and n for ctxIdx from 277 to 337 */
+	CABAC_ENTRY(277, -13, 106, -21, 126, -22, 127, -6, 93),
+	CABAC_ENTRY(278, -16, 106, -23, 124, -25, 127, -6, 84),
+	CABAC_ENTRY(279, -10, 87, -20, 110, -25, 120, -8, 79),
+	CABAC_ENTRY(280, -21, 114, -26, 126, -27, 127, 0, 66),
+	CABAC_ENTRY(281, -18, 110, -25, 124, -19, 114, -1, 71),
+	CABAC_ENTRY(282, -14, 98, -17, 105, -23, 117, 0, 62),
+	CABAC_ENTRY(283, -22, 110, -27, 121, -25, 118, -2, 60),
+	CABAC_ENTRY(284, -21, 106, -27, 117, -26, 117, -2, 59),
+	CABAC_ENTRY(285, -18, 103, -17, 102, -24, 113, -5, 75),
+	CABAC_ENTRY(286, -21, 107, -26, 117, -28, 118, -3, 62),
+	CABAC_ENTRY(287, -23, 108, -27, 116, -31, 120, -4, 58),
+	CABAC_ENTRY(288, -26, 112, -33, 122, -37, 124, -9, 66),
+	CABAC_ENTRY(289, -10, 96, -10, 95, -10, 94, -1, 79),
+	CABAC_ENTRY(290, -12, 95, -14, 100, -15, 102, 0, 71),
+	CABAC_ENTRY(291, -5, 91, -8, 95, -10, 99, 3, 68),
+	CABAC_ENTRY(292, -9, 93, -17, 111, -13, 106, 10, 44),
+	CABAC_ENTRY(293, -22, 94, -28, 114, -50, 127, -7, 62),
+	CABAC_ENTRY(294, -5, 86, -6, 89, -5, 92, 15, 36),
+	CABAC_ENTRY(295, 9, 67, -2, 80, 17, 57, 14, 40),
+	CABAC_ENTRY(296, -4, 80, -4, 82, -5, 86, 16, 27),
+	CABAC_ENTRY(297, -10, 85, -9, 85, -13, 94, 12, 29),
+	CABAC_ENTRY(298, -1, 70, -8, 81, -12, 91, 1, 44),
+	CABAC_ENTRY(299, 7, 60, -1, 72, -2, 77, 20, 36),
+	CABAC_ENTRY(300, 9, 58, 5, 64, 0, 71, 18, 32),
+	CABAC_ENTRY(301, 5, 61, 1, 67, -1, 73, 5, 42),
+	CABAC_ENTRY(302, 12, 50, 9, 56, 4, 64, 1, 48),
+	CABAC_ENTRY(303, 15, 50, 0, 69, -7, 81, 10, 62),
+	CABAC_ENTRY(304, 18, 49, 1, 69, 5, 64, 17, 46),
+	CABAC_ENTRY(305, 17, 54, 7, 69, 15, 57, 9, 64),
+	CABAC_ENTRY(306, 10, 41, -7, 69, 1, 67, -12, 104),
+	CABAC_ENTRY(307, 7, 46, -6, 67, 0, 68, -11, 97),
+	CABAC_ENTRY(308, -1, 51, -16, 77, -10, 67, -16, 96),
+	CABAC_ENTRY(309, 7, 49, -2, 64, 1, 68, -7, 88),
+	CABAC_ENTRY(310, 8, 52, 2, 61, 0, 77, -8, 85),
+	CABAC_ENTRY(311, 9, 41, -6, 67, 2, 64, -7, 85),
+	CABAC_ENTRY(312, 6, 47, -3, 64, 0, 68, -9, 85),
+	CABAC_ENTRY(313, 2, 55, 2, 57, -5, 78, -13, 88),
+	CABAC_ENTRY(314, 13, 41, -3, 65, 7, 55, 4, 66),
+	CABAC_ENTRY(315, 10, 44, -3, 66, 5, 59, -3, 77),
+	CABAC_ENTRY(316, 6, 50, 0, 62, 2, 65, -3, 76),
+	CABAC_ENTRY(317, 5, 53, 9, 51, 14, 54, -6, 76),
+	CABAC_ENTRY(318, 13, 49, -1, 66, 15, 44, 10, 58),
+	CABAC_ENTRY(319, 4, 63, -2, 71, 5, 60, -1, 76),
+	CABAC_ENTRY(320, 6, 64, -2, 75, 2, 70, -1, 83),
+	CABAC_ENTRY(321, -2, 69, -1, 70, -2, 76, -7, 99),
+	CABAC_ENTRY(322, -2, 59, -9, 72, -18, 86, -14, 95),
+	CABAC_ENTRY(323, 6, 70, 14, 60, 12, 70, 2, 95),
+	CABAC_ENTRY(324, 10, 44, 16, 37, 5, 64, 0, 76),
+	CABAC_ENTRY(325, 9, 31, 0, 47, -12, 70, -5, 74),
+	CABAC_ENTRY(326, 12, 43, 18, 35, 11, 55, 0, 70),
+	CABAC_ENTRY(327, 3, 53, 11, 37, 5, 56, -11, 75),
+	CABAC_ENTRY(328, 14, 34, 12, 41, 0, 69, 1, 68),
+	CABAC_ENTRY(329, 10, 38, 10, 41, 2, 65, 0, 65),
+	CABAC_ENTRY(330, -3, 52, 2, 48, -6, 74, -14, 73),
+	CABAC_ENTRY(331, 13, 40, 12, 41, 5, 54, 3, 62),
+	CABAC_ENTRY(332, 17, 32, 13, 41, 7, 54, 4, 62),
+	CABAC_ENTRY(333, 7, 44, 0, 59, -6, 76, -1, 68),
+	CABAC_ENTRY(334, 7, 38, 3, 50, -11, 82, -13, 75),
+	CABAC_ENTRY(335, 13, 50, 19, 40, -2, 77, 11, 55),
+	CABAC_ENTRY(336, 10, 57, 3, 66, -2, 77, 5, 64),
+	CABAC_ENTRY(337, 26, 43, 18, 50, 25, 42, 12, 70),
+
+	/* Table 9-23 – Values of variables m and n for ctxIdx from 338 to 398 */
+	CABAC_ENTRY(338, 14, 11, 19, -6, 17, -13, 15, 6),
+	CABAC_ENTRY(339, 11, 14, 18, -6, 16, -9, 6, 19),
+	CABAC_ENTRY(340, 9, 11, 14, 0, 17, -12, 7, 16),
+	CABAC_ENTRY(341, 18, 11, 26, -12, 27, -21, 12, 14),
+	CABAC_ENTRY(342, 21, 9, 31, -16, 37, -30, 18, 13),
+	CABAC_ENTRY(343, 23, -2, 33, -25, 41, -40, 13, 11),
+	CABAC_ENTRY(344, 32, -15, 33, -22, 42, -41, 13, 15),
+	CABAC_ENTRY(345, 32, -15, 37, -28, 48, -47, 15, 16),
+	CABAC_ENTRY(346, 34, -21, 39, -30, 39, -32, 12, 23),
+	CABAC_ENTRY(347, 39, -23, 42, -30, 46, -40, 13, 23),
+	CABAC_ENTRY(348, 42, -33, 47, -42, 52, -51, 15, 20),
+	CABAC_ENTRY(349, 41, -31, 45, -36, 46, -41, 14, 26),
+	CABAC_ENTRY(350, 46, -28, 49, -34, 52, -39, 14, 44),
+	CABAC_ENTRY(351, 38, -12, 41, -17, 43, -19, 17, 40),
+	CABAC_ENTRY(352, 21, 29, 32, 9, 32, 11, 17, 47),
+	CABAC_ENTRY(353, 45, -24, 69, -71, 61, -55, 24, 17),
+	CABAC_ENTRY(354, 53, -45, 63, -63, 56, -46, 21, 21),
+	CABAC_ENTRY(355, 48, -26, 66, -64, 62, -50, 25, 22),
+	CABAC_ENTRY(356, 65, -43, 77, -74, 81, -67, 31, 27),
+	CABAC_ENTRY(357, 43, -19, 54, -39, 45, -20, 22, 29),
+	CABAC_ENTRY(358, 39, -10, 52, -35, 35, -2, 19, 35),
+	CABAC_ENTRY(359, 30, 9, 41, -10, 28, 15, 14, 50),
+	CABAC_ENTRY(360, 18, 26, 36, 0, 34, 1, 10, 57),
+	CABAC_ENTRY(361, 20, 27, 40, -1, 39, 1, 7, 63),
+	CABAC_ENTRY(362, 0, 57, 30, 14, 30, 17, -2, 77),
+	CABAC_ENTRY(363, -14, 82, 28, 26, 20, 38, -4, 82),
+	CABAC_ENTRY(364, -5, 75, 23, 37, 18, 45, -3, 94),
+	CABAC_ENTRY(365, -19, 97, 12, 55, 15, 54, 9, 69),
+	CABAC_ENTRY(366, -35, 125, 11, 65, 0, 79, -12, 109),
+	CABAC_ENTRY(367, 27, 0, 37, -33, 36, -16, 36, -35),
+	CABAC_ENTRY(368, 28, 0, 39, -36, 37, -14, 36, -34),
+	CABAC_ENTRY(369, 31, -4, 40, -37, 37, -17, 32, -26),
+	CABAC_ENTRY(370, 27, 6, 38, -30, 32, 1, 37, -30),
+	CABAC_ENTRY(371, 34, 8, 46, -33, 34, 15, 44, -32),
+	CABAC_ENTRY(372, 30, 10, 42, -30, 29, 15, 34, -18),
+	CABAC_ENTRY(373, 24, 22, 40, -24, 24, 25, 34, -15),
+	CABAC_ENTRY(374, 33, 19, 49, -29, 34, 22, 40, -15),
+	CABAC_ENTRY(375, 22, 32, 38, -12, 31, 16, 33, -7),
+	CABAC_ENTRY(376, 26, 31, 40, -10, 35, 18, 35, -5),
+	CABAC_ENTRY(377, 21, 41, 38, -3, 31, 28, 33, 0),
+	CABAC_ENTRY(378, 26, 44, 46, -5, 33, 41, 38, 2),
+	CABAC_ENTRY(379, 23, 47, 31, 20, 36, 28, 33, 13),
+	CABAC_ENTRY(380, 16, 65, 29, 30, 27, 47, 23, 35),
+	CABAC_ENTRY(381, 14, 71, 25, 44, 21, 62, 13, 58),
+	CABAC_ENTRY(382, 8, 60, 12, 48, 18, 31, 29, -3),
+	CABAC_ENTRY(383, 6, 63, 11, 49, 19, 26, 26, 0),
+	CABAC_ENTRY(384, 17, 65, 26, 45, 36, 24, 22, 30),
+	CABAC_ENTRY(385, 21, 24, 22, 22, 24, 23, 31, -7),
+	CABAC_ENTRY(386, 23, 20, 23, 22, 27, 16, 35, -15),
+	CABAC_ENTRY(387, 26, 23, 27, 21, 24, 30, 34, -3),
+	CABAC_ENTRY(388, 27, 32, 33, 20, 31, 29, 34, 3),
+	CABAC_ENTRY(389, 28, 23, 26, 28, 22, 41, 36, -1),
+	CABAC_ENTRY(390, 28, 24, 30, 24, 22, 42, 34, 5),
+	CABAC_ENTRY(391, 23, 40, 27, 34, 16, 60, 32, 11),
+	CABAC_ENTRY(392, 24, 32, 18, 42, 15, 52, 35, 5),
+	CABAC_ENTRY(393, 28, 29, 25, 39, 14, 60, 34, 12),
+	CABAC_ENTRY(394, 23, 42, 18, 50, 3, 78, 39, 11),
+	CABAC_ENTRY(395, 19, 57, 12, 70, -16, 123, 30, 29),
+	CABAC_ENTRY(396, 22, 53, 21, 54, 21, 53, 34, 26),
+	CABAC_ENTRY(397, 22, 61, 14, 71, 22, 56, 29, 39),
+	CABAC_ENTRY(398, 11, 86, 11, 83, 25, 61, 19, 66),
+
+	/* Values of variables m and n for ctxIdx from 399 to 463 (not documented) */
+	CABAC_ENTRY(399, 12, 40, 25, 32, 21, 33, 31, 21),
+	CABAC_ENTRY(400, 11, 51, 21, 49, 19, 50, 31, 31),
+	CABAC_ENTRY(401, 14, 59, 21, 54, 17, 61, 25, 50),
+	CABAC_ENTRY(402, -4, 79, -5, 85, -3, 78, -17, 120),
+	CABAC_ENTRY(403, -7, 71, -6, 81, -8, 74, -20, 112),
+	CABAC_ENTRY(404, -5, 69, -10, 77, -9, 72, -18, 114),
+	CABAC_ENTRY(405, -9, 70, -7, 81, -10, 72, -11, 85),
+	CABAC_ENTRY(406, -8, 66, -17, 80, -18, 75, -15, 92),
+	CABAC_ENTRY(407, -10, 68, -18, 73, -12, 71, -14, 89),
+	CABAC_ENTRY(408, -19, 73, -4, 74, -11, 63, -26, 71),
+	CABAC_ENTRY(409, -12, 69, -10, 83, -5, 70, -15, 81),
+	CABAC_ENTRY(410, -16, 70, -9, 71, -17, 75, -14, 80),
+	CABAC_ENTRY(411, -15, 67, -9, 67, -14, 72, 0, 68),
+	CABAC_ENTRY(412, -20, 62, -1, 61, -16, 67, -14, 70),
+	CABAC_ENTRY(413, -19, 70, -8, 66, -8, 53, -24, 56),
+	CABAC_ENTRY(414, -16, 66, -14, 66, -14, 59, -23, 68),
+	CABAC_ENTRY(415, -22, 65, 0, 59, -9, 52, -24, 50),
+	CABAC_ENTRY(416, -20, 63, 2, 59, -11, 68, -11, 74),
+	CABAC_ENTRY(417, 9, -2, 17, -10, 9, -2, 23, -13),
+	CABAC_ENTRY(418, 26, -9, 32, -13, 30, -10, 26, -13),
+	CABAC_ENTRY(419, 33, -9, 42, -9, 31, -4, 40, -15),
+	CABAC_ENTRY(420, 39, -7, 49, -5, 33, -1, 49, -14),
+	CABAC_ENTRY(421, 41, -2, 53, 0, 33, 7, 44, 3),
+	CABAC_ENTRY(422, 45, 3, 64, 3, 31, 12, 45, 6),
+	CABAC_ENTRY(423, 49, 9, 68, 10, 37, 23, 44, 34),
+	CABAC_ENTRY(424, 45, 27, 66, 27, 31, 38, 33, 54),
+	CABAC_ENTRY(425, 36, 59, 47, 57, 20, 64, 19, 82),
+	CABAC_ENTRY(426, -6, 66, -5, 71, -9, 71, -3, 75),
+	CABAC_ENTRY(427, -7, 35, 0, 24, -7, 37, -1, 23),
+	CABAC_ENTRY(428, -7, 42, -1, 36, -8, 44, 1, 34),
+	CABAC_ENTRY(429, -8, 45, -2, 42, -11, 49, 1, 43),
+	CABAC_ENTRY(430, -5, 48, -2, 52, -10, 56, 0, 54),
+	CABAC_ENTRY(431, -12, 56, -9, 57, -12, 59, -2, 55),
+	CABAC_ENTRY(432, -6, 60, -6, 63, -8, 63, 0, 61),
+	CABAC_ENTRY(433, -5, 62, -4, 65, -9, 67, 1, 64),
+	CABAC_ENTRY(434, -8, 66, -4, 67, -6, 68, 0, 68),
+	CABAC_ENTRY(435, -8, 76, -7, 82, -10, 79, -9, 92),
+	CABAC_ENTRY(436, -5, 85, -3, 81, -3, 78, -14, 106),
+	CABAC_ENTRY(437, -6, 81, -3, 76, -8, 74, -13, 97),
+	CABAC_ENTRY(438, -10, 77, -7, 72, -9, 72, -15, 90),
+	CABAC_ENTRY(439, -7, 81, -6, 78, -10, 72, -12, 90),
+	CABAC_ENTRY(440, -17, 80, -12, 72, -18, 75, -18, 88),
+	CABAC_ENTRY(441, -18, 73, -14, 68, -12, 71, -10, 73),
+	CABAC_ENTRY(442, -4, 74, -3, 70, -11, 63, -9, 79),
+	CABAC_ENTRY(443, -10, 83, -6, 76, -5, 70, -14, 86),
+	CABAC_ENTRY(444, -9, 71, -5, 66, -17, 75, -10, 73),
+	CABAC_ENTRY(445, -9, 67, -5, 62, -14, 72, -10, 70),
+	CABAC_ENTRY(446, -1, 61, 0, 57, -16, 67, -10, 69),
+	CABAC_ENTRY(447, -8, 66, -4, 61, -8, 53, -5, 66),
+	CABAC_ENTRY(448, -14, 66, -9, 60, -14, 59, -9, 64),
+	CABAC_ENTRY(449, 0, 59, 1, 54, -9, 52, -5, 58),
+	CABAC_ENTRY(450, 2, 59, 2, 58, -11, 68, 2, 59),
+	CABAC_ENTRY(451, 21, -13, 17, -10, 9, -2, 21, -10),
+	CABAC_ENTRY(452, 33, -14, 32, -13, 30, -10, 24, -11),
+	CABAC_ENTRY(453, 39, -7, 42, -9, 31, -4, 28, -8),
+	CABAC_ENTRY(454, 46, -2, 49, -5, 33, -1, 28, -1),
+	CABAC_ENTRY(455, 51, 2, 53, 0, 33, 7, 29, 3),
+	CABAC_ENTRY(456, 60, 6, 64, 3, 31, 12, 29, 9),
+	CABAC_ENTRY(457, 61, 17, 68, 10, 37, 23, 35, 20),
+	CABAC_ENTRY(458, 55, 34, 66, 27, 31, 38, 29, 36),
+	CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67),
+};
+
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index 1adb2e1f5f0ed..15f2378bbc020 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -15,6 +15,8 @@
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
 
+extern const s8 rkvdec_h264_cabac_table[4][464][2];
+
 /* Size with u32 units. */
 #define RKV_CABAC_INIT_BUFFER_SIZE	(3680 + 128)
 #define RKV_RPS_SIZE			((128 + 128) / 4)
@@ -118,505 +120,6 @@ struct rkvdec_h264_ctx {
 	struct rkvdec_regs regs;
 };
 
-#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n,		\
-	    idc2_m, idc2_n, intra_m, intra_n)			\
-	[0][(ctxidx)] = {idc0_m, idc0_n},			\
-	[1][(ctxidx)] = {idc1_m, idc1_n},			\
-	[2][(ctxidx)] = {idc2_m, idc2_n},			\
-	[3][(ctxidx)] = {intra_m, intra_n}
-
-/*
- * Constant CABAC table.
- * Built from the tables described in section '9.3.1.1 Initialisation process
- * for context variables' of the H264 spec.
- */
-static const s8 rkvdec_h264_cabac_table[4][464][2] = {
-	/* Table 9-12 – Values of variables m and n for ctxIdx from 0 to 10 */
-	CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15),
-	CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54),
-	CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74),
-	CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15),
-	CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54),
-	CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74),
-	CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127),
-	CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104),
-	CABAC_ENTRY(8, -6, 53, -6, 53, -6, 53, -6, 53),
-	CABAC_ENTRY(9, -1, 54, -1, 54, -1, 54, -1, 54),
-	CABAC_ENTRY(10, 7, 51, 7, 51, 7, 51, 7, 51),
-
-	/* Table 9-13 – Values of variables m and n for ctxIdx from 11 to 23 */
-	CABAC_ENTRY(11, 23, 33, 22, 25, 29, 16, 0, 0),
-	CABAC_ENTRY(12, 23, 2, 34, 0, 25, 0, 0, 0),
-	CABAC_ENTRY(13, 21, 0, 16, 0, 14, 0, 0, 0),
-	CABAC_ENTRY(14, 1, 9, -2, 9, -10, 51, 0, 0),
-	CABAC_ENTRY(15, 0, 49, 4, 41, -3, 62, 0, 0),
-	CABAC_ENTRY(16, -37, 118, -29, 118, -27, 99, 0, 0),
-	CABAC_ENTRY(17, 5, 57, 2, 65, 26, 16, 0, 0),
-	CABAC_ENTRY(18, -13, 78, -6, 71, -4, 85, 0, 0),
-	CABAC_ENTRY(19, -11, 65, -13, 79, -24, 102, 0, 0),
-	CABAC_ENTRY(20, 1, 62, 5, 52, 5, 57, 0, 0),
-	CABAC_ENTRY(21, 12, 49, 9, 50, 6, 57, 0, 0),
-	CABAC_ENTRY(22, -4, 73, -3, 70, -17, 73, 0, 0),
-	CABAC_ENTRY(23, 17, 50, 10, 54, 14, 57, 0, 0),
-
-	/* Table 9-14 – Values of variables m and n for ctxIdx from 24 to 39 */
-	CABAC_ENTRY(24, 18, 64, 26, 34, 20, 40, 0, 0),
-	CABAC_ENTRY(25, 9, 43, 19, 22, 20, 10, 0, 0),
-	CABAC_ENTRY(26, 29, 0, 40, 0, 29, 0, 0, 0),
-	CABAC_ENTRY(27, 26, 67, 57, 2, 54, 0, 0, 0),
-	CABAC_ENTRY(28, 16, 90, 41, 36, 37, 42, 0, 0),
-	CABAC_ENTRY(29, 9, 104, 26, 69, 12, 97, 0, 0),
-	CABAC_ENTRY(30, -46, 127, -45, 127, -32, 127, 0, 0),
-	CABAC_ENTRY(31, -20, 104, -15, 101, -22, 117, 0, 0),
-	CABAC_ENTRY(32, 1, 67, -4, 76, -2, 74, 0, 0),
-	CABAC_ENTRY(33, -13, 78, -6, 71, -4, 85, 0, 0),
-	CABAC_ENTRY(34, -11, 65, -13, 79, -24, 102, 0, 0),
-	CABAC_ENTRY(35, 1, 62, 5, 52, 5, 57, 0, 0),
-	CABAC_ENTRY(36, -6, 86, 6, 69, -6, 93, 0, 0),
-	CABAC_ENTRY(37, -17, 95, -13, 90, -14, 88, 0, 0),
-	CABAC_ENTRY(38, -6, 61, 0, 52, -6, 44, 0, 0),
-	CABAC_ENTRY(39, 9, 45, 8, 43, 4, 55, 0, 0),
-
-	/* Table 9-15 – Values of variables m and n for ctxIdx from 40 to 53 */
-	CABAC_ENTRY(40, -3, 69, -2, 69, -11, 89, 0, 0),
-	CABAC_ENTRY(41, -6, 81, -5, 82, -15, 103, 0, 0),
-	CABAC_ENTRY(42, -11, 96, -10, 96, -21, 116, 0, 0),
-	CABAC_ENTRY(43, 6, 55, 2, 59, 19, 57, 0, 0),
-	CABAC_ENTRY(44, 7, 67, 2, 75, 20, 58, 0, 0),
-	CABAC_ENTRY(45, -5, 86, -3, 87, 4, 84, 0, 0),
-	CABAC_ENTRY(46, 2, 88, -3, 100, 6, 96, 0, 0),
-	CABAC_ENTRY(47, 0, 58, 1, 56, 1, 63, 0, 0),
-	CABAC_ENTRY(48, -3, 76, -3, 74, -5, 85, 0, 0),
-	CABAC_ENTRY(49, -10, 94, -6, 85, -13, 106, 0, 0),
-	CABAC_ENTRY(50, 5, 54, 0, 59, 5, 63, 0, 0),
-	CABAC_ENTRY(51, 4, 69, -3, 81, 6, 75, 0, 0),
-	CABAC_ENTRY(52, -3, 81, -7, 86, -3, 90, 0, 0),
-	CABAC_ENTRY(53, 0, 88, -5, 95, -1, 101, 0, 0),
-
-	/* Table 9-16 – Values of variables m and n for ctxIdx from 54 to 59 */
-	CABAC_ENTRY(54, -7, 67, -1, 66, 3, 55, 0, 0),
-	CABAC_ENTRY(55, -5, 74, -1, 77, -4, 79, 0, 0),
-	CABAC_ENTRY(56, -4, 74, 1, 70, -2, 75, 0, 0),
-	CABAC_ENTRY(57, -5, 80, -2, 86, -12, 97, 0, 0),
-	CABAC_ENTRY(58, -7, 72, -5, 72, -7, 50, 0, 0),
-	CABAC_ENTRY(59, 1, 58, 0, 61, 1, 60, 0, 0),
-
-	/* Table 9-17 – Values of variables m and n for ctxIdx from 60 to 69 */
-	CABAC_ENTRY(60, 0, 41, 0, 41, 0, 41, 0, 41),
-	CABAC_ENTRY(61, 0, 63, 0, 63, 0, 63, 0, 63),
-	CABAC_ENTRY(62, 0, 63, 0, 63, 0, 63, 0, 63),
-	CABAC_ENTRY(63, 0, 63, 0, 63, 0, 63, 0, 63),
-	CABAC_ENTRY(64, -9, 83, -9, 83, -9, 83, -9, 83),
-	CABAC_ENTRY(65, 4, 86, 4, 86, 4, 86, 4, 86),
-	CABAC_ENTRY(66, 0, 97, 0, 97, 0, 97, 0, 97),
-	CABAC_ENTRY(67, -7, 72, -7, 72, -7, 72, -7, 72),
-	CABAC_ENTRY(68, 13, 41, 13, 41, 13, 41, 13, 41),
-	CABAC_ENTRY(69, 3, 62, 3, 62, 3, 62, 3, 62),
-
-	/* Table 9-18 – Values of variables m and n for ctxIdx from 70 to 104 */
-	CABAC_ENTRY(70, 0, 45, 13, 15, 7, 34, 0, 11),
-	CABAC_ENTRY(71, -4, 78, 7, 51, -9, 88, 1, 55),
-	CABAC_ENTRY(72, -3, 96, 2, 80, -20, 127, 0, 69),
-	CABAC_ENTRY(73, -27, 126, -39, 127, -36, 127, -17, 127),
-	CABAC_ENTRY(74, -28, 98, -18, 91, -17, 91, -13, 102),
-	CABAC_ENTRY(75, -25, 101, -17, 96, -14, 95, 0, 82),
-	CABAC_ENTRY(76, -23, 67, -26, 81, -25, 84, -7, 74),
-	CABAC_ENTRY(77, -28, 82, -35, 98, -25, 86, -21, 107),
-	CABAC_ENTRY(78, -20, 94, -24, 102, -12, 89, -27, 127),
-	CABAC_ENTRY(79, -16, 83, -23, 97, -17, 91, -31, 127),
-	CABAC_ENTRY(80, -22, 110, -27, 119, -31, 127, -24, 127),
-	CABAC_ENTRY(81, -21, 91, -24, 99, -14, 76, -18, 95),
-	CABAC_ENTRY(82, -18, 102, -21, 110, -18, 103, -27, 127),
-	CABAC_ENTRY(83, -13, 93, -18, 102, -13, 90, -21, 114),
-	CABAC_ENTRY(84, -29, 127, -36, 127, -37, 127, -30, 127),
-	CABAC_ENTRY(85, -7, 92, 0, 80, 11, 80, -17, 123),
-	CABAC_ENTRY(86, -5, 89, -5, 89, 5, 76, -12, 115),
-	CABAC_ENTRY(87, -7, 96, -7, 94, 2, 84, -16, 122),
-	CABAC_ENTRY(88, -13, 108, -4, 92, 5, 78, -11, 115),
-	CABAC_ENTRY(89, -3, 46, 0, 39, -6, 55, -12, 63),
-	CABAC_ENTRY(90, -1, 65, 0, 65, 4, 61, -2, 68),
-	CABAC_ENTRY(91, -1, 57, -15, 84, -14, 83, -15, 84),
-	CABAC_ENTRY(92, -9, 93, -35, 127, -37, 127, -13, 104),
-	CABAC_ENTRY(93, -3, 74, -2, 73, -5, 79, -3, 70),
-	CABAC_ENTRY(94, -9, 92, -12, 104, -11, 104, -8, 93),
-	CABAC_ENTRY(95, -8, 87, -9, 91, -11, 91, -10, 90),
-	CABAC_ENTRY(96, -23, 126, -31, 127, -30, 127, -30, 127),
-	CABAC_ENTRY(97, 5, 54, 3, 55, 0, 65, -1, 74),
-	CABAC_ENTRY(98, 6, 60, 7, 56, -2, 79, -6, 97),
-	CABAC_ENTRY(99, 6, 59, 7, 55, 0, 72, -7, 91),
-	CABAC_ENTRY(100, 6, 69, 8, 61, -4, 92, -20, 127),
-	CABAC_ENTRY(101, -1, 48, -3, 53, -6, 56, -4, 56),
-	CABAC_ENTRY(102, 0, 68, 0, 68, 3, 68, -5, 82),
-	CABAC_ENTRY(103, -4, 69, -7, 74, -8, 71, -7, 76),
-	CABAC_ENTRY(104, -8, 88, -9, 88, -13, 98, -22, 125),
-
-	/* Table 9-19 – Values of variables m and n for ctxIdx from 105 to 165 */
-	CABAC_ENTRY(105, -2, 85, -13, 103, -4, 86, -7, 93),
-	CABAC_ENTRY(106, -6, 78, -13, 91, -12, 88, -11, 87),
-	CABAC_ENTRY(107, -1, 75, -9, 89, -5, 82, -3, 77),
-	CABAC_ENTRY(108, -7, 77, -14, 92, -3, 72, -5, 71),
-	CABAC_ENTRY(109, 2, 54, -8, 76, -4, 67, -4, 63),
-	CABAC_ENTRY(110, 5, 50, -12, 87, -8, 72, -4, 68),
-	CABAC_ENTRY(111, -3, 68, -23, 110, -16, 89, -12, 84),
-	CABAC_ENTRY(112, 1, 50, -24, 105, -9, 69, -7, 62),
-	CABAC_ENTRY(113, 6, 42, -10, 78, -1, 59, -7, 65),
-	CABAC_ENTRY(114, -4, 81, -20, 112, 5, 66, 8, 61),
-	CABAC_ENTRY(115, 1, 63, -17, 99, 4, 57, 5, 56),
-	CABAC_ENTRY(116, -4, 70, -78, 127, -4, 71, -2, 66),
-	CABAC_ENTRY(117, 0, 67, -70, 127, -2, 71, 1, 64),
-	CABAC_ENTRY(118, 2, 57, -50, 127, 2, 58, 0, 61),
-	CABAC_ENTRY(119, -2, 76, -46, 127, -1, 74, -2, 78),
-	CABAC_ENTRY(120, 11, 35, -4, 66, -4, 44, 1, 50),
-	CABAC_ENTRY(121, 4, 64, -5, 78, -1, 69, 7, 52),
-	CABAC_ENTRY(122, 1, 61, -4, 71, 0, 62, 10, 35),
-	CABAC_ENTRY(123, 11, 35, -8, 72, -7, 51, 0, 44),
-	CABAC_ENTRY(124, 18, 25, 2, 59, -4, 47, 11, 38),
-	CABAC_ENTRY(125, 12, 24, -1, 55, -6, 42, 1, 45),
-	CABAC_ENTRY(126, 13, 29, -7, 70, -3, 41, 0, 46),
-	CABAC_ENTRY(127, 13, 36, -6, 75, -6, 53, 5, 44),
-	CABAC_ENTRY(128, -10, 93, -8, 89, 8, 76, 31, 17),
-	CABAC_ENTRY(129, -7, 73, -34, 119, -9, 78, 1, 51),
-	CABAC_ENTRY(130, -2, 73, -3, 75, -11, 83, 7, 50),
-	CABAC_ENTRY(131, 13, 46, 32, 20, 9, 52, 28, 19),
-	CABAC_ENTRY(132, 9, 49, 30, 22, 0, 67, 16, 33),
-	CABAC_ENTRY(133, -7, 100, -44, 127, -5, 90, 14, 62),
-	CABAC_ENTRY(134, 9, 53, 0, 54, 1, 67, -13, 108),
-	CABAC_ENTRY(135, 2, 53, -5, 61, -15, 72, -15, 100),
-	CABAC_ENTRY(136, 5, 53, 0, 58, -5, 75, -13, 101),
-	CABAC_ENTRY(137, -2, 61, -1, 60, -8, 80, -13, 91),
-	CABAC_ENTRY(138, 0, 56, -3, 61, -21, 83, -12, 94),
-	CABAC_ENTRY(139, 0, 56, -8, 67, -21, 64, -10, 88),
-	CABAC_ENTRY(140, -13, 63, -25, 84, -13, 31, -16, 84),
-	CABAC_ENTRY(141, -5, 60, -14, 74, -25, 64, -10, 86),
-	CABAC_ENTRY(142, -1, 62, -5, 65, -29, 94, -7, 83),
-	CABAC_ENTRY(143, 4, 57, 5, 52, 9, 75, -13, 87),
-	CABAC_ENTRY(144, -6, 69, 2, 57, 17, 63, -19, 94),
-	CABAC_ENTRY(145, 4, 57, 0, 61, -8, 74, 1, 70),
-	CABAC_ENTRY(146, 14, 39, -9, 69, -5, 35, 0, 72),
-	CABAC_ENTRY(147, 4, 51, -11, 70, -2, 27, -5, 74),
-	CABAC_ENTRY(148, 13, 68, 18, 55, 13, 91, 18, 59),
-	CABAC_ENTRY(149, 3, 64, -4, 71, 3, 65, -8, 102),
-	CABAC_ENTRY(150, 1, 61, 0, 58, -7, 69, -15, 100),
-	CABAC_ENTRY(151, 9, 63, 7, 61, 8, 77, 0, 95),
-	CABAC_ENTRY(152, 7, 50, 9, 41, -10, 66, -4, 75),
-	CABAC_ENTRY(153, 16, 39, 18, 25, 3, 62, 2, 72),
-	CABAC_ENTRY(154, 5, 44, 9, 32, -3, 68, -11, 75),
-	CABAC_ENTRY(155, 4, 52, 5, 43, -20, 81, -3, 71),
-	CABAC_ENTRY(156, 11, 48, 9, 47, 0, 30, 15, 46),
-	CABAC_ENTRY(157, -5, 60, 0, 44, 1, 7, -13, 69),
-	CABAC_ENTRY(158, -1, 59, 0, 51, -3, 23, 0, 62),
-	CABAC_ENTRY(159, 0, 59, 2, 46, -21, 74, 0, 65),
-	CABAC_ENTRY(160, 22, 33, 19, 38, 16, 66, 21, 37),
-	CABAC_ENTRY(161, 5, 44, -4, 66, -23, 124, -15, 72),
-	CABAC_ENTRY(162, 14, 43, 15, 38, 17, 37, 9, 57),
-	CABAC_ENTRY(163, -1, 78, 12, 42, 44, -18, 16, 54),
-	CABAC_ENTRY(164, 0, 60, 9, 34, 50, -34, 0, 62),
-	CABAC_ENTRY(165, 9, 69, 0, 89, -22, 127, 12, 72),
-
-	/* Table 9-20 – Values of variables m and n for ctxIdx from 166 to 226 */
-	CABAC_ENTRY(166, 11, 28, 4, 45, 4, 39, 24, 0),
-	CABAC_ENTRY(167, 2, 40, 10, 28, 0, 42, 15, 9),
-	CABAC_ENTRY(168, 3, 44, 10, 31, 7, 34, 8, 25),
-	CABAC_ENTRY(169, 0, 49, 33, -11, 11, 29, 13, 18),
-	CABAC_ENTRY(170, 0, 46, 52, -43, 8, 31, 15, 9),
-	CABAC_ENTRY(171, 2, 44, 18, 15, 6, 37, 13, 19),
-	CABAC_ENTRY(172, 2, 51, 28, 0, 7, 42, 10, 37),
-	CABAC_ENTRY(173, 0, 47, 35, -22, 3, 40, 12, 18),
-	CABAC_ENTRY(174, 4, 39, 38, -25, 8, 33, 6, 29),
-	CABAC_ENTRY(175, 2, 62, 34, 0, 13, 43, 20, 33),
-	CABAC_ENTRY(176, 6, 46, 39, -18, 13, 36, 15, 30),
-	CABAC_ENTRY(177, 0, 54, 32, -12, 4, 47, 4, 45),
-	CABAC_ENTRY(178, 3, 54, 102, -94, 3, 55, 1, 58),
-	CABAC_ENTRY(179, 2, 58, 0, 0, 2, 58, 0, 62),
-	CABAC_ENTRY(180, 4, 63, 56, -15, 6, 60, 7, 61),
-	CABAC_ENTRY(181, 6, 51, 33, -4, 8, 44, 12, 38),
-	CABAC_ENTRY(182, 6, 57, 29, 10, 11, 44, 11, 45),
-	CABAC_ENTRY(183, 7, 53, 37, -5, 14, 42, 15, 39),
-	CABAC_ENTRY(184, 6, 52, 51, -29, 7, 48, 11, 42),
-	CABAC_ENTRY(185, 6, 55, 39, -9, 4, 56, 13, 44),
-	CABAC_ENTRY(186, 11, 45, 52, -34, 4, 52, 16, 45),
-	CABAC_ENTRY(187, 14, 36, 69, -58, 13, 37, 12, 41),
-	CABAC_ENTRY(188, 8, 53, 67, -63, 9, 49, 10, 49),
-	CABAC_ENTRY(189, -1, 82, 44, -5, 19, 58, 30, 34),
-	CABAC_ENTRY(190, 7, 55, 32, 7, 10, 48, 18, 42),
-	CABAC_ENTRY(191, -3, 78, 55, -29, 12, 45, 10, 55),
-	CABAC_ENTRY(192, 15, 46, 32, 1, 0, 69, 17, 51),
-	CABAC_ENTRY(193, 22, 31, 0, 0, 20, 33, 17, 46),
-	CABAC_ENTRY(194, -1, 84, 27, 36, 8, 63, 0, 89),
-	CABAC_ENTRY(195, 25, 7, 33, -25, 35, -18, 26, -19),
-	CABAC_ENTRY(196, 30, -7, 34, -30, 33, -25, 22, -17),
-	CABAC_ENTRY(197, 28, 3, 36, -28, 28, -3, 26, -17),
-	CABAC_ENTRY(198, 28, 4, 38, -28, 24, 10, 30, -25),
-	CABAC_ENTRY(199, 32, 0, 38, -27, 27, 0, 28, -20),
-	CABAC_ENTRY(200, 34, -1, 34, -18, 34, -14, 33, -23),
-	CABAC_ENTRY(201, 30, 6, 35, -16, 52, -44, 37, -27),
-	CABAC_ENTRY(202, 30, 6, 34, -14, 39, -24, 33, -23),
-	CABAC_ENTRY(203, 32, 9, 32, -8, 19, 17, 40, -28),
-	CABAC_ENTRY(204, 31, 19, 37, -6, 31, 25, 38, -17),
-	CABAC_ENTRY(205, 26, 27, 35, 0, 36, 29, 33, -11),
-	CABAC_ENTRY(206, 26, 30, 30, 10, 24, 33, 40, -15),
-	CABAC_ENTRY(207, 37, 20, 28, 18, 34, 15, 41, -6),
-	CABAC_ENTRY(208, 28, 34, 26, 25, 30, 20, 38, 1),
-	CABAC_ENTRY(209, 17, 70, 29, 41, 22, 73, 41, 17),
-	CABAC_ENTRY(210, 1, 67, 0, 75, 20, 34, 30, -6),
-	CABAC_ENTRY(211, 5, 59, 2, 72, 19, 31, 27, 3),
-	CABAC_ENTRY(212, 9, 67, 8, 77, 27, 44, 26, 22),
-	CABAC_ENTRY(213, 16, 30, 14, 35, 19, 16, 37, -16),
-	CABAC_ENTRY(214, 18, 32, 18, 31, 15, 36, 35, -4),
-	CABAC_ENTRY(215, 18, 35, 17, 35, 15, 36, 38, -8),
-	CABAC_ENTRY(216, 22, 29, 21, 30, 21, 28, 38, -3),
-	CABAC_ENTRY(217, 24, 31, 17, 45, 25, 21, 37, 3),
-	CABAC_ENTRY(218, 23, 38, 20, 42, 30, 20, 38, 5),
-	CABAC_ENTRY(219, 18, 43, 18, 45, 31, 12, 42, 0),
-	CABAC_ENTRY(220, 20, 41, 27, 26, 27, 16, 35, 16),
-	CABAC_ENTRY(221, 11, 63, 16, 54, 24, 42, 39, 22),
-	CABAC_ENTRY(222, 9, 59, 7, 66, 0, 93, 14, 48),
-	CABAC_ENTRY(223, 9, 64, 16, 56, 14, 56, 27, 37),
-	CABAC_ENTRY(224, -1, 94, 11, 73, 15, 57, 21, 60),
-	CABAC_ENTRY(225, -2, 89, 10, 67, 26, 38, 12, 68),
-	CABAC_ENTRY(226, -9, 108, -10, 116, -24, 127, 2, 97),
-
-	/* Table 9-21 – Values of variables m and n for ctxIdx from 227 to 275 */
-	CABAC_ENTRY(227, -6, 76, -23, 112, -24, 115, -3, 71),
-	CABAC_ENTRY(228, -2, 44, -15, 71, -22, 82, -6, 42),
-	CABAC_ENTRY(229, 0, 45, -7, 61, -9, 62, -5, 50),
-	CABAC_ENTRY(230, 0, 52, 0, 53, 0, 53, -3, 54),
-	CABAC_ENTRY(231, -3, 64, -5, 66, 0, 59, -2, 62),
-	CABAC_ENTRY(232, -2, 59, -11, 77, -14, 85, 0, 58),
-	CABAC_ENTRY(233, -4, 70, -9, 80, -13, 89, 1, 63),
-	CABAC_ENTRY(234, -4, 75, -9, 84, -13, 94, -2, 72),
-	CABAC_ENTRY(235, -8, 82, -10, 87, -11, 92, -1, 74),
-	CABAC_ENTRY(236, -17, 102, -34, 127, -29, 127, -9, 91),
-	CABAC_ENTRY(237, -9, 77, -21, 101, -21, 100, -5, 67),
-	CABAC_ENTRY(238, 3, 24, -3, 39, -14, 57, -5, 27),
-	CABAC_ENTRY(239, 0, 42, -5, 53, -12, 67, -3, 39),
-	CABAC_ENTRY(240, 0, 48, -7, 61, -11, 71, -2, 44),
-	CABAC_ENTRY(241, 0, 55, -11, 75, -10, 77, 0, 46),
-	CABAC_ENTRY(242, -6, 59, -15, 77, -21, 85, -16, 64),
-	CABAC_ENTRY(243, -7, 71, -17, 91, -16, 88, -8, 68),
-	CABAC_ENTRY(244, -12, 83, -25, 107, -23, 104, -10, 78),
-	CABAC_ENTRY(245, -11, 87, -25, 111, -15, 98, -6, 77),
-	CABAC_ENTRY(246, -30, 119, -28, 122, -37, 127, -10, 86),
-	CABAC_ENTRY(247, 1, 58, -11, 76, -10, 82, -12, 92),
-	CABAC_ENTRY(248, -3, 29, -10, 44, -8, 48, -15, 55),
-	CABAC_ENTRY(249, -1, 36, -10, 52, -8, 61, -10, 60),
-	CABAC_ENTRY(250, 1, 38, -10, 57, -8, 66, -6, 62),
-	CABAC_ENTRY(251, 2, 43, -9, 58, -7, 70, -4, 65),
-	CABAC_ENTRY(252, -6, 55, -16, 72, -14, 75, -12, 73),
-	CABAC_ENTRY(253, 0, 58, -7, 69, -10, 79, -8, 76),
-	CABAC_ENTRY(254, 0, 64, -4, 69, -9, 83, -7, 80),
-	CABAC_ENTRY(255, -3, 74, -5, 74, -12, 92, -9, 88),
-	CABAC_ENTRY(256, -10, 90, -9, 86, -18, 108, -17, 110),
-	CABAC_ENTRY(257, 0, 70, 2, 66, -4, 79, -11, 97),
-	CABAC_ENTRY(258, -4, 29, -9, 34, -22, 69, -20, 84),
-	CABAC_ENTRY(259, 5, 31, 1, 32, -16, 75, -11, 79),
-	CABAC_ENTRY(260, 7, 42, 11, 31, -2, 58, -6, 73),
-	CABAC_ENTRY(261, 1, 59, 5, 52, 1, 58, -4, 74),
-	CABAC_ENTRY(262, -2, 58, -2, 55, -13, 78, -13, 86),
-	CABAC_ENTRY(263, -3, 72, -2, 67, -9, 83, -13, 96),
-	CABAC_ENTRY(264, -3, 81, 0, 73, -4, 81, -11, 97),
-	CABAC_ENTRY(265, -11, 97, -8, 89, -13, 99, -19, 117),
-	CABAC_ENTRY(266, 0, 58, 3, 52, -13, 81, -8, 78),
-	CABAC_ENTRY(267, 8, 5, 7, 4, -6, 38, -5, 33),
-	CABAC_ENTRY(268, 10, 14, 10, 8, -13, 62, -4, 48),
-	CABAC_ENTRY(269, 14, 18, 17, 8, -6, 58, -2, 53),
-	CABAC_ENTRY(270, 13, 27, 16, 19, -2, 59, -3, 62),
-	CABAC_ENTRY(271, 2, 40, 3, 37, -16, 73, -13, 71),
-	CABAC_ENTRY(272, 0, 58, -1, 61, -10, 76, -10, 79),
-	CABAC_ENTRY(273, -3, 70, -5, 73, -13, 86, -12, 86),
-	CABAC_ENTRY(274, -6, 79, -1, 70, -9, 83, -13, 90),
-	CABAC_ENTRY(275, -8, 85, -4, 78, -10, 87, -14, 97),
-
-	/* Table 9-22 – Values of variables m and n for ctxIdx from 277 to 337 */
-	CABAC_ENTRY(277, -13, 106, -21, 126, -22, 127, -6, 93),
-	CABAC_ENTRY(278, -16, 106, -23, 124, -25, 127, -6, 84),
-	CABAC_ENTRY(279, -10, 87, -20, 110, -25, 120, -8, 79),
-	CABAC_ENTRY(280, -21, 114, -26, 126, -27, 127, 0, 66),
-	CABAC_ENTRY(281, -18, 110, -25, 124, -19, 114, -1, 71),
-	CABAC_ENTRY(282, -14, 98, -17, 105, -23, 117, 0, 62),
-	CABAC_ENTRY(283, -22, 110, -27, 121, -25, 118, -2, 60),
-	CABAC_ENTRY(284, -21, 106, -27, 117, -26, 117, -2, 59),
-	CABAC_ENTRY(285, -18, 103, -17, 102, -24, 113, -5, 75),
-	CABAC_ENTRY(286, -21, 107, -26, 117, -28, 118, -3, 62),
-	CABAC_ENTRY(287, -23, 108, -27, 116, -31, 120, -4, 58),
-	CABAC_ENTRY(288, -26, 112, -33, 122, -37, 124, -9, 66),
-	CABAC_ENTRY(289, -10, 96, -10, 95, -10, 94, -1, 79),
-	CABAC_ENTRY(290, -12, 95, -14, 100, -15, 102, 0, 71),
-	CABAC_ENTRY(291, -5, 91, -8, 95, -10, 99, 3, 68),
-	CABAC_ENTRY(292, -9, 93, -17, 111, -13, 106, 10, 44),
-	CABAC_ENTRY(293, -22, 94, -28, 114, -50, 127, -7, 62),
-	CABAC_ENTRY(294, -5, 86, -6, 89, -5, 92, 15, 36),
-	CABAC_ENTRY(295, 9, 67, -2, 80, 17, 57, 14, 40),
-	CABAC_ENTRY(296, -4, 80, -4, 82, -5, 86, 16, 27),
-	CABAC_ENTRY(297, -10, 85, -9, 85, -13, 94, 12, 29),
-	CABAC_ENTRY(298, -1, 70, -8, 81, -12, 91, 1, 44),
-	CABAC_ENTRY(299, 7, 60, -1, 72, -2, 77, 20, 36),
-	CABAC_ENTRY(300, 9, 58, 5, 64, 0, 71, 18, 32),
-	CABAC_ENTRY(301, 5, 61, 1, 67, -1, 73, 5, 42),
-	CABAC_ENTRY(302, 12, 50, 9, 56, 4, 64, 1, 48),
-	CABAC_ENTRY(303, 15, 50, 0, 69, -7, 81, 10, 62),
-	CABAC_ENTRY(304, 18, 49, 1, 69, 5, 64, 17, 46),
-	CABAC_ENTRY(305, 17, 54, 7, 69, 15, 57, 9, 64),
-	CABAC_ENTRY(306, 10, 41, -7, 69, 1, 67, -12, 104),
-	CABAC_ENTRY(307, 7, 46, -6, 67, 0, 68, -11, 97),
-	CABAC_ENTRY(308, -1, 51, -16, 77, -10, 67, -16, 96),
-	CABAC_ENTRY(309, 7, 49, -2, 64, 1, 68, -7, 88),
-	CABAC_ENTRY(310, 8, 52, 2, 61, 0, 77, -8, 85),
-	CABAC_ENTRY(311, 9, 41, -6, 67, 2, 64, -7, 85),
-	CABAC_ENTRY(312, 6, 47, -3, 64, 0, 68, -9, 85),
-	CABAC_ENTRY(313, 2, 55, 2, 57, -5, 78, -13, 88),
-	CABAC_ENTRY(314, 13, 41, -3, 65, 7, 55, 4, 66),
-	CABAC_ENTRY(315, 10, 44, -3, 66, 5, 59, -3, 77),
-	CABAC_ENTRY(316, 6, 50, 0, 62, 2, 65, -3, 76),
-	CABAC_ENTRY(317, 5, 53, 9, 51, 14, 54, -6, 76),
-	CABAC_ENTRY(318, 13, 49, -1, 66, 15, 44, 10, 58),
-	CABAC_ENTRY(319, 4, 63, -2, 71, 5, 60, -1, 76),
-	CABAC_ENTRY(320, 6, 64, -2, 75, 2, 70, -1, 83),
-	CABAC_ENTRY(321, -2, 69, -1, 70, -2, 76, -7, 99),
-	CABAC_ENTRY(322, -2, 59, -9, 72, -18, 86, -14, 95),
-	CABAC_ENTRY(323, 6, 70, 14, 60, 12, 70, 2, 95),
-	CABAC_ENTRY(324, 10, 44, 16, 37, 5, 64, 0, 76),
-	CABAC_ENTRY(325, 9, 31, 0, 47, -12, 70, -5, 74),
-	CABAC_ENTRY(326, 12, 43, 18, 35, 11, 55, 0, 70),
-	CABAC_ENTRY(327, 3, 53, 11, 37, 5, 56, -11, 75),
-	CABAC_ENTRY(328, 14, 34, 12, 41, 0, 69, 1, 68),
-	CABAC_ENTRY(329, 10, 38, 10, 41, 2, 65, 0, 65),
-	CABAC_ENTRY(330, -3, 52, 2, 48, -6, 74, -14, 73),
-	CABAC_ENTRY(331, 13, 40, 12, 41, 5, 54, 3, 62),
-	CABAC_ENTRY(332, 17, 32, 13, 41, 7, 54, 4, 62),
-	CABAC_ENTRY(333, 7, 44, 0, 59, -6, 76, -1, 68),
-	CABAC_ENTRY(334, 7, 38, 3, 50, -11, 82, -13, 75),
-	CABAC_ENTRY(335, 13, 50, 19, 40, -2, 77, 11, 55),
-	CABAC_ENTRY(336, 10, 57, 3, 66, -2, 77, 5, 64),
-	CABAC_ENTRY(337, 26, 43, 18, 50, 25, 42, 12, 70),
-
-	/* Table 9-23 – Values of variables m and n for ctxIdx from 338 to 398 */
-	CABAC_ENTRY(338, 14, 11, 19, -6, 17, -13, 15, 6),
-	CABAC_ENTRY(339, 11, 14, 18, -6, 16, -9, 6, 19),
-	CABAC_ENTRY(340, 9, 11, 14, 0, 17, -12, 7, 16),
-	CABAC_ENTRY(341, 18, 11, 26, -12, 27, -21, 12, 14),
-	CABAC_ENTRY(342, 21, 9, 31, -16, 37, -30, 18, 13),
-	CABAC_ENTRY(343, 23, -2, 33, -25, 41, -40, 13, 11),
-	CABAC_ENTRY(344, 32, -15, 33, -22, 42, -41, 13, 15),
-	CABAC_ENTRY(345, 32, -15, 37, -28, 48, -47, 15, 16),
-	CABAC_ENTRY(346, 34, -21, 39, -30, 39, -32, 12, 23),
-	CABAC_ENTRY(347, 39, -23, 42, -30, 46, -40, 13, 23),
-	CABAC_ENTRY(348, 42, -33, 47, -42, 52, -51, 15, 20),
-	CABAC_ENTRY(349, 41, -31, 45, -36, 46, -41, 14, 26),
-	CABAC_ENTRY(350, 46, -28, 49, -34, 52, -39, 14, 44),
-	CABAC_ENTRY(351, 38, -12, 41, -17, 43, -19, 17, 40),
-	CABAC_ENTRY(352, 21, 29, 32, 9, 32, 11, 17, 47),
-	CABAC_ENTRY(353, 45, -24, 69, -71, 61, -55, 24, 17),
-	CABAC_ENTRY(354, 53, -45, 63, -63, 56, -46, 21, 21),
-	CABAC_ENTRY(355, 48, -26, 66, -64, 62, -50, 25, 22),
-	CABAC_ENTRY(356, 65, -43, 77, -74, 81, -67, 31, 27),
-	CABAC_ENTRY(357, 43, -19, 54, -39, 45, -20, 22, 29),
-	CABAC_ENTRY(358, 39, -10, 52, -35, 35, -2, 19, 35),
-	CABAC_ENTRY(359, 30, 9, 41, -10, 28, 15, 14, 50),
-	CABAC_ENTRY(360, 18, 26, 36, 0, 34, 1, 10, 57),
-	CABAC_ENTRY(361, 20, 27, 40, -1, 39, 1, 7, 63),
-	CABAC_ENTRY(362, 0, 57, 30, 14, 30, 17, -2, 77),
-	CABAC_ENTRY(363, -14, 82, 28, 26, 20, 38, -4, 82),
-	CABAC_ENTRY(364, -5, 75, 23, 37, 18, 45, -3, 94),
-	CABAC_ENTRY(365, -19, 97, 12, 55, 15, 54, 9, 69),
-	CABAC_ENTRY(366, -35, 125, 11, 65, 0, 79, -12, 109),
-	CABAC_ENTRY(367, 27, 0, 37, -33, 36, -16, 36, -35),
-	CABAC_ENTRY(368, 28, 0, 39, -36, 37, -14, 36, -34),
-	CABAC_ENTRY(369, 31, -4, 40, -37, 37, -17, 32, -26),
-	CABAC_ENTRY(370, 27, 6, 38, -30, 32, 1, 37, -30),
-	CABAC_ENTRY(371, 34, 8, 46, -33, 34, 15, 44, -32),
-	CABAC_ENTRY(372, 30, 10, 42, -30, 29, 15, 34, -18),
-	CABAC_ENTRY(373, 24, 22, 40, -24, 24, 25, 34, -15),
-	CABAC_ENTRY(374, 33, 19, 49, -29, 34, 22, 40, -15),
-	CABAC_ENTRY(375, 22, 32, 38, -12, 31, 16, 33, -7),
-	CABAC_ENTRY(376, 26, 31, 40, -10, 35, 18, 35, -5),
-	CABAC_ENTRY(377, 21, 41, 38, -3, 31, 28, 33, 0),
-	CABAC_ENTRY(378, 26, 44, 46, -5, 33, 41, 38, 2),
-	CABAC_ENTRY(379, 23, 47, 31, 20, 36, 28, 33, 13),
-	CABAC_ENTRY(380, 16, 65, 29, 30, 27, 47, 23, 35),
-	CABAC_ENTRY(381, 14, 71, 25, 44, 21, 62, 13, 58),
-	CABAC_ENTRY(382, 8, 60, 12, 48, 18, 31, 29, -3),
-	CABAC_ENTRY(383, 6, 63, 11, 49, 19, 26, 26, 0),
-	CABAC_ENTRY(384, 17, 65, 26, 45, 36, 24, 22, 30),
-	CABAC_ENTRY(385, 21, 24, 22, 22, 24, 23, 31, -7),
-	CABAC_ENTRY(386, 23, 20, 23, 22, 27, 16, 35, -15),
-	CABAC_ENTRY(387, 26, 23, 27, 21, 24, 30, 34, -3),
-	CABAC_ENTRY(388, 27, 32, 33, 20, 31, 29, 34, 3),
-	CABAC_ENTRY(389, 28, 23, 26, 28, 22, 41, 36, -1),
-	CABAC_ENTRY(390, 28, 24, 30, 24, 22, 42, 34, 5),
-	CABAC_ENTRY(391, 23, 40, 27, 34, 16, 60, 32, 11),
-	CABAC_ENTRY(392, 24, 32, 18, 42, 15, 52, 35, 5),
-	CABAC_ENTRY(393, 28, 29, 25, 39, 14, 60, 34, 12),
-	CABAC_ENTRY(394, 23, 42, 18, 50, 3, 78, 39, 11),
-	CABAC_ENTRY(395, 19, 57, 12, 70, -16, 123, 30, 29),
-	CABAC_ENTRY(396, 22, 53, 21, 54, 21, 53, 34, 26),
-	CABAC_ENTRY(397, 22, 61, 14, 71, 22, 56, 29, 39),
-	CABAC_ENTRY(398, 11, 86, 11, 83, 25, 61, 19, 66),
-
-	/* Values of variables m and n for ctxIdx from 399 to 463 (not documented) */
-	CABAC_ENTRY(399, 12, 40, 25, 32, 21, 33, 31, 21),
-	CABAC_ENTRY(400, 11, 51, 21, 49, 19, 50, 31, 31),
-	CABAC_ENTRY(401, 14, 59, 21, 54, 17, 61, 25, 50),
-	CABAC_ENTRY(402, -4, 79, -5, 85, -3, 78, -17, 120),
-	CABAC_ENTRY(403, -7, 71, -6, 81, -8, 74, -20, 112),
-	CABAC_ENTRY(404, -5, 69, -10, 77, -9, 72, -18, 114),
-	CABAC_ENTRY(405, -9, 70, -7, 81, -10, 72, -11, 85),
-	CABAC_ENTRY(406, -8, 66, -17, 80, -18, 75, -15, 92),
-	CABAC_ENTRY(407, -10, 68, -18, 73, -12, 71, -14, 89),
-	CABAC_ENTRY(408, -19, 73, -4, 74, -11, 63, -26, 71),
-	CABAC_ENTRY(409, -12, 69, -10, 83, -5, 70, -15, 81),
-	CABAC_ENTRY(410, -16, 70, -9, 71, -17, 75, -14, 80),
-	CABAC_ENTRY(411, -15, 67, -9, 67, -14, 72, 0, 68),
-	CABAC_ENTRY(412, -20, 62, -1, 61, -16, 67, -14, 70),
-	CABAC_ENTRY(413, -19, 70, -8, 66, -8, 53, -24, 56),
-	CABAC_ENTRY(414, -16, 66, -14, 66, -14, 59, -23, 68),
-	CABAC_ENTRY(415, -22, 65, 0, 59, -9, 52, -24, 50),
-	CABAC_ENTRY(416, -20, 63, 2, 59, -11, 68, -11, 74),
-	CABAC_ENTRY(417, 9, -2, 17, -10, 9, -2, 23, -13),
-	CABAC_ENTRY(418, 26, -9, 32, -13, 30, -10, 26, -13),
-	CABAC_ENTRY(419, 33, -9, 42, -9, 31, -4, 40, -15),
-	CABAC_ENTRY(420, 39, -7, 49, -5, 33, -1, 49, -14),
-	CABAC_ENTRY(421, 41, -2, 53, 0, 33, 7, 44, 3),
-	CABAC_ENTRY(422, 45, 3, 64, 3, 31, 12, 45, 6),
-	CABAC_ENTRY(423, 49, 9, 68, 10, 37, 23, 44, 34),
-	CABAC_ENTRY(424, 45, 27, 66, 27, 31, 38, 33, 54),
-	CABAC_ENTRY(425, 36, 59, 47, 57, 20, 64, 19, 82),
-	CABAC_ENTRY(426, -6, 66, -5, 71, -9, 71, -3, 75),
-	CABAC_ENTRY(427, -7, 35, 0, 24, -7, 37, -1, 23),
-	CABAC_ENTRY(428, -7, 42, -1, 36, -8, 44, 1, 34),
-	CABAC_ENTRY(429, -8, 45, -2, 42, -11, 49, 1, 43),
-	CABAC_ENTRY(430, -5, 48, -2, 52, -10, 56, 0, 54),
-	CABAC_ENTRY(431, -12, 56, -9, 57, -12, 59, -2, 55),
-	CABAC_ENTRY(432, -6, 60, -6, 63, -8, 63, 0, 61),
-	CABAC_ENTRY(433, -5, 62, -4, 65, -9, 67, 1, 64),
-	CABAC_ENTRY(434, -8, 66, -4, 67, -6, 68, 0, 68),
-	CABAC_ENTRY(435, -8, 76, -7, 82, -10, 79, -9, 92),
-	CABAC_ENTRY(436, -5, 85, -3, 81, -3, 78, -14, 106),
-	CABAC_ENTRY(437, -6, 81, -3, 76, -8, 74, -13, 97),
-	CABAC_ENTRY(438, -10, 77, -7, 72, -9, 72, -15, 90),
-	CABAC_ENTRY(439, -7, 81, -6, 78, -10, 72, -12, 90),
-	CABAC_ENTRY(440, -17, 80, -12, 72, -18, 75, -18, 88),
-	CABAC_ENTRY(441, -18, 73, -14, 68, -12, 71, -10, 73),
-	CABAC_ENTRY(442, -4, 74, -3, 70, -11, 63, -9, 79),
-	CABAC_ENTRY(443, -10, 83, -6, 76, -5, 70, -14, 86),
-	CABAC_ENTRY(444, -9, 71, -5, 66, -17, 75, -10, 73),
-	CABAC_ENTRY(445, -9, 67, -5, 62, -14, 72, -10, 70),
-	CABAC_ENTRY(446, -1, 61, 0, 57, -16, 67, -10, 69),
-	CABAC_ENTRY(447, -8, 66, -4, 61, -8, 53, -5, 66),
-	CABAC_ENTRY(448, -14, 66, -9, 60, -14, 59, -9, 64),
-	CABAC_ENTRY(449, 0, 59, 1, 54, -9, 52, -5, 58),
-	CABAC_ENTRY(450, 2, 59, 2, 58, -11, 68, 2, 59),
-	CABAC_ENTRY(451, 21, -13, 17, -10, 9, -2, 21, -10),
-	CABAC_ENTRY(452, 33, -14, 32, -13, 30, -10, 24, -11),
-	CABAC_ENTRY(453, 39, -7, 42, -9, 31, -4, 28, -8),
-	CABAC_ENTRY(454, 46, -2, 49, -5, 33, -1, 28, -1),
-	CABAC_ENTRY(455, 51, 2, 53, 0, 33, 7, 29, 3),
-	CABAC_ENTRY(456, 60, 6, 64, 3, 31, 12, 29, 9),
-	CABAC_ENTRY(457, 61, 17, 68, 10, 37, 23, 35, 20),
-	CABAC_ENTRY(458, 55, 34, 66, 27, 31, 38, 29, 36),
-	CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67),
-};
-
 static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value)
 {
 	u8 bit = field.offset % 32, word = field.offset / 32;
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 03/12] media: rkvdec: Use structs to represent the HW RPS
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 01/12] media: rkvdec: Switch to using structs instead of writel Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 02/12] media: rkvdec: Move cabac table to its own source file Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 04/12] media: rkvdec: Move h264 functions to common file Detlev Casanova
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

This is in preparation to add support for other variants of the decoder.

Moving to struct representation is mainly to prepare for multicore
support that is present in e.g. rk3588.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../platform/rockchip/rkvdec/rkvdec-h264.c    | 97 ++++++++++++++++---
 1 file changed, 86 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index 15f2378bbc020..3527919aa8ff6 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -19,7 +19,6 @@ extern const s8 rkvdec_h264_cabac_table[4][464][2];
 
 /* Size with u32 units. */
 #define RKV_CABAC_INIT_BUFFER_SIZE	(3680 + 128)
-#define RKV_RPS_SIZE			((128 + 128) / 4)
 #define RKV_ERROR_INFO_SIZE		(256 * 144 * 4)
 
 #define RKVDEC_NUM_REFLIST		3
@@ -34,6 +33,40 @@ struct rkvdec_sps_pps_packet {
 	u32 info[8];
 };
 
+struct rkvdec_rps_entry {
+	u32 dpb_info0:          5;
+	u32 bottom_flag0:       1;
+	u32 view_index_off0:    1;
+	u32 dpb_info1:          5;
+	u32 bottom_flag1:       1;
+	u32 view_index_off1:    1;
+	u32 dpb_info2:          5;
+	u32 bottom_flag2:       1;
+	u32 view_index_off2:    1;
+	u32 dpb_info3:          5;
+	u32 bottom_flag3:       1;
+	u32 view_index_off3:    1;
+	u32 dpb_info4:          5;
+	u32 bottom_flag4:       1;
+	u32 view_index_off4:    1;
+	u32 dpb_info5:          5;
+	u32 bottom_flag5:       1;
+	u32 view_index_off5:    1;
+	u32 dpb_info6:          5;
+	u32 bottom_flag6:       1;
+	u32 view_index_off6:    1;
+	u32 dpb_info7:          5;
+	u32 bottom_flag7:       1;
+	u32 view_index_off7:    1;
+} __packed;
+
+struct rkvdec_rps {
+	u16 frame_num[16];
+	u32 reserved0;
+	struct rkvdec_rps_entry entries[12];
+	u32 reserved1[66];
+} __packed;
+
 struct rkvdec_ps_field {
 	u16 offset;
 	u8 len;
@@ -94,7 +127,7 @@ struct rkvdec_ps_field {
 struct rkvdec_h264_priv_tbl {
 	s8 cabac_table[4][464][2];
 	struct rkvdec_h264_scaling_list scaling_list;
-	u32 rps[RKV_RPS_SIZE];
+	struct rkvdec_rps rps;
 	struct rkvdec_sps_pps_packet param_set[256];
 	u8 err_info[RKV_ERROR_INFO_SIZE];
 };
@@ -260,20 +293,64 @@ static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
 	}
 }
 
+static void set_dpb_info(struct rkvdec_rps_entry *entries,
+			 u8 reflist,
+			 u8 refnum,
+			 u8 info,
+			 bool bottom)
+{
+	struct rkvdec_rps_entry *entry = &entries[(reflist * 4) + refnum / 8];
+	u8 idx = refnum % 8;
+
+	switch (idx) {
+	case 0:
+		entry->dpb_info0 = info;
+		entry->bottom_flag0 = bottom;
+		break;
+	case 1:
+		entry->dpb_info1 = info;
+		entry->bottom_flag1 = bottom;
+		break;
+	case 2:
+		entry->dpb_info2 = info;
+		entry->bottom_flag2 = bottom;
+		break;
+	case 3:
+		entry->dpb_info3 = info;
+		entry->bottom_flag3 = bottom;
+		break;
+	case 4:
+		entry->dpb_info4 = info;
+		entry->bottom_flag4 = bottom;
+		break;
+	case 5:
+		entry->dpb_info5 = info;
+		entry->bottom_flag5 = bottom;
+		break;
+	case 6:
+		entry->dpb_info6 = info;
+		entry->bottom_flag6 = bottom;
+		break;
+	case 7:
+		entry->dpb_info7 = info;
+		entry->bottom_flag7 = bottom;
+		break;
+	}
+}
+
 static void assemble_hw_rps(struct rkvdec_ctx *ctx,
-			    struct v4l2_h264_reflist_builder *builder,
-			    struct rkvdec_h264_run *run)
+		     struct v4l2_h264_reflist_builder *builder,
+		     struct rkvdec_h264_run *run)
 {
 	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
 	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
 	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
 	struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
 
-	u32 *hw_rps = priv_tbl->rps;
+	struct rkvdec_rps *hw_rps = &priv_tbl->rps;
 	u32 i, j;
-	u16 *p = (u16 *)hw_rps;
 
-	memset(hw_rps, 0, sizeof(priv_tbl->rps));
+	memset(hw_rps, 0, sizeof(*hw_rps));
 
 	/*
 	 * Assign an invalid pic_num if DPB entry at that position is inactive.
@@ -285,7 +362,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
 		if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
 			continue;
 
-		p[i] = builder->refs[i].frame_num;
+		hw_rps->frame_num[i] = builder->refs[i].frame_num;
 	}
 
 	for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
@@ -312,9 +389,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
 			dpb_valid = run->ref_buf[ref->index] != NULL;
 			bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
 
-			set_ps_field(hw_rps, DPB_INFO(i, j),
-				     ref->index | dpb_valid << 4);
-			set_ps_field(hw_rps, BOTTOM_FLAG(i, j), bottom);
+			set_dpb_info(hw_rps->entries, j, i, ref->index | (dpb_valid << 4), bottom);
 		}
 	}
 }
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 04/12] media: rkvdec: Move h264 functions to common file
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (2 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 03/12] media: rkvdec: Use structs to represent the HW RPS Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 05/12] media: rkvdec: Add per variant configuration Detlev Casanova
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

This is a preparation commit to add support for new variants of the
decoder.

The functions will later be shared with vdpu381 (rk3588) and vdpu383
(rk3576).

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Makefile   |   1 +
 .../rockchip/rkvdec/rkvdec-h264-common.c      | 253 ++++++++++++++++
 .../rockchip/rkvdec/rkvdec-h264-common.h      |  79 +++++
 .../platform/rockchip/rkvdec/rkvdec-h264.c    | 274 +-----------------
 4 files changed, 337 insertions(+), 270 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index 164ea06c26c2a..94c067084acd1 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -4,4 +4,5 @@ rockchip-vdec-y += \
 		   rkvdec.o \
 		   rkvdec-cabac.o \
 		   rkvdec-h264.o \
+		   rkvdec-h264-common.o \
 		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
new file mode 100644
index 0000000000000..e7557c3a5cfaf
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip video decoder h264 common functions
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <linux/v4l2-common.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+#include "rkvdec-h264-common.h"
+
+#define RKVDEC_NUM_REFLIST		3
+
+static void set_dpb_info(struct rkvdec_rps_entry *entries,
+			 u8 reflist,
+			 u8 refnum,
+			 u8 info,
+			 bool bottom)
+{
+	struct rkvdec_rps_entry *entry = &entries[(reflist * 4) + refnum / 8];
+	u8 idx = refnum % 8;
+
+	switch (idx) {
+	case 0:
+		entry->dpb_info0 = info;
+		entry->bottom_flag0 = bottom;
+		break;
+	case 1:
+		entry->dpb_info1 = info;
+		entry->bottom_flag1 = bottom;
+		break;
+	case 2:
+		entry->dpb_info2 = info;
+		entry->bottom_flag2 = bottom;
+		break;
+	case 3:
+		entry->dpb_info3 = info;
+		entry->bottom_flag3 = bottom;
+		break;
+	case 4:
+		entry->dpb_info4 = info;
+		entry->bottom_flag4 = bottom;
+		break;
+	case 5:
+		entry->dpb_info5 = info;
+		entry->bottom_flag5 = bottom;
+		break;
+	case 6:
+		entry->dpb_info6 = info;
+		entry->bottom_flag6 = bottom;
+		break;
+	case 7:
+		entry->dpb_info7 = info;
+		entry->bottom_flag7 = bottom;
+		break;
+	}
+}
+
+void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
+			struct rkvdec_h264_run *run)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+		const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb;
+		struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+		struct vb2_buffer *buf = NULL;
+
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) {
+			buf = vb2_find_buffer(cap_q, dpb[i].reference_ts);
+			if (!buf)
+				pr_debug("No buffer for reference_ts %llu",
+					 dpb[i].reference_ts);
+		}
+
+		run->ref_buf[i] = buf;
+	}
+}
+
+void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
+		     struct rkvdec_h264_run *run,
+		     struct rkvdec_h264_reflists *reflists,
+		     struct rkvdec_rps *hw_rps)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
+	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
+
+	u32 i, j;
+
+	memset(hw_rps, 0, sizeof(*hw_rps));
+
+	/*
+	 * Assign an invalid pic_num if DPB entry at that position is inactive.
+	 * If we assign 0 in that position hardware will treat that as a real
+	 * reference picture with pic_num 0, triggering output picture
+	 * corruption.
+	 */
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		hw_rps->frame_num[i] = builder->refs[i].frame_num;
+	}
+
+	for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
+		for (i = 0; i < builder->num_valid; i++) {
+			struct v4l2_h264_reference *ref;
+			bool dpb_valid;
+			bool bottom;
+
+			switch (j) {
+			case 0:
+				ref = &reflists->p[i];
+				break;
+			case 1:
+				ref = &reflists->b0[i];
+				break;
+			case 2:
+				ref = &reflists->b1[i];
+				break;
+			}
+
+			if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb)))
+				continue;
+
+			dpb_valid = !!(run->ref_buf[ref->index]);
+			bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
+
+			set_dpb_info(hw_rps->entries, j, i, ref->index | (dpb_valid << 4), bottom);
+		}
+	}
+}
+
+void assemble_hw_scaling_list(struct rkvdec_h264_run *run,
+			      struct rkvdec_h264_scaling_list *scaling_list)
+{
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix;
+	const struct v4l2_ctrl_h264_pps *pps = run->pps;
+
+	if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT))
+		return;
+
+	BUILD_BUG_ON(sizeof(scaling_list->scaling_list_4x4) !=
+		     sizeof(scaling->scaling_list_4x4));
+	BUILD_BUG_ON(sizeof(scaling_list->scaling_list_8x8) !=
+		     sizeof(scaling->scaling_list_8x8));
+
+	memcpy(scaling_list->scaling_list_4x4,
+	       scaling->scaling_list_4x4,
+	       sizeof(scaling->scaling_list_4x4));
+
+	memcpy(scaling_list->scaling_list_8x8,
+	       scaling->scaling_list_8x8,
+	       sizeof(scaling->scaling_list_8x8));
+}
+
+#define RKVDEC_H264_MAX_DEPTH_IN_BYTES		2
+
+int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx,
+			   struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
+
+	fmt->num_planes = 1;
+	if (!fmt->plane_fmt[0].sizeimage)
+		fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
+					      RKVDEC_H264_MAX_DEPTH_IN_BYTES;
+	return 0;
+}
+
+enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx,
+						struct v4l2_ctrl *ctrl)
+{
+	const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+
+	if (ctrl->id != V4L2_CID_STATELESS_H264_SPS)
+		return RKVDEC_IMG_FMT_ANY;
+
+	if (sps->bit_depth_luma_minus8 == 0) {
+		if (sps->chroma_format_idc == 2)
+			return RKVDEC_IMG_FMT_422_8BIT;
+		else
+			return RKVDEC_IMG_FMT_420_8BIT;
+	} else if (sps->bit_depth_luma_minus8 == 2) {
+		if (sps->chroma_format_idc == 2)
+			return RKVDEC_IMG_FMT_422_10BIT;
+		else
+			return RKVDEC_IMG_FMT_420_10BIT;
+	}
+
+	return RKVDEC_IMG_FMT_ANY;
+}
+
+int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx,
+			     const struct v4l2_ctrl_h264_sps *sps)
+{
+	unsigned int width, height;
+
+	if (sps->chroma_format_idc > 2)
+		/* Only 4:0:0, 4:2:0 and 4:2:2 are supported */
+		return -EINVAL;
+	if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
+		/* Luma and chroma bit depth mismatch */
+		return -EINVAL;
+	if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
+		/* Only 8-bit and 10-bit is supported */
+		return -EINVAL;
+
+	width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
+	height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
+
+	/*
+	 * When frame_mbs_only_flag is not set, this is field height,
+	 * which is half the final height (see (7-18) in the
+	 * specification)
+	 */
+	if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
+		height *= 2;
+
+	if (width > ctx->coded_fmt.fmt.pix_mp.width ||
+	    height > ctx->coded_fmt.fmt.pix_mp.height)
+		return -EINVAL;
+
+	return 0;
+}
+
+void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx,
+			      struct rkvdec_h264_run *run)
+{
+	struct v4l2_ctrl *ctrl;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_H264_SPS);
+	run->sps = ctrl ? ctrl->p_cur.p : NULL;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_H264_PPS);
+	run->pps = ctrl ? ctrl->p_cur.p : NULL;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
+
+	rkvdec_run_preamble(ctx, &run->base);
+}
+
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
new file mode 100644
index 0000000000000..df95a16787341
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip video decoder h264 common functions
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+
+struct rkvdec_h264_scaling_list {
+	u8 scaling_list_4x4[6][16];
+	u8 scaling_list_8x8[6][64];
+	u8 padding[128];
+};
+
+struct rkvdec_h264_reflists {
+	struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN];
+	struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN];
+	struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN];
+};
+
+struct rkvdec_h264_run {
+	struct rkvdec_run base;
+	const struct v4l2_ctrl_h264_decode_params *decode_params;
+	const struct v4l2_ctrl_h264_sps *sps;
+	const struct v4l2_ctrl_h264_pps *pps;
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
+	struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES];
+};
+
+struct rkvdec_rps_entry {
+	u32 dpb_info0:          5;
+	u32 bottom_flag0:       1;
+	u32 view_index_off0:    1;
+	u32 dpb_info1:          5;
+	u32 bottom_flag1:       1;
+	u32 view_index_off1:    1;
+	u32 dpb_info2:          5;
+	u32 bottom_flag2:       1;
+	u32 view_index_off2:    1;
+	u32 dpb_info3:          5;
+	u32 bottom_flag3:       1;
+	u32 view_index_off3:    1;
+	u32 dpb_info4:          5;
+	u32 bottom_flag4:       1;
+	u32 view_index_off4:    1;
+	u32 dpb_info5:          5;
+	u32 bottom_flag5:       1;
+	u32 view_index_off5:    1;
+	u32 dpb_info6:          5;
+	u32 bottom_flag6:       1;
+	u32 view_index_off6:    1;
+	u32 dpb_info7:          5;
+	u32 bottom_flag7:       1;
+	u32 view_index_off7:    1;
+} __packed;
+
+struct rkvdec_rps {
+	u16 frame_num[16];
+	u32 reserved0;
+	struct rkvdec_rps_entry entries[12];
+	u32 reserved1[66];
+} __packed;
+
+void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run);
+void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
+		     struct rkvdec_h264_run *run,
+		     struct rkvdec_h264_reflists *reflists,
+		     struct rkvdec_rps *hw_rps);
+void assemble_hw_scaling_list(struct rkvdec_h264_run *run,
+			      struct rkvdec_h264_scaling_list *scaling_list);
+int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f);
+enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl);
+int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx, const struct v4l2_ctrl_h264_sps *sps);
+void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run);
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index 3527919aa8ff6..28a0ab7840c3e 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -14,6 +14,7 @@
 
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
+#include "rkvdec-h264-common.h"
 
 extern const s8 rkvdec_h264_cabac_table[4][464][2];
 
@@ -21,14 +22,6 @@ extern const s8 rkvdec_h264_cabac_table[4][464][2];
 #define RKV_CABAC_INIT_BUFFER_SIZE	(3680 + 128)
 #define RKV_ERROR_INFO_SIZE		(256 * 144 * 4)
 
-#define RKVDEC_NUM_REFLIST		3
-
-struct rkvdec_h264_scaling_list {
-	u8 scaling_list_4x4[6][16];
-	u8 scaling_list_8x8[6][64];
-	u8 padding[128];
-};
-
 struct rkvdec_sps_pps_packet {
 	u32 info[8];
 };
@@ -118,11 +111,6 @@ struct rkvdec_ps_field {
 #define SCALING_LIST_ADDRESS				PS_FIELD(184, 32)
 #define IS_LONG_TERM(i)				PS_FIELD(216 + (i), 1)
 
-#define DPB_OFFS(i, j)					(288 + ((j) * 32 * 7) + ((i) * 7))
-#define DPB_INFO(i, j)					PS_FIELD(DPB_OFFS(i, j), 5)
-#define BOTTOM_FLAG(i, j)				PS_FIELD(DPB_OFFS(i, j) + 5, 1)
-#define VIEW_INDEX_OFF(i, j)				PS_FIELD(DPB_OFFS(i, j) + 6, 1)
-
 /* Data structure describing auxiliary buffer format. */
 struct rkvdec_h264_priv_tbl {
 	s8 cabac_table[4][464][2];
@@ -132,21 +120,6 @@ struct rkvdec_h264_priv_tbl {
 	u8 err_info[RKV_ERROR_INFO_SIZE];
 };
 
-struct rkvdec_h264_reflists {
-	struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN];
-	struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN];
-	struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN];
-};
-
-struct rkvdec_h264_run {
-	struct rkvdec_run base;
-	const struct v4l2_ctrl_h264_decode_params *decode_params;
-	const struct v4l2_ctrl_h264_sps *sps;
-	const struct v4l2_ctrl_h264_pps *pps;
-	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
-	struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES];
-};
-
 struct rkvdec_h264_ctx {
 	struct rkvdec_aux_buf priv_tbl;
 	struct rkvdec_h264_reflists reflists;
@@ -270,155 +243,6 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
 	}
 }
 
-static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
-			       struct rkvdec_h264_run *run)
-{
-	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
-	u32 i;
-
-	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
-		struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
-		const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb;
-		struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
-		struct vb2_buffer *buf = NULL;
-
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) {
-			buf = vb2_find_buffer(cap_q, dpb[i].reference_ts);
-			if (!buf)
-				pr_debug("No buffer for reference_ts %llu",
-					 dpb[i].reference_ts);
-		}
-
-		run->ref_buf[i] = buf;
-	}
-}
-
-static void set_dpb_info(struct rkvdec_rps_entry *entries,
-			 u8 reflist,
-			 u8 refnum,
-			 u8 info,
-			 bool bottom)
-{
-	struct rkvdec_rps_entry *entry = &entries[(reflist * 4) + refnum / 8];
-	u8 idx = refnum % 8;
-
-	switch (idx) {
-	case 0:
-		entry->dpb_info0 = info;
-		entry->bottom_flag0 = bottom;
-		break;
-	case 1:
-		entry->dpb_info1 = info;
-		entry->bottom_flag1 = bottom;
-		break;
-	case 2:
-		entry->dpb_info2 = info;
-		entry->bottom_flag2 = bottom;
-		break;
-	case 3:
-		entry->dpb_info3 = info;
-		entry->bottom_flag3 = bottom;
-		break;
-	case 4:
-		entry->dpb_info4 = info;
-		entry->bottom_flag4 = bottom;
-		break;
-	case 5:
-		entry->dpb_info5 = info;
-		entry->bottom_flag5 = bottom;
-		break;
-	case 6:
-		entry->dpb_info6 = info;
-		entry->bottom_flag6 = bottom;
-		break;
-	case 7:
-		entry->dpb_info7 = info;
-		entry->bottom_flag7 = bottom;
-		break;
-	}
-}
-
-static void assemble_hw_rps(struct rkvdec_ctx *ctx,
-		     struct v4l2_h264_reflist_builder *builder,
-		     struct rkvdec_h264_run *run)
-{
-	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
-	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
-	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
-	struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
-
-	struct rkvdec_rps *hw_rps = &priv_tbl->rps;
-	u32 i, j;
-
-	memset(hw_rps, 0, sizeof(*hw_rps));
-
-	/*
-	 * Assign an invalid pic_num if DPB entry at that position is inactive.
-	 * If we assign 0 in that position hardware will treat that as a real
-	 * reference picture with pic_num 0, triggering output picture
-	 * corruption.
-	 */
-	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
-		if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
-			continue;
-
-		hw_rps->frame_num[i] = builder->refs[i].frame_num;
-	}
-
-	for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
-		for (i = 0; i < builder->num_valid; i++) {
-			struct v4l2_h264_reference *ref;
-			bool dpb_valid;
-			bool bottom;
-
-			switch (j) {
-			case 0:
-				ref = &h264_ctx->reflists.p[i];
-				break;
-			case 1:
-				ref = &h264_ctx->reflists.b0[i];
-				break;
-			case 2:
-				ref = &h264_ctx->reflists.b1[i];
-				break;
-			}
-
-			if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb)))
-				continue;
-
-			dpb_valid = run->ref_buf[ref->index] != NULL;
-			bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
-
-			set_dpb_info(hw_rps->entries, j, i, ref->index | (dpb_valid << 4), bottom);
-		}
-	}
-}
-
-static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
-				     struct rkvdec_h264_run *run)
-{
-	const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix;
-	const struct v4l2_ctrl_h264_pps *pps = run->pps;
-	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
-	struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
-
-	if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT))
-		return;
-
-	BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_4x4) !=
-		     sizeof(scaling->scaling_list_4x4));
-	BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_8x8) !=
-		     sizeof(scaling->scaling_list_8x8));
-
-	memcpy(tbl->scaling_list.scaling_list_4x4,
-	       scaling->scaling_list_4x4,
-	       sizeof(scaling->scaling_list_4x4));
-
-	memcpy(tbl->scaling_list.scaling_list_8x8,
-	       scaling->scaling_list_8x8,
-	       sizeof(scaling->scaling_list_8x8));
-}
-
 /*
  * Set the ref POC in the correct register.
  *
@@ -568,76 +392,6 @@ static void config_registers(struct rkvdec_ctx *ctx,
 	rkvdec_memcpy_toio(rkvdec->regs, regs, sizeof(*regs));
 }
 
-#define RKVDEC_H264_MAX_DEPTH_IN_BYTES		2
-
-static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx,
-				  struct v4l2_format *f)
-{
-	struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
-
-	fmt->num_planes = 1;
-	if (!fmt->plane_fmt[0].sizeimage)
-		fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
-					      RKVDEC_H264_MAX_DEPTH_IN_BYTES;
-	return 0;
-}
-
-static enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx,
-						       struct v4l2_ctrl *ctrl)
-{
-	const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
-
-	if (ctrl->id != V4L2_CID_STATELESS_H264_SPS)
-		return RKVDEC_IMG_FMT_ANY;
-
-	if (sps->bit_depth_luma_minus8 == 0) {
-		if (sps->chroma_format_idc == 2)
-			return RKVDEC_IMG_FMT_422_8BIT;
-		else
-			return RKVDEC_IMG_FMT_420_8BIT;
-	} else if (sps->bit_depth_luma_minus8 == 2) {
-		if (sps->chroma_format_idc == 2)
-			return RKVDEC_IMG_FMT_422_10BIT;
-		else
-			return RKVDEC_IMG_FMT_420_10BIT;
-	}
-
-	return RKVDEC_IMG_FMT_ANY;
-}
-
-static int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx,
-				    const struct v4l2_ctrl_h264_sps *sps)
-{
-	unsigned int width, height;
-
-	if (sps->chroma_format_idc > 2)
-		/* Only 4:0:0, 4:2:0 and 4:2:2 are supported */
-		return -EINVAL;
-	if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
-		/* Luma and chroma bit depth mismatch */
-		return -EINVAL;
-	if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
-		/* Only 8-bit and 10-bit is supported */
-		return -EINVAL;
-
-	width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
-	height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
-
-	/*
-	 * When frame_mbs_only_flag is not set, this is field height,
-	 * which is half the final height (see (7-18) in the
-	 * specification)
-	 */
-	if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
-		height *= 2;
-
-	if (width > ctx->coded_fmt.fmt.pix_mp.width ||
-	    height > ctx->coded_fmt.fmt.pix_mp.height)
-		return -EINVAL;
-
-	return 0;
-}
-
 static int rkvdec_h264_start(struct rkvdec_ctx *ctx)
 {
 	struct rkvdec_dev *rkvdec = ctx->dev;
@@ -689,33 +443,13 @@ static void rkvdec_h264_stop(struct rkvdec_ctx *ctx)
 	kfree(h264_ctx);
 }
 
-static void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx,
-				     struct rkvdec_h264_run *run)
-{
-	struct v4l2_ctrl *ctrl;
-
-	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-			      V4L2_CID_STATELESS_H264_DECODE_PARAMS);
-	run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
-	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-			      V4L2_CID_STATELESS_H264_SPS);
-	run->sps = ctrl ? ctrl->p_cur.p : NULL;
-	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-			      V4L2_CID_STATELESS_H264_PPS);
-	run->pps = ctrl ? ctrl->p_cur.p : NULL;
-	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
-			      V4L2_CID_STATELESS_H264_SCALING_MATRIX);
-	run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
-
-	rkvdec_run_preamble(ctx, &run->base);
-}
-
 static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
 {
 	struct v4l2_h264_reflist_builder reflist_builder;
 	struct rkvdec_dev *rkvdec = ctx->dev;
 	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
 	struct rkvdec_h264_run run;
+	struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
 
 	rkvdec_h264_run_preamble(ctx, &run);
 
@@ -726,10 +460,10 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
 	v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
 				    h264_ctx->reflists.b1);
 
-	assemble_hw_scaling_list(ctx, &run);
+	assemble_hw_scaling_list(&run, &tbl->scaling_list);
 	assemble_hw_pps(ctx, &run);
 	lookup_ref_buf_idx(ctx, &run);
-	assemble_hw_rps(ctx, &reflist_builder, &run);
+	assemble_hw_rps(&reflist_builder, &run, &h264_ctx->reflists, &tbl->rps);
 	config_registers(ctx, &run);
 
 	rkvdec_run_postamble(ctx, &run.base);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 05/12] media: rkvdec: Add per variant configuration
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (3 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 04/12] media: rkvdec: Move h264 functions to common file Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-11  6:13   ` Krzysztof Kozlowski
  2025-08-08 20:03 ` [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support Detlev Casanova
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

This is to prepare for adding different variants of the decoder and
support specific formats and ops.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/rkvdec.c   | 50 ++++++++++++-------
 .../media/platform/rockchip/rkvdec/rkvdec.h   |  6 +++
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index a71837103b71d..28585522523c7 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -286,13 +286,14 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
 };
 
 static const struct rkvdec_coded_fmt_desc *
-rkvdec_find_coded_fmt_desc(u32 fourcc)
+rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
 {
+	struct rkvdec_config *cfg = ctx->dev->config;
 	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
-		if (rkvdec_coded_fmts[i].fourcc == fourcc)
-			return &rkvdec_coded_fmts[i];
+	for (i = 0; i < cfg->coded_fmts_num; i++) {
+		if (cfg->coded_fmts[i].fourcc == fourcc)
+			return &cfg->coded_fmts[i];
 	}
 
 	return NULL;
@@ -300,9 +301,10 @@ rkvdec_find_coded_fmt_desc(u32 fourcc)
 
 static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
 {
+	struct rkvdec_config *cfg = ctx->dev->config;
 	struct v4l2_format *f = &ctx->coded_fmt;
 
-	ctx->coded_fmt_desc = &rkvdec_coded_fmts[0];
+	ctx->coded_fmt_desc = &cfg->coded_fmts[0];
 	rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc);
 
 	f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
@@ -316,12 +318,13 @@ static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
 static int rkvdec_enum_framesizes(struct file *file, void *priv,
 				  struct v4l2_frmsizeenum *fsize)
 {
+	struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
 	const struct rkvdec_coded_fmt_desc *fmt;
 
 	if (fsize->index != 0)
 		return -EINVAL;
 
-	fmt = rkvdec_find_coded_fmt_desc(fsize->pixel_format);
+	fmt = rkvdec_find_coded_fmt_desc(ctx, fsize->pixel_format);
 	if (!fmt)
 		return -EINVAL;
 
@@ -388,12 +391,13 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
 {
 	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 	struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+	struct rkvdec_config *cfg = ctx->dev->config;
 	const struct rkvdec_coded_fmt_desc *desc;
 
-	desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat);
+	desc = rkvdec_find_coded_fmt_desc(ctx, pix_mp->pixelformat);
 	if (!desc) {
-		pix_mp->pixelformat = rkvdec_coded_fmts[0].fourcc;
-		desc = &rkvdec_coded_fmts[0];
+		pix_mp->pixelformat = cfg->coded_fmts[0].fourcc;
+		desc = &cfg->coded_fmts[0];
 	}
 
 	v4l2_apply_frmsize_constraints(&pix_mp->width,
@@ -470,7 +474,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
 	if (ret)
 		return ret;
 
-	desc = rkvdec_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat);
+	desc = rkvdec_find_coded_fmt_desc(ctx, f->fmt.pix_mp.pixelformat);
 	if (!desc)
 		return -EINVAL;
 	ctx->coded_fmt_desc = desc;
@@ -522,10 +526,13 @@ static int rkvdec_g_capture_fmt(struct file *file, void *priv,
 static int rkvdec_enum_output_fmt(struct file *file, void *priv,
 				  struct v4l2_fmtdesc *f)
 {
-	if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts))
+	struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+	struct rkvdec_config *cfg = ctx->dev->config;
+
+	if (f->index >= cfg->coded_fmts_num)
 		return -EINVAL;
 
-	f->pixelformat = rkvdec_coded_fmts[f->index].fourcc;
+	f->pixelformat = cfg->coded_fmts[f->index].fourcc;
 	return 0;
 }
 
@@ -895,16 +902,17 @@ static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx,
 
 static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
 {
+	struct rkvdec_config *cfg = ctx->dev->config;
 	unsigned int i, nctrls = 0;
 	int ret;
 
-	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++)
-		nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
+	for (i = 0; i < cfg->coded_fmts_num; i++)
+		nctrls += cfg->coded_fmts[i].ctrls->num_ctrls;
 
 	v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
 
-	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
-		ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
+	for (i = 0; i < cfg->coded_fmts_num; i++) {
+		ret = rkvdec_add_ctrls(ctx, cfg->coded_fmts[i].ctrls);
 		if (ret)
 			goto err_free_handler;
 	}
@@ -1119,8 +1127,13 @@ static void rkvdec_watchdog_func(struct work_struct *work)
 	}
 }
 
+const struct rkvdec_config config_rkvdec = {
+	.coded_fmts = (struct rkvdec_coded_fmt_desc *)rkvdec_coded_fmts,
+	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
+};
+
 static const struct of_device_id of_rkvdec_match[] = {
-	{ .compatible = "rockchip,rk3399-vdec" },
+	{ .compatible = "rockchip,rk3399-vdec", .data = &config_rkvdec },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_rkvdec_match);
@@ -1144,6 +1157,9 @@ static int rkvdec_probe(struct platform_device *pdev)
 	mutex_init(&rkvdec->vdev_lock);
 	INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);
 
+	rkvdec->config =
+		(struct rkvdec_config *)of_device_get_match_data(rkvdec->dev);
+
 	rkvdec->clocks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names),
 				      sizeof(*rkvdec->clocks), GFP_KERNEL);
 	if (!rkvdec->clocks)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index 3451c4bf7cb75..14717c646c665 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -100,6 +100,11 @@ struct rkvdec_coded_fmt_desc {
 	u32 subsystem_flags;
 };
 
+struct rkvdec_config {
+	struct rkvdec_coded_fmt_desc *coded_fmts;
+	size_t coded_fmts_num;
+};
+
 struct rkvdec_dev {
 	struct v4l2_device v4l2_dev;
 	struct media_device mdev;
@@ -111,6 +116,7 @@ struct rkvdec_dev {
 	struct mutex vdev_lock; /* serializes ioctls */
 	struct delayed_work watchdog_work;
 	struct iommu_domain *empty_domain;
+	struct rkvdec_config *config;
 };
 
 struct rkvdec_ctx {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (4 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 05/12] media: rkvdec: Add per variant configuration Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-11  6:13   ` Krzysztof Kozlowski
  2025-08-08 20:03 ` [PATCH v2 07/12] media: rkvdec: Support per-variant interrupt handler Detlev Casanova
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

The RCB (Rows and Cols Buffers) are a set of buffers used by other
variations of the decoder to store temporary data.

Those variation come with a dedicated SRAM area used to store those
buffers for better performances.

The buffer sizes are either the width or height of the frame being
decoded multiplied by a documented factor and can be stored either
in SRAM or RAM.
A fallback to RAM is provided if the SRAM is full (e.g.: multiple
streams are being decoded at the same time).

To manage the different kind of allocation, an enum is added to the
rkvdec_aux_buf struct to specify how the buffer was allocated, and
so, how to free it.

This commit is in preparation of other variants support.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Makefile   |   1 +
 .../platform/rockchip/rkvdec/rkvdec-rcb.c     | 174 ++++++++++++++++++
 .../platform/rockchip/rkvdec/rkvdec-rcb.h     |  29 +++
 .../media/platform/rockchip/rkvdec/rkvdec.c   |  29 ++-
 .../media/platform/rockchip/rkvdec/rkvdec.h   |  13 ++
 5 files changed, 242 insertions(+), 4 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index 94c067084acd1..2b7ba9f7de286 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -5,4 +5,5 @@ rockchip-vdec-y += \
 		   rkvdec-cabac.o \
 		   rkvdec-h264.o \
 		   rkvdec-h264-common.o \
+		   rkvdec-rcb.o \
 		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c
new file mode 100644
index 0000000000000..210e59db2c622
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip video decoder Rows and Cols Buffers manager
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include "rkvdec.h"
+#include "rkvdec-rcb.h"
+
+#include <linux/types.h>
+#include <linux/iommu.h>
+#include <linux/genalloc.h>
+
+struct rkvdec_rcb_config {
+	struct rkvdec_aux_buf *rcb_bufs;
+	size_t rcb_count;
+};
+
+static size_t rkvdec_rcb_size(const struct rcb_size_info *size_info,
+			      unsigned int width, unsigned int height)
+{
+	return size_info->multiplier * (size_info->axis == PIC_HEIGHT ? height : width);
+}
+
+dma_addr_t rkvdec_rcb_buf_dma_addr(struct rkvdec_ctx *ctx, int id)
+{
+	return ctx->rcb_config->rcb_bufs[id].dma;
+}
+
+size_t rkvdec_rcb_buf_size(struct rkvdec_ctx *ctx, int id)
+{
+	return ctx->rcb_config->rcb_bufs[id].size;
+}
+
+int rkvdec_rcb_buf_count(struct rkvdec_ctx *ctx)
+{
+	return ctx->rcb_config->rcb_count;
+}
+
+void rkvdec_free_rcb(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *dev = ctx->dev;
+	struct rkvdec_rcb_config *cfg = ctx->rcb_config;
+	unsigned long virt_addr;
+	int i;
+
+	if (!cfg)
+		return;
+
+	for (i = 0; i < cfg->rcb_count; i++) {
+		size_t rcb_size = cfg->rcb_bufs[i].size;
+
+		if (!cfg->rcb_bufs[i].cpu)
+			continue;
+
+		switch (cfg->rcb_bufs[i].type) {
+		case RKVDEC2_ALLOC_SRAM:
+			virt_addr = (unsigned long)cfg->rcb_bufs[i].cpu;
+
+			if (dev->iommu_domain)
+				iommu_unmap(dev->iommu_domain, virt_addr, rcb_size);
+			gen_pool_free(dev->sram_pool, virt_addr, rcb_size);
+			break;
+		case RKVDEC2_ALLOC_DMA:
+			dma_free_coherent(dev->dev,
+					  rcb_size,
+					  cfg->rcb_bufs[i].cpu,
+					  cfg->rcb_bufs[i].dma);
+			break;
+		}
+	}
+
+	if (cfg->rcb_bufs)
+		devm_kfree(dev->dev, cfg->rcb_bufs);
+
+	devm_kfree(dev->dev, cfg);
+}
+
+int rkvdec_allocate_rcb(struct rkvdec_ctx *ctx,
+			const struct rcb_size_info *size_info,
+			size_t rcb_count)
+{
+	int ret, i;
+	u32 width, height;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_rcb_config *cfg;
+
+	ctx->rcb_config = devm_kzalloc(rkvdec->dev, sizeof(*ctx->rcb_config), GFP_KERNEL);
+	if (!ctx->rcb_config)
+		return -ENOMEM;
+
+	cfg = ctx->rcb_config;
+
+	cfg->rcb_bufs = devm_kzalloc(rkvdec->dev, sizeof(*cfg->rcb_bufs) * rcb_count, GFP_KERNEL);
+	if (!cfg->rcb_bufs) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	width = ctx->decoded_fmt.fmt.pix_mp.width;
+	height = ctx->decoded_fmt.fmt.pix_mp.height;
+
+	for (i = 0; i < rcb_count; i++) {
+		void *cpu = NULL;
+		dma_addr_t dma;
+		size_t rcb_size = rkvdec_rcb_size(&size_info[i], width, height);
+		enum rkvdec_alloc_type alloc_type = RKVDEC2_ALLOC_SRAM;
+
+		/* Try allocating an SRAM buffer */
+		if (ctx->dev->sram_pool) {
+			if (rkvdec->iommu_domain)
+				rcb_size = ALIGN(rcb_size, 0x1000);
+
+			cpu = gen_pool_dma_zalloc_align(ctx->dev->sram_pool,
+							rcb_size,
+							&dma,
+							0x1000);
+		}
+
+		/* If an IOMMU is used, map the SRAM address through it */
+		if (cpu && rkvdec->iommu_domain) {
+			unsigned long virt_addr = (unsigned long)cpu;
+			phys_addr_t phys_addr = dma;
+
+			ret = iommu_map(rkvdec->iommu_domain, virt_addr, phys_addr,
+					rcb_size, IOMMU_READ | IOMMU_WRITE, 0);
+			if (ret) {
+				gen_pool_free(ctx->dev->sram_pool,
+					      (unsigned long)cpu,
+					      rcb_size);
+				cpu = NULL;
+				goto ram_fallback;
+			}
+
+			/*
+			 * The registers will be configured with the virtual
+			 * address so that it goes through the IOMMU
+			 */
+			dma = virt_addr;
+		}
+
+ram_fallback:
+		/* Fallback to RAM */
+		if (!cpu) {
+			cpu = dma_alloc_coherent(ctx->dev->dev,
+						 rcb_size,
+						 &dma,
+						 GFP_KERNEL);
+			alloc_type = RKVDEC2_ALLOC_DMA;
+		}
+
+		if (!cpu) {
+			ret = -ENOMEM;
+			goto err_alloc;
+		}
+
+		cfg->rcb_bufs[i].cpu = cpu;
+		cfg->rcb_bufs[i].dma = dma;
+		cfg->rcb_bufs[i].size = rcb_size;
+		cfg->rcb_bufs[i].type = alloc_type;
+
+		cfg->rcb_count += 1;
+	}
+
+	return 0;
+
+err_alloc:
+	rkvdec_free_rcb(ctx);
+
+	return ret;
+}
+
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h
new file mode 100644
index 0000000000000..30e8002555c8a
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-rcb.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip video decoder Rows and Cols Buffers manager
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <linux/types.h>
+
+struct rkvdec_ctx;
+
+enum rcb_axis {
+	PIC_WIDTH = 0,
+	PIC_HEIGHT = 1
+};
+
+struct rcb_size_info {
+	u8 multiplier;
+	enum rcb_axis axis;
+};
+
+int rkvdec_allocate_rcb(struct rkvdec_ctx *ctx,
+			const struct rcb_size_info *size_info,
+			size_t rcb_count);
+dma_addr_t rkvdec_rcb_buf_dma_addr(struct rkvdec_ctx *ctx, int id);
+size_t rkvdec_rcb_buf_size(struct rkvdec_ctx *ctx, int id);
+int rkvdec_rcb_buf_count(struct rkvdec_ctx *ctx);
+void rkvdec_free_rcb(struct rkvdec_ctx *ctx);
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 28585522523c7..2602676a047a1 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/genalloc.h>
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/module.h>
@@ -27,6 +28,7 @@
 
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
+#include "rkvdec-rcb.h"
 
 static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,
 				   enum rkvdec_image_fmt fmt2)
@@ -668,6 +670,7 @@ static int rkvdec_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct rkvdec_ctx *ctx = vb2_get_drv_priv(q);
 	const struct rkvdec_coded_fmt_desc *desc;
+	struct rkvdec_config *cfg = ctx->dev->config;
 	int ret;
 
 	if (V4L2_TYPE_IS_CAPTURE(q->type))
@@ -677,13 +680,22 @@ static int rkvdec_start_streaming(struct vb2_queue *q, unsigned int count)
 	if (WARN_ON(!desc))
 		return -EINVAL;
 
+	ret = rkvdec_allocate_rcb(ctx, cfg->rcb_size_info, cfg->rcb_num);
+	if (ret)
+		return ret;
+
 	if (desc->ops->start) {
 		ret = desc->ops->start(ctx);
 		if (ret)
-			return ret;
+			goto err_ops_start;
 	}
 
 	return 0;
+
+err_ops_start:
+	rkvdec_free_rcb(ctx);
+
+	return ret;
 }
 
 static void rkvdec_queue_cleanup(struct vb2_queue *vq, u32 state)
@@ -719,6 +731,8 @@ static void rkvdec_stop_streaming(struct vb2_queue *q)
 
 		if (desc->ops->stop)
 			desc->ops->stop(ctx);
+
+		rkvdec_free_rcb(ctx);
 	}
 
 	rkvdec_queue_cleanup(q, VB2_BUF_STATE_ERROR);
@@ -1183,15 +1197,14 @@ static int rkvdec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	if (iommu_get_domain_for_dev(&pdev->dev)) {
+	rkvdec->iommu_domain = iommu_get_domain_for_dev(&pdev->dev);
+	if (rkvdec->iommu_domain) {
 		rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev);
 
 		if (!rkvdec->empty_domain)
 			dev_warn(rkvdec->dev, "cannot alloc new empty domain\n");
 	}
 
-	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq <= 0)
 		return -ENXIO;
@@ -1204,6 +1217,10 @@ static int rkvdec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
+	if (!rkvdec->sram_pool && rkvdec->config->rcb_num > 0)
+		dev_info(&pdev->dev, "No sram node, RCB will be stored in RAM\n");
+
 	pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
@@ -1217,6 +1234,10 @@ static int rkvdec_probe(struct platform_device *pdev)
 err_disable_runtime_pm:
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+
+	if (rkvdec->sram_pool)
+		gen_pool_destroy(rkvdec->sram_pool);
+
 	return ret;
 }
 
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index 14717c646c665..3a073883d21eb 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -19,10 +19,12 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 
 struct rkvdec_ctx;
+struct rkvdec_rcb_config;
 
 struct rkvdec_ctrl_desc {
 	struct v4l2_ctrl_config cfg;
@@ -103,6 +105,8 @@ struct rkvdec_coded_fmt_desc {
 struct rkvdec_config {
 	struct rkvdec_coded_fmt_desc *coded_fmts;
 	size_t coded_fmts_num;
+	struct rcb_size_info *rcb_size_info;
+	size_t rcb_num;
 };
 
 struct rkvdec_dev {
@@ -115,6 +119,8 @@ struct rkvdec_dev {
 	void __iomem *regs;
 	struct mutex vdev_lock; /* serializes ioctls */
 	struct delayed_work watchdog_work;
+	struct gen_pool *sram_pool;
+	struct iommu_domain *iommu_domain;
 	struct iommu_domain *empty_domain;
 	struct rkvdec_config *config;
 };
@@ -127,6 +133,7 @@ struct rkvdec_ctx {
 	struct v4l2_ctrl_handler ctrl_hdl;
 	struct rkvdec_dev *dev;
 	enum rkvdec_image_fmt image_fmt;
+	struct rkvdec_rcb_config *rcb_config;
 	void *priv;
 };
 
@@ -135,10 +142,16 @@ static inline struct rkvdec_ctx *fh_to_rkvdec_ctx(struct v4l2_fh *fh)
 	return container_of(fh, struct rkvdec_ctx, fh);
 }
 
+enum rkvdec_alloc_type {
+	RKVDEC2_ALLOC_DMA  = 0,
+	RKVDEC2_ALLOC_SRAM = 1,
+};
+
 struct rkvdec_aux_buf {
 	void *cpu;
 	dma_addr_t dma;
 	size_t size;
+	enum rkvdec_alloc_type type;
 };
 
 void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 07/12] media: rkvdec: Support per-variant interrupt handler
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (5 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 08/12] media: rkvdec: Enable all clocks without naming them Detlev Casanova
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

Preparation commit for supporting different variants with different
interrupt management.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 drivers/media/platform/rockchip/rkvdec/rkvdec.c | 15 ++++++++++++---
 drivers/media/platform/rockchip/rkvdec/rkvdec.h |  1 +
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 2602676a047a1..5f3057e8136b5 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -1102,10 +1102,9 @@ static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec)
 	}
 }
 
-static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
+static irqreturn_t rk3399_irq_handler(struct rkvdec_ctx *ctx)
 {
-	struct rkvdec_dev *rkvdec = priv;
-	struct rkvdec_ctx *ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
+	struct rkvdec_dev *rkvdec = ctx->dev;
 	enum vb2_buffer_state state;
 	u32 status;
 
@@ -1126,6 +1125,15 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
+{
+	struct rkvdec_dev *rkvdec = priv;
+	struct rkvdec_ctx *ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
+	struct rkvdec_config *cfg = rkvdec->config;
+
+	return cfg->irq_handler(ctx);
+}
+
 static void rkvdec_watchdog_func(struct work_struct *work)
 {
 	struct rkvdec_dev *rkvdec;
@@ -1144,6 +1152,7 @@ static void rkvdec_watchdog_func(struct work_struct *work)
 const struct rkvdec_config config_rkvdec = {
 	.coded_fmts = (struct rkvdec_coded_fmt_desc *)rkvdec_coded_fmts,
 	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
+	.irq_handler = rk3399_irq_handler,
 };
 
 static const struct of_device_id of_rkvdec_match[] = {
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index 3a073883d21eb..679de66df2479 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -107,6 +107,7 @@ struct rkvdec_config {
 	size_t coded_fmts_num;
 	struct rcb_size_info *rcb_size_info;
 	size_t rcb_num;
+	irqreturn_t (*irq_handler)(struct rkvdec_ctx *ctx);
 };
 
 struct rkvdec_dev {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 08/12] media: rkvdec: Enable all clocks without naming them
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (6 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 07/12] media: rkvdec: Support per-variant interrupt handler Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-08 20:03 ` [PATCH v2 09/12] media: rkvdec: Add H264 support for the VDPU381 variant Detlev Casanova
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

For other variants, the clock names and number will differ.

There is no need to keep track of the clock names in the driver so drop
them to avoid having a list for each variant.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/rkvdec.c   | 24 +++++--------------
 .../media/platform/rockchip/rkvdec/rkvdec.h   |  1 +
 2 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 5f3057e8136b5..0ccf1ba81958a 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -1161,14 +1161,9 @@ static const struct of_device_id of_rkvdec_match[] = {
 };
 MODULE_DEVICE_TABLE(of, of_rkvdec_match);
 
-static const char * const rkvdec_clk_names[] = {
-	"axi", "ahb", "cabac", "core"
-};
-
 static int rkvdec_probe(struct platform_device *pdev)
 {
 	struct rkvdec_dev *rkvdec;
-	unsigned int i;
 	int ret, irq;
 
 	rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL);
@@ -1183,19 +1178,12 @@ static int rkvdec_probe(struct platform_device *pdev)
 	rkvdec->config =
 		(struct rkvdec_config *)of_device_get_match_data(rkvdec->dev);
 
-	rkvdec->clocks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names),
-				      sizeof(*rkvdec->clocks), GFP_KERNEL);
-	if (!rkvdec->clocks)
-		return -ENOMEM;
-
-	for (i = 0; i < ARRAY_SIZE(rkvdec_clk_names); i++)
-		rkvdec->clocks[i].id = rkvdec_clk_names[i];
-
-	ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names),
-				rkvdec->clocks);
-	if (ret)
+	ret = devm_clk_bulk_get_all_enabled(&pdev->dev, &rkvdec->clocks);
+	if (ret < 0)
 		return ret;
 
+	rkvdec->clk_count = ret;
+
 	rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(rkvdec->regs))
 		return PTR_ERR(rkvdec->regs);
@@ -1269,7 +1257,7 @@ static int rkvdec_runtime_resume(struct device *dev)
 {
 	struct rkvdec_dev *rkvdec = dev_get_drvdata(dev);
 
-	return clk_bulk_prepare_enable(ARRAY_SIZE(rkvdec_clk_names),
+	return clk_bulk_prepare_enable(rkvdec->clk_count,
 				       rkvdec->clocks);
 }
 
@@ -1277,7 +1265,7 @@ static int rkvdec_runtime_suspend(struct device *dev)
 {
 	struct rkvdec_dev *rkvdec = dev_get_drvdata(dev);
 
-	clk_bulk_disable_unprepare(ARRAY_SIZE(rkvdec_clk_names),
+	clk_bulk_disable_unprepare(rkvdec->clk_count,
 				   rkvdec->clocks);
 	return 0;
 }
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index 679de66df2479..af47f16cb417d 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -117,6 +117,7 @@ struct rkvdec_dev {
 	struct v4l2_m2m_dev *m2m_dev;
 	struct device *dev;
 	struct clk_bulk_data *clocks;
+	unsigned int clk_count;
 	void __iomem *regs;
 	struct mutex vdev_lock; /* serializes ioctls */
 	struct delayed_work watchdog_work;
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 09/12] media: rkvdec: Add H264 support for the VDPU381 variant
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (7 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 08/12] media: rkvdec: Enable all clocks without naming them Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-12 17:07   ` Dmitry Osipenko
  2025-08-08 20:03 ` [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant Detlev Casanova
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

This decoder variant is found in Rockchip RK3588 SoC family.

Like for rkvdec on rk3399, it supports the NV12, NV15, NV16 and NV20
output formats and level up to 5.1.

The maximum width and height have been significantly increased
supporting up to 65520 pixels for both.

Also make sure to only expose the first core and ignore the other
until mutli-core is supported.

Fluster score for JVT-AVC_V1 is 129/135.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Makefile   |   1 +
 .../rockchip/rkvdec/rkvdec-h264-common.h      |   2 +
 .../platform/rockchip/rkvdec/rkvdec-h264.c    |  36 --
 .../rockchip/rkvdec/rkvdec-vdpu381-h264.c     | 469 ++++++++++++++++++
 .../rockchip/rkvdec/rkvdec-vdpu381-regs.h     | 427 ++++++++++++++++
 .../media/platform/rockchip/rkvdec/rkvdec.c   | 164 +++++-
 .../media/platform/rockchip/rkvdec/rkvdec.h   |   6 +
 7 files changed, 1067 insertions(+), 38 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index 2b7ba9f7de286..20128bb6e35dc 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -6,4 +6,5 @@ rockchip-vdec-y += \
 		   rkvdec-h264.o \
 		   rkvdec-h264-common.o \
 		   rkvdec-rcb.o \
+		   rkvdec-vdpu381-h264.o \
 		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
index df95a16787341..38446e2886e3d 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
@@ -66,6 +66,8 @@ struct rkvdec_rps {
 	u32 reserved1[66];
 } __packed;
 
+extern const s8 rkvdec_h264_cabac_table[4][464][2];
+
 void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run);
 void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
 		     struct rkvdec_h264_run *run,
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index 28a0ab7840c3e..d50e985cff953 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -16,8 +16,6 @@
 #include "rkvdec-regs.h"
 #include "rkvdec-h264-common.h"
 
-extern const s8 rkvdec_h264_cabac_table[4][464][2];
-
 /* Size with u32 units. */
 #define RKV_CABAC_INIT_BUFFER_SIZE	(3680 + 128)
 #define RKV_ERROR_INFO_SIZE		(256 * 144 * 4)
@@ -26,40 +24,6 @@ struct rkvdec_sps_pps_packet {
 	u32 info[8];
 };
 
-struct rkvdec_rps_entry {
-	u32 dpb_info0:          5;
-	u32 bottom_flag0:       1;
-	u32 view_index_off0:    1;
-	u32 dpb_info1:          5;
-	u32 bottom_flag1:       1;
-	u32 view_index_off1:    1;
-	u32 dpb_info2:          5;
-	u32 bottom_flag2:       1;
-	u32 view_index_off2:    1;
-	u32 dpb_info3:          5;
-	u32 bottom_flag3:       1;
-	u32 view_index_off3:    1;
-	u32 dpb_info4:          5;
-	u32 bottom_flag4:       1;
-	u32 view_index_off4:    1;
-	u32 dpb_info5:          5;
-	u32 bottom_flag5:       1;
-	u32 view_index_off5:    1;
-	u32 dpb_info6:          5;
-	u32 bottom_flag6:       1;
-	u32 view_index_off6:    1;
-	u32 dpb_info7:          5;
-	u32 bottom_flag7:       1;
-	u32 view_index_off7:    1;
-} __packed;
-
-struct rkvdec_rps {
-	u16 frame_num[16];
-	u32 reserved0;
-	struct rkvdec_rps_entry entries[12];
-	u32 reserved1[66];
-} __packed;
-
 struct rkvdec_ps_field {
 	u16 offset;
 	u8 len;
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c
new file mode 100644
index 0000000000000..e65a56bc9c63f
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip VDPU381 Video Decoder H264 backend
+ *
+ * Copyright (C) 2024 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+#include "rkvdec-rcb.h"
+#include "rkvdec-h264-common.h"
+#include "rkvdec-vdpu381-regs.h"
+
+struct rkvdec_sps {
+	u16 seq_parameter_set_id:			4;
+	u16 profile_idc:				8;
+	u16 constraint_set3_flag:			1;
+	u16 chroma_format_idc:				2;
+	u16 bit_depth_luma:				3;
+	u16 bit_depth_chroma:				3;
+	u16 qpprime_y_zero_transform_bypass_flag:	1;
+	u16 log2_max_frame_num_minus4:			4;
+	u16 max_num_ref_frames:				5;
+	u16 pic_order_cnt_type:				2;
+	u16 log2_max_pic_order_cnt_lsb_minus4:		4;
+	u16 delta_pic_order_always_zero_flag:		1;
+	u16 pic_width_in_mbs:				12;
+	u16 pic_height_in_mbs:				12;
+	u16 frame_mbs_only_flag:			1;
+	u16 mb_adaptive_frame_field_flag:		1;
+	u16 direct_8x8_inference_flag:			1;
+	u16 mvc_extension_enable:			1;
+	u16 num_views:					2;
+
+	u16 reserved_bits:				12;
+	u16 reserved[11];
+} __packed;
+
+struct rkvdec_pps {
+	u16 pic_parameter_set_id:				8;
+	u16 pps_seq_parameter_set_id:				5;
+	u16 entropy_coding_mode_flag:				1;
+	u16 bottom_field_pic_order_in_frame_present_flag:	1;
+	u16 num_ref_idx_l0_default_active_minus1:		5;
+	u16 num_ref_idx_l1_default_active_minus1:		5;
+	u16 weighted_pred_flag:					1;
+	u16 weighted_bipred_idc:				2;
+	u16 pic_init_qp_minus26:				7;
+	u16 pic_init_qs_minus26:				6;
+	u16 chroma_qp_index_offset:				5;
+	u16 deblocking_filter_control_present_flag:		1;
+	u16 constrained_intra_pred_flag:			1;
+	u16 redundant_pic_cnt_present:				1;
+	u16 transform_8x8_mode_flag:				1;
+	u16 second_chroma_qp_index_offset:			5;
+	u16 scaling_list_enable_flag:				1;
+	u32 scaling_list_address;
+	u16 is_longterm;
+
+	u8 reserved[3];
+} __packed;
+
+struct rkvdec_sps_pps {
+	struct rkvdec_sps sps;
+	struct rkvdec_pps pps;
+} __packed;
+
+/* Data structure describing auxiliary buffer format. */
+struct rkvdec_h264_priv_tbl {
+	s8 cabac_table[4][464][2];
+	struct rkvdec_h264_scaling_list scaling_list;
+	struct rkvdec_sps_pps param_set[256];
+	struct rkvdec_rps rps;
+};
+
+struct rkvdec_h264_ctx {
+	struct rkvdec_aux_buf priv_tbl;
+	struct rkvdec_h264_reflists reflists;
+	struct rkvdec_vdpu381_regs_h264 regs;
+};
+
+static void assemble_hw_pps(struct rkvdec_ctx *ctx,
+			    struct rkvdec_h264_run *run)
+{
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	const struct v4l2_ctrl_h264_sps *sps = run->sps;
+	const struct v4l2_ctrl_h264_pps *pps = run->pps;
+	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
+	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
+	struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
+	struct rkvdec_sps_pps *hw_ps;
+	dma_addr_t scaling_list_address;
+	u32 scaling_distance;
+	u32 i;
+
+	/*
+	 * HW read the SPS/PPS information from PPS packet index by PPS id.
+	 * offset from the base can be calculated by PPS_id * 32 (size per PPS
+	 * packet unit). so the driver copy SPS/PPS information to the exact PPS
+	 * packet unit for HW accessing.
+	 */
+	hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
+	memset(hw_ps, 0, sizeof(*hw_ps));
+
+	/* write sps */
+	hw_ps->sps.seq_parameter_set_id = sps->seq_parameter_set_id;
+	hw_ps->sps.profile_idc = sps->profile_idc;
+	hw_ps->sps.constraint_set3_flag = !!(sps->constraint_set_flags & (1 << 3));
+	hw_ps->sps.chroma_format_idc = sps->chroma_format_idc;
+	hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8;
+	hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8;
+	hw_ps->sps.qpprime_y_zero_transform_bypass_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	hw_ps->sps.log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4;
+	hw_ps->sps.max_num_ref_frames = sps->max_num_ref_frames;
+	hw_ps->sps.pic_order_cnt_type = sps->pic_order_cnt_type;
+	hw_ps->sps.log2_max_pic_order_cnt_lsb_minus4 =
+		sps->log2_max_pic_order_cnt_lsb_minus4;
+	hw_ps->sps.delta_pic_order_always_zero_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	hw_ps->sps.mvc_extension_enable = 1;
+	hw_ps->sps.num_views = 1;
+
+	/*
+	 * Use the SPS values since they are already in macroblocks
+	 * dimensions, height can be field height (halved) if
+	 * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is not set and also it allows
+	 * decoding smaller images into larger allocation which can be used
+	 * to implementing SVC spatial layer support.
+	 */
+	hw_ps->sps.pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1;
+	hw_ps->sps.pic_height_in_mbs = sps->pic_height_in_map_units_minus1 + 1;
+	hw_ps->sps.frame_mbs_only_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	hw_ps->sps.mb_adaptive_frame_field_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	hw_ps->sps.direct_8x8_inference_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+
+	/* write pps */
+	hw_ps->pps.pic_parameter_set_id = pps->pic_parameter_set_id;
+	hw_ps->pps.pps_seq_parameter_set_id = pps->seq_parameter_set_id;
+	hw_ps->pps.entropy_coding_mode_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	hw_ps->pps.bottom_field_pic_order_in_frame_present_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	hw_ps->pps.num_ref_idx_l0_default_active_minus1 =
+		pps->num_ref_idx_l0_default_active_minus1;
+	hw_ps->pps.num_ref_idx_l1_default_active_minus1 =
+		pps->num_ref_idx_l1_default_active_minus1;
+	hw_ps->pps.weighted_pred_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	hw_ps->pps.weighted_bipred_idc = pps->weighted_bipred_idc;
+	hw_ps->pps.pic_init_qp_minus26 = pps->pic_init_qp_minus26;
+	hw_ps->pps.pic_init_qs_minus26 = pps->pic_init_qs_minus26;
+	hw_ps->pps.chroma_qp_index_offset = pps->chroma_qp_index_offset;
+	hw_ps->pps.deblocking_filter_control_present_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	hw_ps->pps.constrained_intra_pred_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	hw_ps->pps.redundant_pic_cnt_present =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	hw_ps->pps.transform_8x8_mode_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	hw_ps->pps.second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset;
+	hw_ps->pps.scaling_list_enable_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+
+	/*
+	 * To be on the safe side, program the scaling matrix address
+	 */
+	scaling_distance = offsetof(struct rkvdec_h264_priv_tbl, scaling_list);
+	scaling_list_address = h264_ctx->priv_tbl.dma + scaling_distance;
+	hw_ps->pps.scaling_list_address = scaling_list_address;
+
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+			hw_ps->pps.is_longterm |= (1 << i);
+	}
+}
+
+static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_COMMON_REGS,
+			   &h264_ctx->regs.common,
+			   sizeof(h264_ctx->regs.common));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_CODEC_PARAMS_REGS,
+			   &h264_ctx->regs.h264_param,
+			   sizeof(h264_ctx->regs.h264_param));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_COMMON_ADDR_REGS,
+			   &h264_ctx->regs.common_addr,
+			   sizeof(h264_ctx->regs.common_addr));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_CODEC_ADDR_REGS,
+			   &h264_ctx->regs.h264_addr,
+			   sizeof(h264_ctx->regs.h264_addr));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_POC_HIGHBIT_REGS,
+			   &h264_ctx->regs.h264_highpoc,
+			   sizeof(h264_ctx->regs.h264_highpoc));
+}
+
+static void config_registers(struct rkvdec_ctx *ctx,
+			     struct rkvdec_h264_run *run)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
+	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma;
+	const struct v4l2_pix_format_mplane *dst_fmt;
+	struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
+	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
+	struct rkvdec_vdpu381_regs_h264 *regs = &h264_ctx->regs;
+	const struct v4l2_format *f;
+	dma_addr_t rlc_addr;
+	dma_addr_t dst_addr;
+	u32 hor_virstride;
+	u32 ver_virstride;
+	u32 y_virstride;
+	u32 offset;
+	u32 pixels;
+	u32 i;
+
+	memset(regs, 0, sizeof(*regs));
+
+	/* Set H264 mode */
+	regs->common.reg009.dec_mode = VDPU381_MODE_H264;
+
+	/* Set config */
+	regs->common.reg011.buf_empty_en = 1;
+	regs->common.reg011.dec_clkgate_e = 1;
+	regs->common.reg011.dec_timeout_e = 1;
+	regs->common.reg011.pix_range_detection_e = 1;
+
+	/*
+	 * Even though the scan list address can be set in RPS,
+	 * with some frames, it will try to use the address set in the register.
+	 */
+	regs->common.reg012.scanlist_addr_valid_en = 1;
+
+	/* Set IDR flag */
+	regs->common.reg013.cur_pic_is_idr =
+		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC);
+
+	/* Set input stream length */
+	regs->common.stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+
+	/* Set max slice number */
+	regs->common.reg017.slice_num = MAX_SLICE_NUMBER;
+
+	/* Set strides */
+	f = &ctx->decoded_fmt;
+	dst_fmt = &f->fmt.pix_mp;
+	hor_virstride = dst_fmt->plane_fmt[0].bytesperline;
+	ver_virstride = dst_fmt->height;
+	y_virstride = hor_virstride * ver_virstride;
+
+	pixels = dst_fmt->height * dst_fmt->width;
+
+	regs->common.reg018.y_hor_virstride = hor_virstride / 16;
+	regs->common.reg019.uv_hor_virstride = hor_virstride / 16;
+	regs->common.reg020.y_virstride = y_virstride / 16;
+
+	/* Activate block gating */
+	regs->common.reg026.swreg_block_gating_e = 0xfffef;
+	regs->common.reg026.reg_cfg_gating_en = 1;
+
+	/* Set timeout threshold */
+	if (pixels < RKVDEC_1080P_PIXELS)
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_1080p;
+	else if (pixels < RKVDEC_4K_PIXELS)
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_4K;
+	else if (pixels < RKVDEC_8K_PIXELS)
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_8K;
+	else
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_MAX;
+
+	/* Set TOP and BOTTOM POCs */
+	regs->h264_param.cur_top_poc = dec_params->top_field_order_cnt;
+	regs->h264_param.cur_bot_poc = dec_params->bottom_field_order_cnt;
+
+	/* Set ref pic address & poc */
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		struct vb2_buffer *vb_buf = run->ref_buf[i];
+		dma_addr_t buf_dma;
+
+		/*
+		 * If a DPB entry is unused or invalid, address of current destination
+		 * buffer is returned.
+		 */
+		if (!vb_buf)
+			vb_buf = &dst_buf->vb2_buf;
+
+		buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
+
+		/* Set reference addresses */
+		regs->h264_addr.ref_base[i] = buf_dma;
+
+		/* Set COLMV addresses */
+		regs->h264_addr.colmv_base[i] = buf_dma + ctx->colmv_offset;
+
+		struct rkvdec_vdpu381_h264_ref_info *ref_info =
+			&regs->h264_param.ref_info_regs[i / 4].ref_info[i % 4];
+
+		ref_info->ref_field =
+			!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD);
+		ref_info->ref_colmv_use_flag =
+			!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE);
+		ref_info->ref_topfield_used =
+			!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF);
+		ref_info->ref_botfield_used =
+			!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF);
+
+		regs->h264_param.ref_pocs[i * 2] =
+			dpb[i].top_field_order_cnt;
+		regs->h264_param.ref_pocs[i * 2 + 1] =
+			dpb[i].bottom_field_order_cnt;
+	}
+
+	/* Set rlc base address (input stream) */
+	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	regs->common_addr.rlc_base = rlc_addr;
+	regs->common_addr.rlcwrite_base = rlc_addr;
+
+	/* Set output base address */
+	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+	regs->common_addr.decout_base = dst_addr;
+	regs->common_addr.error_ref_base = dst_addr;
+
+	/* Set colmv address */
+	regs->common_addr.colmv_cur_base = dst_addr + ctx->colmv_offset;
+
+	/* Set RCB addresses */
+	for (i = 0; i < rkvdec_rcb_buf_count(ctx); i++)
+		regs->common_addr.rcb_base[i] = rkvdec_rcb_buf_dma_addr(ctx, i);
+
+	/* Set hw pps address */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, param_set);
+	regs->h264_addr.pps_base = priv_start_addr + offset;
+
+	/* Set hw rps address */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, rps);
+	regs->h264_addr.rps_base = priv_start_addr + offset;
+
+	/* Set cabac table */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table);
+	regs->h264_addr.cabactbl_base = priv_start_addr + offset;
+
+	offset = offsetof(struct rkvdec_h264_priv_tbl, scaling_list);
+	regs->h264_addr.scanlist_addr = priv_start_addr + offset;
+
+	rkvdec_write_regs(ctx);
+}
+
+static int rkvdec_h264_start(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_h264_priv_tbl *priv_tbl;
+	struct rkvdec_h264_ctx *h264_ctx;
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_H264_SPS);
+	if (!ctrl)
+		return -EINVAL;
+
+	ret = rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps);
+	if (ret)
+		return ret;
+
+	h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL);
+	if (!h264_ctx)
+		return -ENOMEM;
+
+	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+				      &h264_ctx->priv_tbl.dma, GFP_KERNEL);
+	if (!priv_tbl) {
+		ret = -ENOMEM;
+		goto err_free_ctx;
+	}
+
+	h264_ctx->priv_tbl.size = sizeof(*priv_tbl);
+	h264_ctx->priv_tbl.cpu = priv_tbl;
+	memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table,
+	       sizeof(rkvdec_h264_cabac_table));
+
+	ctx->priv = h264_ctx;
+	return 0;
+
+err_free_ctx:
+	kfree(h264_ctx);
+	return ret;
+}
+
+static void rkvdec_h264_stop(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+
+	dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size,
+			  h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma);
+	kfree(h264_ctx);
+}
+
+static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
+{
+	struct v4l2_h264_reflist_builder reflist_builder;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
+	struct rkvdec_h264_run run;
+	u32 watchdog_time;
+
+	rkvdec_h264_run_preamble(ctx, &run);
+
+	/* Build the P/B{0,1} ref lists. */
+	v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params,
+				       run.sps, run.decode_params->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
+				    h264_ctx->reflists.b1);
+
+	assemble_hw_scaling_list(&run, &tbl->scaling_list);
+	assemble_hw_pps(ctx, &run);
+	lookup_ref_buf_idx(ctx, &run);
+	assemble_hw_rps(&reflist_builder, &run, &h264_ctx->reflists, &tbl->rps);
+
+	config_registers(ctx, &run);
+
+	rkvdec_run_postamble(ctx, &run.base);
+
+	/* Set watchdog at 2 times the hardware timeout threshold */
+	u64 timeout_threshold = h264_ctx->regs.common.timeout_threshold;
+	unsigned long axi_rate = clk_get_rate(rkvdec->axi_clk);
+
+	if (axi_rate)
+		watchdog_time = 2 * (1000 * timeout_threshold) / axi_rate;
+	else
+		watchdog_time = 2000;
+	schedule_delayed_work(&rkvdec->watchdog_work,
+			      msecs_to_jiffies(watchdog_time));
+
+	/* Start decoding! */
+	writel(VDPU381_DEC_E_BIT, rkvdec->regs + VDPU381_REG_DEC_E);
+
+	return 0;
+}
+
+static int rkvdec_h264_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl)
+{
+	if (ctrl->id == V4L2_CID_STATELESS_H264_SPS)
+		return rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps);
+
+	return 0;
+}
+
+const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_h264_fmt_ops = {
+	.adjust_fmt = rkvdec_h264_adjust_fmt,
+	.get_image_fmt = rkvdec_h264_get_image_fmt,
+	.start = rkvdec_h264_start,
+	.stop = rkvdec_h264_stop,
+	.run = rkvdec_h264_run,
+	.try_ctrl = rkvdec_h264_try_ctrl,
+};
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h
new file mode 100644
index 0000000000000..11b545e9ee7ea
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-regs.h
@@ -0,0 +1,427 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip VDPU381 Video Decoder driver registers description
+ *
+ * Copyright (C) 2024 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <linux/types.h>
+
+#ifndef _RKVDEC_REGS_H_
+#define _RKVDEC_REGS_H_
+
+#define OFFSET_COMMON_REGS		(8 * sizeof(u32))
+#define OFFSET_CODEC_PARAMS_REGS	(64 * sizeof(u32))
+#define OFFSET_COMMON_ADDR_REGS		(128 * sizeof(u32))
+#define OFFSET_CODEC_ADDR_REGS		(160 * sizeof(u32))
+#define OFFSET_POC_HIGHBIT_REGS		(200 * sizeof(u32))
+
+#define VDPU381_MODE_HEVC	0
+#define VDPU381_MODE_H264	1
+#define VDPU381_MODE_VP9	2
+#define VDPU381_MODE_AVS2	3
+
+#define MAX_SLICE_NUMBER	0x3fff
+
+#define RKVDEC_1080P_PIXELS		(1920 * 1080)
+#define RKVDEC_4K_PIXELS		(4096 * 2304)
+#define RKVDEC_8K_PIXELS		(7680 * 4320)
+#define RKVDEC_TIMEOUT_1080p		(0xefffff)
+#define RKVDEC_TIMEOUT_4K		(0x2cfffff)
+#define RKVDEC_TIMEOUT_8K		(0x4ffffff)
+#define RKVDEC_TIMEOUT_MAX		(0xffffffff)
+
+#define VDPU381_REG_DEC_E		0x028
+#define VDPU381_DEC_E_BIT		1
+
+#define VDPU381_REG_IMPORTANT_EN	0x02c
+#define VDPU381_DEC_IRQ_DISABLE	BIT(4)
+
+#define VDPU381_REG_STA_INT		0x380
+#define VDPU381_STA_INT_DEC_RDY_STA	BIT(2)
+#define VDPU381_STA_INT_ERROR		BIT(4)
+#define VDPU381_STA_INT_TIMEOUT		BIT(5)
+#define VDPU381_STA_INT_SOFTRESET_RDY	BIT(9)
+
+/* base: OFFSET_COMMON_REGS */
+struct rkvdec_vdpu381_regs_common {
+	struct rkvdec_vdpu381_in_out {
+		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 out_swap64_e	: 1;
+		u32 reserved		: 22;
+	} reg008;
+
+	struct rkvdec_vdpu381_dec_mode {
+		u32 dec_mode	: 10;
+		u32 reserved	: 22;
+	} reg009;
+
+	struct rkvdec_vdpu381_dec_e {
+		u32 dec_e	: 1;
+		u32 reserved	: 31;
+	} reg010;
+
+	struct rkvdec_vdpu381_important_en {
+		u32 reserved			: 1;
+		u32 dec_clkgate_e		: 1;
+		u32 dec_e_strmd_clkgate_dis	: 1;
+		u32 reserved0			: 1;
+
+		u32 dec_irq_dis			: 1;
+		u32 dec_timeout_e		: 1;
+		u32 buf_empty_en		: 1;
+		u32 reserved1			: 3;
+
+		u32 dec_e_rewrite_valid		: 1;
+		u32 reserved2			: 9;
+		u32 softrst_en_p		: 1;
+		u32 force_softreset_valid	: 1;
+		u32 reserved3			: 2;
+		u32 pix_range_detection_e	: 1;
+		u32 reserved4			: 7;
+	} reg011;
+
+	struct rkvdec_vdpu381_sencodary_en {
+		u32 wr_ddr_align_en		: 1;
+		u32 colmv_compress_en		: 1;
+		u32 fbc_e			: 1;
+		u32 reserved0			: 1;
+
+		u32 buspr_slot_disable		: 1;
+		u32 error_info_en		: 1;
+		u32 info_collect_en		: 1;
+		u32 wait_reset_en		: 1;
+
+		u32 scanlist_addr_valid_en	: 1;
+		u32 scale_down_en		: 1;
+		u32 error_cfg_wr_disable	: 1;
+		u32 reserved1			: 21;
+	} reg012;
+
+	struct rkvdec_vdpu381_en_mode_set {
+		u32 timeout_mode		: 1;
+		u32 req_timeout_rst_sel		: 1;
+		u32 reserved0			: 1;
+		u32 dec_commonirq_mode		: 1;
+		u32 reserved1			: 2;
+		u32 stmerror_waitdecfifo_empty	: 1;
+		u32 reserved2			: 2;
+		u32 h26x_streamd_error_mode	: 1;
+		u32 reserved3			: 2;
+		u32 allow_not_wr_unref_bframe	: 1;
+		u32 fbc_output_wr_disable	: 1;
+		u32 reserved4			: 1;
+		u32 colmv_error_mode		: 1;
+
+		u32 reserved5			: 2;
+		u32 h26x_error_mode		: 1;
+		u32 reserved6			: 2;
+		u32 ycacherd_prior		: 1;
+		u32 reserved7			: 2;
+		u32 cur_pic_is_idr		: 1;
+		u32 reserved8			: 1;
+		u32 right_auto_rst_disable	: 1;
+		u32 frame_end_err_rst_flag	: 1;
+		u32 rd_prior_mode		: 1;
+		u32 rd_ctrl_prior_mode		: 1;
+		u32 reserved9			: 1;
+		u32 filter_outbuf_mode		: 1;
+	} reg013;
+
+	struct rkvdec_vdpu381_fbc_param_set {
+		u32 fbc_force_uncompress	: 1;
+
+		u32 reserved0			: 2;
+		u32 allow_16x8_cp_flag		: 1;
+		u32 reserved1			: 2;
+
+		u32 fbc_h264_exten_4or8_flag	: 1;
+		u32 reserved2			: 25;
+	} reg014;
+
+	struct rkvdec_vdpu381_stream_param_set {
+		u32 rlc_mode_direct_write	: 1;
+		u32 rlc_mode			: 1;
+		u32 reserved0			: 3;
+
+		u32 strm_start_bit		: 7;
+		u32 reserved1			: 20;
+	} reg015;
+
+	u32 stream_len;
+
+	struct rkvdec_vdpu381_slice_number {
+		u32 slice_num	: 25;
+		u32 reserved	: 7;
+	} reg017;
+
+	struct rkvdec_vdpu381_y_hor_stride {
+		u32 y_hor_virstride	: 16;
+		u32 reserved		: 16;
+	} reg018;
+
+	struct rkvdec_vdpu381_uv_hor_stride {
+		u32 uv_hor_virstride	: 16;
+		u32 reserved		: 16;
+	} reg019;
+
+	struct rkvdec_vdpu381_y_stride {
+		u32 y_virstride		: 28;
+		u32 reserved		: 4;
+	} reg020;
+
+	struct rkvdec_vdpu381_error_ctrl_set {
+		u32 inter_error_prc_mode		: 1;
+		u32 error_intra_mode			: 1;
+		u32 error_deb_en			: 1;
+		u32 picidx_replace			: 5;
+		u32 error_spread_e			: 1;
+		u32 reserved0				: 3;
+		u32 error_inter_pred_cross_slice	: 1;
+		u32 reserved1				: 11;
+		u32 roi_error_ctu_cal_en		: 1;
+		u32 reserved2				: 7;
+	} reg021;
+
+	struct rkvdec_vdpu381_err_roi_ctu_offset_start {
+		u32 roi_x_ctu_offset_st	: 12;
+		u32 reserved0		: 4;
+		u32 roi_y_ctu_offset_st	: 12;
+		u32 reserved1		: 4;
+	} reg022;
+
+	struct rkvdec_vdpu381_err_roi_ctu_offset_end {
+		u32 roi_x_ctu_offset_end	: 12;
+		u32 reserved0			: 4;
+		u32 roi_y_ctu_offset_end	: 12;
+		u32 reserved1			: 4;
+	} reg023;
+
+	struct rkvdec_vdpu381_cabac_error_en_lowbits {
+		u32 cabac_err_en_lowbits	: 32;
+	} reg024;
+
+	struct rkvdec_vdpu381_cabac_error_en_highbits {
+		u32 cabac_err_en_highbits	: 30;
+		u32 reserved			: 2;
+	} reg025;
+
+	struct rkvdec_vdpu381_block_gating_en {
+		u32 swreg_block_gating_e	: 20;
+		u32 reserved			: 11;
+		u32 reg_cfg_gating_en		: 1;
+	} reg026;
+
+	struct SW027_CORE_SAFE_PIXELS {
+		u32 core_safe_x_pixels	: 16;
+		u32 core_safe_y_pixels	: 16;
+	} reg027;
+
+	struct rkvdec_vdpu381_multiply_core_ctrl {
+		u32 swreg_vp9_wr_prob_idx	: 3;
+		u32 reserved0			: 1;
+		u32 swreg_vp9_rd_prob_idx	: 3;
+		u32 reserved1			: 1;
+
+		u32 swreg_ref_req_advance_flag	: 1;
+		u32 sw_colmv_req_advance_flag	: 1;
+		u32 sw_poc_only_highbit_flag	: 1;
+		u32 sw_poc_arb_flag		: 1;
+
+		u32 reserved2			: 4;
+		u32 sw_film_idx			: 10;
+		u32 reserved3			: 2;
+		u32 sw_pu_req_mismatch_dis	: 1;
+		u32 sw_colmv_req_mismatch_dis	: 1;
+		u32 reserved4			: 2;
+	} reg028;
+
+	struct SW029_SCALE_DOWN_CTRL {
+		u32 scale_down_hor_ratio	: 2;
+		u32 reserved0			: 6;
+		u32 scale_down_vrz_ratio	: 2;
+		u32 reserved1			: 22;
+	} reg029;
+
+	struct SW032_Y_SCALE_DOWN_TILE8x8_HOR_STRIDE {
+		u32 y_scale_down_hor_stride	: 20;
+		u32 reserved0			: 12;
+	} reg030;
+
+	struct SW031_UV_SCALE_DOWN_TILE8x8_HOR_STRIDE {
+		u32 uv_scale_down_hor_stride	: 20;
+		u32 reserved0			: 12;
+	} reg031;
+
+	u32 timeout_threshold;
+} __packed;
+
+/* base: OFFSET_COMMON_ADDR_REGS */
+struct rkvdec_vdpu381_regs_common_addr {
+	u32 rlc_base;
+	u32 rlcwrite_base;
+	u32 decout_base;
+	u32 colmv_cur_base;
+	u32 error_ref_base;
+	u32 rcb_base[10];
+} __packed;
+
+struct rkvdec_vdpu381_h26x_set {
+	u32 h26x_frame_orslice		: 1;
+	u32 h26x_rps_mode		: 1;
+	u32 h26x_stream_mode		: 1;
+	u32 h26x_stream_lastpacket	: 1;
+	u32 h264_firstslice_flag	: 1;
+	u32 reserved			: 27;
+} __packed;
+
+/* base: OFFSET_CODEC_PARAMS_REGS */
+struct rkvdec_vdpu381_regs_h264_params {
+	struct rkvdec_vdpu381_h26x_set reg064;
+
+	u32 cur_top_poc;
+	u32 cur_bot_poc;
+	u32 ref_pocs[32];
+
+	struct rkvdec_vdpu381_h264_info {
+		struct rkvdec_vdpu381_h264_ref_info {
+			u32 ref_field		: 1;
+			u32 ref_topfield_used	: 1;
+			u32 ref_botfield_used	: 1;
+			u32 ref_colmv_use_flag	: 1;
+			u32 ref_reserved	: 4;
+		} __packed ref_info[4];
+	} __packed ref_info_regs[4];
+
+	u32 reserved_103_111[9];
+
+	struct rkvdec_vdpu381_error_ref_info {
+		u32 avs2_ref_error_field	: 1;
+		u32 avs2_ref_error_topfield	: 1;
+		u32 ref_error_topfield_used	: 1;
+		u32 ref_error_botfield_used	: 1;
+		u32 reserved			: 28;
+	} reg112;
+} __packed;
+
+struct rkvdec_vdpu381_regs_hevc_params {
+	struct rkvdec_vdpu381_h26x_set reg064;
+
+	u32 cur_top_poc;
+	u32 cur_bot_poc;
+
+	u32 reg067_082_ref_poc[16];
+
+	u32 reserved_083_098[16];
+
+	struct rkvdec_vdpu381_hevc_ref_valid {
+		u32 hevc_ref_valid_0    : 1;
+		u32 hevc_ref_valid_1    : 1;
+		u32 hevc_ref_valid_2    : 1;
+		u32 hevc_ref_valid_3    : 1;
+		u32 reserve0            : 4;
+		u32 hevc_ref_valid_4    : 1;
+		u32 hevc_ref_valid_5    : 1;
+		u32 hevc_ref_valid_6    : 1;
+		u32 hevc_ref_valid_7    : 1;
+		u32 reserve1            : 4;
+		u32 hevc_ref_valid_8    : 1;
+		u32 hevc_ref_valid_9    : 1;
+		u32 hevc_ref_valid_10   : 1;
+		u32 hevc_ref_valid_11   : 1;
+		u32 reserve2            : 4;
+		u32 hevc_ref_valid_12   : 1;
+		u32 hevc_ref_valid_13   : 1;
+		u32 hevc_ref_valid_14   : 1;
+		u32 reserve3            : 5;
+	} reg099;
+
+	u32 reserved_100_102[3];
+
+	struct rkvdec_vdpu381_hevc_mvc0 {
+		u32 ref_pic_layer_same_with_cur : 16;
+		u32 reserve                     : 16;
+	} reg103;
+
+	struct rkvdec_vdpu381_hevc_mvc1 {
+		u32 poc_lsb_not_present_flag        : 1;
+		u32 num_direct_ref_layers           : 6;
+		u32 reserve0                        : 1;
+
+		u32 num_reflayer_pics               : 6;
+		u32 default_ref_layers_active_flag  : 1;
+		u32 max_one_active_ref_layer_flag   : 1;
+
+		u32 poc_reset_info_present_flag     : 1;
+		u32 vps_poc_lsb_aligned_flag        : 1;
+		u32 mvc_poc15_valid_flag            : 1;
+		u32 reserve1                        : 13;
+	} reg104;
+
+	u32 reserved_105_111[7];
+
+	struct rkvdec_vdpu381_hevc_ref_info {
+		u32 avs2_ref_error_field        : 1;
+		u32 avs2_ref_error_topfield     : 1;
+		u32 ref_error_topfield_used     : 1;
+		u32 ref_error_botfield_used     : 1;
+		u32 reserve                     : 28;
+	} reg112;
+
+} __packed;
+
+/* base: OFFSET_CODEC_ADDR_REGS */
+struct rkvdec_vdpu381_regs_h26x_addr {
+	u32 reserved_160;
+	u32 pps_base;
+	u32 reserved_162;
+	u32 rps_base;
+	u32 ref_base[16];
+	u32 scanlist_addr;
+	u32 colmv_base[16];
+	u32 cabactbl_base;
+} __packed;
+
+struct rkvdec_vdpu381_regs_h26x_highpoc {
+	struct rkvdec_vdpu381_ref_poc_highbit {
+		u32 ref0_poc_highbit	: 4;
+		u32 ref1_poc_highbit	: 4;
+		u32 ref2_poc_highbit	: 4;
+		u32 ref3_poc_highbit	: 4;
+		u32 ref4_poc_highbit	: 4;
+		u32 ref5_poc_highbit	: 4;
+		u32 ref6_poc_highbit	: 4;
+		u32 ref7_poc_highbit	: 4;
+	} reg200[4];
+	struct rkvdec_vdpu381_cur_poc_highbit {
+		u32 cur_poc_highbit	: 4;
+		u32 reserved		: 28;
+	} reg204;
+} __packed;
+
+struct rkvdec_vdpu381_regs_h264 {
+	struct rkvdec_vdpu381_regs_common		common;
+	struct rkvdec_vdpu381_regs_h264_params		h264_param;
+	struct rkvdec_vdpu381_regs_common_addr		common_addr;
+	struct rkvdec_vdpu381_regs_h26x_addr		h264_addr;
+	struct rkvdec_vdpu381_regs_h26x_highpoc		h264_highpoc;
+} __packed;
+
+struct rkvdec_vdpu381_regs_hevc {
+	struct rkvdec_vdpu381_regs_common		common;
+	struct rkvdec_vdpu381_regs_hevc_params		hevc_param;
+	struct rkvdec_vdpu381_regs_common_addr		common_addr;
+	struct rkvdec_vdpu381_regs_h26x_addr		hevc_addr;
+	struct rkvdec_vdpu381_regs_h26x_highpoc		hevc_highpoc;
+} __packed;
+
+#endif /* __RKVDEC_REGS_H__ */
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 0ccf1ba81958a..1b55fe4ff2baf 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -28,6 +28,7 @@
 
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
+#include "rkvdec-vdpu381-regs.h"
 #include "rkvdec-rcb.h"
 
 static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,
@@ -84,11 +85,50 @@ static bool rkvdec_is_valid_fmt(struct rkvdec_ctx *ctx, u32 fourcc,
 	return false;
 }
 
+#define VDPU38X_STRIDE_ALIGN	16
+
+/**
+ * The default v4l2_fill_pixfmt_mp() function doesn't allow for specific alignment values.
+ * As the VDPU381 and VDPU383 need lines to be aligned on 16, use our own implementation here.
+ */
+static int vdpu38x_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pix_mp, u32 pixelformat,
+				  u32 width, u32 height)
+{
+	const struct v4l2_format_info *info = v4l2_format_info(pix_mp->pixelformat);
+	struct v4l2_plane_pix_format *plane = &pix_mp->plane_fmt[0];
+
+	if (!info)
+		return -EINVAL;
+
+	pix_mp->num_planes = 1;
+
+	memset(plane, 0, sizeof(*plane));
+
+	plane->bytesperline = pix_mp->width * info->bpp[0] / info->bpp_div[0];
+	plane->bytesperline = ALIGN(plane->bytesperline, VDPU38X_STRIDE_ALIGN);
+
+	for (int i = 0; i < info->comp_planes; i++) {
+		unsigned int vdiv = i ? info->vdiv : 1;
+		unsigned int hdiv = i ? info->hdiv : 1;
+		unsigned int stride = DIV_ROUND_UP(pix_mp->width, hdiv)
+				    * info->bpp[i] / info->bpp_div[i];
+		unsigned int height = DIV_ROUND_UP(pix_mp->height, vdiv);
+
+		plane->sizeimage += ALIGN(stride, VDPU38X_STRIDE_ALIGN) * height;
+	}
+
+	return 0;
+}
+
 static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx,
 				       struct v4l2_pix_format_mplane *pix_mp)
 {
-	v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat,
-			    pix_mp->width, pix_mp->height);
+	struct rkvdec_config *cfg = ctx->dev->config;
+
+	cfg->fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, pix_mp->width, pix_mp->height);
+
+	ctx->colmv_offset = pix_mp->plane_fmt[0].sizeimage;
+
 	pix_mp->plane_fmt[0].sizeimage += 128 *
 		DIV_ROUND_UP(pix_mp->width, 16) *
 		DIV_ROUND_UP(pix_mp->height, 16);
@@ -287,6 +327,25 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
 	}
 };
 
+static const struct rkvdec_coded_fmt_desc vdpu381_coded_fmts[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_H264_SLICE,
+		.frmsize = {
+			.min_width = 64,
+			.max_width =  65520,
+			.step_width = 64,
+			.min_height = 16,
+			.max_height =  65520,
+			.step_height = 16,
+		},
+		.ctrls = &rkvdec_h264_ctrls,
+		.ops = &rkvdec_vdpu381_h264_fmt_ops,
+		.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
+		.decoded_fmts = rkvdec_h264_decoded_fmts,
+		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
+	},
+};
+
 static const struct rkvdec_coded_fmt_desc *
 rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
 {
@@ -1125,6 +1184,35 @@ static irqreturn_t rk3399_irq_handler(struct rkvdec_ctx *ctx)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t vdpu381_irq_handler(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	enum vb2_buffer_state state;
+	bool need_reset = 0;
+	u32 status;
+
+	status = readl(rkvdec->regs + VDPU381_REG_STA_INT);
+	writel(0, rkvdec->regs + VDPU381_REG_STA_INT);
+
+	if (status & VDPU381_STA_INT_DEC_RDY_STA) {
+		state = VB2_BUF_STATE_DONE;
+	} else {
+		state = VB2_BUF_STATE_ERROR;
+		if (status & (VDPU381_STA_INT_SOFTRESET_RDY |
+			      VDPU381_STA_INT_TIMEOUT |
+			      VDPU381_STA_INT_ERROR))
+			rkvdec_iommu_restore(rkvdec);
+	}
+
+	if (need_reset)
+		rkvdec_iommu_restore(rkvdec);
+
+	if (cancel_delayed_work(&rkvdec->watchdog_work))
+		rkvdec_job_finish(ctx, state);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
 {
 	struct rkvdec_dev *rkvdec = priv;
@@ -1149,14 +1237,81 @@ static void rkvdec_watchdog_func(struct work_struct *work)
 	}
 }
 
+/*
+ * Some SoCs, like RK3588 have multiple identical VDPU cores, but the
+ * kernel is currently missing support for multi-core handling. Exposing
+ * separate devices for each core to userspace is bad, since that does
+ * not allow scheduling tasks properly (and creates ABI). With this workaround
+ * the driver will only probe for the first core and early exit for the other
+ * cores. Once the driver gains multi-core support, the same technique
+ * for detecting the first core can be used to cluster all cores together.
+ */
+static int rkvdec_disable_multicore(struct rkvdec_dev *rkvdec)
+{
+	struct device_node *node = NULL;
+	const char *compatible;
+	bool is_first_core;
+	int ret;
+
+	/* Intentionally ignores the fallback strings */
+	ret = of_property_read_string(rkvdec->dev->of_node, "compatible", &compatible);
+	if (ret)
+		return ret;
+
+	/* The first compatible and available node found is considered the main core */
+	do {
+		node = of_find_compatible_node(node, NULL, compatible);
+		if (of_device_is_available(node))
+			break;
+	} while (node);
+
+	if (!node)
+		return -EINVAL;
+
+	is_first_core = (rkvdec->dev->of_node == node);
+
+	of_node_put(node);
+
+	if (!is_first_core) {
+		dev_info(rkvdec->dev, "missing multi-core support, ignoring this instance\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 const struct rkvdec_config config_rkvdec = {
 	.coded_fmts = (struct rkvdec_coded_fmt_desc *)rkvdec_coded_fmts,
 	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
 	.irq_handler = rk3399_irq_handler,
+	.fill_pixfmt_mp = v4l2_fill_pixfmt_mp,
+};
+
+static struct rcb_size_info vdpu381_rcb_sizes[] = {
+	{6,	PIC_WIDTH},	// intrar
+	{1,	PIC_WIDTH},	// transdr (Is actually 0.4*pic_width)
+	{1,	PIC_HEIGHT},	// transdc (Is actually 0.1*pic_height)
+	{3,	PIC_WIDTH},	// streamdr
+	{6,	PIC_WIDTH},	// interr
+	{3,	PIC_HEIGHT},	// interc
+	{22,	PIC_WIDTH},	// dblkr
+	{6,	PIC_WIDTH},	// saor
+	{11,	PIC_WIDTH},	// fbcr
+	{67,	PIC_HEIGHT},	// filtc col
+};
+
+const struct rkvdec_config config_vdpu381 = {
+	.coded_fmts = (struct rkvdec_coded_fmt_desc *)vdpu381_coded_fmts,
+	.coded_fmts_num = ARRAY_SIZE(vdpu381_coded_fmts),
+	.rcb_size_info = vdpu381_rcb_sizes,
+	.rcb_num = ARRAY_SIZE(vdpu381_rcb_sizes),
+	.irq_handler = vdpu381_irq_handler,
+	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
 };
 
 static const struct of_device_id of_rkvdec_match[] = {
 	{ .compatible = "rockchip,rk3399-vdec", .data = &config_rkvdec },
+	{ .compatible = "rockchip,rk3588-vdec", .data = &config_vdpu381 },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_rkvdec_match);
@@ -1175,6 +1330,10 @@ static int rkvdec_probe(struct platform_device *pdev)
 	mutex_init(&rkvdec->vdev_lock);
 	INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);
 
+	ret = rkvdec_disable_multicore(rkvdec);
+	if (ret)
+		return ret;
+
 	rkvdec->config =
 		(struct rkvdec_config *)of_device_get_match_data(rkvdec->dev);
 
@@ -1183,6 +1342,7 @@ static int rkvdec_probe(struct platform_device *pdev)
 		return ret;
 
 	rkvdec->clk_count = ret;
+	rkvdec->axi_clk = devm_clk_get(&pdev->dev, "axi");
 
 	rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(rkvdec->regs))
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index af47f16cb417d..9e0fef2445abc 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -108,6 +108,8 @@ struct rkvdec_config {
 	struct rcb_size_info *rcb_size_info;
 	size_t rcb_num;
 	irqreturn_t (*irq_handler)(struct rkvdec_ctx *ctx);
+	int (*fill_pixfmt_mp)(struct v4l2_pix_format_mplane *pix_mp, u32 pixelformat,
+			      u32 width, u32 height);
 };
 
 struct rkvdec_dev {
@@ -118,6 +120,7 @@ struct rkvdec_dev {
 	struct device *dev;
 	struct clk_bulk_data *clocks;
 	unsigned int clk_count;
+	struct clk *axi_clk;
 	void __iomem *regs;
 	struct mutex vdev_lock; /* serializes ioctls */
 	struct delayed_work watchdog_work;
@@ -136,6 +139,7 @@ struct rkvdec_ctx {
 	struct rkvdec_dev *dev;
 	enum rkvdec_image_fmt image_fmt;
 	struct rkvdec_rcb_config *rcb_config;
+	u32 colmv_offset;
 	void *priv;
 };
 
@@ -163,4 +167,6 @@ void rkvdec_memcpy_toio(void __iomem *dst, void *src, size_t len);
 extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
 extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
 
+extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_h264_fmt_ops;
+
 #endif /* RKVDEC_H_ */
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (8 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 09/12] media: rkvdec: Add H264 support for the VDPU381 variant Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-09 11:53   ` kernel test robot
  2025-08-11 18:28   ` Nicolas Dufresne
  2025-08-08 20:03 ` [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant Detlev Casanova
                   ` (3 subsequent siblings)
  13 siblings, 2 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

This variant is used on the RK3576 SoC.

The moving vectors size requirements are slightly different so support
for a colmv_size function per variant is added.

Also, the link registers are used to start the decoder and read IRQ status.
Per variant support for named register sections is added.

The fluster score is 128/135 for JVT-AVC_V1.
The other test suites are not supported yet.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Makefile   |   1 +
 .../rockchip/rkvdec/rkvdec-vdpu383-h264.c     | 582 ++++++++++++++++++
 .../rockchip/rkvdec/rkvdec-vdpu383-regs.h     | 284 +++++++++
 .../media/platform/rockchip/rkvdec/rkvdec.c   | 109 +++-
 .../media/platform/rockchip/rkvdec/rkvdec.h   |   8 +
 5 files changed, 978 insertions(+), 6 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index 20128bb6e35dc..c38ce1e8d3601 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -7,4 +7,5 @@ rockchip-vdec-y += \
 		   rkvdec-h264-common.o \
 		   rkvdec-rcb.o \
 		   rkvdec-vdpu381-h264.o \
+		   rkvdec-vdpu383-h264.o \
 		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
new file mode 100644
index 0000000000000..bb2c62d9c3d47
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
@@ -0,0 +1,582 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Video Decoder VDPU383 H264 backend
+ *
+ * Copyright (C) 2024 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include <linux/iopoll.h>
+
+#include "rkvdec-rcb.h"
+#include "rkvdec-vdpu383-regs.h"
+#include "rkvdec-h264-common.h"
+
+struct rkvdec_sps {
+	u16 seq_parameter_set_id:			4;
+	u16 profile_idc:				8;
+	u16 constraint_set3_flag:			1;
+	u16 chroma_format_idc:				2;
+	u16 bit_depth_luma:				3;
+	u16 bit_depth_chroma:				3;
+	u16 qpprime_y_zero_transform_bypass_flag:	1;
+	u16 log2_max_frame_num_minus4:			4;
+	u16 max_num_ref_frames:				5;
+	u16 pic_order_cnt_type:				2;
+	u16 log2_max_pic_order_cnt_lsb_minus4:		4;
+	u16 delta_pic_order_always_zero_flag:		1;
+
+	u16 pic_width_in_mbs:				16;
+	u16 pic_height_in_mbs:				16;
+
+	u16 frame_mbs_only_flag:			1;
+	u16 mb_adaptive_frame_field_flag:		1;
+	u16 direct_8x8_inference_flag:			1;
+	u16 mvc_extension_enable:			1;
+	u16 num_views:					2;
+	u16 view_id0:                                   10;
+	u16 view_id1:                                   10;
+} __packed;
+
+struct rkvdec_pps {
+	u32 pic_parameter_set_id:				8;
+	u32 pps_seq_parameter_set_id:				5;
+	u32 entropy_coding_mode_flag:				1;
+	u32 bottom_field_pic_order_in_frame_present_flag:	1;
+	u32 num_ref_idx_l0_default_active_minus1:		5;
+	u32 num_ref_idx_l1_default_active_minus1:		5;
+	u32 weighted_pred_flag:					1;
+	u32 weighted_bipred_idc:				2;
+	u32 pic_init_qp_minus26:				7;
+	u32 pic_init_qs_minus26:				6;
+	u32 chroma_qp_index_offset:				5;
+	u32 deblocking_filter_control_present_flag:		1;
+	u32 constrained_intra_pred_flag:			1;
+	u32 redundant_pic_cnt_present:				1;
+	u32 transform_8x8_mode_flag:				1;
+	u32 second_chroma_qp_index_offset:			5;
+	u32 scaling_list_enable_flag:				1;
+	u32 is_longterm:					16;
+	u32 voidx:						16;
+
+	// dpb
+	u32 pic_field_flag:                                     1;
+	u32 pic_associated_flag:                                1;
+	u32 cur_top_field:					32;
+	u32 cur_bot_field:					32;
+
+	u32 top_field_order_cnt0:				32;
+	u32 bot_field_order_cnt0:				32;
+	u32 top_field_order_cnt1:				32;
+	u32 bot_field_order_cnt1:				32;
+	u32 top_field_order_cnt2:				32;
+	u32 bot_field_order_cnt2:				32;
+	u32 top_field_order_cnt3:				32;
+	u32 bot_field_order_cnt3:				32;
+	u32 top_field_order_cnt4:				32;
+	u32 bot_field_order_cnt4:				32;
+	u32 top_field_order_cnt5:				32;
+	u32 bot_field_order_cnt5:				32;
+	u32 top_field_order_cnt6:				32;
+	u32 bot_field_order_cnt6:				32;
+	u32 top_field_order_cnt7:				32;
+	u32 bot_field_order_cnt7:				32;
+	u32 top_field_order_cnt8:				32;
+	u32 bot_field_order_cnt8:				32;
+	u32 top_field_order_cnt9:				32;
+	u32 bot_field_order_cnt9:				32;
+	u32 top_field_order_cnt10:				32;
+	u32 bot_field_order_cnt10:				32;
+	u32 top_field_order_cnt11:				32;
+	u32 bot_field_order_cnt11:				32;
+	u32 top_field_order_cnt12:				32;
+	u32 bot_field_order_cnt12:				32;
+	u32 top_field_order_cnt13:				32;
+	u32 bot_field_order_cnt13:				32;
+	u32 top_field_order_cnt14:				32;
+	u32 bot_field_order_cnt14:				32;
+	u32 top_field_order_cnt15:				32;
+	u32 bot_field_order_cnt15:				32;
+
+	u32 ref_field_flags:					16;
+	u32 ref_topfield_used:					16;
+	u32 ref_botfield_used:					16;
+	u32 ref_colmv_use_flag:					16;
+
+	u32 reserved0:						30;
+	u32 reserved[3];
+} __packed;
+
+struct rkvdec_sps_pps {
+	struct rkvdec_sps sps;
+	struct rkvdec_pps pps;
+} __packed;
+
+/* Data structure describing auxiliary buffer format. */
+struct rkvdec_h264_priv_tbl {
+	s8 cabac_table[4][464][2];
+	struct rkvdec_h264_scaling_list scaling_list;
+	struct rkvdec_sps_pps param_set[256];
+	struct rkvdec_rps rps;
+} __packed;
+
+struct rkvdec_h264_ctx {
+	struct rkvdec_aux_buf priv_tbl;
+	struct rkvdec_h264_reflists reflists;
+	struct vdpu383_regs_h26x regs;
+};
+
+static void set_field_order_cnt(struct rkvdec_sps_pps *hw_ps, int id, u32 top, u32 bottom)
+{
+	switch (id) {
+	case 0:
+		hw_ps->pps.top_field_order_cnt0 = top;
+		hw_ps->pps.bot_field_order_cnt0 = bottom;
+		break;
+	case 1:
+		hw_ps->pps.top_field_order_cnt1 = top;
+		hw_ps->pps.bot_field_order_cnt1 = bottom;
+		break;
+	case 2:
+		hw_ps->pps.top_field_order_cnt2 = top;
+		hw_ps->pps.bot_field_order_cnt2 = bottom;
+		break;
+	case 3:
+		hw_ps->pps.top_field_order_cnt3 = top;
+		hw_ps->pps.bot_field_order_cnt3 = bottom;
+		break;
+	case 4:
+		hw_ps->pps.top_field_order_cnt4 = top;
+		hw_ps->pps.bot_field_order_cnt4 = bottom;
+		break;
+	case 5:
+		hw_ps->pps.top_field_order_cnt5 = top;
+		hw_ps->pps.bot_field_order_cnt5 = bottom;
+		break;
+	case 6:
+		hw_ps->pps.top_field_order_cnt6 = top;
+		hw_ps->pps.bot_field_order_cnt6 = bottom;
+		break;
+	case 7:
+		hw_ps->pps.top_field_order_cnt7 = top;
+		hw_ps->pps.bot_field_order_cnt7 = bottom;
+		break;
+	case 8:
+		hw_ps->pps.top_field_order_cnt8 = top;
+		hw_ps->pps.bot_field_order_cnt8 = bottom;
+		break;
+	case 9:
+		hw_ps->pps.top_field_order_cnt9 = top;
+		hw_ps->pps.bot_field_order_cnt9 = bottom;
+		break;
+	case 10:
+		hw_ps->pps.top_field_order_cnt10 = top;
+		hw_ps->pps.bot_field_order_cnt10 = bottom;
+		break;
+	case 11:
+		hw_ps->pps.top_field_order_cnt11 = top;
+		hw_ps->pps.bot_field_order_cnt11 = bottom;
+		break;
+	case 12:
+		hw_ps->pps.top_field_order_cnt12 = top;
+		hw_ps->pps.bot_field_order_cnt12 = bottom;
+		break;
+	case 13:
+		hw_ps->pps.top_field_order_cnt13 = top;
+		hw_ps->pps.bot_field_order_cnt13 = bottom;
+		break;
+	case 14:
+		hw_ps->pps.top_field_order_cnt14 = top;
+		hw_ps->pps.bot_field_order_cnt14 = bottom;
+		break;
+	case 15:
+		hw_ps->pps.top_field_order_cnt15 = top;
+		hw_ps->pps.bot_field_order_cnt15 = bottom;
+		break;
+	}
+}
+
+static void assemble_hw_pps(struct rkvdec_ctx *ctx,
+			    struct rkvdec_h264_run *run)
+{
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	const struct v4l2_ctrl_h264_sps *sps = run->sps;
+	const struct v4l2_ctrl_h264_pps *pps = run->pps;
+	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
+	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
+	struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
+	struct rkvdec_sps_pps *hw_ps;
+	u32 pic_width, pic_height;
+	u32 i;
+
+	/*
+	 * HW read the SPS/PPS information from PPS packet index by PPS id.
+	 * offset from the base can be calculated by PPS_id * 32 (size per PPS
+	 * packet unit). so the driver copy SPS/PPS information to the exact PPS
+	 * packet unit for HW accessing.
+	 */
+	hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
+	memset(hw_ps, 0, sizeof(*hw_ps));
+
+	/* write sps */
+	hw_ps->sps.seq_parameter_set_id = sps->seq_parameter_set_id;
+	hw_ps->sps.profile_idc = sps->profile_idc;
+	hw_ps->sps.constraint_set3_flag = !!(sps->constraint_set_flags & (1 << 3));
+	hw_ps->sps.chroma_format_idc = sps->chroma_format_idc;
+	hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8;
+	hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8;
+	hw_ps->sps.qpprime_y_zero_transform_bypass_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	hw_ps->sps.log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4;
+	hw_ps->sps.max_num_ref_frames = sps->max_num_ref_frames;
+	hw_ps->sps.pic_order_cnt_type = sps->pic_order_cnt_type;
+	hw_ps->sps.log2_max_pic_order_cnt_lsb_minus4 =
+		sps->log2_max_pic_order_cnt_lsb_minus4;
+	hw_ps->sps.delta_pic_order_always_zero_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	hw_ps->sps.mvc_extension_enable = 0;
+	hw_ps->sps.num_views = 0;
+
+	/*
+	 * Use the SPS values since they are already in macroblocks
+	 * dimensions, height can be field height (halved) if
+	 * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is not set and also it allows
+	 * decoding smaller images into larger allocation which can be used
+	 * to implementing SVC spatial layer support.
+	 */
+	pic_width = 16 * (sps->pic_width_in_mbs_minus1 + 1);
+	pic_height = 16 * (sps->pic_height_in_map_units_minus1 + 1);
+	if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
+		pic_height *= 2;
+	if (!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC))
+		pic_height /= 2;
+
+	hw_ps->sps.pic_width_in_mbs = pic_width;
+	hw_ps->sps.pic_height_in_mbs = pic_height;
+
+	hw_ps->sps.frame_mbs_only_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	hw_ps->sps.mb_adaptive_frame_field_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	hw_ps->sps.direct_8x8_inference_flag =
+		!!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+
+	/* write pps */
+	hw_ps->pps.pic_parameter_set_id = pps->pic_parameter_set_id;
+	hw_ps->pps.pps_seq_parameter_set_id = pps->seq_parameter_set_id;
+	hw_ps->pps.entropy_coding_mode_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	hw_ps->pps.bottom_field_pic_order_in_frame_present_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	hw_ps->pps.num_ref_idx_l0_default_active_minus1 =
+		pps->num_ref_idx_l0_default_active_minus1;
+	hw_ps->pps.num_ref_idx_l1_default_active_minus1 =
+		pps->num_ref_idx_l1_default_active_minus1;
+	hw_ps->pps.weighted_pred_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	hw_ps->pps.weighted_bipred_idc = pps->weighted_bipred_idc;
+	hw_ps->pps.pic_init_qp_minus26 = pps->pic_init_qp_minus26;
+	hw_ps->pps.pic_init_qs_minus26 = pps->pic_init_qs_minus26;
+	hw_ps->pps.chroma_qp_index_offset = pps->chroma_qp_index_offset;
+	hw_ps->pps.deblocking_filter_control_present_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	hw_ps->pps.constrained_intra_pred_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	hw_ps->pps.redundant_pic_cnt_present =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	hw_ps->pps.transform_8x8_mode_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	hw_ps->pps.second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset;
+	hw_ps->pps.scaling_list_enable_flag =
+		!!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+			hw_ps->pps.is_longterm |= (1 << i);
+
+		set_field_order_cnt(hw_ps, i, dpb[i].top_field_order_cnt,
+				    dpb[i].bottom_field_order_cnt);
+
+		hw_ps->pps.ref_field_flags |=
+			(!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) << i;
+		hw_ps->pps.ref_colmv_use_flag |=
+			(!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) << i;
+		hw_ps->pps.ref_topfield_used |=
+			(!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF)) << i;
+		hw_ps->pps.ref_botfield_used |=
+			(!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) << i;
+	}
+
+	hw_ps->pps.pic_field_flag =
+		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC);
+	hw_ps->pps.pic_associated_flag =
+		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);
+
+	hw_ps->pps.cur_top_field = dec_params->top_field_order_cnt;
+	hw_ps->pps.cur_bot_field = dec_params->bottom_field_order_cnt;
+}
+
+static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_REGS,
+			   &h264_ctx->regs.common,
+			   sizeof(h264_ctx->regs.common));
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_ADDR_REGS,
+			   &h264_ctx->regs.common_addr,
+			   sizeof(h264_ctx->regs.common_addr));
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_PARAMS_REGS,
+			   &h264_ctx->regs.h26x_params,
+			   sizeof(h264_ctx->regs.h26x_params));
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_ADDR_REGS,
+			   &h264_ctx->regs.h26x_addr,
+			   sizeof(h264_ctx->regs.h26x_addr));
+}
+
+static void config_registers(struct rkvdec_ctx *ctx,
+			     struct rkvdec_h264_run *run)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma;
+	const struct v4l2_pix_format_mplane *dst_fmt;
+	struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
+	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
+	struct vdpu383_regs_h26x *regs = &h264_ctx->regs;
+	const struct v4l2_format *f;
+	dma_addr_t rlc_addr;
+	dma_addr_t dst_addr;
+	u32 hor_virstride;
+	u32 ver_virstride;
+	u32 y_virstride;
+	u32 offset;
+	u32 pixels;
+	u32 i;
+
+	memset(regs, 0, sizeof(*regs));
+
+	/* Set H264 mode */
+	regs->common.reg008_dec_mode = VDPU383_MODE_H264;
+
+	/* Set input stream length */
+	regs->h26x_params.reg066_stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+
+	/* Set strides */
+	f = &ctx->decoded_fmt;
+	dst_fmt = &f->fmt.pix_mp;
+	hor_virstride = dst_fmt->plane_fmt[0].bytesperline;
+	ver_virstride = dst_fmt->height;
+	y_virstride = hor_virstride * ver_virstride;
+
+	pixels = dst_fmt->height * dst_fmt->width;
+
+	regs->h26x_params.reg068_hor_virstride = hor_virstride / 16;
+	regs->h26x_params.reg069_raster_uv_hor_virstride = hor_virstride / 16;
+	regs->h26x_params.reg070_y_virstride = y_virstride / 16;
+
+	/* Activate block gating */
+	regs->common.reg010.strmd_auto_gating_e      = 1;
+	regs->common.reg010.inter_auto_gating_e      = 1;
+	regs->common.reg010.intra_auto_gating_e      = 1;
+	regs->common.reg010.transd_auto_gating_e     = 1;
+	regs->common.reg010.recon_auto_gating_e      = 1;
+	regs->common.reg010.filterd_auto_gating_e    = 1;
+	regs->common.reg010.bus_auto_gating_e        = 1;
+	regs->common.reg010.ctrl_auto_gating_e       = 1;
+	regs->common.reg010.rcb_auto_gating_e        = 1;
+	regs->common.reg010.err_prc_auto_gating_e    = 1;
+
+	/* Set timeout threshold */
+	if (pixels < VDPU383_1080P_PIXELS)
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_1080p;
+	else if (pixels < VDPU383_4K_PIXELS)
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_4K;
+	else if (pixels < VDPU383_8K_PIXELS)
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_8K;
+	else
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_MAX;
+
+	regs->common.reg016.error_proc_disable = 1;
+
+	/* Set ref pic address & poc */
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		struct vb2_buffer *vb_buf = run->ref_buf[i];
+		dma_addr_t buf_dma;
+
+		/*
+		 * If a DPB entry is unused or invalid, address of current destination
+		 * buffer is returned.
+		 */
+		if (!vb_buf)
+			vb_buf = &dst_buf->vb2_buf;
+
+		buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
+
+		/* Set reference addresses */
+		regs->h26x_addr.reg170_185_ref_base[i] = buf_dma;
+		regs->h26x_addr.reg195_210_payload_st_ref_base[i] = buf_dma;
+
+		/* Set COLMV addresses */
+		regs->h26x_addr.reg217_232_colmv_ref_base[i] = buf_dma + ctx->colmv_offset;
+	}
+
+	/* Set rlc base address (input stream) */
+	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	regs->common_addr.reg128_strm_base = rlc_addr;
+
+	/* Set output base address */
+	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+	regs->h26x_addr.reg168_decout_base = dst_addr;
+	regs->h26x_addr.reg169_error_ref_base = dst_addr;
+	regs->h26x_addr.reg192_payload_st_cur_base = dst_addr;
+
+	/* Set colmv address */
+	regs->h26x_addr.reg216_colmv_cur_base = dst_addr + ctx->colmv_offset;
+
+	/* Set RCB addresses */
+	for (i = 0; i < rkvdec_rcb_buf_count(ctx); i++) {
+		regs->common_addr.reg140_162_rcb_info[i].offset = rkvdec_rcb_buf_dma_addr(ctx, i);
+		regs->common_addr.reg140_162_rcb_info[i].size = rkvdec_rcb_buf_size(ctx, i);
+	}
+
+	/* Set hw pps address */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, param_set);
+	regs->common_addr.reg131_gbl_base = priv_start_addr + offset;
+	regs->h26x_params.reg067_global_len = sizeof(struct rkvdec_sps_pps) / 16;
+
+	/* Set hw rps address */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, rps);
+	regs->common_addr.reg129_rps_base = priv_start_addr + offset;
+
+	/* Set cabac table */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table);
+	regs->common_addr.reg130_cabactbl_base = priv_start_addr + offset;
+
+	/* Set scaling list address */
+	offset = offsetof(struct rkvdec_h264_priv_tbl, scaling_list);
+	regs->common_addr.reg132_scanlist_addr = priv_start_addr + offset;
+
+	rkvdec_write_regs(ctx);
+}
+
+static int rkvdec_h264_start(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_h264_priv_tbl *priv_tbl;
+	struct rkvdec_h264_ctx *h264_ctx;
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_H264_SPS);
+	if (!ctrl)
+		return -EINVAL;
+
+	ret = rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps);
+	if (ret)
+		return ret;
+
+	h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL);
+	if (!h264_ctx)
+		return -ENOMEM;
+
+	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+				      &h264_ctx->priv_tbl.dma, GFP_KERNEL);
+	if (!priv_tbl) {
+		ret = -ENOMEM;
+		goto err_free_ctx;
+	}
+
+	h264_ctx->priv_tbl.size = sizeof(*priv_tbl);
+	h264_ctx->priv_tbl.cpu = priv_tbl;
+	memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table,
+	       sizeof(rkvdec_h264_cabac_table));
+
+	ctx->priv = h264_ctx;
+
+	return 0;
+
+err_free_ctx:
+	kfree(h264_ctx);
+	return ret;
+}
+
+static void rkvdec_h264_stop(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+
+	dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size,
+			  h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma);
+	kfree(h264_ctx);
+}
+
+static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
+{
+	struct v4l2_h264_reflist_builder reflist_builder;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
+	struct rkvdec_h264_run run;
+	struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
+	u32 watchdog_time;
+	u64 timeout_threshold;
+	unsigned long axi_rate;
+
+	rkvdec_h264_run_preamble(ctx, &run);
+
+	/* Build the P/B{0,1} ref lists. */
+	v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params,
+				       run.sps, run.decode_params->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
+				    h264_ctx->reflists.b1);
+
+	assemble_hw_scaling_list(&run, &tbl->scaling_list);
+	assemble_hw_pps(ctx, &run);
+	lookup_ref_buf_idx(ctx, &run);
+	assemble_hw_rps(&reflist_builder, &run, &h264_ctx->reflists, &tbl->rps);
+
+	config_registers(ctx, &run);
+
+	rkvdec_run_postamble(ctx, &run.base);
+
+	/* Set watchdog at 2 times the hardware timeout threshold */
+	timeout_threshold = h264_ctx->regs.common.reg013_core_timeout_threshold;
+	axi_rate = clk_get_rate(rkvdec->axi_clk);
+
+	if (axi_rate)
+		watchdog_time = 2 * (1000 * timeout_threshold) / axi_rate;
+	else
+		watchdog_time = 2000;
+	schedule_delayed_work(&rkvdec->watchdog_work,
+			      msecs_to_jiffies(watchdog_time));
+
+	/* Start decoding! */
+	writel(timeout_threshold, rkvdec->link + VDPU383_LINK_TIMEOUT_THRESHOLD);
+	writel(0, rkvdec->link + VDPU383_LINK_IP_ENABLE);
+	writel(VDPU383_DEC_E_BIT, rkvdec->link + VDPU383_LINK_DEC_ENABLE);
+
+	return 0;
+}
+
+static int rkvdec_h264_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl)
+{
+	if (ctrl->id == V4L2_CID_STATELESS_H264_SPS)
+		return rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps);
+
+	return 0;
+}
+
+const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops = {
+	.adjust_fmt = rkvdec_h264_adjust_fmt,
+	.get_image_fmt = rkvdec_h264_get_image_fmt,
+	.start = rkvdec_h264_start,
+	.stop = rkvdec_h264_stop,
+	.run = rkvdec_h264_run,
+	.try_ctrl = rkvdec_h264_try_ctrl,
+};
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h
new file mode 100644
index 0000000000000..2b614393a3afa
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h
@@ -0,0 +1,284 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Video Decoder VDPU383 driver registers description
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#ifndef _RKVDEC_VDPU838_REGS_H_
+#define _RKVDEC_VDPU838_REGS_H_
+
+#include <linux/types.h>
+
+#define VDPU383_OFFSET_COMMON_REGS		(8 * sizeof(u32))
+#define VDPU383_OFFSET_CODEC_PARAMS_REGS	(64 * sizeof(u32))
+#define VDPU383_OFFSET_COMMON_ADDR_REGS		(128 * sizeof(u32))
+#define VDPU383_OFFSET_CODEC_ADDR_REGS		(168 * sizeof(u32))
+#define VDPU383_OFFSET_POC_HIGHBIT_REGS		(200 * sizeof(u32))
+
+#define VDPU383_MODE_HEVC	0
+#define VDPU383_MODE_H264	1
+
+#define VDPU383_1080P_PIXELS		(1920 * 1080)
+#define VDPU383_4K_PIXELS		(4096 * 2304)
+#define VDPU383_8K_PIXELS		(7680 * 4320)
+#define VDPU383_TIMEOUT_1080p		(0xffffff)
+#define VDPU383_TIMEOUT_4K		(0x2cfffff)
+#define VDPU383_TIMEOUT_8K		(0x4ffffff)
+#define VDPU383_TIMEOUT_MAX		(0xffffffff)
+
+#define VDPU383_LINK_TIMEOUT_THRESHOLD	0x54
+
+#define VDPU383_LINK_IP_ENABLE		0x58
+#define VDPU383_IP_CRU_MODE		BIT(24)
+
+#define VDPU383_LINK_DEC_ENABLE		0x40
+#define VDPU383_DEC_E_BIT		BIT(0)
+
+#define VDPU383_LINK_INT_EN		0x048
+#define VDPU383_INT_EN_IRQ		BIT(0)
+#define VDPU383_INT_EN_LINE_IRQ		BIT(1)
+
+#define VDPU383_LINK_STA_INT		0x04c
+#define VDPU383_STA_INT_DEC_RDY_STA	BIT(0)
+#define VDPU383_STA_INT_SOFTRESET_RDY	(BIT(10) | BIT(11))
+#define VDPU383_STA_INT_ALL		0x3ff
+
+struct vdpu383_regs_common {
+	u32 reg008_dec_mode;
+
+	struct swreg9_important_en {
+		u32 fbc_e			: 1;
+		u32 tile_e			: 1;
+		u32 reserve0			: 2;
+		u32 buf_empty_en		: 1;
+		u32 scale_down_en		: 1;
+		u32 reserve1			: 1;
+		u32 pix_range_det_e		: 1;
+		u32 av1_fgs_en			: 1;
+		u32 reserve2			: 7;
+		u32 line_irq_en			: 1;
+		u32 out_cbcr_swap		: 1;
+		u32 fbc_force_uncompress	: 1;
+		u32 fbc_sparse_mode		: 1;
+		u32 reserve3			: 12;
+	} reg009;
+
+	struct swreg010_block_gating_en {
+		u32 strmd_auto_gating_e		: 1;
+		u32 inter_auto_gating_e		: 1;
+		u32 intra_auto_gating_e		: 1;
+		u32 transd_auto_gating_e	: 1;
+		u32 recon_auto_gating_e		: 1;
+		u32 filterd_auto_gating_e	: 1;
+		u32 bus_auto_gating_e		: 1;
+		u32 ctrl_auto_gating_e		: 1;
+		u32 rcb_auto_gating_e		: 1;
+		u32 err_prc_auto_gating_e	: 1;
+		u32 reserve0			: 22;
+	} reg010;
+
+	struct swreg011_cfg_para {
+		u32 reserve0			: 9;
+		u32 dec_timeout_dis		: 1;
+		u32 reserve1			: 22;
+	} reg011;
+
+	struct swreg012_cache_hash_mask {
+		u32 reserve0			: 7;
+		u32 cache_hash_mask		: 25;
+	} reg012;
+
+	u32 reg013_core_timeout_threshold;
+
+	struct swreg014_line_irq_ctrl {
+		u32 dec_line_irq_step		: 16;
+		u32 dec_line_offset_y_st	: 16;
+	} reg014;
+
+	struct swreg015_irq_sta {
+		u32 rkvdec_frame_rdy_sta	: 1;
+		u32 rkvdec_strm_error_sta	: 1;
+		u32 rkvdec_core_timeout_sta	: 1;
+		u32 rkvdec_ip_timeout_sta	: 1;
+		u32 rkvdec_bus_error_sta	: 1;
+		u32 rkvdec_buffer_empty_sta	: 1;
+		u32 rkvdec_colmv_ref_error_sta	: 1;
+		u32 rkvdec_error_spread_sta	: 1;
+		u32 create_core_timeout_sta	: 1;
+		u32 wlast_miss_match_sta	: 1;
+		u32 rkvdec_core_rst_rdy_sta	: 1;
+		u32 rkvdec_ip_rst_rdy_sta	: 1;
+		u32 force_busidle_rdy_sta	: 1;
+		u32 ltb_pause_rdy_sta		: 1;
+		u32 ltb_end_flag		: 1;
+		u32 unsupport_decmode_error_sta	: 1;
+		u32 wmask_bits			: 15;
+		u32 reserve0			: 1;
+	} reg015;
+
+	struct swreg016_error_ctrl_set {
+		u32 error_proc_disable		: 1;
+		u32 reserve0			: 7;
+		u32 error_spread_disable	: 1;
+		u32 reserve1			: 15;
+		u32 roi_error_ctu_cal_en	: 1;
+		u32 reserve2			: 7;
+	} reg016;
+
+	struct swreg017_err_roi_ctu_offset_start {
+		u32 roi_x_ctu_offset_st		: 12;
+		u32 reserve0			: 4;
+		u32 roi_y_ctu_offset_st		: 12;
+		u32 reserve1			: 4;
+	} reg017;
+
+	struct swreg018_err_roi_ctu_offset_end {
+		u32 roi_x_ctu_offset_end	: 12;
+		u32 reserve0			: 4;
+		u32 roi_y_ctu_offset_end	: 12;
+		u32 reserve1			: 4;
+	} reg018;
+
+	struct swreg019_error_ref_info {
+		u32 avs2_ref_error_field	: 1;
+		u32 avs2_ref_error_topfield	: 1;
+		u32 ref_error_topfield_used	: 1;
+		u32 ref_error_botfield_used	: 1;
+		u32 reserve0			: 28;
+	} reg019;
+
+	u32 reg020_cabac_error_en_lowbits;
+	u32 reg021_cabac_error_en_highbits;
+
+	u32 reg022_reserved;
+
+	struct swreg023_invalid_pixel_fill {
+		u32 fill_y			: 10;
+		u32 fill_u			: 10;
+		u32 fill_v			: 10;
+		u32 reserve0			: 2;
+	} reg023;
+
+	u32 reg024_026_reserved[3];
+
+	struct swreg027_align_en {
+		u32 reserve0			: 4;
+		u32 ctu_align_wr_en		: 1;
+		u32 reserve1			: 27;
+	} reg027;
+
+	struct swreg028_debug_perf_latency_ctrl0 {
+		u32 axi_perf_work_e		: 1;
+		u32 reserve0			: 2;
+		u32 axi_cnt_type		: 1;
+		u32 rd_latency_id		: 8;
+		u32 reserve1			: 4;
+		u32 rd_latency_thr		: 12;
+		u32 reserve2			: 4;
+	} reg028;
+
+	struct swreg029_debug_perf_latency_ctrl1 {
+		u32 addr_align_type		: 2;
+		u32 ar_cnt_id_type		: 1;
+		u32 aw_cnt_id_type		: 1;
+		u32 ar_count_id			: 8;
+		u32 reserve0			: 4;
+		u32 aw_count_id			: 8;
+		u32 rd_band_width_mode		: 1;
+		u32 reserve1			: 7;
+	} reg029;
+
+	struct swreg030_qos_ctrl {
+		u32 axi_wr_qos_level		: 4;
+		u32 reserve0			: 4;
+		u32 axi_wr_qos			: 4;
+		u32 reserve1			: 4;
+		u32 axi_rd_qos_level		: 4;
+		u32 reserve2			: 4;
+		u32 axi_rd_qos			: 4;
+		u32 reserve3			: 4;
+	} reg030;
+};
+
+struct vdpu383_regs_common_addr {
+	u32 reg128_strm_base;
+	u32 reg129_rps_base;
+	u32 reg130_cabactbl_base;
+	u32 reg131_gbl_base;
+	u32 reg132_scanlist_addr;
+	u32 reg133_scale_down_base;
+	u32 reg134_fgs_base;
+	u32 reg135_139_reserved[5];
+
+	struct rcb_info {
+	u32 offset;
+	u32 size;
+	} reg140_162_rcb_info[11];
+};
+
+struct vdpu383_regs_h26x_addr {
+	u32 reg168_decout_base;
+	u32 reg169_error_ref_base;
+	u32 reg170_185_ref_base[16];
+	u32 reg186_191_reserved[6];
+	u32 reg192_payload_st_cur_base;
+	u32 reg193_fbc_payload_offset;
+	u32 reg194_payload_st_error_ref_base;
+	u32 reg195_210_payload_st_ref_base[16];
+	u32 reg211_215_reserved[5];
+	u32 reg216_colmv_cur_base;
+	u32 reg217_232_colmv_ref_base[16];
+};
+
+struct vdpu383_regs_h26x_params {
+	u32 reg064_start_decoder;
+	u32 reg065_strm_start_bit;
+	u32 reg066_stream_len;
+	u32 reg067_global_len;
+	u32 reg068_hor_virstride;
+	u32 reg069_raster_uv_hor_virstride;
+	u32 reg070_y_virstride;
+	u32 reg071_scl_ref_hor_virstride;
+	u32 reg072_scl_ref_raster_uv_hor_virstride;
+	u32 reg073_scl_ref_virstride;
+	u32 reg074_fgs_ref_hor_virstride;
+	u32 reg075_079_reserved[5];
+	u32 reg080_error_ref_hor_virstride;
+	u32 reg081_error_ref_raster_uv_hor_virstride;
+	u32 reg082_error_ref_virstride;
+	u32 reg083_ref0_hor_virstride;
+	u32 reg084_ref0_raster_uv_hor_virstride;
+	u32 reg085_ref0_virstride;
+	u32 reg086_ref1_hor_virstride;
+	u32 reg087_ref1_raster_uv_hor_virstride;
+	u32 reg088_ref1_virstride;
+	u32 reg089_ref2_hor_virstride;
+	u32 reg090_ref2_raster_uv_hor_virstride;
+	u32 reg091_ref2_virstride;
+	u32 reg092_ref3_hor_virstride;
+	u32 reg093_ref3_raster_uv_hor_virstride;
+	u32 reg094_ref3_virstride;
+	u32 reg095_ref4_hor_virstride;
+	u32 reg096_ref4_raster_uv_hor_virstride;
+	u32 reg097_ref4_virstride;
+	u32 reg098_ref5_hor_virstride;
+	u32 reg099_ref5_raster_uv_hor_virstride;
+	u32 reg100_ref5_virstride;
+	u32 reg101_ref6_hor_virstride;
+	u32 reg102_ref6_raster_uv_hor_virstride;
+	u32 reg103_ref6_virstride;
+	u32 reg104_ref7_hor_virstride;
+	u32 reg105_ref7_raster_uv_hor_virstride;
+	u32 reg106_ref7_virstride;
+};
+
+struct vdpu383_regs_h26x {
+	struct vdpu383_regs_common		common;		/* 8-30 */
+	struct vdpu383_regs_h26x_params		h26x_params;	/* 64-74, 80-106 */
+	struct vdpu383_regs_common_addr		common_addr;	/* 128-134, 140-161 */
+	struct vdpu383_regs_h26x_addr		h26x_addr;	/* 168-185, 192-210, 216-232 */
+} __packed;
+
+#endif /* __RKVDEC_VDPU838_REGS_H__ */
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 1b55fe4ff2baf..dab34a2322c95 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -9,6 +9,7 @@
  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
  */
 
+#include <linux/hw_bitfield.h>
 #include <linux/clk.h>
 #include <linux/genalloc.h>
 #include <linux/interrupt.h>
@@ -29,6 +30,7 @@
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
 #include "rkvdec-vdpu381-regs.h"
+#include "rkvdec-vdpu383-regs.h"
 #include "rkvdec-rcb.h"
 
 static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,
@@ -120,6 +122,16 @@ static int vdpu38x_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pix_mp, u32 pix
 	return 0;
 }
 
+static u32 rkvdec_colmv_size(u16 width, u16 height)
+{
+	return 128 * DIV_ROUND_UP(width, 16) * DIV_ROUND_UP(height, 16);
+}
+
+static u32 rkvdec_vdpu383_colmv_size(u16 width, u16 height)
+{
+	return ALIGN(width, 64) * ALIGN(height, 16);
+}
+
 static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx,
 				       struct v4l2_pix_format_mplane *pix_mp)
 {
@@ -129,9 +141,7 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx,
 
 	ctx->colmv_offset = pix_mp->plane_fmt[0].sizeimage;
 
-	pix_mp->plane_fmt[0].sizeimage += 128 *
-		DIV_ROUND_UP(pix_mp->width, 16) *
-		DIV_ROUND_UP(pix_mp->height, 16);
+	pix_mp->plane_fmt[0].sizeimage += cfg->colmv_size(pix_mp->width, pix_mp->height);
 }
 
 static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f,
@@ -346,6 +356,25 @@ static const struct rkvdec_coded_fmt_desc vdpu381_coded_fmts[] = {
 	},
 };
 
+static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_H264_SLICE,
+		.frmsize = {
+			.min_width = 64,
+			.max_width =  65520,
+			.step_width = 64,
+			.min_height = 16,
+			.max_height =  65520,
+			.step_height = 16,
+		},
+		.ctrls = &rkvdec_h264_ctrls,
+		.ops = &rkvdec_vdpu383_h264_fmt_ops,
+		.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
+		.decoded_fmts = rkvdec_h264_decoded_fmts,
+		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
+	},
+};
+
 static const struct rkvdec_coded_fmt_desc *
 rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
 {
@@ -1213,6 +1242,35 @@ static irqreturn_t vdpu381_irq_handler(struct rkvdec_ctx *ctx)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t vdpu383_irq_handler(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	enum vb2_buffer_state state;
+	bool need_reset = 0;
+	u32 status;
+
+	status = readl(rkvdec->link + VDPU383_LINK_STA_INT);
+	writel(FIELD_PREP_WM16(VDPU383_STA_INT_ALL, 0), rkvdec->link + VDPU383_LINK_STA_INT);
+	/* On vdpu383, the interrupts must be disabled */
+	writel(FIELD_PREP_WM16(VDPU383_INT_EN_IRQ | VDPU383_INT_EN_LINE_IRQ, 0),
+	       rkvdec->link + VDPU383_LINK_INT_EN);
+
+	if (status & VDPU383_STA_INT_DEC_RDY_STA) {
+		state = VB2_BUF_STATE_DONE;
+	} else {
+		state = VB2_BUF_STATE_ERROR;
+		rkvdec_iommu_restore(rkvdec);
+	}
+
+	if (need_reset)
+		rkvdec_iommu_restore(rkvdec);
+
+	if (cancel_delayed_work(&rkvdec->watchdog_work))
+		rkvdec_job_finish(ctx, state);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
 {
 	struct rkvdec_dev *rkvdec = priv;
@@ -1285,6 +1343,7 @@ const struct rkvdec_config config_rkvdec = {
 	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
 	.irq_handler = rk3399_irq_handler,
 	.fill_pixfmt_mp = v4l2_fill_pixfmt_mp,
+	.colmv_size = rkvdec_colmv_size,
 };
 
 static struct rcb_size_info vdpu381_rcb_sizes[] = {
@@ -1307,11 +1366,39 @@ const struct rkvdec_config config_vdpu381 = {
 	.rcb_num = ARRAY_SIZE(vdpu381_rcb_sizes),
 	.irq_handler = vdpu381_irq_handler,
 	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
+	.colmv_size = rkvdec_colmv_size,
+	.named_regs = true,
+};
+
+static struct rcb_size_info vdpu383_rcb_sizes[] = {
+	{6,	PIC_WIDTH},	// streamd
+	{6,	PIC_WIDTH},	// streamd_tile
+	{12,	PIC_WIDTH},	// inter
+	{12,	PIC_WIDTH},	// inter_tile
+	{16,	PIC_WIDTH},	// intra
+	{10,	PIC_WIDTH},	// intra_tile
+	{120,	PIC_WIDTH},	// filterd
+	{120,	PIC_WIDTH},	// filterd_protect
+	{120,	PIC_WIDTH},	// filterd_tile_row
+	{180,	PIC_HEIGHT},	// filterd_tile_col
+};
+
+const struct rkvdec_config config_vdpu383 = {
+	.coded_fmts = (struct rkvdec_coded_fmt_desc *)vdpu383_coded_fmts,
+	.coded_fmts_num = ARRAY_SIZE(vdpu383_coded_fmts),
+	.rcb_size_info = vdpu383_rcb_sizes,
+	.rcb_num = ARRAY_SIZE(vdpu383_rcb_sizes),
+	.irq_handler = vdpu383_irq_handler,
+	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
+	.colmv_size = rkvdec_vdpu383_colmv_size,
+	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
+	.named_regs = true,
 };
 
 static const struct of_device_id of_rkvdec_match[] = {
 	{ .compatible = "rockchip,rk3399-vdec", .data = &config_rkvdec },
 	{ .compatible = "rockchip,rk3588-vdec", .data = &config_vdpu381 },
+	{ .compatible = "rockchip,rk3576-vdec", .data = &config_vdpu383 },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_rkvdec_match);
@@ -1344,9 +1431,19 @@ static int rkvdec_probe(struct platform_device *pdev)
 	rkvdec->clk_count = ret;
 	rkvdec->axi_clk = devm_clk_get(&pdev->dev, "axi");
 
-	rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(rkvdec->regs))
-		return PTR_ERR(rkvdec->regs);
+	if (rkvdec->config->named_regs) {
+		rkvdec->regs = devm_platform_ioremap_resource_byname(pdev, "function");
+		if (IS_ERR(rkvdec->regs))
+			return PTR_ERR(rkvdec->regs);
+
+		rkvdec->link = devm_platform_ioremap_resource_byname(pdev, "link");
+		if (IS_ERR(rkvdec->link))
+			return PTR_ERR(rkvdec->link);
+	} else {
+		rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(rkvdec->regs))
+			return PTR_ERR(rkvdec->regs);
+	}
 
 	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret) {
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index 9e0fef2445abc..acb9d72b130bb 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -110,6 +110,8 @@ struct rkvdec_config {
 	irqreturn_t (*irq_handler)(struct rkvdec_ctx *ctx);
 	int (*fill_pixfmt_mp)(struct v4l2_pix_format_mplane *pix_mp, u32 pixelformat,
 			      u32 width, u32 height);
+	u32 (*colmv_size)(u16 width, u16 height);
+	bool named_regs;
 };
 
 struct rkvdec_dev {
@@ -122,6 +124,7 @@ struct rkvdec_dev {
 	unsigned int clk_count;
 	struct clk *axi_clk;
 	void __iomem *regs;
+	void __iomem *link;
 	struct mutex vdev_lock; /* serializes ioctls */
 	struct delayed_work watchdog_work;
 	struct gen_pool *sram_pool;
@@ -164,9 +167,14 @@ 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);
 
+/* RKVDEC ops */
 extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
 extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
 
+/* VDPU381 ops */
 extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_h264_fmt_ops;
 
+/* VDPU383 ops */
+extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops;
+
 #endif /* RKVDEC_H_ */
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (9 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-09 13:17   ` kernel test robot
  2025-08-08 20:03 ` [PATCH v2 12/12] media: rkvdec: Add HEVC support for the VDPU383 variant Detlev Casanova
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

The VDPU381 supports HEVC decoding up to 7680x4320@30fps.
It could double that when using both decoder cores.

It support YUV420 (8 and 10 bits) as well as AFBC (not implemented
here)

The fluster score is 146/147 for JCT-VC-HEVC_V1, tested on ROCK 5B.
None of the other test suites works.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Kconfig    |    1 +
 .../media/platform/rockchip/rkvdec/Makefile   |    2 +
 .../platform/rockchip/rkvdec/rkvdec-cabac.c   | 3435 +++++++++++++++++
 .../rockchip/rkvdec/rkvdec-hevc-common.c      |  546 +++
 .../rockchip/rkvdec/rkvdec-hevc-common.h      |  101 +
 .../rockchip/rkvdec/rkvdec-vdpu381-hevc.c     |  596 +++
 .../media/platform/rockchip/rkvdec/rkvdec.c   |   81 +
 .../media/platform/rockchip/rkvdec/rkvdec.h   |    1 +
 8 files changed, 4763 insertions(+)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c

diff --git a/drivers/media/platform/rockchip/rkvdec/Kconfig b/drivers/media/platform/rockchip/rkvdec/Kconfig
index 5f3bdd848a2cf..3303b0ce32809 100644
--- a/drivers/media/platform/rockchip/rkvdec/Kconfig
+++ b/drivers/media/platform/rockchip/rkvdec/Kconfig
@@ -8,6 +8,7 @@ config VIDEO_ROCKCHIP_VDEC
 	select VIDEOBUF2_VMALLOC
 	select V4L2_MEM2MEM_DEV
 	select V4L2_H264
+	select V4L2_HEVC
 	select V4L2_VP9
 	help
 	  Support for the Rockchip Video Decoder IP present on Rockchip SoCs,
diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index c38ce1e8d3601..fbc8d0d639ab6 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -5,7 +5,9 @@ rockchip-vdec-y += \
 		   rkvdec-cabac.o \
 		   rkvdec-h264.o \
 		   rkvdec-h264-common.o \
+		   rkvdec-hevc-common.o \
 		   rkvdec-rcb.o \
 		   rkvdec-vdpu381-h264.o \
+		   rkvdec-vdpu381-hevc.o \
 		   rkvdec-vdpu383-h264.o \
 		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c
index 6ac4b45cdcb73..fb0cd393b6cd2 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-cabac.c
@@ -507,3 +507,3438 @@ const s8 rkvdec_h264_cabac_table[4][464][2] = {
 	CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67),
 };
 
+const u8 rkvdec_hevc_cabac_table[27456] = {
+	0x07, 0x0f, 0x48, 0x58, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0f, 0x40, 0x40, 0x40, 0x0f, 0x68,
+	0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x40, 0x40, 0x68,
+	0x58, 0x60, 0x40, 0x1f, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x48, 0x48, 0x60, 0x60, 0x50, 0x58,
+	0x50, 0x07, 0x58, 0x68, 0x50, 0x58, 0x68, 0x68,
+	0x68, 0x68, 0x68, 0x50, 0x48, 0x68, 0x60, 0x60,
+	0x50, 0x58, 0x50, 0x07, 0x58, 0x68, 0x50, 0x58,
+	0x68, 0x68, 0x68, 0x68, 0x68, 0x50, 0x48, 0x68,
+	0x48, 0x48, 0x1f, 0x58, 0x68, 0x68, 0x58, 0x60,
+	0x60, 0x60, 0x50, 0x50, 0x50, 0x48, 0x58, 0x58,
+	0x37, 0x07, 0x58, 0x48, 0x58, 0x58, 0x37, 0x07,
+	0x58, 0x48, 0x58, 0x58, 0x37, 0x07, 0x58, 0x50,
+	0x48, 0x1f, 0x1f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07,
+	0x0f, 0x48, 0x68, 0x0f, 0x48, 0x68, 0x40, 0x40,
+	0x50, 0x50, 0x07, 0x40, 0x50, 0x0f, 0x40, 0x48,
+	0x07, 0x40, 0x27, 0x50, 0x48, 0x48, 0x40, 0x0f,
+	0x50, 0x37, 0x1f, 0x1f, 0x50, 0x37, 0x40, 0x27,
+	0x40, 0x07, 0x0f, 0x17, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0f, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0f, 0x40, 0x40, 0x40, 0x0f, 0x66,
+	0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x00, 0x00, 0x67,
+	0x57, 0x5e, 0x00, 0x1f, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x5f, 0x5f, 0x4f, 0x57,
+	0x4f, 0x07, 0x57, 0x67, 0x4f, 0x57, 0x67, 0x67,
+	0x67, 0x67, 0x66, 0x4f, 0x47, 0x66, 0x5f, 0x5f,
+	0x4f, 0x57, 0x4f, 0x07, 0x57, 0x67, 0x4f, 0x57,
+	0x67, 0x67, 0x67, 0x67, 0x66, 0x4f, 0x47, 0x66,
+	0x46, 0x48, 0x20, 0x57, 0x67, 0x67, 0x57, 0x5f,
+	0x5f, 0x5e, 0x4f, 0x4f, 0x4f, 0x47, 0x57, 0x57,
+	0x37, 0x07, 0x57, 0x47, 0x57, 0x57, 0x37, 0x07,
+	0x57, 0x47, 0x57, 0x57, 0x37, 0x07, 0x57, 0x4f,
+	0x47, 0x1f, 0x1f, 0x0f, 0x10, 0x0f, 0x10, 0x07,
+	0x10, 0x47, 0x67, 0x10, 0x47, 0x67, 0x40, 0x40,
+	0x4f, 0x4e, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47,
+	0x07, 0x01, 0x27, 0x4e, 0x47, 0x47, 0x00, 0x0f,
+	0x4f, 0x37, 0x1f, 0x1f, 0x4f, 0x36, 0x00, 0x27,
+	0x00, 0x07, 0x10, 0x17, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0e, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0e, 0x40, 0x40, 0x40, 0x0e, 0x64,
+	0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x00, 0x00, 0x66,
+	0x57, 0x5d, 0x00, 0x1e, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x5e, 0x5e, 0x4e, 0x56,
+	0x4f, 0x07, 0x56, 0x66, 0x4f, 0x56, 0x66, 0x67,
+	0x66, 0x66, 0x64, 0x4e, 0x46, 0x64, 0x5e, 0x5e,
+	0x4e, 0x56, 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x56,
+	0x66, 0x67, 0x66, 0x66, 0x64, 0x4e, 0x46, 0x64,
+	0x45, 0x48, 0x20, 0x57, 0x66, 0x66, 0x56, 0x5e,
+	0x5e, 0x5d, 0x4e, 0x4e, 0x4e, 0x46, 0x56, 0x57,
+	0x36, 0x07, 0x56, 0x46, 0x56, 0x57, 0x36, 0x07,
+	0x56, 0x46, 0x56, 0x57, 0x36, 0x07, 0x56, 0x4f,
+	0x47, 0x1e, 0x1e, 0x0f, 0x10, 0x0f, 0x10, 0x07,
+	0x10, 0x47, 0x66, 0x10, 0x47, 0x66, 0x40, 0x40,
+	0x4f, 0x4d, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47,
+	0x07, 0x03, 0x27, 0x4d, 0x47, 0x46, 0x01, 0x0f,
+	0x4f, 0x36, 0x1f, 0x1e, 0x4f, 0x34, 0x01, 0x26,
+	0x00, 0x07, 0x10, 0x17, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0d, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0e, 0x40, 0x40, 0x40, 0x0e, 0x62,
+	0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x00, 0x00, 0x65,
+	0x57, 0x5c, 0x00, 0x1e, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x5d, 0x5d, 0x4e, 0x56,
+	0x4f, 0x07, 0x56, 0x66, 0x4f, 0x55, 0x65, 0x67,
+	0x66, 0x65, 0x63, 0x4d, 0x46, 0x62, 0x5d, 0x5d,
+	0x4e, 0x56, 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x55,
+	0x65, 0x67, 0x66, 0x65, 0x63, 0x4d, 0x46, 0x62,
+	0x44, 0x48, 0x20, 0x57, 0x65, 0x65, 0x56, 0x5d,
+	0x5d, 0x5c, 0x4e, 0x4d, 0x4e, 0x45, 0x56, 0x57,
+	0x36, 0x07, 0x56, 0x45, 0x56, 0x57, 0x36, 0x07,
+	0x56, 0x45, 0x56, 0x57, 0x36, 0x07, 0x56, 0x4f,
+	0x47, 0x1e, 0x1e, 0x0f, 0x10, 0x0f, 0x10, 0x07,
+	0x10, 0x47, 0x65, 0x10, 0x47, 0x65, 0x40, 0x40,
+	0x4f, 0x4c, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47,
+	0x07, 0x04, 0x27, 0x4c, 0x47, 0x45, 0x01, 0x0f,
+	0x4f, 0x36, 0x1f, 0x1e, 0x4f, 0x33, 0x01, 0x25,
+	0x00, 0x07, 0x10, 0x17, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0c, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0d, 0x40, 0x40, 0x40, 0x0d, 0x60,
+	0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x01, 0x01, 0x64,
+	0x56, 0x5b, 0x01, 0x1d, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x5c, 0x5c, 0x4d, 0x55,
+	0x4e, 0x07, 0x55, 0x65, 0x4e, 0x54, 0x64, 0x66,
+	0x65, 0x64, 0x61, 0x4c, 0x45, 0x60, 0x5c, 0x5c,
+	0x4d, 0x55, 0x4e, 0x07, 0x55, 0x65, 0x4e, 0x54,
+	0x64, 0x66, 0x65, 0x64, 0x61, 0x4c, 0x45, 0x60,
+	0x43, 0x49, 0x21, 0x56, 0x64, 0x64, 0x55, 0x5c,
+	0x5c, 0x5b, 0x4d, 0x4c, 0x4d, 0x44, 0x55, 0x56,
+	0x35, 0x07, 0x55, 0x44, 0x55, 0x56, 0x35, 0x07,
+	0x55, 0x44, 0x55, 0x56, 0x35, 0x07, 0x55, 0x4e,
+	0x46, 0x1d, 0x1d, 0x0f, 0x11, 0x0f, 0x11, 0x07,
+	0x11, 0x46, 0x64, 0x11, 0x46, 0x64, 0x40, 0x40,
+	0x4e, 0x4b, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46,
+	0x07, 0x06, 0x27, 0x4b, 0x46, 0x44, 0x02, 0x0f,
+	0x4e, 0x35, 0x1e, 0x1d, 0x4e, 0x31, 0x02, 0x24,
+	0x01, 0x07, 0x11, 0x16, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0b, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0c, 0x40, 0x40, 0x40, 0x0c, 0x5e,
+	0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x01, 0x01, 0x63,
+	0x56, 0x59, 0x01, 0x1c, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x5b, 0x5b, 0x4c, 0x54,
+	0x4e, 0x07, 0x54, 0x64, 0x4e, 0x53, 0x63, 0x66,
+	0x64, 0x63, 0x60, 0x4b, 0x44, 0x5e, 0x5b, 0x5b,
+	0x4c, 0x54, 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x53,
+	0x63, 0x66, 0x64, 0x63, 0x60, 0x4b, 0x44, 0x5e,
+	0x41, 0x49, 0x21, 0x56, 0x63, 0x63, 0x54, 0x5b,
+	0x5b, 0x59, 0x4c, 0x4b, 0x4c, 0x43, 0x54, 0x56,
+	0x34, 0x07, 0x54, 0x43, 0x54, 0x56, 0x34, 0x07,
+	0x54, 0x43, 0x54, 0x56, 0x34, 0x07, 0x54, 0x4e,
+	0x46, 0x1c, 0x1c, 0x0f, 0x11, 0x0f, 0x11, 0x07,
+	0x11, 0x46, 0x63, 0x11, 0x46, 0x63, 0x40, 0x40,
+	0x4e, 0x49, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46,
+	0x07, 0x07, 0x27, 0x49, 0x46, 0x43, 0x03, 0x0f,
+	0x4e, 0x34, 0x1e, 0x1c, 0x4e, 0x30, 0x03, 0x23,
+	0x01, 0x07, 0x11, 0x16, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0a, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0c, 0x40, 0x40, 0x40, 0x0c, 0x5c,
+	0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x01, 0x01, 0x62,
+	0x56, 0x58, 0x01, 0x1c, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x5a, 0x5a, 0x4c, 0x54,
+	0x4e, 0x07, 0x54, 0x64, 0x4e, 0x52, 0x62, 0x66,
+	0x64, 0x62, 0x5e, 0x4a, 0x44, 0x5c, 0x5a, 0x5a,
+	0x4c, 0x54, 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x52,
+	0x62, 0x66, 0x64, 0x62, 0x5e, 0x4a, 0x44, 0x5c,
+	0x40, 0x49, 0x21, 0x56, 0x62, 0x62, 0x54, 0x5a,
+	0x5a, 0x58, 0x4c, 0x4a, 0x4c, 0x42, 0x54, 0x56,
+	0x34, 0x07, 0x54, 0x42, 0x54, 0x56, 0x34, 0x07,
+	0x54, 0x42, 0x54, 0x56, 0x34, 0x07, 0x54, 0x4e,
+	0x46, 0x1c, 0x1c, 0x0f, 0x11, 0x0f, 0x11, 0x07,
+	0x11, 0x46, 0x62, 0x11, 0x46, 0x62, 0x40, 0x40,
+	0x4e, 0x48, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46,
+	0x07, 0x09, 0x27, 0x48, 0x46, 0x42, 0x03, 0x0f,
+	0x4e, 0x34, 0x1e, 0x1c, 0x4e, 0x2e, 0x03, 0x22,
+	0x01, 0x07, 0x11, 0x16, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x09, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0b, 0x40, 0x40, 0x40, 0x0b, 0x5a,
+	0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x02, 0x02, 0x61,
+	0x55, 0x57, 0x02, 0x1b, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x59, 0x59, 0x4b, 0x53,
+	0x4d, 0x07, 0x53, 0x63, 0x4d, 0x51, 0x61, 0x65,
+	0x63, 0x61, 0x5d, 0x49, 0x43, 0x5a, 0x59, 0x59,
+	0x4b, 0x53, 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x51,
+	0x61, 0x65, 0x63, 0x61, 0x5d, 0x49, 0x43, 0x5a,
+	0x00, 0x4a, 0x22, 0x55, 0x61, 0x61, 0x53, 0x59,
+	0x59, 0x57, 0x4b, 0x49, 0x4b, 0x41, 0x53, 0x55,
+	0x33, 0x07, 0x53, 0x41, 0x53, 0x55, 0x33, 0x07,
+	0x53, 0x41, 0x53, 0x55, 0x33, 0x07, 0x53, 0x4d,
+	0x45, 0x1b, 0x1b, 0x0f, 0x12, 0x0f, 0x12, 0x07,
+	0x12, 0x45, 0x61, 0x12, 0x45, 0x61, 0x40, 0x40,
+	0x4d, 0x47, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45,
+	0x07, 0x0a, 0x27, 0x47, 0x45, 0x41, 0x04, 0x0f,
+	0x4d, 0x33, 0x1d, 0x1b, 0x4d, 0x2d, 0x04, 0x21,
+	0x02, 0x07, 0x12, 0x15, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x08, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0a, 0x40, 0x40, 0x40, 0x0a, 0x59,
+	0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x02, 0x02, 0x60,
+	0x55, 0x56, 0x02, 0x1a, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x58, 0x58, 0x4b, 0x53,
+	0x4d, 0x07, 0x53, 0x63, 0x4d, 0x50, 0x60, 0x65,
+	0x63, 0x60, 0x5b, 0x48, 0x43, 0x59, 0x58, 0x58,
+	0x4b, 0x53, 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x50,
+	0x60, 0x65, 0x63, 0x60, 0x5b, 0x48, 0x43, 0x59,
+	0x01, 0x4a, 0x22, 0x55, 0x60, 0x60, 0x53, 0x58,
+	0x58, 0x56, 0x4b, 0x48, 0x4b, 0x40, 0x53, 0x55,
+	0x32, 0x07, 0x53, 0x40, 0x53, 0x55, 0x32, 0x07,
+	0x53, 0x40, 0x53, 0x55, 0x32, 0x07, 0x53, 0x4d,
+	0x45, 0x1a, 0x1a, 0x0f, 0x12, 0x0f, 0x12, 0x07,
+	0x12, 0x45, 0x60, 0x12, 0x45, 0x60, 0x40, 0x40,
+	0x4d, 0x46, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45,
+	0x07, 0x0c, 0x27, 0x46, 0x45, 0x40, 0x04, 0x0f,
+	0x4d, 0x32, 0x1d, 0x1a, 0x4d, 0x2b, 0x04, 0x20,
+	0x02, 0x07, 0x12, 0x15, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x07, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x0a, 0x40, 0x40, 0x40, 0x0a, 0x57,
+	0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x02, 0x02, 0x5f,
+	0x55, 0x54, 0x02, 0x1a, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x57, 0x57, 0x4a, 0x52,
+	0x4d, 0x07, 0x52, 0x62, 0x4d, 0x4f, 0x5f, 0x65,
+	0x62, 0x5f, 0x59, 0x47, 0x42, 0x57, 0x57, 0x57,
+	0x4a, 0x52, 0x4d, 0x07, 0x52, 0x62, 0x4d, 0x4f,
+	0x5f, 0x65, 0x62, 0x5f, 0x59, 0x47, 0x42, 0x57,
+	0x03, 0x4a, 0x22, 0x55, 0x5f, 0x5f, 0x52, 0x57,
+	0x57, 0x54, 0x4a, 0x47, 0x4a, 0x00, 0x52, 0x55,
+	0x32, 0x07, 0x52, 0x00, 0x52, 0x55, 0x32, 0x07,
+	0x52, 0x00, 0x52, 0x55, 0x32, 0x07, 0x52, 0x4d,
+	0x45, 0x1a, 0x1a, 0x0f, 0x12, 0x0f, 0x12, 0x07,
+	0x12, 0x45, 0x5f, 0x12, 0x45, 0x5f, 0x40, 0x40,
+	0x4d, 0x44, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45,
+	0x07, 0x0e, 0x27, 0x44, 0x45, 0x00, 0x05, 0x0f,
+	0x4d, 0x32, 0x1d, 0x1a, 0x4d, 0x29, 0x05, 0x1f,
+	0x02, 0x07, 0x12, 0x15, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x06, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x09, 0x40, 0x40, 0x40, 0x09, 0x55,
+	0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x03, 0x03, 0x5e,
+	0x54, 0x53, 0x03, 0x19, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x56, 0x56, 0x49, 0x51,
+	0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4e, 0x5e, 0x64,
+	0x61, 0x5e, 0x58, 0x46, 0x41, 0x55, 0x56, 0x56,
+	0x49, 0x51, 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4e,
+	0x5e, 0x64, 0x61, 0x5e, 0x58, 0x46, 0x41, 0x55,
+	0x04, 0x4b, 0x23, 0x54, 0x5e, 0x5e, 0x51, 0x56,
+	0x56, 0x53, 0x49, 0x46, 0x49, 0x01, 0x51, 0x54,
+	0x31, 0x07, 0x51, 0x01, 0x51, 0x54, 0x31, 0x07,
+	0x51, 0x01, 0x51, 0x54, 0x31, 0x07, 0x51, 0x4c,
+	0x44, 0x19, 0x19, 0x0f, 0x13, 0x0f, 0x13, 0x07,
+	0x13, 0x44, 0x5e, 0x13, 0x44, 0x5e, 0x40, 0x40,
+	0x4c, 0x43, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44,
+	0x07, 0x0f, 0x27, 0x43, 0x44, 0x01, 0x06, 0x0f,
+	0x4c, 0x31, 0x1c, 0x19, 0x4c, 0x28, 0x06, 0x1e,
+	0x03, 0x07, 0x13, 0x14, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x05, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x09, 0x40, 0x40, 0x40, 0x09, 0x53,
+	0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x03, 0x03, 0x5d,
+	0x54, 0x52, 0x03, 0x19, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x55, 0x55, 0x49, 0x51,
+	0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4d, 0x5d, 0x64,
+	0x61, 0x5d, 0x56, 0x45, 0x41, 0x53, 0x55, 0x55,
+	0x49, 0x51, 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4d,
+	0x5d, 0x64, 0x61, 0x5d, 0x56, 0x45, 0x41, 0x53,
+	0x05, 0x4b, 0x23, 0x54, 0x5d, 0x5d, 0x51, 0x55,
+	0x55, 0x52, 0x49, 0x45, 0x49, 0x02, 0x51, 0x54,
+	0x31, 0x07, 0x51, 0x02, 0x51, 0x54, 0x31, 0x07,
+	0x51, 0x02, 0x51, 0x54, 0x31, 0x07, 0x51, 0x4c,
+	0x44, 0x19, 0x19, 0x0f, 0x13, 0x0f, 0x13, 0x07,
+	0x13, 0x44, 0x5d, 0x13, 0x44, 0x5d, 0x40, 0x40,
+	0x4c, 0x42, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44,
+	0x07, 0x11, 0x27, 0x42, 0x44, 0x02, 0x06, 0x0f,
+	0x4c, 0x31, 0x1c, 0x19, 0x4c, 0x26, 0x06, 0x1d,
+	0x03, 0x07, 0x13, 0x14, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x04, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x08, 0x40, 0x40, 0x40, 0x08, 0x51,
+	0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x03, 0x03, 0x5c,
+	0x54, 0x51, 0x03, 0x18, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x54, 0x54, 0x48, 0x50,
+	0x4c, 0x07, 0x50, 0x60, 0x4c, 0x4c, 0x5c, 0x64,
+	0x60, 0x5c, 0x55, 0x44, 0x40, 0x51, 0x54, 0x54,
+	0x48, 0x50, 0x4c, 0x07, 0x50, 0x60, 0x4c, 0x4c,
+	0x5c, 0x64, 0x60, 0x5c, 0x55, 0x44, 0x40, 0x51,
+	0x06, 0x4b, 0x23, 0x54, 0x5c, 0x5c, 0x50, 0x54,
+	0x54, 0x51, 0x48, 0x44, 0x48, 0x03, 0x50, 0x54,
+	0x30, 0x07, 0x50, 0x03, 0x50, 0x54, 0x30, 0x07,
+	0x50, 0x03, 0x50, 0x54, 0x30, 0x07, 0x50, 0x4c,
+	0x44, 0x18, 0x18, 0x0f, 0x13, 0x0f, 0x13, 0x07,
+	0x13, 0x44, 0x5c, 0x13, 0x44, 0x5c, 0x40, 0x40,
+	0x4c, 0x41, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44,
+	0x07, 0x12, 0x27, 0x41, 0x44, 0x03, 0x07, 0x0f,
+	0x4c, 0x30, 0x1c, 0x18, 0x4c, 0x25, 0x07, 0x1c,
+	0x03, 0x07, 0x13, 0x14, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x03, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x07, 0x40, 0x40, 0x40, 0x07, 0x4f,
+	0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x5b,
+	0x53, 0x4f, 0x04, 0x17, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x53, 0x53, 0x47, 0x4f,
+	0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4b, 0x5b, 0x63,
+	0x5f, 0x5b, 0x53, 0x43, 0x00, 0x4f, 0x53, 0x53,
+	0x47, 0x4f, 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4b,
+	0x5b, 0x63, 0x5f, 0x5b, 0x53, 0x43, 0x00, 0x4f,
+	0x08, 0x4c, 0x24, 0x53, 0x5b, 0x5b, 0x4f, 0x53,
+	0x53, 0x4f, 0x47, 0x43, 0x47, 0x04, 0x4f, 0x53,
+	0x2f, 0x07, 0x4f, 0x04, 0x4f, 0x53, 0x2f, 0x07,
+	0x4f, 0x04, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x4b,
+	0x43, 0x17, 0x17, 0x0f, 0x14, 0x0f, 0x14, 0x07,
+	0x14, 0x43, 0x5b, 0x14, 0x43, 0x5b, 0x40, 0x40,
+	0x4b, 0x00, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43,
+	0x07, 0x14, 0x27, 0x00, 0x43, 0x04, 0x08, 0x0f,
+	0x4b, 0x2f, 0x1b, 0x17, 0x4b, 0x23, 0x08, 0x1b,
+	0x04, 0x07, 0x14, 0x13, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x02, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x07, 0x40, 0x40, 0x40, 0x07, 0x4d,
+	0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x5a,
+	0x53, 0x4e, 0x04, 0x17, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x52, 0x52, 0x47, 0x4f,
+	0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4a, 0x5a, 0x63,
+	0x5f, 0x5a, 0x52, 0x42, 0x00, 0x4d, 0x52, 0x52,
+	0x47, 0x4f, 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4a,
+	0x5a, 0x63, 0x5f, 0x5a, 0x52, 0x42, 0x00, 0x4d,
+	0x09, 0x4c, 0x24, 0x53, 0x5a, 0x5a, 0x4f, 0x52,
+	0x52, 0x4e, 0x47, 0x42, 0x47, 0x05, 0x4f, 0x53,
+	0x2f, 0x07, 0x4f, 0x05, 0x4f, 0x53, 0x2f, 0x07,
+	0x4f, 0x05, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x4b,
+	0x43, 0x17, 0x17, 0x0f, 0x14, 0x0f, 0x14, 0x07,
+	0x14, 0x43, 0x5a, 0x14, 0x43, 0x5a, 0x40, 0x40,
+	0x4b, 0x01, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43,
+	0x07, 0x15, 0x27, 0x01, 0x43, 0x05, 0x08, 0x0f,
+	0x4b, 0x2f, 0x1b, 0x17, 0x4b, 0x22, 0x08, 0x1a,
+	0x04, 0x07, 0x14, 0x13, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x01, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x06, 0x40, 0x40, 0x40, 0x06, 0x4b,
+	0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x59,
+	0x53, 0x4d, 0x04, 0x16, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x51, 0x51, 0x46, 0x4e,
+	0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63,
+	0x5e, 0x59, 0x50, 0x41, 0x01, 0x4b, 0x51, 0x51,
+	0x46, 0x4e, 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49,
+	0x59, 0x63, 0x5e, 0x59, 0x50, 0x41, 0x01, 0x4b,
+	0x0a, 0x4c, 0x24, 0x53, 0x59, 0x59, 0x4e, 0x51,
+	0x51, 0x4d, 0x46, 0x41, 0x46, 0x06, 0x4e, 0x53,
+	0x2e, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2e, 0x07,
+	0x4e, 0x06, 0x4e, 0x53, 0x2e, 0x07, 0x4e, 0x4b,
+	0x43, 0x16, 0x16, 0x0f, 0x14, 0x0f, 0x14, 0x07,
+	0x14, 0x43, 0x59, 0x14, 0x43, 0x59, 0x40, 0x40,
+	0x4b, 0x02, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43,
+	0x07, 0x17, 0x27, 0x02, 0x43, 0x06, 0x09, 0x0f,
+	0x4b, 0x2e, 0x1b, 0x16, 0x4b, 0x20, 0x09, 0x19,
+	0x04, 0x07, 0x14, 0x13, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x00, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x05, 0x40, 0x40, 0x40, 0x05, 0x4a,
+	0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x59,
+	0x53, 0x4c, 0x04, 0x15, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x51, 0x51, 0x46, 0x4e,
+	0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63,
+	0x5e, 0x59, 0x4f, 0x41, 0x01, 0x4a, 0x51, 0x51,
+	0x46, 0x4e, 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49,
+	0x59, 0x63, 0x5e, 0x59, 0x4f, 0x41, 0x01, 0x4a,
+	0x0b, 0x4d, 0x24, 0x53, 0x59, 0x59, 0x4e, 0x51,
+	0x51, 0x4c, 0x46, 0x41, 0x46, 0x06, 0x4e, 0x53,
+	0x2d, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2d, 0x07,
+	0x4e, 0x06, 0x4e, 0x53, 0x2d, 0x07, 0x4e, 0x4b,
+	0x43, 0x15, 0x15, 0x0f, 0x14, 0x0f, 0x14, 0x07,
+	0x14, 0x43, 0x59, 0x14, 0x43, 0x59, 0x40, 0x40,
+	0x4b, 0x03, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43,
+	0x07, 0x18, 0x27, 0x03, 0x43, 0x06, 0x09, 0x0f,
+	0x4b, 0x2d, 0x1a, 0x15, 0x4b, 0x1e, 0x09, 0x18,
+	0x04, 0x07, 0x14, 0x12, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x00, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x05, 0x40, 0x40, 0x40, 0x05, 0x48,
+	0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x05, 0x05, 0x58,
+	0x52, 0x4a, 0x05, 0x15, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x50, 0x50, 0x45, 0x4d,
+	0x4a, 0x07, 0x4d, 0x5d, 0x4a, 0x48, 0x58, 0x62,
+	0x5d, 0x58, 0x4d, 0x40, 0x02, 0x48, 0x50, 0x50,
+	0x45, 0x4d, 0x4a, 0x07, 0x4d, 0x5d, 0x4a, 0x48,
+	0x58, 0x62, 0x5d, 0x58, 0x4d, 0x40, 0x02, 0x48,
+	0x0d, 0x4d, 0x25, 0x52, 0x58, 0x58, 0x4d, 0x50,
+	0x50, 0x4a, 0x45, 0x40, 0x45, 0x07, 0x4d, 0x52,
+	0x2d, 0x07, 0x4d, 0x07, 0x4d, 0x52, 0x2d, 0x07,
+	0x4d, 0x07, 0x4d, 0x52, 0x2d, 0x07, 0x4d, 0x4a,
+	0x42, 0x15, 0x15, 0x0f, 0x15, 0x0f, 0x15, 0x07,
+	0x15, 0x42, 0x58, 0x15, 0x42, 0x58, 0x40, 0x40,
+	0x4a, 0x05, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42,
+	0x07, 0x1a, 0x27, 0x05, 0x42, 0x07, 0x0a, 0x0f,
+	0x4a, 0x2d, 0x1a, 0x15, 0x4a, 0x1d, 0x0a, 0x18,
+	0x05, 0x07, 0x15, 0x12, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x40, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x04, 0x40, 0x40, 0x40, 0x04, 0x46,
+	0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x05, 0x05, 0x57,
+	0x52, 0x49, 0x05, 0x14, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4f, 0x4f, 0x44, 0x4c,
+	0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x47, 0x57, 0x62,
+	0x5c, 0x57, 0x4b, 0x00, 0x03, 0x46, 0x4f, 0x4f,
+	0x44, 0x4c, 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x47,
+	0x57, 0x62, 0x5c, 0x57, 0x4b, 0x00, 0x03, 0x46,
+	0x0e, 0x4d, 0x25, 0x52, 0x57, 0x57, 0x4c, 0x4f,
+	0x4f, 0x49, 0x44, 0x00, 0x44, 0x08, 0x4c, 0x52,
+	0x2c, 0x07, 0x4c, 0x08, 0x4c, 0x52, 0x2c, 0x07,
+	0x4c, 0x08, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x4a,
+	0x42, 0x14, 0x14, 0x0f, 0x15, 0x0f, 0x15, 0x07,
+	0x15, 0x42, 0x57, 0x15, 0x42, 0x57, 0x40, 0x40,
+	0x4a, 0x06, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42,
+	0x07, 0x1c, 0x27, 0x06, 0x42, 0x08, 0x0b, 0x0f,
+	0x4a, 0x2c, 0x1a, 0x14, 0x4a, 0x1b, 0x0b, 0x17,
+	0x05, 0x07, 0x15, 0x12, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x41, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x04, 0x40, 0x40, 0x40, 0x04, 0x44,
+	0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x05, 0x05, 0x56,
+	0x52, 0x48, 0x05, 0x14, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4e, 0x4e, 0x44, 0x4c,
+	0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x46, 0x56, 0x62,
+	0x5c, 0x56, 0x4a, 0x01, 0x03, 0x44, 0x4e, 0x4e,
+	0x44, 0x4c, 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x46,
+	0x56, 0x62, 0x5c, 0x56, 0x4a, 0x01, 0x03, 0x44,
+	0x0f, 0x4d, 0x25, 0x52, 0x56, 0x56, 0x4c, 0x4e,
+	0x4e, 0x48, 0x44, 0x01, 0x44, 0x09, 0x4c, 0x52,
+	0x2c, 0x07, 0x4c, 0x09, 0x4c, 0x52, 0x2c, 0x07,
+	0x4c, 0x09, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x4a,
+	0x42, 0x14, 0x14, 0x0f, 0x15, 0x0f, 0x15, 0x07,
+	0x15, 0x42, 0x56, 0x15, 0x42, 0x56, 0x40, 0x40,
+	0x4a, 0x07, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42,
+	0x07, 0x1d, 0x27, 0x07, 0x42, 0x09, 0x0b, 0x0f,
+	0x4a, 0x2c, 0x1a, 0x14, 0x4a, 0x1a, 0x0b, 0x16,
+	0x05, 0x07, 0x15, 0x12, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x42, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x03, 0x40, 0x40, 0x40, 0x03, 0x42,
+	0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x06, 0x06, 0x55,
+	0x51, 0x47, 0x06, 0x13, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4d, 0x4d, 0x43, 0x4b,
+	0x49, 0x07, 0x4b, 0x5b, 0x49, 0x45, 0x55, 0x61,
+	0x5b, 0x55, 0x48, 0x02, 0x04, 0x42, 0x4d, 0x4d,
+	0x43, 0x4b, 0x49, 0x07, 0x4b, 0x5b, 0x49, 0x45,
+	0x55, 0x61, 0x5b, 0x55, 0x48, 0x02, 0x04, 0x42,
+	0x10, 0x4e, 0x26, 0x51, 0x55, 0x55, 0x4b, 0x4d,
+	0x4d, 0x47, 0x43, 0x02, 0x43, 0x0a, 0x4b, 0x51,
+	0x2b, 0x07, 0x4b, 0x0a, 0x4b, 0x51, 0x2b, 0x07,
+	0x4b, 0x0a, 0x4b, 0x51, 0x2b, 0x07, 0x4b, 0x49,
+	0x41, 0x13, 0x13, 0x0f, 0x16, 0x0f, 0x16, 0x07,
+	0x16, 0x41, 0x55, 0x16, 0x41, 0x55, 0x40, 0x40,
+	0x49, 0x08, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41,
+	0x07, 0x1f, 0x27, 0x08, 0x41, 0x0a, 0x0c, 0x0f,
+	0x49, 0x2b, 0x19, 0x13, 0x49, 0x18, 0x0c, 0x15,
+	0x06, 0x07, 0x16, 0x11, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x43, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x40, 0x40, 0x40, 0x02, 0x40,
+	0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x06, 0x06, 0x54,
+	0x51, 0x45, 0x06, 0x12, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4c, 0x4c, 0x42, 0x4a,
+	0x49, 0x07, 0x4a, 0x5a, 0x49, 0x44, 0x54, 0x61,
+	0x5a, 0x54, 0x47, 0x03, 0x05, 0x40, 0x4c, 0x4c,
+	0x42, 0x4a, 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x44,
+	0x54, 0x61, 0x5a, 0x54, 0x47, 0x03, 0x05, 0x40,
+	0x12, 0x4e, 0x26, 0x51, 0x54, 0x54, 0x4a, 0x4c,
+	0x4c, 0x45, 0x42, 0x03, 0x42, 0x0b, 0x4a, 0x51,
+	0x2a, 0x07, 0x4a, 0x0b, 0x4a, 0x51, 0x2a, 0x07,
+	0x4a, 0x0b, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x49,
+	0x41, 0x12, 0x12, 0x0f, 0x16, 0x0f, 0x16, 0x07,
+	0x16, 0x41, 0x54, 0x16, 0x41, 0x54, 0x40, 0x40,
+	0x49, 0x0a, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41,
+	0x07, 0x20, 0x27, 0x0a, 0x41, 0x0b, 0x0d, 0x0f,
+	0x49, 0x2a, 0x19, 0x12, 0x49, 0x17, 0x0d, 0x14,
+	0x06, 0x07, 0x16, 0x11, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x44, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x40, 0x40, 0x40, 0x02, 0x01,
+	0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x06, 0x06, 0x53,
+	0x51, 0x44, 0x06, 0x12, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4b, 0x4b, 0x42, 0x4a,
+	0x49, 0x07, 0x4a, 0x5a, 0x49, 0x43, 0x53, 0x61,
+	0x5a, 0x53, 0x45, 0x04, 0x05, 0x01, 0x4b, 0x4b,
+	0x42, 0x4a, 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x43,
+	0x53, 0x61, 0x5a, 0x53, 0x45, 0x04, 0x05, 0x01,
+	0x13, 0x4e, 0x26, 0x51, 0x53, 0x53, 0x4a, 0x4b,
+	0x4b, 0x44, 0x42, 0x04, 0x42, 0x0c, 0x4a, 0x51,
+	0x2a, 0x07, 0x4a, 0x0c, 0x4a, 0x51, 0x2a, 0x07,
+	0x4a, 0x0c, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x49,
+	0x41, 0x12, 0x12, 0x0f, 0x16, 0x0f, 0x16, 0x07,
+	0x16, 0x41, 0x53, 0x16, 0x41, 0x53, 0x40, 0x40,
+	0x49, 0x0b, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41,
+	0x07, 0x22, 0x27, 0x0b, 0x41, 0x0c, 0x0d, 0x0f,
+	0x49, 0x2a, 0x19, 0x12, 0x49, 0x15, 0x0d, 0x13,
+	0x06, 0x07, 0x16, 0x11, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x45, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x01, 0x40, 0x40, 0x40, 0x01, 0x03,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x52,
+	0x50, 0x43, 0x07, 0x11, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x4a, 0x4a, 0x41, 0x49,
+	0x48, 0x07, 0x49, 0x59, 0x48, 0x42, 0x52, 0x60,
+	0x59, 0x52, 0x44, 0x05, 0x06, 0x03, 0x4a, 0x4a,
+	0x41, 0x49, 0x48, 0x07, 0x49, 0x59, 0x48, 0x42,
+	0x52, 0x60, 0x59, 0x52, 0x44, 0x05, 0x06, 0x03,
+	0x14, 0x4f, 0x27, 0x50, 0x52, 0x52, 0x49, 0x4a,
+	0x4a, 0x43, 0x41, 0x05, 0x41, 0x0d, 0x49, 0x50,
+	0x29, 0x07, 0x49, 0x0d, 0x49, 0x50, 0x29, 0x07,
+	0x49, 0x0d, 0x49, 0x50, 0x29, 0x07, 0x49, 0x48,
+	0x40, 0x11, 0x11, 0x0f, 0x17, 0x0f, 0x17, 0x07,
+	0x17, 0x40, 0x52, 0x17, 0x40, 0x52, 0x40, 0x40,
+	0x48, 0x0c, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40,
+	0x07, 0x23, 0x27, 0x0c, 0x40, 0x0d, 0x0e, 0x0f,
+	0x48, 0x29, 0x18, 0x11, 0x48, 0x14, 0x0e, 0x12,
+	0x07, 0x07, 0x17, 0x10, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x46, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x04,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x51,
+	0x50, 0x42, 0x07, 0x10, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x41, 0x49,
+	0x48, 0x07, 0x49, 0x59, 0x48, 0x41, 0x51, 0x60,
+	0x59, 0x51, 0x42, 0x06, 0x06, 0x04, 0x49, 0x49,
+	0x41, 0x49, 0x48, 0x07, 0x49, 0x59, 0x48, 0x41,
+	0x51, 0x60, 0x59, 0x51, 0x42, 0x06, 0x06, 0x04,
+	0x15, 0x4f, 0x27, 0x50, 0x51, 0x51, 0x49, 0x49,
+	0x49, 0x42, 0x41, 0x06, 0x41, 0x0e, 0x49, 0x50,
+	0x28, 0x07, 0x49, 0x0e, 0x49, 0x50, 0x28, 0x07,
+	0x49, 0x0e, 0x49, 0x50, 0x28, 0x07, 0x49, 0x48,
+	0x40, 0x10, 0x10, 0x0f, 0x17, 0x0f, 0x17, 0x07,
+	0x17, 0x40, 0x51, 0x17, 0x40, 0x51, 0x40, 0x40,
+	0x48, 0x0d, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40,
+	0x07, 0x25, 0x27, 0x0d, 0x40, 0x0e, 0x0e, 0x0f,
+	0x48, 0x28, 0x18, 0x10, 0x48, 0x12, 0x0e, 0x11,
+	0x07, 0x07, 0x17, 0x10, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x47, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x06,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x50,
+	0x50, 0x40, 0x07, 0x10, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x40, 0x48,
+	0x48, 0x07, 0x48, 0x58, 0x48, 0x40, 0x50, 0x60,
+	0x58, 0x50, 0x40, 0x07, 0x07, 0x06, 0x48, 0x48,
+	0x40, 0x48, 0x48, 0x07, 0x48, 0x58, 0x48, 0x40,
+	0x50, 0x60, 0x58, 0x50, 0x40, 0x07, 0x07, 0x06,
+	0x17, 0x4f, 0x27, 0x50, 0x50, 0x50, 0x48, 0x48,
+	0x48, 0x40, 0x40, 0x07, 0x40, 0x0f, 0x48, 0x50,
+	0x28, 0x07, 0x48, 0x0f, 0x48, 0x50, 0x28, 0x07,
+	0x48, 0x0f, 0x48, 0x50, 0x28, 0x07, 0x48, 0x48,
+	0x40, 0x10, 0x10, 0x0f, 0x17, 0x0f, 0x17, 0x07,
+	0x17, 0x40, 0x50, 0x17, 0x40, 0x50, 0x40, 0x40,
+	0x48, 0x0f, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40,
+	0x07, 0x27, 0x27, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x48, 0x28, 0x18, 0x10, 0x48, 0x10, 0x0f, 0x10,
+	0x07, 0x07, 0x17, 0x10, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x48, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x08,
+	0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x08, 0x08, 0x4f,
+	0x4f, 0x00, 0x08, 0x0f, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x47, 0x47, 0x00, 0x47,
+	0x47, 0x07, 0x47, 0x57, 0x47, 0x00, 0x4f, 0x5f,
+	0x57, 0x4f, 0x00, 0x08, 0x08, 0x08, 0x47, 0x47,
+	0x00, 0x47, 0x47, 0x07, 0x47, 0x57, 0x47, 0x00,
+	0x4f, 0x5f, 0x57, 0x4f, 0x00, 0x08, 0x08, 0x08,
+	0x18, 0x50, 0x28, 0x4f, 0x4f, 0x4f, 0x47, 0x47,
+	0x47, 0x00, 0x00, 0x08, 0x00, 0x10, 0x47, 0x4f,
+	0x27, 0x07, 0x47, 0x10, 0x47, 0x4f, 0x27, 0x07,
+	0x47, 0x10, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x47,
+	0x00, 0x0f, 0x0f, 0x0f, 0x18, 0x0f, 0x18, 0x07,
+	0x18, 0x00, 0x4f, 0x18, 0x00, 0x4f, 0x40, 0x40,
+	0x47, 0x10, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00,
+	0x07, 0x28, 0x27, 0x10, 0x00, 0x10, 0x10, 0x0f,
+	0x47, 0x27, 0x17, 0x0f, 0x47, 0x0f, 0x10, 0x0f,
+	0x08, 0x07, 0x18, 0x0f, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x49, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0a,
+	0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x08, 0x08, 0x4e,
+	0x4f, 0x01, 0x08, 0x0f, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x46, 0x46, 0x00, 0x47,
+	0x47, 0x07, 0x47, 0x57, 0x47, 0x01, 0x4e, 0x5f,
+	0x57, 0x4e, 0x02, 0x09, 0x08, 0x0a, 0x46, 0x46,
+	0x00, 0x47, 0x47, 0x07, 0x47, 0x57, 0x47, 0x01,
+	0x4e, 0x5f, 0x57, 0x4e, 0x02, 0x09, 0x08, 0x0a,
+	0x19, 0x50, 0x28, 0x4f, 0x4e, 0x4e, 0x47, 0x46,
+	0x46, 0x01, 0x00, 0x09, 0x00, 0x11, 0x47, 0x4f,
+	0x27, 0x07, 0x47, 0x11, 0x47, 0x4f, 0x27, 0x07,
+	0x47, 0x11, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x47,
+	0x00, 0x0f, 0x0f, 0x0f, 0x18, 0x0f, 0x18, 0x07,
+	0x18, 0x00, 0x4e, 0x18, 0x00, 0x4e, 0x40, 0x40,
+	0x47, 0x11, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00,
+	0x07, 0x2a, 0x27, 0x11, 0x00, 0x11, 0x10, 0x0f,
+	0x47, 0x27, 0x17, 0x0f, 0x47, 0x0d, 0x10, 0x0e,
+	0x08, 0x07, 0x18, 0x0f, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4a, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x41, 0x40, 0x40, 0x40, 0x41, 0x0c,
+	0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x08, 0x08, 0x4d,
+	0x4f, 0x02, 0x08, 0x0e, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x45, 0x45, 0x01, 0x46,
+	0x47, 0x07, 0x46, 0x56, 0x47, 0x02, 0x4d, 0x5f,
+	0x56, 0x4d, 0x03, 0x0a, 0x09, 0x0c, 0x45, 0x45,
+	0x01, 0x46, 0x47, 0x07, 0x46, 0x56, 0x47, 0x02,
+	0x4d, 0x5f, 0x56, 0x4d, 0x03, 0x0a, 0x09, 0x0c,
+	0x1a, 0x50, 0x28, 0x4f, 0x4d, 0x4d, 0x46, 0x45,
+	0x45, 0x02, 0x01, 0x0a, 0x01, 0x12, 0x46, 0x4f,
+	0x26, 0x07, 0x46, 0x12, 0x46, 0x4f, 0x26, 0x07,
+	0x46, 0x12, 0x46, 0x4f, 0x26, 0x07, 0x46, 0x47,
+	0x00, 0x0e, 0x0e, 0x0f, 0x18, 0x0f, 0x18, 0x07,
+	0x18, 0x00, 0x4d, 0x18, 0x00, 0x4d, 0x40, 0x40,
+	0x47, 0x12, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00,
+	0x07, 0x2b, 0x27, 0x12, 0x00, 0x12, 0x11, 0x0f,
+	0x47, 0x26, 0x17, 0x0e, 0x47, 0x0c, 0x11, 0x0d,
+	0x08, 0x07, 0x18, 0x0f, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4b, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x42, 0x40, 0x40, 0x40, 0x42, 0x0e,
+	0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4c,
+	0x4e, 0x04, 0x09, 0x0d, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x44, 0x44, 0x02, 0x45,
+	0x46, 0x07, 0x45, 0x55, 0x46, 0x03, 0x4c, 0x5e,
+	0x55, 0x4c, 0x05, 0x0b, 0x0a, 0x0e, 0x44, 0x44,
+	0x02, 0x45, 0x46, 0x07, 0x45, 0x55, 0x46, 0x03,
+	0x4c, 0x5e, 0x55, 0x4c, 0x05, 0x0b, 0x0a, 0x0e,
+	0x1c, 0x51, 0x29, 0x4e, 0x4c, 0x4c, 0x45, 0x44,
+	0x44, 0x04, 0x02, 0x0b, 0x02, 0x13, 0x45, 0x4e,
+	0x25, 0x07, 0x45, 0x13, 0x45, 0x4e, 0x25, 0x07,
+	0x45, 0x13, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x46,
+	0x01, 0x0d, 0x0d, 0x0f, 0x19, 0x0f, 0x19, 0x07,
+	0x19, 0x01, 0x4c, 0x19, 0x01, 0x4c, 0x40, 0x40,
+	0x46, 0x14, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01,
+	0x07, 0x2d, 0x27, 0x14, 0x01, 0x13, 0x12, 0x0f,
+	0x46, 0x25, 0x16, 0x0d, 0x46, 0x0a, 0x12, 0x0c,
+	0x09, 0x07, 0x19, 0x0e, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4c, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x42, 0x40, 0x40, 0x40, 0x42, 0x10,
+	0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4b,
+	0x4e, 0x05, 0x09, 0x0d, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x43, 0x43, 0x02, 0x45,
+	0x46, 0x07, 0x45, 0x55, 0x46, 0x04, 0x4b, 0x5e,
+	0x55, 0x4b, 0x06, 0x0c, 0x0a, 0x10, 0x43, 0x43,
+	0x02, 0x45, 0x46, 0x07, 0x45, 0x55, 0x46, 0x04,
+	0x4b, 0x5e, 0x55, 0x4b, 0x06, 0x0c, 0x0a, 0x10,
+	0x1d, 0x51, 0x29, 0x4e, 0x4b, 0x4b, 0x45, 0x43,
+	0x43, 0x05, 0x02, 0x0c, 0x02, 0x14, 0x45, 0x4e,
+	0x25, 0x07, 0x45, 0x14, 0x45, 0x4e, 0x25, 0x07,
+	0x45, 0x14, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x46,
+	0x01, 0x0d, 0x0d, 0x0f, 0x19, 0x0f, 0x19, 0x07,
+	0x19, 0x01, 0x4b, 0x19, 0x01, 0x4b, 0x40, 0x40,
+	0x46, 0x15, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01,
+	0x07, 0x2e, 0x27, 0x15, 0x01, 0x14, 0x12, 0x0f,
+	0x46, 0x25, 0x16, 0x0d, 0x46, 0x09, 0x12, 0x0b,
+	0x09, 0x07, 0x19, 0x0e, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4d, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x43, 0x40, 0x40, 0x40, 0x43, 0x12,
+	0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4a,
+	0x4e, 0x06, 0x09, 0x0c, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x42, 0x42, 0x03, 0x44,
+	0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e,
+	0x54, 0x4a, 0x08, 0x0d, 0x0b, 0x12, 0x42, 0x42,
+	0x03, 0x44, 0x46, 0x07, 0x44, 0x54, 0x46, 0x05,
+	0x4a, 0x5e, 0x54, 0x4a, 0x08, 0x0d, 0x0b, 0x12,
+	0x1e, 0x51, 0x29, 0x4e, 0x4a, 0x4a, 0x44, 0x42,
+	0x42, 0x06, 0x03, 0x0d, 0x03, 0x15, 0x44, 0x4e,
+	0x24, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x24, 0x07,
+	0x44, 0x15, 0x44, 0x4e, 0x24, 0x07, 0x44, 0x46,
+	0x01, 0x0c, 0x0c, 0x0f, 0x19, 0x0f, 0x19, 0x07,
+	0x19, 0x01, 0x4a, 0x19, 0x01, 0x4a, 0x40, 0x40,
+	0x46, 0x16, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01,
+	0x07, 0x30, 0x27, 0x16, 0x01, 0x15, 0x13, 0x0f,
+	0x46, 0x24, 0x16, 0x0c, 0x46, 0x07, 0x13, 0x0a,
+	0x09, 0x07, 0x19, 0x0e, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4e, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x44, 0x40, 0x40, 0x40, 0x44, 0x13,
+	0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4a,
+	0x4e, 0x07, 0x09, 0x0b, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x42, 0x42, 0x03, 0x44,
+	0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e,
+	0x54, 0x4a, 0x09, 0x0d, 0x0b, 0x13, 0x42, 0x42,
+	0x03, 0x44, 0x46, 0x07, 0x44, 0x54, 0x46, 0x05,
+	0x4a, 0x5e, 0x54, 0x4a, 0x09, 0x0d, 0x0b, 0x13,
+	0x1f, 0x52, 0x29, 0x4e, 0x4a, 0x4a, 0x44, 0x42,
+	0x42, 0x07, 0x03, 0x0d, 0x03, 0x15, 0x44, 0x4e,
+	0x23, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x23, 0x07,
+	0x44, 0x15, 0x44, 0x4e, 0x23, 0x07, 0x44, 0x46,
+	0x01, 0x0b, 0x0b, 0x0f, 0x19, 0x0f, 0x19, 0x07,
+	0x19, 0x01, 0x4a, 0x19, 0x01, 0x4a, 0x40, 0x40,
+	0x46, 0x17, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01,
+	0x07, 0x31, 0x27, 0x17, 0x01, 0x15, 0x13, 0x0f,
+	0x46, 0x23, 0x15, 0x0b, 0x46, 0x05, 0x13, 0x09,
+	0x09, 0x07, 0x19, 0x0d, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4e, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x44, 0x40, 0x40, 0x40, 0x44, 0x15,
+	0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0a, 0x0a, 0x49,
+	0x4d, 0x09, 0x0a, 0x0b, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x41, 0x41, 0x04, 0x43,
+	0x45, 0x07, 0x43, 0x53, 0x45, 0x06, 0x49, 0x5d,
+	0x53, 0x49, 0x0b, 0x0e, 0x0c, 0x15, 0x41, 0x41,
+	0x04, 0x43, 0x45, 0x07, 0x43, 0x53, 0x45, 0x06,
+	0x49, 0x5d, 0x53, 0x49, 0x0b, 0x0e, 0x0c, 0x15,
+	0x21, 0x52, 0x2a, 0x4d, 0x49, 0x49, 0x43, 0x41,
+	0x41, 0x09, 0x04, 0x0e, 0x04, 0x16, 0x43, 0x4d,
+	0x23, 0x07, 0x43, 0x16, 0x43, 0x4d, 0x23, 0x07,
+	0x43, 0x16, 0x43, 0x4d, 0x23, 0x07, 0x43, 0x45,
+	0x02, 0x0b, 0x0b, 0x0f, 0x1a, 0x0f, 0x1a, 0x07,
+	0x1a, 0x02, 0x49, 0x1a, 0x02, 0x49, 0x40, 0x40,
+	0x45, 0x19, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02,
+	0x07, 0x33, 0x27, 0x19, 0x02, 0x16, 0x14, 0x0f,
+	0x45, 0x23, 0x15, 0x0b, 0x45, 0x04, 0x14, 0x09,
+	0x0a, 0x07, 0x1a, 0x0d, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4f, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x45, 0x40, 0x40, 0x40, 0x45, 0x17,
+	0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0a, 0x0a, 0x48,
+	0x4d, 0x0a, 0x0a, 0x0a, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x40, 0x40, 0x05, 0x42,
+	0x45, 0x07, 0x42, 0x52, 0x45, 0x07, 0x48, 0x5d,
+	0x52, 0x48, 0x0d, 0x0f, 0x0d, 0x17, 0x40, 0x40,
+	0x05, 0x42, 0x45, 0x07, 0x42, 0x52, 0x45, 0x07,
+	0x48, 0x5d, 0x52, 0x48, 0x0d, 0x0f, 0x0d, 0x17,
+	0x22, 0x52, 0x2a, 0x4d, 0x48, 0x48, 0x42, 0x40,
+	0x40, 0x0a, 0x05, 0x0f, 0x05, 0x17, 0x42, 0x4d,
+	0x22, 0x07, 0x42, 0x17, 0x42, 0x4d, 0x22, 0x07,
+	0x42, 0x17, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x45,
+	0x02, 0x0a, 0x0a, 0x0f, 0x1a, 0x0f, 0x1a, 0x07,
+	0x1a, 0x02, 0x48, 0x1a, 0x02, 0x48, 0x40, 0x40,
+	0x45, 0x1a, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02,
+	0x07, 0x35, 0x27, 0x1a, 0x02, 0x17, 0x15, 0x0f,
+	0x45, 0x22, 0x15, 0x0a, 0x45, 0x02, 0x15, 0x08,
+	0x0a, 0x07, 0x1a, 0x0d, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x50, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x45, 0x40, 0x40, 0x40, 0x45, 0x19,
+	0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0a, 0x0a, 0x47,
+	0x4d, 0x0b, 0x0a, 0x0a, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x00, 0x00, 0x05, 0x42,
+	0x45, 0x07, 0x42, 0x52, 0x45, 0x08, 0x47, 0x5d,
+	0x52, 0x47, 0x0e, 0x10, 0x0d, 0x19, 0x00, 0x00,
+	0x05, 0x42, 0x45, 0x07, 0x42, 0x52, 0x45, 0x08,
+	0x47, 0x5d, 0x52, 0x47, 0x0e, 0x10, 0x0d, 0x19,
+	0x23, 0x52, 0x2a, 0x4d, 0x47, 0x47, 0x42, 0x00,
+	0x00, 0x0b, 0x05, 0x10, 0x05, 0x18, 0x42, 0x4d,
+	0x22, 0x07, 0x42, 0x18, 0x42, 0x4d, 0x22, 0x07,
+	0x42, 0x18, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x45,
+	0x02, 0x0a, 0x0a, 0x0f, 0x1a, 0x0f, 0x1a, 0x07,
+	0x1a, 0x02, 0x47, 0x1a, 0x02, 0x47, 0x40, 0x40,
+	0x45, 0x1b, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02,
+	0x07, 0x36, 0x27, 0x1b, 0x02, 0x18, 0x15, 0x0f,
+	0x45, 0x22, 0x15, 0x0a, 0x45, 0x01, 0x15, 0x07,
+	0x0a, 0x07, 0x1a, 0x0d, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x51, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x46, 0x40, 0x40, 0x40, 0x46, 0x1b,
+	0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0b, 0x0b, 0x46,
+	0x4c, 0x0c, 0x0b, 0x09, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x01, 0x01, 0x06, 0x41,
+	0x44, 0x07, 0x41, 0x51, 0x44, 0x09, 0x46, 0x5c,
+	0x51, 0x46, 0x10, 0x11, 0x0e, 0x1b, 0x01, 0x01,
+	0x06, 0x41, 0x44, 0x07, 0x41, 0x51, 0x44, 0x09,
+	0x46, 0x5c, 0x51, 0x46, 0x10, 0x11, 0x0e, 0x1b,
+	0x24, 0x53, 0x2b, 0x4c, 0x46, 0x46, 0x41, 0x01,
+	0x01, 0x0c, 0x06, 0x11, 0x06, 0x19, 0x41, 0x4c,
+	0x21, 0x07, 0x41, 0x19, 0x41, 0x4c, 0x21, 0x07,
+	0x41, 0x19, 0x41, 0x4c, 0x21, 0x07, 0x41, 0x44,
+	0x03, 0x09, 0x09, 0x0f, 0x1b, 0x0f, 0x1b, 0x07,
+	0x1b, 0x03, 0x46, 0x1b, 0x03, 0x46, 0x40, 0x40,
+	0x44, 0x1c, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03,
+	0x07, 0x38, 0x27, 0x1c, 0x03, 0x19, 0x16, 0x0f,
+	0x44, 0x21, 0x14, 0x09, 0x44, 0x40, 0x16, 0x06,
+	0x0b, 0x07, 0x1b, 0x0c, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x52, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x47, 0x40, 0x40, 0x40, 0x47, 0x1d,
+	0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0b, 0x0b, 0x45,
+	0x4c, 0x0e, 0x0b, 0x08, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x02, 0x02, 0x07, 0x40,
+	0x44, 0x07, 0x40, 0x50, 0x44, 0x0a, 0x45, 0x5c,
+	0x50, 0x45, 0x11, 0x12, 0x0f, 0x1d, 0x02, 0x02,
+	0x07, 0x40, 0x44, 0x07, 0x40, 0x50, 0x44, 0x0a,
+	0x45, 0x5c, 0x50, 0x45, 0x11, 0x12, 0x0f, 0x1d,
+	0x26, 0x53, 0x2b, 0x4c, 0x45, 0x45, 0x40, 0x02,
+	0x02, 0x0e, 0x07, 0x12, 0x07, 0x1a, 0x40, 0x4c,
+	0x20, 0x07, 0x40, 0x1a, 0x40, 0x4c, 0x20, 0x07,
+	0x40, 0x1a, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x44,
+	0x03, 0x08, 0x08, 0x0f, 0x1b, 0x0f, 0x1b, 0x07,
+	0x1b, 0x03, 0x45, 0x1b, 0x03, 0x45, 0x40, 0x40,
+	0x44, 0x1e, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03,
+	0x07, 0x39, 0x27, 0x1e, 0x03, 0x1a, 0x17, 0x0f,
+	0x44, 0x20, 0x14, 0x08, 0x44, 0x41, 0x17, 0x05,
+	0x0b, 0x07, 0x1b, 0x0c, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x53, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x47, 0x40, 0x40, 0x40, 0x47, 0x1f,
+	0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0b, 0x0b, 0x44,
+	0x4c, 0x0f, 0x0b, 0x08, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x03, 0x03, 0x07, 0x40,
+	0x44, 0x07, 0x40, 0x50, 0x44, 0x0b, 0x44, 0x5c,
+	0x50, 0x44, 0x13, 0x13, 0x0f, 0x1f, 0x03, 0x03,
+	0x07, 0x40, 0x44, 0x07, 0x40, 0x50, 0x44, 0x0b,
+	0x44, 0x5c, 0x50, 0x44, 0x13, 0x13, 0x0f, 0x1f,
+	0x27, 0x53, 0x2b, 0x4c, 0x44, 0x44, 0x40, 0x03,
+	0x03, 0x0f, 0x07, 0x13, 0x07, 0x1b, 0x40, 0x4c,
+	0x20, 0x07, 0x40, 0x1b, 0x40, 0x4c, 0x20, 0x07,
+	0x40, 0x1b, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x44,
+	0x03, 0x08, 0x08, 0x0f, 0x1b, 0x0f, 0x1b, 0x07,
+	0x1b, 0x03, 0x44, 0x1b, 0x03, 0x44, 0x40, 0x40,
+	0x44, 0x1f, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03,
+	0x07, 0x3b, 0x27, 0x1f, 0x03, 0x1b, 0x17, 0x0f,
+	0x44, 0x20, 0x14, 0x08, 0x44, 0x43, 0x17, 0x04,
+	0x0b, 0x07, 0x1b, 0x0c, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x54, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x48, 0x40, 0x40, 0x40, 0x48, 0x21,
+	0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0c, 0x0c, 0x43,
+	0x4b, 0x10, 0x0c, 0x07, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x04, 0x04, 0x08, 0x00,
+	0x43, 0x07, 0x00, 0x4f, 0x43, 0x0c, 0x43, 0x5b,
+	0x4f, 0x43, 0x14, 0x14, 0x10, 0x21, 0x04, 0x04,
+	0x08, 0x00, 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0c,
+	0x43, 0x5b, 0x4f, 0x43, 0x14, 0x14, 0x10, 0x21,
+	0x28, 0x54, 0x2c, 0x4b, 0x43, 0x43, 0x00, 0x04,
+	0x04, 0x10, 0x08, 0x14, 0x08, 0x1c, 0x00, 0x4b,
+	0x1f, 0x07, 0x00, 0x1c, 0x00, 0x4b, 0x1f, 0x07,
+	0x00, 0x1c, 0x00, 0x4b, 0x1f, 0x07, 0x00, 0x43,
+	0x04, 0x07, 0x07, 0x0f, 0x1c, 0x0f, 0x1c, 0x07,
+	0x1c, 0x04, 0x43, 0x1c, 0x04, 0x43, 0x40, 0x40,
+	0x43, 0x20, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04,
+	0x07, 0x3c, 0x27, 0x20, 0x04, 0x1c, 0x18, 0x0f,
+	0x43, 0x1f, 0x13, 0x07, 0x43, 0x44, 0x18, 0x03,
+	0x0c, 0x07, 0x1c, 0x0b, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x55, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x49, 0x40, 0x40, 0x40, 0x49, 0x22,
+	0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0c, 0x0c, 0x42,
+	0x4b, 0x11, 0x0c, 0x06, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x05, 0x05, 0x08, 0x00,
+	0x43, 0x07, 0x00, 0x4f, 0x43, 0x0d, 0x42, 0x5b,
+	0x4f, 0x42, 0x16, 0x15, 0x10, 0x22, 0x05, 0x05,
+	0x08, 0x00, 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0d,
+	0x42, 0x5b, 0x4f, 0x42, 0x16, 0x15, 0x10, 0x22,
+	0x29, 0x54, 0x2c, 0x4b, 0x42, 0x42, 0x00, 0x05,
+	0x05, 0x11, 0x08, 0x15, 0x08, 0x1d, 0x00, 0x4b,
+	0x1e, 0x07, 0x00, 0x1d, 0x00, 0x4b, 0x1e, 0x07,
+	0x00, 0x1d, 0x00, 0x4b, 0x1e, 0x07, 0x00, 0x43,
+	0x04, 0x06, 0x06, 0x0f, 0x1c, 0x0f, 0x1c, 0x07,
+	0x1c, 0x04, 0x42, 0x1c, 0x04, 0x42, 0x40, 0x40,
+	0x43, 0x21, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04,
+	0x07, 0x3e, 0x27, 0x21, 0x04, 0x1d, 0x18, 0x0f,
+	0x43, 0x1e, 0x13, 0x06, 0x43, 0x46, 0x18, 0x02,
+	0x0c, 0x07, 0x1c, 0x0b, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x56, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x49, 0x40, 0x40, 0x40, 0x49, 0x24,
+	0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0c, 0x0c, 0x41,
+	0x4b, 0x13, 0x0c, 0x06, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x06, 0x06, 0x09, 0x01,
+	0x43, 0x07, 0x01, 0x4e, 0x43, 0x0e, 0x41, 0x5b,
+	0x4e, 0x41, 0x18, 0x16, 0x11, 0x24, 0x06, 0x06,
+	0x09, 0x01, 0x43, 0x07, 0x01, 0x4e, 0x43, 0x0e,
+	0x41, 0x5b, 0x4e, 0x41, 0x18, 0x16, 0x11, 0x24,
+	0x2b, 0x54, 0x2c, 0x4b, 0x41, 0x41, 0x01, 0x06,
+	0x06, 0x13, 0x09, 0x16, 0x09, 0x1e, 0x01, 0x4b,
+	0x1e, 0x07, 0x01, 0x1e, 0x01, 0x4b, 0x1e, 0x07,
+	0x01, 0x1e, 0x01, 0x4b, 0x1e, 0x07, 0x01, 0x43,
+	0x04, 0x06, 0x06, 0x0f, 0x1c, 0x0f, 0x1c, 0x07,
+	0x1c, 0x04, 0x41, 0x1c, 0x04, 0x41, 0x40, 0x40,
+	0x43, 0x23, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04,
+	0x07, 0x3e, 0x27, 0x23, 0x04, 0x1e, 0x19, 0x0f,
+	0x43, 0x1e, 0x13, 0x06, 0x43, 0x48, 0x19, 0x01,
+	0x0c, 0x07, 0x1c, 0x0b, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x57, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4a, 0x40, 0x40, 0x40, 0x4a, 0x26,
+	0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0d, 0x0d, 0x40,
+	0x4a, 0x14, 0x0d, 0x05, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x07, 0x07, 0x0a, 0x02,
+	0x42, 0x07, 0x02, 0x4d, 0x42, 0x0f, 0x40, 0x5a,
+	0x4d, 0x40, 0x19, 0x17, 0x12, 0x26, 0x07, 0x07,
+	0x0a, 0x02, 0x42, 0x07, 0x02, 0x4d, 0x42, 0x0f,
+	0x40, 0x5a, 0x4d, 0x40, 0x19, 0x17, 0x12, 0x26,
+	0x2c, 0x55, 0x2d, 0x4a, 0x40, 0x40, 0x02, 0x07,
+	0x07, 0x14, 0x0a, 0x17, 0x0a, 0x1f, 0x02, 0x4a,
+	0x1d, 0x07, 0x02, 0x1f, 0x02, 0x4a, 0x1d, 0x07,
+	0x02, 0x1f, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x42,
+	0x05, 0x05, 0x05, 0x0f, 0x1d, 0x0f, 0x1d, 0x07,
+	0x1d, 0x05, 0x40, 0x1d, 0x05, 0x40, 0x40, 0x40,
+	0x42, 0x24, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05,
+	0x07, 0x3e, 0x27, 0x24, 0x05, 0x1f, 0x1a, 0x0f,
+	0x42, 0x1d, 0x12, 0x05, 0x42, 0x49, 0x1a, 0x00,
+	0x0d, 0x07, 0x1d, 0x0a, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x58, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4a, 0x40, 0x40, 0x40, 0x4a, 0x28,
+	0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0d, 0x0d, 0x00,
+	0x4a, 0x15, 0x0d, 0x05, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x08, 0x08, 0x0a, 0x02,
+	0x42, 0x07, 0x02, 0x4d, 0x42, 0x10, 0x00, 0x5a,
+	0x4d, 0x00, 0x1b, 0x18, 0x12, 0x28, 0x08, 0x08,
+	0x0a, 0x02, 0x42, 0x07, 0x02, 0x4d, 0x42, 0x10,
+	0x00, 0x5a, 0x4d, 0x00, 0x1b, 0x18, 0x12, 0x28,
+	0x2d, 0x55, 0x2d, 0x4a, 0x00, 0x00, 0x02, 0x08,
+	0x08, 0x15, 0x0a, 0x18, 0x0a, 0x20, 0x02, 0x4a,
+	0x1d, 0x07, 0x02, 0x20, 0x02, 0x4a, 0x1d, 0x07,
+	0x02, 0x20, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x42,
+	0x05, 0x05, 0x05, 0x0f, 0x1d, 0x0f, 0x1d, 0x07,
+	0x1d, 0x05, 0x00, 0x1d, 0x05, 0x00, 0x40, 0x40,
+	0x42, 0x25, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05,
+	0x07, 0x3e, 0x27, 0x25, 0x05, 0x20, 0x1a, 0x0f,
+	0x42, 0x1d, 0x12, 0x05, 0x42, 0x4b, 0x1a, 0x40,
+	0x0d, 0x07, 0x1d, 0x0a, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x59, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4b, 0x40, 0x40, 0x40, 0x4b, 0x2a,
+	0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0d, 0x0d, 0x01,
+	0x4a, 0x16, 0x0d, 0x04, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x09, 0x09, 0x0b, 0x03,
+	0x42, 0x07, 0x03, 0x4c, 0x42, 0x11, 0x01, 0x5a,
+	0x4c, 0x01, 0x1c, 0x19, 0x13, 0x2a, 0x09, 0x09,
+	0x0b, 0x03, 0x42, 0x07, 0x03, 0x4c, 0x42, 0x11,
+	0x01, 0x5a, 0x4c, 0x01, 0x1c, 0x19, 0x13, 0x2a,
+	0x2e, 0x55, 0x2d, 0x4a, 0x01, 0x01, 0x03, 0x09,
+	0x09, 0x16, 0x0b, 0x19, 0x0b, 0x21, 0x03, 0x4a,
+	0x1c, 0x07, 0x03, 0x21, 0x03, 0x4a, 0x1c, 0x07,
+	0x03, 0x21, 0x03, 0x4a, 0x1c, 0x07, 0x03, 0x42,
+	0x05, 0x04, 0x04, 0x0f, 0x1d, 0x0f, 0x1d, 0x07,
+	0x1d, 0x05, 0x01, 0x1d, 0x05, 0x01, 0x40, 0x40,
+	0x42, 0x26, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05,
+	0x07, 0x3e, 0x27, 0x26, 0x05, 0x21, 0x1b, 0x0f,
+	0x42, 0x1c, 0x12, 0x04, 0x42, 0x4c, 0x1b, 0x41,
+	0x0d, 0x07, 0x1d, 0x0a, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5a, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4c, 0x40, 0x40, 0x40, 0x4c, 0x2c,
+	0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x02,
+	0x49, 0x18, 0x0e, 0x03, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x0a, 0x0a, 0x0c, 0x04,
+	0x41, 0x07, 0x04, 0x4b, 0x41, 0x12, 0x02, 0x59,
+	0x4b, 0x02, 0x1e, 0x1a, 0x14, 0x2c, 0x0a, 0x0a,
+	0x0c, 0x04, 0x41, 0x07, 0x04, 0x4b, 0x41, 0x12,
+	0x02, 0x59, 0x4b, 0x02, 0x1e, 0x1a, 0x14, 0x2c,
+	0x30, 0x56, 0x2e, 0x49, 0x02, 0x02, 0x04, 0x0a,
+	0x0a, 0x18, 0x0c, 0x1a, 0x0c, 0x22, 0x04, 0x49,
+	0x1b, 0x07, 0x04, 0x22, 0x04, 0x49, 0x1b, 0x07,
+	0x04, 0x22, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x41,
+	0x06, 0x03, 0x03, 0x0f, 0x1e, 0x0f, 0x1e, 0x07,
+	0x1e, 0x06, 0x02, 0x1e, 0x06, 0x02, 0x40, 0x40,
+	0x41, 0x28, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06,
+	0x07, 0x3e, 0x27, 0x28, 0x06, 0x22, 0x1c, 0x0f,
+	0x41, 0x1b, 0x11, 0x03, 0x41, 0x4e, 0x1c, 0x42,
+	0x0e, 0x07, 0x1e, 0x09, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5b, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4c, 0x40, 0x40, 0x40, 0x4c, 0x2e,
+	0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x03,
+	0x49, 0x19, 0x0e, 0x03, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x0b, 0x0b, 0x0c, 0x04,
+	0x41, 0x07, 0x04, 0x4b, 0x41, 0x13, 0x03, 0x59,
+	0x4b, 0x03, 0x1f, 0x1b, 0x14, 0x2e, 0x0b, 0x0b,
+	0x0c, 0x04, 0x41, 0x07, 0x04, 0x4b, 0x41, 0x13,
+	0x03, 0x59, 0x4b, 0x03, 0x1f, 0x1b, 0x14, 0x2e,
+	0x31, 0x56, 0x2e, 0x49, 0x03, 0x03, 0x04, 0x0b,
+	0x0b, 0x19, 0x0c, 0x1b, 0x0c, 0x23, 0x04, 0x49,
+	0x1b, 0x07, 0x04, 0x23, 0x04, 0x49, 0x1b, 0x07,
+	0x04, 0x23, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x41,
+	0x06, 0x03, 0x03, 0x0f, 0x1e, 0x0f, 0x1e, 0x07,
+	0x1e, 0x06, 0x03, 0x1e, 0x06, 0x03, 0x40, 0x40,
+	0x41, 0x29, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06,
+	0x07, 0x3e, 0x27, 0x29, 0x06, 0x23, 0x1c, 0x0f,
+	0x41, 0x1b, 0x11, 0x03, 0x41, 0x4f, 0x1c, 0x43,
+	0x0e, 0x07, 0x1e, 0x09, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5c, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4d, 0x40, 0x40, 0x40, 0x4d, 0x30,
+	0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x04,
+	0x49, 0x1a, 0x0e, 0x02, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x0c, 0x0c, 0x0d, 0x05,
+	0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59,
+	0x4a, 0x04, 0x21, 0x1c, 0x15, 0x30, 0x0c, 0x0c,
+	0x0d, 0x05, 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14,
+	0x04, 0x59, 0x4a, 0x04, 0x21, 0x1c, 0x15, 0x30,
+	0x32, 0x56, 0x2e, 0x49, 0x04, 0x04, 0x05, 0x0c,
+	0x0c, 0x1a, 0x0d, 0x1c, 0x0d, 0x24, 0x05, 0x49,
+	0x1a, 0x07, 0x05, 0x24, 0x05, 0x49, 0x1a, 0x07,
+	0x05, 0x24, 0x05, 0x49, 0x1a, 0x07, 0x05, 0x41,
+	0x06, 0x02, 0x02, 0x0f, 0x1e, 0x0f, 0x1e, 0x07,
+	0x1e, 0x06, 0x04, 0x1e, 0x06, 0x04, 0x40, 0x40,
+	0x41, 0x2a, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06,
+	0x07, 0x3e, 0x27, 0x2a, 0x06, 0x24, 0x1d, 0x0f,
+	0x41, 0x1a, 0x11, 0x02, 0x41, 0x51, 0x1d, 0x44,
+	0x0e, 0x07, 0x1e, 0x09, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5d, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4e, 0x40, 0x40, 0x40, 0x4e, 0x31,
+	0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x04,
+	0x49, 0x1b, 0x0e, 0x01, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x0c, 0x0c, 0x0d, 0x05,
+	0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59,
+	0x4a, 0x04, 0x22, 0x1c, 0x15, 0x31, 0x0c, 0x0c,
+	0x0d, 0x05, 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14,
+	0x04, 0x59, 0x4a, 0x04, 0x22, 0x1c, 0x15, 0x31,
+	0x33, 0x57, 0x2e, 0x49, 0x04, 0x04, 0x05, 0x0c,
+	0x0c, 0x1b, 0x0d, 0x1c, 0x0d, 0x24, 0x05, 0x49,
+	0x19, 0x07, 0x05, 0x24, 0x05, 0x49, 0x19, 0x07,
+	0x05, 0x24, 0x05, 0x49, 0x19, 0x07, 0x05, 0x41,
+	0x06, 0x01, 0x01, 0x0f, 0x1e, 0x0f, 0x1e, 0x07,
+	0x1e, 0x06, 0x04, 0x1e, 0x06, 0x04, 0x40, 0x40,
+	0x41, 0x2b, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06,
+	0x07, 0x3e, 0x27, 0x2b, 0x06, 0x24, 0x1d, 0x0f,
+	0x41, 0x19, 0x10, 0x01, 0x41, 0x53, 0x1d, 0x45,
+	0x0e, 0x07, 0x1e, 0x08, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5d, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4e, 0x40, 0x40, 0x40, 0x4e, 0x33,
+	0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0f, 0x0f, 0x05,
+	0x48, 0x1d, 0x0f, 0x01, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x0d, 0x0d, 0x0e, 0x06,
+	0x40, 0x07, 0x06, 0x49, 0x40, 0x15, 0x05, 0x58,
+	0x49, 0x05, 0x24, 0x1d, 0x16, 0x33, 0x0d, 0x0d,
+	0x0e, 0x06, 0x40, 0x07, 0x06, 0x49, 0x40, 0x15,
+	0x05, 0x58, 0x49, 0x05, 0x24, 0x1d, 0x16, 0x33,
+	0x35, 0x57, 0x2f, 0x48, 0x05, 0x05, 0x06, 0x0d,
+	0x0d, 0x1d, 0x0e, 0x1d, 0x0e, 0x25, 0x06, 0x48,
+	0x19, 0x07, 0x06, 0x25, 0x06, 0x48, 0x19, 0x07,
+	0x06, 0x25, 0x06, 0x48, 0x19, 0x07, 0x06, 0x40,
+	0x07, 0x01, 0x01, 0x0f, 0x1f, 0x0f, 0x1f, 0x07,
+	0x1f, 0x07, 0x05, 0x1f, 0x07, 0x05, 0x40, 0x40,
+	0x40, 0x2d, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07,
+	0x07, 0x3e, 0x27, 0x2d, 0x07, 0x25, 0x1e, 0x0f,
+	0x40, 0x19, 0x10, 0x01, 0x40, 0x54, 0x1e, 0x45,
+	0x0f, 0x07, 0x1f, 0x08, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5e, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4f, 0x40, 0x40, 0x40, 0x4f, 0x35,
+	0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0f, 0x0f, 0x06,
+	0x48, 0x1e, 0x0f, 0x00, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x0e, 0x0e, 0x0f, 0x07,
+	0x40, 0x07, 0x07, 0x48, 0x40, 0x16, 0x06, 0x58,
+	0x48, 0x06, 0x26, 0x1e, 0x17, 0x35, 0x0e, 0x0e,
+	0x0f, 0x07, 0x40, 0x07, 0x07, 0x48, 0x40, 0x16,
+	0x06, 0x58, 0x48, 0x06, 0x26, 0x1e, 0x17, 0x35,
+	0x36, 0x57, 0x2f, 0x48, 0x06, 0x06, 0x07, 0x0e,
+	0x0e, 0x1e, 0x0f, 0x1e, 0x0f, 0x26, 0x07, 0x48,
+	0x18, 0x07, 0x07, 0x26, 0x07, 0x48, 0x18, 0x07,
+	0x07, 0x26, 0x07, 0x48, 0x18, 0x07, 0x07, 0x40,
+	0x07, 0x00, 0x00, 0x0f, 0x1f, 0x0f, 0x1f, 0x07,
+	0x1f, 0x07, 0x06, 0x1f, 0x07, 0x06, 0x40, 0x40,
+	0x40, 0x2e, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07,
+	0x07, 0x3e, 0x27, 0x2e, 0x07, 0x26, 0x1f, 0x0f,
+	0x40, 0x18, 0x10, 0x00, 0x40, 0x56, 0x1f, 0x46,
+	0x0f, 0x07, 0x1f, 0x08, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x5f, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x4f, 0x40, 0x40, 0x40, 0x4f, 0x37,
+	0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x07, 0x0f, 0x0f, 0x07,
+	0x48, 0x1f, 0x0f, 0x00, 0x40, 0x40, 0x40, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x0f, 0x0f, 0x0f, 0x07,
+	0x40, 0x07, 0x07, 0x48, 0x40, 0x17, 0x07, 0x58,
+	0x48, 0x07, 0x27, 0x1f, 0x17, 0x37, 0x0f, 0x0f,
+	0x0f, 0x07, 0x40, 0x07, 0x07, 0x48, 0x40, 0x17,
+	0x07, 0x58, 0x48, 0x07, 0x27, 0x1f, 0x17, 0x37,
+	0x37, 0x57, 0x2f, 0x48, 0x07, 0x07, 0x07, 0x0f,
+	0x0f, 0x1f, 0x0f, 0x1f, 0x0f, 0x27, 0x07, 0x48,
+	0x18, 0x07, 0x07, 0x27, 0x07, 0x48, 0x18, 0x07,
+	0x07, 0x27, 0x07, 0x48, 0x18, 0x07, 0x07, 0x40,
+	0x07, 0x00, 0x00, 0x0f, 0x1f, 0x0f, 0x1f, 0x07,
+	0x1f, 0x07, 0x07, 0x1f, 0x07, 0x07, 0x40, 0x40,
+	0x40, 0x2f, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07,
+	0x07, 0x3e, 0x27, 0x2f, 0x07, 0x27, 0x1f, 0x0f,
+	0x40, 0x18, 0x10, 0x00, 0x40, 0x57, 0x1f, 0x47,
+	0x0f, 0x07, 0x1f, 0x08, 0x0f, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x07, 0x48, 0x48, 0x60, 0x40, 0x27, 0x07,
+	0x07, 0x27, 0x40, 0x48, 0x40, 0x40, 0x40, 0x0f,
+	0x48, 0x68, 0x60, 0x40, 0x68, 0x68, 0x68, 0x68,
+	0x68, 0x07, 0x07, 0x0f, 0x50, 0x40, 0x60, 0x07,
+	0x68, 0x27, 0x48, 0x17, 0x40, 0x50, 0x1f, 0x40,
+	0x40, 0x40, 0x48, 0x48, 0x58, 0x60, 0x60, 0x60,
+	0x68, 0x68, 0x58, 0x68, 0x60, 0x60, 0x60, 0x68,
+	0x68, 0x68, 0x60, 0x50, 0x48, 0x50, 0x58, 0x60,
+	0x60, 0x60, 0x68, 0x68, 0x58, 0x68, 0x60, 0x60,
+	0x60, 0x68, 0x68, 0x68, 0x60, 0x50, 0x48, 0x50,
+	0x07, 0x50, 0x58, 0x40, 0x48, 0x40, 0x48, 0x07,
+	0x48, 0x48, 0x48, 0x68, 0x07, 0x1f, 0x17, 0x50,
+	0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07,
+	0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x40,
+	0x07, 0x48, 0x48, 0x48, 0x07, 0x48, 0x07, 0x17,
+	0x17, 0x17, 0x50, 0x17, 0x17, 0x50, 0x40, 0x40,
+	0x40, 0x2f, 0x2f, 0x17, 0x40, 0x0f, 0x17, 0x1f,
+	0x1f, 0x1f, 0x27, 0x0f, 0x07, 0x07, 0x0f, 0x07,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x07, 0x1f,
+	0x48, 0x17, 0x48, 0x40, 0x48, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x07, 0x47, 0x47, 0x5f, 0x40, 0x27, 0x07,
+	0x07, 0x27, 0x40, 0x47, 0x40, 0x40, 0x40, 0x0f,
+	0x47, 0x66, 0x5f, 0x00, 0x66, 0x66, 0x66, 0x65,
+	0x65, 0x07, 0x07, 0x0f, 0x4f, 0x00, 0x5e, 0x07,
+	0x67, 0x27, 0x47, 0x17, 0x40, 0x4f, 0x1f, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x57, 0x5f, 0x5e, 0x5f,
+	0x66, 0x66, 0x57, 0x67, 0x5f, 0x5e, 0x5f, 0x67,
+	0x67, 0x66, 0x5e, 0x4f, 0x47, 0x4f, 0x57, 0x5f,
+	0x5e, 0x5f, 0x66, 0x66, 0x57, 0x67, 0x5f, 0x5e,
+	0x5f, 0x67, 0x67, 0x66, 0x5e, 0x4f, 0x47, 0x4f,
+	0x08, 0x4f, 0x56, 0x40, 0x48, 0x40, 0x47, 0x07,
+	0x47, 0x47, 0x47, 0x66, 0x07, 0x1f, 0x17, 0x4f,
+	0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07,
+	0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x40,
+	0x07, 0x47, 0x47, 0x47, 0x08, 0x47, 0x08, 0x17,
+	0x17, 0x17, 0x4f, 0x17, 0x17, 0x4f, 0x40, 0x40,
+	0x40, 0x2f, 0x2f, 0x17, 0x40, 0x0f, 0x17, 0x1f,
+	0x1f, 0x20, 0x27, 0x10, 0x07, 0x08, 0x10, 0x08,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1f,
+	0x47, 0x17, 0x46, 0x00, 0x47, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x06, 0x46, 0x47, 0x5e, 0x40, 0x26, 0x06,
+	0x06, 0x27, 0x40, 0x47, 0x40, 0x40, 0x40, 0x0f,
+	0x47, 0x64, 0x5e, 0x01, 0x65, 0x64, 0x64, 0x63,
+	0x63, 0x07, 0x07, 0x0f, 0x4e, 0x00, 0x5d, 0x07,
+	0x66, 0x27, 0x46, 0x17, 0x40, 0x4f, 0x1e, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x56, 0x5e, 0x5d, 0x5e,
+	0x65, 0x64, 0x56, 0x66, 0x5e, 0x5c, 0x5e, 0x66,
+	0x66, 0x65, 0x5d, 0x4e, 0x46, 0x4e, 0x56, 0x5e,
+	0x5d, 0x5e, 0x65, 0x64, 0x56, 0x66, 0x5e, 0x5c,
+	0x5e, 0x66, 0x66, 0x65, 0x5d, 0x4e, 0x46, 0x4e,
+	0x09, 0x4f, 0x54, 0x40, 0x48, 0x40, 0x47, 0x07,
+	0x47, 0x46, 0x46, 0x64, 0x07, 0x1f, 0x16, 0x4f,
+	0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07,
+	0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40,
+	0x07, 0x46, 0x46, 0x46, 0x09, 0x46, 0x09, 0x17,
+	0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40,
+	0x40, 0x2e, 0x2e, 0x17, 0x40, 0x0f, 0x17, 0x1e,
+	0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x08,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1e,
+	0x46, 0x17, 0x45, 0x01, 0x46, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x06, 0x45, 0x47, 0x5e, 0x40, 0x25, 0x06,
+	0x05, 0x27, 0x40, 0x47, 0x40, 0x40, 0x40, 0x0f,
+	0x47, 0x63, 0x5d, 0x01, 0x64, 0x63, 0x62, 0x60,
+	0x60, 0x07, 0x07, 0x0f, 0x4e, 0x00, 0x5c, 0x07,
+	0x65, 0x27, 0x45, 0x17, 0x40, 0x4f, 0x1d, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x56, 0x5d, 0x5c, 0x5d,
+	0x64, 0x63, 0x56, 0x65, 0x5d, 0x5b, 0x5d, 0x65,
+	0x65, 0x64, 0x5c, 0x4d, 0x46, 0x4d, 0x56, 0x5d,
+	0x5c, 0x5d, 0x64, 0x63, 0x56, 0x65, 0x5d, 0x5b,
+	0x5d, 0x65, 0x65, 0x64, 0x5c, 0x4d, 0x46, 0x4d,
+	0x09, 0x4f, 0x52, 0x40, 0x48, 0x40, 0x47, 0x07,
+	0x47, 0x46, 0x46, 0x62, 0x07, 0x1f, 0x16, 0x4f,
+	0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07,
+	0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40,
+	0x07, 0x46, 0x46, 0x45, 0x09, 0x45, 0x09, 0x17,
+	0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40,
+	0x40, 0x2d, 0x2d, 0x17, 0x40, 0x0f, 0x17, 0x1e,
+	0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x08,
+	0x07, 0x3d, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1e,
+	0x45, 0x17, 0x44, 0x01, 0x45, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x05, 0x44, 0x46, 0x5d, 0x40, 0x24, 0x05,
+	0x04, 0x27, 0x40, 0x46, 0x40, 0x40, 0x40, 0x0f,
+	0x46, 0x61, 0x5c, 0x02, 0x63, 0x61, 0x60, 0x5e,
+	0x5e, 0x07, 0x07, 0x0e, 0x4d, 0x01, 0x5b, 0x07,
+	0x64, 0x27, 0x44, 0x16, 0x40, 0x4e, 0x1c, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x55, 0x5c, 0x5b, 0x5c,
+	0x63, 0x61, 0x55, 0x64, 0x5c, 0x59, 0x5c, 0x64,
+	0x64, 0x63, 0x5b, 0x4c, 0x45, 0x4c, 0x55, 0x5c,
+	0x5b, 0x5c, 0x63, 0x61, 0x55, 0x64, 0x5c, 0x59,
+	0x5c, 0x64, 0x64, 0x63, 0x5b, 0x4c, 0x45, 0x4c,
+	0x0a, 0x4e, 0x50, 0x40, 0x48, 0x40, 0x46, 0x07,
+	0x46, 0x45, 0x45, 0x60, 0x07, 0x1e, 0x15, 0x4e,
+	0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07,
+	0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x41,
+	0x07, 0x45, 0x45, 0x44, 0x0a, 0x44, 0x0a, 0x16,
+	0x17, 0x15, 0x4e, 0x17, 0x15, 0x4e, 0x40, 0x40,
+	0x40, 0x2c, 0x2c, 0x16, 0x40, 0x0f, 0x16, 0x1d,
+	0x1d, 0x21, 0x27, 0x11, 0x07, 0x0a, 0x11, 0x09,
+	0x06, 0x3c, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1d,
+	0x44, 0x16, 0x43, 0x02, 0x44, 0x16, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x04, 0x43, 0x46, 0x5c, 0x40, 0x23, 0x04,
+	0x03, 0x27, 0x40, 0x46, 0x40, 0x40, 0x40, 0x0f,
+	0x46, 0x60, 0x5b, 0x03, 0x61, 0x60, 0x5e, 0x5b,
+	0x5b, 0x07, 0x07, 0x0e, 0x4c, 0x01, 0x59, 0x07,
+	0x63, 0x27, 0x43, 0x16, 0x40, 0x4e, 0x1b, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x54, 0x5b, 0x59, 0x5b,
+	0x61, 0x60, 0x54, 0x63, 0x5b, 0x58, 0x5b, 0x63,
+	0x63, 0x61, 0x59, 0x4b, 0x44, 0x4b, 0x54, 0x5b,
+	0x59, 0x5b, 0x61, 0x60, 0x54, 0x63, 0x5b, 0x58,
+	0x5b, 0x63, 0x63, 0x61, 0x59, 0x4b, 0x44, 0x4b,
+	0x0b, 0x4e, 0x4e, 0x40, 0x48, 0x40, 0x46, 0x07,
+	0x46, 0x44, 0x44, 0x5e, 0x07, 0x1e, 0x14, 0x4e,
+	0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07,
+	0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41,
+	0x07, 0x44, 0x44, 0x43, 0x0b, 0x43, 0x0b, 0x16,
+	0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40,
+	0x40, 0x2b, 0x2b, 0x16, 0x40, 0x0f, 0x16, 0x1c,
+	0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x09,
+	0x06, 0x3b, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1c,
+	0x43, 0x16, 0x41, 0x03, 0x43, 0x16, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x04, 0x42, 0x46, 0x5c, 0x40, 0x22, 0x04,
+	0x02, 0x27, 0x40, 0x46, 0x40, 0x40, 0x40, 0x0f,
+	0x46, 0x5e, 0x5a, 0x03, 0x60, 0x5e, 0x5c, 0x59,
+	0x59, 0x07, 0x07, 0x0e, 0x4c, 0x01, 0x58, 0x07,
+	0x62, 0x27, 0x42, 0x16, 0x40, 0x4e, 0x1a, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x54, 0x5a, 0x58, 0x5a,
+	0x60, 0x5e, 0x54, 0x62, 0x5a, 0x56, 0x5a, 0x62,
+	0x62, 0x60, 0x58, 0x4a, 0x44, 0x4a, 0x54, 0x5a,
+	0x58, 0x5a, 0x60, 0x5e, 0x54, 0x62, 0x5a, 0x56,
+	0x5a, 0x62, 0x62, 0x60, 0x58, 0x4a, 0x44, 0x4a,
+	0x0b, 0x4e, 0x4c, 0x40, 0x48, 0x40, 0x46, 0x07,
+	0x46, 0x44, 0x44, 0x5c, 0x07, 0x1e, 0x14, 0x4e,
+	0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07,
+	0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41,
+	0x07, 0x44, 0x44, 0x42, 0x0b, 0x42, 0x0b, 0x16,
+	0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40,
+	0x40, 0x2a, 0x2a, 0x16, 0x40, 0x0f, 0x16, 0x1c,
+	0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x09,
+	0x06, 0x3a, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1c,
+	0x42, 0x16, 0x40, 0x03, 0x42, 0x16, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x03, 0x41, 0x45, 0x5b, 0x40, 0x21, 0x03,
+	0x01, 0x27, 0x40, 0x45, 0x40, 0x40, 0x40, 0x0f,
+	0x45, 0x5d, 0x59, 0x04, 0x5f, 0x5d, 0x5a, 0x56,
+	0x56, 0x07, 0x07, 0x0d, 0x4b, 0x02, 0x57, 0x07,
+	0x61, 0x27, 0x41, 0x15, 0x40, 0x4d, 0x19, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x53, 0x59, 0x57, 0x59,
+	0x5f, 0x5d, 0x53, 0x61, 0x59, 0x55, 0x59, 0x61,
+	0x61, 0x5f, 0x57, 0x49, 0x43, 0x49, 0x53, 0x59,
+	0x57, 0x59, 0x5f, 0x5d, 0x53, 0x61, 0x59, 0x55,
+	0x59, 0x61, 0x61, 0x5f, 0x57, 0x49, 0x43, 0x49,
+	0x0c, 0x4d, 0x4a, 0x40, 0x48, 0x40, 0x45, 0x07,
+	0x45, 0x43, 0x43, 0x5a, 0x07, 0x1d, 0x13, 0x4d,
+	0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07,
+	0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x42,
+	0x07, 0x43, 0x43, 0x41, 0x0c, 0x41, 0x0c, 0x15,
+	0x17, 0x13, 0x4d, 0x17, 0x13, 0x4d, 0x40, 0x40,
+	0x40, 0x29, 0x29, 0x15, 0x40, 0x0f, 0x15, 0x1b,
+	0x1b, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x0a,
+	0x05, 0x39, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1b,
+	0x41, 0x15, 0x00, 0x04, 0x41, 0x15, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x02, 0x40, 0x45, 0x5b, 0x40, 0x20, 0x02,
+	0x00, 0x27, 0x40, 0x45, 0x40, 0x40, 0x40, 0x0f,
+	0x45, 0x5b, 0x58, 0x04, 0x5e, 0x5b, 0x59, 0x54,
+	0x54, 0x07, 0x07, 0x0d, 0x4b, 0x02, 0x56, 0x07,
+	0x60, 0x27, 0x40, 0x15, 0x40, 0x4d, 0x18, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x53, 0x58, 0x56, 0x58,
+	0x5e, 0x5b, 0x53, 0x60, 0x58, 0x53, 0x58, 0x60,
+	0x60, 0x5e, 0x56, 0x48, 0x43, 0x48, 0x53, 0x58,
+	0x56, 0x58, 0x5e, 0x5b, 0x53, 0x60, 0x58, 0x53,
+	0x58, 0x60, 0x60, 0x5e, 0x56, 0x48, 0x43, 0x48,
+	0x0c, 0x4d, 0x49, 0x40, 0x48, 0x40, 0x45, 0x07,
+	0x45, 0x43, 0x43, 0x59, 0x07, 0x1d, 0x12, 0x4d,
+	0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07,
+	0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42,
+	0x07, 0x43, 0x43, 0x40, 0x0c, 0x40, 0x0c, 0x15,
+	0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40,
+	0x40, 0x28, 0x28, 0x15, 0x40, 0x0f, 0x15, 0x1a,
+	0x1a, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x0a,
+	0x05, 0x38, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1a,
+	0x40, 0x15, 0x01, 0x04, 0x40, 0x15, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x02, 0x00, 0x45, 0x5a, 0x40, 0x1f, 0x02,
+	0x40, 0x27, 0x40, 0x45, 0x40, 0x40, 0x40, 0x0f,
+	0x45, 0x59, 0x57, 0x05, 0x5c, 0x59, 0x57, 0x51,
+	0x51, 0x07, 0x07, 0x0d, 0x4a, 0x02, 0x54, 0x07,
+	0x5f, 0x27, 0x00, 0x15, 0x40, 0x4d, 0x17, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x52, 0x57, 0x54, 0x57,
+	0x5c, 0x59, 0x52, 0x5f, 0x57, 0x51, 0x57, 0x5f,
+	0x5f, 0x5c, 0x54, 0x47, 0x42, 0x47, 0x52, 0x57,
+	0x54, 0x57, 0x5c, 0x59, 0x52, 0x5f, 0x57, 0x51,
+	0x57, 0x5f, 0x5f, 0x5c, 0x54, 0x47, 0x42, 0x47,
+	0x0d, 0x4d, 0x47, 0x40, 0x48, 0x40, 0x45, 0x07,
+	0x45, 0x42, 0x42, 0x57, 0x07, 0x1d, 0x12, 0x4d,
+	0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07,
+	0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42,
+	0x07, 0x42, 0x42, 0x00, 0x0d, 0x00, 0x0d, 0x15,
+	0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40,
+	0x40, 0x27, 0x27, 0x15, 0x40, 0x0f, 0x15, 0x1a,
+	0x1a, 0x22, 0x27, 0x12, 0x07, 0x0d, 0x12, 0x0a,
+	0x05, 0x37, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1a,
+	0x00, 0x15, 0x03, 0x05, 0x00, 0x15, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x01, 0x01, 0x44, 0x59, 0x40, 0x1e, 0x01,
+	0x41, 0x27, 0x40, 0x44, 0x40, 0x40, 0x40, 0x0f,
+	0x44, 0x58, 0x56, 0x06, 0x5b, 0x58, 0x55, 0x4f,
+	0x4f, 0x07, 0x07, 0x0c, 0x49, 0x03, 0x53, 0x07,
+	0x5e, 0x27, 0x01, 0x14, 0x40, 0x4c, 0x16, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x51, 0x56, 0x53, 0x56,
+	0x5b, 0x58, 0x51, 0x5e, 0x56, 0x50, 0x56, 0x5e,
+	0x5e, 0x5b, 0x53, 0x46, 0x41, 0x46, 0x51, 0x56,
+	0x53, 0x56, 0x5b, 0x58, 0x51, 0x5e, 0x56, 0x50,
+	0x56, 0x5e, 0x5e, 0x5b, 0x53, 0x46, 0x41, 0x46,
+	0x0e, 0x4c, 0x45, 0x40, 0x48, 0x40, 0x44, 0x07,
+	0x44, 0x41, 0x41, 0x55, 0x07, 0x1c, 0x11, 0x4c,
+	0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07,
+	0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43,
+	0x07, 0x41, 0x41, 0x01, 0x0e, 0x01, 0x0e, 0x14,
+	0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40,
+	0x40, 0x26, 0x26, 0x14, 0x40, 0x0f, 0x14, 0x19,
+	0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x0b,
+	0x04, 0x36, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x19,
+	0x01, 0x14, 0x04, 0x06, 0x01, 0x14, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x01, 0x02, 0x44, 0x59, 0x40, 0x1d, 0x01,
+	0x42, 0x27, 0x40, 0x44, 0x40, 0x40, 0x40, 0x0f,
+	0x44, 0x56, 0x55, 0x06, 0x5a, 0x56, 0x53, 0x4c,
+	0x4c, 0x07, 0x07, 0x0c, 0x49, 0x03, 0x52, 0x07,
+	0x5d, 0x27, 0x02, 0x14, 0x40, 0x4c, 0x15, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x51, 0x55, 0x52, 0x55,
+	0x5a, 0x56, 0x51, 0x5d, 0x55, 0x4e, 0x55, 0x5d,
+	0x5d, 0x5a, 0x52, 0x45, 0x41, 0x45, 0x51, 0x55,
+	0x52, 0x55, 0x5a, 0x56, 0x51, 0x5d, 0x55, 0x4e,
+	0x55, 0x5d, 0x5d, 0x5a, 0x52, 0x45, 0x41, 0x45,
+	0x0e, 0x4c, 0x43, 0x40, 0x48, 0x40, 0x44, 0x07,
+	0x44, 0x41, 0x41, 0x53, 0x07, 0x1c, 0x11, 0x4c,
+	0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07,
+	0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43,
+	0x07, 0x41, 0x41, 0x02, 0x0e, 0x02, 0x0e, 0x14,
+	0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40,
+	0x40, 0x25, 0x25, 0x14, 0x40, 0x0f, 0x14, 0x19,
+	0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x0b,
+	0x04, 0x35, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x19,
+	0x02, 0x14, 0x05, 0x06, 0x02, 0x14, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x00, 0x03, 0x44, 0x58, 0x40, 0x1c, 0x00,
+	0x43, 0x27, 0x40, 0x44, 0x40, 0x40, 0x40, 0x0f,
+	0x44, 0x55, 0x54, 0x07, 0x59, 0x55, 0x51, 0x4a,
+	0x4a, 0x07, 0x07, 0x0c, 0x48, 0x03, 0x51, 0x07,
+	0x5c, 0x27, 0x03, 0x14, 0x40, 0x4c, 0x14, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x50, 0x54, 0x51, 0x54,
+	0x59, 0x55, 0x50, 0x5c, 0x54, 0x4d, 0x54, 0x5c,
+	0x5c, 0x59, 0x51, 0x44, 0x40, 0x44, 0x50, 0x54,
+	0x51, 0x54, 0x59, 0x55, 0x50, 0x5c, 0x54, 0x4d,
+	0x54, 0x5c, 0x5c, 0x59, 0x51, 0x44, 0x40, 0x44,
+	0x0f, 0x4c, 0x41, 0x40, 0x48, 0x40, 0x44, 0x07,
+	0x44, 0x40, 0x40, 0x51, 0x07, 0x1c, 0x10, 0x4c,
+	0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07,
+	0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x43,
+	0x07, 0x40, 0x40, 0x03, 0x0f, 0x03, 0x0f, 0x14,
+	0x17, 0x10, 0x4c, 0x17, 0x10, 0x4c, 0x40, 0x40,
+	0x40, 0x24, 0x24, 0x14, 0x40, 0x0f, 0x14, 0x18,
+	0x18, 0x23, 0x27, 0x13, 0x07, 0x0f, 0x13, 0x0b,
+	0x04, 0x34, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x18,
+	0x03, 0x14, 0x06, 0x07, 0x03, 0x14, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x40, 0x04, 0x43, 0x57, 0x40, 0x1b, 0x40,
+	0x44, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f,
+	0x43, 0x53, 0x53, 0x08, 0x57, 0x53, 0x4f, 0x47,
+	0x47, 0x07, 0x07, 0x0b, 0x47, 0x04, 0x4f, 0x07,
+	0x5b, 0x27, 0x04, 0x13, 0x40, 0x4b, 0x13, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4f, 0x53, 0x4f, 0x53,
+	0x57, 0x53, 0x4f, 0x5b, 0x53, 0x4b, 0x53, 0x5b,
+	0x5b, 0x57, 0x4f, 0x43, 0x00, 0x43, 0x4f, 0x53,
+	0x4f, 0x53, 0x57, 0x53, 0x4f, 0x5b, 0x53, 0x4b,
+	0x53, 0x5b, 0x5b, 0x57, 0x4f, 0x43, 0x00, 0x43,
+	0x10, 0x4b, 0x00, 0x40, 0x48, 0x40, 0x43, 0x07,
+	0x43, 0x00, 0x00, 0x4f, 0x07, 0x1b, 0x0f, 0x4b,
+	0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07,
+	0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44,
+	0x07, 0x00, 0x00, 0x04, 0x10, 0x04, 0x10, 0x13,
+	0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40,
+	0x40, 0x23, 0x23, 0x13, 0x40, 0x0f, 0x13, 0x17,
+	0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x0c,
+	0x03, 0x33, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x17,
+	0x04, 0x13, 0x08, 0x08, 0x04, 0x13, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x40, 0x05, 0x43, 0x57, 0x40, 0x1a, 0x40,
+	0x45, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f,
+	0x43, 0x52, 0x52, 0x08, 0x56, 0x52, 0x4d, 0x45,
+	0x45, 0x07, 0x07, 0x0b, 0x47, 0x04, 0x4e, 0x07,
+	0x5a, 0x27, 0x05, 0x13, 0x40, 0x4b, 0x12, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4f, 0x52, 0x4e, 0x52,
+	0x56, 0x52, 0x4f, 0x5a, 0x52, 0x4a, 0x52, 0x5a,
+	0x5a, 0x56, 0x4e, 0x42, 0x00, 0x42, 0x4f, 0x52,
+	0x4e, 0x52, 0x56, 0x52, 0x4f, 0x5a, 0x52, 0x4a,
+	0x52, 0x5a, 0x5a, 0x56, 0x4e, 0x42, 0x00, 0x42,
+	0x10, 0x4b, 0x02, 0x40, 0x48, 0x40, 0x43, 0x07,
+	0x43, 0x00, 0x00, 0x4d, 0x07, 0x1b, 0x0f, 0x4b,
+	0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07,
+	0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44,
+	0x07, 0x00, 0x00, 0x05, 0x10, 0x05, 0x10, 0x13,
+	0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40,
+	0x40, 0x22, 0x22, 0x13, 0x40, 0x0f, 0x13, 0x17,
+	0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x0c,
+	0x03, 0x32, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x17,
+	0x05, 0x13, 0x09, 0x08, 0x05, 0x13, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x41, 0x06, 0x43, 0x56, 0x40, 0x19, 0x41,
+	0x46, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f,
+	0x43, 0x50, 0x51, 0x09, 0x55, 0x50, 0x4b, 0x42,
+	0x42, 0x07, 0x07, 0x0b, 0x46, 0x04, 0x4d, 0x07,
+	0x59, 0x27, 0x06, 0x13, 0x40, 0x4b, 0x11, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x4d, 0x51,
+	0x55, 0x50, 0x4e, 0x59, 0x51, 0x48, 0x51, 0x59,
+	0x59, 0x55, 0x4d, 0x41, 0x01, 0x41, 0x4e, 0x51,
+	0x4d, 0x51, 0x55, 0x50, 0x4e, 0x59, 0x51, 0x48,
+	0x51, 0x59, 0x59, 0x55, 0x4d, 0x41, 0x01, 0x41,
+	0x11, 0x4b, 0x04, 0x40, 0x48, 0x40, 0x43, 0x07,
+	0x43, 0x01, 0x01, 0x4b, 0x07, 0x1b, 0x0e, 0x4b,
+	0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07,
+	0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x44,
+	0x07, 0x01, 0x01, 0x06, 0x11, 0x06, 0x11, 0x13,
+	0x17, 0x0e, 0x4b, 0x17, 0x0e, 0x4b, 0x40, 0x40,
+	0x40, 0x21, 0x21, 0x13, 0x40, 0x0f, 0x13, 0x16,
+	0x16, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x0c,
+	0x03, 0x31, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x16,
+	0x06, 0x13, 0x0a, 0x09, 0x06, 0x13, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x42, 0x06, 0x43, 0x56, 0x40, 0x18, 0x42,
+	0x47, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f,
+	0x43, 0x4f, 0x51, 0x09, 0x54, 0x4f, 0x4a, 0x40,
+	0x40, 0x07, 0x07, 0x0a, 0x46, 0x04, 0x4c, 0x07,
+	0x59, 0x27, 0x06, 0x12, 0x40, 0x4b, 0x10, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x4c, 0x51,
+	0x54, 0x4f, 0x4e, 0x59, 0x51, 0x47, 0x51, 0x59,
+	0x59, 0x54, 0x4c, 0x41, 0x01, 0x41, 0x4e, 0x51,
+	0x4c, 0x51, 0x54, 0x4f, 0x4e, 0x59, 0x51, 0x47,
+	0x51, 0x59, 0x59, 0x54, 0x4c, 0x41, 0x01, 0x41,
+	0x11, 0x4b, 0x05, 0x40, 0x48, 0x40, 0x43, 0x07,
+	0x43, 0x01, 0x01, 0x4a, 0x07, 0x1a, 0x0d, 0x4b,
+	0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07,
+	0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x45,
+	0x07, 0x01, 0x01, 0x06, 0x11, 0x06, 0x11, 0x12,
+	0x17, 0x0d, 0x4b, 0x17, 0x0d, 0x4b, 0x40, 0x40,
+	0x40, 0x20, 0x20, 0x12, 0x40, 0x0f, 0x12, 0x15,
+	0x15, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x0c,
+	0x02, 0x30, 0x1a, 0x12, 0x40, 0x12, 0x0c, 0x15,
+	0x06, 0x12, 0x0b, 0x09, 0x06, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x42, 0x07, 0x42, 0x55, 0x40, 0x18, 0x42,
+	0x47, 0x27, 0x40, 0x42, 0x40, 0x40, 0x40, 0x0f,
+	0x42, 0x4d, 0x50, 0x0a, 0x52, 0x4d, 0x48, 0x02,
+	0x02, 0x07, 0x07, 0x0a, 0x45, 0x05, 0x4a, 0x07,
+	0x58, 0x27, 0x07, 0x12, 0x40, 0x4a, 0x10, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4d, 0x50, 0x4a, 0x50,
+	0x52, 0x4d, 0x4d, 0x58, 0x50, 0x45, 0x50, 0x58,
+	0x58, 0x52, 0x4a, 0x40, 0x02, 0x40, 0x4d, 0x50,
+	0x4a, 0x50, 0x52, 0x4d, 0x4d, 0x58, 0x50, 0x45,
+	0x50, 0x58, 0x58, 0x52, 0x4a, 0x40, 0x02, 0x40,
+	0x12, 0x4a, 0x07, 0x40, 0x48, 0x40, 0x42, 0x07,
+	0x42, 0x02, 0x02, 0x48, 0x07, 0x1a, 0x0d, 0x4a,
+	0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07,
+	0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x45,
+	0x07, 0x02, 0x02, 0x07, 0x12, 0x07, 0x12, 0x12,
+	0x17, 0x0d, 0x4a, 0x17, 0x0d, 0x4a, 0x40, 0x40,
+	0x40, 0x20, 0x20, 0x12, 0x40, 0x0f, 0x12, 0x15,
+	0x15, 0x25, 0x27, 0x15, 0x07, 0x12, 0x15, 0x0d,
+	0x02, 0x30, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x15,
+	0x07, 0x12, 0x0d, 0x0a, 0x07, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x43, 0x08, 0x42, 0x54, 0x40, 0x17, 0x43,
+	0x48, 0x27, 0x40, 0x42, 0x40, 0x40, 0x40, 0x0f,
+	0x42, 0x4b, 0x4f, 0x0b, 0x51, 0x4b, 0x46, 0x04,
+	0x04, 0x07, 0x07, 0x0a, 0x44, 0x05, 0x49, 0x07,
+	0x57, 0x27, 0x08, 0x12, 0x40, 0x4a, 0x0f, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4c, 0x4f, 0x49, 0x4f,
+	0x51, 0x4b, 0x4c, 0x57, 0x4f, 0x43, 0x4f, 0x57,
+	0x57, 0x51, 0x49, 0x00, 0x03, 0x00, 0x4c, 0x4f,
+	0x49, 0x4f, 0x51, 0x4b, 0x4c, 0x57, 0x4f, 0x43,
+	0x4f, 0x57, 0x57, 0x51, 0x49, 0x00, 0x03, 0x00,
+	0x13, 0x4a, 0x09, 0x40, 0x48, 0x40, 0x42, 0x07,
+	0x42, 0x03, 0x03, 0x46, 0x07, 0x1a, 0x0c, 0x4a,
+	0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07,
+	0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45,
+	0x07, 0x03, 0x03, 0x08, 0x13, 0x08, 0x13, 0x12,
+	0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40,
+	0x40, 0x1f, 0x1f, 0x12, 0x40, 0x0f, 0x12, 0x14,
+	0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0d,
+	0x02, 0x2f, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x14,
+	0x08, 0x12, 0x0e, 0x0b, 0x08, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x43, 0x09, 0x42, 0x54, 0x40, 0x16, 0x43,
+	0x49, 0x27, 0x40, 0x42, 0x40, 0x40, 0x40, 0x0f,
+	0x42, 0x4a, 0x4e, 0x0b, 0x50, 0x4a, 0x44, 0x07,
+	0x07, 0x07, 0x07, 0x0a, 0x44, 0x05, 0x48, 0x07,
+	0x56, 0x27, 0x09, 0x12, 0x40, 0x4a, 0x0e, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4c, 0x4e, 0x48, 0x4e,
+	0x50, 0x4a, 0x4c, 0x56, 0x4e, 0x42, 0x4e, 0x56,
+	0x56, 0x50, 0x48, 0x01, 0x03, 0x01, 0x4c, 0x4e,
+	0x48, 0x4e, 0x50, 0x4a, 0x4c, 0x56, 0x4e, 0x42,
+	0x4e, 0x56, 0x56, 0x50, 0x48, 0x01, 0x03, 0x01,
+	0x13, 0x4a, 0x0b, 0x40, 0x48, 0x40, 0x42, 0x07,
+	0x42, 0x03, 0x03, 0x44, 0x07, 0x1a, 0x0c, 0x4a,
+	0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07,
+	0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45,
+	0x07, 0x03, 0x03, 0x09, 0x13, 0x09, 0x13, 0x12,
+	0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40,
+	0x40, 0x1e, 0x1e, 0x12, 0x40, 0x0f, 0x12, 0x14,
+	0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0d,
+	0x02, 0x2e, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x14,
+	0x09, 0x12, 0x0f, 0x0b, 0x09, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x44, 0x0a, 0x41, 0x53, 0x40, 0x15, 0x44,
+	0x4a, 0x27, 0x40, 0x41, 0x40, 0x40, 0x40, 0x0f,
+	0x41, 0x48, 0x4d, 0x0c, 0x4f, 0x48, 0x42, 0x09,
+	0x09, 0x07, 0x07, 0x09, 0x43, 0x06, 0x47, 0x07,
+	0x55, 0x27, 0x0a, 0x11, 0x40, 0x49, 0x0d, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4b, 0x4d, 0x47, 0x4d,
+	0x4f, 0x48, 0x4b, 0x55, 0x4d, 0x40, 0x4d, 0x55,
+	0x55, 0x4f, 0x47, 0x02, 0x04, 0x02, 0x4b, 0x4d,
+	0x47, 0x4d, 0x4f, 0x48, 0x4b, 0x55, 0x4d, 0x40,
+	0x4d, 0x55, 0x55, 0x4f, 0x47, 0x02, 0x04, 0x02,
+	0x14, 0x49, 0x0d, 0x40, 0x48, 0x40, 0x41, 0x07,
+	0x41, 0x04, 0x04, 0x42, 0x07, 0x19, 0x0b, 0x49,
+	0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07,
+	0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x46,
+	0x07, 0x04, 0x04, 0x0a, 0x14, 0x0a, 0x14, 0x11,
+	0x17, 0x0b, 0x49, 0x17, 0x0b, 0x49, 0x40, 0x40,
+	0x40, 0x1d, 0x1d, 0x11, 0x40, 0x0f, 0x11, 0x13,
+	0x13, 0x26, 0x27, 0x16, 0x07, 0x14, 0x16, 0x0e,
+	0x01, 0x2d, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x13,
+	0x0a, 0x11, 0x10, 0x0c, 0x0a, 0x11, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x45, 0x0b, 0x41, 0x52, 0x40, 0x14, 0x45,
+	0x4b, 0x27, 0x40, 0x41, 0x40, 0x40, 0x40, 0x0f,
+	0x41, 0x47, 0x4c, 0x0d, 0x4d, 0x47, 0x40, 0x0c,
+	0x0c, 0x07, 0x07, 0x09, 0x42, 0x06, 0x45, 0x07,
+	0x54, 0x27, 0x0b, 0x11, 0x40, 0x49, 0x0c, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4a, 0x4c, 0x45, 0x4c,
+	0x4d, 0x47, 0x4a, 0x54, 0x4c, 0x00, 0x4c, 0x54,
+	0x54, 0x4d, 0x45, 0x03, 0x05, 0x03, 0x4a, 0x4c,
+	0x45, 0x4c, 0x4d, 0x47, 0x4a, 0x54, 0x4c, 0x00,
+	0x4c, 0x54, 0x54, 0x4d, 0x45, 0x03, 0x05, 0x03,
+	0x15, 0x49, 0x0f, 0x40, 0x48, 0x40, 0x41, 0x07,
+	0x41, 0x05, 0x05, 0x40, 0x07, 0x19, 0x0a, 0x49,
+	0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07,
+	0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46,
+	0x07, 0x05, 0x05, 0x0b, 0x15, 0x0b, 0x15, 0x11,
+	0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40,
+	0x40, 0x1c, 0x1c, 0x11, 0x40, 0x0f, 0x11, 0x12,
+	0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0e,
+	0x01, 0x2c, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x12,
+	0x0b, 0x11, 0x12, 0x0d, 0x0b, 0x11, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x45, 0x0c, 0x41, 0x52, 0x40, 0x13, 0x45,
+	0x4c, 0x27, 0x40, 0x41, 0x40, 0x40, 0x40, 0x0f,
+	0x41, 0x45, 0x4b, 0x0d, 0x4c, 0x45, 0x01, 0x0e,
+	0x0e, 0x07, 0x07, 0x09, 0x42, 0x06, 0x44, 0x07,
+	0x53, 0x27, 0x0c, 0x11, 0x40, 0x49, 0x0b, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4a, 0x4b, 0x44, 0x4b,
+	0x4c, 0x45, 0x4a, 0x53, 0x4b, 0x02, 0x4b, 0x53,
+	0x53, 0x4c, 0x44, 0x04, 0x05, 0x04, 0x4a, 0x4b,
+	0x44, 0x4b, 0x4c, 0x45, 0x4a, 0x53, 0x4b, 0x02,
+	0x4b, 0x53, 0x53, 0x4c, 0x44, 0x04, 0x05, 0x04,
+	0x15, 0x49, 0x11, 0x40, 0x48, 0x40, 0x41, 0x07,
+	0x41, 0x05, 0x05, 0x01, 0x07, 0x19, 0x0a, 0x49,
+	0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07,
+	0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46,
+	0x07, 0x05, 0x05, 0x0c, 0x15, 0x0c, 0x15, 0x11,
+	0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40,
+	0x40, 0x1b, 0x1b, 0x11, 0x40, 0x0f, 0x11, 0x12,
+	0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0e,
+	0x01, 0x2b, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x12,
+	0x0c, 0x11, 0x13, 0x0d, 0x0c, 0x11, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x46, 0x0d, 0x40, 0x51, 0x40, 0x12, 0x46,
+	0x4d, 0x27, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f,
+	0x40, 0x44, 0x4a, 0x0e, 0x4b, 0x44, 0x03, 0x11,
+	0x11, 0x07, 0x07, 0x08, 0x41, 0x07, 0x43, 0x07,
+	0x52, 0x27, 0x0d, 0x10, 0x40, 0x48, 0x0a, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x49, 0x4a, 0x43, 0x4a,
+	0x4b, 0x44, 0x49, 0x52, 0x4a, 0x03, 0x4a, 0x52,
+	0x52, 0x4b, 0x43, 0x05, 0x06, 0x05, 0x49, 0x4a,
+	0x43, 0x4a, 0x4b, 0x44, 0x49, 0x52, 0x4a, 0x03,
+	0x4a, 0x52, 0x52, 0x4b, 0x43, 0x05, 0x06, 0x05,
+	0x16, 0x48, 0x13, 0x40, 0x48, 0x40, 0x40, 0x07,
+	0x40, 0x06, 0x06, 0x03, 0x07, 0x18, 0x09, 0x48,
+	0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07,
+	0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x47,
+	0x07, 0x06, 0x06, 0x0d, 0x16, 0x0d, 0x16, 0x10,
+	0x17, 0x09, 0x48, 0x17, 0x09, 0x48, 0x40, 0x40,
+	0x40, 0x1a, 0x1a, 0x10, 0x40, 0x0f, 0x10, 0x11,
+	0x11, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0f,
+	0x00, 0x2a, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x11,
+	0x0d, 0x10, 0x14, 0x0e, 0x0d, 0x10, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x47, 0x0e, 0x40, 0x51, 0x40, 0x11, 0x47,
+	0x4e, 0x27, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f,
+	0x40, 0x42, 0x49, 0x0e, 0x4a, 0x42, 0x04, 0x13,
+	0x13, 0x07, 0x07, 0x08, 0x41, 0x07, 0x42, 0x07,
+	0x51, 0x27, 0x0e, 0x10, 0x40, 0x48, 0x09, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x42, 0x49,
+	0x4a, 0x42, 0x49, 0x51, 0x49, 0x05, 0x49, 0x51,
+	0x51, 0x4a, 0x42, 0x06, 0x06, 0x06, 0x49, 0x49,
+	0x42, 0x49, 0x4a, 0x42, 0x49, 0x51, 0x49, 0x05,
+	0x49, 0x51, 0x51, 0x4a, 0x42, 0x06, 0x06, 0x06,
+	0x16, 0x48, 0x14, 0x40, 0x48, 0x40, 0x40, 0x07,
+	0x40, 0x06, 0x06, 0x04, 0x07, 0x18, 0x08, 0x48,
+	0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07,
+	0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47,
+	0x07, 0x06, 0x06, 0x0e, 0x16, 0x0e, 0x16, 0x10,
+	0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40,
+	0x40, 0x19, 0x19, 0x10, 0x40, 0x0f, 0x10, 0x10,
+	0x10, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0f,
+	0x00, 0x29, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x10,
+	0x0e, 0x10, 0x15, 0x0e, 0x0e, 0x10, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x47, 0x0f, 0x40, 0x50, 0x40, 0x10, 0x47,
+	0x4f, 0x27, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f,
+	0x40, 0x40, 0x48, 0x0f, 0x48, 0x40, 0x06, 0x16,
+	0x16, 0x07, 0x07, 0x08, 0x40, 0x07, 0x40, 0x07,
+	0x50, 0x27, 0x0f, 0x10, 0x40, 0x48, 0x08, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x40, 0x48,
+	0x48, 0x40, 0x48, 0x50, 0x48, 0x07, 0x48, 0x50,
+	0x50, 0x48, 0x40, 0x07, 0x07, 0x07, 0x48, 0x48,
+	0x40, 0x48, 0x48, 0x40, 0x48, 0x50, 0x48, 0x07,
+	0x48, 0x50, 0x50, 0x48, 0x40, 0x07, 0x07, 0x07,
+	0x17, 0x48, 0x16, 0x40, 0x48, 0x40, 0x40, 0x07,
+	0x40, 0x07, 0x07, 0x06, 0x07, 0x18, 0x08, 0x48,
+	0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07,
+	0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47,
+	0x07, 0x07, 0x07, 0x0f, 0x17, 0x0f, 0x17, 0x10,
+	0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40,
+	0x40, 0x18, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10,
+	0x10, 0x27, 0x27, 0x17, 0x07, 0x17, 0x17, 0x0f,
+	0x00, 0x28, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x10,
+	0x0f, 0x10, 0x17, 0x0f, 0x0f, 0x10, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x48, 0x10, 0x00, 0x4f, 0x40, 0x0f, 0x48,
+	0x50, 0x27, 0x40, 0x00, 0x40, 0x40, 0x40, 0x0f,
+	0x00, 0x00, 0x47, 0x10, 0x47, 0x00, 0x08, 0x18,
+	0x18, 0x07, 0x07, 0x07, 0x00, 0x08, 0x00, 0x07,
+	0x4f, 0x27, 0x10, 0x0f, 0x40, 0x47, 0x07, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x47, 0x47, 0x00, 0x47,
+	0x47, 0x00, 0x47, 0x4f, 0x47, 0x08, 0x47, 0x4f,
+	0x4f, 0x47, 0x00, 0x08, 0x08, 0x08, 0x47, 0x47,
+	0x00, 0x47, 0x47, 0x00, 0x47, 0x4f, 0x47, 0x08,
+	0x47, 0x4f, 0x4f, 0x47, 0x00, 0x08, 0x08, 0x08,
+	0x18, 0x47, 0x18, 0x40, 0x48, 0x40, 0x00, 0x07,
+	0x00, 0x08, 0x08, 0x08, 0x07, 0x17, 0x07, 0x47,
+	0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07,
+	0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48,
+	0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f,
+	0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40,
+	0x40, 0x17, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10,
+	0x40, 0x27, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0f,
+	0x10, 0x0f, 0x18, 0x10, 0x10, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x48, 0x11, 0x00, 0x4f, 0x40, 0x0e, 0x48,
+	0x51, 0x27, 0x40, 0x00, 0x40, 0x40, 0x40, 0x0f,
+	0x00, 0x02, 0x46, 0x10, 0x46, 0x02, 0x0a, 0x1b,
+	0x1b, 0x07, 0x07, 0x07, 0x00, 0x08, 0x01, 0x07,
+	0x4e, 0x27, 0x11, 0x0f, 0x40, 0x47, 0x06, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x47, 0x46, 0x01, 0x46,
+	0x46, 0x02, 0x47, 0x4e, 0x46, 0x0a, 0x46, 0x4e,
+	0x4e, 0x46, 0x01, 0x09, 0x08, 0x09, 0x47, 0x46,
+	0x01, 0x46, 0x46, 0x02, 0x47, 0x4e, 0x46, 0x0a,
+	0x46, 0x4e, 0x4e, 0x46, 0x01, 0x09, 0x08, 0x09,
+	0x18, 0x47, 0x1a, 0x40, 0x48, 0x40, 0x00, 0x07,
+	0x00, 0x08, 0x08, 0x0a, 0x07, 0x17, 0x07, 0x47,
+	0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07,
+	0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48,
+	0x07, 0x08, 0x08, 0x11, 0x18, 0x11, 0x18, 0x0f,
+	0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40,
+	0x40, 0x16, 0x16, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10,
+	0x40, 0x26, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0f,
+	0x11, 0x0f, 0x19, 0x10, 0x11, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x49, 0x12, 0x00, 0x4e, 0x40, 0x0d, 0x49,
+	0x52, 0x27, 0x40, 0x00, 0x40, 0x40, 0x40, 0x0f,
+	0x00, 0x03, 0x45, 0x11, 0x45, 0x03, 0x0c, 0x1d,
+	0x1d, 0x07, 0x07, 0x07, 0x01, 0x08, 0x02, 0x07,
+	0x4d, 0x27, 0x12, 0x0f, 0x40, 0x47, 0x05, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x46, 0x45, 0x02, 0x45,
+	0x45, 0x03, 0x46, 0x4d, 0x45, 0x0b, 0x45, 0x4d,
+	0x4d, 0x45, 0x02, 0x0a, 0x09, 0x0a, 0x46, 0x45,
+	0x02, 0x45, 0x45, 0x03, 0x46, 0x4d, 0x45, 0x0b,
+	0x45, 0x4d, 0x4d, 0x45, 0x02, 0x0a, 0x09, 0x0a,
+	0x19, 0x47, 0x1c, 0x40, 0x48, 0x40, 0x00, 0x07,
+	0x00, 0x09, 0x09, 0x0c, 0x07, 0x17, 0x06, 0x47,
+	0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07,
+	0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x48,
+	0x07, 0x09, 0x09, 0x12, 0x19, 0x12, 0x19, 0x0f,
+	0x17, 0x06, 0x47, 0x17, 0x06, 0x47, 0x40, 0x40,
+	0x40, 0x15, 0x15, 0x0f, 0x40, 0x0f, 0x0f, 0x0e,
+	0x0e, 0x28, 0x27, 0x18, 0x07, 0x19, 0x18, 0x10,
+	0x40, 0x25, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0e,
+	0x12, 0x0f, 0x1a, 0x11, 0x12, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4a, 0x13, 0x01, 0x4d, 0x40, 0x0c, 0x4a,
+	0x53, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f,
+	0x01, 0x05, 0x44, 0x12, 0x43, 0x05, 0x0e, 0x20,
+	0x20, 0x07, 0x07, 0x06, 0x02, 0x09, 0x04, 0x07,
+	0x4c, 0x27, 0x13, 0x0e, 0x40, 0x46, 0x04, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x45, 0x44, 0x04, 0x44,
+	0x43, 0x05, 0x45, 0x4c, 0x44, 0x0d, 0x44, 0x4c,
+	0x4c, 0x43, 0x04, 0x0b, 0x0a, 0x0b, 0x45, 0x44,
+	0x04, 0x44, 0x43, 0x05, 0x45, 0x4c, 0x44, 0x0d,
+	0x44, 0x4c, 0x4c, 0x43, 0x04, 0x0b, 0x0a, 0x0b,
+	0x1a, 0x46, 0x1e, 0x40, 0x48, 0x40, 0x01, 0x07,
+	0x01, 0x0a, 0x0a, 0x0e, 0x07, 0x16, 0x05, 0x46,
+	0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07,
+	0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49,
+	0x07, 0x0a, 0x0a, 0x13, 0x1a, 0x13, 0x1a, 0x0e,
+	0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40,
+	0x40, 0x14, 0x14, 0x0e, 0x40, 0x0f, 0x0e, 0x0d,
+	0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x11,
+	0x41, 0x24, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0d,
+	0x13, 0x0e, 0x1c, 0x12, 0x13, 0x0e, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4a, 0x14, 0x01, 0x4d, 0x40, 0x0b, 0x4a,
+	0x54, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f,
+	0x01, 0x06, 0x43, 0x12, 0x42, 0x06, 0x10, 0x22,
+	0x22, 0x07, 0x07, 0x06, 0x02, 0x09, 0x05, 0x07,
+	0x4b, 0x27, 0x14, 0x0e, 0x40, 0x46, 0x03, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x45, 0x43, 0x05, 0x43,
+	0x42, 0x06, 0x45, 0x4b, 0x43, 0x0e, 0x43, 0x4b,
+	0x4b, 0x42, 0x05, 0x0c, 0x0a, 0x0c, 0x45, 0x43,
+	0x05, 0x43, 0x42, 0x06, 0x45, 0x4b, 0x43, 0x0e,
+	0x43, 0x4b, 0x4b, 0x42, 0x05, 0x0c, 0x0a, 0x0c,
+	0x1a, 0x46, 0x20, 0x40, 0x48, 0x40, 0x01, 0x07,
+	0x01, 0x0a, 0x0a, 0x10, 0x07, 0x16, 0x05, 0x46,
+	0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07,
+	0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49,
+	0x07, 0x0a, 0x0a, 0x14, 0x1a, 0x14, 0x1a, 0x0e,
+	0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40,
+	0x40, 0x13, 0x13, 0x0e, 0x40, 0x0f, 0x0e, 0x0d,
+	0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x11,
+	0x41, 0x23, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0d,
+	0x14, 0x0e, 0x1d, 0x12, 0x14, 0x0e, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4b, 0x15, 0x01, 0x4c, 0x40, 0x0a, 0x4b,
+	0x55, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f,
+	0x01, 0x08, 0x42, 0x13, 0x41, 0x08, 0x12, 0x25,
+	0x25, 0x07, 0x07, 0x06, 0x03, 0x09, 0x06, 0x07,
+	0x4a, 0x27, 0x15, 0x0e, 0x40, 0x46, 0x02, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x06, 0x42,
+	0x41, 0x08, 0x44, 0x4a, 0x42, 0x10, 0x42, 0x4a,
+	0x4a, 0x41, 0x06, 0x0d, 0x0b, 0x0d, 0x44, 0x42,
+	0x06, 0x42, 0x41, 0x08, 0x44, 0x4a, 0x42, 0x10,
+	0x42, 0x4a, 0x4a, 0x41, 0x06, 0x0d, 0x0b, 0x0d,
+	0x1b, 0x46, 0x22, 0x40, 0x48, 0x40, 0x01, 0x07,
+	0x01, 0x0b, 0x0b, 0x12, 0x07, 0x16, 0x04, 0x46,
+	0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07,
+	0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x49,
+	0x07, 0x0b, 0x0b, 0x15, 0x1b, 0x15, 0x1b, 0x0e,
+	0x17, 0x04, 0x46, 0x17, 0x04, 0x46, 0x40, 0x40,
+	0x40, 0x12, 0x12, 0x0e, 0x40, 0x0f, 0x0e, 0x0c,
+	0x0c, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x11,
+	0x41, 0x22, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0c,
+	0x15, 0x0e, 0x1e, 0x13, 0x15, 0x0e, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4c, 0x15, 0x01, 0x4c, 0x40, 0x09, 0x4c,
+	0x56, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f,
+	0x01, 0x09, 0x42, 0x13, 0x40, 0x09, 0x13, 0x27,
+	0x27, 0x07, 0x07, 0x05, 0x03, 0x09, 0x07, 0x07,
+	0x4a, 0x27, 0x15, 0x0d, 0x40, 0x46, 0x01, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x07, 0x42,
+	0x40, 0x09, 0x44, 0x4a, 0x42, 0x11, 0x42, 0x4a,
+	0x4a, 0x40, 0x07, 0x0d, 0x0b, 0x0d, 0x44, 0x42,
+	0x07, 0x42, 0x40, 0x09, 0x44, 0x4a, 0x42, 0x11,
+	0x42, 0x4a, 0x4a, 0x40, 0x07, 0x0d, 0x0b, 0x0d,
+	0x1b, 0x46, 0x23, 0x40, 0x48, 0x40, 0x01, 0x07,
+	0x01, 0x0b, 0x0b, 0x13, 0x07, 0x15, 0x03, 0x46,
+	0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07,
+	0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x4a,
+	0x07, 0x0b, 0x0b, 0x15, 0x1b, 0x15, 0x1b, 0x0d,
+	0x17, 0x03, 0x46, 0x17, 0x03, 0x46, 0x40, 0x40,
+	0x40, 0x11, 0x11, 0x0d, 0x40, 0x0f, 0x0d, 0x0b,
+	0x0b, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x11,
+	0x42, 0x21, 0x15, 0x0d, 0x40, 0x0d, 0x11, 0x0b,
+	0x15, 0x0d, 0x1f, 0x13, 0x15, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4c, 0x16, 0x02, 0x4b, 0x40, 0x09, 0x4c,
+	0x56, 0x27, 0x40, 0x02, 0x40, 0x40, 0x40, 0x0f,
+	0x02, 0x0b, 0x41, 0x14, 0x01, 0x0b, 0x15, 0x2a,
+	0x2a, 0x07, 0x07, 0x05, 0x04, 0x0a, 0x09, 0x07,
+	0x49, 0x27, 0x16, 0x0d, 0x40, 0x45, 0x01, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x43, 0x41, 0x09, 0x41,
+	0x01, 0x0b, 0x43, 0x49, 0x41, 0x13, 0x41, 0x49,
+	0x49, 0x01, 0x09, 0x0e, 0x0c, 0x0e, 0x43, 0x41,
+	0x09, 0x41, 0x01, 0x0b, 0x43, 0x49, 0x41, 0x13,
+	0x41, 0x49, 0x49, 0x01, 0x09, 0x0e, 0x0c, 0x0e,
+	0x1c, 0x45, 0x25, 0x40, 0x48, 0x40, 0x02, 0x07,
+	0x02, 0x0c, 0x0c, 0x15, 0x07, 0x15, 0x03, 0x45,
+	0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07,
+	0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x4a,
+	0x07, 0x0c, 0x0c, 0x16, 0x1c, 0x16, 0x1c, 0x0d,
+	0x17, 0x03, 0x45, 0x17, 0x03, 0x45, 0x40, 0x40,
+	0x40, 0x11, 0x11, 0x0d, 0x40, 0x0f, 0x0d, 0x0b,
+	0x0b, 0x2a, 0x27, 0x1a, 0x07, 0x1c, 0x1a, 0x12,
+	0x42, 0x21, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0b,
+	0x16, 0x0d, 0x21, 0x14, 0x16, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4d, 0x17, 0x02, 0x4a, 0x40, 0x08, 0x4d,
+	0x57, 0x27, 0x40, 0x02, 0x40, 0x40, 0x40, 0x0f,
+	0x02, 0x0d, 0x40, 0x15, 0x02, 0x0d, 0x17, 0x2c,
+	0x2c, 0x07, 0x07, 0x05, 0x05, 0x0a, 0x0a, 0x07,
+	0x48, 0x27, 0x17, 0x0d, 0x40, 0x45, 0x00, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x42, 0x40, 0x0a, 0x40,
+	0x02, 0x0d, 0x42, 0x48, 0x40, 0x15, 0x40, 0x48,
+	0x48, 0x02, 0x0a, 0x0f, 0x0d, 0x0f, 0x42, 0x40,
+	0x0a, 0x40, 0x02, 0x0d, 0x42, 0x48, 0x40, 0x15,
+	0x40, 0x48, 0x48, 0x02, 0x0a, 0x0f, 0x0d, 0x0f,
+	0x1d, 0x45, 0x27, 0x40, 0x48, 0x40, 0x02, 0x07,
+	0x02, 0x0d, 0x0d, 0x17, 0x07, 0x15, 0x02, 0x45,
+	0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07,
+	0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a,
+	0x07, 0x0d, 0x0d, 0x17, 0x1d, 0x17, 0x1d, 0x0d,
+	0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40,
+	0x40, 0x10, 0x10, 0x0d, 0x40, 0x0f, 0x0d, 0x0a,
+	0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x12,
+	0x42, 0x20, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0a,
+	0x17, 0x0d, 0x22, 0x15, 0x17, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4d, 0x18, 0x02, 0x4a, 0x40, 0x07, 0x4d,
+	0x58, 0x27, 0x40, 0x02, 0x40, 0x40, 0x40, 0x0f,
+	0x02, 0x0e, 0x00, 0x15, 0x03, 0x0e, 0x19, 0x2f,
+	0x2f, 0x07, 0x07, 0x05, 0x05, 0x0a, 0x0b, 0x07,
+	0x47, 0x27, 0x18, 0x0d, 0x40, 0x45, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x42, 0x00, 0x0b, 0x00,
+	0x03, 0x0e, 0x42, 0x47, 0x00, 0x16, 0x00, 0x47,
+	0x47, 0x03, 0x0b, 0x10, 0x0d, 0x10, 0x42, 0x00,
+	0x0b, 0x00, 0x03, 0x0e, 0x42, 0x47, 0x00, 0x16,
+	0x00, 0x47, 0x47, 0x03, 0x0b, 0x10, 0x0d, 0x10,
+	0x1d, 0x45, 0x29, 0x40, 0x48, 0x40, 0x02, 0x07,
+	0x02, 0x0d, 0x0d, 0x19, 0x07, 0x15, 0x02, 0x45,
+	0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07,
+	0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a,
+	0x07, 0x0d, 0x0d, 0x18, 0x1d, 0x18, 0x1d, 0x0d,
+	0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40,
+	0x40, 0x0f, 0x0f, 0x0d, 0x40, 0x0f, 0x0d, 0x0a,
+	0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x12,
+	0x42, 0x1f, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0a,
+	0x18, 0x0d, 0x23, 0x15, 0x18, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4e, 0x19, 0x03, 0x49, 0x40, 0x06, 0x4e,
+	0x59, 0x27, 0x40, 0x03, 0x40, 0x40, 0x40, 0x0f,
+	0x03, 0x10, 0x01, 0x16, 0x04, 0x10, 0x1b, 0x31,
+	0x31, 0x07, 0x07, 0x04, 0x06, 0x0b, 0x0c, 0x07,
+	0x46, 0x27, 0x19, 0x0c, 0x40, 0x44, 0x41, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x41, 0x01, 0x0c, 0x01,
+	0x04, 0x10, 0x41, 0x46, 0x01, 0x18, 0x01, 0x46,
+	0x46, 0x04, 0x0c, 0x11, 0x0e, 0x11, 0x41, 0x01,
+	0x0c, 0x01, 0x04, 0x10, 0x41, 0x46, 0x01, 0x18,
+	0x01, 0x46, 0x46, 0x04, 0x0c, 0x11, 0x0e, 0x11,
+	0x1e, 0x44, 0x2b, 0x40, 0x48, 0x40, 0x03, 0x07,
+	0x03, 0x0e, 0x0e, 0x1b, 0x07, 0x14, 0x01, 0x44,
+	0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07,
+	0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x4b,
+	0x07, 0x0e, 0x0e, 0x19, 0x1e, 0x19, 0x1e, 0x0c,
+	0x17, 0x01, 0x44, 0x17, 0x01, 0x44, 0x40, 0x40,
+	0x40, 0x0e, 0x0e, 0x0c, 0x40, 0x0f, 0x0c, 0x09,
+	0x09, 0x2b, 0x27, 0x1b, 0x07, 0x1e, 0x1b, 0x13,
+	0x43, 0x1e, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x09,
+	0x19, 0x0c, 0x24, 0x16, 0x19, 0x0c, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4f, 0x1a, 0x03, 0x48, 0x40, 0x05, 0x4f,
+	0x5a, 0x27, 0x40, 0x03, 0x40, 0x40, 0x40, 0x0f,
+	0x03, 0x11, 0x02, 0x17, 0x06, 0x11, 0x1d, 0x34,
+	0x34, 0x07, 0x07, 0x04, 0x07, 0x0b, 0x0e, 0x07,
+	0x45, 0x27, 0x1a, 0x0c, 0x40, 0x44, 0x42, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x40, 0x02, 0x0e, 0x02,
+	0x06, 0x11, 0x40, 0x45, 0x02, 0x19, 0x02, 0x45,
+	0x45, 0x06, 0x0e, 0x12, 0x0f, 0x12, 0x40, 0x02,
+	0x0e, 0x02, 0x06, 0x11, 0x40, 0x45, 0x02, 0x19,
+	0x02, 0x45, 0x45, 0x06, 0x0e, 0x12, 0x0f, 0x12,
+	0x1f, 0x44, 0x2d, 0x40, 0x48, 0x40, 0x03, 0x07,
+	0x03, 0x0f, 0x0f, 0x1d, 0x07, 0x14, 0x00, 0x44,
+	0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07,
+	0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b,
+	0x07, 0x0f, 0x0f, 0x1a, 0x1f, 0x1a, 0x1f, 0x0c,
+	0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40,
+	0x40, 0x0d, 0x0d, 0x0c, 0x40, 0x0f, 0x0c, 0x08,
+	0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x13,
+	0x43, 0x1d, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x08,
+	0x1a, 0x0c, 0x26, 0x17, 0x1a, 0x0c, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x4f, 0x1b, 0x03, 0x48, 0x40, 0x04, 0x4f,
+	0x5b, 0x27, 0x40, 0x03, 0x40, 0x40, 0x40, 0x0f,
+	0x03, 0x13, 0x03, 0x17, 0x07, 0x13, 0x1f, 0x36,
+	0x36, 0x07, 0x07, 0x04, 0x07, 0x0b, 0x0f, 0x07,
+	0x44, 0x27, 0x1b, 0x0c, 0x40, 0x44, 0x43, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x40, 0x03, 0x0f, 0x03,
+	0x07, 0x13, 0x40, 0x44, 0x03, 0x1b, 0x03, 0x44,
+	0x44, 0x07, 0x0f, 0x13, 0x0f, 0x13, 0x40, 0x03,
+	0x0f, 0x03, 0x07, 0x13, 0x40, 0x44, 0x03, 0x1b,
+	0x03, 0x44, 0x44, 0x07, 0x0f, 0x13, 0x0f, 0x13,
+	0x1f, 0x44, 0x2f, 0x40, 0x48, 0x40, 0x03, 0x07,
+	0x03, 0x0f, 0x0f, 0x1f, 0x07, 0x14, 0x00, 0x44,
+	0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07,
+	0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b,
+	0x07, 0x0f, 0x0f, 0x1b, 0x1f, 0x1b, 0x1f, 0x0c,
+	0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40,
+	0x40, 0x0c, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08,
+	0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x13,
+	0x43, 0x1c, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x08,
+	0x1b, 0x0c, 0x27, 0x17, 0x1b, 0x0c, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x50, 0x1c, 0x04, 0x47, 0x40, 0x03, 0x50,
+	0x5c, 0x27, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f,
+	0x04, 0x14, 0x04, 0x18, 0x08, 0x14, 0x21, 0x39,
+	0x39, 0x07, 0x07, 0x03, 0x08, 0x0c, 0x10, 0x07,
+	0x43, 0x27, 0x1c, 0x0b, 0x40, 0x43, 0x44, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x00, 0x04, 0x10, 0x04,
+	0x08, 0x14, 0x00, 0x43, 0x04, 0x1c, 0x04, 0x43,
+	0x43, 0x08, 0x10, 0x14, 0x10, 0x14, 0x00, 0x04,
+	0x10, 0x04, 0x08, 0x14, 0x00, 0x43, 0x04, 0x1c,
+	0x04, 0x43, 0x43, 0x08, 0x10, 0x14, 0x10, 0x14,
+	0x20, 0x43, 0x31, 0x40, 0x48, 0x40, 0x04, 0x07,
+	0x04, 0x10, 0x10, 0x21, 0x07, 0x13, 0x40, 0x43,
+	0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07,
+	0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x4c,
+	0x07, 0x10, 0x10, 0x1c, 0x20, 0x1c, 0x20, 0x0b,
+	0x17, 0x40, 0x43, 0x17, 0x40, 0x43, 0x40, 0x40,
+	0x40, 0x0b, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x07,
+	0x07, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x14,
+	0x44, 0x1b, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x07,
+	0x1c, 0x0b, 0x28, 0x18, 0x1c, 0x0b, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x51, 0x1d, 0x04, 0x47, 0x40, 0x02, 0x51,
+	0x5d, 0x27, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f,
+	0x04, 0x16, 0x05, 0x18, 0x09, 0x16, 0x22, 0x3b,
+	0x3b, 0x07, 0x07, 0x03, 0x08, 0x0c, 0x11, 0x07,
+	0x42, 0x27, 0x1d, 0x0b, 0x40, 0x43, 0x45, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x00, 0x05, 0x11, 0x05,
+	0x09, 0x16, 0x00, 0x42, 0x05, 0x1e, 0x05, 0x42,
+	0x42, 0x09, 0x11, 0x15, 0x10, 0x15, 0x00, 0x05,
+	0x11, 0x05, 0x09, 0x16, 0x00, 0x42, 0x05, 0x1e,
+	0x05, 0x42, 0x42, 0x09, 0x11, 0x15, 0x10, 0x15,
+	0x20, 0x43, 0x32, 0x40, 0x48, 0x40, 0x04, 0x07,
+	0x04, 0x10, 0x10, 0x22, 0x07, 0x13, 0x41, 0x43,
+	0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07,
+	0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c,
+	0x07, 0x10, 0x10, 0x1d, 0x20, 0x1d, 0x20, 0x0b,
+	0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40,
+	0x40, 0x0a, 0x0a, 0x0b, 0x40, 0x0f, 0x0b, 0x06,
+	0x06, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x14,
+	0x44, 0x1a, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x06,
+	0x1d, 0x0b, 0x29, 0x18, 0x1d, 0x0b, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x51, 0x1e, 0x04, 0x46, 0x40, 0x01, 0x51,
+	0x5e, 0x27, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f,
+	0x04, 0x18, 0x06, 0x19, 0x0b, 0x18, 0x24, 0x3e,
+	0x3e, 0x07, 0x07, 0x03, 0x09, 0x0c, 0x13, 0x07,
+	0x41, 0x27, 0x1e, 0x0b, 0x40, 0x43, 0x46, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x01, 0x06, 0x13, 0x06,
+	0x0b, 0x18, 0x01, 0x41, 0x06, 0x20, 0x06, 0x41,
+	0x41, 0x0b, 0x13, 0x16, 0x11, 0x16, 0x01, 0x06,
+	0x13, 0x06, 0x0b, 0x18, 0x01, 0x41, 0x06, 0x20,
+	0x06, 0x41, 0x41, 0x0b, 0x13, 0x16, 0x11, 0x16,
+	0x21, 0x43, 0x34, 0x40, 0x48, 0x40, 0x04, 0x07,
+	0x04, 0x11, 0x11, 0x24, 0x07, 0x13, 0x41, 0x43,
+	0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07,
+	0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c,
+	0x07, 0x11, 0x11, 0x1e, 0x21, 0x1e, 0x21, 0x0b,
+	0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40,
+	0x40, 0x09, 0x09, 0x0b, 0x40, 0x0f, 0x0b, 0x06,
+	0x06, 0x2c, 0x27, 0x1c, 0x07, 0x21, 0x1c, 0x14,
+	0x44, 0x19, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x06,
+	0x1e, 0x0b, 0x2b, 0x19, 0x1e, 0x0b, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x52, 0x1f, 0x05, 0x45, 0x40, 0x00, 0x52,
+	0x5f, 0x27, 0x40, 0x05, 0x40, 0x40, 0x40, 0x0f,
+	0x05, 0x19, 0x07, 0x1a, 0x0c, 0x19, 0x26, 0x3e,
+	0x3e, 0x07, 0x07, 0x02, 0x0a, 0x0d, 0x14, 0x07,
+	0x40, 0x27, 0x1f, 0x0a, 0x40, 0x42, 0x47, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x02, 0x07, 0x14, 0x07,
+	0x0c, 0x19, 0x02, 0x40, 0x07, 0x21, 0x07, 0x40,
+	0x40, 0x0c, 0x14, 0x17, 0x12, 0x17, 0x02, 0x07,
+	0x14, 0x07, 0x0c, 0x19, 0x02, 0x40, 0x07, 0x21,
+	0x07, 0x40, 0x40, 0x0c, 0x14, 0x17, 0x12, 0x17,
+	0x22, 0x42, 0x36, 0x40, 0x48, 0x40, 0x05, 0x07,
+	0x05, 0x12, 0x12, 0x26, 0x07, 0x12, 0x42, 0x42,
+	0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07,
+	0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d,
+	0x07, 0x12, 0x12, 0x1f, 0x22, 0x1f, 0x22, 0x0a,
+	0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40,
+	0x40, 0x08, 0x08, 0x0a, 0x40, 0x0f, 0x0a, 0x05,
+	0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x15,
+	0x45, 0x18, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x05,
+	0x1f, 0x0a, 0x2c, 0x1a, 0x1f, 0x0a, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x52, 0x20, 0x05, 0x45, 0x40, 0x40, 0x52,
+	0x60, 0x27, 0x40, 0x05, 0x40, 0x40, 0x40, 0x0f,
+	0x05, 0x1b, 0x08, 0x1a, 0x0d, 0x1b, 0x28, 0x3e,
+	0x3e, 0x07, 0x07, 0x02, 0x0a, 0x0d, 0x15, 0x07,
+	0x00, 0x27, 0x20, 0x0a, 0x40, 0x42, 0x48, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x02, 0x08, 0x15, 0x08,
+	0x0d, 0x1b, 0x02, 0x00, 0x08, 0x23, 0x08, 0x00,
+	0x00, 0x0d, 0x15, 0x18, 0x12, 0x18, 0x02, 0x08,
+	0x15, 0x08, 0x0d, 0x1b, 0x02, 0x00, 0x08, 0x23,
+	0x08, 0x00, 0x00, 0x0d, 0x15, 0x18, 0x12, 0x18,
+	0x22, 0x42, 0x38, 0x40, 0x48, 0x40, 0x05, 0x07,
+	0x05, 0x12, 0x12, 0x28, 0x07, 0x12, 0x42, 0x42,
+	0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07,
+	0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d,
+	0x07, 0x12, 0x12, 0x20, 0x22, 0x20, 0x22, 0x0a,
+	0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40,
+	0x40, 0x07, 0x07, 0x0a, 0x40, 0x0f, 0x0a, 0x05,
+	0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x15,
+	0x45, 0x17, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x05,
+	0x20, 0x0a, 0x2d, 0x1a, 0x20, 0x0a, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x53, 0x21, 0x05, 0x44, 0x40, 0x41, 0x53,
+	0x61, 0x27, 0x40, 0x05, 0x40, 0x40, 0x40, 0x0f,
+	0x05, 0x1c, 0x09, 0x1b, 0x0e, 0x1c, 0x2a, 0x3e,
+	0x3e, 0x07, 0x07, 0x02, 0x0b, 0x0d, 0x16, 0x07,
+	0x01, 0x27, 0x21, 0x0a, 0x40, 0x42, 0x49, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x03, 0x09, 0x16, 0x09,
+	0x0e, 0x1c, 0x03, 0x01, 0x09, 0x24, 0x09, 0x01,
+	0x01, 0x0e, 0x16, 0x19, 0x13, 0x19, 0x03, 0x09,
+	0x16, 0x09, 0x0e, 0x1c, 0x03, 0x01, 0x09, 0x24,
+	0x09, 0x01, 0x01, 0x0e, 0x16, 0x19, 0x13, 0x19,
+	0x23, 0x42, 0x3a, 0x40, 0x48, 0x40, 0x05, 0x07,
+	0x05, 0x13, 0x13, 0x2a, 0x07, 0x12, 0x43, 0x42,
+	0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07,
+	0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x4d,
+	0x07, 0x13, 0x13, 0x21, 0x23, 0x21, 0x23, 0x0a,
+	0x17, 0x43, 0x42, 0x17, 0x43, 0x42, 0x40, 0x40,
+	0x40, 0x06, 0x06, 0x0a, 0x40, 0x0f, 0x0a, 0x04,
+	0x04, 0x2d, 0x27, 0x1d, 0x07, 0x23, 0x1d, 0x15,
+	0x45, 0x16, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x04,
+	0x21, 0x0a, 0x2e, 0x1b, 0x21, 0x0a, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x54, 0x22, 0x06, 0x43, 0x40, 0x42, 0x54,
+	0x62, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f,
+	0x06, 0x1e, 0x0a, 0x1c, 0x10, 0x1e, 0x2c, 0x3e,
+	0x3e, 0x07, 0x07, 0x01, 0x0c, 0x0e, 0x18, 0x07,
+	0x02, 0x27, 0x22, 0x09, 0x40, 0x41, 0x4a, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x04, 0x0a, 0x18, 0x0a,
+	0x10, 0x1e, 0x04, 0x02, 0x0a, 0x26, 0x0a, 0x02,
+	0x02, 0x10, 0x18, 0x1a, 0x14, 0x1a, 0x04, 0x0a,
+	0x18, 0x0a, 0x10, 0x1e, 0x04, 0x02, 0x0a, 0x26,
+	0x0a, 0x02, 0x02, 0x10, 0x18, 0x1a, 0x14, 0x1a,
+	0x24, 0x41, 0x3c, 0x40, 0x48, 0x40, 0x06, 0x07,
+	0x06, 0x14, 0x14, 0x2c, 0x07, 0x11, 0x44, 0x41,
+	0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07,
+	0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e,
+	0x07, 0x14, 0x14, 0x22, 0x24, 0x22, 0x24, 0x09,
+	0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40,
+	0x40, 0x05, 0x05, 0x09, 0x40, 0x0f, 0x09, 0x03,
+	0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x16,
+	0x46, 0x15, 0x11, 0x09, 0x40, 0x09, 0x16, 0x03,
+	0x22, 0x09, 0x30, 0x1c, 0x22, 0x09, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x54, 0x23, 0x06, 0x43, 0x40, 0x43, 0x54,
+	0x63, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f,
+	0x06, 0x1f, 0x0b, 0x1c, 0x11, 0x1f, 0x2e, 0x3e,
+	0x3e, 0x07, 0x07, 0x01, 0x0c, 0x0e, 0x19, 0x07,
+	0x03, 0x27, 0x23, 0x09, 0x40, 0x41, 0x4b, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x04, 0x0b, 0x19, 0x0b,
+	0x11, 0x1f, 0x04, 0x03, 0x0b, 0x27, 0x0b, 0x03,
+	0x03, 0x11, 0x19, 0x1b, 0x14, 0x1b, 0x04, 0x0b,
+	0x19, 0x0b, 0x11, 0x1f, 0x04, 0x03, 0x0b, 0x27,
+	0x0b, 0x03, 0x03, 0x11, 0x19, 0x1b, 0x14, 0x1b,
+	0x24, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07,
+	0x06, 0x14, 0x14, 0x2e, 0x07, 0x11, 0x44, 0x41,
+	0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07,
+	0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e,
+	0x07, 0x14, 0x14, 0x23, 0x24, 0x23, 0x24, 0x09,
+	0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40,
+	0x40, 0x04, 0x04, 0x09, 0x40, 0x0f, 0x09, 0x03,
+	0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x16,
+	0x46, 0x14, 0x11, 0x09, 0x40, 0x09, 0x16, 0x03,
+	0x23, 0x09, 0x31, 0x1c, 0x23, 0x09, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x55, 0x24, 0x06, 0x42, 0x40, 0x44, 0x55,
+	0x64, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f,
+	0x06, 0x21, 0x0c, 0x1d, 0x12, 0x21, 0x30, 0x3e,
+	0x3e, 0x07, 0x07, 0x01, 0x0d, 0x0e, 0x1a, 0x07,
+	0x04, 0x27, 0x24, 0x09, 0x40, 0x41, 0x4c, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x1a, 0x0c,
+	0x12, 0x21, 0x05, 0x04, 0x0c, 0x29, 0x0c, 0x04,
+	0x04, 0x12, 0x1a, 0x1c, 0x15, 0x1c, 0x05, 0x0c,
+	0x1a, 0x0c, 0x12, 0x21, 0x05, 0x04, 0x0c, 0x29,
+	0x0c, 0x04, 0x04, 0x12, 0x1a, 0x1c, 0x15, 0x1c,
+	0x25, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07,
+	0x06, 0x15, 0x15, 0x30, 0x07, 0x11, 0x45, 0x41,
+	0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07,
+	0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x4e,
+	0x07, 0x15, 0x15, 0x24, 0x25, 0x24, 0x25, 0x09,
+	0x17, 0x45, 0x41, 0x17, 0x45, 0x41, 0x40, 0x40,
+	0x40, 0x03, 0x03, 0x09, 0x40, 0x0f, 0x09, 0x02,
+	0x02, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x16,
+	0x46, 0x13, 0x11, 0x09, 0x40, 0x09, 0x16, 0x02,
+	0x24, 0x09, 0x32, 0x1d, 0x24, 0x09, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x56, 0x24, 0x06, 0x42, 0x40, 0x45, 0x56,
+	0x65, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f,
+	0x06, 0x22, 0x0c, 0x1d, 0x13, 0x22, 0x31, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x0d, 0x0e, 0x1b, 0x07,
+	0x04, 0x27, 0x24, 0x08, 0x40, 0x41, 0x4d, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x1b, 0x0c,
+	0x13, 0x22, 0x05, 0x04, 0x0c, 0x2a, 0x0c, 0x04,
+	0x04, 0x13, 0x1b, 0x1c, 0x15, 0x1c, 0x05, 0x0c,
+	0x1b, 0x0c, 0x13, 0x22, 0x05, 0x04, 0x0c, 0x2a,
+	0x0c, 0x04, 0x04, 0x13, 0x1b, 0x1c, 0x15, 0x1c,
+	0x25, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07,
+	0x06, 0x15, 0x15, 0x31, 0x07, 0x10, 0x46, 0x41,
+	0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07,
+	0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x4f,
+	0x07, 0x15, 0x15, 0x24, 0x25, 0x24, 0x25, 0x08,
+	0x17, 0x46, 0x41, 0x17, 0x46, 0x41, 0x40, 0x40,
+	0x40, 0x02, 0x02, 0x08, 0x40, 0x0f, 0x08, 0x01,
+	0x01, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x16,
+	0x47, 0x12, 0x10, 0x08, 0x40, 0x08, 0x16, 0x01,
+	0x24, 0x08, 0x33, 0x1d, 0x24, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x56, 0x25, 0x07, 0x41, 0x40, 0x45, 0x56,
+	0x65, 0x27, 0x40, 0x07, 0x40, 0x40, 0x40, 0x0f,
+	0x07, 0x24, 0x0d, 0x1e, 0x15, 0x24, 0x33, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x0e, 0x0f, 0x1d, 0x07,
+	0x05, 0x27, 0x25, 0x08, 0x40, 0x40, 0x4d, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x06, 0x0d, 0x1d, 0x0d,
+	0x15, 0x24, 0x06, 0x05, 0x0d, 0x2c, 0x0d, 0x05,
+	0x05, 0x15, 0x1d, 0x1d, 0x16, 0x1d, 0x06, 0x0d,
+	0x1d, 0x0d, 0x15, 0x24, 0x06, 0x05, 0x0d, 0x2c,
+	0x0d, 0x05, 0x05, 0x15, 0x1d, 0x1d, 0x16, 0x1d,
+	0x26, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07,
+	0x07, 0x16, 0x16, 0x33, 0x07, 0x10, 0x46, 0x40,
+	0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07,
+	0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x4f,
+	0x07, 0x16, 0x16, 0x25, 0x26, 0x25, 0x26, 0x08,
+	0x17, 0x46, 0x40, 0x17, 0x46, 0x40, 0x40, 0x40,
+	0x40, 0x02, 0x02, 0x08, 0x40, 0x0f, 0x08, 0x01,
+	0x01, 0x2f, 0x27, 0x1f, 0x07, 0x26, 0x1f, 0x17,
+	0x47, 0x12, 0x10, 0x08, 0x40, 0x08, 0x17, 0x01,
+	0x25, 0x08, 0x35, 0x1e, 0x25, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x57, 0x26, 0x07, 0x40, 0x40, 0x46, 0x57,
+	0x66, 0x27, 0x40, 0x07, 0x40, 0x40, 0x40, 0x0f,
+	0x07, 0x26, 0x0e, 0x1f, 0x16, 0x26, 0x35, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x0f, 0x0f, 0x1e, 0x07,
+	0x06, 0x27, 0x26, 0x08, 0x40, 0x40, 0x4e, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x07, 0x0e, 0x1e, 0x0e,
+	0x16, 0x26, 0x07, 0x06, 0x0e, 0x2e, 0x0e, 0x06,
+	0x06, 0x16, 0x1e, 0x1e, 0x17, 0x1e, 0x07, 0x0e,
+	0x1e, 0x0e, 0x16, 0x26, 0x07, 0x06, 0x0e, 0x2e,
+	0x0e, 0x06, 0x06, 0x16, 0x1e, 0x1e, 0x17, 0x1e,
+	0x27, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07,
+	0x07, 0x17, 0x17, 0x35, 0x07, 0x10, 0x47, 0x40,
+	0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07,
+	0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f,
+	0x07, 0x17, 0x17, 0x26, 0x27, 0x26, 0x27, 0x08,
+	0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40,
+	0x40, 0x01, 0x01, 0x08, 0x40, 0x0f, 0x08, 0x00,
+	0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x17,
+	0x47, 0x11, 0x10, 0x08, 0x40, 0x08, 0x17, 0x00,
+	0x26, 0x08, 0x36, 0x1f, 0x26, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x57, 0x27, 0x07, 0x40, 0x40, 0x47, 0x57,
+	0x67, 0x27, 0x40, 0x07, 0x40, 0x40, 0x40, 0x0f,
+	0x07, 0x27, 0x0f, 0x1f, 0x17, 0x27, 0x37, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x0f, 0x0f, 0x1f, 0x07,
+	0x07, 0x27, 0x27, 0x08, 0x40, 0x40, 0x4f, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x07, 0x0f, 0x1f, 0x0f,
+	0x17, 0x27, 0x07, 0x07, 0x0f, 0x2f, 0x0f, 0x07,
+	0x07, 0x17, 0x1f, 0x1f, 0x17, 0x1f, 0x07, 0x0f,
+	0x1f, 0x0f, 0x17, 0x27, 0x07, 0x07, 0x0f, 0x2f,
+	0x0f, 0x07, 0x07, 0x17, 0x1f, 0x1f, 0x17, 0x1f,
+	0x27, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07,
+	0x07, 0x17, 0x17, 0x37, 0x07, 0x10, 0x47, 0x40,
+	0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07,
+	0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f,
+	0x07, 0x17, 0x17, 0x27, 0x27, 0x27, 0x27, 0x08,
+	0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40,
+	0x40, 0x00, 0x00, 0x08, 0x40, 0x0f, 0x08, 0x00,
+	0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x17,
+	0x47, 0x10, 0x10, 0x08, 0x40, 0x08, 0x17, 0x00,
+	0x27, 0x08, 0x37, 0x1f, 0x27, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x48, 0x48, 0x60, 0x40, 0x27, 0x07,
+	0x07, 0x1f, 0x40, 0x48, 0x40, 0x40, 0x17, 0x0f,
+	0x48, 0x68, 0x40, 0x07, 0x68, 0x68, 0x68, 0x68,
+	0x68, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x40, 0x07,
+	0x68, 0x27, 0x50, 0x17, 0x40, 0x07, 0x1f, 0x40,
+	0x40, 0x40, 0x48, 0x48, 0x58, 0x60, 0x50, 0x60,
+	0x68, 0x60, 0x58, 0x68, 0x68, 0x68, 0x58, 0x60,
+	0x68, 0x68, 0x68, 0x50, 0x48, 0x58, 0x58, 0x60,
+	0x50, 0x60, 0x68, 0x60, 0x58, 0x68, 0x68, 0x68,
+	0x58, 0x60, 0x68, 0x68, 0x68, 0x50, 0x48, 0x58,
+	0x07, 0x50, 0x58, 0x40, 0x40, 0x40, 0x48, 0x07,
+	0x48, 0x48, 0x48, 0x68, 0x50, 0x1f, 0x17, 0x50,
+	0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07,
+	0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x40,
+	0x07, 0x40, 0x40, 0x40, 0x07, 0x40, 0x07, 0x17,
+	0x17, 0x17, 0x50, 0x17, 0x17, 0x50, 0x40, 0x40,
+	0x40, 0x2f, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1f,
+	0x1f, 0x1f, 0x27, 0x0f, 0x07, 0x07, 0x0f, 0x40,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1f,
+	0x48, 0x17, 0x48, 0x48, 0x48, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x47, 0x47, 0x5f, 0x40, 0x27, 0x07,
+	0x07, 0x20, 0x40, 0x47, 0x40, 0x40, 0x17, 0x0f,
+	0x47, 0x66, 0x40, 0x08, 0x66, 0x66, 0x66, 0x65,
+	0x65, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x00, 0x07,
+	0x67, 0x27, 0x4e, 0x17, 0x40, 0x07, 0x1f, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x57, 0x5f, 0x4f, 0x5f,
+	0x66, 0x5e, 0x57, 0x67, 0x67, 0x66, 0x57, 0x5f,
+	0x67, 0x67, 0x66, 0x4f, 0x47, 0x56, 0x57, 0x5f,
+	0x4f, 0x5f, 0x66, 0x5e, 0x57, 0x67, 0x67, 0x66,
+	0x57, 0x5f, 0x67, 0x67, 0x66, 0x4f, 0x47, 0x56,
+	0x08, 0x4f, 0x56, 0x40, 0x40, 0x40, 0x47, 0x07,
+	0x47, 0x47, 0x47, 0x66, 0x4f, 0x1f, 0x17, 0x4f,
+	0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07,
+	0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x40,
+	0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x17,
+	0x17, 0x17, 0x4f, 0x17, 0x17, 0x4f, 0x40, 0x40,
+	0x40, 0x2f, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1f,
+	0x1f, 0x20, 0x27, 0x10, 0x07, 0x08, 0x10, 0x00,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1f,
+	0x47, 0x17, 0x46, 0x47, 0x47, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x46, 0x47, 0x5e, 0x40, 0x26, 0x06,
+	0x06, 0x20, 0x40, 0x47, 0x40, 0x40, 0x16, 0x0f,
+	0x47, 0x64, 0x40, 0x08, 0x65, 0x64, 0x64, 0x63,
+	0x63, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x01, 0x07,
+	0x66, 0x27, 0x4d, 0x17, 0x40, 0x07, 0x1e, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x56, 0x5e, 0x4e, 0x5e,
+	0x65, 0x5d, 0x56, 0x66, 0x66, 0x64, 0x56, 0x5e,
+	0x66, 0x66, 0x64, 0x4e, 0x46, 0x55, 0x56, 0x5e,
+	0x4e, 0x5e, 0x65, 0x5d, 0x56, 0x66, 0x66, 0x64,
+	0x56, 0x5e, 0x66, 0x66, 0x64, 0x4e, 0x46, 0x55,
+	0x09, 0x4f, 0x54, 0x40, 0x40, 0x40, 0x47, 0x07,
+	0x47, 0x46, 0x46, 0x64, 0x4e, 0x1f, 0x16, 0x4f,
+	0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07,
+	0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40,
+	0x07, 0x00, 0x00, 0x01, 0x09, 0x01, 0x09, 0x17,
+	0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40,
+	0x40, 0x2e, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1e,
+	0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x01,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1e,
+	0x46, 0x17, 0x45, 0x46, 0x46, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x45, 0x47, 0x5e, 0x40, 0x25, 0x06,
+	0x05, 0x20, 0x40, 0x47, 0x40, 0x40, 0x16, 0x0f,
+	0x47, 0x63, 0x40, 0x08, 0x64, 0x63, 0x62, 0x60,
+	0x60, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x01, 0x07,
+	0x65, 0x27, 0x4c, 0x17, 0x40, 0x07, 0x1d, 0x40,
+	0x40, 0x40, 0x47, 0x47, 0x56, 0x5d, 0x4e, 0x5d,
+	0x64, 0x5c, 0x56, 0x65, 0x65, 0x63, 0x56, 0x5e,
+	0x65, 0x65, 0x63, 0x4d, 0x46, 0x54, 0x56, 0x5d,
+	0x4e, 0x5d, 0x64, 0x5c, 0x56, 0x65, 0x65, 0x63,
+	0x56, 0x5e, 0x65, 0x65, 0x63, 0x4d, 0x46, 0x54,
+	0x09, 0x4f, 0x52, 0x40, 0x40, 0x40, 0x47, 0x07,
+	0x47, 0x46, 0x46, 0x62, 0x4e, 0x1f, 0x16, 0x4f,
+	0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07,
+	0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40,
+	0x07, 0x00, 0x00, 0x01, 0x09, 0x01, 0x09, 0x17,
+	0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40,
+	0x40, 0x2d, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1e,
+	0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x01,
+	0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1e,
+	0x45, 0x17, 0x44, 0x45, 0x45, 0x17, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x44, 0x46, 0x5d, 0x40, 0x24, 0x05,
+	0x04, 0x21, 0x40, 0x46, 0x40, 0x40, 0x15, 0x0f,
+	0x46, 0x61, 0x40, 0x09, 0x63, 0x61, 0x60, 0x5e,
+	0x5e, 0x07, 0x07, 0x0e, 0x3e, 0x16, 0x02, 0x07,
+	0x64, 0x27, 0x4b, 0x16, 0x40, 0x06, 0x1c, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x55, 0x5c, 0x4d, 0x5c,
+	0x63, 0x5b, 0x55, 0x64, 0x64, 0x61, 0x55, 0x5d,
+	0x64, 0x64, 0x61, 0x4c, 0x45, 0x53, 0x55, 0x5c,
+	0x4d, 0x5c, 0x63, 0x5b, 0x55, 0x64, 0x64, 0x61,
+	0x55, 0x5d, 0x64, 0x64, 0x61, 0x4c, 0x45, 0x53,
+	0x0a, 0x4e, 0x50, 0x40, 0x41, 0x40, 0x46, 0x07,
+	0x46, 0x45, 0x45, 0x60, 0x4d, 0x1e, 0x15, 0x4e,
+	0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07,
+	0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x41,
+	0x07, 0x01, 0x01, 0x02, 0x0a, 0x02, 0x0a, 0x16,
+	0x17, 0x15, 0x4e, 0x17, 0x15, 0x4e, 0x40, 0x40,
+	0x40, 0x2c, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1d,
+	0x1d, 0x21, 0x27, 0x11, 0x07, 0x0a, 0x11, 0x02,
+	0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1d,
+	0x44, 0x16, 0x43, 0x44, 0x44, 0x16, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x43, 0x46, 0x5c, 0x40, 0x23, 0x04,
+	0x03, 0x21, 0x40, 0x46, 0x40, 0x40, 0x14, 0x0f,
+	0x46, 0x60, 0x40, 0x09, 0x61, 0x60, 0x5e, 0x5b,
+	0x5b, 0x07, 0x07, 0x0e, 0x3e, 0x16, 0x03, 0x07,
+	0x63, 0x27, 0x49, 0x16, 0x40, 0x06, 0x1b, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x54, 0x5b, 0x4c, 0x5b,
+	0x61, 0x59, 0x54, 0x63, 0x63, 0x60, 0x54, 0x5c,
+	0x63, 0x63, 0x60, 0x4b, 0x44, 0x51, 0x54, 0x5b,
+	0x4c, 0x5b, 0x61, 0x59, 0x54, 0x63, 0x63, 0x60,
+	0x54, 0x5c, 0x63, 0x63, 0x60, 0x4b, 0x44, 0x51,
+	0x0b, 0x4e, 0x4e, 0x40, 0x41, 0x40, 0x46, 0x07,
+	0x46, 0x44, 0x44, 0x5e, 0x4c, 0x1e, 0x14, 0x4e,
+	0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07,
+	0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41,
+	0x07, 0x01, 0x01, 0x03, 0x0b, 0x03, 0x0b, 0x16,
+	0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40,
+	0x40, 0x2b, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1c,
+	0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x03,
+	0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1c,
+	0x43, 0x16, 0x41, 0x43, 0x43, 0x16, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x42, 0x46, 0x5c, 0x40, 0x22, 0x04,
+	0x02, 0x21, 0x40, 0x46, 0x40, 0x40, 0x14, 0x0f,
+	0x46, 0x5e, 0x40, 0x09, 0x60, 0x5e, 0x5c, 0x59,
+	0x59, 0x07, 0x07, 0x0e, 0x3e, 0x16, 0x03, 0x07,
+	0x62, 0x27, 0x48, 0x16, 0x40, 0x06, 0x1a, 0x40,
+	0x40, 0x40, 0x46, 0x46, 0x54, 0x5a, 0x4c, 0x5a,
+	0x60, 0x58, 0x54, 0x62, 0x62, 0x5e, 0x54, 0x5c,
+	0x62, 0x62, 0x5e, 0x4a, 0x44, 0x50, 0x54, 0x5a,
+	0x4c, 0x5a, 0x60, 0x58, 0x54, 0x62, 0x62, 0x5e,
+	0x54, 0x5c, 0x62, 0x62, 0x5e, 0x4a, 0x44, 0x50,
+	0x0b, 0x4e, 0x4c, 0x40, 0x41, 0x40, 0x46, 0x07,
+	0x46, 0x44, 0x44, 0x5c, 0x4c, 0x1e, 0x14, 0x4e,
+	0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07,
+	0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41,
+	0x07, 0x01, 0x01, 0x03, 0x0b, 0x03, 0x0b, 0x16,
+	0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40,
+	0x40, 0x2a, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1c,
+	0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x03,
+	0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1c,
+	0x42, 0x16, 0x40, 0x42, 0x42, 0x16, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x41, 0x45, 0x5b, 0x40, 0x21, 0x03,
+	0x01, 0x22, 0x40, 0x45, 0x40, 0x40, 0x13, 0x0f,
+	0x45, 0x5d, 0x40, 0x0a, 0x5f, 0x5d, 0x5a, 0x56,
+	0x56, 0x07, 0x07, 0x0d, 0x3e, 0x15, 0x04, 0x07,
+	0x61, 0x27, 0x47, 0x15, 0x40, 0x05, 0x19, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x53, 0x59, 0x4b, 0x59,
+	0x5f, 0x57, 0x53, 0x61, 0x61, 0x5d, 0x53, 0x5b,
+	0x61, 0x61, 0x5d, 0x49, 0x43, 0x4f, 0x53, 0x59,
+	0x4b, 0x59, 0x5f, 0x57, 0x53, 0x61, 0x61, 0x5d,
+	0x53, 0x5b, 0x61, 0x61, 0x5d, 0x49, 0x43, 0x4f,
+	0x0c, 0x4d, 0x4a, 0x40, 0x42, 0x40, 0x45, 0x07,
+	0x45, 0x43, 0x43, 0x5a, 0x4b, 0x1d, 0x13, 0x4d,
+	0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07,
+	0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x42,
+	0x07, 0x02, 0x02, 0x04, 0x0c, 0x04, 0x0c, 0x15,
+	0x17, 0x13, 0x4d, 0x17, 0x13, 0x4d, 0x40, 0x40,
+	0x40, 0x29, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1b,
+	0x1b, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x04,
+	0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1b,
+	0x41, 0x15, 0x00, 0x41, 0x41, 0x15, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x40, 0x45, 0x5b, 0x40, 0x20, 0x02,
+	0x00, 0x22, 0x40, 0x45, 0x40, 0x40, 0x12, 0x0f,
+	0x45, 0x5b, 0x40, 0x0a, 0x5e, 0x5b, 0x59, 0x54,
+	0x54, 0x07, 0x07, 0x0d, 0x3e, 0x15, 0x04, 0x07,
+	0x60, 0x27, 0x46, 0x15, 0x40, 0x05, 0x18, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x53, 0x58, 0x4b, 0x58,
+	0x5e, 0x56, 0x53, 0x60, 0x60, 0x5b, 0x53, 0x5b,
+	0x60, 0x60, 0x5b, 0x48, 0x43, 0x4e, 0x53, 0x58,
+	0x4b, 0x58, 0x5e, 0x56, 0x53, 0x60, 0x60, 0x5b,
+	0x53, 0x5b, 0x60, 0x60, 0x5b, 0x48, 0x43, 0x4e,
+	0x0c, 0x4d, 0x49, 0x40, 0x42, 0x40, 0x45, 0x07,
+	0x45, 0x43, 0x43, 0x59, 0x4b, 0x1d, 0x12, 0x4d,
+	0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07,
+	0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42,
+	0x07, 0x02, 0x02, 0x04, 0x0c, 0x04, 0x0c, 0x15,
+	0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40,
+	0x40, 0x28, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1a,
+	0x1a, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x04,
+	0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1a,
+	0x40, 0x15, 0x01, 0x40, 0x40, 0x15, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x00, 0x45, 0x5a, 0x40, 0x1f, 0x02,
+	0x40, 0x22, 0x40, 0x45, 0x40, 0x40, 0x12, 0x0f,
+	0x45, 0x59, 0x40, 0x0a, 0x5c, 0x59, 0x57, 0x51,
+	0x51, 0x07, 0x07, 0x0d, 0x3e, 0x15, 0x05, 0x07,
+	0x5f, 0x27, 0x44, 0x15, 0x40, 0x05, 0x17, 0x40,
+	0x40, 0x40, 0x45, 0x45, 0x52, 0x57, 0x4a, 0x57,
+	0x5c, 0x54, 0x52, 0x5f, 0x5f, 0x59, 0x52, 0x5a,
+	0x5f, 0x5f, 0x59, 0x47, 0x42, 0x4c, 0x52, 0x57,
+	0x4a, 0x57, 0x5c, 0x54, 0x52, 0x5f, 0x5f, 0x59,
+	0x52, 0x5a, 0x5f, 0x5f, 0x59, 0x47, 0x42, 0x4c,
+	0x0d, 0x4d, 0x47, 0x40, 0x42, 0x40, 0x45, 0x07,
+	0x45, 0x42, 0x42, 0x57, 0x4a, 0x1d, 0x12, 0x4d,
+	0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07,
+	0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42,
+	0x07, 0x02, 0x02, 0x05, 0x0d, 0x05, 0x0d, 0x15,
+	0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40,
+	0x40, 0x27, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1a,
+	0x1a, 0x22, 0x27, 0x12, 0x07, 0x0d, 0x12, 0x05,
+	0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1a,
+	0x00, 0x15, 0x03, 0x00, 0x00, 0x15, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x01, 0x44, 0x59, 0x40, 0x1e, 0x01,
+	0x41, 0x23, 0x40, 0x44, 0x40, 0x40, 0x11, 0x0f,
+	0x44, 0x58, 0x40, 0x0b, 0x5b, 0x58, 0x55, 0x4f,
+	0x4f, 0x07, 0x07, 0x0c, 0x3e, 0x14, 0x06, 0x07,
+	0x5e, 0x27, 0x43, 0x14, 0x40, 0x04, 0x16, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x51, 0x56, 0x49, 0x56,
+	0x5b, 0x53, 0x51, 0x5e, 0x5e, 0x58, 0x51, 0x59,
+	0x5e, 0x5e, 0x58, 0x46, 0x41, 0x4b, 0x51, 0x56,
+	0x49, 0x56, 0x5b, 0x53, 0x51, 0x5e, 0x5e, 0x58,
+	0x51, 0x59, 0x5e, 0x5e, 0x58, 0x46, 0x41, 0x4b,
+	0x0e, 0x4c, 0x45, 0x40, 0x43, 0x40, 0x44, 0x07,
+	0x44, 0x41, 0x41, 0x55, 0x49, 0x1c, 0x11, 0x4c,
+	0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07,
+	0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43,
+	0x07, 0x03, 0x03, 0x06, 0x0e, 0x06, 0x0e, 0x14,
+	0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40,
+	0x40, 0x26, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x19,
+	0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x06,
+	0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x19,
+	0x01, 0x14, 0x04, 0x01, 0x01, 0x14, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x02, 0x44, 0x59, 0x40, 0x1d, 0x01,
+	0x42, 0x23, 0x40, 0x44, 0x40, 0x40, 0x11, 0x0f,
+	0x44, 0x56, 0x40, 0x0b, 0x5a, 0x56, 0x53, 0x4c,
+	0x4c, 0x07, 0x07, 0x0c, 0x3e, 0x14, 0x06, 0x07,
+	0x5d, 0x27, 0x42, 0x14, 0x40, 0x04, 0x15, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x51, 0x55, 0x49, 0x55,
+	0x5a, 0x52, 0x51, 0x5d, 0x5d, 0x56, 0x51, 0x59,
+	0x5d, 0x5d, 0x56, 0x45, 0x41, 0x4a, 0x51, 0x55,
+	0x49, 0x55, 0x5a, 0x52, 0x51, 0x5d, 0x5d, 0x56,
+	0x51, 0x59, 0x5d, 0x5d, 0x56, 0x45, 0x41, 0x4a,
+	0x0e, 0x4c, 0x43, 0x40, 0x43, 0x40, 0x44, 0x07,
+	0x44, 0x41, 0x41, 0x53, 0x49, 0x1c, 0x11, 0x4c,
+	0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07,
+	0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43,
+	0x07, 0x03, 0x03, 0x06, 0x0e, 0x06, 0x0e, 0x14,
+	0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40,
+	0x40, 0x25, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x19,
+	0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x06,
+	0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x19,
+	0x02, 0x14, 0x05, 0x02, 0x02, 0x14, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x03, 0x44, 0x58, 0x40, 0x1c, 0x00,
+	0x43, 0x23, 0x40, 0x44, 0x40, 0x40, 0x10, 0x0f,
+	0x44, 0x55, 0x40, 0x0b, 0x59, 0x55, 0x51, 0x4a,
+	0x4a, 0x07, 0x07, 0x0c, 0x3d, 0x14, 0x07, 0x07,
+	0x5c, 0x27, 0x41, 0x14, 0x40, 0x04, 0x14, 0x40,
+	0x40, 0x40, 0x44, 0x44, 0x50, 0x54, 0x48, 0x54,
+	0x59, 0x51, 0x50, 0x5c, 0x5c, 0x55, 0x50, 0x58,
+	0x5c, 0x5c, 0x55, 0x44, 0x40, 0x49, 0x50, 0x54,
+	0x48, 0x54, 0x59, 0x51, 0x50, 0x5c, 0x5c, 0x55,
+	0x50, 0x58, 0x5c, 0x5c, 0x55, 0x44, 0x40, 0x49,
+	0x0f, 0x4c, 0x41, 0x40, 0x43, 0x40, 0x44, 0x07,
+	0x44, 0x40, 0x40, 0x51, 0x48, 0x1c, 0x10, 0x4c,
+	0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07,
+	0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x43,
+	0x07, 0x03, 0x03, 0x07, 0x0f, 0x07, 0x0f, 0x14,
+	0x17, 0x10, 0x4c, 0x17, 0x10, 0x4c, 0x40, 0x40,
+	0x40, 0x24, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x18,
+	0x18, 0x23, 0x27, 0x13, 0x07, 0x0f, 0x13, 0x07,
+	0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x18,
+	0x03, 0x14, 0x06, 0x03, 0x03, 0x14, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x04, 0x43, 0x57, 0x40, 0x1b, 0x40,
+	0x44, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0f, 0x0f,
+	0x43, 0x53, 0x40, 0x0c, 0x57, 0x53, 0x4f, 0x47,
+	0x47, 0x07, 0x07, 0x0b, 0x3b, 0x13, 0x08, 0x07,
+	0x5b, 0x27, 0x00, 0x13, 0x40, 0x03, 0x13, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4f, 0x53, 0x47, 0x53,
+	0x57, 0x4f, 0x4f, 0x5b, 0x5b, 0x53, 0x4f, 0x57,
+	0x5b, 0x5b, 0x53, 0x43, 0x00, 0x47, 0x4f, 0x53,
+	0x47, 0x53, 0x57, 0x4f, 0x4f, 0x5b, 0x5b, 0x53,
+	0x4f, 0x57, 0x5b, 0x5b, 0x53, 0x43, 0x00, 0x47,
+	0x10, 0x4b, 0x00, 0x40, 0x44, 0x40, 0x43, 0x07,
+	0x43, 0x00, 0x00, 0x4f, 0x47, 0x1b, 0x0f, 0x4b,
+	0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07,
+	0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44,
+	0x07, 0x04, 0x04, 0x08, 0x10, 0x08, 0x10, 0x13,
+	0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40,
+	0x40, 0x23, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x17,
+	0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x08,
+	0x03, 0x3e, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x17,
+	0x04, 0x13, 0x08, 0x04, 0x04, 0x13, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x05, 0x43, 0x57, 0x40, 0x1a, 0x40,
+	0x45, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0f, 0x0f,
+	0x43, 0x52, 0x40, 0x0c, 0x56, 0x52, 0x4d, 0x45,
+	0x45, 0x07, 0x07, 0x0b, 0x3a, 0x13, 0x08, 0x07,
+	0x5a, 0x27, 0x01, 0x13, 0x40, 0x03, 0x12, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4f, 0x52, 0x47, 0x52,
+	0x56, 0x4e, 0x4f, 0x5a, 0x5a, 0x52, 0x4f, 0x57,
+	0x5a, 0x5a, 0x52, 0x42, 0x00, 0x46, 0x4f, 0x52,
+	0x47, 0x52, 0x56, 0x4e, 0x4f, 0x5a, 0x5a, 0x52,
+	0x4f, 0x57, 0x5a, 0x5a, 0x52, 0x42, 0x00, 0x46,
+	0x10, 0x4b, 0x02, 0x40, 0x44, 0x40, 0x43, 0x07,
+	0x43, 0x00, 0x00, 0x4d, 0x47, 0x1b, 0x0f, 0x4b,
+	0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07,
+	0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44,
+	0x07, 0x04, 0x04, 0x08, 0x10, 0x08, 0x10, 0x13,
+	0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40,
+	0x40, 0x22, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x17,
+	0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x08,
+	0x03, 0x3e, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x17,
+	0x05, 0x13, 0x09, 0x05, 0x05, 0x13, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x06, 0x43, 0x56, 0x40, 0x19, 0x41,
+	0x46, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0e, 0x0f,
+	0x43, 0x50, 0x40, 0x0c, 0x55, 0x50, 0x4b, 0x42,
+	0x42, 0x07, 0x07, 0x0b, 0x38, 0x13, 0x09, 0x07,
+	0x59, 0x27, 0x02, 0x13, 0x40, 0x03, 0x11, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x46, 0x51,
+	0x55, 0x4d, 0x4e, 0x59, 0x59, 0x50, 0x4e, 0x56,
+	0x59, 0x59, 0x50, 0x41, 0x01, 0x45, 0x4e, 0x51,
+	0x46, 0x51, 0x55, 0x4d, 0x4e, 0x59, 0x59, 0x50,
+	0x4e, 0x56, 0x59, 0x59, 0x50, 0x41, 0x01, 0x45,
+	0x11, 0x4b, 0x04, 0x40, 0x44, 0x40, 0x43, 0x07,
+	0x43, 0x01, 0x01, 0x4b, 0x46, 0x1b, 0x0e, 0x4b,
+	0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07,
+	0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x44,
+	0x07, 0x04, 0x04, 0x09, 0x11, 0x09, 0x11, 0x13,
+	0x17, 0x0e, 0x4b, 0x17, 0x0e, 0x4b, 0x40, 0x40,
+	0x40, 0x21, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x16,
+	0x16, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x09,
+	0x03, 0x3d, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x16,
+	0x06, 0x13, 0x0a, 0x06, 0x06, 0x13, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x06, 0x43, 0x56, 0x40, 0x18, 0x42,
+	0x47, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0d, 0x0f,
+	0x43, 0x4f, 0x40, 0x0c, 0x54, 0x4f, 0x4a, 0x40,
+	0x40, 0x07, 0x07, 0x0a, 0x36, 0x12, 0x09, 0x07,
+	0x59, 0x27, 0x03, 0x12, 0x40, 0x02, 0x10, 0x40,
+	0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x46, 0x51,
+	0x54, 0x4c, 0x4e, 0x59, 0x59, 0x4f, 0x4e, 0x56,
+	0x59, 0x59, 0x4f, 0x41, 0x01, 0x44, 0x4e, 0x51,
+	0x46, 0x51, 0x54, 0x4c, 0x4e, 0x59, 0x59, 0x4f,
+	0x4e, 0x56, 0x59, 0x59, 0x4f, 0x41, 0x01, 0x44,
+	0x11, 0x4b, 0x05, 0x40, 0x45, 0x40, 0x43, 0x07,
+	0x43, 0x01, 0x01, 0x4a, 0x46, 0x1a, 0x0d, 0x4b,
+	0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07,
+	0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x45,
+	0x07, 0x04, 0x04, 0x09, 0x11, 0x09, 0x11, 0x12,
+	0x17, 0x0d, 0x4b, 0x17, 0x0d, 0x4b, 0x40, 0x40,
+	0x40, 0x20, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x15,
+	0x15, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x09,
+	0x02, 0x3b, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x15,
+	0x06, 0x12, 0x0b, 0x06, 0x06, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x07, 0x42, 0x55, 0x40, 0x18, 0x42,
+	0x47, 0x25, 0x40, 0x42, 0x40, 0x40, 0x0d, 0x0f,
+	0x42, 0x4d, 0x40, 0x0d, 0x52, 0x4d, 0x48, 0x02,
+	0x02, 0x07, 0x07, 0x0a, 0x35, 0x12, 0x0a, 0x07,
+	0x58, 0x27, 0x05, 0x12, 0x40, 0x02, 0x10, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4d, 0x50, 0x45, 0x50,
+	0x52, 0x4a, 0x4d, 0x58, 0x58, 0x4d, 0x4d, 0x55,
+	0x58, 0x58, 0x4d, 0x40, 0x02, 0x42, 0x4d, 0x50,
+	0x45, 0x50, 0x52, 0x4a, 0x4d, 0x58, 0x58, 0x4d,
+	0x4d, 0x55, 0x58, 0x58, 0x4d, 0x40, 0x02, 0x42,
+	0x12, 0x4a, 0x07, 0x40, 0x45, 0x40, 0x42, 0x07,
+	0x42, 0x02, 0x02, 0x48, 0x45, 0x1a, 0x0d, 0x4a,
+	0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07,
+	0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x45,
+	0x07, 0x05, 0x05, 0x0a, 0x12, 0x0a, 0x12, 0x12,
+	0x17, 0x0d, 0x4a, 0x17, 0x0d, 0x4a, 0x40, 0x40,
+	0x40, 0x20, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x15,
+	0x15, 0x25, 0x27, 0x15, 0x07, 0x12, 0x15, 0x0a,
+	0x02, 0x3a, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x15,
+	0x07, 0x12, 0x0d, 0x07, 0x07, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x08, 0x42, 0x54, 0x40, 0x17, 0x43,
+	0x48, 0x25, 0x40, 0x42, 0x40, 0x40, 0x0c, 0x0f,
+	0x42, 0x4b, 0x40, 0x0d, 0x51, 0x4b, 0x46, 0x04,
+	0x04, 0x07, 0x07, 0x0a, 0x33, 0x12, 0x0b, 0x07,
+	0x57, 0x27, 0x06, 0x12, 0x40, 0x02, 0x0f, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4c, 0x4f, 0x44, 0x4f,
+	0x51, 0x49, 0x4c, 0x57, 0x57, 0x4b, 0x4c, 0x54,
+	0x57, 0x57, 0x4b, 0x00, 0x03, 0x41, 0x4c, 0x4f,
+	0x44, 0x4f, 0x51, 0x49, 0x4c, 0x57, 0x57, 0x4b,
+	0x4c, 0x54, 0x57, 0x57, 0x4b, 0x00, 0x03, 0x41,
+	0x13, 0x4a, 0x09, 0x40, 0x45, 0x40, 0x42, 0x07,
+	0x42, 0x03, 0x03, 0x46, 0x44, 0x1a, 0x0c, 0x4a,
+	0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07,
+	0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45,
+	0x07, 0x05, 0x05, 0x0b, 0x13, 0x0b, 0x13, 0x12,
+	0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40,
+	0x40, 0x1f, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x14,
+	0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0b,
+	0x02, 0x39, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x14,
+	0x08, 0x12, 0x0e, 0x08, 0x08, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x09, 0x42, 0x54, 0x40, 0x16, 0x43,
+	0x49, 0x25, 0x40, 0x42, 0x40, 0x40, 0x0c, 0x0f,
+	0x42, 0x4a, 0x40, 0x0d, 0x50, 0x4a, 0x44, 0x07,
+	0x07, 0x07, 0x07, 0x0a, 0x32, 0x12, 0x0b, 0x07,
+	0x56, 0x27, 0x07, 0x12, 0x40, 0x02, 0x0e, 0x40,
+	0x40, 0x40, 0x42, 0x42, 0x4c, 0x4e, 0x44, 0x4e,
+	0x50, 0x48, 0x4c, 0x56, 0x56, 0x4a, 0x4c, 0x54,
+	0x56, 0x56, 0x4a, 0x01, 0x03, 0x40, 0x4c, 0x4e,
+	0x44, 0x4e, 0x50, 0x48, 0x4c, 0x56, 0x56, 0x4a,
+	0x4c, 0x54, 0x56, 0x56, 0x4a, 0x01, 0x03, 0x40,
+	0x13, 0x4a, 0x0b, 0x40, 0x45, 0x40, 0x42, 0x07,
+	0x42, 0x03, 0x03, 0x44, 0x44, 0x1a, 0x0c, 0x4a,
+	0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07,
+	0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45,
+	0x07, 0x05, 0x05, 0x0b, 0x13, 0x0b, 0x13, 0x12,
+	0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40,
+	0x40, 0x1e, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x14,
+	0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0b,
+	0x02, 0x38, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x14,
+	0x09, 0x12, 0x0f, 0x09, 0x09, 0x12, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x0a, 0x41, 0x53, 0x40, 0x15, 0x44,
+	0x4a, 0x26, 0x40, 0x41, 0x40, 0x40, 0x0b, 0x0f,
+	0x41, 0x48, 0x40, 0x0e, 0x4f, 0x48, 0x42, 0x09,
+	0x09, 0x07, 0x07, 0x09, 0x30, 0x11, 0x0c, 0x07,
+	0x55, 0x27, 0x08, 0x11, 0x40, 0x01, 0x0d, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4b, 0x4d, 0x43, 0x4d,
+	0x4f, 0x47, 0x4b, 0x55, 0x55, 0x48, 0x4b, 0x53,
+	0x55, 0x55, 0x48, 0x02, 0x04, 0x00, 0x4b, 0x4d,
+	0x43, 0x4d, 0x4f, 0x47, 0x4b, 0x55, 0x55, 0x48,
+	0x4b, 0x53, 0x55, 0x55, 0x48, 0x02, 0x04, 0x00,
+	0x14, 0x49, 0x0d, 0x40, 0x46, 0x40, 0x41, 0x07,
+	0x41, 0x04, 0x04, 0x42, 0x43, 0x19, 0x0b, 0x49,
+	0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07,
+	0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x46,
+	0x07, 0x06, 0x06, 0x0c, 0x14, 0x0c, 0x14, 0x11,
+	0x17, 0x0b, 0x49, 0x17, 0x0b, 0x49, 0x40, 0x40,
+	0x40, 0x1d, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x13,
+	0x13, 0x26, 0x27, 0x16, 0x07, 0x14, 0x16, 0x0c,
+	0x01, 0x36, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x13,
+	0x0a, 0x11, 0x10, 0x0a, 0x0a, 0x11, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x0b, 0x41, 0x52, 0x40, 0x14, 0x45,
+	0x4b, 0x26, 0x40, 0x41, 0x40, 0x40, 0x0a, 0x0f,
+	0x41, 0x47, 0x40, 0x0e, 0x4d, 0x47, 0x40, 0x0c,
+	0x0c, 0x07, 0x07, 0x09, 0x2f, 0x11, 0x0d, 0x07,
+	0x54, 0x27, 0x0a, 0x11, 0x40, 0x01, 0x0c, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4a, 0x4c, 0x42, 0x4c,
+	0x4d, 0x45, 0x4a, 0x54, 0x54, 0x47, 0x4a, 0x52,
+	0x54, 0x54, 0x47, 0x03, 0x05, 0x02, 0x4a, 0x4c,
+	0x42, 0x4c, 0x4d, 0x45, 0x4a, 0x54, 0x54, 0x47,
+	0x4a, 0x52, 0x54, 0x54, 0x47, 0x03, 0x05, 0x02,
+	0x15, 0x49, 0x0f, 0x40, 0x46, 0x40, 0x41, 0x07,
+	0x41, 0x05, 0x05, 0x40, 0x42, 0x19, 0x0a, 0x49,
+	0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07,
+	0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46,
+	0x07, 0x06, 0x06, 0x0d, 0x15, 0x0d, 0x15, 0x11,
+	0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40,
+	0x40, 0x1c, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x12,
+	0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0d,
+	0x01, 0x35, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x12,
+	0x0b, 0x11, 0x12, 0x0b, 0x0b, 0x11, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x0c, 0x41, 0x52, 0x40, 0x13, 0x45,
+	0x4c, 0x26, 0x40, 0x41, 0x40, 0x40, 0x0a, 0x0f,
+	0x41, 0x45, 0x40, 0x0e, 0x4c, 0x45, 0x01, 0x0e,
+	0x0e, 0x07, 0x07, 0x09, 0x2d, 0x11, 0x0d, 0x07,
+	0x53, 0x27, 0x0b, 0x11, 0x40, 0x01, 0x0b, 0x40,
+	0x40, 0x40, 0x41, 0x41, 0x4a, 0x4b, 0x42, 0x4b,
+	0x4c, 0x44, 0x4a, 0x53, 0x53, 0x45, 0x4a, 0x52,
+	0x53, 0x53, 0x45, 0x04, 0x05, 0x03, 0x4a, 0x4b,
+	0x42, 0x4b, 0x4c, 0x44, 0x4a, 0x53, 0x53, 0x45,
+	0x4a, 0x52, 0x53, 0x53, 0x45, 0x04, 0x05, 0x03,
+	0x15, 0x49, 0x11, 0x40, 0x46, 0x40, 0x41, 0x07,
+	0x41, 0x05, 0x05, 0x01, 0x42, 0x19, 0x0a, 0x49,
+	0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07,
+	0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46,
+	0x07, 0x06, 0x06, 0x0d, 0x15, 0x0d, 0x15, 0x11,
+	0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40,
+	0x40, 0x1b, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x12,
+	0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0d,
+	0x01, 0x34, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x12,
+	0x0c, 0x11, 0x13, 0x0c, 0x0c, 0x11, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x0d, 0x40, 0x51, 0x40, 0x12, 0x46,
+	0x4d, 0x27, 0x40, 0x40, 0x40, 0x40, 0x09, 0x0f,
+	0x40, 0x44, 0x40, 0x0f, 0x4b, 0x44, 0x03, 0x11,
+	0x11, 0x07, 0x07, 0x08, 0x2c, 0x10, 0x0e, 0x07,
+	0x52, 0x27, 0x0c, 0x10, 0x40, 0x00, 0x0a, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x49, 0x4a, 0x41, 0x4a,
+	0x4b, 0x43, 0x49, 0x52, 0x52, 0x44, 0x49, 0x51,
+	0x52, 0x52, 0x44, 0x05, 0x06, 0x04, 0x49, 0x4a,
+	0x41, 0x4a, 0x4b, 0x43, 0x49, 0x52, 0x52, 0x44,
+	0x49, 0x51, 0x52, 0x52, 0x44, 0x05, 0x06, 0x04,
+	0x16, 0x48, 0x13, 0x40, 0x47, 0x40, 0x40, 0x07,
+	0x40, 0x06, 0x06, 0x03, 0x41, 0x18, 0x09, 0x48,
+	0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07,
+	0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x47,
+	0x07, 0x07, 0x07, 0x0e, 0x16, 0x0e, 0x16, 0x10,
+	0x17, 0x09, 0x48, 0x17, 0x09, 0x48, 0x40, 0x40,
+	0x40, 0x1a, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x11,
+	0x11, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0e,
+	0x00, 0x33, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x11,
+	0x0d, 0x10, 0x14, 0x0d, 0x0d, 0x10, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x0e, 0x40, 0x51, 0x40, 0x11, 0x47,
+	0x4e, 0x27, 0x40, 0x40, 0x40, 0x40, 0x08, 0x0f,
+	0x40, 0x42, 0x40, 0x0f, 0x4a, 0x42, 0x04, 0x13,
+	0x13, 0x07, 0x07, 0x08, 0x2a, 0x10, 0x0e, 0x07,
+	0x51, 0x27, 0x0d, 0x10, 0x40, 0x00, 0x09, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x41, 0x49,
+	0x4a, 0x42, 0x49, 0x51, 0x51, 0x42, 0x49, 0x51,
+	0x51, 0x51, 0x42, 0x06, 0x06, 0x05, 0x49, 0x49,
+	0x41, 0x49, 0x4a, 0x42, 0x49, 0x51, 0x51, 0x42,
+	0x49, 0x51, 0x51, 0x51, 0x42, 0x06, 0x06, 0x05,
+	0x16, 0x48, 0x14, 0x40, 0x47, 0x40, 0x40, 0x07,
+	0x40, 0x06, 0x06, 0x04, 0x41, 0x18, 0x08, 0x48,
+	0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07,
+	0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47,
+	0x07, 0x07, 0x07, 0x0e, 0x16, 0x0e, 0x16, 0x10,
+	0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40,
+	0x40, 0x19, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x10,
+	0x10, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0e,
+	0x00, 0x31, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10,
+	0x0e, 0x10, 0x15, 0x0e, 0x0e, 0x10, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x0f, 0x40, 0x50, 0x40, 0x10, 0x47,
+	0x4f, 0x27, 0x40, 0x40, 0x40, 0x40, 0x08, 0x0f,
+	0x40, 0x40, 0x40, 0x0f, 0x48, 0x40, 0x06, 0x16,
+	0x16, 0x07, 0x07, 0x08, 0x28, 0x10, 0x0f, 0x07,
+	0x50, 0x27, 0x0f, 0x10, 0x40, 0x00, 0x08, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x40, 0x48,
+	0x48, 0x40, 0x48, 0x50, 0x50, 0x40, 0x48, 0x50,
+	0x50, 0x50, 0x40, 0x07, 0x07, 0x07, 0x48, 0x48,
+	0x40, 0x48, 0x48, 0x40, 0x48, 0x50, 0x50, 0x40,
+	0x48, 0x50, 0x50, 0x50, 0x40, 0x07, 0x07, 0x07,
+	0x17, 0x48, 0x16, 0x40, 0x47, 0x40, 0x40, 0x07,
+	0x40, 0x07, 0x07, 0x06, 0x40, 0x18, 0x08, 0x48,
+	0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07,
+	0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47,
+	0x07, 0x07, 0x07, 0x0f, 0x17, 0x0f, 0x17, 0x10,
+	0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40,
+	0x40, 0x18, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x10,
+	0x10, 0x27, 0x27, 0x17, 0x07, 0x17, 0x17, 0x0f,
+	0x00, 0x30, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10,
+	0x0f, 0x10, 0x17, 0x0f, 0x0f, 0x10, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x10, 0x00, 0x4f, 0x40, 0x0f, 0x48,
+	0x50, 0x28, 0x40, 0x00, 0x40, 0x40, 0x07, 0x0f,
+	0x00, 0x00, 0x40, 0x10, 0x47, 0x00, 0x08, 0x18,
+	0x18, 0x07, 0x07, 0x07, 0x27, 0x0f, 0x10, 0x07,
+	0x4f, 0x27, 0x10, 0x0f, 0x40, 0x40, 0x07, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x47, 0x47, 0x00, 0x47,
+	0x47, 0x00, 0x47, 0x4f, 0x4f, 0x00, 0x47, 0x4f,
+	0x4f, 0x4f, 0x00, 0x08, 0x08, 0x08, 0x47, 0x47,
+	0x00, 0x47, 0x47, 0x00, 0x47, 0x4f, 0x4f, 0x00,
+	0x47, 0x4f, 0x4f, 0x4f, 0x00, 0x08, 0x08, 0x08,
+	0x18, 0x47, 0x18, 0x40, 0x48, 0x40, 0x00, 0x07,
+	0x00, 0x08, 0x08, 0x08, 0x00, 0x17, 0x07, 0x47,
+	0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07,
+	0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48,
+	0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f,
+	0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40,
+	0x40, 0x17, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10,
+	0x40, 0x2f, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x10, 0x0f, 0x18, 0x10, 0x10, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x11, 0x00, 0x4f, 0x40, 0x0e, 0x48,
+	0x51, 0x28, 0x40, 0x00, 0x40, 0x40, 0x07, 0x0f,
+	0x00, 0x02, 0x40, 0x10, 0x46, 0x02, 0x0a, 0x1b,
+	0x1b, 0x07, 0x07, 0x07, 0x25, 0x0f, 0x10, 0x07,
+	0x4e, 0x27, 0x11, 0x0f, 0x40, 0x40, 0x06, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x47, 0x46, 0x00, 0x46,
+	0x46, 0x01, 0x47, 0x4e, 0x4e, 0x02, 0x47, 0x4f,
+	0x4e, 0x4e, 0x02, 0x09, 0x08, 0x09, 0x47, 0x46,
+	0x00, 0x46, 0x46, 0x01, 0x47, 0x4e, 0x4e, 0x02,
+	0x47, 0x4f, 0x4e, 0x4e, 0x02, 0x09, 0x08, 0x09,
+	0x18, 0x47, 0x1a, 0x40, 0x48, 0x40, 0x00, 0x07,
+	0x00, 0x08, 0x08, 0x0a, 0x00, 0x17, 0x07, 0x47,
+	0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07,
+	0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48,
+	0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f,
+	0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40,
+	0x40, 0x16, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10,
+	0x40, 0x2e, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f,
+	0x11, 0x0f, 0x19, 0x11, 0x11, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x12, 0x00, 0x4e, 0x40, 0x0d, 0x49,
+	0x52, 0x28, 0x40, 0x00, 0x40, 0x40, 0x06, 0x0f,
+	0x00, 0x03, 0x40, 0x10, 0x45, 0x03, 0x0c, 0x1d,
+	0x1d, 0x07, 0x07, 0x07, 0x24, 0x0f, 0x11, 0x07,
+	0x4d, 0x27, 0x12, 0x0f, 0x40, 0x40, 0x05, 0x40,
+	0x40, 0x40, 0x00, 0x00, 0x46, 0x45, 0x01, 0x45,
+	0x45, 0x02, 0x46, 0x4d, 0x4d, 0x03, 0x46, 0x4e,
+	0x4d, 0x4d, 0x03, 0x0a, 0x09, 0x0a, 0x46, 0x45,
+	0x01, 0x45, 0x45, 0x02, 0x46, 0x4d, 0x4d, 0x03,
+	0x46, 0x4e, 0x4d, 0x4d, 0x03, 0x0a, 0x09, 0x0a,
+	0x19, 0x47, 0x1c, 0x40, 0x48, 0x40, 0x00, 0x07,
+	0x00, 0x09, 0x09, 0x0c, 0x01, 0x17, 0x06, 0x47,
+	0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07,
+	0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x48,
+	0x07, 0x08, 0x08, 0x11, 0x19, 0x11, 0x19, 0x0f,
+	0x17, 0x06, 0x47, 0x17, 0x06, 0x47, 0x40, 0x40,
+	0x40, 0x15, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0e,
+	0x0e, 0x28, 0x27, 0x18, 0x07, 0x19, 0x18, 0x11,
+	0x40, 0x2c, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0e,
+	0x12, 0x0f, 0x1a, 0x12, 0x12, 0x0f, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x13, 0x01, 0x4d, 0x40, 0x0c, 0x4a,
+	0x53, 0x29, 0x40, 0x01, 0x40, 0x40, 0x05, 0x0f,
+	0x01, 0x05, 0x40, 0x11, 0x43, 0x05, 0x0e, 0x20,
+	0x20, 0x07, 0x07, 0x06, 0x22, 0x0e, 0x12, 0x07,
+	0x4c, 0x27, 0x14, 0x0e, 0x40, 0x41, 0x04, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x45, 0x44, 0x02, 0x44,
+	0x43, 0x04, 0x45, 0x4c, 0x4c, 0x05, 0x45, 0x4d,
+	0x4c, 0x4c, 0x05, 0x0b, 0x0a, 0x0c, 0x45, 0x44,
+	0x02, 0x44, 0x43, 0x04, 0x45, 0x4c, 0x4c, 0x05,
+	0x45, 0x4d, 0x4c, 0x4c, 0x05, 0x0b, 0x0a, 0x0c,
+	0x1a, 0x46, 0x1e, 0x40, 0x49, 0x40, 0x01, 0x07,
+	0x01, 0x0a, 0x0a, 0x0e, 0x02, 0x16, 0x05, 0x46,
+	0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07,
+	0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49,
+	0x07, 0x09, 0x09, 0x12, 0x1a, 0x12, 0x1a, 0x0e,
+	0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40,
+	0x40, 0x14, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0d,
+	0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x12,
+	0x41, 0x2b, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0d,
+	0x13, 0x0e, 0x1c, 0x13, 0x13, 0x0e, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x14, 0x01, 0x4d, 0x40, 0x0b, 0x4a,
+	0x54, 0x29, 0x40, 0x01, 0x40, 0x40, 0x05, 0x0f,
+	0x01, 0x06, 0x40, 0x11, 0x42, 0x06, 0x10, 0x22,
+	0x22, 0x07, 0x07, 0x06, 0x21, 0x0e, 0x12, 0x07,
+	0x4b, 0x27, 0x15, 0x0e, 0x40, 0x41, 0x03, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x45, 0x43, 0x02, 0x43,
+	0x42, 0x05, 0x45, 0x4b, 0x4b, 0x06, 0x45, 0x4d,
+	0x4b, 0x4b, 0x06, 0x0c, 0x0a, 0x0d, 0x45, 0x43,
+	0x02, 0x43, 0x42, 0x05, 0x45, 0x4b, 0x4b, 0x06,
+	0x45, 0x4d, 0x4b, 0x4b, 0x06, 0x0c, 0x0a, 0x0d,
+	0x1a, 0x46, 0x20, 0x40, 0x49, 0x40, 0x01, 0x07,
+	0x01, 0x0a, 0x0a, 0x10, 0x02, 0x16, 0x05, 0x46,
+	0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07,
+	0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49,
+	0x07, 0x09, 0x09, 0x12, 0x1a, 0x12, 0x1a, 0x0e,
+	0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40,
+	0x40, 0x13, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0d,
+	0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x12,
+	0x41, 0x2a, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0d,
+	0x14, 0x0e, 0x1d, 0x14, 0x14, 0x0e, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x15, 0x01, 0x4c, 0x40, 0x0a, 0x4b,
+	0x55, 0x29, 0x40, 0x01, 0x40, 0x40, 0x04, 0x0f,
+	0x01, 0x08, 0x40, 0x11, 0x41, 0x08, 0x12, 0x25,
+	0x25, 0x07, 0x07, 0x06, 0x1f, 0x0e, 0x13, 0x07,
+	0x4a, 0x27, 0x16, 0x0e, 0x40, 0x41, 0x02, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x03, 0x42,
+	0x41, 0x06, 0x44, 0x4a, 0x4a, 0x08, 0x44, 0x4c,
+	0x4a, 0x4a, 0x08, 0x0d, 0x0b, 0x0e, 0x44, 0x42,
+	0x03, 0x42, 0x41, 0x06, 0x44, 0x4a, 0x4a, 0x08,
+	0x44, 0x4c, 0x4a, 0x4a, 0x08, 0x0d, 0x0b, 0x0e,
+	0x1b, 0x46, 0x22, 0x40, 0x49, 0x40, 0x01, 0x07,
+	0x01, 0x0b, 0x0b, 0x12, 0x03, 0x16, 0x04, 0x46,
+	0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07,
+	0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x49,
+	0x07, 0x09, 0x09, 0x13, 0x1b, 0x13, 0x1b, 0x0e,
+	0x17, 0x04, 0x46, 0x17, 0x04, 0x46, 0x40, 0x40,
+	0x40, 0x12, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0c,
+	0x0c, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x13,
+	0x41, 0x29, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0c,
+	0x15, 0x0e, 0x1e, 0x15, 0x15, 0x0e, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x15, 0x01, 0x4c, 0x40, 0x09, 0x4c,
+	0x56, 0x29, 0x40, 0x01, 0x40, 0x40, 0x03, 0x0f,
+	0x01, 0x09, 0x40, 0x11, 0x40, 0x09, 0x13, 0x27,
+	0x27, 0x07, 0x07, 0x05, 0x1d, 0x0d, 0x13, 0x07,
+	0x4a, 0x27, 0x17, 0x0d, 0x40, 0x42, 0x01, 0x40,
+	0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x03, 0x42,
+	0x40, 0x07, 0x44, 0x4a, 0x4a, 0x09, 0x44, 0x4c,
+	0x4a, 0x4a, 0x09, 0x0d, 0x0b, 0x0f, 0x44, 0x42,
+	0x03, 0x42, 0x40, 0x07, 0x44, 0x4a, 0x4a, 0x09,
+	0x44, 0x4c, 0x4a, 0x4a, 0x09, 0x0d, 0x0b, 0x0f,
+	0x1b, 0x46, 0x23, 0x40, 0x4a, 0x40, 0x01, 0x07,
+	0x01, 0x0b, 0x0b, 0x13, 0x03, 0x15, 0x03, 0x46,
+	0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07,
+	0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x4a,
+	0x07, 0x09, 0x09, 0x13, 0x1b, 0x13, 0x1b, 0x0d,
+	0x17, 0x03, 0x46, 0x17, 0x03, 0x46, 0x40, 0x40,
+	0x40, 0x11, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0b,
+	0x0b, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x13,
+	0x42, 0x27, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0b,
+	0x15, 0x0d, 0x1f, 0x15, 0x15, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x16, 0x02, 0x4b, 0x40, 0x09, 0x4c,
+	0x56, 0x2a, 0x40, 0x02, 0x40, 0x40, 0x03, 0x0f,
+	0x02, 0x0b, 0x40, 0x12, 0x01, 0x0b, 0x15, 0x2a,
+	0x2a, 0x07, 0x07, 0x05, 0x1c, 0x0d, 0x14, 0x07,
+	0x49, 0x27, 0x19, 0x0d, 0x40, 0x42, 0x01, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x43, 0x41, 0x04, 0x41,
+	0x01, 0x09, 0x43, 0x49, 0x49, 0x0b, 0x43, 0x4b,
+	0x49, 0x49, 0x0b, 0x0e, 0x0c, 0x11, 0x43, 0x41,
+	0x04, 0x41, 0x01, 0x09, 0x43, 0x49, 0x49, 0x0b,
+	0x43, 0x4b, 0x49, 0x49, 0x0b, 0x0e, 0x0c, 0x11,
+	0x1c, 0x45, 0x25, 0x40, 0x4a, 0x40, 0x02, 0x07,
+	0x02, 0x0c, 0x0c, 0x15, 0x04, 0x15, 0x03, 0x45,
+	0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07,
+	0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x4a,
+	0x07, 0x0a, 0x0a, 0x14, 0x1c, 0x14, 0x1c, 0x0d,
+	0x17, 0x03, 0x45, 0x17, 0x03, 0x45, 0x40, 0x40,
+	0x40, 0x11, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0b,
+	0x0b, 0x2a, 0x27, 0x1a, 0x07, 0x1c, 0x1a, 0x14,
+	0x42, 0x26, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0b,
+	0x16, 0x0d, 0x21, 0x16, 0x16, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x17, 0x02, 0x4a, 0x40, 0x08, 0x4d,
+	0x57, 0x2a, 0x40, 0x02, 0x40, 0x40, 0x02, 0x0f,
+	0x02, 0x0d, 0x40, 0x12, 0x02, 0x0d, 0x17, 0x2c,
+	0x2c, 0x07, 0x07, 0x05, 0x1a, 0x0d, 0x15, 0x07,
+	0x48, 0x27, 0x1a, 0x0d, 0x40, 0x42, 0x00, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x42, 0x40, 0x05, 0x40,
+	0x02, 0x0a, 0x42, 0x48, 0x48, 0x0d, 0x42, 0x4a,
+	0x48, 0x48, 0x0d, 0x0f, 0x0d, 0x12, 0x42, 0x40,
+	0x05, 0x40, 0x02, 0x0a, 0x42, 0x48, 0x48, 0x0d,
+	0x42, 0x4a, 0x48, 0x48, 0x0d, 0x0f, 0x0d, 0x12,
+	0x1d, 0x45, 0x27, 0x40, 0x4a, 0x40, 0x02, 0x07,
+	0x02, 0x0d, 0x0d, 0x17, 0x05, 0x15, 0x02, 0x45,
+	0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07,
+	0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a,
+	0x07, 0x0a, 0x0a, 0x15, 0x1d, 0x15, 0x1d, 0x0d,
+	0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40,
+	0x40, 0x10, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0a,
+	0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x15,
+	0x42, 0x25, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0a,
+	0x17, 0x0d, 0x22, 0x17, 0x17, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x18, 0x02, 0x4a, 0x40, 0x07, 0x4d,
+	0x58, 0x2a, 0x40, 0x02, 0x40, 0x40, 0x02, 0x0f,
+	0x02, 0x0e, 0x40, 0x12, 0x03, 0x0e, 0x19, 0x2f,
+	0x2f, 0x07, 0x07, 0x05, 0x19, 0x0d, 0x15, 0x07,
+	0x47, 0x27, 0x1b, 0x0d, 0x40, 0x42, 0x40, 0x40,
+	0x40, 0x40, 0x02, 0x02, 0x42, 0x00, 0x05, 0x00,
+	0x03, 0x0b, 0x42, 0x47, 0x47, 0x0e, 0x42, 0x4a,
+	0x47, 0x47, 0x0e, 0x10, 0x0d, 0x13, 0x42, 0x00,
+	0x05, 0x00, 0x03, 0x0b, 0x42, 0x47, 0x47, 0x0e,
+	0x42, 0x4a, 0x47, 0x47, 0x0e, 0x10, 0x0d, 0x13,
+	0x1d, 0x45, 0x29, 0x40, 0x4a, 0x40, 0x02, 0x07,
+	0x02, 0x0d, 0x0d, 0x19, 0x05, 0x15, 0x02, 0x45,
+	0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07,
+	0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a,
+	0x07, 0x0a, 0x0a, 0x15, 0x1d, 0x15, 0x1d, 0x0d,
+	0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40,
+	0x40, 0x0f, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0a,
+	0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x15,
+	0x42, 0x24, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0a,
+	0x18, 0x0d, 0x23, 0x18, 0x18, 0x0d, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x19, 0x03, 0x49, 0x40, 0x06, 0x4e,
+	0x59, 0x2b, 0x40, 0x03, 0x40, 0x40, 0x01, 0x0f,
+	0x03, 0x10, 0x40, 0x13, 0x04, 0x10, 0x1b, 0x31,
+	0x31, 0x07, 0x07, 0x04, 0x17, 0x0c, 0x16, 0x07,
+	0x46, 0x27, 0x1c, 0x0c, 0x40, 0x43, 0x41, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x41, 0x01, 0x06, 0x01,
+	0x04, 0x0c, 0x41, 0x46, 0x46, 0x10, 0x41, 0x49,
+	0x46, 0x46, 0x10, 0x11, 0x0e, 0x14, 0x41, 0x01,
+	0x06, 0x01, 0x04, 0x0c, 0x41, 0x46, 0x46, 0x10,
+	0x41, 0x49, 0x46, 0x46, 0x10, 0x11, 0x0e, 0x14,
+	0x1e, 0x44, 0x2b, 0x40, 0x4b, 0x40, 0x03, 0x07,
+	0x03, 0x0e, 0x0e, 0x1b, 0x06, 0x14, 0x01, 0x44,
+	0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07,
+	0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x4b,
+	0x07, 0x0b, 0x0b, 0x16, 0x1e, 0x16, 0x1e, 0x0c,
+	0x17, 0x01, 0x44, 0x17, 0x01, 0x44, 0x40, 0x40,
+	0x40, 0x0e, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x09,
+	0x09, 0x2b, 0x27, 0x1b, 0x07, 0x1e, 0x1b, 0x16,
+	0x43, 0x22, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x09,
+	0x19, 0x0c, 0x24, 0x19, 0x19, 0x0c, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x1a, 0x03, 0x48, 0x40, 0x05, 0x4f,
+	0x5a, 0x2b, 0x40, 0x03, 0x40, 0x40, 0x00, 0x0f,
+	0x03, 0x11, 0x40, 0x13, 0x06, 0x11, 0x1d, 0x34,
+	0x34, 0x07, 0x07, 0x04, 0x16, 0x0c, 0x17, 0x07,
+	0x45, 0x27, 0x1e, 0x0c, 0x40, 0x43, 0x42, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x40, 0x02, 0x07, 0x02,
+	0x06, 0x0e, 0x40, 0x45, 0x45, 0x11, 0x40, 0x48,
+	0x45, 0x45, 0x11, 0x12, 0x0f, 0x16, 0x40, 0x02,
+	0x07, 0x02, 0x06, 0x0e, 0x40, 0x45, 0x45, 0x11,
+	0x40, 0x48, 0x45, 0x45, 0x11, 0x12, 0x0f, 0x16,
+	0x1f, 0x44, 0x2d, 0x40, 0x4b, 0x40, 0x03, 0x07,
+	0x03, 0x0f, 0x0f, 0x1d, 0x07, 0x14, 0x00, 0x44,
+	0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07,
+	0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b,
+	0x07, 0x0b, 0x0b, 0x17, 0x1f, 0x17, 0x1f, 0x0c,
+	0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40,
+	0x40, 0x0d, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08,
+	0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x17,
+	0x43, 0x21, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x08,
+	0x1a, 0x0c, 0x26, 0x1a, 0x1a, 0x0c, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x1b, 0x03, 0x48, 0x40, 0x04, 0x4f,
+	0x5b, 0x2b, 0x40, 0x03, 0x40, 0x40, 0x00, 0x0f,
+	0x03, 0x13, 0x40, 0x13, 0x07, 0x13, 0x1f, 0x36,
+	0x36, 0x07, 0x07, 0x04, 0x14, 0x0c, 0x17, 0x07,
+	0x44, 0x27, 0x1f, 0x0c, 0x40, 0x43, 0x43, 0x40,
+	0x40, 0x40, 0x03, 0x03, 0x40, 0x03, 0x07, 0x03,
+	0x07, 0x0f, 0x40, 0x44, 0x44, 0x13, 0x40, 0x48,
+	0x44, 0x44, 0x13, 0x13, 0x0f, 0x17, 0x40, 0x03,
+	0x07, 0x03, 0x07, 0x0f, 0x40, 0x44, 0x44, 0x13,
+	0x40, 0x48, 0x44, 0x44, 0x13, 0x13, 0x0f, 0x17,
+	0x1f, 0x44, 0x2f, 0x40, 0x4b, 0x40, 0x03, 0x07,
+	0x03, 0x0f, 0x0f, 0x1f, 0x07, 0x14, 0x00, 0x44,
+	0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07,
+	0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b,
+	0x07, 0x0b, 0x0b, 0x17, 0x1f, 0x17, 0x1f, 0x0c,
+	0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40,
+	0x40, 0x0c, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08,
+	0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x17,
+	0x43, 0x20, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x08,
+	0x1b, 0x0c, 0x27, 0x1b, 0x1b, 0x0c, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x1c, 0x04, 0x47, 0x40, 0x03, 0x50,
+	0x5c, 0x2c, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f,
+	0x04, 0x14, 0x40, 0x14, 0x08, 0x14, 0x21, 0x39,
+	0x39, 0x07, 0x07, 0x03, 0x13, 0x0b, 0x18, 0x07,
+	0x43, 0x27, 0x20, 0x0b, 0x40, 0x44, 0x44, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x00, 0x04, 0x08, 0x04,
+	0x08, 0x10, 0x00, 0x43, 0x43, 0x14, 0x00, 0x47,
+	0x43, 0x43, 0x14, 0x14, 0x10, 0x18, 0x00, 0x04,
+	0x08, 0x04, 0x08, 0x10, 0x00, 0x43, 0x43, 0x14,
+	0x00, 0x47, 0x43, 0x43, 0x14, 0x14, 0x10, 0x18,
+	0x20, 0x43, 0x31, 0x40, 0x4c, 0x40, 0x04, 0x07,
+	0x04, 0x10, 0x10, 0x21, 0x08, 0x13, 0x40, 0x43,
+	0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07,
+	0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x4c,
+	0x07, 0x0c, 0x0c, 0x18, 0x20, 0x18, 0x20, 0x0b,
+	0x17, 0x40, 0x43, 0x17, 0x40, 0x43, 0x40, 0x40,
+	0x40, 0x0b, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x07,
+	0x07, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x18,
+	0x44, 0x1f, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x07,
+	0x1c, 0x0b, 0x28, 0x1c, 0x1c, 0x0b, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x1d, 0x04, 0x47, 0x40, 0x02, 0x51,
+	0x5d, 0x2c, 0x40, 0x04, 0x40, 0x40, 0x41, 0x0f,
+	0x04, 0x16, 0x40, 0x14, 0x09, 0x16, 0x22, 0x3b,
+	0x3b, 0x07, 0x07, 0x03, 0x11, 0x0b, 0x18, 0x07,
+	0x42, 0x27, 0x21, 0x0b, 0x40, 0x44, 0x45, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x00, 0x05, 0x08, 0x05,
+	0x09, 0x11, 0x00, 0x42, 0x42, 0x16, 0x00, 0x47,
+	0x42, 0x42, 0x16, 0x15, 0x10, 0x19, 0x00, 0x05,
+	0x08, 0x05, 0x09, 0x11, 0x00, 0x42, 0x42, 0x16,
+	0x00, 0x47, 0x42, 0x42, 0x16, 0x15, 0x10, 0x19,
+	0x20, 0x43, 0x32, 0x40, 0x4c, 0x40, 0x04, 0x07,
+	0x04, 0x10, 0x10, 0x22, 0x08, 0x13, 0x41, 0x43,
+	0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07,
+	0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c,
+	0x07, 0x0c, 0x0c, 0x18, 0x20, 0x18, 0x20, 0x0b,
+	0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40,
+	0x40, 0x0a, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x06,
+	0x06, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x18,
+	0x44, 0x1d, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x06,
+	0x1d, 0x0b, 0x29, 0x1d, 0x1d, 0x0b, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x1e, 0x04, 0x46, 0x40, 0x01, 0x51,
+	0x5e, 0x2c, 0x40, 0x04, 0x40, 0x40, 0x41, 0x0f,
+	0x04, 0x18, 0x40, 0x14, 0x0b, 0x18, 0x24, 0x3e,
+	0x3e, 0x07, 0x07, 0x03, 0x0f, 0x0b, 0x19, 0x07,
+	0x41, 0x27, 0x23, 0x0b, 0x40, 0x44, 0x46, 0x40,
+	0x40, 0x40, 0x04, 0x04, 0x01, 0x06, 0x09, 0x06,
+	0x0b, 0x13, 0x01, 0x41, 0x41, 0x18, 0x01, 0x46,
+	0x41, 0x41, 0x18, 0x16, 0x11, 0x1b, 0x01, 0x06,
+	0x09, 0x06, 0x0b, 0x13, 0x01, 0x41, 0x41, 0x18,
+	0x01, 0x46, 0x41, 0x41, 0x18, 0x16, 0x11, 0x1b,
+	0x21, 0x43, 0x34, 0x40, 0x4c, 0x40, 0x04, 0x07,
+	0x04, 0x11, 0x11, 0x24, 0x09, 0x13, 0x41, 0x43,
+	0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07,
+	0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c,
+	0x07, 0x0c, 0x0c, 0x19, 0x21, 0x19, 0x21, 0x0b,
+	0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40,
+	0x40, 0x09, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x06,
+	0x06, 0x2c, 0x27, 0x1c, 0x07, 0x21, 0x1c, 0x19,
+	0x44, 0x1c, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x06,
+	0x1e, 0x0b, 0x2b, 0x1e, 0x1e, 0x0b, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x1f, 0x05, 0x45, 0x40, 0x00, 0x52,
+	0x5f, 0x2d, 0x40, 0x05, 0x40, 0x40, 0x42, 0x0f,
+	0x05, 0x19, 0x40, 0x15, 0x0c, 0x19, 0x26, 0x3e,
+	0x3e, 0x07, 0x07, 0x02, 0x0e, 0x0a, 0x1a, 0x07,
+	0x40, 0x27, 0x24, 0x0a, 0x40, 0x45, 0x47, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x02, 0x07, 0x0a, 0x07,
+	0x0c, 0x14, 0x02, 0x40, 0x40, 0x19, 0x02, 0x45,
+	0x40, 0x40, 0x19, 0x17, 0x12, 0x1c, 0x02, 0x07,
+	0x0a, 0x07, 0x0c, 0x14, 0x02, 0x40, 0x40, 0x19,
+	0x02, 0x45, 0x40, 0x40, 0x19, 0x17, 0x12, 0x1c,
+	0x22, 0x42, 0x36, 0x40, 0x4d, 0x40, 0x05, 0x07,
+	0x05, 0x12, 0x12, 0x26, 0x0a, 0x12, 0x42, 0x42,
+	0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07,
+	0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d,
+	0x07, 0x0d, 0x0d, 0x1a, 0x22, 0x1a, 0x22, 0x0a,
+	0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40,
+	0x40, 0x08, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x05,
+	0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x1a,
+	0x45, 0x1b, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x05,
+	0x1f, 0x0a, 0x2c, 0x1f, 0x1f, 0x0a, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x20, 0x05, 0x45, 0x40, 0x40, 0x52,
+	0x60, 0x2d, 0x40, 0x05, 0x40, 0x40, 0x42, 0x0f,
+	0x05, 0x1b, 0x40, 0x15, 0x0d, 0x1b, 0x28, 0x3e,
+	0x3e, 0x07, 0x07, 0x02, 0x0c, 0x0a, 0x1a, 0x07,
+	0x00, 0x27, 0x25, 0x0a, 0x40, 0x45, 0x48, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x02, 0x08, 0x0a, 0x08,
+	0x0d, 0x15, 0x02, 0x00, 0x00, 0x1b, 0x02, 0x45,
+	0x00, 0x00, 0x1b, 0x18, 0x12, 0x1d, 0x02, 0x08,
+	0x0a, 0x08, 0x0d, 0x15, 0x02, 0x00, 0x00, 0x1b,
+	0x02, 0x45, 0x00, 0x00, 0x1b, 0x18, 0x12, 0x1d,
+	0x22, 0x42, 0x38, 0x40, 0x4d, 0x40, 0x05, 0x07,
+	0x05, 0x12, 0x12, 0x28, 0x0a, 0x12, 0x42, 0x42,
+	0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07,
+	0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d,
+	0x07, 0x0d, 0x0d, 0x1a, 0x22, 0x1a, 0x22, 0x0a,
+	0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40,
+	0x40, 0x07, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x05,
+	0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x1a,
+	0x45, 0x1a, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x05,
+	0x20, 0x0a, 0x2d, 0x20, 0x20, 0x0a, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x21, 0x05, 0x44, 0x40, 0x41, 0x53,
+	0x61, 0x2d, 0x40, 0x05, 0x40, 0x40, 0x43, 0x0f,
+	0x05, 0x1c, 0x40, 0x15, 0x0e, 0x1c, 0x2a, 0x3e,
+	0x3e, 0x07, 0x07, 0x02, 0x0b, 0x0a, 0x1b, 0x07,
+	0x01, 0x27, 0x26, 0x0a, 0x40, 0x45, 0x49, 0x40,
+	0x40, 0x40, 0x05, 0x05, 0x03, 0x09, 0x0b, 0x09,
+	0x0e, 0x16, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x44,
+	0x01, 0x01, 0x1c, 0x19, 0x13, 0x1e, 0x03, 0x09,
+	0x0b, 0x09, 0x0e, 0x16, 0x03, 0x01, 0x01, 0x1c,
+	0x03, 0x44, 0x01, 0x01, 0x1c, 0x19, 0x13, 0x1e,
+	0x23, 0x42, 0x3a, 0x40, 0x4d, 0x40, 0x05, 0x07,
+	0x05, 0x13, 0x13, 0x2a, 0x0b, 0x12, 0x43, 0x42,
+	0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07,
+	0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x4d,
+	0x07, 0x0d, 0x0d, 0x1b, 0x23, 0x1b, 0x23, 0x0a,
+	0x17, 0x43, 0x42, 0x17, 0x43, 0x42, 0x40, 0x40,
+	0x40, 0x06, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x04,
+	0x04, 0x2d, 0x27, 0x1d, 0x07, 0x23, 0x1d, 0x1b,
+	0x45, 0x18, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x04,
+	0x21, 0x0a, 0x2e, 0x21, 0x21, 0x0a, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x22, 0x06, 0x43, 0x40, 0x42, 0x54,
+	0x62, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x44, 0x0f,
+	0x06, 0x1e, 0x40, 0x16, 0x10, 0x1e, 0x2c, 0x3e,
+	0x3e, 0x07, 0x07, 0x01, 0x09, 0x09, 0x1c, 0x07,
+	0x02, 0x27, 0x28, 0x09, 0x40, 0x46, 0x4a, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x04, 0x0a, 0x0c, 0x0a,
+	0x10, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x04, 0x43,
+	0x02, 0x02, 0x1e, 0x1a, 0x14, 0x20, 0x04, 0x0a,
+	0x0c, 0x0a, 0x10, 0x18, 0x04, 0x02, 0x02, 0x1e,
+	0x04, 0x43, 0x02, 0x02, 0x1e, 0x1a, 0x14, 0x20,
+	0x24, 0x41, 0x3c, 0x40, 0x4e, 0x40, 0x06, 0x07,
+	0x06, 0x14, 0x14, 0x2c, 0x0c, 0x11, 0x44, 0x41,
+	0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07,
+	0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e,
+	0x07, 0x0e, 0x0e, 0x1c, 0x24, 0x1c, 0x24, 0x09,
+	0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40,
+	0x40, 0x05, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x03,
+	0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x1c,
+	0x46, 0x17, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x03,
+	0x22, 0x09, 0x30, 0x22, 0x22, 0x09, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x23, 0x06, 0x43, 0x40, 0x43, 0x54,
+	0x63, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x44, 0x0f,
+	0x06, 0x1f, 0x40, 0x16, 0x11, 0x1f, 0x2e, 0x3e,
+	0x3e, 0x07, 0x07, 0x01, 0x08, 0x09, 0x1c, 0x07,
+	0x03, 0x27, 0x29, 0x09, 0x40, 0x46, 0x4b, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x04, 0x0b, 0x0c, 0x0b,
+	0x11, 0x19, 0x04, 0x03, 0x03, 0x1f, 0x04, 0x43,
+	0x03, 0x03, 0x1f, 0x1b, 0x14, 0x21, 0x04, 0x0b,
+	0x0c, 0x0b, 0x11, 0x19, 0x04, 0x03, 0x03, 0x1f,
+	0x04, 0x43, 0x03, 0x03, 0x1f, 0x1b, 0x14, 0x21,
+	0x24, 0x41, 0x3e, 0x40, 0x4e, 0x40, 0x06, 0x07,
+	0x06, 0x14, 0x14, 0x2e, 0x0c, 0x11, 0x44, 0x41,
+	0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07,
+	0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e,
+	0x07, 0x0e, 0x0e, 0x1c, 0x24, 0x1c, 0x24, 0x09,
+	0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40,
+	0x40, 0x04, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x03,
+	0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x1c,
+	0x46, 0x16, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x03,
+	0x23, 0x09, 0x31, 0x23, 0x23, 0x09, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x24, 0x06, 0x42, 0x40, 0x44, 0x55,
+	0x64, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x45, 0x0f,
+	0x06, 0x21, 0x40, 0x16, 0x12, 0x21, 0x30, 0x3e,
+	0x3e, 0x07, 0x07, 0x01, 0x06, 0x09, 0x1d, 0x07,
+	0x04, 0x27, 0x2a, 0x09, 0x40, 0x46, 0x4c, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x0d, 0x0c,
+	0x12, 0x1a, 0x05, 0x04, 0x04, 0x21, 0x05, 0x42,
+	0x04, 0x04, 0x21, 0x1c, 0x15, 0x22, 0x05, 0x0c,
+	0x0d, 0x0c, 0x12, 0x1a, 0x05, 0x04, 0x04, 0x21,
+	0x05, 0x42, 0x04, 0x04, 0x21, 0x1c, 0x15, 0x22,
+	0x25, 0x41, 0x3e, 0x40, 0x4e, 0x40, 0x06, 0x07,
+	0x06, 0x15, 0x15, 0x30, 0x0d, 0x11, 0x45, 0x41,
+	0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07,
+	0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x4e,
+	0x07, 0x0e, 0x0e, 0x1d, 0x25, 0x1d, 0x25, 0x09,
+	0x17, 0x45, 0x41, 0x17, 0x45, 0x41, 0x40, 0x40,
+	0x40, 0x03, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x02,
+	0x02, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x1d,
+	0x46, 0x15, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x02,
+	0x24, 0x09, 0x32, 0x24, 0x24, 0x09, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x24, 0x06, 0x42, 0x40, 0x45, 0x56,
+	0x65, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x46, 0x0f,
+	0x06, 0x22, 0x40, 0x16, 0x13, 0x22, 0x31, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x04, 0x08, 0x1d, 0x07,
+	0x04, 0x27, 0x2b, 0x08, 0x40, 0x47, 0x4d, 0x40,
+	0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x0d, 0x0c,
+	0x13, 0x1b, 0x05, 0x04, 0x04, 0x22, 0x05, 0x42,
+	0x04, 0x04, 0x22, 0x1c, 0x15, 0x23, 0x05, 0x0c,
+	0x0d, 0x0c, 0x13, 0x1b, 0x05, 0x04, 0x04, 0x22,
+	0x05, 0x42, 0x04, 0x04, 0x22, 0x1c, 0x15, 0x23,
+	0x25, 0x41, 0x3e, 0x40, 0x4f, 0x40, 0x06, 0x07,
+	0x06, 0x15, 0x15, 0x31, 0x0d, 0x10, 0x46, 0x41,
+	0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07,
+	0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x4f,
+	0x07, 0x0e, 0x0e, 0x1d, 0x25, 0x1d, 0x25, 0x08,
+	0x17, 0x46, 0x41, 0x17, 0x46, 0x41, 0x40, 0x40,
+	0x40, 0x02, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x01,
+	0x01, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x1d,
+	0x47, 0x13, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x01,
+	0x24, 0x08, 0x33, 0x24, 0x24, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x25, 0x07, 0x41, 0x40, 0x45, 0x56,
+	0x65, 0x2f, 0x40, 0x07, 0x40, 0x40, 0x46, 0x0f,
+	0x07, 0x24, 0x40, 0x17, 0x15, 0x24, 0x33, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x03, 0x08, 0x1e, 0x07,
+	0x05, 0x27, 0x2d, 0x08, 0x40, 0x47, 0x4d, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x06, 0x0d, 0x0e, 0x0d,
+	0x15, 0x1d, 0x06, 0x05, 0x05, 0x24, 0x06, 0x41,
+	0x05, 0x05, 0x24, 0x1d, 0x16, 0x25, 0x06, 0x0d,
+	0x0e, 0x0d, 0x15, 0x1d, 0x06, 0x05, 0x05, 0x24,
+	0x06, 0x41, 0x05, 0x05, 0x24, 0x1d, 0x16, 0x25,
+	0x26, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07,
+	0x07, 0x16, 0x16, 0x33, 0x0e, 0x10, 0x46, 0x40,
+	0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07,
+	0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x4f,
+	0x07, 0x0f, 0x0f, 0x1e, 0x26, 0x1e, 0x26, 0x08,
+	0x17, 0x46, 0x40, 0x17, 0x46, 0x40, 0x40, 0x40,
+	0x40, 0x02, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x01,
+	0x01, 0x2f, 0x27, 0x1f, 0x07, 0x26, 0x1f, 0x1e,
+	0x47, 0x12, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x01,
+	0x25, 0x08, 0x35, 0x25, 0x25, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x26, 0x07, 0x40, 0x40, 0x46, 0x57,
+	0x66, 0x2f, 0x40, 0x07, 0x40, 0x40, 0x47, 0x0f,
+	0x07, 0x26, 0x40, 0x17, 0x16, 0x26, 0x35, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x01, 0x08, 0x1f, 0x07,
+	0x06, 0x27, 0x2e, 0x08, 0x40, 0x47, 0x4e, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x07, 0x0e, 0x0f, 0x0e,
+	0x16, 0x1e, 0x07, 0x06, 0x06, 0x26, 0x07, 0x40,
+	0x06, 0x06, 0x26, 0x1e, 0x17, 0x26, 0x07, 0x0e,
+	0x0f, 0x0e, 0x16, 0x1e, 0x07, 0x06, 0x06, 0x26,
+	0x07, 0x40, 0x06, 0x06, 0x26, 0x1e, 0x17, 0x26,
+	0x27, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07,
+	0x07, 0x17, 0x17, 0x35, 0x0f, 0x10, 0x47, 0x40,
+	0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07,
+	0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f,
+	0x07, 0x0f, 0x0f, 0x1f, 0x27, 0x1f, 0x27, 0x08,
+	0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40,
+	0x40, 0x01, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x00,
+	0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x1f,
+	0x47, 0x11, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x00,
+	0x26, 0x08, 0x36, 0x26, 0x26, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x3e, 0x27, 0x07, 0x40, 0x40, 0x47, 0x57,
+	0x67, 0x2f, 0x40, 0x07, 0x40, 0x40, 0x47, 0x0f,
+	0x07, 0x27, 0x40, 0x17, 0x17, 0x27, 0x37, 0x3e,
+	0x3e, 0x07, 0x07, 0x00, 0x00, 0x08, 0x1f, 0x07,
+	0x07, 0x27, 0x2f, 0x08, 0x40, 0x47, 0x4f, 0x40,
+	0x40, 0x40, 0x07, 0x07, 0x07, 0x0f, 0x0f, 0x0f,
+	0x17, 0x1f, 0x07, 0x07, 0x07, 0x27, 0x07, 0x40,
+	0x07, 0x07, 0x27, 0x1f, 0x17, 0x27, 0x07, 0x0f,
+	0x0f, 0x0f, 0x17, 0x1f, 0x07, 0x07, 0x07, 0x27,
+	0x07, 0x40, 0x07, 0x07, 0x27, 0x1f, 0x17, 0x27,
+	0x27, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07,
+	0x07, 0x17, 0x17, 0x37, 0x0f, 0x10, 0x47, 0x40,
+	0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07,
+	0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f,
+	0x07, 0x0f, 0x0f, 0x1f, 0x27, 0x1f, 0x27, 0x08,
+	0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40,
+	0x40, 0x00, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x00,
+	0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x1f,
+	0x47, 0x10, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x00,
+	0x27, 0x08, 0x37, 0x27, 0x27, 0x08, 0x40, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
new file mode 100644
index 0000000000000..63579c08065d4
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
@@ -0,0 +1,546 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip video decoder hevc common functions
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include "rkvdec-hevc-common.h"
+#include "rkvdec.h"
+
+#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES		2
+
+/* Store the Short term ref pic set calculated values */
+struct calculated_rps_st_set {
+	u8 num_delta_pocs;
+	u8 num_negative_pics;
+	u8 num_positive_pics;
+	u8 used_by_curr_pic_s0[16];
+	u8 used_by_curr_pic_s1[16];
+	s32 delta_poc_s0[16];
+	s32 delta_poc_s1[16];
+};
+
+enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx,
+						struct v4l2_ctrl *ctrl)
+{
+	const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
+
+	if (ctrl->id != V4L2_CID_STATELESS_HEVC_SPS)
+		return RKVDEC_IMG_FMT_ANY;
+
+	if (sps->bit_depth_luma_minus8 == 0)
+		return RKVDEC_IMG_FMT_420_8BIT;
+	else if (sps->bit_depth_luma_minus8 == 2)
+		return RKVDEC_IMG_FMT_420_10BIT;
+
+	return RKVDEC_IMG_FMT_ANY;
+}
+
+void compute_tiles_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size,
+			   u16 width, u16 height, s32 pic_in_cts_width,
+			   s32 pic_in_cts_height, u16 *column_width, u16 *row_height)
+{
+	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
+	int i;
+
+	for (i = 0; i < pps->num_tile_columns_minus1 + 1; i++)
+		column_width[i] = ((i + 1) * pic_in_cts_width) /
+				  (pps->num_tile_columns_minus1 + 1) -
+				  (i * pic_in_cts_width) /
+				  (pps->num_tile_columns_minus1 + 1);
+
+	for (i = 0; i < pps->num_tile_rows_minus1 + 1; i++)
+		row_height[i] = ((i + 1) * pic_in_cts_height) /
+				(pps->num_tile_rows_minus1 + 1) -
+				(i * pic_in_cts_height) /
+				(pps->num_tile_rows_minus1 + 1);
+}
+
+void compute_tiles_non_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size,
+			       u16 width, u16 height, s32 pic_in_cts_width,
+			       s32 pic_in_cts_height, u16 *column_width, u16 *row_height)
+{
+	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
+	s32 sum = 0;
+	int i;
+
+	for (i = 0; i < pps->num_tile_columns_minus1; i++) {
+		column_width[i] = pps->column_width_minus1[i] + 1;
+		sum += column_width[i];
+	}
+	column_width[i] = pic_in_cts_width - sum;
+
+	sum = 0;
+	for (i = 0; i < pps->num_tile_rows_minus1; i++) {
+		row_height[i] = pps->row_height_minus1[i] + 1;
+		sum += row_height[i];
+	}
+	row_height[i] = pic_in_cts_height - sum;
+}
+
+static void set_ref_poc(struct rkvdec_rps_short_term_ref_set *set, int poc, int value, int flag)
+{
+	switch (poc) {
+	case 0:
+		set->delta_poc0 = value;
+		set->used_flag0 = flag;
+		break;
+	case 1:
+		set->delta_poc1 = value;
+		set->used_flag1 = flag;
+		break;
+	case 2:
+		set->delta_poc2 = value;
+		set->used_flag2 = flag;
+		break;
+	case 3:
+		set->delta_poc3 = value;
+		set->used_flag3 = flag;
+		break;
+	case 4:
+		set->delta_poc4 = value;
+		set->used_flag4 = flag;
+		break;
+	case 5:
+		set->delta_poc5 = value;
+		set->used_flag5 = flag;
+		break;
+	case 6:
+		set->delta_poc6 = value;
+		set->used_flag6 = flag;
+		break;
+	case 7:
+		set->delta_poc7 = value;
+		set->used_flag7 = flag;
+		break;
+	case 8:
+		set->delta_poc8 = value;
+		set->used_flag8 = flag;
+		break;
+	case 9:
+		set->delta_poc9 = value;
+		set->used_flag9 = flag;
+		break;
+	case 10:
+		set->delta_poc10 = value;
+		set->used_flag10 = flag;
+		break;
+	case 11:
+		set->delta_poc11 = value;
+		set->used_flag11 = flag;
+		break;
+	case 12:
+		set->delta_poc12 = value;
+		set->used_flag12 = flag;
+		break;
+	case 13:
+		set->delta_poc13 = value;
+		set->used_flag13 = flag;
+		break;
+	case 14:
+		set->delta_poc14 = value;
+		set->used_flag14 = flag;
+		break;
+	}
+}
+
+/*
+ * Flip one or more matrices along their main diagonal and flatten them
+ * before writing it to the memory.
+ * Convert:
+ * ABCD         AEIM
+ * EFGH     =>  BFJN     =>     AEIMBFJNCGKODHLP
+ * IJKL         CGKO
+ * MNOP         DHLP
+ */
+static void transpose_and_flatten_matrices(u8 *output, const u8 *input,
+					   int matrices, int row_length)
+{
+	int i, j, row, x_offset, matrix_offset, rot_index, y_offset, matrix_size, new_value;
+
+	matrix_size = row_length * row_length;
+	for (i = 0; i < matrices; i++) {
+		row = 0;
+		x_offset = 0;
+		matrix_offset = i * matrix_size;
+		for (j = 0; j < matrix_size; j++) {
+			y_offset = j - (row * row_length);
+			rot_index = y_offset * row_length + x_offset;
+			new_value = *(input + i * matrix_size + j);
+			output[matrix_offset + rot_index] = new_value;
+			if ((j + 1) % row_length == 0) {
+				row += 1;
+				x_offset += 1;
+			}
+		}
+	}
+}
+
+static void assemble_scalingfactor0(struct rkvdec_dev *rkvdec, u8 *output,
+				    const struct v4l2_ctrl_hevc_scaling_matrix *input)
+{
+	int offset = 0;
+
+	transpose_and_flatten_matrices(output, (const u8 *)input->scaling_list_4x4, 6, 4);
+	offset = 6 * 16 * sizeof(u8);
+	transpose_and_flatten_matrices(output + offset,
+				       (const u8 *)input->scaling_list_8x8, 6, 8);
+	offset += 6 * 64 * sizeof(u8);
+	transpose_and_flatten_matrices(output + offset,
+				       (const u8 *)input->scaling_list_16x16, 6, 8);
+	offset += 6 * 64 * sizeof(u8);
+
+	/* Add a 128 byte padding with 0s between the two 32x32 matrices */
+	transpose_and_flatten_matrices(output + offset,
+				       (const u8 *)input->scaling_list_32x32, 1, 8);
+	offset += 64 * sizeof(u8);
+	memset(output + offset, 0, 128);
+	offset += 128 * sizeof(u8);
+	transpose_and_flatten_matrices(output + offset,
+				       (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)),
+				       1, 8);
+	offset += 64 * sizeof(u8);
+	memset(output + offset, 0, 128);
+}
+
+/*
+ * Required layout:
+ * A = scaling_list_dc_coef_16x16
+ * B = scaling_list_dc_coef_32x32
+ * 0 = Padding
+ *
+ * A, A, A, A, A, A, B, 0, 0, B, 0, 0
+ */
+static void assemble_scalingdc(u8 *output, const struct v4l2_ctrl_hevc_scaling_matrix *input)
+{
+	u8 list_32x32[6] = {0};
+
+	memcpy(output, input->scaling_list_dc_coef_16x16, 6 * sizeof(u8));
+	list_32x32[0] = input->scaling_list_dc_coef_32x32[0];
+	list_32x32[3] = input->scaling_list_dc_coef_32x32[1];
+	memcpy(output + 6 * sizeof(u8), list_32x32, 6 * sizeof(u8));
+}
+
+static void translate_scaling_list(struct rkvdec_dev *rkvdec, struct scaling_factor *output,
+				   const struct v4l2_ctrl_hevc_scaling_matrix *input)
+{
+	assemble_scalingfactor0(rkvdec, output->scalingfactor0, input);
+	memcpy(output->scalingfactor1, (const u8 *)input->scaling_list_4x4, 96);
+	assemble_scalingdc(output->scalingdc, input);
+	memset(output->reserved, 0, 4 * sizeof(u8));
+}
+
+void rkvdec_hevc_assemble_hw_scaling_list(struct rkvdec_dev *rkvdec,
+					  struct rkvdec_hevc_run *run,
+					  struct scaling_factor *scaling_list,
+					  struct v4l2_ctrl_hevc_scaling_matrix *cache)
+{
+	const struct v4l2_ctrl_hevc_scaling_matrix *scaling = run->scaling_matrix;
+
+	if (!memcmp(cache, scaling,
+		    sizeof(struct v4l2_ctrl_hevc_scaling_matrix)))
+		return;
+
+	translate_scaling_list(rkvdec, scaling_list, scaling);
+
+	memcpy(cache, scaling,
+	       sizeof(struct v4l2_ctrl_hevc_scaling_matrix));
+}
+
+static void rkvdec_hevc_assemble_hw_lt_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps)
+{
+	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
+
+	if (!run->ext_sps_lt_rps)
+		return;
+
+	for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
+		rps->refs[i].lt_ref_pic_poc_lsb =
+			run->ext_sps_lt_rps[i].lt_ref_pic_poc_lsb_sps;
+		rps->refs[i].used_by_curr_pic_lt_flag =
+			!!(run->ext_sps_lt_rps[i].flags & V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT);
+	}
+}
+
+static void rkvdec_hevc_assemble_hw_st_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
+					   struct calculated_rps_st_set *calculated_rps_st_sets)
+{
+	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
+
+	for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) {
+		int poc = 0;
+		int j = 0;
+		const struct calculated_rps_st_set *set = &calculated_rps_st_sets[i];
+
+		rps->short_term_ref_sets[i].num_negative = set->num_negative_pics;
+		rps->short_term_ref_sets[i].num_positive = set->num_positive_pics;
+
+		for (; j < set->num_negative_pics; j++) {
+			set_ref_poc(&rps->short_term_ref_sets[i], j,
+				    set->delta_poc_s0[j], set->used_by_curr_pic_s0[j]);
+		}
+		poc = j;
+
+		for (j = 0; j < set->num_positive_pics; j++) {
+			set_ref_poc(&rps->short_term_ref_sets[i], poc + j,
+				    set->delta_poc_s1[j], set->used_by_curr_pic_s1[j]);
+		}
+	}
+}
+
+/*
+ * Compute the short term ref pic set parameters based on its reference short term ref pic
+ */
+static void st_ref_pic_set_prediction(struct rkvdec_hevc_run *run, int idx,
+				      struct calculated_rps_st_set *calculated_rps_st_sets)
+{
+	const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
+	struct calculated_rps_st_set *st_rps = &calculated_rps_st_sets[idx];
+	struct calculated_rps_st_set *ref_rps;
+	u8 st_rps_idx = idx;
+	u8 ref_rps_idx = 0;
+	s16 delta_rps = 0;
+	u8 use_delta_flag[16] = { 0 };
+	u8 used_by_curr_pic_flag[16] = { 0 };
+	int i, j;
+	int dPoc;
+
+	ref_rps_idx = st_rps_idx - (rps_data->delta_idx_minus1 + 1); /* 7-59 */
+	delta_rps = (1 - 2 * rps_data->delta_rps_sign) *
+		   (rps_data->abs_delta_rps_minus1 + 1); /* 7-60 */
+
+	ref_rps = &calculated_rps_st_sets[ref_rps_idx];
+
+	for (j = 0; j <= ref_rps->num_delta_pocs; j++) {
+		used_by_curr_pic_flag[j] = !!(rps_data->used_by_curr_pic & (1 << j));
+		use_delta_flag[j] = !!(rps_data->use_delta_flag & (1 << j));
+	}
+
+	/* 7-61: calculate num_negative_pics, delta_poc_s0 and used_by_curr_pic_s0 */
+	i = 0;
+	for (j = (ref_rps->num_positive_pics - 1); j >= 0; j--) {
+		dPoc = ref_rps->delta_poc_s1[j] + delta_rps;
+		if (dPoc < 0 && use_delta_flag[ref_rps->num_negative_pics + j]) {
+			st_rps->delta_poc_s0[i] = dPoc;
+			st_rps->used_by_curr_pic_s0[i++] =
+				used_by_curr_pic_flag[ref_rps->num_negative_pics + j];
+		}
+	}
+	if (delta_rps < 0 && use_delta_flag[ref_rps->num_delta_pocs]) {
+		st_rps->delta_poc_s0[i] = delta_rps;
+		st_rps->used_by_curr_pic_s0[i++] = used_by_curr_pic_flag[ref_rps->num_delta_pocs];
+	}
+	for (j = 0; j < ref_rps->num_negative_pics; j++) {
+		dPoc = ref_rps->delta_poc_s0[j] + delta_rps;
+		if (dPoc < 0 && use_delta_flag[j]) {
+			st_rps->delta_poc_s0[i] = dPoc;
+			st_rps->used_by_curr_pic_s0[i++] = used_by_curr_pic_flag[j];
+		}
+	}
+	st_rps->num_negative_pics = i;
+
+	/* 7-62: calculate num_positive_pics, delta_poc_s1 and used_by_curr_pic_s1 */
+	i = 0;
+	for (j = (ref_rps->num_negative_pics - 1); j >= 0; j--) {
+		dPoc = ref_rps->delta_poc_s0[j] + delta_rps;
+		if (dPoc > 0 && use_delta_flag[j]) {
+			st_rps->delta_poc_s1[i] = dPoc;
+			st_rps->used_by_curr_pic_s1[i++] = used_by_curr_pic_flag[j];
+		}
+	}
+	if (delta_rps > 0 && use_delta_flag[ref_rps->num_delta_pocs]) {
+		st_rps->delta_poc_s1[i] = delta_rps;
+		st_rps->used_by_curr_pic_s1[i++] = used_by_curr_pic_flag[ref_rps->num_delta_pocs];
+	}
+	for (j = 0; j < ref_rps->num_positive_pics; j++) {
+		dPoc = ref_rps->delta_poc_s1[j] + delta_rps;
+		if (dPoc > 0 && use_delta_flag[ref_rps->num_negative_pics + j]) {
+			st_rps->delta_poc_s1[i] = dPoc;
+			st_rps->used_by_curr_pic_s1[i++] =
+				used_by_curr_pic_flag[ref_rps->num_negative_pics + j];
+		}
+	}
+	st_rps->num_positive_pics = i;
+
+	st_rps->num_delta_pocs = st_rps->num_positive_pics + st_rps->num_negative_pics;
+}
+
+/*
+ * Compute the short term ref pic set parameters based on the control's data.
+ */
+static void st_ref_pic_set_calculate(struct rkvdec_hevc_run *run, int idx,
+				     struct calculated_rps_st_set *calculated_rps_st_sets)
+{
+	const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
+	struct calculated_rps_st_set *st_rps = &calculated_rps_st_sets[idx];
+	int j, i = 0;
+
+	/* 7-63 */
+	st_rps->num_negative_pics = rps_data->num_negative_pics;
+	/* 7-64 */
+	st_rps->num_positive_pics = rps_data->num_positive_pics;
+
+	for (i = 0; i < st_rps->num_negative_pics; i++) {
+		/* 7-65 */
+		st_rps->used_by_curr_pic_s0[i] = !!(rps_data->used_by_curr_pic & (1 << i));
+
+		if (i == 0) {
+			/* 7-67 */
+			st_rps->delta_poc_s0[i] = -(rps_data->delta_poc_s0_minus1[i] + 1);
+		} else {
+			/* 7-69 */
+			st_rps->delta_poc_s0[i] =
+				st_rps->delta_poc_s0[i - 1] -
+				(rps_data->delta_poc_s0_minus1[i] + 1);
+		}
+	}
+
+	for (j = 0; j < st_rps->num_positive_pics; j++) {
+		/* 7-66 */
+		st_rps->used_by_curr_pic_s1[j] = !!(rps_data->used_by_curr_pic & (1 << (i + j)));
+
+		if (j == 0) {
+			/* 7-68 */
+			st_rps->delta_poc_s1[j] = rps_data->delta_poc_s1_minus1[j] + 1;
+		} else {
+			/* 7-70 */
+			st_rps->delta_poc_s1[j] =
+				st_rps->delta_poc_s1[j - 1] +
+				(rps_data->delta_poc_s1_minus1[j] + 1);
+		}
+	}
+
+	/* 7-71 */
+	st_rps->num_delta_pocs = st_rps->num_positive_pics + st_rps->num_negative_pics;
+}
+
+static void rkvdec_hevc_prepare_hw_st_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
+					  struct v4l2_ctrl_hevc_ext_sps_st_rps *cache)
+{
+	int idx;
+
+	if (!run->ext_sps_st_rps)
+		return;
+
+	if (!memcmp(cache, run->ext_sps_st_rps, sizeof(struct v4l2_ctrl_hevc_ext_sps_st_rps)))
+		return;
+
+	struct calculated_rps_st_set *calculated_rps_st_sets =
+		kzalloc(sizeof(struct calculated_rps_st_set) *
+			run->sps->num_short_term_ref_pic_sets, GFP_KERNEL);
+
+	for (idx = 0; idx < run->sps->num_short_term_ref_pic_sets; idx++) {
+		const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
+
+		if (rps_data->flags & V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED)
+			st_ref_pic_set_prediction(run, idx, calculated_rps_st_sets);
+		else
+			st_ref_pic_set_calculate(run, idx, calculated_rps_st_sets);
+	}
+
+	rkvdec_hevc_assemble_hw_st_rps(run, rps, calculated_rps_st_sets);
+
+	kfree(calculated_rps_st_sets);
+
+	memcpy(cache, run->ext_sps_st_rps, sizeof(struct v4l2_ctrl_hevc_ext_sps_st_rps));
+}
+
+void rkvdec_hevc_assemble_hw_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
+				 struct v4l2_ctrl_hevc_ext_sps_st_rps *st_cache)
+{
+	rkvdec_hevc_prepare_hw_st_rps(run, rps, st_cache);
+	rkvdec_hevc_assemble_hw_lt_rps(run, rps);
+}
+
+struct vb2_buffer *get_ref_buf(struct rkvdec_ctx *ctx,
+			       struct rkvdec_hevc_run *run,
+			       unsigned int dpb_idx)
+{
+	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+	const struct v4l2_ctrl_hevc_decode_params *decode_params = run->decode_params;
+	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
+	struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+	struct vb2_buffer *buf = NULL;
+
+	if (dpb_idx < decode_params->num_active_dpb_entries)
+		buf = vb2_find_buffer(cap_q, dpb[dpb_idx].timestamp);
+
+	/*
+	 * If a DPB entry is unused or invalid, the address of current destination
+	 * buffer is returned.
+	 */
+	if (!buf)
+		return &run->base.bufs.dst->vb2_buf;
+
+	return buf;
+}
+
+int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx,
+			   struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
+
+	fmt->num_planes = 1;
+	if (!fmt->plane_fmt[0].sizeimage)
+		fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
+					      RKVDEC_HEVC_MAX_DEPTH_IN_BYTES;
+	return 0;
+}
+
+int rkvdec_hevc_validate_sps(struct rkvdec_ctx *ctx,
+			     const struct v4l2_ctrl_hevc_sps *sps)
+{
+	/* Only 4:2:0 is supported */
+	if (sps->chroma_format_idc != 1)
+		return -EINVAL;
+
+	/* Luma and chroma bit depth mismatch */
+	if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
+		return -EINVAL;
+
+	/* Only 8-bit and 10-bit are supported */
+	if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
+		return -EINVAL;
+
+	if (sps->pic_width_in_luma_samples > ctx->coded_fmt.fmt.pix_mp.width ||
+	    sps->pic_height_in_luma_samples > ctx->coded_fmt.fmt.pix_mp.height)
+		return -EINVAL;
+
+	return 0;
+}
+
+void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx,
+			      struct rkvdec_hevc_run *run)
+{
+	struct v4l2_ctrl *ctrl;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
+	run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
+	run->slice_params = ctrl ? ctrl->p_cur.p : NULL;
+	run->num_slices = ctrl ? ctrl->new_elems : 0;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_SPS);
+	run->sps = ctrl ? ctrl->p_cur.p : NULL;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_PPS);
+	run->pps = ctrl ? ctrl->p_cur.p : NULL;
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
+	run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS);
+	run->ext_sps_st_rps = ctrl ? ctrl->p_cur.p : NULL;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS);
+	run->ext_sps_lt_rps = ctrl ? ctrl->p_cur.p : NULL;
+
+	rkvdec_run_preamble(ctx, &run->base);
+}
+
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
new file mode 100644
index 0000000000000..b98f65318d96f
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip video decoder hevc common functions
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <linux/types.h>
+
+#include "rkvdec.h"
+
+struct rkvdec_rps_refs {
+	u16 lt_ref_pic_poc_lsb;
+	u16 used_by_curr_pic_lt_flag	: 1;
+	u16 reserved			: 15;
+} __packed;
+
+struct rkvdec_rps_short_term_ref_set {
+	u32 num_negative	: 4;
+	u32 num_positive	: 4;
+	u32 delta_poc0		: 16;
+	u32 used_flag0		: 1;
+	u32 delta_poc1		: 16;
+	u32 used_flag1		: 1;
+	u32 delta_poc2		: 16;
+	u32 used_flag2		: 1;
+	u32 delta_poc3		: 16;
+	u32 used_flag3		: 1;
+	u32 delta_poc4		: 16;
+	u32 used_flag4		: 1;
+	u32 delta_poc5		: 16;
+	u32 used_flag5		: 1;
+	u32 delta_poc6		: 16;
+	u32 used_flag6		: 1;
+	u32 delta_poc7		: 16;
+	u32 used_flag7		: 1;
+	u32 delta_poc8		: 16;
+	u32 used_flag8		: 1;
+	u32 delta_poc9		: 16;
+	u32 used_flag9		: 1;
+	u32 delta_poc10		: 16;
+	u32 used_flag10		: 1;
+	u32 delta_poc11		: 16;
+	u32 used_flag11		: 1;
+	u32 delta_poc12		: 16;
+	u32 used_flag12		: 1;
+	u32 delta_poc13		: 16;
+	u32 used_flag13		: 1;
+	u32 delta_poc14		: 16;
+	u32 used_flag14		: 1;
+	u32 reserved_bits	: 25;
+	u32 reserved[3];
+} __packed;
+
+struct rkvdec_rps {
+	struct rkvdec_rps_refs refs[32];
+	struct rkvdec_rps_short_term_ref_set short_term_ref_sets[64];
+} __packed;
+
+struct rkvdec_hevc_run {
+	struct rkvdec_run				base;
+	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
+	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
+	const struct v4l2_ctrl_hevc_sps			*sps;
+	const struct v4l2_ctrl_hevc_pps			*pps;
+	const struct v4l2_ctrl_hevc_scaling_matrix	*scaling_matrix;
+	const struct v4l2_ctrl_hevc_ext_sps_st_rps	*ext_sps_st_rps;
+	const struct v4l2_ctrl_hevc_ext_sps_lt_rps	*ext_sps_lt_rps;
+	int						num_slices;
+};
+
+struct scaling_factor {
+	u8 scalingfactor0[1248];
+	u8 scalingfactor1[96];		/*4X4 TU Rotate, total 16X4*/
+	u8 scalingdc[12];		/*N1005 Vienna Meeting*/
+	u8 reserved[4];			/*16Bytes align*/
+} __packed;
+
+extern const u8 rkvdec_hevc_cabac_table[27456];
+
+enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx,
+						struct v4l2_ctrl *ctrl);
+void compute_tiles_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size,
+			   u16 width, u16 height, s32 pic_in_cts_width,
+			   s32 pic_in_cts_height, u16 *column_width, u16 *row_height);
+void compute_tiles_non_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size,
+			       u16 width, u16 height, s32 pic_in_cts_width,
+			       s32 pic_in_cts_height, u16 *column_width, u16 *row_height);
+void rkvdec_hevc_assemble_hw_rps(struct rkvdec_hevc_run *run, struct rkvdec_rps *rps,
+				 struct v4l2_ctrl_hevc_ext_sps_st_rps *st_cache);
+void rkvdec_hevc_assemble_hw_scaling_list(struct rkvdec_dev *rkvdec,
+					  struct rkvdec_hevc_run *run,
+					  struct scaling_factor *scaling_factor,
+					  struct v4l2_ctrl_hevc_scaling_matrix *cache);
+struct vb2_buffer *get_ref_buf(struct rkvdec_ctx *ctx,
+			       struct rkvdec_hevc_run *run,
+			       unsigned int dpb_idx);
+int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f);
+int rkvdec_hevc_validate_sps(struct rkvdec_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps);
+void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run);
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
new file mode 100644
index 0000000000000..efe0fa48bfcc0
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
@@ -0,0 +1,596 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip VDPU381 HEVC backend
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+#include "rkvdec-rcb.h"
+#include "rkvdec-hevc-common.h"
+#include "rkvdec-vdpu381-regs.h"
+
+// SPS
+struct rkvdec_hevc_sps {
+	u16 video_parameters_set_id			: 4;
+	u16 seq_parameters_set_id_sps			: 4;
+	u16 chroma_format_idc				: 2;
+	u16 width					: 16;
+	u16 height					: 16;
+	u16 bit_depth_luma				: 4;
+	u16 bit_depth_chroma				: 4;
+	u16 max_pic_order_count_lsb			: 5;
+	u16 diff_max_min_luma_coding_block_size		: 2;
+	u16 min_luma_coding_block_size			: 3;
+	u16 min_transform_block_size			: 3;
+	u16 diff_max_min_transform_block_size		: 2;
+	u16 max_transform_hierarchy_depth_inter		: 3;
+	u16 max_transform_hierarchy_depth_intra		: 3;
+	u16 scaling_list_enabled_flag			: 1;
+	u16 amp_enabled_flag				: 1;
+	u16 sample_adaptive_offset_enabled_flag		: 1;
+	u16 pcm_enabled_flag				: 1;
+	u16 pcm_sample_bit_depth_luma			: 4;
+	u16 pcm_sample_bit_depth_chroma			: 4;
+	u16 pcm_loop_filter_disabled_flag		: 1;
+	u16 diff_max_min_pcm_luma_coding_block_size	: 3;
+	u16 min_pcm_luma_coding_block_size		: 3;
+	u16 num_short_term_ref_pic_sets			: 7;
+	u16 long_term_ref_pics_present_flag		: 1;
+	u16 num_long_term_ref_pics_sps			: 6;
+	u16 sps_temporal_mvp_enabled_flag		: 1;
+	u16 strong_intra_smoothing_enabled_flag		: 1;
+	u16 reserved_0					: 7;
+	u16 sps_max_dec_pic_buffering_minus1		: 4;
+	u16 reserved_0_2				: 3;
+	u16 reserved_f					: 8;
+} __packed;
+
+//PPS
+struct rkvdec_hevc_pps {
+	u16 picture_parameters_set_id			: 6;
+	u16 seq_parameters_set_id_pps			: 4;
+	u16 dependent_slice_segments_enabled_flag	: 1;
+	u16 output_flag_present_flag			: 1;
+	u16 num_extra_slice_header_bits			: 13;
+	u16 sign_data_hiding_enabled_flag		: 1;
+	u16 cabac_init_present_flag			: 1;
+	u16 num_ref_idx_l0_default_active		: 4;
+	u16 num_ref_idx_l1_default_active		: 4;
+	u16 init_qp_minus26				: 7;
+	u16 constrained_intra_pred_flag			: 1;
+	u16 transform_skip_enabled_flag			: 1;
+	u16 cu_qp_delta_enabled_flag			: 1;
+	u16 log2_min_cb_size				: 3;
+	u16 pps_cb_qp_offset				: 5;
+	u16 pps_cr_qp_offset				: 5;
+	u16 pps_slice_chroma_qp_offsets_present_flag	: 1;
+	u16 weighted_pred_flag				: 1;
+	u16 weighted_bipred_flag			: 1;
+	u16 transquant_bypass_enabled_flag		: 1;
+	u16 tiles_enabled_flag				: 1;
+	u16 entropy_coding_sync_enabled_flag		: 1;
+	u16 pps_loop_filter_across_slices_enabled_flag	: 1;
+	u16 loop_filter_across_tiles_enabled_flag	: 1;
+	u16 deblocking_filter_override_enabled_flag	: 1;
+	u16 pps_deblocking_filter_disabled_flag		: 1;
+	u16 pps_beta_offset_div2			: 4;
+	u16 pps_tc_offset_div2				: 4;
+	u16 lists_modification_present_flag		: 1;
+	u16 log2_parallel_merge_level			: 3;
+	u16 slice_segment_header_extension_present_flag	: 1;
+	u16 zeroes					: 3;
+	u16 num_tile_columns				: 5;
+	u16 num_tile_rows				: 5;
+	u16 sps_pps_mode				: 4;
+	u16 reserved_bits				: 14;
+	u16 reserved;
+} __packed;
+
+struct rkvdec_hevc_tile {
+	u16 value0	: 12;
+	u16 value1	: 12;
+} __packed;
+
+struct rkvdec_sps_pps_packet {
+	struct rkvdec_hevc_sps sps;
+	struct rkvdec_hevc_pps pps;
+	struct rkvdec_hevc_tile column_width[10];
+	struct rkvdec_hevc_tile row_height[11];
+	u32 zeroes[3];
+	u32 zeroes_bits		: 6;
+	u32 padding_bits	: 2;
+	u32 padding;
+} __packed;
+
+struct rkvdec_hevc_priv_tbl {
+	struct rkvdec_sps_pps_packet param_set[64];
+	struct rkvdec_rps rps;
+	struct scaling_factor scaling_list;
+	u8 cabac_table[27456];
+};
+
+struct rkvdec_hevc_ctx {
+	struct rkvdec_aux_buf			priv_tbl;
+	struct v4l2_ctrl_hevc_scaling_matrix	scaling_matrix_cache;
+	struct v4l2_ctrl_hevc_ext_sps_st_rps	st_cache;
+	struct rkvdec_vdpu381_regs_hevc		regs;
+};
+
+static void assemble_hw_pps(struct rkvdec_ctx *ctx,
+			    struct rkvdec_hevc_run *run)
+{
+	struct rkvdec_hevc_ctx *h264_ctx = ctx->priv;
+	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
+	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
+	struct rkvdec_hevc_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
+	struct rkvdec_sps_pps_packet *hw_ps;
+	bool tiles_enabled;
+	s32 max_cu_width;
+	s32 pic_in_cts_width;
+	s32 pic_in_cts_height;
+	u16 log2_min_cb_size, width, height;
+	u16 column_width[20];
+	u16 row_height[22];
+	u8 pcm_enabled;
+	u32 i;
+
+	/*
+	 * HW read the SPS/PPS information from PPS packet index by PPS id.
+	 * offset from the base can be calculated by PPS_id * 32 (size per PPS
+	 * packet unit). so the driver copy SPS/PPS information to the exact PPS
+	 * packet unit for HW accessing.
+	 */
+	hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
+	memset(hw_ps, 0, sizeof(*hw_ps));
+
+	/* write sps */
+	hw_ps->sps.video_parameters_set_id = sps->video_parameter_set_id;
+	hw_ps->sps.seq_parameters_set_id_sps = sps->seq_parameter_set_id;
+	hw_ps->sps.chroma_format_idc = sps->chroma_format_idc;
+
+	log2_min_cb_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
+	width = sps->pic_width_in_luma_samples;
+	height = sps->pic_height_in_luma_samples;
+	hw_ps->sps.width = width;
+	hw_ps->sps.height = height;
+	hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
+	hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
+	hw_ps->sps.max_pic_order_count_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
+	hw_ps->sps.diff_max_min_luma_coding_block_size =
+		sps->log2_diff_max_min_luma_coding_block_size;
+	hw_ps->sps.min_luma_coding_block_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
+	hw_ps->sps.min_transform_block_size = sps->log2_min_luma_transform_block_size_minus2 + 2;
+	hw_ps->sps.diff_max_min_transform_block_size =
+		sps->log2_diff_max_min_luma_transform_block_size;
+	hw_ps->sps.max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
+	hw_ps->sps.max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
+	hw_ps->sps.scaling_list_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED);
+	hw_ps->sps.amp_enabled_flag = !!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED);
+	hw_ps->sps.sample_adaptive_offset_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET);
+
+	pcm_enabled = !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED);
+	hw_ps->sps.pcm_enabled_flag = pcm_enabled;
+	hw_ps->sps.pcm_sample_bit_depth_luma =
+		pcm_enabled ? sps->pcm_sample_bit_depth_luma_minus1 + 1 : 0;
+	hw_ps->sps.pcm_sample_bit_depth_chroma =
+		pcm_enabled ? sps->pcm_sample_bit_depth_chroma_minus1 + 1 : 0;
+	hw_ps->sps.pcm_loop_filter_disabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED);
+	hw_ps->sps.diff_max_min_pcm_luma_coding_block_size =
+		sps->log2_diff_max_min_pcm_luma_coding_block_size;
+	hw_ps->sps.min_pcm_luma_coding_block_size =
+		pcm_enabled ? sps->log2_min_pcm_luma_coding_block_size_minus3 + 3 : 0;
+	hw_ps->sps.num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
+	hw_ps->sps.long_term_ref_pics_present_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT);
+	hw_ps->sps.num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
+	hw_ps->sps.sps_temporal_mvp_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED);
+	hw_ps->sps.strong_intra_smoothing_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED);
+	hw_ps->sps.sps_max_dec_pic_buffering_minus1 = sps->sps_max_dec_pic_buffering_minus1;
+	hw_ps->sps.reserved_f = 0xff;
+
+	/* write pps */
+	hw_ps->pps.picture_parameters_set_id = pps->pic_parameter_set_id;
+	hw_ps->pps.seq_parameters_set_id_pps = sps->seq_parameter_set_id;
+	hw_ps->pps.dependent_slice_segments_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED);
+	hw_ps->pps.output_flag_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT);
+	hw_ps->pps.num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
+	hw_ps->pps.sign_data_hiding_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED);
+	hw_ps->pps.cabac_init_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT);
+	hw_ps->pps.num_ref_idx_l0_default_active = pps->num_ref_idx_l0_default_active_minus1 + 1;
+	hw_ps->pps.num_ref_idx_l1_default_active = pps->num_ref_idx_l1_default_active_minus1 + 1;
+	hw_ps->pps.init_qp_minus26 = pps->init_qp_minus26;
+	hw_ps->pps.constrained_intra_pred_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	hw_ps->pps.transform_skip_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED);
+	hw_ps->pps.cu_qp_delta_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED);
+	hw_ps->pps.log2_min_cb_size = log2_min_cb_size +
+				      sps->log2_diff_max_min_luma_coding_block_size -
+				      pps->diff_cu_qp_delta_depth;
+	hw_ps->pps.pps_cb_qp_offset = pps->pps_cb_qp_offset;
+	hw_ps->pps.pps_cr_qp_offset = pps->pps_cr_qp_offset;
+	hw_ps->pps.pps_slice_chroma_qp_offsets_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT);
+	hw_ps->pps.weighted_pred_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED);
+	hw_ps->pps.weighted_bipred_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED);
+	hw_ps->pps.transquant_bypass_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED);
+
+	tiles_enabled = !!(pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED);
+	hw_ps->pps.tiles_enabled_flag = tiles_enabled;
+	hw_ps->pps.entropy_coding_sync_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED);
+	hw_ps->pps.pps_loop_filter_across_slices_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED);
+	hw_ps->pps.loop_filter_across_tiles_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED);
+	hw_ps->pps.deblocking_filter_override_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED);
+	hw_ps->pps.pps_deblocking_filter_disabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER);
+	hw_ps->pps.pps_beta_offset_div2 = pps->pps_beta_offset_div2;
+	hw_ps->pps.pps_tc_offset_div2 = pps->pps_tc_offset_div2;
+	hw_ps->pps.lists_modification_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT);
+	hw_ps->pps.log2_parallel_merge_level = pps->log2_parallel_merge_level_minus2 + 2;
+	hw_ps->pps.slice_segment_header_extension_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT);
+	hw_ps->pps.num_tile_columns = tiles_enabled ? pps->num_tile_columns_minus1 + 1 : 0;
+	hw_ps->pps.num_tile_rows = tiles_enabled ? pps->num_tile_rows_minus1 + 1 : 0;
+	hw_ps->pps.sps_pps_mode = 0;
+	hw_ps->pps.reserved_bits = 0x3fff;
+	hw_ps->pps.reserved = 0xffff;
+
+	// Setup tiles information
+	memset(column_width, 0, sizeof(column_width));
+	memset(row_height, 0, sizeof(row_height));
+
+	max_cu_width = 1 << (sps->log2_diff_max_min_luma_coding_block_size + log2_min_cb_size);
+	pic_in_cts_width = (width + max_cu_width - 1) / max_cu_width;
+	pic_in_cts_height = (height + max_cu_width - 1) / max_cu_width;
+
+	if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) {
+		if (pps->flags & V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING) {
+			compute_tiles_uniform(run, log2_min_cb_size, width, height,
+					      pic_in_cts_width, pic_in_cts_height,
+					      column_width, row_height);
+		} else {
+			compute_tiles_non_uniform(run, log2_min_cb_size, width, height,
+						  pic_in_cts_width, pic_in_cts_height,
+						  column_width, row_height);
+		}
+	} else {
+		column_width[0] = (width + max_cu_width - 1) / max_cu_width;
+		row_height[0] = (height + max_cu_width - 1) / max_cu_width;
+	}
+
+	for (i = 0; i < 20; i++) {
+		if (column_width[i] > 0)
+			column_width[i]--;
+
+		if (i & 1)
+			hw_ps->column_width[i / 2].value1 = column_width[i];
+		else
+			hw_ps->column_width[i / 2].value0 = column_width[i];
+	}
+
+	for (i = 0; i < 22; i++) {
+		if (row_height[i] > 0)
+			row_height[i]--;
+
+		if (i & 1)
+			hw_ps->row_height[i / 2].value1 = row_height[i];
+		else
+			hw_ps->row_height[i / 2].value0 = row_height[i];
+	}
+
+	hw_ps->padding = 0xffffffff;
+	hw_ps->padding_bits = 0x3;
+}
+
+static void set_ref_valid(struct rkvdec_vdpu381_regs_hevc *regs, int id, u32 valid)
+{
+	switch (id) {
+	case 0:
+		regs->hevc_param.reg099.hevc_ref_valid_0 = valid;
+		break;
+	case 1:
+		regs->hevc_param.reg099.hevc_ref_valid_1 = valid;
+		break;
+	case 2:
+		regs->hevc_param.reg099.hevc_ref_valid_2 = valid;
+		break;
+	case 3:
+		regs->hevc_param.reg099.hevc_ref_valid_3 = valid;
+		break;
+	case 4:
+		regs->hevc_param.reg099.hevc_ref_valid_4 = valid;
+		break;
+	case 5:
+		regs->hevc_param.reg099.hevc_ref_valid_5 = valid;
+		break;
+	case 6:
+		regs->hevc_param.reg099.hevc_ref_valid_6 = valid;
+		break;
+	case 7:
+		regs->hevc_param.reg099.hevc_ref_valid_7 = valid;
+		break;
+	case 8:
+		regs->hevc_param.reg099.hevc_ref_valid_8 = valid;
+		break;
+	case 9:
+		regs->hevc_param.reg099.hevc_ref_valid_9 = valid;
+		break;
+	case 10:
+		regs->hevc_param.reg099.hevc_ref_valid_10 = valid;
+		break;
+	case 11:
+		regs->hevc_param.reg099.hevc_ref_valid_11 = valid;
+		break;
+	case 12:
+		regs->hevc_param.reg099.hevc_ref_valid_12 = valid;
+		break;
+	case 13:
+		regs->hevc_param.reg099.hevc_ref_valid_13 = valid;
+		break;
+	case 14:
+		regs->hevc_param.reg099.hevc_ref_valid_14 = valid;
+		break;
+	}
+}
+
+static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
+
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_COMMON_REGS,
+			   &hevc_ctx->regs.common,
+			   sizeof(hevc_ctx->regs.common));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_CODEC_PARAMS_REGS,
+			   &hevc_ctx->regs.hevc_param,
+			   sizeof(hevc_ctx->regs.hevc_param));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_COMMON_ADDR_REGS,
+			   &hevc_ctx->regs.common_addr,
+			   sizeof(hevc_ctx->regs.common_addr));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_CODEC_ADDR_REGS,
+			   &hevc_ctx->regs.hevc_addr,
+			   sizeof(hevc_ctx->regs.hevc_addr));
+	rkvdec_memcpy_toio(rkvdec->regs + OFFSET_POC_HIGHBIT_REGS,
+			   &hevc_ctx->regs.hevc_highpoc,
+			   sizeof(hevc_ctx->regs.hevc_highpoc));
+}
+
+static void config_registers(struct rkvdec_ctx *ctx,
+			     struct rkvdec_hevc_run *run)
+{
+	const struct v4l2_ctrl_hevc_decode_params *dec_params = run->decode_params;
+	const struct v4l2_hevc_dpb_entry *dpb = dec_params->dpb;
+	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
+	struct rkvdec_vdpu381_regs_hevc *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;
+	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
+	const struct v4l2_format *f;
+	dma_addr_t rlc_addr;
+	u32 hor_virstride = 0;
+	u32 ver_virstride = 0;
+	u32 y_virstride = 0;
+	u32 offset;
+	u32 pixels;
+	dma_addr_t dst_addr;
+	u32 i;
+
+	memset(regs, 0, sizeof(*regs));
+
+	/* Set HEVC mode */
+	regs->common.reg009.dec_mode = VDPU381_MODE_HEVC;
+
+	/* Set config */
+	regs->common.reg011.buf_empty_en = 1;
+	regs->common.reg011.dec_clkgate_e = 1;
+	regs->common.reg011.dec_timeout_e = 1;
+	regs->common.reg011.pix_range_detection_e = 1;
+
+	/* Set IDR flag */
+	regs->common.reg013.cur_pic_is_idr =
+		!!(dec_params->flags & V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC);
+
+	/* Set input stream length */
+	regs->common.stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+
+	/* Set max slice number */
+	regs->common.reg017.slice_num = 1;
+
+	/* Set strides */
+	f = &ctx->decoded_fmt;
+	dst_fmt = &f->fmt.pix_mp;
+	hor_virstride = dst_fmt->plane_fmt[0].bytesperline;
+	ver_virstride = dst_fmt->height;
+	y_virstride = hor_virstride * ver_virstride;
+	pixels = dst_fmt->height * dst_fmt->width;
+
+	regs->common.reg018.y_hor_virstride = hor_virstride / 16;
+	regs->common.reg019.uv_hor_virstride = hor_virstride / 16;
+	regs->common.reg020.y_virstride = y_virstride / 16;
+
+	/* Activate block gating */
+	regs->common.reg026.swreg_block_gating_e = 0xfffef;
+	regs->common.reg026.reg_cfg_gating_en = 1;
+
+	/* Set timeout threshold */
+	if (pixels < RKVDEC_1080P_PIXELS)
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_1080p;
+	else if (pixels < RKVDEC_4K_PIXELS)
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_4K;
+	else if (pixels < RKVDEC_8K_PIXELS)
+		regs->common.timeout_threshold = RKVDEC_TIMEOUT_8K;
+
+	/* Set POC val */
+	regs->hevc_param.cur_top_poc = dec_params->pic_order_cnt_val;
+
+	/* Set ref pic address & poc */
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		struct vb2_buffer *vb_buf = get_ref_buf(ctx, run, i);
+		dma_addr_t buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
+		u32 valid = !!(dec_params->num_active_dpb_entries > i);
+
+		/* Set reference addresses */
+		regs->hevc_addr.ref_base[i] = buf_dma;
+
+		/* Set COLMV addresses */
+		regs->hevc_addr.colmv_base[i] = buf_dma + ctx->colmv_offset;
+
+		regs->hevc_param.reg067_082_ref_poc[i] =
+			dpb[i].pic_order_cnt_val;
+
+		set_ref_valid(regs, i, valid);
+		regs->hevc_param.reg103.ref_pic_layer_same_with_cur |= 1 << i;
+	}
+
+	/* Set rlc base address (input stream) */
+	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	regs->common_addr.rlc_base = rlc_addr;
+	regs->common_addr.rlcwrite_base = rlc_addr;
+
+	/* Set output base address */
+	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+	regs->common_addr.decout_base = dst_addr;
+	regs->common_addr.error_ref_base = dst_addr;
+
+	/* Set colmv address */
+	regs->common_addr.colmv_cur_base = dst_addr + ctx->colmv_offset;
+
+	/* Set RCB addresses */
+	for (i = 0; i < rkvdec_rcb_buf_count(ctx); i++)
+		regs->common_addr.rcb_base[i] = rkvdec_rcb_buf_dma_addr(ctx, i);
+
+	/* Set hw pps address */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, param_set);
+	regs->hevc_addr.pps_base = priv_start_addr + offset;
+
+	/* Set hw rps address */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, rps);
+	regs->hevc_addr.rps_base = priv_start_addr + offset;
+
+	/* Set cabac table */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, cabac_table);
+	regs->hevc_addr.cabactbl_base = priv_start_addr + offset;
+
+	/* Set scaling matrix */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, scaling_list);
+	regs->hevc_addr.scanlist_addr = priv_start_addr + offset;
+
+	rkvdec_write_regs(ctx);
+}
+
+static int rkvdec_hevc_start(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_hevc_priv_tbl *priv_tbl;
+	struct rkvdec_hevc_ctx *hevc_ctx;
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_SPS);
+	if (!ctrl)
+		return -EINVAL;
+
+	ret = rkvdec_hevc_validate_sps(ctx, ctrl->p_new.p_hevc_sps);
+	if (ret)
+		return ret;
+
+	hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL);
+	if (!hevc_ctx)
+		return -ENOMEM;
+
+	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+				      &hevc_ctx->priv_tbl.dma, GFP_KERNEL);
+	if (!priv_tbl) {
+		ret = -ENOMEM;
+		goto err_free_ctx;
+	}
+
+	hevc_ctx->priv_tbl.size = sizeof(*priv_tbl);
+	hevc_ctx->priv_tbl.cpu = priv_tbl;
+	memcpy(priv_tbl->cabac_table, rkvdec_hevc_cabac_table,
+	       sizeof(rkvdec_hevc_cabac_table));
+
+	ctx->priv = hevc_ctx;
+	return 0;
+
+err_free_ctx:
+	kfree(hevc_ctx);
+	return ret;
+}
+
+static void rkvdec_hevc_stop(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+
+	dma_free_coherent(rkvdec->dev, hevc_ctx->priv_tbl.size,
+			  hevc_ctx->priv_tbl.cpu, hevc_ctx->priv_tbl.dma);
+	kfree(hevc_ctx);
+}
+
+static int rkvdec_hevc_run(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_hevc_run run;
+	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
+	struct rkvdec_hevc_priv_tbl *tbl = hevc_ctx->priv_tbl.cpu;
+
+	rkvdec_hevc_run_preamble(ctx, &run);
+
+	rkvdec_hevc_assemble_hw_scaling_list(rkvdec,
+					     &run,
+					     &tbl->scaling_list,
+					     &hevc_ctx->scaling_matrix_cache);
+	assemble_hw_pps(ctx, &run);
+	rkvdec_hevc_assemble_hw_rps(&run, &tbl->rps, &hevc_ctx->st_cache);
+
+	config_registers(ctx, &run);
+
+	rkvdec_run_postamble(ctx, &run.base);
+
+	schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
+
+	/* Start decoding! */
+	writel(VDPU381_DEC_E_BIT, rkvdec->regs + VDPU381_REG_DEC_E);
+
+	return 0;
+}
+
+static int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl)
+{
+	if (ctrl->id == V4L2_CID_STATELESS_HEVC_SPS)
+		return rkvdec_hevc_validate_sps(ctx, ctrl->p_new.p_hevc_sps);
+
+	return 0;
+}
+
+const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_hevc_fmt_ops = {
+	.adjust_fmt = rkvdec_hevc_adjust_fmt,
+	.start = rkvdec_hevc_start,
+	.stop = rkvdec_hevc_stop,
+	.run = rkvdec_hevc_run,
+	.try_ctrl = rkvdec_hevc_try_ctrl,
+	.get_image_fmt = rkvdec_hevc_get_image_fmt,
+};
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index dab34a2322c95..cd01f1e41beb5 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -257,6 +257,60 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
 	.num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
 };
 
+static const struct rkvdec_ctrl_desc rkvdec_hevc_ctrl_descs[] = {
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_SPS,
+		.cfg.ops = &rkvdec_ctrl_ops,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_PPS,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_MODE,
+		.cfg.min = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
+		.cfg.max = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
+		.cfg.def = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_START_CODE,
+		.cfg.min = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
+		.cfg.def = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
+		.cfg.max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
+	},
+	{
+		.cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+		.cfg.min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+		.cfg.max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+		.cfg.menu_skip_mask =
+			BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE),
+		.cfg.def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+	},
+	{
+		.cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+		.cfg.min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+		.cfg.max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS,
+		.cfg.dims = { 65 },
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS,
+		.cfg.dims = { 65 },
+	},
+};
+
+static const struct rkvdec_ctrls rkvdec_hevc_ctrls = {
+	.ctrls = rkvdec_hevc_ctrl_descs,
+	.num_ctrls = ARRAY_SIZE(rkvdec_hevc_ctrl_descs),
+};
+
 static const struct rkvdec_decoded_fmt_desc rkvdec_h264_decoded_fmts[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_NV12,
@@ -276,6 +330,17 @@ static const struct rkvdec_decoded_fmt_desc rkvdec_h264_decoded_fmts[] = {
 	},
 };
 
+static const struct rkvdec_decoded_fmt_desc rkvdec_hevc_decoded_fmts[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.image_fmt = RKVDEC_IMG_FMT_420_8BIT,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV15,
+		.image_fmt = RKVDEC_IMG_FMT_420_10BIT,
+	},
+};
+
 static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
 	{
 		.cfg.id = V4L2_CID_STATELESS_VP9_FRAME,
@@ -354,6 +419,22 @@ static const struct rkvdec_coded_fmt_desc vdpu381_coded_fmts[] = {
 		.decoded_fmts = rkvdec_h264_decoded_fmts,
 		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
 	},
+	{
+		.fourcc = V4L2_PIX_FMT_HEVC_SLICE,
+		.frmsize = {
+			.min_width = 16,
+			.max_width = 65472,
+			.step_width = 16,
+			.min_height = 16,
+			.max_height = 65472,
+			.step_height = 16,
+		},
+		.ctrls = &rkvdec_hevc_ctrls,
+		.ops = &rkvdec_vdpu381_hevc_fmt_ops,
+		.num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts),
+		.decoded_fmts = rkvdec_hevc_decoded_fmts,
+		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
+	},
 };
 
 static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = {
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index acb9d72b130bb..df56bc0516ac9 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -173,6 +173,7 @@ extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
 
 /* VDPU381 ops */
 extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_h264_fmt_ops;
+extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_hevc_fmt_ops;
 
 /* VDPU383 ops */
 extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops;
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 12/12] media: rkvdec: Add HEVC support for the VDPU383 variant
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (10 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant Detlev Casanova
@ 2025-08-08 20:03 ` Detlev Casanova
  2025-08-11  9:56 ` [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Heiko Stübner
  2025-08-12  7:20 ` Piotr Oniszczuk
  13 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-08 20:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Detlev Casanova, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, kernel

The VDPU383 decoder is used on the RK3576 SoC and has support for HEVC.

This patch also moves some functions to a common rkvdec-hevc-common.c
file and adds a specific scaling matrix flatten function.

The fluster score for JCT-VC-HEVC_V1 is 146/147.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
 .../media/platform/rockchip/rkvdec/Makefile   |   1 +
 .../rockchip/rkvdec/rkvdec-hevc-common.c      |  49 +-
 .../rockchip/rkvdec/rkvdec-vdpu383-hevc.c     | 688 ++++++++++++++++++
 .../media/platform/rockchip/rkvdec/rkvdec.c   |  91 +++
 .../media/platform/rockchip/rkvdec/rkvdec.h   |   2 +
 5 files changed, 789 insertions(+), 42 deletions(-)
 create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c

diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
index fbc8d0d639ab6..3e072099894ea 100644
--- a/drivers/media/platform/rockchip/rkvdec/Makefile
+++ b/drivers/media/platform/rockchip/rkvdec/Makefile
@@ -10,4 +10,5 @@ rockchip-vdec-y += \
 		   rkvdec-vdpu381-h264.o \
 		   rkvdec-vdpu381-hevc.o \
 		   rkvdec-vdpu383-h264.o \
+		   rkvdec-vdpu383-hevc.o \
 		   rkvdec-vp9.o
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
index 63579c08065d4..c37a24165e493 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
@@ -146,61 +146,26 @@ static void set_ref_poc(struct rkvdec_rps_short_term_ref_set *set, int poc, int
 	}
 }
 
-/*
- * Flip one or more matrices along their main diagonal and flatten them
- * before writing it to the memory.
- * Convert:
- * ABCD         AEIM
- * EFGH     =>  BFJN     =>     AEIMBFJNCGKODHLP
- * IJKL         CGKO
- * MNOP         DHLP
- */
-static void transpose_and_flatten_matrices(u8 *output, const u8 *input,
-					   int matrices, int row_length)
-{
-	int i, j, row, x_offset, matrix_offset, rot_index, y_offset, matrix_size, new_value;
-
-	matrix_size = row_length * row_length;
-	for (i = 0; i < matrices; i++) {
-		row = 0;
-		x_offset = 0;
-		matrix_offset = i * matrix_size;
-		for (j = 0; j < matrix_size; j++) {
-			y_offset = j - (row * row_length);
-			rot_index = y_offset * row_length + x_offset;
-			new_value = *(input + i * matrix_size + j);
-			output[matrix_offset + rot_index] = new_value;
-			if ((j + 1) % row_length == 0) {
-				row += 1;
-				x_offset += 1;
-			}
-		}
-	}
-}
-
 static void assemble_scalingfactor0(struct rkvdec_dev *rkvdec, u8 *output,
 				    const struct v4l2_ctrl_hevc_scaling_matrix *input)
 {
+	struct rkvdec_config *cfg = rkvdec->config;
 	int offset = 0;
 
-	transpose_and_flatten_matrices(output, (const u8 *)input->scaling_list_4x4, 6, 4);
+	cfg->flatten_matrices(output, (const u8 *)input->scaling_list_4x4, 6, 4);
 	offset = 6 * 16 * sizeof(u8);
-	transpose_and_flatten_matrices(output + offset,
-				       (const u8 *)input->scaling_list_8x8, 6, 8);
+	cfg->flatten_matrices(output + offset, (const u8 *)input->scaling_list_8x8, 6, 8);
 	offset += 6 * 64 * sizeof(u8);
-	transpose_and_flatten_matrices(output + offset,
-				       (const u8 *)input->scaling_list_16x16, 6, 8);
+	cfg->flatten_matrices(output + offset, (const u8 *)input->scaling_list_16x16, 6, 8);
 	offset += 6 * 64 * sizeof(u8);
 
 	/* Add a 128 byte padding with 0s between the two 32x32 matrices */
-	transpose_and_flatten_matrices(output + offset,
-				       (const u8 *)input->scaling_list_32x32, 1, 8);
+	cfg->flatten_matrices(output + offset, (const u8 *)input->scaling_list_32x32, 1, 8);
 	offset += 64 * sizeof(u8);
 	memset(output + offset, 0, 128);
 	offset += 128 * sizeof(u8);
-	transpose_and_flatten_matrices(output + offset,
-				       (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)),
-				       1, 8);
+	cfg->flatten_matrices(output + offset,
+			      (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)), 1, 8);
 	offset += 64 * sizeof(u8);
 	memset(output + offset, 0, 128);
 }
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
new file mode 100644
index 0000000000000..c465e3df2c314
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip VDPU383 HEVC backend
+ *
+ * Copyright (C) 2025 Collabora, Ltd.
+ *  Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <media/v4l2-mem2mem.h>
+
+#include "rkvdec.h"
+#include "rkvdec-rcb.h"
+#include "rkvdec-hevc-common.h"
+#include "rkvdec-vdpu383-regs.h"
+
+struct rkvdec_hevc_sps_pps {
+	// SPS
+	u16 video_parameters_set_id			: 4;
+	u16 seq_parameters_set_id_sps			: 4;
+	u16 chroma_format_idc				: 2;
+	u16 width					: 16;
+	u16 height					: 16;
+	u16 bit_depth_luma				: 3;
+	u16 bit_depth_chroma				: 3;
+	u16 max_pic_order_count_lsb			: 5;
+	u16 diff_max_min_luma_coding_block_size		: 2;
+	u16 min_luma_coding_block_size			: 3;
+	u16 min_transform_block_size			: 3;
+	u16 diff_max_min_transform_block_size		: 2;
+	u16 max_transform_hierarchy_depth_inter		: 3;
+	u16 max_transform_hierarchy_depth_intra		: 3;
+	u16 scaling_list_enabled_flag			: 1;
+	u16 amp_enabled_flag				: 1;
+	u16 sample_adaptive_offset_enabled_flag		: 1;
+	u16 pcm_enabled_flag				: 1;
+	u16 pcm_sample_bit_depth_luma			: 4;
+	u16 pcm_sample_bit_depth_chroma			: 4;
+	u16 pcm_loop_filter_disabled_flag		: 1;
+	u16 diff_max_min_pcm_luma_coding_block_size	: 3;
+	u16 min_pcm_luma_coding_block_size		: 3;
+	u16 num_short_term_ref_pic_sets			: 7;
+	u16 long_term_ref_pics_present_flag		: 1;
+	u16 num_long_term_ref_pics_sps			: 6;
+	u16 sps_temporal_mvp_enabled_flag		: 1;
+	u16 strong_intra_smoothing_enabled_flag		: 1;
+	u16 reserved0					: 7;
+	u16 sps_max_dec_pic_buffering_minus1		: 4;
+	u16 separate_colour_plane_flag			: 1;
+	u16 high_precision_offsets_enabled_flag		: 1;
+	u16 persistent_rice_adaptation_enabled_flag	: 1;
+
+	// PPS
+	u16 picture_parameters_set_id			: 6;
+	u16 seq_parameters_set_id_pps			: 4;
+	u16 dependent_slice_segments_enabled_flag	: 1;
+	u16 output_flag_present_flag			: 1;
+	u16 num_extra_slice_header_bits			: 13;
+	u16 sign_data_hiding_enabled_flag		: 1;
+	u16 cabac_init_present_flag			: 1;
+	u16 num_ref_idx_l0_default_active		: 4;
+	u16 num_ref_idx_l1_default_active		: 4;
+	u16 init_qp_minus26				: 7;
+	u16 constrained_intra_pred_flag			: 1;
+	u16 transform_skip_enabled_flag			: 1;
+	u16 cu_qp_delta_enabled_flag			: 1;
+	u16 log2_min_cb_size				: 3;
+	u16 pps_cb_qp_offset				: 5;
+	u16 pps_cr_qp_offset				: 5;
+	u16 pps_slice_chroma_qp_offsets_present_flag	: 1;
+	u16 weighted_pred_flag				: 1;
+	u16 weighted_bipred_flag			: 1;
+	u16 transquant_bypass_enabled_flag		: 1;
+	u16 tiles_enabled_flag				: 1;
+	u16 entropy_coding_sync_enabled_flag		: 1;
+	u16 pps_loop_filter_across_slices_enabled_flag	: 1;
+	u16 loop_filter_across_tiles_enabled_flag	: 1;
+	u16 deblocking_filter_override_enabled_flag	: 1;
+	u16 pps_deblocking_filter_disabled_flag		: 1;
+	u16 pps_beta_offset_div2			: 4;
+	u16 pps_tc_offset_div2				: 4;
+	u16 lists_modification_present_flag		: 1;
+	u16 log2_parallel_merge_level			: 3;
+	u16 slice_segment_header_extension_present_flag	: 1;
+	u16 reserved1					: 3;
+
+	// pps extensions
+	u16 log2_max_transform_skip_block_size		: 2;
+	u16 cross_component_prediction_enabled_flag	: 1;
+	u16 chroma_qp_offset_list_enabled_flag		: 1;
+	u16 log2_min_cu_chroma_qp_delta_size		: 3;
+	u16 cb_qp_offset_list0				: 5;
+	u16 cb_qp_offset_list1				: 5;
+	u16 cb_qp_offset_list2				: 5;
+	u16 cb_qp_offset_list3				: 5;
+	u16 cb_qp_offset_list4				: 5;
+	u16 cb_qp_offset_list5				: 5;
+	u16 cb_cr_offset_list0				: 5;
+	u16 cb_cr_offset_list1				: 5;
+	u16 cb_cr_offset_list2				: 5;
+	u16 cb_cr_offset_list3				: 5;
+	u16 cb_cr_offset_list4				: 5;
+	u16 cb_cr_offset_list5				: 5;
+	u16 chroma_qp_offset_list_len_minus1		: 3;
+
+	/* mvc0 && mvc1 */
+	u16 mvc_ff					: 16;
+	u16 mvc_00					: 9;
+
+	/* poc info */
+	u16 reserved2					: 3;
+	u32 current_poc					: 32;
+	u32 ref_pic_poc0				: 32;
+	u32 ref_pic_poc1				: 32;
+	u32 ref_pic_poc2				: 32;
+	u32 ref_pic_poc3				: 32;
+	u32 ref_pic_poc4				: 32;
+	u32 ref_pic_poc5				: 32;
+	u32 ref_pic_poc6				: 32;
+	u32 ref_pic_poc7				: 32;
+	u32 ref_pic_poc8				: 32;
+	u32 ref_pic_poc9				: 32;
+	u32 ref_pic_poc10				: 32;
+	u32 ref_pic_poc11				: 32;
+	u32 ref_pic_poc12				: 32;
+	u32 ref_pic_poc13				: 32;
+	u32 ref_pic_poc14				: 32;
+	u32 reserved3					: 32;
+	u32 ref_is_valid				: 15;
+	u32 reserved4					: 1;
+
+	/* tile info*/
+	u16 num_tile_columns				: 5;
+	u16 num_tile_rows				: 5;
+	u32 column_width0				: 24;
+	u32 column_width1				: 24;
+	u32 column_width2				: 24;
+	u32 column_width3				: 24;
+	u32 column_width4				: 24;
+	u32 column_width5				: 24;
+	u32 column_width6				: 24;
+	u32 column_width7				: 24;
+	u32 column_width8				: 24;
+	u32 column_width9				: 24;
+	u32 row_height0					: 24;
+	u32 row_height1					: 24;
+	u32 row_height2					: 24;
+	u32 row_height3					: 24;
+	u32 row_height4					: 24;
+	u32 row_height5					: 24;
+	u32 row_height6					: 24;
+	u32 row_height7					: 24;
+	u32 row_height8					: 24;
+	u32 row_height9					: 24;
+	u32 row_height10				: 24;
+	u32 reserved5					: 2;
+	u32 padding;
+} __packed;
+
+struct rkvdec_hevc_priv_tbl {
+	struct rkvdec_hevc_sps_pps param_set;
+	struct rkvdec_rps rps;
+	struct scaling_factor scaling_list;
+	u8 cabac_table[27456];
+}  __packed;
+
+struct rkvdec_hevc_ctx {
+	struct rkvdec_aux_buf			priv_tbl;
+	struct v4l2_ctrl_hevc_scaling_matrix	scaling_matrix_cache;
+	struct v4l2_ctrl_hevc_ext_sps_st_rps	st_cache;
+	struct vdpu383_regs_h26x		regs;
+};
+
+static void set_column_row(struct rkvdec_hevc_sps_pps *hw_ps, u16 column, u16 row, int i)
+{
+	int shift = (i & 1) ? 12 : 0;
+
+	switch (i / 2) {
+	case 0:
+		hw_ps->column_width0 |= column << shift;
+		hw_ps->row_height0 |= row << shift;
+		break;
+	case 1:
+		hw_ps->column_width1 |= column << shift;
+		hw_ps->row_height1 |= row << shift;
+		break;
+	case 2:
+		hw_ps->column_width2 |= column << shift;
+		hw_ps->row_height2 |= row << shift;
+		break;
+	case 3:
+		hw_ps->column_width3 |= column << shift;
+		hw_ps->row_height3 |= row << shift;
+		break;
+	case 4:
+		hw_ps->column_width4 |= column << shift;
+		hw_ps->row_height4 |= row << shift;
+		break;
+	case 5:
+		hw_ps->column_width5 |= column << shift;
+		hw_ps->row_height5 |= row << shift;
+		break;
+	case 6:
+		hw_ps->column_width6 |= column << shift;
+		hw_ps->row_height6 |= row << shift;
+		break;
+	case 7:
+		hw_ps->column_width7 |= column << shift;
+		hw_ps->row_height7 |= row << shift;
+		break;
+	case 8:
+		hw_ps->column_width8 |= column << shift;
+		hw_ps->row_height8 |= row << shift;
+		break;
+	case 9:
+		hw_ps->column_width9 |= column << shift;
+		hw_ps->row_height9 |= row << shift;
+		break;
+	case 10:
+		hw_ps->row_height10 |= row << shift;
+		break;
+	}
+}
+
+static void set_pps_ref_pic_poc(struct rkvdec_hevc_sps_pps *hw_ps, u32 poc, int i)
+{
+	switch (i) {
+	case 0:
+		hw_ps->ref_pic_poc0 = poc;
+		break;
+	case 1:
+		hw_ps->ref_pic_poc1 = poc;
+		break;
+	case 2:
+		hw_ps->ref_pic_poc2 = poc;
+		break;
+	case 3:
+		hw_ps->ref_pic_poc3 = poc;
+		break;
+	case 4:
+		hw_ps->ref_pic_poc4 = poc;
+		break;
+	case 5:
+		hw_ps->ref_pic_poc5 = poc;
+		break;
+	case 6:
+		hw_ps->ref_pic_poc6 = poc;
+		break;
+	case 7:
+		hw_ps->ref_pic_poc7 = poc;
+		break;
+	case 8:
+		hw_ps->ref_pic_poc8 = poc;
+		break;
+	case 9:
+		hw_ps->ref_pic_poc9 = poc;
+		break;
+	case 10:
+		hw_ps->ref_pic_poc10 = poc;
+		break;
+	case 11:
+		hw_ps->ref_pic_poc11 = poc;
+		break;
+	case 12:
+		hw_ps->ref_pic_poc12 = poc;
+		break;
+	case 13:
+		hw_ps->ref_pic_poc13 = poc;
+		break;
+	case 14:
+		hw_ps->ref_pic_poc14 = poc;
+		break;
+	}
+}
+
+static void assemble_hw_pps(struct rkvdec_ctx *ctx,
+			    struct rkvdec_hevc_run *run)
+{
+	struct rkvdec_hevc_ctx *h264_ctx = ctx->priv;
+	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
+	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
+	const struct v4l2_ctrl_hevc_decode_params *dec_params = run->decode_params;
+	struct rkvdec_hevc_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
+	struct rkvdec_hevc_sps_pps *hw_ps;
+	bool tiles_enabled;
+	s32 max_cu_width;
+	s32 pic_in_cts_width;
+	s32 pic_in_cts_height;
+	u16 log2_min_cb_size, width, height;
+	u16 column_width[22];
+	u16 row_height[22];
+	u8 pcm_enabled;
+	u32 i;
+
+	/*
+	 * HW read the SPS/PPS information from PPS packet index by PPS id.
+	 * offset from the base can be calculated by PPS_id * 32 (size per PPS
+	 * packet unit). so the driver copy SPS/PPS information to the exact PPS
+	 * packet unit for HW accessing.
+	 */
+	hw_ps = &priv_tbl->param_set;
+	memset(hw_ps, 0, sizeof(*hw_ps));
+
+	/* write sps */
+	hw_ps->video_parameters_set_id = sps->video_parameter_set_id;
+	hw_ps->seq_parameters_set_id_sps = sps->seq_parameter_set_id;
+	hw_ps->chroma_format_idc = sps->chroma_format_idc;
+
+	log2_min_cb_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
+	width = sps->pic_width_in_luma_samples;
+	height = sps->pic_height_in_luma_samples;
+	hw_ps->width = width;
+	hw_ps->height = height;
+	hw_ps->bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
+	hw_ps->bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
+	hw_ps->max_pic_order_count_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
+	hw_ps->diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_luma_coding_block_size;
+	hw_ps->min_luma_coding_block_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
+	hw_ps->min_transform_block_size = sps->log2_min_luma_transform_block_size_minus2 + 2;
+	hw_ps->diff_max_min_transform_block_size =
+		sps->log2_diff_max_min_luma_transform_block_size;
+	hw_ps->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
+	hw_ps->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
+	hw_ps->scaling_list_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED);
+	hw_ps->amp_enabled_flag = !!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED);
+	hw_ps->sample_adaptive_offset_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET);
+
+	pcm_enabled = !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED);
+	hw_ps->pcm_enabled_flag = pcm_enabled;
+	hw_ps->pcm_sample_bit_depth_luma =
+		pcm_enabled ? sps->pcm_sample_bit_depth_luma_minus1 + 1 : 0;
+	hw_ps->pcm_sample_bit_depth_chroma =
+		pcm_enabled ? sps->pcm_sample_bit_depth_chroma_minus1 + 1 : 0;
+	hw_ps->pcm_loop_filter_disabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED);
+	hw_ps->diff_max_min_pcm_luma_coding_block_size =
+		sps->log2_diff_max_min_pcm_luma_coding_block_size;
+	hw_ps->min_pcm_luma_coding_block_size =
+		pcm_enabled ? sps->log2_min_pcm_luma_coding_block_size_minus3 + 3 : 0;
+	hw_ps->num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
+	hw_ps->long_term_ref_pics_present_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT);
+	hw_ps->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
+	hw_ps->sps_temporal_mvp_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED);
+	hw_ps->strong_intra_smoothing_enabled_flag =
+		!!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED);
+	hw_ps->sps_max_dec_pic_buffering_minus1 = sps->sps_max_dec_pic_buffering_minus1;
+
+	/* write pps */
+	hw_ps->picture_parameters_set_id = pps->pic_parameter_set_id;
+	hw_ps->seq_parameters_set_id_pps = sps->seq_parameter_set_id;
+	hw_ps->dependent_slice_segments_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED);
+	hw_ps->output_flag_present_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT);
+	hw_ps->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
+	hw_ps->sign_data_hiding_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED);
+	hw_ps->cabac_init_present_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT);
+	hw_ps->num_ref_idx_l0_default_active = pps->num_ref_idx_l0_default_active_minus1 + 1;
+	hw_ps->num_ref_idx_l1_default_active = pps->num_ref_idx_l1_default_active_minus1 + 1;
+	hw_ps->init_qp_minus26 = pps->init_qp_minus26;
+	hw_ps->constrained_intra_pred_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	hw_ps->transform_skip_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED);
+	hw_ps->cu_qp_delta_enabled_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED);
+	hw_ps->log2_min_cb_size = log2_min_cb_size +
+				  sps->log2_diff_max_min_luma_coding_block_size -
+				  pps->diff_cu_qp_delta_depth;
+	hw_ps->pps_cb_qp_offset = pps->pps_cb_qp_offset;
+	hw_ps->pps_cr_qp_offset = pps->pps_cr_qp_offset;
+	hw_ps->pps_slice_chroma_qp_offsets_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT);
+	hw_ps->weighted_pred_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED);
+	hw_ps->weighted_bipred_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED);
+	hw_ps->transquant_bypass_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED);
+	tiles_enabled = !!(pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED);
+	hw_ps->tiles_enabled_flag = tiles_enabled;
+	hw_ps->entropy_coding_sync_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED);
+	hw_ps->pps_loop_filter_across_slices_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED);
+	hw_ps->loop_filter_across_tiles_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED);
+	hw_ps->deblocking_filter_override_enabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED);
+	hw_ps->pps_deblocking_filter_disabled_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER);
+	hw_ps->pps_beta_offset_div2 = pps->pps_beta_offset_div2;
+	hw_ps->pps_tc_offset_div2 = pps->pps_tc_offset_div2;
+	hw_ps->lists_modification_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT);
+	hw_ps->log2_parallel_merge_level = pps->log2_parallel_merge_level_minus2 + 2;
+	hw_ps->slice_segment_header_extension_present_flag =
+		!!(pps->flags & V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT);
+	hw_ps->num_tile_columns = tiles_enabled ? pps->num_tile_columns_minus1 + 1 : 1;
+	hw_ps->num_tile_rows = tiles_enabled ? pps->num_tile_rows_minus1 + 1 : 1;
+	hw_ps->mvc_ff = 0xffff;
+
+	// Setup tiles information
+	memset(column_width, 0, sizeof(column_width));
+	memset(row_height, 0, sizeof(row_height));
+
+	max_cu_width = 1 << (sps->log2_diff_max_min_luma_coding_block_size + log2_min_cb_size);
+	pic_in_cts_width = (width + max_cu_width - 1) / max_cu_width;
+	pic_in_cts_height = (height + max_cu_width - 1) / max_cu_width;
+
+	if (tiles_enabled) {
+		if (pps->flags & V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING) {
+			compute_tiles_uniform(run, log2_min_cb_size, width, height,
+					      pic_in_cts_width, pic_in_cts_height,
+					      column_width, row_height);
+		} else {
+			compute_tiles_non_uniform(run, log2_min_cb_size, width, height,
+						  pic_in_cts_width, pic_in_cts_height,
+						  column_width, row_height);
+		}
+	} else {
+		column_width[0] = (width + max_cu_width - 1) / max_cu_width;
+		row_height[0] = (height + max_cu_width - 1) / max_cu_width;
+	}
+
+	for (i = 0; i < 22; i++)
+		set_column_row(hw_ps, column_width[i], row_height[i], i);
+
+	// Setup POC information
+	hw_ps->current_poc = dec_params->pic_order_cnt_val;
+
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+		u32 valid = !!(dec_params->num_active_dpb_entries > i);
+
+		set_pps_ref_pic_poc(hw_ps, dec_params->dpb[i].pic_order_cnt_val, i);
+		hw_ps->ref_is_valid |= valid << i;
+	}
+}
+
+static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_hevc_ctx *h265_ctx = ctx->priv;
+
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_REGS,
+			   &h265_ctx->regs.common,
+			   sizeof(h265_ctx->regs.common));
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_ADDR_REGS,
+			   &h265_ctx->regs.common_addr,
+			   sizeof(h265_ctx->regs.common_addr));
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_PARAMS_REGS,
+			   &h265_ctx->regs.h26x_params,
+			   sizeof(h265_ctx->regs.h26x_params));
+	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_ADDR_REGS,
+			   &h265_ctx->regs.h26x_addr,
+			   sizeof(h265_ctx->regs.h26x_addr));
+}
+
+static void config_registers(struct rkvdec_ctx *ctx,
+			     struct rkvdec_hevc_run *run)
+{
+	const struct v4l2_ctrl_hevc_decode_params *dec_params = run->decode_params;
+	struct rkvdec_hevc_ctx *h265_ctx = ctx->priv;
+	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
+	dma_addr_t priv_start_addr = h265_ctx->priv_tbl.dma;
+	const struct v4l2_pix_format_mplane *dst_fmt;
+	struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
+	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
+	struct vdpu383_regs_h26x *regs = &h265_ctx->regs;
+	const struct v4l2_format *f;
+	dma_addr_t rlc_addr;
+	dma_addr_t dst_addr;
+	u32 hor_virstride;
+	u32 ver_virstride;
+	u32 y_virstride;
+	u32 offset;
+	u32 pixels;
+	u32 i;
+
+	memset(regs, 0, sizeof(*regs));
+
+	/* Set H264 mode */
+	regs->common.reg008_dec_mode = VDPU383_MODE_HEVC;
+
+	/* Set input stream length */
+	regs->h26x_params.reg066_stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+
+	/* Set strides */
+	f = &ctx->decoded_fmt;
+	dst_fmt = &f->fmt.pix_mp;
+	hor_virstride = dst_fmt->plane_fmt[0].bytesperline;
+	ver_virstride = dst_fmt->height;
+	y_virstride = hor_virstride * ver_virstride;
+
+	pixels = dst_fmt->height * dst_fmt->width;
+
+	regs->h26x_params.reg068_hor_virstride = hor_virstride / 16;
+	regs->h26x_params.reg069_raster_uv_hor_virstride = hor_virstride / 16;
+	regs->h26x_params.reg070_y_virstride = y_virstride / 16;
+
+	/* Activate block gating */
+	regs->common.reg010.strmd_auto_gating_e      = 1;
+	regs->common.reg010.inter_auto_gating_e      = 1;
+	regs->common.reg010.intra_auto_gating_e      = 1;
+	regs->common.reg010.transd_auto_gating_e     = 1;
+	regs->common.reg010.recon_auto_gating_e      = 1;
+	regs->common.reg010.filterd_auto_gating_e    = 1;
+	regs->common.reg010.bus_auto_gating_e	     = 1;
+	regs->common.reg010.ctrl_auto_gating_e       = 1;
+	regs->common.reg010.rcb_auto_gating_e	     = 1;
+	regs->common.reg010.err_prc_auto_gating_e    = 1;
+
+	/* Set timeout threshold */
+	if (pixels < VDPU383_1080P_PIXELS)
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_1080p;
+	else if (pixels < VDPU383_4K_PIXELS)
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_4K;
+	else if (pixels < VDPU383_8K_PIXELS)
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_8K;
+	else
+		regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_MAX;
+
+	regs->common.reg016.error_proc_disable = 1;
+
+	/* Set ref pic address & poc */
+	for (i = 0; i < ARRAY_SIZE(dec_params->dpb) - 1; i++) {
+		struct vb2_buffer *vb_buf = get_ref_buf(ctx, run, i);
+		dma_addr_t buf_dma;
+
+		buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
+
+		/* Set reference addresses */
+		regs->h26x_addr.reg170_185_ref_base[i] = buf_dma;
+		regs->h26x_addr.reg195_210_payload_st_ref_base[i] = buf_dma;
+
+		/* Set COLMV addresses */
+		regs->h26x_addr.reg217_232_colmv_ref_base[i] = buf_dma + ctx->colmv_offset;
+	}
+
+	/* Set rlc base address (input stream) */
+	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	regs->common_addr.reg128_strm_base = rlc_addr;
+
+	/* Set output base address */
+	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+	regs->h26x_addr.reg168_decout_base = dst_addr;
+	regs->h26x_addr.reg169_error_ref_base = dst_addr;
+	regs->h26x_addr.reg192_payload_st_cur_base = dst_addr;
+
+	/* Set colmv address */
+	regs->h26x_addr.reg216_colmv_cur_base = dst_addr + ctx->colmv_offset;
+
+	/* Set RCB addresses */
+	for (i = 0; i < rkvdec_rcb_buf_count(ctx); i++) {
+		regs->common_addr.reg140_162_rcb_info[i].offset = rkvdec_rcb_buf_dma_addr(ctx, i);
+		regs->common_addr.reg140_162_rcb_info[i].size = rkvdec_rcb_buf_size(ctx, i);
+	}
+
+	if (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) {
+		/* Set scaling matrix */
+		offset = offsetof(struct rkvdec_hevc_priv_tbl, scaling_list);
+		regs->common_addr.reg132_scanlist_addr = priv_start_addr + offset;
+	}
+
+	/* Set hw pps address */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, param_set);
+	regs->common_addr.reg131_gbl_base = priv_start_addr + offset;
+	regs->h26x_params.reg067_global_len = sizeof(struct rkvdec_hevc_sps_pps) / 16;
+
+	/* Set hw rps address */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, rps);
+	regs->common_addr.reg129_rps_base = priv_start_addr + offset;
+
+	/* Set cabac table */
+	offset = offsetof(struct rkvdec_hevc_priv_tbl, cabac_table);
+	regs->common_addr.reg130_cabactbl_base = priv_start_addr + offset;
+
+	rkvdec_write_regs(ctx);
+}
+
+static int rkvdec_hevc_start(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_hevc_priv_tbl *priv_tbl;
+	struct rkvdec_hevc_ctx *hevc_ctx;
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_HEVC_SPS);
+	if (!ctrl)
+		return -EINVAL;
+
+	ret = rkvdec_hevc_validate_sps(ctx, ctrl->p_new.p_hevc_sps);
+	if (ret)
+		return ret;
+
+	hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL);
+	if (!hevc_ctx)
+		return -ENOMEM;
+
+	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+				      &hevc_ctx->priv_tbl.dma, GFP_KERNEL);
+	if (!priv_tbl) {
+		ret = -ENOMEM;
+		goto err_free_ctx;
+	}
+
+	hevc_ctx->priv_tbl.size = sizeof(*priv_tbl);
+	hevc_ctx->priv_tbl.cpu = priv_tbl;
+	memcpy(priv_tbl->cabac_table, rkvdec_hevc_cabac_table,
+	       sizeof(rkvdec_hevc_cabac_table));
+
+	ctx->priv = hevc_ctx;
+	return 0;
+
+err_free_ctx:
+	kfree(hevc_ctx);
+	return ret;
+}
+
+static void rkvdec_hevc_stop(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+
+	dma_free_coherent(rkvdec->dev, hevc_ctx->priv_tbl.size,
+			  hevc_ctx->priv_tbl.cpu, hevc_ctx->priv_tbl.dma);
+	kfree(hevc_ctx);
+}
+
+static int rkvdec_hevc_run(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_hevc_run run;
+	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
+	struct rkvdec_hevc_priv_tbl *tbl = hevc_ctx->priv_tbl.cpu;
+	u32 watchdog_time;
+	u64 timeout_threshold;
+	unsigned long axi_rate;
+
+	rkvdec_hevc_run_preamble(ctx, &run);
+
+	rkvdec_hevc_assemble_hw_scaling_list(rkvdec, &run,
+					     &tbl->scaling_list,
+					     &hevc_ctx->scaling_matrix_cache);
+	assemble_hw_pps(ctx, &run);
+	rkvdec_hevc_assemble_hw_rps(&run, &tbl->rps, &hevc_ctx->st_cache);
+
+	config_registers(ctx, &run);
+
+	rkvdec_run_postamble(ctx, &run.base);
+
+	/* Set watchdog at 2 times the hardware timeout threshold */
+	timeout_threshold = hevc_ctx->regs.common.reg013_core_timeout_threshold;
+	axi_rate = clk_get_rate(rkvdec->axi_clk);
+
+	if (axi_rate)
+		watchdog_time = 2 * (1000 * timeout_threshold) / axi_rate;
+	else
+		watchdog_time = 2000;
+	schedule_delayed_work(&rkvdec->watchdog_work,
+			      msecs_to_jiffies(watchdog_time));
+
+	/* Start decoding! */
+	writel(timeout_threshold, rkvdec->link + VDPU383_LINK_TIMEOUT_THRESHOLD);
+	writel(VDPU383_IP_CRU_MODE, rkvdec->link + VDPU383_LINK_IP_ENABLE);
+	writel(VDPU383_DEC_E_BIT, rkvdec->link + VDPU383_LINK_DEC_ENABLE);
+
+	return 0;
+}
+
+static int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl)
+{
+	if (ctrl->id == V4L2_CID_STATELESS_HEVC_SPS)
+		return rkvdec_hevc_validate_sps(ctx, ctrl->p_new.p_hevc_sps);
+
+	return 0;
+}
+
+const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_hevc_fmt_ops = {
+	.adjust_fmt = rkvdec_hevc_adjust_fmt,
+	.start = rkvdec_hevc_start,
+	.stop = rkvdec_hevc_stop,
+	.run = rkvdec_hevc_run,
+	.try_ctrl = rkvdec_hevc_try_ctrl,
+	.get_image_fmt = rkvdec_hevc_get_image_fmt,
+};
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index cd01f1e41beb5..62cdbe6459933 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -454,6 +454,22 @@ static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = {
 		.decoded_fmts = rkvdec_h264_decoded_fmts,
 		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
 	},
+	{
+		.fourcc = V4L2_PIX_FMT_HEVC_SLICE,
+		.frmsize = {
+			.min_width = 16,
+			.max_width = 65472,
+			.step_width = 16,
+			.min_height = 16,
+			.max_height = 65472,
+			.step_height = 16,
+		},
+		.ctrls = &rkvdec_hevc_ctrls,
+		.ops = &rkvdec_vdpu383_hevc_fmt_ops,
+		.num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts),
+		.decoded_fmts = rkvdec_hevc_decoded_fmts,
+		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
+	},
 };
 
 static const struct rkvdec_coded_fmt_desc *
@@ -1361,6 +1377,78 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
 	return cfg->irq_handler(ctx);
 }
 
+/*
+ * Flip one or more matrices along their main diagonal and flatten them
+ * before writing it to the memory.
+ * Convert:
+ * ABCD         AEIM
+ * EFGH     =>  BFJN     =>     AEIMBFJNCGKODHLP
+ * IJKL         CGKO
+ * MNOP         DHLP
+ */
+static void transpose_and_flatten_matrices(u8 *output, const u8 *input,
+					   int matrices, int row_length)
+{
+	int i, j, row, x_offset, matrix_offset, rot_index, y_offset, matrix_size, new_value;
+
+	matrix_size = row_length * row_length;
+	for (i = 0; i < matrices; i++) {
+		row = 0;
+		x_offset = 0;
+		matrix_offset = i * matrix_size;
+		for (j = 0; j < matrix_size; j++) {
+			y_offset = j - (row * row_length);
+			rot_index = y_offset * row_length + x_offset;
+			new_value = *(input + i * matrix_size + j);
+			output[matrix_offset + rot_index] = new_value;
+			if ((j + 1) % row_length == 0) {
+				row += 1;
+				x_offset += 1;
+			}
+		}
+	}
+}
+
+/*
+ * VDPU383 needs a specific order:
+ * The 8x8 flatten matrix is based on 4x4 blocks.
+ * Each 4x4 block is written separately in order.
+ *
+ * Base data    =>  Transposed    VDPU383 transposed
+ *
+ * ABCDEFGH         AIQYaiqy      AIQYBJRZ
+ * IJKLMNOP         BJRZbjrz      CKS0DLT1
+ * QRSTUVWX         CKS0cks6      aiqybjrz
+ * YZ012345     =>  DLT1dlt7      cks6dlt7
+ * abcdefgh         EMU2emu8      EMU2FNV3
+ * ijklmnop         FNV3fnv9      GOW4HPX5
+ * qrstuvwx         GOW4gow#      emu8fnv9
+ * yz6789#$         HPX5hpx$      gow#hpx$
+ *
+ * As the function reads block of 4x4 it can be used for both 4x4 and 8x8 matrices.
+ *
+ */
+static void vdpu383_flatten_matrices(u8 *output, const u8 *input, int matrices, int row_length)
+{
+	u8 block;
+	int i, j, matrix_offset, matrix_size, new_value, input_idx, line_offset, block_offset;
+
+	matrix_size = row_length * row_length;
+	for (i = 0; i < matrices; i++) {
+		matrix_offset = i * matrix_size;
+		for (j = 0; j < matrix_size; j++) {
+			block = j / 16;
+			line_offset = (j % 16) / 4;
+			block_offset = (block & 1) * 32 + (block & 2) * 2;
+			input_idx = ((j % 4) * row_length) + line_offset + block_offset;
+
+			new_value = *(input + i * matrix_size + input_idx);
+
+			output[matrix_offset + j] = new_value;
+		}
+	}
+}
+
 static void rkvdec_watchdog_func(struct work_struct *work)
 {
 	struct rkvdec_dev *rkvdec;
@@ -1424,6 +1512,7 @@ const struct rkvdec_config config_rkvdec = {
 	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
 	.irq_handler = rk3399_irq_handler,
 	.fill_pixfmt_mp = v4l2_fill_pixfmt_mp,
+	.flatten_matrices = transpose_and_flatten_matrices,
 	.colmv_size = rkvdec_colmv_size,
 };
 
@@ -1448,6 +1537,7 @@ const struct rkvdec_config config_vdpu381 = {
 	.irq_handler = vdpu381_irq_handler,
 	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
 	.colmv_size = rkvdec_colmv_size,
+	.flatten_matrices = transpose_and_flatten_matrices,
 	.named_regs = true,
 };
 
@@ -1473,6 +1563,7 @@ const struct rkvdec_config config_vdpu383 = {
 	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
 	.colmv_size = rkvdec_vdpu383_colmv_size,
 	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
+	.flatten_matrices = vdpu383_flatten_matrices,
 	.named_regs = true,
 };
 
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index df56bc0516ac9..2434f928040e0 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -111,6 +111,7 @@ struct rkvdec_config {
 	int (*fill_pixfmt_mp)(struct v4l2_pix_format_mplane *pix_mp, u32 pixelformat,
 			      u32 width, u32 height);
 	u32 (*colmv_size)(u16 width, u16 height);
+	void (*flatten_matrices)(u8 *output, const u8 *input, int matrices, int row_length);
 	bool named_regs;
 };
 
@@ -177,5 +178,6 @@ extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_hevc_fmt_ops;
 
 /* VDPU383 ops */
 extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops;
+extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_hevc_fmt_ops;
 
 #endif /* RKVDEC_H_ */
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant
  2025-08-08 20:03 ` [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant Detlev Casanova
@ 2025-08-09 11:53   ` kernel test robot
  2025-08-11 18:28   ` Nicolas Dufresne
  1 sibling, 0 replies; 26+ messages in thread
From: kernel test robot @ 2025-08-09 11:53 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: llvm, oe-kbuild-all, Detlev Casanova, Mauro Carvalho Chehab,
	linux-media, Heiko Stuebner, linux-rockchip, linux-arm-kernel,
	kernel

Hi Detlev,

kernel test robot noticed the following build errors:

[auto build test ERROR on linuxtv-media-pending/master]
[also build test ERROR on linus/master next-20250808]
[cannot apply to rockchip/for-next sailus-media-tree/master sailus-media-tree/streams v6.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Detlev-Casanova/media-rkvdec-Switch-to-using-structs-instead-of-writel/20250809-041049
base:   https://git.linuxtv.org/media-ci/media-pending.git master
patch link:    https://lore.kernel.org/r/20250808200340.156393-11-detlev.casanova%40collabora.com
patch subject: [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant
config: i386-buildonly-randconfig-005-20250809 (https://download.01.org/0day-ci/archive/20250809/202508091909.RNcoZmVb-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250809/202508091909.RNcoZmVb-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508091909.RNcoZmVb-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/media/platform/rockchip/rkvdec/rkvdec.c:12:10: fatal error: 'linux/hw_bitfield.h' file not found
      12 | #include <linux/hw_bitfield.h>
         |          ^~~~~~~~~~~~~~~~~~~~~
   1 error generated.


vim +12 drivers/media/platform/rockchip/rkvdec/rkvdec.c

  > 12	#include <linux/hw_bitfield.h>
    13	#include <linux/clk.h>
    14	#include <linux/genalloc.h>
    15	#include <linux/interrupt.h>
    16	#include <linux/iommu.h>
    17	#include <linux/module.h>
    18	#include <linux/of.h>
    19	#include <linux/platform_device.h>
    20	#include <linux/pm.h>
    21	#include <linux/pm_runtime.h>
    22	#include <linux/slab.h>
    23	#include <linux/videodev2.h>
    24	#include <linux/workqueue.h>
    25	#include <media/v4l2-event.h>
    26	#include <media/v4l2-mem2mem.h>
    27	#include <media/videobuf2-core.h>
    28	#include <media/videobuf2-vmalloc.h>
    29	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant
  2025-08-08 20:03 ` [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant Detlev Casanova
@ 2025-08-09 13:17   ` kernel test robot
  0 siblings, 0 replies; 26+ messages in thread
From: kernel test robot @ 2025-08-09 13:17 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: llvm, oe-kbuild-all, Detlev Casanova, Mauro Carvalho Chehab,
	linux-media, Heiko Stuebner, linux-rockchip, linux-arm-kernel,
	kernel

Hi Detlev,

kernel test robot noticed the following build errors:

[auto build test ERROR on linuxtv-media-pending/master]
[also build test ERROR on linus/master next-20250808]
[cannot apply to rockchip/for-next sailus-media-tree/master sailus-media-tree/streams v6.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Detlev-Casanova/media-rkvdec-Switch-to-using-structs-instead-of-writel/20250809-041049
base:   https://git.linuxtv.org/media-ci/media-pending.git master
patch link:    https://lore.kernel.org/r/20250808200340.156393-12-detlev.casanova%40collabora.com
patch subject: [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant
config: i386-buildonly-randconfig-005-20250809 (https://download.01.org/0day-ci/archive/20250809/202508092052.AFrUDe6V-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250809/202508092052.AFrUDe6V-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508092052.AFrUDe6V-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c:119:39: error: field has incomplete type 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
     119 |         struct v4l2_ctrl_hevc_ext_sps_st_rps    st_cache;
         |                                                 ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   1 error generated.
--
>> drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:261:23: error: subscript of pointer to incomplete type 'const struct v4l2_ctrl_hevc_ext_sps_lt_rps'
     261 |                         run->ext_sps_lt_rps[i].lt_ref_pic_poc_lsb_sps;
         |                         ~~~~~~~~~~~~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:69:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_lt_rps'
      69 |         const struct v4l2_ctrl_hevc_ext_sps_lt_rps      *ext_sps_lt_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:263:26: error: subscript of pointer to incomplete type 'const struct v4l2_ctrl_hevc_ext_sps_lt_rps'
     263 |                         !!(run->ext_sps_lt_rps[i].flags & V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT);
         |                            ~~~~~~~~~~~~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:69:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_lt_rps'
      69 |         const struct v4l2_ctrl_hevc_ext_sps_lt_rps      *ext_sps_lt_rps;
         |                      ^
>> drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:263:38: error: use of undeclared identifier 'V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT'
     263 |                         !!(run->ext_sps_lt_rps[i].flags & V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT);
         |                                                           ^
>> drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:299:77: error: subscript of pointer to incomplete type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     299 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
         |                                                                 ~~~~~~~~~~~~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
>> drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:310:38: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     310 |         ref_rps_idx = st_rps_idx - (rps_data->delta_idx_minus1 + 1); /* 7-59 */
         |                                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:311:31: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     311 |         delta_rps = (1 - 2 * rps_data->delta_rps_sign) *
         |                              ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:312:15: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     312 |                    (rps_data->abs_delta_rps_minus1 + 1); /* 7-60 */
         |                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:317:41: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     317 |                 used_by_curr_pic_flag[j] = !!(rps_data->used_by_curr_pic & (1 << j));
         |                                               ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:318:34: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     318 |                 use_delta_flag[j] = !!(rps_data->use_delta_flag & (1 << j));
         |                                        ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:376:77: error: subscript of pointer to incomplete type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     376 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps *rps_data = &run->ext_sps_st_rps[idx];
         |                                                                 ~~~~~~~~~~~~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:381:38: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     381 |         st_rps->num_negative_pics = rps_data->num_negative_pics;
         |                                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:383:38: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     383 |         st_rps->num_positive_pics = rps_data->num_positive_pics;
         |                                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:387:47: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     387 |                 st_rps->used_by_curr_pic_s0[i] = !!(rps_data->used_by_curr_pic & (1 << i));
         |                                                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:391:40: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     391 |                         st_rps->delta_poc_s0[i] = -(rps_data->delta_poc_s0_minus1[i] + 1);
         |                                                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:396:14: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     396 |                                 (rps_data->delta_poc_s0_minus1[i] + 1);
         |                                  ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:402:47: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     402 |                 st_rps->used_by_curr_pic_s1[j] = !!(rps_data->used_by_curr_pic & (1 << (i + j)));
         |                                                     ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:406:38: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     406 |                         st_rps->delta_poc_s1[j] = rps_data->delta_poc_s1_minus1[j] + 1;
         |                                                   ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:411:14: error: incomplete definition of type 'const struct v4l2_ctrl_hevc_ext_sps_st_rps'
     411 |                                 (rps_data->delta_poc_s1_minus1[j] + 1);
         |                                  ~~~~~~~~^
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
>> drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c:427:42: error: invalid application of 'sizeof' to an incomplete type 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
     427 |         if (!memcmp(cache, run->ext_sps_st_rps, sizeof(struct v4l2_ctrl_hevc_ext_sps_st_rps)))
         |                                                 ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h:68:15: note: forward declaration of 'struct v4l2_ctrl_hevc_ext_sps_st_rps'
      68 |         const struct v4l2_ctrl_hevc_ext_sps_st_rps      *ext_sps_st_rps;
         |                      ^
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   20 errors generated.


vim +119 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c

   115	
   116	struct rkvdec_hevc_ctx {
   117		struct rkvdec_aux_buf			priv_tbl;
   118		struct v4l2_ctrl_hevc_scaling_matrix	scaling_matrix_cache;
 > 119		struct v4l2_ctrl_hevc_ext_sps_st_rps	st_cache;
   120		struct rkvdec_vdpu381_regs_hevc		regs;
   121	};
   122	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 05/12] media: rkvdec: Add per variant configuration
  2025-08-08 20:03 ` [PATCH v2 05/12] media: rkvdec: Add per variant configuration Detlev Casanova
@ 2025-08-11  6:13   ` Krzysztof Kozlowski
  2025-08-11 13:52     ` Detlev Casanova
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-11  6:13 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

On 08/08/2025 22:03, Detlev Casanova wrote:
> This is to prepare for adding different variants of the decoder and

Prepare for...

> support specific formats and ops.
> 
> Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
> ---


...


>  static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
>  {
> +	struct rkvdec_config *cfg = ctx->dev->config;
>  	unsigned int i, nctrls = 0;
>  	int ret;
>  
> -	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++)
> -		nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
> +	for (i = 0; i < cfg->coded_fmts_num; i++)
> +		nctrls += cfg->coded_fmts[i].ctrls->num_ctrls;
>  
>  	v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
>  
> -	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
> -		ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
> +	for (i = 0; i < cfg->coded_fmts_num; i++) {
> +		ret = rkvdec_add_ctrls(ctx, cfg->coded_fmts[i].ctrls);
>  		if (ret)
>  			goto err_free_handler;
>  	}
> @@ -1119,8 +1127,13 @@ static void rkvdec_watchdog_func(struct work_struct *work)
>  	}
>  }
>  
> +const struct rkvdec_config config_rkvdec = {

Why isn't this static?

> +	.coded_fmts = (struct rkvdec_coded_fmt_desc *)rkvdec_coded_fmts,
> +	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
> +};
> +
>  static const struct of_device_id of_rkvdec_match[] = {
> -	{ .compatible = "rockchip,rk3399-vdec" },
> +	{ .compatible = "rockchip,rk3399-vdec", .data = &config_rkvdec },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, of_rkvdec_match);
> @@ -1144,6 +1157,9 @@ static int rkvdec_probe(struct platform_device *pdev)
>  	mutex_init(&rkvdec->vdev_lock);
>  	INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);
>  
> +	rkvdec->config =
> +		(struct rkvdec_config *)of_device_get_match_data(rkvdec->dev);

If you need a cast, your code is wrong.


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support
  2025-08-08 20:03 ` [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support Detlev Casanova
@ 2025-08-11  6:13   ` Krzysztof Kozlowski
  2025-08-11 13:54     ` Detlev Casanova
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-11  6:13 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

On 08/08/2025 22:03, Detlev Casanova wrote:
>  
> -	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
> -
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq <= 0)
>  		return -ENXIO;
> @@ -1204,6 +1217,10 @@ static int rkvdec_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);

Didn't you just add new ABI?

> +	if (!rkvdec->sram_pool && rkvdec->config->rcb_num > 0)
> +		dev_info(&pdev->dev, "No sram node, RCB will be stored in RAM\n");
> +



Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (11 preceding siblings ...)
  2025-08-08 20:03 ` [PATCH v2 12/12] media: rkvdec: Add HEVC support for the VDPU383 variant Detlev Casanova
@ 2025-08-11  9:56 ` Heiko Stübner
  2025-08-11 16:33   ` Detlev Casanova
  2025-08-12  7:20 ` Piotr Oniszczuk
  13 siblings, 1 reply; 26+ messages in thread
From: Heiko Stübner @ 2025-08-11  9:56 UTC (permalink / raw)
  To: linux-kernel, Detlev Casanova
  Cc: Detlev Casanova, Mauro Carvalho Chehab, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

Hi Detlev,

Am Freitag, 8. August 2025, 22:03:22 Mitteleuropäische Sommerzeit schrieb Detlev Casanova:
> These variants are found respectively in the RK3588 and RK3576 SoCs.
> This patch only adds support for H264 and H265 in both variants.
> 
> As there is a considerable part of the code that can be shared with the
> already supported rkvdec decoder driver, the support for these variants
> is added here rather than writing a new driver.
> 
> This patch set uses the newly introduced hevc_ext_sps_[ls]t_rps v4l2
> controls for HEVC [1].
> Therefore, a patched version of userpace tools is needed for HEVC
> support (added for GStreamer[2] and in an early stage for FFmpeg[3]).
> 
> This patch set also depends on the preparation patch set sent earlier [4]
> as well as the iommu restore fix [5] (already merged in linux-media) and
> Nicolas Frattaroli's bitmap patch [6] to support setting registers that
> uses upper 16 bits as masks.
> 
> [1]: https://lore.kernel.org/all/20250807194327.69900-1-detlev.casanova@collabora.com/
> [2]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9355
> [3]: https://gitlab.collabora.com/detlev/ffmpeg
> [4]: https://lore.kernel.org/all/20250623160722.55938-1-detlev.casanova@collabora.com/
> [5]: https://lore.kernel.org/all/20250508-rkvdec-iommu-reset-v1-1-c46b6efa6e9b@collabora.com/
> [6]: https://lore.kernel.org/all/20250623-byeword-update-v2-1-cf1fc08a2e1f@collabora.com/
> 
> Changes since v1:
>  - Add parsing of the short and long term ref frame sets from the new v4l2
>    controls
>  - Add RPS cache to avoid parsing the same data again
>  - Fix HEVC pixel formats selection
>  - Fix multiple indentation errors

when applying the series, git was a bit unhappy about some whitespaces:


> Detlev Casanova (12):
>   media: rkvdec: Switch to using structs instead of writel
>   media: rkvdec: Move cabac table to its own source file

Applying: media: rkvdec: Move cabac table to its own source file
.git/rebase-apply/patch:535: new blank line at EOF.
+
Warnung: 1 Zeile fügt Whitespace-Fehler hinzu.


>   media: rkvdec: Use structs to represent the HW RPS
>   media: rkvdec: Move h264 functions to common file

Applying: media: rkvdec: Move h264 functions to common file
.git/rebase-apply/patch:278: new blank line at EOF.
+
Warnung: 1 Zeile fügt Whitespace-Fehler hinzu.


>   media: rkvdec: Add per variant configuration
>   media: rkvdec: Add RCB and SRAM support

Applying: media: rkvdec: Add RCB and SRAM support
.git/rebase-apply/patch:200: new blank line at EOF.
+
Warnung: 1 Zeile fügt Whitespace-Fehler hinzu.


>   media: rkvdec: Support per-variant interrupt handler
>   media: rkvdec: Enable all clocks without naming them
>   media: rkvdec: Add H264 support for the VDPU381 variant
>   media: rkvdec: Add H264 support for the VDPU383 variant
>   media: rkvdec: Add HEVC support for the VDPU381 variant

Applying: media: rkvdec: Add HEVC support for the VDPU381 variant
.git/rebase-apply/patch:3483: new blank line at EOF.
+
.git/rebase-apply/patch:4035: new blank line at EOF.
+
Warnung: 2 Zeilen fügen Whitespace-Fehler hinzu.


Heiko



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 05/12] media: rkvdec: Add per variant configuration
  2025-08-11  6:13   ` Krzysztof Kozlowski
@ 2025-08-11 13:52     ` Detlev Casanova
  0 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-11 13:52 UTC (permalink / raw)
  To: linux-kernel, Krzysztof Kozlowski
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

Hi Krzysztof,

On Monday, 11 August 2025 02:13:04 EDT Krzysztof Kozlowski wrote:
> On 08/08/2025 22:03, Detlev Casanova wrote:
> > This is to prepare for adding different variants of the decoder and
> 
> Prepare for...

Sounds better indeed.

> > support specific formats and ops.
> > 
> > Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
> > ---
> 
> ...
> 
> >  static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
> >  {
> > 
> > +	struct rkvdec_config *cfg = ctx->dev->config;
> > 
> >  	unsigned int i, nctrls = 0;
> >  	int ret;
> > 
> > -	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++)
> > -		nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
> > +	for (i = 0; i < cfg->coded_fmts_num; i++)
> > +		nctrls += cfg->coded_fmts[i].ctrls->num_ctrls;
> > 
> >  	v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
> > 
> > -	for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
> > -		ret = rkvdec_add_ctrls(ctx, 
rkvdec_coded_fmts[i].ctrls);
> > +	for (i = 0; i < cfg->coded_fmts_num; i++) {
> > +		ret = rkvdec_add_ctrls(ctx, cfg->coded_fmts[i].ctrls);
> > 
> >  		if (ret)
> >  		
> >  			goto err_free_handler;
> >  	
> >  	}
> > 
> > @@ -1119,8 +1127,13 @@ static void rkvdec_watchdog_func(struct work_struct
> > *work)> 
> >  	}
> >  
> >  }
> > 
> > +const struct rkvdec_config config_rkvdec = {
> 
> Why isn't this static?
> 
> > +	.coded_fmts = (struct rkvdec_coded_fmt_desc *)rkvdec_coded_fmts,
> > +	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
> > +};
> > +
> > 
> >  static const struct of_device_id of_rkvdec_match[] = {
> > 
> > -	{ .compatible = "rockchip,rk3399-vdec" },
> > +	{ .compatible = "rockchip,rk3399-vdec", .data = &config_rkvdec },
> > 
> >  	{ /* sentinel */ }
> >  
> >  };
> >  MODULE_DEVICE_TABLE(of, of_rkvdec_match);
> > 
> > @@ -1144,6 +1157,9 @@ static int rkvdec_probe(struct platform_device
> > *pdev)
> > 
> >  	mutex_init(&rkvdec->vdev_lock);
> >  	INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);
> > 
> > +	rkvdec->config =
> > +		(struct rkvdec_config *)of_device_get_match_data(rkvdec-
>dev);
> 
> If you need a cast, your code is wrong.

Right, some const/static addition is needed. I'll fix that :)

Detlev.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support
  2025-08-11  6:13   ` Krzysztof Kozlowski
@ 2025-08-11 13:54     ` Detlev Casanova
  2025-08-11 14:01       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 26+ messages in thread
From: Detlev Casanova @ 2025-08-11 13:54 UTC (permalink / raw)
  To: linux-kernel, Krzysztof Kozlowski
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

On Monday, 11 August 2025 02:13:42 EDT Krzysztof Kozlowski wrote:
> On 08/08/2025 22:03, Detlev Casanova wrote:
> > -	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
> > -
> > 
> >  	irq = platform_get_irq(pdev, 0);
> >  	if (irq <= 0)
> >  	
> >  		return -ENXIO;
> > 
> > @@ -1204,6 +1217,10 @@ static int rkvdec_probe(struct platform_device
> > *pdev)> 
> >  		return ret;
> >  	
> >  	}
> > 
> > +	rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
> 
> Didn't you just add new ABI?

Oh do you mean rkvdec_rcb_buf_count() ? I could indeed use that instead here.

> > +	if (!rkvdec->sram_pool && rkvdec->config->rcb_num > 0)
> > +		dev_info(&pdev->dev, "No sram node, RCB will be stored 
in RAM\n");
> > +
> 
> Best regards,
> Krzysztof





^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support
  2025-08-11 13:54     ` Detlev Casanova
@ 2025-08-11 14:01       ` Krzysztof Kozlowski
  2025-08-11 18:44         ` Detlev Casanova
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-11 14:01 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

On 11/08/2025 15:54, Detlev Casanova wrote:
> On Monday, 11 August 2025 02:13:42 EDT Krzysztof Kozlowski wrote:
>> On 08/08/2025 22:03, Detlev Casanova wrote:
>>> -	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
>>> -
>>>
>>>  	irq = platform_get_irq(pdev, 0);
>>>  	if (irq <= 0)
>>>  	
>>>  		return -ENXIO;
>>>
>>> @@ -1204,6 +1217,10 @@ static int rkvdec_probe(struct platform_device
>>> *pdev)> 
>>>  		return ret;
>>>  	
>>>  	}
>>>
>>> +	rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
>>
>> Didn't you just add new ABI?
> 
> Oh do you mean rkvdec_rcb_buf_count() ? I could indeed use that instead here.


No, I meant DT/OF ABI for "sram".


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383
  2025-08-11  9:56 ` [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Heiko Stübner
@ 2025-08-11 16:33   ` Detlev Casanova
  0 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-11 16:33 UTC (permalink / raw)
  To: linux-kernel, Heiko Stübner
  Cc: Mauro Carvalho Chehab, linux-media, linux-rockchip,
	linux-arm-kernel, kernel

Hi Heiko,

On Monday, 11 August 2025 05:56:00 EDT Heiko Stübner wrote:
> Hi Detlev,
> 
> Am Freitag, 8. August 2025, 22:03:22 Mitteleuropäische Sommerzeit schrieb 
Detlev Casanova:
> > These variants are found respectively in the RK3588 and RK3576 SoCs.
> > This patch only adds support for H264 and H265 in both variants.
> > 
> > As there is a considerable part of the code that can be shared with the
> > already supported rkvdec decoder driver, the support for these variants
> > is added here rather than writing a new driver.
> > 
> > This patch set uses the newly introduced hevc_ext_sps_[ls]t_rps v4l2
> > controls for HEVC [1].
> > Therefore, a patched version of userpace tools is needed for HEVC
> > support (added for GStreamer[2] and in an early stage for FFmpeg[3]).
> > 
> > This patch set also depends on the preparation patch set sent earlier [4]
> > as well as the iommu restore fix [5] (already merged in linux-media) and
> > Nicolas Frattaroli's bitmap patch [6] to support setting registers that
> > uses upper 16 bits as masks.
> > 
> > [1]:
> > https://lore.kernel.org/all/20250807194327.69900-1-detlev.casanova@collab
> > ora.com/ [2]:
> > https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9355
> > [3]: https://gitlab.collabora.com/detlev/ffmpeg
> > [4]:
> > https://lore.kernel.org/all/20250623160722.55938-1-detlev.casanova@collab
> > ora.com/ [5]:
> > https://lore.kernel.org/all/20250508-rkvdec-iommu-reset-v1-1-c46b6efa6e9b
> > @collabora.com/ [6]:
> > https://lore.kernel.org/all/20250623-byeword-update-v2-1-cf1fc08a2e1f@col
> > labora.com/> 
> > Changes since v1:
> >  - Add parsing of the short and long term ref frame sets from the new v4l2
> >  
> >    controls
> >  
> >  - Add RPS cache to avoid parsing the same data again
> >  - Fix HEVC pixel formats selection
> >  - Fix multiple indentation errors
> 
> when applying the series, git was a bit unhappy about some whitespaces:

Mmh, it looks like some rebase issues. Thanks, I'll fix those !

> > Detlev Casanova (12):
> >   media: rkvdec: Switch to using structs instead of writel
> >   media: rkvdec: Move cabac table to its own source file
> 
> Applying: media: rkvdec: Move cabac table to its own source file
> .git/rebase-apply/patch:535: new blank line at EOF.
> +
> Warnung: 1 Zeile fügt Whitespace-Fehler hinzu.
> 
> >   media: rkvdec: Use structs to represent the HW RPS
> >   media: rkvdec: Move h264 functions to common file
> 
> Applying: media: rkvdec: Move h264 functions to common file
> .git/rebase-apply/patch:278: new blank line at EOF.
> +
> Warnung: 1 Zeile fügt Whitespace-Fehler hinzu.
> 
> >   media: rkvdec: Add per variant configuration
> >   media: rkvdec: Add RCB and SRAM support
> 
> Applying: media: rkvdec: Add RCB and SRAM support
> .git/rebase-apply/patch:200: new blank line at EOF.
> +
> Warnung: 1 Zeile fügt Whitespace-Fehler hinzu.
> 
> >   media: rkvdec: Support per-variant interrupt handler
> >   media: rkvdec: Enable all clocks without naming them
> >   media: rkvdec: Add H264 support for the VDPU381 variant
> >   media: rkvdec: Add H264 support for the VDPU383 variant
> >   media: rkvdec: Add HEVC support for the VDPU381 variant
> 
> Applying: media: rkvdec: Add HEVC support for the VDPU381 variant
> .git/rebase-apply/patch:3483: new blank line at EOF.
> +
> .git/rebase-apply/patch:4035: new blank line at EOF.
> +
> Warnung: 2 Zeilen fügen Whitespace-Fehler hinzu.
> 
> 
> Heiko





^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant
  2025-08-08 20:03 ` [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant Detlev Casanova
  2025-08-09 11:53   ` kernel test robot
@ 2025-08-11 18:28   ` Nicolas Dufresne
  1 sibling, 0 replies; 26+ messages in thread
From: Nicolas Dufresne @ 2025-08-11 18:28 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

[-- Attachment #1: Type: text/plain, Size: 40930 bytes --]

Hi Detlev,

Le vendredi 08 août 2025 à 16:03 -0400, Detlev Casanova a écrit :
> This variant is used on the RK3576 SoC.
> 
> The moving vectors size requirements are slightly different so support
> for a colmv_size function per variant is added.
> 
> Also, the link registers are used to start the decoder and read IRQ status.
> Per variant support for named register sections is added.
> 
> The fluster score is 128/135 for JVT-AVC_V1.
> The other test suites are not supported yet.

Since its the same family as RK3399, which scores 129/135, can you explicitly
document which one failed, and if you happen to know why ?

Nicolas

> 
> Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
> ---
>  .../media/platform/rockchip/rkvdec/Makefile   |   1 +
>  .../rockchip/rkvdec/rkvdec-vdpu383-h264.c     | 582 ++++++++++++++++++
>  .../rockchip/rkvdec/rkvdec-vdpu383-regs.h     | 284 +++++++++
>  .../media/platform/rockchip/rkvdec/rkvdec.c   | 109 +++-
>  .../media/platform/rockchip/rkvdec/rkvdec.h   |   8 +
>  5 files changed, 978 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-
> h264.c
>  create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-
> regs.h
> 
> diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile
> b/drivers/media/platform/rockchip/rkvdec/Makefile
> index 20128bb6e35dc..c38ce1e8d3601 100644
> --- a/drivers/media/platform/rockchip/rkvdec/Makefile
> +++ b/drivers/media/platform/rockchip/rkvdec/Makefile
> @@ -7,4 +7,5 @@ rockchip-vdec-y += \
>  		   rkvdec-h264-common.o \
>  		   rkvdec-rcb.o \
>  		   rkvdec-vdpu381-h264.o \
> +		   rkvdec-vdpu383-h264.o \
>  		   rkvdec-vp9.o
> diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
> b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
> new file mode 100644
> index 0000000000000..bb2c62d9c3d47
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
> @@ -0,0 +1,582 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Rockchip Video Decoder VDPU383 H264 backend
> + *
> + * Copyright (C) 2024 Collabora, Ltd.
> + *  Detlev Casanova <detlev.casanova@collabora.com>
> + */
> +
> +#include <media/v4l2-h264.h>
> +#include <media/v4l2-mem2mem.h>
> +
> +#include <linux/iopoll.h>
> +
> +#include "rkvdec-rcb.h"
> +#include "rkvdec-vdpu383-regs.h"
> +#include "rkvdec-h264-common.h"
> +
> +struct rkvdec_sps {
> +	u16 seq_parameter_set_id:			4;
> +	u16 profile_idc:				8;
> +	u16 constraint_set3_flag:			1;
> +	u16 chroma_format_idc:				2;
> +	u16 bit_depth_luma:				3;
> +	u16 bit_depth_chroma:				3;
> +	u16 qpprime_y_zero_transform_bypass_flag:	1;
> +	u16 log2_max_frame_num_minus4:			4;
> +	u16 max_num_ref_frames:				5;
> +	u16 pic_order_cnt_type:				2;
> +	u16 log2_max_pic_order_cnt_lsb_minus4:		4;
> +	u16 delta_pic_order_always_zero_flag:		1;
> +
> +	u16 pic_width_in_mbs:				16;
> +	u16 pic_height_in_mbs:				16;
> +
> +	u16 frame_mbs_only_flag:			1;
> +	u16 mb_adaptive_frame_field_flag:		1;
> +	u16 direct_8x8_inference_flag:			1;
> +	u16 mvc_extension_enable:			1;
> +	u16 num_views:					2;
> +	u16 view_id0:                                   10;
> +	u16 view_id1:                                   10;
> +} __packed;
> +
> +struct rkvdec_pps {
> +	u32 pic_parameter_set_id:				8;
> +	u32 pps_seq_parameter_set_id:				5;
> +	u32 entropy_coding_mode_flag:				1;
> +	u32 bottom_field_pic_order_in_frame_present_flag:	1;
> +	u32 num_ref_idx_l0_default_active_minus1:		5;
> +	u32 num_ref_idx_l1_default_active_minus1:		5;
> +	u32 weighted_pred_flag:					1;
> +	u32 weighted_bipred_idc:				2;
> +	u32 pic_init_qp_minus26:				7;
> +	u32 pic_init_qs_minus26:				6;
> +	u32 chroma_qp_index_offset:				5;
> +	u32 deblocking_filter_control_present_flag:		1;
> +	u32 constrained_intra_pred_flag:			1;
> +	u32 redundant_pic_cnt_present:				1;
> +	u32 transform_8x8_mode_flag:				1;
> +	u32 second_chroma_qp_index_offset:			5;
> +	u32 scaling_list_enable_flag:				1;
> +	u32 is_longterm:					16;
> +	u32 voidx:						16;
> +
> +	// dpb
> +	u32 pic_field_flag:                                     1;
> +	u32 pic_associated_flag:                                1;
> +	u32 cur_top_field:					32;
> +	u32 cur_bot_field:					32;
> +
> +	u32 top_field_order_cnt0:				32;
> +	u32 bot_field_order_cnt0:				32;
> +	u32 top_field_order_cnt1:				32;
> +	u32 bot_field_order_cnt1:				32;
> +	u32 top_field_order_cnt2:				32;
> +	u32 bot_field_order_cnt2:				32;
> +	u32 top_field_order_cnt3:				32;
> +	u32 bot_field_order_cnt3:				32;
> +	u32 top_field_order_cnt4:				32;
> +	u32 bot_field_order_cnt4:				32;
> +	u32 top_field_order_cnt5:				32;
> +	u32 bot_field_order_cnt5:				32;
> +	u32 top_field_order_cnt6:				32;
> +	u32 bot_field_order_cnt6:				32;
> +	u32 top_field_order_cnt7:				32;
> +	u32 bot_field_order_cnt7:				32;
> +	u32 top_field_order_cnt8:				32;
> +	u32 bot_field_order_cnt8:				32;
> +	u32 top_field_order_cnt9:				32;
> +	u32 bot_field_order_cnt9:				32;
> +	u32 top_field_order_cnt10:				32;
> +	u32 bot_field_order_cnt10:				32;
> +	u32 top_field_order_cnt11:				32;
> +	u32 bot_field_order_cnt11:				32;
> +	u32 top_field_order_cnt12:				32;
> +	u32 bot_field_order_cnt12:				32;
> +	u32 top_field_order_cnt13:				32;
> +	u32 bot_field_order_cnt13:				32;
> +	u32 top_field_order_cnt14:				32;
> +	u32 bot_field_order_cnt14:				32;
> +	u32 top_field_order_cnt15:				32;
> +	u32 bot_field_order_cnt15:				32;
> +
> +	u32 ref_field_flags:					16;
> +	u32 ref_topfield_used:					16;
> +	u32 ref_botfield_used:					16;
> +	u32 ref_colmv_use_flag:					16;
> +
> +	u32 reserved0:						30;
> +	u32 reserved[3];
> +} __packed;
> +
> +struct rkvdec_sps_pps {
> +	struct rkvdec_sps sps;
> +	struct rkvdec_pps pps;
> +} __packed;
> +
> +/* Data structure describing auxiliary buffer format. */
> +struct rkvdec_h264_priv_tbl {
> +	s8 cabac_table[4][464][2];
> +	struct rkvdec_h264_scaling_list scaling_list;
> +	struct rkvdec_sps_pps param_set[256];
> +	struct rkvdec_rps rps;
> +} __packed;
> +
> +struct rkvdec_h264_ctx {
> +	struct rkvdec_aux_buf priv_tbl;
> +	struct rkvdec_h264_reflists reflists;
> +	struct vdpu383_regs_h26x regs;
> +};
> +
> +static void set_field_order_cnt(struct rkvdec_sps_pps *hw_ps, int id, u32
> top, u32 bottom)
> +{
> +	switch (id) {
> +	case 0:
> +		hw_ps->pps.top_field_order_cnt0 = top;
> +		hw_ps->pps.bot_field_order_cnt0 = bottom;
> +		break;
> +	case 1:
> +		hw_ps->pps.top_field_order_cnt1 = top;
> +		hw_ps->pps.bot_field_order_cnt1 = bottom;
> +		break;
> +	case 2:
> +		hw_ps->pps.top_field_order_cnt2 = top;
> +		hw_ps->pps.bot_field_order_cnt2 = bottom;
> +		break;
> +	case 3:
> +		hw_ps->pps.top_field_order_cnt3 = top;
> +		hw_ps->pps.bot_field_order_cnt3 = bottom;
> +		break;
> +	case 4:
> +		hw_ps->pps.top_field_order_cnt4 = top;
> +		hw_ps->pps.bot_field_order_cnt4 = bottom;
> +		break;
> +	case 5:
> +		hw_ps->pps.top_field_order_cnt5 = top;
> +		hw_ps->pps.bot_field_order_cnt5 = bottom;
> +		break;
> +	case 6:
> +		hw_ps->pps.top_field_order_cnt6 = top;
> +		hw_ps->pps.bot_field_order_cnt6 = bottom;
> +		break;
> +	case 7:
> +		hw_ps->pps.top_field_order_cnt7 = top;
> +		hw_ps->pps.bot_field_order_cnt7 = bottom;
> +		break;
> +	case 8:
> +		hw_ps->pps.top_field_order_cnt8 = top;
> +		hw_ps->pps.bot_field_order_cnt8 = bottom;
> +		break;
> +	case 9:
> +		hw_ps->pps.top_field_order_cnt9 = top;
> +		hw_ps->pps.bot_field_order_cnt9 = bottom;
> +		break;
> +	case 10:
> +		hw_ps->pps.top_field_order_cnt10 = top;
> +		hw_ps->pps.bot_field_order_cnt10 = bottom;
> +		break;
> +	case 11:
> +		hw_ps->pps.top_field_order_cnt11 = top;
> +		hw_ps->pps.bot_field_order_cnt11 = bottom;
> +		break;
> +	case 12:
> +		hw_ps->pps.top_field_order_cnt12 = top;
> +		hw_ps->pps.bot_field_order_cnt12 = bottom;
> +		break;
> +	case 13:
> +		hw_ps->pps.top_field_order_cnt13 = top;
> +		hw_ps->pps.bot_field_order_cnt13 = bottom;
> +		break;
> +	case 14:
> +		hw_ps->pps.top_field_order_cnt14 = top;
> +		hw_ps->pps.bot_field_order_cnt14 = bottom;
> +		break;
> +	case 15:
> +		hw_ps->pps.top_field_order_cnt15 = top;
> +		hw_ps->pps.bot_field_order_cnt15 = bottom;
> +		break;
> +	}
> +}
> +
> +static void assemble_hw_pps(struct rkvdec_ctx *ctx,
> +			    struct rkvdec_h264_run *run)
> +{
> +	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
> +	const struct v4l2_ctrl_h264_sps *sps = run->sps;
> +	const struct v4l2_ctrl_h264_pps *pps = run->pps;
> +	const struct v4l2_ctrl_h264_decode_params *dec_params = run-
> >decode_params;
> +	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
> +	struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
> +	struct rkvdec_sps_pps *hw_ps;
> +	u32 pic_width, pic_height;
> +	u32 i;
> +
> +	/*
> +	 * HW read the SPS/PPS information from PPS packet index by PPS id.
> +	 * offset from the base can be calculated by PPS_id * 32 (size per
> PPS
> +	 * packet unit). so the driver copy SPS/PPS information to the exact
> PPS
> +	 * packet unit for HW accessing.
> +	 */
> +	hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
> +	memset(hw_ps, 0, sizeof(*hw_ps));
> +
> +	/* write sps */
> +	hw_ps->sps.seq_parameter_set_id = sps->seq_parameter_set_id;
> +	hw_ps->sps.profile_idc = sps->profile_idc;
> +	hw_ps->sps.constraint_set3_flag = !!(sps->constraint_set_flags & (1
> << 3));
> +	hw_ps->sps.chroma_format_idc = sps->chroma_format_idc;
> +	hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8;
> +	hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8;
> +	hw_ps->sps.qpprime_y_zero_transform_bypass_flag =
> +		!!(sps->flags &
> V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
> +	hw_ps->sps.log2_max_frame_num_minus4 = sps-
> >log2_max_frame_num_minus4;
> +	hw_ps->sps.max_num_ref_frames = sps->max_num_ref_frames;
> +	hw_ps->sps.pic_order_cnt_type = sps->pic_order_cnt_type;
> +	hw_ps->sps.log2_max_pic_order_cnt_lsb_minus4 =
> +		sps->log2_max_pic_order_cnt_lsb_minus4;
> +	hw_ps->sps.delta_pic_order_always_zero_flag =
> +		!!(sps->flags &
> V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
> +	hw_ps->sps.mvc_extension_enable = 0;
> +	hw_ps->sps.num_views = 0;
> +
> +	/*
> +	 * Use the SPS values since they are already in macroblocks
> +	 * dimensions, height can be field height (halved) if
> +	 * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is not set and also it allows
> +	 * decoding smaller images into larger allocation which can be used
> +	 * to implementing SVC spatial layer support.
> +	 */
> +	pic_width = 16 * (sps->pic_width_in_mbs_minus1 + 1);
> +	pic_height = 16 * (sps->pic_height_in_map_units_minus1 + 1);
> +	if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
> +		pic_height *= 2;
> +	if (!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC))
> +		pic_height /= 2;
> +
> +	hw_ps->sps.pic_width_in_mbs = pic_width;
> +	hw_ps->sps.pic_height_in_mbs = pic_height;
> +
> +	hw_ps->sps.frame_mbs_only_flag =
> +		!!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
> +	hw_ps->sps.mb_adaptive_frame_field_flag =
> +		!!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
> +	hw_ps->sps.direct_8x8_inference_flag =
> +		!!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
> +
> +	/* write pps */
> +	hw_ps->pps.pic_parameter_set_id = pps->pic_parameter_set_id;
> +	hw_ps->pps.pps_seq_parameter_set_id = pps->seq_parameter_set_id;
> +	hw_ps->pps.entropy_coding_mode_flag =
> +		!!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
> +	hw_ps->pps.bottom_field_pic_order_in_frame_present_flag =
> +		!!(pps->flags &
> V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
> +	hw_ps->pps.num_ref_idx_l0_default_active_minus1 =
> +		pps->num_ref_idx_l0_default_active_minus1;
> +	hw_ps->pps.num_ref_idx_l1_default_active_minus1 =
> +		pps->num_ref_idx_l1_default_active_minus1;
> +	hw_ps->pps.weighted_pred_flag =
> +		!!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
> +	hw_ps->pps.weighted_bipred_idc = pps->weighted_bipred_idc;
> +	hw_ps->pps.pic_init_qp_minus26 = pps->pic_init_qp_minus26;
> +	hw_ps->pps.pic_init_qs_minus26 = pps->pic_init_qs_minus26;
> +	hw_ps->pps.chroma_qp_index_offset = pps->chroma_qp_index_offset;
> +	hw_ps->pps.deblocking_filter_control_present_flag =
> +		!!(pps->flags &
> V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
> +	hw_ps->pps.constrained_intra_pred_flag =
> +		!!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
> +	hw_ps->pps.redundant_pic_cnt_present =
> +		!!(pps->flags &
> V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
> +	hw_ps->pps.transform_8x8_mode_flag =
> +		!!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
> +	hw_ps->pps.second_chroma_qp_index_offset = pps-
> >second_chroma_qp_index_offset;
> +	hw_ps->pps.scaling_list_enable_flag =
> +		!!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
> +
> +	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
> +		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
> +			hw_ps->pps.is_longterm |= (1 << i);
> +
> +		set_field_order_cnt(hw_ps, i, dpb[i].top_field_order_cnt,
> +				    dpb[i].bottom_field_order_cnt);
> +
> +		hw_ps->pps.ref_field_flags |=
> +			(!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD))
> << i;
> +		hw_ps->pps.ref_colmv_use_flag |=
> +			(!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> << i;
> +		hw_ps->pps.ref_topfield_used |=
> +			(!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF)) << i;
> +		hw_ps->pps.ref_botfield_used |=
> +			(!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) <<
> i;
> +	}
> +
> +	hw_ps->pps.pic_field_flag =
> +		!!(dec_params->flags &
> V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC);
> +	hw_ps->pps.pic_associated_flag =
> +		!!(dec_params->flags &
> V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);
> +
> +	hw_ps->pps.cur_top_field = dec_params->top_field_order_cnt;
> +	hw_ps->pps.cur_bot_field = dec_params->bottom_field_order_cnt;
> +}
> +
> +static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
> +{
> +	struct rkvdec_dev *rkvdec = ctx->dev;
> +	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
> +
> +	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_REGS,
> +			   &h264_ctx->regs.common,
> +			   sizeof(h264_ctx->regs.common));
> +	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_ADDR_REGS,
> +			   &h264_ctx->regs.common_addr,
> +			   sizeof(h264_ctx->regs.common_addr));
> +	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_PARAMS_REGS,
> +			   &h264_ctx->regs.h26x_params,
> +			   sizeof(h264_ctx->regs.h26x_params));
> +	rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_ADDR_REGS,
> +			   &h264_ctx->regs.h26x_addr,
> +			   sizeof(h264_ctx->regs.h26x_addr));
> +}
> +
> +static void config_registers(struct rkvdec_ctx *ctx,
> +			     struct rkvdec_h264_run *run)
> +{
> +	const struct v4l2_ctrl_h264_decode_params *dec_params = run-
> >decode_params;
> +	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
> +	dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma;
> +	const struct v4l2_pix_format_mplane *dst_fmt;
> +	struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
> +	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
> +	struct vdpu383_regs_h26x *regs = &h264_ctx->regs;
> +	const struct v4l2_format *f;
> +	dma_addr_t rlc_addr;
> +	dma_addr_t dst_addr;
> +	u32 hor_virstride;
> +	u32 ver_virstride;
> +	u32 y_virstride;
> +	u32 offset;
> +	u32 pixels;
> +	u32 i;
> +
> +	memset(regs, 0, sizeof(*regs));
> +
> +	/* Set H264 mode */
> +	regs->common.reg008_dec_mode = VDPU383_MODE_H264;
> +
> +	/* Set input stream length */
> +	regs->h26x_params.reg066_stream_len = vb2_get_plane_payload(&src_buf-
> >vb2_buf, 0);
> +
> +	/* Set strides */
> +	f = &ctx->decoded_fmt;
> +	dst_fmt = &f->fmt.pix_mp;
> +	hor_virstride = dst_fmt->plane_fmt[0].bytesperline;
> +	ver_virstride = dst_fmt->height;
> +	y_virstride = hor_virstride * ver_virstride;
> +
> +	pixels = dst_fmt->height * dst_fmt->width;
> +
> +	regs->h26x_params.reg068_hor_virstride = hor_virstride / 16;
> +	regs->h26x_params.reg069_raster_uv_hor_virstride = hor_virstride /
> 16;
> +	regs->h26x_params.reg070_y_virstride = y_virstride / 16;
> +
> +	/* Activate block gating */
> +	regs->common.reg010.strmd_auto_gating_e      = 1;
> +	regs->common.reg010.inter_auto_gating_e      = 1;
> +	regs->common.reg010.intra_auto_gating_e      = 1;
> +	regs->common.reg010.transd_auto_gating_e     = 1;
> +	regs->common.reg010.recon_auto_gating_e      = 1;
> +	regs->common.reg010.filterd_auto_gating_e    = 1;
> +	regs->common.reg010.bus_auto_gating_e        = 1;
> +	regs->common.reg010.ctrl_auto_gating_e       = 1;
> +	regs->common.reg010.rcb_auto_gating_e        = 1;
> +	regs->common.reg010.err_prc_auto_gating_e    = 1;
> +
> +	/* Set timeout threshold */
> +	if (pixels < VDPU383_1080P_PIXELS)
> +		regs->common.reg013_core_timeout_threshold =
> VDPU383_TIMEOUT_1080p;
> +	else if (pixels < VDPU383_4K_PIXELS)
> +		regs->common.reg013_core_timeout_threshold =
> VDPU383_TIMEOUT_4K;
> +	else if (pixels < VDPU383_8K_PIXELS)
> +		regs->common.reg013_core_timeout_threshold =
> VDPU383_TIMEOUT_8K;
> +	else
> +		regs->common.reg013_core_timeout_threshold =
> VDPU383_TIMEOUT_MAX;
> +
> +	regs->common.reg016.error_proc_disable = 1;
> +
> +	/* Set ref pic address & poc */
> +	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
> +		struct vb2_buffer *vb_buf = run->ref_buf[i];
> +		dma_addr_t buf_dma;
> +
> +		/*
> +		 * If a DPB entry is unused or invalid, address of current
> destination
> +		 * buffer is returned.
> +		 */
> +		if (!vb_buf)
> +			vb_buf = &dst_buf->vb2_buf;
> +
> +		buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
> +
> +		/* Set reference addresses */
> +		regs->h26x_addr.reg170_185_ref_base[i] = buf_dma;
> +		regs->h26x_addr.reg195_210_payload_st_ref_base[i] = buf_dma;
> +
> +		/* Set COLMV addresses */
> +		regs->h26x_addr.reg217_232_colmv_ref_base[i] = buf_dma + ctx-
> >colmv_offset;
> +	}
> +
> +	/* Set rlc base address (input stream) */
> +	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
> +	regs->common_addr.reg128_strm_base = rlc_addr;
> +
> +	/* Set output base address */
> +	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
> +	regs->h26x_addr.reg168_decout_base = dst_addr;
> +	regs->h26x_addr.reg169_error_ref_base = dst_addr;
> +	regs->h26x_addr.reg192_payload_st_cur_base = dst_addr;
> +
> +	/* Set colmv address */
> +	regs->h26x_addr.reg216_colmv_cur_base = dst_addr + ctx->colmv_offset;
> +
> +	/* Set RCB addresses */
> +	for (i = 0; i < rkvdec_rcb_buf_count(ctx); i++) {
> +		regs->common_addr.reg140_162_rcb_info[i].offset =
> rkvdec_rcb_buf_dma_addr(ctx, i);
> +		regs->common_addr.reg140_162_rcb_info[i].size =
> rkvdec_rcb_buf_size(ctx, i);
> +	}
> +
> +	/* Set hw pps address */
> +	offset = offsetof(struct rkvdec_h264_priv_tbl, param_set);
> +	regs->common_addr.reg131_gbl_base = priv_start_addr + offset;
> +	regs->h26x_params.reg067_global_len = sizeof(struct rkvdec_sps_pps) /
> 16;
> +
> +	/* Set hw rps address */
> +	offset = offsetof(struct rkvdec_h264_priv_tbl, rps);
> +	regs->common_addr.reg129_rps_base = priv_start_addr + offset;
> +
> +	/* Set cabac table */
> +	offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table);
> +	regs->common_addr.reg130_cabactbl_base = priv_start_addr + offset;
> +
> +	/* Set scaling list address */
> +	offset = offsetof(struct rkvdec_h264_priv_tbl, scaling_list);
> +	regs->common_addr.reg132_scanlist_addr = priv_start_addr + offset;
> +
> +	rkvdec_write_regs(ctx);
> +}
> +
> +static int rkvdec_h264_start(struct rkvdec_ctx *ctx)
> +{
> +	struct rkvdec_dev *rkvdec = ctx->dev;
> +	struct rkvdec_h264_priv_tbl *priv_tbl;
> +	struct rkvdec_h264_ctx *h264_ctx;
> +	struct v4l2_ctrl *ctrl;
> +	int ret;
> +
> +	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
> +			      V4L2_CID_STATELESS_H264_SPS);
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	ret = rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps);
> +	if (ret)
> +		return ret;
> +
> +	h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL);
> +	if (!h264_ctx)
> +		return -ENOMEM;
> +
> +	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
> +				      &h264_ctx->priv_tbl.dma, GFP_KERNEL);
> +	if (!priv_tbl) {
> +		ret = -ENOMEM;
> +		goto err_free_ctx;
> +	}
> +
> +	h264_ctx->priv_tbl.size = sizeof(*priv_tbl);
> +	h264_ctx->priv_tbl.cpu = priv_tbl;
> +	memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table,
> +	       sizeof(rkvdec_h264_cabac_table));
> +
> +	ctx->priv = h264_ctx;
> +
> +	return 0;
> +
> +err_free_ctx:
> +	kfree(h264_ctx);
> +	return ret;
> +}
> +
> +static void rkvdec_h264_stop(struct rkvdec_ctx *ctx)
> +{
> +	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
> +	struct rkvdec_dev *rkvdec = ctx->dev;
> +
> +	dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size,
> +			  h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma);
> +	kfree(h264_ctx);
> +}
> +
> +static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
> +{
> +	struct v4l2_h264_reflist_builder reflist_builder;
> +	struct rkvdec_dev *rkvdec = ctx->dev;
> +	struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
> +	struct rkvdec_h264_run run;
> +	struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
> +	u32 watchdog_time;
> +	u64 timeout_threshold;
> +	unsigned long axi_rate;
> +
> +	rkvdec_h264_run_preamble(ctx, &run);
> +
> +	/* Build the P/B{0,1} ref lists. */
> +	v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params,
> +				       run.sps, run.decode_params->dpb);
> +	v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
> +	v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
> +				    h264_ctx->reflists.b1);
> +
> +	assemble_hw_scaling_list(&run, &tbl->scaling_list);
> +	assemble_hw_pps(ctx, &run);
> +	lookup_ref_buf_idx(ctx, &run);
> +	assemble_hw_rps(&reflist_builder, &run, &h264_ctx->reflists, &tbl-
> >rps);
> +
> +	config_registers(ctx, &run);
> +
> +	rkvdec_run_postamble(ctx, &run.base);
> +
> +	/* Set watchdog at 2 times the hardware timeout threshold */
> +	timeout_threshold = h264_ctx-
> >regs.common.reg013_core_timeout_threshold;
> +	axi_rate = clk_get_rate(rkvdec->axi_clk);
> +
> +	if (axi_rate)
> +		watchdog_time = 2 * (1000 * timeout_threshold) / axi_rate;
> +	else
> +		watchdog_time = 2000;
> +	schedule_delayed_work(&rkvdec->watchdog_work,
> +			      msecs_to_jiffies(watchdog_time));
> +
> +	/* Start decoding! */
> +	writel(timeout_threshold, rkvdec->link +
> VDPU383_LINK_TIMEOUT_THRESHOLD);
> +	writel(0, rkvdec->link + VDPU383_LINK_IP_ENABLE);
> +	writel(VDPU383_DEC_E_BIT, rkvdec->link + VDPU383_LINK_DEC_ENABLE);
> +
> +	return 0;
> +}
> +
> +static int rkvdec_h264_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl
> *ctrl)
> +{
> +	if (ctrl->id == V4L2_CID_STATELESS_H264_SPS)
> +		return rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps);
> +
> +	return 0;
> +}
> +
> +const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops = {
> +	.adjust_fmt = rkvdec_h264_adjust_fmt,
> +	.get_image_fmt = rkvdec_h264_get_image_fmt,
> +	.start = rkvdec_h264_start,
> +	.stop = rkvdec_h264_stop,
> +	.run = rkvdec_h264_run,
> +	.try_ctrl = rkvdec_h264_try_ctrl,
> +};
> diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h
> b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h
> new file mode 100644
> index 0000000000000..2b614393a3afa
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h
> @@ -0,0 +1,284 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Rockchip Video Decoder VDPU383 driver registers description
> + *
> + * Copyright (C) 2025 Collabora, Ltd.
> + *  Detlev Casanova <detlev.casanova@collabora.com>
> + */
> +
> +#ifndef _RKVDEC_VDPU838_REGS_H_
> +#define _RKVDEC_VDPU838_REGS_H_
> +
> +#include <linux/types.h>
> +
> +#define VDPU383_OFFSET_COMMON_REGS		(8 * sizeof(u32))
> +#define VDPU383_OFFSET_CODEC_PARAMS_REGS	(64 * sizeof(u32))
> +#define VDPU383_OFFSET_COMMON_ADDR_REGS		(128 * sizeof(u32))
> +#define VDPU383_OFFSET_CODEC_ADDR_REGS		(168 * sizeof(u32))
> +#define VDPU383_OFFSET_POC_HIGHBIT_REGS		(200 * sizeof(u32))
> +
> +#define VDPU383_MODE_HEVC	0
> +#define VDPU383_MODE_H264	1
> +
> +#define VDPU383_1080P_PIXELS		(1920 * 1080)
> +#define VDPU383_4K_PIXELS		(4096 * 2304)
> +#define VDPU383_8K_PIXELS		(7680 * 4320)
> +#define VDPU383_TIMEOUT_1080p		(0xffffff)
> +#define VDPU383_TIMEOUT_4K		(0x2cfffff)
> +#define VDPU383_TIMEOUT_8K		(0x4ffffff)
> +#define VDPU383_TIMEOUT_MAX		(0xffffffff)
> +
> +#define VDPU383_LINK_TIMEOUT_THRESHOLD	0x54
> +
> +#define VDPU383_LINK_IP_ENABLE		0x58
> +#define VDPU383_IP_CRU_MODE		BIT(24)
> +
> +#define VDPU383_LINK_DEC_ENABLE		0x40
> +#define VDPU383_DEC_E_BIT		BIT(0)
> +
> +#define VDPU383_LINK_INT_EN		0x048
> +#define VDPU383_INT_EN_IRQ		BIT(0)
> +#define VDPU383_INT_EN_LINE_IRQ		BIT(1)
> +
> +#define VDPU383_LINK_STA_INT		0x04c
> +#define VDPU383_STA_INT_DEC_RDY_STA	BIT(0)
> +#define VDPU383_STA_INT_SOFTRESET_RDY	(BIT(10) | BIT(11))
> +#define VDPU383_STA_INT_ALL		0x3ff
> +
> +struct vdpu383_regs_common {
> +	u32 reg008_dec_mode;
> +
> +	struct swreg9_important_en {
> +		u32 fbc_e			: 1;
> +		u32 tile_e			: 1;
> +		u32 reserve0			: 2;
> +		u32 buf_empty_en		: 1;
> +		u32 scale_down_en		: 1;
> +		u32 reserve1			: 1;
> +		u32 pix_range_det_e		: 1;
> +		u32 av1_fgs_en			: 1;
> +		u32 reserve2			: 7;
> +		u32 line_irq_en			: 1;
> +		u32 out_cbcr_swap		: 1;
> +		u32 fbc_force_uncompress	: 1;
> +		u32 fbc_sparse_mode		: 1;
> +		u32 reserve3			: 12;
> +	} reg009;
> +
> +	struct swreg010_block_gating_en {
> +		u32 strmd_auto_gating_e		: 1;
> +		u32 inter_auto_gating_e		: 1;
> +		u32 intra_auto_gating_e		: 1;
> +		u32 transd_auto_gating_e	: 1;
> +		u32 recon_auto_gating_e		: 1;
> +		u32 filterd_auto_gating_e	: 1;
> +		u32 bus_auto_gating_e		: 1;
> +		u32 ctrl_auto_gating_e		: 1;
> +		u32 rcb_auto_gating_e		: 1;
> +		u32 err_prc_auto_gating_e	: 1;
> +		u32 reserve0			: 22;
> +	} reg010;
> +
> +	struct swreg011_cfg_para {
> +		u32 reserve0			: 9;
> +		u32 dec_timeout_dis		: 1;
> +		u32 reserve1			: 22;
> +	} reg011;
> +
> +	struct swreg012_cache_hash_mask {
> +		u32 reserve0			: 7;
> +		u32 cache_hash_mask		: 25;
> +	} reg012;
> +
> +	u32 reg013_core_timeout_threshold;
> +
> +	struct swreg014_line_irq_ctrl {
> +		u32 dec_line_irq_step		: 16;
> +		u32 dec_line_offset_y_st	: 16;
> +	} reg014;
> +
> +	struct swreg015_irq_sta {
> +		u32 rkvdec_frame_rdy_sta	: 1;
> +		u32 rkvdec_strm_error_sta	: 1;
> +		u32 rkvdec_core_timeout_sta	: 1;
> +		u32 rkvdec_ip_timeout_sta	: 1;
> +		u32 rkvdec_bus_error_sta	: 1;
> +		u32 rkvdec_buffer_empty_sta	: 1;
> +		u32 rkvdec_colmv_ref_error_sta	: 1;
> +		u32 rkvdec_error_spread_sta	: 1;
> +		u32 create_core_timeout_sta	: 1;
> +		u32 wlast_miss_match_sta	: 1;
> +		u32 rkvdec_core_rst_rdy_sta	: 1;
> +		u32 rkvdec_ip_rst_rdy_sta	: 1;
> +		u32 force_busidle_rdy_sta	: 1;
> +		u32 ltb_pause_rdy_sta		: 1;
> +		u32 ltb_end_flag		: 1;
> +		u32 unsupport_decmode_error_sta	: 1;
> +		u32 wmask_bits			: 15;
> +		u32 reserve0			: 1;
> +	} reg015;
> +
> +	struct swreg016_error_ctrl_set {
> +		u32 error_proc_disable		: 1;
> +		u32 reserve0			: 7;
> +		u32 error_spread_disable	: 1;
> +		u32 reserve1			: 15;
> +		u32 roi_error_ctu_cal_en	: 1;
> +		u32 reserve2			: 7;
> +	} reg016;
> +
> +	struct swreg017_err_roi_ctu_offset_start {
> +		u32 roi_x_ctu_offset_st		: 12;
> +		u32 reserve0			: 4;
> +		u32 roi_y_ctu_offset_st		: 12;
> +		u32 reserve1			: 4;
> +	} reg017;
> +
> +	struct swreg018_err_roi_ctu_offset_end {
> +		u32 roi_x_ctu_offset_end	: 12;
> +		u32 reserve0			: 4;
> +		u32 roi_y_ctu_offset_end	: 12;
> +		u32 reserve1			: 4;
> +	} reg018;
> +
> +	struct swreg019_error_ref_info {
> +		u32 avs2_ref_error_field	: 1;
> +		u32 avs2_ref_error_topfield	: 1;
> +		u32 ref_error_topfield_used	: 1;
> +		u32 ref_error_botfield_used	: 1;
> +		u32 reserve0			: 28;
> +	} reg019;
> +
> +	u32 reg020_cabac_error_en_lowbits;
> +	u32 reg021_cabac_error_en_highbits;
> +
> +	u32 reg022_reserved;
> +
> +	struct swreg023_invalid_pixel_fill {
> +		u32 fill_y			: 10;
> +		u32 fill_u			: 10;
> +		u32 fill_v			: 10;
> +		u32 reserve0			: 2;
> +	} reg023;
> +
> +	u32 reg024_026_reserved[3];
> +
> +	struct swreg027_align_en {
> +		u32 reserve0			: 4;
> +		u32 ctu_align_wr_en		: 1;
> +		u32 reserve1			: 27;
> +	} reg027;
> +
> +	struct swreg028_debug_perf_latency_ctrl0 {
> +		u32 axi_perf_work_e		: 1;
> +		u32 reserve0			: 2;
> +		u32 axi_cnt_type		: 1;
> +		u32 rd_latency_id		: 8;
> +		u32 reserve1			: 4;
> +		u32 rd_latency_thr		: 12;
> +		u32 reserve2			: 4;
> +	} reg028;
> +
> +	struct swreg029_debug_perf_latency_ctrl1 {
> +		u32 addr_align_type		: 2;
> +		u32 ar_cnt_id_type		: 1;
> +		u32 aw_cnt_id_type		: 1;
> +		u32 ar_count_id			: 8;
> +		u32 reserve0			: 4;
> +		u32 aw_count_id			: 8;
> +		u32 rd_band_width_mode		: 1;
> +		u32 reserve1			: 7;
> +	} reg029;
> +
> +	struct swreg030_qos_ctrl {
> +		u32 axi_wr_qos_level		: 4;
> +		u32 reserve0			: 4;
> +		u32 axi_wr_qos			: 4;
> +		u32 reserve1			: 4;
> +		u32 axi_rd_qos_level		: 4;
> +		u32 reserve2			: 4;
> +		u32 axi_rd_qos			: 4;
> +		u32 reserve3			: 4;
> +	} reg030;
> +};
> +
> +struct vdpu383_regs_common_addr {
> +	u32 reg128_strm_base;
> +	u32 reg129_rps_base;
> +	u32 reg130_cabactbl_base;
> +	u32 reg131_gbl_base;
> +	u32 reg132_scanlist_addr;
> +	u32 reg133_scale_down_base;
> +	u32 reg134_fgs_base;
> +	u32 reg135_139_reserved[5];
> +
> +	struct rcb_info {
> +	u32 offset;
> +	u32 size;
> +	} reg140_162_rcb_info[11];
> +};
> +
> +struct vdpu383_regs_h26x_addr {
> +	u32 reg168_decout_base;
> +	u32 reg169_error_ref_base;
> +	u32 reg170_185_ref_base[16];
> +	u32 reg186_191_reserved[6];
> +	u32 reg192_payload_st_cur_base;
> +	u32 reg193_fbc_payload_offset;
> +	u32 reg194_payload_st_error_ref_base;
> +	u32 reg195_210_payload_st_ref_base[16];
> +	u32 reg211_215_reserved[5];
> +	u32 reg216_colmv_cur_base;
> +	u32 reg217_232_colmv_ref_base[16];
> +};
> +
> +struct vdpu383_regs_h26x_params {
> +	u32 reg064_start_decoder;
> +	u32 reg065_strm_start_bit;
> +	u32 reg066_stream_len;
> +	u32 reg067_global_len;
> +	u32 reg068_hor_virstride;
> +	u32 reg069_raster_uv_hor_virstride;
> +	u32 reg070_y_virstride;
> +	u32 reg071_scl_ref_hor_virstride;
> +	u32 reg072_scl_ref_raster_uv_hor_virstride;
> +	u32 reg073_scl_ref_virstride;
> +	u32 reg074_fgs_ref_hor_virstride;
> +	u32 reg075_079_reserved[5];
> +	u32 reg080_error_ref_hor_virstride;
> +	u32 reg081_error_ref_raster_uv_hor_virstride;
> +	u32 reg082_error_ref_virstride;
> +	u32 reg083_ref0_hor_virstride;
> +	u32 reg084_ref0_raster_uv_hor_virstride;
> +	u32 reg085_ref0_virstride;
> +	u32 reg086_ref1_hor_virstride;
> +	u32 reg087_ref1_raster_uv_hor_virstride;
> +	u32 reg088_ref1_virstride;
> +	u32 reg089_ref2_hor_virstride;
> +	u32 reg090_ref2_raster_uv_hor_virstride;
> +	u32 reg091_ref2_virstride;
> +	u32 reg092_ref3_hor_virstride;
> +	u32 reg093_ref3_raster_uv_hor_virstride;
> +	u32 reg094_ref3_virstride;
> +	u32 reg095_ref4_hor_virstride;
> +	u32 reg096_ref4_raster_uv_hor_virstride;
> +	u32 reg097_ref4_virstride;
> +	u32 reg098_ref5_hor_virstride;
> +	u32 reg099_ref5_raster_uv_hor_virstride;
> +	u32 reg100_ref5_virstride;
> +	u32 reg101_ref6_hor_virstride;
> +	u32 reg102_ref6_raster_uv_hor_virstride;
> +	u32 reg103_ref6_virstride;
> +	u32 reg104_ref7_hor_virstride;
> +	u32 reg105_ref7_raster_uv_hor_virstride;
> +	u32 reg106_ref7_virstride;
> +};
> +
> +struct vdpu383_regs_h26x {
> +	struct vdpu383_regs_common		common;		/* 8-
> 30 */
> +	struct vdpu383_regs_h26x_params		h26x_params;	/*
> 64-74, 80-106 */
> +	struct vdpu383_regs_common_addr		common_addr;	/*
> 128-134, 140-161 */
> +	struct vdpu383_regs_h26x_addr		h26x_addr;	/* 168-185,
> 192-210, 216-232 */
> +} __packed;
> +
> +#endif /* __RKVDEC_VDPU838_REGS_H__ */
> diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
> b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
> index 1b55fe4ff2baf..dab34a2322c95 100644
> --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
> +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
> @@ -9,6 +9,7 @@
>   * Copyright (C) 2011 Samsung Electronics Co., Ltd.
>   */
>  
> +#include <linux/hw_bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/genalloc.h>
>  #include <linux/interrupt.h>
> @@ -29,6 +30,7 @@
>  #include "rkvdec.h"
>  #include "rkvdec-regs.h"
>  #include "rkvdec-vdpu381-regs.h"
> +#include "rkvdec-vdpu383-regs.h"
>  #include "rkvdec-rcb.h"
>  
>  static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,
> @@ -120,6 +122,16 @@ static int vdpu38x_fill_pixfmt_mp(struct
> v4l2_pix_format_mplane *pix_mp, u32 pix
>  	return 0;
>  }
>  
> +static u32 rkvdec_colmv_size(u16 width, u16 height)
> +{
> +	return 128 * DIV_ROUND_UP(width, 16) * DIV_ROUND_UP(height, 16);
> +}
> +
> +static u32 rkvdec_vdpu383_colmv_size(u16 width, u16 height)
> +{
> +	return ALIGN(width, 64) * ALIGN(height, 16);
> +}
> +
>  static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx,
>  				       struct v4l2_pix_format_mplane *pix_mp)
>  {
> @@ -129,9 +141,7 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx
> *ctx,
>  
>  	ctx->colmv_offset = pix_mp->plane_fmt[0].sizeimage;
>  
> -	pix_mp->plane_fmt[0].sizeimage += 128 *
> -		DIV_ROUND_UP(pix_mp->width, 16) *
> -		DIV_ROUND_UP(pix_mp->height, 16);
> +	pix_mp->plane_fmt[0].sizeimage += cfg->colmv_size(pix_mp->width,
> pix_mp->height);
>  }
>  
>  static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f,
> @@ -346,6 +356,25 @@ static const struct rkvdec_coded_fmt_desc
> vdpu381_coded_fmts[] = {
>  	},
>  };
>  
> +static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = {
> +	{
> +		.fourcc = V4L2_PIX_FMT_H264_SLICE,
> +		.frmsize = {
> +			.min_width = 64,
> +			.max_width =  65520,
> +			.step_width = 64,
> +			.min_height = 16,
> +			.max_height =  65520,
> +			.step_height = 16,
> +		},
> +		.ctrls = &rkvdec_h264_ctrls,
> +		.ops = &rkvdec_vdpu383_h264_fmt_ops,
> +		.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
> +		.decoded_fmts = rkvdec_h264_decoded_fmts,
> +		.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
> +	},
> +};
> +
>  static const struct rkvdec_coded_fmt_desc *
>  rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
>  {
> @@ -1213,6 +1242,35 @@ static irqreturn_t vdpu381_irq_handler(struct
> rkvdec_ctx *ctx)
>  	return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t vdpu383_irq_handler(struct rkvdec_ctx *ctx)
> +{
> +	struct rkvdec_dev *rkvdec = ctx->dev;
> +	enum vb2_buffer_state state;
> +	bool need_reset = 0;
> +	u32 status;
> +
> +	status = readl(rkvdec->link + VDPU383_LINK_STA_INT);
> +	writel(FIELD_PREP_WM16(VDPU383_STA_INT_ALL, 0), rkvdec->link +
> VDPU383_LINK_STA_INT);
> +	/* On vdpu383, the interrupts must be disabled */
> +	writel(FIELD_PREP_WM16(VDPU383_INT_EN_IRQ | VDPU383_INT_EN_LINE_IRQ,
> 0),
> +	       rkvdec->link + VDPU383_LINK_INT_EN);
> +
> +	if (status & VDPU383_STA_INT_DEC_RDY_STA) {
> +		state = VB2_BUF_STATE_DONE;
> +	} else {
> +		state = VB2_BUF_STATE_ERROR;
> +		rkvdec_iommu_restore(rkvdec);
> +	}
> +
> +	if (need_reset)
> +		rkvdec_iommu_restore(rkvdec);
> +
> +	if (cancel_delayed_work(&rkvdec->watchdog_work))
> +		rkvdec_job_finish(ctx, state);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
>  {
>  	struct rkvdec_dev *rkvdec = priv;
> @@ -1285,6 +1343,7 @@ const struct rkvdec_config config_rkvdec = {
>  	.coded_fmts_num = ARRAY_SIZE(rkvdec_coded_fmts),
>  	.irq_handler = rk3399_irq_handler,
>  	.fill_pixfmt_mp = v4l2_fill_pixfmt_mp,
> +	.colmv_size = rkvdec_colmv_size,
>  };
>  
>  static struct rcb_size_info vdpu381_rcb_sizes[] = {
> @@ -1307,11 +1366,39 @@ const struct rkvdec_config config_vdpu381 = {
>  	.rcb_num = ARRAY_SIZE(vdpu381_rcb_sizes),
>  	.irq_handler = vdpu381_irq_handler,
>  	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
> +	.colmv_size = rkvdec_colmv_size,
> +	.named_regs = true,
> +};
> +
> +static struct rcb_size_info vdpu383_rcb_sizes[] = {
> +	{6,	PIC_WIDTH},	// streamd
> +	{6,	PIC_WIDTH},	// streamd_tile
> +	{12,	PIC_WIDTH},	// inter
> +	{12,	PIC_WIDTH},	// inter_tile
> +	{16,	PIC_WIDTH},	// intra
> +	{10,	PIC_WIDTH},	// intra_tile
> +	{120,	PIC_WIDTH},	// filterd
> +	{120,	PIC_WIDTH},	// filterd_protect
> +	{120,	PIC_WIDTH},	// filterd_tile_row
> +	{180,	PIC_HEIGHT},	// filterd_tile_col
> +};
> +
> +const struct rkvdec_config config_vdpu383 = {
> +	.coded_fmts = (struct rkvdec_coded_fmt_desc *)vdpu383_coded_fmts,
> +	.coded_fmts_num = ARRAY_SIZE(vdpu383_coded_fmts),
> +	.rcb_size_info = vdpu383_rcb_sizes,
> +	.rcb_num = ARRAY_SIZE(vdpu383_rcb_sizes),
> +	.irq_handler = vdpu383_irq_handler,
> +	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
> +	.colmv_size = rkvdec_vdpu383_colmv_size,
> +	.fill_pixfmt_mp = vdpu38x_fill_pixfmt_mp,
> +	.named_regs = true,
>  };
>  
>  static const struct of_device_id of_rkvdec_match[] = {
>  	{ .compatible = "rockchip,rk3399-vdec", .data = &config_rkvdec },
>  	{ .compatible = "rockchip,rk3588-vdec", .data = &config_vdpu381 },
> +	{ .compatible = "rockchip,rk3576-vdec", .data = &config_vdpu383 },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, of_rkvdec_match);
> @@ -1344,9 +1431,19 @@ static int rkvdec_probe(struct platform_device *pdev)
>  	rkvdec->clk_count = ret;
>  	rkvdec->axi_clk = devm_clk_get(&pdev->dev, "axi");
>  
> -	rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
> -	if (IS_ERR(rkvdec->regs))
> -		return PTR_ERR(rkvdec->regs);
> +	if (rkvdec->config->named_regs) {
> +		rkvdec->regs = devm_platform_ioremap_resource_byname(pdev,
> "function");
> +		if (IS_ERR(rkvdec->regs))
> +			return PTR_ERR(rkvdec->regs);
> +
> +		rkvdec->link = devm_platform_ioremap_resource_byname(pdev,
> "link");
> +		if (IS_ERR(rkvdec->link))
> +			return PTR_ERR(rkvdec->link);
> +	} else {
> +		rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
> +		if (IS_ERR(rkvdec->regs))
> +			return PTR_ERR(rkvdec->regs);
> +	}
>  
>  	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
>  	if (ret) {
> diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
> b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
> index 9e0fef2445abc..acb9d72b130bb 100644
> --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
> +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
> @@ -110,6 +110,8 @@ struct rkvdec_config {
>  	irqreturn_t (*irq_handler)(struct rkvdec_ctx *ctx);
>  	int (*fill_pixfmt_mp)(struct v4l2_pix_format_mplane *pix_mp, u32
> pixelformat,
>  			      u32 width, u32 height);
> +	u32 (*colmv_size)(u16 width, u16 height);
> +	bool named_regs;
>  };
>  
>  struct rkvdec_dev {
> @@ -122,6 +124,7 @@ struct rkvdec_dev {
>  	unsigned int clk_count;
>  	struct clk *axi_clk;
>  	void __iomem *regs;
> +	void __iomem *link;
>  	struct mutex vdev_lock; /* serializes ioctls */
>  	struct delayed_work watchdog_work;
>  	struct gen_pool *sram_pool;
> @@ -164,9 +167,14 @@ 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);
>  
> +/* RKVDEC ops */
>  extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
>  extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
>  
> +/* VDPU381 ops */
>  extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_h264_fmt_ops;
>  
> +/* VDPU383 ops */
> +extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops;
> +
>  #endif /* RKVDEC_H_ */

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support
  2025-08-11 14:01       ` Krzysztof Kozlowski
@ 2025-08-11 18:44         ` Detlev Casanova
  0 siblings, 0 replies; 26+ messages in thread
From: Detlev Casanova @ 2025-08-11 18:44 UTC (permalink / raw)
  To: linux-kernel, Krzysztof Kozlowski
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

On Monday, 11 August 2025 10:01:59 EDT Krzysztof Kozlowski wrote:
> On 11/08/2025 15:54, Detlev Casanova wrote:
> > On Monday, 11 August 2025 02:13:42 EDT Krzysztof Kozlowski wrote:
> >> On 08/08/2025 22:03, Detlev Casanova wrote:
> >>> -	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
> >>> -
> >>> 
> >>>  	irq = platform_get_irq(pdev, 0);
> >>>  	if (irq <= 0)
> >>>  	
> >>>  		return -ENXIO;
> >>> 
> >>> @@ -1204,6 +1217,10 @@ static int rkvdec_probe(struct platform_device
> >>> *pdev)>
> >>> 
> >>>  		return ret;
> >>>  	
> >>>  	}
> >>> 
> >>> +	rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
> >> 
> >> Didn't you just add new ABI?
> > 
> > Oh do you mean rkvdec_rcb_buf_count() ? I could indeed use that instead
> > here.
> No, I meant DT/OF ABI for "sram".

Yes, the sram Documentation was added in commit c6ffb7e1fb90 "media: dt-
bindings: rockchip: Document RK3588 Video Decoder bindings".

Is that not how it is supposed to be used ?

Detlev.



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383
  2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
                   ` (12 preceding siblings ...)
  2025-08-11  9:56 ` [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Heiko Stübner
@ 2025-08-12  7:20 ` Piotr Oniszczuk
  13 siblings, 0 replies; 26+ messages in thread
From: Piotr Oniszczuk @ 2025-08-12  7:20 UTC (permalink / raw)
  To: Detlev Casanova
  Cc: linux-kernel, Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel



> Wiadomość napisana przez Detlev Casanova <detlev.casanova@collabora.com> w dniu 8 sie 2025, o godz. 22:03:
> 
> These variants are found respectively in the RK3588 and RK3576 SoCs.
> This patch only adds support for H264 and H265 in both variants.
> 
> As there is a considerable part of the code that can be shared with the
> already supported rkvdec decoder driver, the support for these variants
> is added here rather than writing a new driver.
> 
> This patch set uses the newly introduced hevc_ext_sps_[ls]t_rps v4l2
> controls for HEVC [1].
> Therefore, a patched version of userpace tools is needed for HEVC
> support (added for GStreamer[2] and in an early stage for FFmpeg[3]).
> 
> This patch set also depends on the preparation patch set sent earlier [4]
> as well as the iommu restore fix [5] (already merged in linux-media) and
> Nicolas Frattaroli's bitmap patch [6] to support setting registers that
> uses upper 16 bits as masks.
> 
> [1]: https://lore.kernel.org/all/20250807194327.69900-1-detlev.casanova@collabora.com/
> [2]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9355
> [3]: https://gitlab.collabora.com/detlev/ffmpeg
> [4]: https://lore.kernel.org/all/20250623160722.55938-1-detlev.casanova@collabora.com/
> [5]: https://lore.kernel.org/all/20250508-rkvdec-iommu-reset-v1-1-c46b6efa6e9b@collabora.com/
> [6]: https://lore.kernel.org/all/20250623-byeword-update-v2-1-cf1fc08a2e1f@collabora.com/
> 
> Changes since v1:
> - Add parsing of the short and long term ref frame sets from the new v4l2
>   controls
> - Add RPS cache to avoid parsing the same data again
> - Fix HEVC pixel formats selection
> - Fix multiple indentation errors
> 
> Detlev Casanova (12):
>  media: rkvdec: Switch to using structs instead of writel
>  media: rkvdec: Move cabac table to its own source file
>  media: rkvdec: Use structs to represent the HW RPS
>  media: rkvdec: Move h264 functions to common file
>  media: rkvdec: Add per variant configuration
>  media: rkvdec: Add RCB and SRAM support
>  media: rkvdec: Support per-variant interrupt handler
>  media: rkvdec: Enable all clocks without naming them
>  media: rkvdec: Add H264 support for the VDPU381 variant
>  media: rkvdec: Add H264 support for the VDPU383 variant
>  media: rkvdec: Add HEVC support for the VDPU381 variant
>  media: rkvdec: Add HEVC support for the VDPU383 variant
> 
> ..

Detlev,

I give run for this series on rk3576 and rk3588 devices (various SBC boards) on mainline 6.16 kernel.
Userspace was: KODI, MythTV and mpv.
All are using ffmpeg - but without [3] applied*.
Tested video rendering pipelines was: EGL DAMBuf and DRM direct to plane

Happy to report:
-all h264 content** i tested was decoded ok.
-on some rk3576 h264 rendering manifest known "green lines" issue***  
-hevc content**** was also decoded ok except samples requiring long sps/rps hinting from userspace (from ffmpeg in my case)


* - it looks (to me) your's ffmpeg branch changes are incompatible with yours rkvdec code (i.e. ffmpeg refers to V4L2_HEVC_EXT_SPS_RPS_FLAG_INTER_REF_PIC_SET_PRED but kernel v2 driver don't have it)

**  - i'm referring to multiple h.264 movies and TV HD channels

*** - issue of thin green lines we discussed on rockchip IRC channel

**** - as my ffmpeg7.1 has not applied newly introduced hevc_ext_sps_[ls]t_rps v4l2
controls for HEVC (due *) - some content is not decoded properly.

If any extra tests can be helpful - i'' be more that happy to do so!

br 


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 09/12] media: rkvdec: Add H264 support for the VDPU381 variant
  2025-08-08 20:03 ` [PATCH v2 09/12] media: rkvdec: Add H264 support for the VDPU381 variant Detlev Casanova
@ 2025-08-12 17:07   ` Dmitry Osipenko
  0 siblings, 0 replies; 26+ messages in thread
From: Dmitry Osipenko @ 2025-08-12 17:07 UTC (permalink / raw)
  To: Detlev Casanova, linux-kernel
  Cc: Mauro Carvalho Chehab, Heiko Stuebner, linux-media,
	linux-rockchip, linux-arm-kernel, kernel

On 8/8/25 23:03, Detlev Casanova wrote:
> +static struct rcb_size_info vdpu381_rcb_sizes[] = {
> +	{6,	PIC_WIDTH},	// intrar
> +	{1,	PIC_WIDTH},	// transdr (Is actually 0.4*pic_width)
> +	{1,	PIC_HEIGHT},	// transdc (Is actually 0.1*pic_height)
> +	{3,	PIC_WIDTH},	// streamdr
> +	{6,	PIC_WIDTH},	// interr
> +	{3,	PIC_HEIGHT},	// interc
> +	{22,	PIC_WIDTH},	// dblkr
> +	{6,	PIC_WIDTH},	// saor
> +	{11,	PIC_WIDTH},	// fbcr
> +	{67,	PIC_HEIGHT},	// filtc col
> +};
> +
> +const struct rkvdec_config config_vdpu381 = {

Nit: config_vdpu381 should be declared as "static", same for
config_vdpu383 in the next patch

-- 
Best regards,
Dmitry

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2025-08-12 17:08 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-08 20:03 [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 01/12] media: rkvdec: Switch to using structs instead of writel Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 02/12] media: rkvdec: Move cabac table to its own source file Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 03/12] media: rkvdec: Use structs to represent the HW RPS Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 04/12] media: rkvdec: Move h264 functions to common file Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 05/12] media: rkvdec: Add per variant configuration Detlev Casanova
2025-08-11  6:13   ` Krzysztof Kozlowski
2025-08-11 13:52     ` Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 06/12] media: rkvdec: Add RCB and SRAM support Detlev Casanova
2025-08-11  6:13   ` Krzysztof Kozlowski
2025-08-11 13:54     ` Detlev Casanova
2025-08-11 14:01       ` Krzysztof Kozlowski
2025-08-11 18:44         ` Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 07/12] media: rkvdec: Support per-variant interrupt handler Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 08/12] media: rkvdec: Enable all clocks without naming them Detlev Casanova
2025-08-08 20:03 ` [PATCH v2 09/12] media: rkvdec: Add H264 support for the VDPU381 variant Detlev Casanova
2025-08-12 17:07   ` Dmitry Osipenko
2025-08-08 20:03 ` [PATCH v2 10/12] media: rkvdec: Add H264 support for the VDPU383 variant Detlev Casanova
2025-08-09 11:53   ` kernel test robot
2025-08-11 18:28   ` Nicolas Dufresne
2025-08-08 20:03 ` [PATCH v2 11/12] media: rkvdec: Add HEVC support for the VDPU381 variant Detlev Casanova
2025-08-09 13:17   ` kernel test robot
2025-08-08 20:03 ` [PATCH v2 12/12] media: rkvdec: Add HEVC support for the VDPU383 variant Detlev Casanova
2025-08-11  9:56 ` [PATCH v2 00/12] media: rkvdec: Add support for VDPU381 and VDPU383 Heiko Stübner
2025-08-11 16:33   ` Detlev Casanova
2025-08-12  7:20 ` Piotr Oniszczuk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).