From nobody Sat Feb 7 07:24:44 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E26327BF7C; Wed, 22 Oct 2025 16:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761150354; cv=none; b=cZex2IK7AMjYn0UfN08+jnFVwzHKS5aDQIDzBnFLw2PTH4ulItWv8TthnY6+D+mOUtyf10v1kf7KTnlPHIx+m/ukpl3Gh0M5fvh9r5wVjHSqbAo1b9pCD0n776/x5Lz8NuhvdTdsj3IQG6vav0hB+aZtx4BWvQvB7O+x0ZMrrbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761150354; c=relaxed/simple; bh=p6jGiM+GGEp9U5AHK1oND8hRojGmvlhceK8h3kX7S50=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BaMmaZeEa0ZgHYAQRL3TJGYJF4DBqhT6MkD1MWpCQGm3bxI8xpfZp/I0h3g91MAkIp6czWCjWTtWZcPBgQJnI06ovjRadHHtd2GocRaAx+ueEUaHk2abrkrF9O7X1CXPrq+tLbe+KsrV/xnkmoieNWhRxoKSTQ1Af7+1BWmdJGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=YUQ09nmf; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="YUQ09nmf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1761150349; bh=p6jGiM+GGEp9U5AHK1oND8hRojGmvlhceK8h3kX7S50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YUQ09nmfUGoMO5u/UbI2mAYfSIQSeDuGTiaVbxLN1GdoaQEAgMkIHlILkzP8FFAM+ 4dYR3H15OGr8yUihUylFINBRcCB6BE/odL28w+CF84Odj806P0S0eC9ssul42KcEpb zoN5G2vMqWnwu5KGGTWC8wLIPX+rywlUGnOf+hW7WtHg0lsVgxNeMASQuDxiidmAw0 PIJywpaXxmjZcOwAvZi+jgn2eqc1+eY7v436uDmepuLEUmV9n9zQiE4MNC/9soAIjD EM0nPyH/henkQeID/03o0VBEhWBvdQwvEFRZLyTz6U86mepuCrEhS/NLEQxDr2xf69 EGO6o3HUF/RVg== Received: from trenzalore (unknown [23.233.251.139]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: detlev) by bali.collaboradmins.com (Postfix) with ESMTPSA id 598B717E1413; Wed, 22 Oct 2025 18:25:47 +0200 (CEST) From: Detlev Casanova To: linux-kernel@vger.kernel.org Cc: Mauro Carvalho Chehab , Detlev Casanova , Ezequiel Garcia , Heiko Stuebner , Ricardo Ribalda , Hans Verkuil , Hans de Goede , Yunke Cao , Jonathan Corbet , Laurent Pinchart , Sakari Ailus , James Cowgill , linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@collabora.com, Nicolas Dufresne , Diederik de Haas Subject: [PATCH v3 07/15] media: rkvdec: Move hevc functions to common file Date: Wed, 22 Oct 2025 12:22:06 -0400 Message-ID: <20251022162459.271603-8-detlev.casanova@collabora.com> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251022162459.271603-1-detlev.casanova@collabora.com> References: <20251022162459.271603-1-detlev.casanova@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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). Tested-by: Diederik de Haas # Rock 5B Signed-off-by: Detlev Casanova --- .../media/platform/rockchip/rkvdec/Makefile | 1 + .../rockchip/rkvdec/rkvdec-hevc-common.c | 233 +++++++++++++++++ .../rockchip/rkvdec/rkvdec-hevc-common.h | 51 ++++ .../platform/rockchip/rkvdec/rkvdec-hevc.c | 243 +----------------- 4 files changed, 291 insertions(+), 237 deletions(-) create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-comm= on.c create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-comm= on.h diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/medi= a/platform/rockchip/rkvdec/Makefile index d2ba7a7c15e5..1b4bc44be23e 100644 --- a/drivers/media/platform/rockchip/rkvdec/Makefile +++ b/drivers/media/platform/rockchip/rkvdec/Makefile @@ -6,4 +6,5 @@ rockchip-vdec-y +=3D \ rkvdec-h264.o \ rkvdec-h264-common.o \ rkvdec-hevc.o \ + rkvdec-hevc-common.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 new file mode 100644 index 000000000000..d571107f2242 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip video decoder hevc common functions + * + * Copyright (C) 2025 Collabora, Ltd. + * Detlev Casanova + * + * Copyright (C) 2023 Collabora, Ltd. + * Sebastian Fricke + * + * Copyright (C) 2019 Collabora, Ltd. + * Boris Brezillon + * + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Jeffy Chen + */ + +#include +#include + +#include "rkvdec.h" +#include "rkvdec-hevc-common.h" + +/* + * Flip one or more matrices along their main diagonal and flatten them + * before writing it to the memory. + * Convert: + * ABCD AEIM + * EFGH =3D> BFJN =3D> 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 =3D row_length * row_length; + for (i =3D 0; i < matrices; i++) { + row =3D 0; + x_offset =3D 0; + matrix_offset =3D i * matrix_size; + for (j =3D 0; j < matrix_size; j++) { + y_offset =3D j - (row * row_length); + rot_index =3D y_offset * row_length + x_offset; + new_value =3D *(input + i * matrix_size + j); + output[matrix_offset + rot_index] =3D new_value; + if ((j + 1) % row_length =3D=3D 0) { + row +=3D 1; + x_offset +=3D 1; + } + } + } +} + +static void assemble_scalingfactor0(u8 *output, const struct v4l2_ctrl_hev= c_scaling_matrix *input) +{ + int offset =3D 0; + + transpose_and_flatten_matrices(output, (const u8 *)input->scaling_list_4x= 4, 6, 4); + offset =3D 6 * 16 * sizeof(u8); + transpose_and_flatten_matrices(output + offset, (const u8 *)input->scalin= g_list_8x8, 6, 8); + offset +=3D 6 * 64 * sizeof(u8); + transpose_and_flatten_matrices(output + offset, + (const u8 *)input->scaling_list_16x16, 6, 8); + offset +=3D 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 +=3D 64 * sizeof(u8); + memset(output + offset, 0, 128); + offset +=3D 128 * sizeof(u8); + transpose_and_flatten_matrices(output + offset, + (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)), + 1, 8); + offset +=3D 64 * sizeof(u8); + memset(output + offset, 0, 128); +} + +/* + * Required layout: + * A =3D scaling_list_dc_coef_16x16 + * B =3D scaling_list_dc_coef_32x32 + * 0 =3D Padding + * + * A, A, A, A, A, A, B, 0, 0, B, 0, 0 + */ +static void assemble_scalingdc(u8 *output, const struct v4l2_ctrl_hevc_sca= ling_matrix *input) +{ + u8 list_32x32[6] =3D {0}; + + memcpy(output, input->scaling_list_dc_coef_16x16, 6 * sizeof(u8)); + list_32x32[0] =3D input->scaling_list_dc_coef_32x32[0]; + list_32x32[3] =3D input->scaling_list_dc_coef_32x32[1]; + memcpy(output + 6 * sizeof(u8), list_32x32, 6 * sizeof(u8)); +} + +static void translate_scaling_list(struct scaling_factor *output, + const struct v4l2_ctrl_hevc_scaling_matrix *input) +{ + assemble_scalingfactor0(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_hevc_run *run, + struct scaling_factor *scaling_factor, + struct v4l2_ctrl_hevc_scaling_matrix *cache) +{ + const struct v4l2_ctrl_hevc_scaling_matrix *scaling =3D run->scaling_matr= ix; + + if (!memcmp(cache, scaling, + sizeof(struct v4l2_ctrl_hevc_scaling_matrix))) + return; + + translate_scaling_list(scaling_factor, scaling); + + memcpy(cache, scaling, + sizeof(struct v4l2_ctrl_hevc_scaling_matrix)); +} + +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 =3D ctx->fh.m2m_ctx; + const struct v4l2_ctrl_hevc_decode_params *decode_params =3D run->decode_= params; + const struct v4l2_hevc_dpb_entry *dpb =3D decode_params->dpb; + struct vb2_queue *cap_q =3D &m2m_ctx->cap_q_ctx.q; + struct vb2_buffer *buf =3D NULL; + + if (dpb_idx < decode_params->num_active_dpb_entries) + buf =3D 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; +} + +#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES 2 + +int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *fmt =3D &f->fmt.pix_mp; + + fmt->num_planes =3D 1; + if (!fmt->plane_fmt[0].sizeimage) + fmt->plane_fmt[0].sizeimage =3D fmt->width * fmt->height * + RKVDEC_HEVC_MAX_DEPTH_IN_BYTES; + return 0; +} + +enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx, + struct v4l2_ctrl *ctrl) +{ + const struct v4l2_ctrl_hevc_sps *sps =3D ctrl->p_new.p_hevc_sps; + + if (ctrl->id !=3D V4L2_CID_STATELESS_HEVC_SPS) + return RKVDEC_IMG_FMT_ANY; + + if (sps->bit_depth_luma_minus8 =3D=3D 0) { + if (sps->chroma_format_idc =3D=3D 2) + return RKVDEC_IMG_FMT_422_8BIT; + else + return RKVDEC_IMG_FMT_420_8BIT; + } else if (sps->bit_depth_luma_minus8 =3D=3D 2) { + if (sps->chroma_format_idc =3D=3D 2) + return RKVDEC_IMG_FMT_422_10BIT; + else + return RKVDEC_IMG_FMT_420_10BIT; + } + + return RKVDEC_IMG_FMT_ANY; +} + +static int rkvdec_hevc_validate_sps(struct rkvdec_ctx *ctx, + const struct v4l2_ctrl_hevc_sps *sps) +{ + if (sps->chroma_format_idc > 1) + /* Only 4:0:0 and 4:2:0 are supported */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 !=3D sps->bit_depth_chroma_minus8) + /* Luma and chroma bit depth mismatch */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 !=3D 0 && sps->bit_depth_luma_minus8 !=3D = 2) + /* Only 8-bit and 10-bit are supported */ + 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 =3D v4l2_ctrl_find(&ctx->ctrl_hdl, + V4L2_CID_STATELESS_HEVC_DECODE_PARAMS); + run->decode_params =3D ctrl ? ctrl->p_cur.p : NULL; + ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, + V4L2_CID_STATELESS_HEVC_SLICE_PARAMS); + run->slices_params =3D ctrl ? ctrl->p_cur.p : NULL; + run->num_slices =3D ctrl ? ctrl->new_elems : 0; + ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, + V4L2_CID_STATELESS_HEVC_SPS); + run->sps =3D ctrl ? ctrl->p_cur.p : NULL; + ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, + V4L2_CID_STATELESS_HEVC_PPS); + run->pps =3D ctrl ? ctrl->p_cur.p : NULL; + ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, + V4L2_CID_STATELESS_HEVC_SCALING_MATRIX); + run->scaling_matrix =3D ctrl ? ctrl->p_cur.p : NULL; + + rkvdec_run_preamble(ctx, &run->base); +} + +int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) +{ + if (ctrl->id =3D=3D V4L2_CID_STATELESS_HEVC_SPS) + return rkvdec_hevc_validate_sps(ctx, ctrl->p_new.p_hevc_sps); + + return 0; +} 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 000000000000..746b1bd73c08 --- /dev/null +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip video decoder hevc common functions + * + * Copyright (C) 2025 Collabora, Ltd. + * Detlev Casanova + * + * Copyright (C) 2023 Collabora, Ltd. + * Sebastian Fricke + * + * Copyright (C) 2019 Collabora, Ltd. + * Boris Brezillon + * + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Jeffy Chen + */ + +#include +#include "rkvdec.h" + +#define RKV_HEVC_CABAC_TABLE_SIZE 27456 +extern const u8 rkvdec_hevc_cabac_table[RKV_HEVC_CABAC_TABLE_SIZE]; + +struct rkvdec_hevc_run { + struct rkvdec_run base; + const struct v4l2_ctrl_hevc_slice_params *slices_params; + const struct v4l2_ctrl_hevc_decode_params *decode_params; + const struct v4l2_ctrl_hevc_sps *sps; + const struct v4l2_ctrl_hevc_pps *pps; + const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix; + 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*/ +}; + +enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx, + struct v4l2_ctrl *ctrl); +void rkvdec_hevc_assemble_hw_scaling_list(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_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl); +void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_hevc_r= un *run); diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers= /media/platform/rockchip/rkvdec/rkvdec-hevc.c index b01c1bb52a04..31a979698578 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -16,6 +16,7 @@ =20 #include "rkvdec.h" #include "rkvdec-regs.h" +#include "rkvdec-hevc-common.h" =20 /* Size in u8/u32 units. */ #define RKV_SCALING_LIST_SIZE 1360 @@ -24,9 +25,6 @@ #define RKV_RPS_SIZE (32 / 4) #define RKV_RPS_LEN 600 =20 -#define RKV_HEVC_CABAC_TABLE_SIZE 27456 -extern const u8 rkvdec_hevc_cabac_table[RKV_HEVC_CABAC_TABLE_SIZE]; - struct rkvdec_sps_pps_packet { u32 info[RKV_PPS_SIZE]; }; @@ -113,34 +111,17 @@ struct rkvdec_ps_field { /* Data structure describing auxiliary buffer format. */ struct rkvdec_hevc_priv_tbl { u8 cabac_table[RKV_HEVC_CABAC_TABLE_SIZE]; - u8 scaling_list[RKV_SCALING_LIST_SIZE]; + struct scaling_factor scaling_list; struct rkvdec_sps_pps_packet param_set[RKV_PPS_LEN]; struct rkvdec_rps_packet rps[RKV_RPS_LEN]; }; =20 -struct rkvdec_hevc_run { - struct rkvdec_run base; - const struct v4l2_ctrl_hevc_slice_params *slices_params; - const struct v4l2_ctrl_hevc_decode_params *decode_params; - const struct v4l2_ctrl_hevc_sps *sps; - const struct v4l2_ctrl_hevc_pps *pps; - const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix; - int num_slices; -}; - struct rkvdec_hevc_ctx { struct rkvdec_aux_buf priv_tbl; struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix_cache; struct rkvdec_regs regs; }; =20 -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*/ -}; - static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value) { u8 bit =3D field.offset % 32, word =3D field.offset / 32; @@ -417,131 +398,6 @@ static void assemble_sw_rps(struct rkvdec_ctx *ctx, } } =20 -/* - * Flip one or more matrices along their main diagonal and flatten them - * before writing it to the memory. - * Convert: - * ABCD AEIM - * EFGH =3D> BFJN =3D> 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 =3D row_length * row_length; - for (i =3D 0; i < matrices; i++) { - row =3D 0; - x_offset =3D 0; - matrix_offset =3D i * matrix_size; - for (j =3D 0; j < matrix_size; j++) { - y_offset =3D j - (row * row_length); - rot_index =3D y_offset * row_length + x_offset; - new_value =3D *(input + i * matrix_size + j); - output[matrix_offset + rot_index] =3D new_value; - if ((j + 1) % row_length =3D=3D 0) { - row +=3D 1; - x_offset +=3D 1; - } - } - } -} - -static void assemble_scalingfactor0(u8 *output, const struct v4l2_ctrl_hev= c_scaling_matrix *input) -{ - int offset =3D 0; - - transpose_and_flatten_matrices(output, (const u8 *)input->scaling_list_4x= 4, 6, 4); - offset =3D 6 * 16 * sizeof(u8); - transpose_and_flatten_matrices(output + offset, (const u8 *)input->scalin= g_list_8x8, 6, 8); - offset +=3D 6 * 64 * sizeof(u8); - transpose_and_flatten_matrices(output + offset, - (const u8 *)input->scaling_list_16x16, 6, 8); - offset +=3D 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 +=3D 64 * sizeof(u8); - memset(output + offset, 0, 128); - offset +=3D 128 * sizeof(u8); - transpose_and_flatten_matrices(output + offset, - (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)), - 1, 8); - offset +=3D 64 * sizeof(u8); - memset(output + offset, 0, 128); -} - -/* - * Required layout: - * A =3D scaling_list_dc_coef_16x16 - * B =3D scaling_list_dc_coef_32x32 - * 0 =3D Padding - * - * A, A, A, A, A, A, B, 0, 0, B, 0, 0 - */ -static void assemble_scalingdc(u8 *output, const struct v4l2_ctrl_hevc_sca= ling_matrix *input) -{ - u8 list_32x32[6] =3D {0}; - - memcpy(output, input->scaling_list_dc_coef_16x16, 6 * sizeof(u8)); - list_32x32[0] =3D input->scaling_list_dc_coef_32x32[0]; - list_32x32[3] =3D input->scaling_list_dc_coef_32x32[1]; - memcpy(output + 6 * sizeof(u8), list_32x32, 6 * sizeof(u8)); -} - -static void translate_scaling_list(struct scaling_factor *output, - const struct v4l2_ctrl_hevc_scaling_matrix *input) -{ - assemble_scalingfactor0(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)); -} - -static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx, - struct rkvdec_hevc_run *run) -{ - const struct v4l2_ctrl_hevc_scaling_matrix *scaling =3D run->scaling_matr= ix; - struct rkvdec_hevc_ctx *hevc_ctx =3D ctx->priv; - struct rkvdec_hevc_priv_tbl *tbl =3D hevc_ctx->priv_tbl.cpu; - u8 *dst; - - if (!memcmp((void *)&hevc_ctx->scaling_matrix_cache, scaling, - sizeof(struct v4l2_ctrl_hevc_scaling_matrix))) - return; - - dst =3D tbl->scaling_list; - translate_scaling_list((struct scaling_factor *)dst, scaling); - - memcpy((void *)&hevc_ctx->scaling_matrix_cache, scaling, - sizeof(struct v4l2_ctrl_hevc_scaling_matrix)); -} - -static 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 =3D ctx->fh.m2m_ctx; - const struct v4l2_ctrl_hevc_decode_params *decode_params =3D run->decode_= params; - const struct v4l2_hevc_dpb_entry *dpb =3D decode_params->dpb; - struct vb2_queue *cap_q =3D &m2m_ctx->cap_q_ctx.q; - struct vb2_buffer *buf =3D NULL; - - if (dpb_idx < decode_params->num_active_dpb_entries) - buf =3D 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; -} - static void config_registers(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run) { @@ -644,63 +500,6 @@ static void config_registers(struct rkvdec_ctx *ctx, rkvdec_memcpy_toio(rkvdec->regs, regs, MIN(sizeof(*regs), 4 * rkvdec->var= iant->num_regs)); } =20 -#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES 2 - -static int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *fmt =3D &f->fmt.pix_mp; - - fmt->num_planes =3D 1; - if (!fmt->plane_fmt[0].sizeimage) - fmt->plane_fmt[0].sizeimage =3D fmt->width * fmt->height * - RKVDEC_HEVC_MAX_DEPTH_IN_BYTES; - return 0; -} - -static enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *= ctx, - struct v4l2_ctrl *ctrl) -{ - const struct v4l2_ctrl_hevc_sps *sps =3D ctrl->p_new.p_hevc_sps; - - if (ctrl->id !=3D V4L2_CID_STATELESS_HEVC_SPS) - return RKVDEC_IMG_FMT_ANY; - - if (sps->bit_depth_luma_minus8 =3D=3D 0) { - if (sps->chroma_format_idc =3D=3D 2) - return RKVDEC_IMG_FMT_422_8BIT; - else - return RKVDEC_IMG_FMT_420_8BIT; - } else if (sps->bit_depth_luma_minus8 =3D=3D 2) { - if (sps->chroma_format_idc =3D=3D 2) - return RKVDEC_IMG_FMT_422_10BIT; - else - return RKVDEC_IMG_FMT_420_10BIT; - } - - return RKVDEC_IMG_FMT_ANY; -} - -static int rkvdec_hevc_validate_sps(struct rkvdec_ctx *ctx, - const struct v4l2_ctrl_hevc_sps *sps) -{ - if (sps->chroma_format_idc > 1) - /* Only 4:0:0 and 4:2:0 are supported */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 !=3D sps->bit_depth_chroma_minus8) - /* Luma and chroma bit depth mismatch */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 !=3D 0 && sps->bit_depth_luma_minus8 !=3D = 2) - /* Only 8-bit and 10-bit is supported */ - 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; -} - static int rkvdec_hevc_start(struct rkvdec_ctx *ctx) { struct rkvdec_dev *rkvdec =3D ctx->dev; @@ -737,40 +536,18 @@ static void rkvdec_hevc_stop(struct rkvdec_ctx *ctx) kfree(hevc_ctx); } =20 -static void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx, - struct rkvdec_hevc_run *run) -{ - struct v4l2_ctrl *ctrl; - - ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_HEVC_DECODE_PARAMS); - run->decode_params =3D ctrl ? ctrl->p_cur.p : NULL; - ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_HEVC_SLICE_PARAMS); - run->slices_params =3D ctrl ? ctrl->p_cur.p : NULL; - run->num_slices =3D ctrl ? ctrl->new_elems : 0; - ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_HEVC_SPS); - run->sps =3D ctrl ? ctrl->p_cur.p : NULL; - ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_HEVC_PPS); - run->pps =3D ctrl ? ctrl->p_cur.p : NULL; - ctrl =3D v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_HEVC_SCALING_MATRIX); - run->scaling_matrix =3D ctrl ? ctrl->p_cur.p : NULL; - - rkvdec_run_preamble(ctx, &run->base); -} - static int rkvdec_hevc_run(struct rkvdec_ctx *ctx) { struct rkvdec_dev *rkvdec =3D ctx->dev; struct rkvdec_hevc_run run; + struct rkvdec_hevc_ctx *hevc_ctx =3D ctx->priv; + struct rkvdec_hevc_priv_tbl *tbl =3D hevc_ctx->priv_tbl.cpu; u32 reg; =20 rkvdec_hevc_run_preamble(ctx, &run); =20 - assemble_hw_scaling_list(ctx, &run); + rkvdec_hevc_assemble_hw_scaling_list(&run, &tbl->scaling_list, + &hevc_ctx->scaling_matrix_cache); assemble_hw_pps(ctx, &run); assemble_sw_rps(ctx, &run); config_registers(ctx, &run); @@ -795,14 +572,6 @@ static int rkvdec_hevc_run(struct rkvdec_ctx *ctx) return 0; } =20 -static int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *= ctrl) -{ - if (ctrl->id =3D=3D 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_hevc_fmt_ops =3D { .adjust_fmt =3D rkvdec_hevc_adjust_fmt, .start =3D rkvdec_hevc_start, --=20 2.51.1.dirty