Re: [PATCH v5 12/16] media: iris: implement support for the Agatti platform
From: Dmitry Baryshkov
Date: Wed Jul 01 2026 - 09:31:16 EST
On Wed, Jun 24, 2026 at 07:47:43PM +0530, Vikash Garodia wrote:
>
>
> On 6/16/2026 5:34 AM, Dmitry Baryshkov wrote:
> > Port support for the AR50Lt video codec core (present for example on the
> > Agatti platform) to the Iris driver. Unlike more recent cores this
> > generation doesn't have the PIPE property (as it always has only one
> > pipe). Also, unlike newer platforms, buffer sizes are requested from the
> > firmware instead of being calculated by the driver.
> >
> > Co-developed-by: Dikshita Agarwal <dikshita.agarwal@xxxxxxxxxxxxxxxx>
> > Signed-off-by: Dikshita Agarwal <dikshita.agarwal@xxxxxxxxxxxxxxxx>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxxxxxxxx>
> > ---
> > drivers/media/platform/qcom/iris/Makefile | 1 +
> > drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 227 +++++++++++++++++++++
> > .../platform/qcom/iris/iris_platform_common.h | 6 +
> > .../platform/qcom/iris/iris_platform_vpu_ar50lt.c | 110 ++++++++++
> > drivers/media/platform/qcom/iris/iris_probe.c | 4 +
> > drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 13 ++
> > drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 1 +
> > 7 files changed, 362 insertions(+)
> >
> > diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> > index f1b204b95694..bbd1f724963e 100644
> > --- a/drivers/media/platform/qcom/iris/Makefile
> > +++ b/drivers/media/platform/qcom/iris/Makefile
> > @@ -14,6 +14,7 @@ qcom-iris-objs += iris_buffer.o \
> > iris_hfi_queue.o \
> > iris_platform_vpu2.o \
> > iris_platform_vpu3x.o \
> > + iris_platform_vpu_ar50lt.o \
> > iris_power.o \
> > iris_probe.o \
> > iris_resources.o \
> > diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> > index ca1545d28b53..f57af31dbd9f 100644
> > --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> > +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> > @@ -443,3 +443,230 @@ const struct iris_firmware_data iris_hfi_gen1_data = {
> > .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl,
> > .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl),
> > };
> > +
> > +static const struct platform_inst_fw_cap iris_inst_fw_cap_gen1_ar50lt_dec[] = {
> > + {
> > + .cap_id = STAGE,
> > + .min = STAGE_1,
> > + .max = STAGE_2,
> > + .step_or_mask = 1,
> > + .value = STAGE_2,
> > + .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
> > + .set = iris_set_stage,
> > + },
> > +};
> > +
> > +static const struct platform_inst_fw_cap inst_fw_cap_gen1_ar50lt_enc[] = {
> > + {
> > + .cap_id = STAGE,
> > + .min = STAGE_1,
> > + .max = STAGE_2,
> > + .step_or_mask = 1,
> > + .value = STAGE_2,
> > + .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
> > + .set = iris_set_stage,
> > + },
> > + {
> > + .cap_id = PROFILE_H264,
> > + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
> > + .max = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
> > + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
> > + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
> > + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
> > + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
> > + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH),
> > + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
> > + .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_profile_level_gen1,
> > + },
> > + {
> > + .cap_id = PROFILE_HEVC,
> > + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
> > + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE),
> > + .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
> > + .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_profile_level_gen1,
> > + },
> > + {
> > + .cap_id = LEVEL_H264,
> > + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
> > + .max = V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
> > + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2),
> > + .value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
> > + .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_profile_level_gen1,
> > + },
> > + {
> > + .cap_id = LEVEL_HEVC,
> > + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
> > + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1),
> > + .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
> > + .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_profile_level_gen1,
> > + },
> > + {
> > + .cap_id = HEADER_MODE,
> > + .min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
> > + .max = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
> > + BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
> > + .value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
> > + .hfi_id = HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_header_mode_gen1,
> > + },
> > + {
> > + .cap_id = BITRATE,
> > + .min = BITRATE_MIN,
> > + .max = BITRATE_MAX_AR50LT,
> > + .step_or_mask = BITRATE_STEP,
> > + .value = BITRATE_DEFAULT_AR50LT,
> > + .hfi_id = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
> > + CAP_FLAG_DYNAMIC_ALLOWED,
> > + .set = iris_set_bitrate_gen1,
> > + },
> > + {
> > + .cap_id = BITRATE_MODE,
> > + .min = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
> > + .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
> > + BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
> > + .value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
> > + .hfi_id = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_bitrate_mode_gen1,
> > + },
> > + {
> > + .cap_id = FRAME_SKIP_MODE,
> > + .min = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
> > + .max = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) |
> > + BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT),
> > + .value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + },
> > + {
> > + .cap_id = FRAME_RC_ENABLE,
> > + .min = 0,
> > + .max = 1,
> > + .step_or_mask = 1,
> > + .value = 1,
> > + },
> > + {
> > + .cap_id = GOP_SIZE,
> > + .min = 0,
> > + .max = (1 << 16) - 1,
> > + .step_or_mask = 1,
> > + .value = 30,
> > + .set = iris_set_u32
> > + },
> > + {
> > + .cap_id = ENTROPY_MODE,
> > + .min = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
> > + .max = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
> > + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
> > + BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
> > + .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
> > + .hfi_id = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL,
> > + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> > + .set = iris_set_entropy_mode_gen1,
> > + },
> > + {
> > + .cap_id = MIN_FRAME_QP_H264,
> > + .min = MIN_QP_8BIT_AR50LT,
> > + .max = MAX_QP,
> > + .step_or_mask = 1,
> > + .value = MIN_QP_8BIT_AR50LT,
> > + .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
> > + .flags = CAP_FLAG_OUTPUT_PORT,
> > + .set = iris_set_qp_range,
> > + },
> > + {
> > + .cap_id = MIN_FRAME_QP_HEVC,
> > + .min = MIN_QP_8BIT_AR50LT,
> > + .max = MAX_QP_HEVC,
> > + .step_or_mask = 1,
> > + .value = MIN_QP_8BIT_AR50LT,
> > + .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
> > + .flags = CAP_FLAG_OUTPUT_PORT,
> > + .set = iris_set_qp_range,
> > + },
> > + {
> > + .cap_id = MAX_FRAME_QP_H264,
> > + .min = MIN_QP_8BIT_AR50LT,
> > + .max = MAX_QP,
> > + .step_or_mask = 1,
> > + .value = MAX_QP,
> > + .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
> > + .flags = CAP_FLAG_OUTPUT_PORT,
> > + .set = iris_set_qp_range,
> > + },
> > + {
> > + .cap_id = MAX_FRAME_QP_HEVC,
> > + .min = MIN_QP_8BIT_AR50LT,
> > + .max = MAX_QP_HEVC,
> > + .step_or_mask = 1,
> > + .value = MAX_QP_HEVC,
> > + .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
> > + .flags = CAP_FLAG_OUTPUT_PORT,
> > + .set = iris_set_qp_range,
> > + },
> > +};
> > +
> > +static const u32 iris_hfi_gen2_ar50lt_dec_ip_int_buf_tbl[] = {
> > + BUF_BIN,
> > + BUF_SCRATCH_1,
> > +};
> > +
> > +const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
> > + .init_hfi_ops = &iris_hfi_gen1_sys_ops_init,
> > +
> > + .inst_fw_caps_dec = iris_inst_fw_cap_gen1_ar50lt_dec,
> > + .inst_fw_caps_dec_size = ARRAY_SIZE(iris_inst_fw_cap_gen1_ar50lt_dec),
> > + .inst_fw_caps_enc = inst_fw_cap_gen1_ar50lt_enc,
> > + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen1_ar50lt_enc),
> > +
> > + .dec_input_config_params_default =
> > + sm8250_vdec_input_config_param_default,
> > + .dec_input_config_params_default_size =
> > + ARRAY_SIZE(sm8250_vdec_input_config_param_default),
> > + .enc_input_config_params = sm8250_venc_input_config_param,
> > + .enc_input_config_params_size =
> > + ARRAY_SIZE(sm8250_venc_input_config_param),
> > +
> > + .dec_ip_int_buf_tbl = iris_hfi_gen2_ar50lt_dec_ip_int_buf_tbl,
> > + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(iris_hfi_gen2_ar50lt_dec_ip_int_buf_tbl),
> > + .dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl,
> > + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl),
> > +
> > + .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl,
> > + .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl),
> > +};
> > diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> > index 6a189489369f..bc04831ae7fc 100644
> > --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> > +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> > @@ -39,6 +39,10 @@ struct iris_inst;
> > #define MAX_HEVC_VBR_LAYER_HP_SLIDING_WINDOW 5
> > #define MAX_HIER_CODING_LAYER_GEN1 6
> > +#define BITRATE_MAX_AR50LT 100000000
> > +#define BITRATE_DEFAULT_AR50LT 20000000
> > +#define MIN_QP_8BIT_AR50LT 0
> > +
> > enum stage_type {
> > STAGE_1 = 1,
> > STAGE_2 = 2,
> > @@ -51,8 +55,10 @@ enum pipe_type {
> > };
> > extern const struct iris_firmware_data iris_hfi_gen1_data;
> > +extern const struct iris_firmware_data iris_hfi_gen1_ar50lt_data;
> > extern const struct iris_firmware_data iris_hfi_gen2_data;
> > +extern const struct iris_platform_data qcm2290_data;
> > extern const struct iris_platform_data qcs8300_data;
> > extern const struct iris_platform_data sc7280_data;
> > extern const struct iris_platform_data sm8250_data;
> > diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
> > new file mode 100644
> > index 000000000000..393256f39112
> > --- /dev/null
> > +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
> > @@ -0,0 +1,110 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
> > + */
> > +
> > +#include "iris_core.h"
> > +#include "iris_ctrls.h"
> > +#include "iris_hfi_gen2.h"
> > +#include "iris_hfi_gen2_defines.h"
> > +#include "iris_platform_common.h"
> > +#include "iris_vpu_buffer.h"
> > +#include "iris_vpu_common.h"
> > +
> > +#define WRAPPER_INTR_STATUS_A2HWD_BMSK 0x10
> > +
> > +const struct iris_firmware_desc iris_vpu_ar50lt_p1_gen1_s6_desc = {
> > + .firmware_data = &iris_hfi_gen1_ar50lt_data,
> > + .get_vpu_buffer_size = iris_vpu_ar50lt_gen1_buf_size,
>
> unlike gen2, gen1 is calling buffer_requirement from firmware for every
> buffer types. And given that call is a synchronous call to firmware i.e it
> calls and wait for a response, i see it can cause delay (and infact not
> needed) if called for multiple internal buffer types. Can we see if we can
> call that call once ? That call to firmware (get prop for
> HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS) fetches requirement for all buffer
> types.
This matches the Venus driver, it was querying buffer properties for
each packet. If we query buffer sizes only once, what would be the
condition to re-query them? One of the property updates? Which ones?
--
With best wishes
Dmitry