]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
media: verisilicon: AV1: Fix tx mode bit setting
authorBenjamin Gaignard <benjamin.gaignard@collabora.com>
Tue, 9 Dec 2025 10:34:17 +0000 (11:34 +0100)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Mon, 5 Jan 2026 14:56:31 +0000 (15:56 +0100)
AV1 specification describes 3 possibles tx modes: 4x4 only, largest and
select. The hardware allows 5 possibles tx modes: 4x4 only, 8x8, 16x16,
32x32 and select. Since the both aren't exactly matching we need to add
a mapping function to set the correct mode on hardware.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Fixes: 727a400686a2c ("media: verisilicon: Add Rockchip AV1 decoder")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c

index f4f7cb45b1f1bd44828ea2091b34e493d477224c..f52b8208e6b93b3d892914be88fbcc9a6e11d8ce 100644 (file)
                : AV1_DIV_ROUND_UP_POW2((_value_), (_n_)));             \
 })
 
+enum rockchip_av1_tx_mode {
+       ROCKCHIP_AV1_TX_MODE_ONLY_4X4   = 0,
+       ROCKCHIP_AV1_TX_MODE_8X8        = 1,
+       ROCKCHIP_AV1_TX_MODE_16x16      = 2,
+       ROCKCHIP_AV1_TX_MODE_32x32      = 3,
+       ROCKCHIP_AV1_TX_MODE_SELECT     = 4,
+};
+
 struct rockchip_av1_film_grain {
        u8 scaling_lut_y[256];
        u8 scaling_lut_cb[256];
@@ -1935,11 +1943,26 @@ static void rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx)
        rockchip_vpu981_av1_dec_set_other_frames(ctx);
 }
 
+static int rockchip_vpu981_av1_get_hardware_tx_mode(enum v4l2_av1_tx_mode tx_mode)
+{
+       switch (tx_mode) {
+       case V4L2_AV1_TX_MODE_ONLY_4X4:
+               return ROCKCHIP_AV1_TX_MODE_ONLY_4X4;
+       case V4L2_AV1_TX_MODE_LARGEST:
+               return ROCKCHIP_AV1_TX_MODE_32x32;
+       case V4L2_AV1_TX_MODE_SELECT:
+               return ROCKCHIP_AV1_TX_MODE_SELECT;
+       }
+
+       return ROCKCHIP_AV1_TX_MODE_32x32;
+}
+
 static void rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx)
 {
        struct hantro_dev *vpu = ctx->dev;
        struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
        struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+       int tx_mode;
 
        hantro_reg_write(vpu, &av1_skip_mode,
                         !!(ctrls->frame->flags & V4L2_AV1_FRAME_FLAG_SKIP_MODE_PRESENT));
@@ -2005,7 +2028,9 @@ static void rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx)
                         !!(ctrls->frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_HIGH_PRECISION_MV));
        hantro_reg_write(vpu, &av1_comp_pred_mode,
                         (ctrls->frame->flags & V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT) ? 2 : 0);
-       hantro_reg_write(vpu, &av1_transform_mode, (ctrls->frame->tx_mode == 1) ? 3 : 4);
+
+       tx_mode = rockchip_vpu981_av1_get_hardware_tx_mode(ctrls->frame->tx_mode);
+       hantro_reg_write(vpu, &av1_transform_mode, tx_mode);
        hantro_reg_write(vpu, &av1_max_cb_size,
                         (ctrls->sequence->flags
                          & V4L2_AV1_SEQUENCE_FLAG_USE_128X128_SUPERBLOCK) ? 7 : 6);