VPU cores starting with VC8000D feature a separate decoding mode named
"high10", capable of decoding both 8bit and 10bit streams, alongside the
previous (still supported) "normal / classic" h264 decoding mode.

The new kernel module param h264_high10 can be used to switch modes,
otherwise the driver will use the platform configured default.

Currently only 8bit decoding is implemented in the high10 mode.

Signed-off-by: Ezequiel Garcia <ezequ...@collabora.com>
Signed-off-by: Adrian Ratiu <adrian.ra...@collabora.com>
---
 drivers/staging/media/hantro/hantro.h         |   7 +
 drivers/staging/media/hantro/hantro_drv.c     |  10 ++
 .../staging/media/hantro/hantro_g1_h264_dec.c | 142 ++++++++++++++----
 drivers/staging/media/hantro/hantro_hw.h      |  21 ++-
 .../staging/media/hantro/hantro_postproc.c    |   3 +-
 drivers/staging/media/hantro/hantro_regmap.c  |  36 +++++
 drivers/staging/media/hantro/hantro_regmap.h  |  17 +++
 drivers/staging/media/hantro/hantro_v4l2.c    |   3 +-
 8 files changed, 203 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro.h 
b/drivers/staging/media/hantro/hantro.h
index 05e59bc83b71..70aeb11b1149 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -71,6 +71,7 @@ struct hantro_irq {
  * @num_clocks:                        number of clocks in the array
  * @reg_names:                 array of register range names
  * @num_regs:                  number of register range names in the array
+ * @has_h264_high10:           platform has support for high10 decoding mode
  */
 struct hantro_variant {
        unsigned int enc_offset;
@@ -91,6 +92,8 @@ struct hantro_variant {
        int num_clocks;
        const char * const *reg_names;
        int num_regs;
+
+       bool has_h264_high10;
 };
 
 /**
@@ -177,6 +180,8 @@ hantro_vdev_to_func(struct video_device *vdev)
  *                     shared with interrupt handlers.
  * @variant:           Hardware variant-specific parameters.
  * @watchdog_work:     Delayed work for hardware timeout handling.
+ *
+ * @h264_hw_mode:      H264 mode: legacy, high10 supported.
  */
 struct hantro_dev {
        struct v4l2_device v4l2_dev;
@@ -200,6 +205,8 @@ struct hantro_dev {
        spinlock_t irqlock;
        const struct hantro_variant *variant;
        struct delayed_work watchdog_work;
+
+       enum hantro_h264_hw_mode h264_hw_mode;
 };
 
 /**
diff --git a/drivers/staging/media/hantro/hantro_drv.c 
b/drivers/staging/media/hantro/hantro_drv.c
index e225515d6985..afb4e201fa42 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -32,6 +32,10 @@
 
 #define DRIVER_NAME "hantro-vpu"
 
+static bool hantro_h264_high10 = true;
+module_param_named(h264_high10, hantro_h264_high10, bool, 0444);
+MODULE_PARM_DESC(h264_high10, "Enable High10 decoding mode");
+
 int hantro_debug;
 module_param_named(debug, hantro_debug, int, 0644);
 MODULE_PARM_DESC(debug,
@@ -824,6 +828,12 @@ static int hantro_probe(struct platform_device *pdev)
                goto err_clk_unprepare;
        }
 
+       /* Small quirk: check if H264 High10 mode can be used */
+       if (hantro_h264_high10 && vpu->variant->has_h264_high10)
+               vpu->h264_hw_mode = HANTRO_H264_HIGH10;
+       else
+               vpu->h264_hw_mode = HANTRO_H264_LEGACY;
+
        pm_runtime_set_autosuspend_delay(vpu->dev, 100);
        pm_runtime_use_autosuspend(vpu->dev);
        pm_runtime_enable(vpu->dev);
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c 
b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
index a04cb616d628..e64b59c84111 100644
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
@@ -2,6 +2,8 @@
 /*
  * Rockchip RK3288 VPU codec driver
  *
+ * Copyright (c) 2020 Collabora, Ltd.
+ *
  * Copyright (c) 2014 Rockchip Electronics Co., Ltd.
  *     Hertz Wong <hertz.w...@rock-chips.com>
  *     Herman Chen <herman.c...@rock-chips.com>
@@ -10,6 +12,7 @@
  *     Tomasz Figa <tf...@chromium.org>
  */
 
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/sort.h>
 
@@ -20,6 +23,8 @@
 #include "hantro_v4l2.h"
 #include "hantro_regmap.h"
 
+/* TODO: remove this harcoded pixel size when adding 10bit streams */
+#define VC8KD_PIXEL_SIZE 8
 #define VC8KD_TIMEOUT 0x500000
 
 extern struct regmap_config hantro_regmap_dec;
@@ -30,7 +35,6 @@ static void set_params(struct hantro_ctx *ctx)
        const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode;
        const struct v4l2_ctrl_h264_sps *sps = ctrls->sps;
        const struct v4l2_ctrl_h264_pps *pps = ctrls->pps;
-       struct vb2_v4l2_buffer *src_buf = hantro_get_src_buf(ctx);
        struct hantro_dev *vpu = ctx->dev;
        struct hantro_regmap_fields_dec *fields = vpu->reg_fields_dec;
        u32 width = MB_WIDTH(ctx->src_fmt.width);
@@ -40,8 +44,26 @@ static void set_params(struct hantro_ctx *ctx)
        regmap_field_write(fields->dec_axi_wr_id, 0x0);
 
        if (vpu->core_hw_dec_rev == HANTRO_VC8000_REV) {
-               /* stride should be computed in hantro_try_fmt() and set here */
-               stride = width * 4 * 16;
+               /*
+                * TODO: For now we only support 8bit pixel depth even in high10
+                * decoding mode, so this is why PIXEL_SIZE is always defined 8
+                */
+               regmap_field_write(fields->dec_bit_depth_c_minus8,
+                                  VC8KD_PIXEL_SIZE - 8);
+               regmap_field_write(fields->dec_bit_depth_y_minus8,
+                                  VC8KD_PIXEL_SIZE - 8);
+
+               regmap_field_write(fields->dec_pic_height_4x4,
+                                  ctx->src_fmt.height / 4);
+               regmap_field_write(fields->dec_pic_width_4x4,
+                                  ctx->src_fmt.width / 4);
+
+               /*
+                * This depends on tiled_stride_enable.
+                * It's a weird math, we still don't know
+                * what's the rationale.
+                */
+               stride = width * MB_DIM * 4;
                regmap_field_write(fields->dec_out_y_stride, stride);
                regmap_field_write(fields->dec_out_c_stride, stride);
 
@@ -93,8 +115,6 @@ static void set_params(struct hantro_ctx *ctx)
        regmap_field_write(fields->dec_start_code_e, 1);
        regmap_field_write(fields->dec_init_qp,
                           pps->pic_init_qp_minus26 + 26);
-       regmap_field_write(fields->dec_stream_len,
-                          vb2_get_plane_payload(&src_buf->vb2_buf, 0));
 
        /* Decoder control register 4. */
        reg = G1_REG_DEC_CTRL4_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) 
|
@@ -111,8 +131,7 @@ static void set_params(struct hantro_ctx *ctx)
        vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL4);
 
        /* Decoder control register 5. */
-       reg = 
G1_REG_DEC_CTRL5_REFPIC_MK_LEN(dec_param->dec_ref_pic_marking_bit_size) |
-             G1_REG_DEC_CTRL5_IDR_PIC_ID(dec_param->idr_pic_id);
+       reg = 
G1_REG_DEC_CTRL5_REFPIC_MK_LEN(dec_param->dec_ref_pic_marking_bit_size);
        if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
                reg |= G1_REG_DEC_CTRL5_CONST_INTRA_E;
        if (pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT)
@@ -125,6 +144,8 @@ static void set_params(struct hantro_ctx *ctx)
                reg |= G1_REG_DEC_CTRL5_IDR_PIC_E;
        vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL5);
 
+       regmap_field_write(fields->dec_idr_pic_id_h10, dec_param->idr_pic_id);
+
        /* Decoder control register 6. */
        reg = G1_REG_DEC_CTRL6_PPS_ID(pps->pic_parameter_set_id) |
              
G1_REG_DEC_CTRL6_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) |
@@ -149,11 +170,46 @@ static void set_params(struct hantro_ctx *ctx)
        regmap_field_write(fields->dec_apf_threshold, 8);
 }
 
+static size_t get_mv_offset(struct hantro_ctx *ctx)
+{
+       const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
+       u32 bytes_per_mb = 384;
+       size_t mv_offset = 0;
+
+       /* DMV buffer for monochrome start directly after Y-plane */
+       if (ctrls->sps->profile_idc >= 100 &&
+           ctrls->sps->chroma_format_idc == 0)
+               bytes_per_mb = 256;
+
+       mv_offset = bytes_per_mb * MB_WIDTH(ctx->src_fmt.width) *
+               MB_HEIGHT(ctx->src_fmt.height) * (VC8KD_PIXEL_SIZE / 8);
+
+       /*
+        * Allocate 32 bytes for multicore status fields
+        * locate it after picture and before direct MV.
+        * TODO: This should be constrained to multicore?
+        */
+       mv_offset += 32;
+
+       /*
+        * DMV buffer is split in two for field encoded frames,
+        * adjust offset for bottom field
+        */
+       if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)
+               mv_offset += 32 * MB_WIDTH(ctx->src_fmt.width) *
+                       MB_HEIGHT(ctx->src_fmt.height);
+
+       return mv_offset;
+}
+
 static void set_ref(struct hantro_ctx *ctx)
 {
        struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
        const u8 *b0_reflist, *b1_reflist, *p_reflist;
        struct hantro_dev *vpu = ctx->dev;
+       const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
+       struct hantro_regmap_fields_dec *fields = vpu->reg_fields_dec;
+       bool do_high10 = (vpu->h264_hw_mode == HANTRO_H264_HIGH10);
        u32 dpb_longterm = 0;
        u32 dpb_valid = 0;
        int reg_num;
@@ -200,7 +256,7 @@ static void set_ref(struct hantro_ctx *ctx)
        p_reflist = ctx->h264_dec.reflists.p;
 
        /*
-        * Each G1_REG_BD_REF_PIC(x) register contains three entries
+        * Each REG_BD_REF_PIC(x) register contains three entries
         * of each forward and backward picture list.
         */
        reg_num = 0;
@@ -211,7 +267,7 @@ static void set_ref(struct hantro_ctx *ctx)
                      G1_REG_BD_REF_PIC_BINIT_RLIST_B0(b1_reflist[i]) |
                      G1_REG_BD_REF_PIC_BINIT_RLIST_B1(b1_reflist[i + 1]) |
                      G1_REG_BD_REF_PIC_BINIT_RLIST_B2(b1_reflist[i + 2]);
-               vdpu_write_relaxed(vpu, reg, G1_REG_BD_REF_PIC(reg_num++));
+               vdpu_write_relaxed(vpu, reg, REG_BD_REF_PIC(reg_num++));
        }
 
        /*
@@ -219,14 +275,19 @@ static void set_ref(struct hantro_ctx *ctx)
         * of forward and backward reference picture lists and first 4 entries
         * of P forward picture list.
         */
-       reg = G1_REG_BD_P_REF_PIC_BINIT_RLIST_F15(b0_reflist[15]) |
-             G1_REG_BD_P_REF_PIC_BINIT_RLIST_B15(b1_reflist[15]) |
-             G1_REG_BD_P_REF_PIC_PINIT_RLIST_F0(p_reflist[0]) |
+       reg = G1_REG_BD_P_REF_PIC_PINIT_RLIST_F0(p_reflist[0]) |
              G1_REG_BD_P_REF_PIC_PINIT_RLIST_F1(p_reflist[1]) |
              G1_REG_BD_P_REF_PIC_PINIT_RLIST_F2(p_reflist[2]) |
              G1_REG_BD_P_REF_PIC_PINIT_RLIST_F3(p_reflist[3]);
        vdpu_write_relaxed(vpu, reg, G1_REG_BD_P_REF_PIC);
 
+       /*
+        * The last fw/bw refpic lists (index 15) have actually moved register
+        * locations between decoder revisions, so set them using regmap fields
+        */
+       regmap_field_write(fields->dec_init_rlist_f15, b0_reflist[15]);
+       regmap_field_write(fields->dec_init_rlist_b15, b1_reflist[15]);
+
        /*
         * Each G1_REG_FWD_PIC(x) register contains six consecutive
         * entries of P forward picture list, starting from index 4.
@@ -246,6 +307,22 @@ static void set_ref(struct hantro_ctx *ctx)
        for (i = 0; i < HANTRO_H264_DPB_SIZE; i++) {
                dma_addr_t dma_addr = hantro_h264_get_ref_buf(ctx, i);
                vdpu_write_relaxed(vpu, dma_addr, REG_ADDR_REF(i));
+
+               if (vpu->core_hw_dec_rev == HANTRO_VC8000_REV) {
+                       if (ctrls->sps->profile_idc > 66) {
+                               size_t mv_offset = get_mv_offset(ctx);
+
+                               vdpu_write_relaxed(vpu, dma_addr + mv_offset,
+                                                  REG_DMV_REF(i));
+                       }
+
+                       if (do_high10) {
+                               size_t chroma_offset = ctx->src_fmt.width *
+                                       ctx->src_fmt.height;
+                               vdpu_write_relaxed(vpu, dma_addr + 
chroma_offset,
+                                                  REG_CHR_REF(i));
+                       }
+               }
        }
 }
 
@@ -255,15 +332,26 @@ static void set_buffers(struct hantro_ctx *ctx)
        struct vb2_v4l2_buffer *src_buf, *dst_buf;
        struct hantro_dev *vpu = ctx->dev;
        struct hantro_regmap_fields_dec *fields = vpu->reg_fields_dec;
+       bool do_high10 = (vpu->h264_hw_mode == HANTRO_H264_HIGH10);
        dma_addr_t src_dma, dst_dma;
        size_t offset = 0;
+       u32 src_len, src_buf_len;
 
        src_buf = hantro_get_src_buf(ctx);
        dst_buf = hantro_get_dst_buf(ctx);
 
        /* Source (stream) buffer. */
        src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+       src_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+
        regmap_field_write(fields->dec_addr_str, src_dma);
+       regmap_field_write(fields->dec_stream_len, src_len);
+
+       if (do_high10) {
+               src_buf_len = vb2_plane_size(&src_buf->vb2_buf, 0);
+               regmap_field_write(fields->dec_strm_buffer_len, src_buf_len);
+               regmap_field_write(fields->dec_strm_start_offset, 0);
+       }
 
        /* Destination (decoded frame) buffer. */
        dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf);
@@ -272,27 +360,18 @@ static void set_buffers(struct hantro_ctx *ctx)
                offset = ALIGN(ctx->src_fmt.width, MB_DIM);
        regmap_field_write(fields->dec_addr_dst, dst_dma + offset);
 
-       /* Higher profiles require DMV buffer appended to reference frames. */
-       if (ctrls->sps->profile_idc > 66 && ctrls->decode->nal_ref_idc) {
-               unsigned int bytes_per_mb = 384;
-
-               /* DMV buffer for monochrome start directly after Y-plane */
-               if (ctrls->sps->profile_idc >= 100 &&
-                   ctrls->sps->chroma_format_idc == 0)
-                       bytes_per_mb = 256;
-               offset = bytes_per_mb * MB_WIDTH(ctx->src_fmt.width) *
-                        MB_HEIGHT(ctx->src_fmt.height);
+       if (do_high10) {
+               size_t chroma_offset = ctx->src_fmt.width * ctx->src_fmt.height;
 
-               /*
-                * DMV buffer is split in two for field encoded frames,
-                * adjust offset for bottom field
-                */
-               if (ctrls->decode->flags & 
V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)
-                       offset += 32 * MB_WIDTH(ctx->src_fmt.width) *
-                                 MB_HEIGHT(ctx->src_fmt.height);
-               regmap_field_write(fields->dec_addr_dir_mv, dst_dma + offset);
+               regmap_field_write(fields->dec_addr_dst_chr,
+                                  dst_dma + chroma_offset);
        }
 
+       /* Higher profiles require DMV buffer appended to reference frames. */
+       if (ctrls->sps->profile_idc > 66 && ctrls->decode->nal_ref_idc)
+               regmap_field_write(fields->dec_addr_dir_mv,
+                                  dst_dma + get_mv_offset(ctx));
+
        /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */
        regmap_field_write(fields->dec_addr_qtable, ctx->h264_dec.priv.dma);
 }
@@ -301,6 +380,7 @@ void hantro_g1_h264_dec_run(struct hantro_ctx *ctx)
 {
        struct hantro_dev *vpu = ctx->dev;
        struct hantro_regmap_fields_dec *fields = vpu->reg_fields_dec;
+       bool do_high10 = (vpu->h264_hw_mode == HANTRO_H264_HIGH10);
        int reg;
 
        /* Prepare the H264 decoder context. */
@@ -332,6 +412,8 @@ void hantro_g1_h264_dec_run(struct hantro_ctx *ctx)
                regmap_field_write(fields->dec_buswidth, 2);
                regmap_field_write(fields->dec_tab_swap, 3);
                regmap_field_write(fields->dec_tiled_mode_lsb, 1);
+               regmap_field_write(fields->dec_ref_compress_bypass, 1);
+               regmap_field_write(fields->dec_mode, do_high10 ? 0xf : 0x0);
                break;
        }
 
diff --git a/drivers/staging/media/hantro/hantro_hw.h 
b/drivers/staging/media/hantro/hantro_hw.h
index e0039a15fe85..7a79d6c8e4e1 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -49,6 +49,11 @@ struct hantro_jpeg_enc_hw_ctx {
        struct hantro_aux_buf bounce_buffer;
 };
 
+enum hantro_h264_hw_mode {
+       HANTRO_H264_LEGACY,
+       HANTRO_H264_HIGH10,
+};
+
 /* Max. number of entries in the DPB (HW limitation). */
 #define HANTRO_H264_DPB_SIZE           16
 
@@ -178,8 +183,11 @@ int hantro_h264_dec_init(struct hantro_ctx *ctx);
 void hantro_h264_dec_exit(struct hantro_ctx *ctx);
 
 static inline size_t
-hantro_h264_mv_size(unsigned int width, unsigned int height)
+hantro_h264_mv_size(unsigned int width, unsigned int height,
+                   enum hantro_h264_hw_mode hw_mode)
 {
+       unsigned int mv_bytes_per_mb;
+
        /*
         * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to
         * 448 bytes per macroblock with additional 32 bytes on
@@ -196,12 +204,17 @@ hantro_h264_mv_size(unsigned int width, unsigned int 
height)
         * +---------------------------+
         * | UV-plane  128 bytes x MBs |
         * +---------------------------+
-        * | MV buffer  64 bytes x MBs |
-        * +---------------------------+
         * | MC sync          32 bytes |
         * +---------------------------+
+        * | MV buffer  64 bytes x MBs |
+        * +---------------------------+
         */
-       return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32;
+       if (hw_mode == HANTRO_H264_LEGACY)
+               mv_bytes_per_mb = 64;
+       else
+               mv_bytes_per_mb = 80;
+
+       return mv_bytes_per_mb * MB_WIDTH(width) * MB_WIDTH(height) + 32;
 }
 
 void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
diff --git a/drivers/staging/media/hantro/hantro_postproc.c 
b/drivers/staging/media/hantro/hantro_postproc.c
index 653bae37eed9..893f226ec301 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/staging/media/hantro/hantro_postproc.c
@@ -156,7 +156,8 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
 
        buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage +
                   hantro_h264_mv_size(ctx->dst_fmt.width,
-                                      ctx->dst_fmt.height);
+                                      ctx->dst_fmt.height,
+                                      vpu->h264_hw_mode);
 
        for (i = 0; i < num_buffers; ++i) {
                struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i];
diff --git a/drivers/staging/media/hantro/hantro_regmap.c 
b/drivers/staging/media/hantro/hantro_regmap.c
index b87fe809f2f7..62280b873859 100644
--- a/drivers/staging/media/hantro/hantro_regmap.c
+++ b/drivers/staging/media/hantro/hantro_regmap.c
@@ -42,6 +42,7 @@ struct hantro_field_dec {
        struct reg_field cfg_dec_dirmv_swap;
        struct reg_field cfg_dec_mode;
        struct reg_field cfg_dec_buffer_empty_int_e;
+       struct reg_field cfg_dec_ref_compress_bypass;
        struct reg_field cfg_dec_max_burst;
        struct reg_field cfg_dec_buswidth;
        struct reg_field cfg_dec_apf_threshold;
@@ -54,6 +55,7 @@ struct hantro_field_dec {
        struct reg_field cfg_dec_scaling_list_e;
        struct reg_field cfg_dec_addr_str;
        struct reg_field cfg_dec_addr_dst;
+       struct reg_field cfg_dec_addr_dst_chr;
        struct reg_field cfg_dec_ilace_mode;
        struct reg_field cfg_dec_addr_qtable;
        struct reg_field cfg_dec_max_cb_size;
@@ -61,6 +63,7 @@ struct hantro_field_dec {
        struct reg_field cfg_dec_out_y_stride;
        struct reg_field cfg_dec_out_c_stride;
        struct reg_field cfg_dec_addr_dir_mv;
+       struct reg_field cfg_dec_idr_pic_id_h10;
        struct reg_field cfg_dec_tiled_mode_lsb;
        struct reg_field cfg_dec_clk_gate_e;
        struct reg_field cfg_dec_tab_swap;
@@ -68,6 +71,14 @@ struct hantro_field_dec {
        struct reg_field cfg_dec_ext_timeout_e;
        struct reg_field cfg_dec_timeout_cycles;
        struct reg_field cfg_dec_timeout_e;
+       struct reg_field cfg_dec_strm_start_offset;
+       struct reg_field cfg_dec_strm_buffer_len;
+       struct reg_field cfg_dec_bit_depth_y_minus8;
+       struct reg_field cfg_dec_bit_depth_c_minus8;
+       struct reg_field cfg_dec_init_rlist_b15;
+       struct reg_field cfg_dec_init_rlist_f15;
+       struct reg_field cfg_dec_pic_height_4x4;
+       struct reg_field cfg_dec_pic_width_4x4;
 
        struct reg_field cfg_pp_pipeline_en;
        struct reg_field cfg_pp_max_burst;
@@ -128,6 +139,9 @@ static const struct hantro_field_dec g1_field = {
        .cfg_dec_ilace_mode =           REG_FIELD(SWREG(13), 1, 1),
        .cfg_dec_addr_qtable =          REG_FIELD(SWREG(40), 0, 31),
        .cfg_dec_addr_dir_mv =          REG_FIELD(SWREG(41), 0, 31),
+       .cfg_dec_idr_pic_id_h10 =       REG_FIELD(SWREG(8), 0, 15),
+       .cfg_dec_init_rlist_f15 =       REG_FIELD(SWREG(47), 0, 4),
+       .cfg_dec_init_rlist_b15 =       REG_FIELD(SWREG(47), 5, 9),
        .cfg_pp_pipeline_en =           REG_FIELD(SWREG(60), 1, 1),
        .cfg_pp_max_burst =             REG_FIELD(SWREG(61), 0, 4),
        .cfg_pp_out_swap32 =            REG_FIELD(SWREG(61), 5, 5),
@@ -166,6 +180,7 @@ static const struct hantro_field_dec vc8000d_field = {
        .cfg_dec_dirmv_swap =           REG_FIELD(SWREG(2), 20, 23),
        .cfg_dec_mode =                 REG_FIELD(SWREG(3), 27, 31),
        .cfg_dec_buffer_empty_int_e =   REG_FIELD(SWREG(3), 2, 2),
+       .cfg_dec_ref_compress_bypass =  REG_FIELD(SWREG(3), 8, 8),
        .cfg_dec_max_burst =            REG_FIELD(SWREG(58), 0, 7),
        .cfg_dec_buswidth =             REG_FIELD(SWREG(58), 8, 10),
        .cfg_dec_apf_threshold =        REG_FIELD(SWREG(55), 0, 15),
@@ -178,9 +193,11 @@ static const struct hantro_field_dec vc8000d_field = {
        .cfg_dec_scaling_list_e =       REG_FIELD(SWREG(5), 24, 24),
        .cfg_dec_addr_str =             REG_FIELD(SWREG(169), 0, 31),
        .cfg_dec_addr_dst =             REG_FIELD(SWREG(65), 0, 31),
+       .cfg_dec_addr_dst_chr =         REG_FIELD(SWREG(99), 0, 31),
        .cfg_dec_ilace_mode =           REG_FIELD(SWREG(65), 1, 1),
        .cfg_dec_addr_qtable =          REG_FIELD(SWREG(175), 0, 31),
        .cfg_dec_addr_dir_mv =          REG_FIELD(SWREG(133), 0, 31),
+       .cfg_dec_idr_pic_id_h10 =       REG_FIELD(SWREG(12), 16, 31),
        .cfg_dec_max_cb_size =          REG_FIELD(SWREG(12), 10, 12),
        .cfg_dec_min_cb_size =          REG_FIELD(SWREG(12), 13, 15),
        .cfg_dec_out_y_stride =         REG_FIELD(SWREG(314), 16, 31),
@@ -189,6 +206,14 @@ static const struct hantro_field_dec vc8000d_field = {
        .cfg_dec_ext_timeout_e =        REG_FIELD(SWREG(318), 31, 31),
        .cfg_dec_timeout_cycles =       REG_FIELD(SWREG(319), 0, 30),
        .cfg_dec_timeout_e =            REG_FIELD(SWREG(319), 31, 31),
+       .cfg_dec_strm_buffer_len =      REG_FIELD(SWREG(258), 0, 31),
+       .cfg_dec_strm_start_offset =    REG_FIELD(SWREG(259), 0, 31),
+       .cfg_dec_bit_depth_y_minus8 =   REG_FIELD(SWREG(8), 6, 7),
+       .cfg_dec_bit_depth_c_minus8 =   REG_FIELD(SWREG(8), 4, 5),
+       .cfg_dec_init_rlist_f15 =       REG_FIELD(SWREG(19), 0, 4),
+       .cfg_dec_init_rlist_b15 =       REG_FIELD(SWREG(19), 5, 9),
+       .cfg_dec_pic_height_4x4 =       REG_FIELD(SWREG(20), 0, 11),
+       .cfg_dec_pic_width_4x4 =        REG_FIELD(SWREG(20), 16, 27),
        .cfg_pp_pipeline_en =           REG_FIELD(SWREG(320), 0, 0),
        .cfg_pp_out_tile_e =            REG_FIELD(SWREG(320), 3, 3),
        .cfg_pp_output_fmt =            REG_FIELD(SWREG(322), 18, 22),
@@ -245,6 +270,7 @@ static int hantro_regmap_fields_init_dec(struct hantro_dev 
*vpu,
        INIT_DEC_FIELD(dec_dirmv_swap);
        INIT_DEC_FIELD(dec_mode);
        INIT_DEC_FIELD(dec_buffer_empty_int_e);
+       INIT_DEC_FIELD(dec_ref_compress_bypass);
        INIT_DEC_FIELD(dec_max_burst);
        INIT_DEC_FIELD(dec_buswidth);
        INIT_DEC_FIELD(dec_apf_threshold);
@@ -257,6 +283,7 @@ static int hantro_regmap_fields_init_dec(struct hantro_dev 
*vpu,
        INIT_DEC_FIELD(dec_scaling_list_e);
        INIT_DEC_FIELD(dec_addr_str);
        INIT_DEC_FIELD(dec_addr_dst);
+       INIT_DEC_FIELD(dec_addr_dst_chr);
        INIT_DEC_FIELD(dec_ilace_mode);
        INIT_DEC_FIELD(dec_addr_qtable);
        INIT_DEC_FIELD(dec_max_cb_size);
@@ -264,6 +291,7 @@ static int hantro_regmap_fields_init_dec(struct hantro_dev 
*vpu,
        INIT_DEC_FIELD(dec_out_y_stride);
        INIT_DEC_FIELD(dec_out_c_stride);
        INIT_DEC_FIELD(dec_addr_dir_mv);
+       INIT_DEC_FIELD(dec_idr_pic_id_h10);
        INIT_DEC_FIELD(dec_tiled_mode_lsb);
        INIT_DEC_FIELD(dec_clk_gate_e);
        INIT_DEC_FIELD(dec_tab_swap);
@@ -271,6 +299,14 @@ static int hantro_regmap_fields_init_dec(struct hantro_dev 
*vpu,
        INIT_DEC_FIELD(dec_ext_timeout_e);
        INIT_DEC_FIELD(dec_timeout_cycles);
        INIT_DEC_FIELD(dec_timeout_e);
+       INIT_DEC_FIELD(dec_strm_buffer_len);
+       INIT_DEC_FIELD(dec_strm_start_offset);
+       INIT_DEC_FIELD(dec_bit_depth_c_minus8);
+       INIT_DEC_FIELD(dec_bit_depth_y_minus8);
+       INIT_DEC_FIELD(dec_init_rlist_b15);
+       INIT_DEC_FIELD(dec_init_rlist_f15);
+       INIT_DEC_FIELD(dec_pic_height_4x4);
+       INIT_DEC_FIELD(dec_pic_width_4x4);
 
        /* Post-processor */
        INIT_DEC_FIELD(pp_pipeline_en);
diff --git a/drivers/staging/media/hantro/hantro_regmap.h 
b/drivers/staging/media/hantro/hantro_regmap.h
index 0a39bae83f85..083c4e92c4bd 100644
--- a/drivers/staging/media/hantro/hantro_regmap.h
+++ b/drivers/staging/media/hantro/hantro_regmap.h
@@ -17,9 +17,15 @@
 #define SWREG_ITER_G1(n, i)    (SWREG(n) + ((i) << 2))
 #define SWREG_ITER_VC8000(n, i)        (SWREG(n) + ((i) << 3))
 
+#define REG_CHR_REF(i)         (SWREG_ITER_VC8000(101, i))
+#define REG_DMV_REF(i)         (SWREG_ITER_VC8000(135, i))
+
 #define REG_ADDR_REF(i)                (vpu->core_hw_dec_rev == HANTRO_G1_REV 
? \
                                 SWREG_ITER_G1(14, i) : \
                                 SWREG_ITER_VC8000(67, i))
+#define REG_BD_REF_PIC(i)      (vpu->core_hw_dec_rev == HANTRO_G1_REV ? \
+                                SWREG_ITER_G1(42, i) : \
+                                SWREG_ITER_VC8000(14, i))
 
 struct hantro_regmap_fields_dec {
        /* Decoder */
@@ -32,6 +38,7 @@ struct hantro_regmap_fields_dec {
        struct regmap_field *dec_dirmv_swap;
        struct regmap_field *dec_mode;
        struct regmap_field *dec_buffer_empty_int_e;
+       struct regmap_field *dec_ref_compress_bypass;
        struct regmap_field *dec_buswidth;
        struct regmap_field *dec_apf_threshold;
        struct regmap_field *dec_stream_len;
@@ -43,6 +50,7 @@ struct hantro_regmap_fields_dec {
        struct regmap_field *dec_scaling_list_e;
        struct regmap_field *dec_addr_str;
        struct regmap_field *dec_addr_dst;
+       struct regmap_field *dec_addr_dst_chr;
        struct regmap_field *dec_ilace_mode;
        struct regmap_field *dec_addr_qtable;
        struct regmap_field *dec_max_cb_size;
@@ -50,6 +58,7 @@ struct hantro_regmap_fields_dec {
        struct regmap_field *dec_out_y_stride;
        struct regmap_field *dec_out_c_stride;
        struct regmap_field *dec_addr_dir_mv;
+       struct regmap_field *dec_idr_pic_id_h10;
        struct regmap_field *dec_tiled_mode_lsb;
        struct regmap_field *dec_clk_gate_e;
        struct regmap_field *dec_tab_swap;
@@ -57,6 +66,14 @@ struct hantro_regmap_fields_dec {
        struct regmap_field *dec_ext_timeout_e;
        struct regmap_field *dec_timeout_cycles;
        struct regmap_field *dec_timeout_e;
+       struct regmap_field *dec_strm_buffer_len;
+       struct regmap_field *dec_strm_start_offset;
+       struct regmap_field *dec_bit_depth_y_minus8;
+       struct regmap_field *dec_bit_depth_c_minus8;
+       struct regmap_field *dec_init_rlist_b15;
+       struct regmap_field *dec_init_rlist_f15;
+       struct regmap_field *dec_pic_height_4x4;
+       struct regmap_field *dec_pic_width_4x4;
 
        /* Post-processor */
        struct regmap_field *pp_pipeline_en;
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c 
b/drivers/staging/media/hantro/hantro_v4l2.c
index b668a82d40ad..dc811e256181 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
@@ -282,7 +282,8 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
                    !hantro_needs_postproc(ctx, fmt))
                        pix_mp->plane_fmt[0].sizeimage +=
                                hantro_h264_mv_size(pix_mp->width,
-                                                   pix_mp->height);
+                                                   pix_mp->height,
+                                                   ctx->dev->h264_hw_mode);
        } else if (!pix_mp->plane_fmt[0].sizeimage) {
                /*
                 * For coded formats the application can specify
-- 
2.28.0

Reply via email to