Re: [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants

Vishnu Reddy <[email protected]> Wed, 5 Aug 2026 21:41:46 +0530
Newsgroups org.kernel.vger.linux-media,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 7/10/2026 1:06 AM, Dmitry Baryshkov wrote:
> The Gen1 firmware expects the profile and level in the
> HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT property as HFI-specific
> enumerants (a one-hot bitmask), but the iris driver passed the raw V4L2
> profile and level values straight through. Only the V4L2 H264 high
> profile happened to match its HFI value (both 0x4); every other profile
> and all levels were programmed with a wrong value.
>
> Translate the V4L2 profile and level to the HFI enumerants per codec
> before building the property, mirroring the mapping the venus driver
> performs for the same firmware interface.
>
> Fixes: d22037f3fd33 ("media: iris: Set platform capabilities to firmware for encoder video device")
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Dmitry Baryshkov <[email protected]>
> ---
>  .../platform/qcom/iris/iris_hfi_gen1_command.c     | 109 +++++++++++++++++++--
>  .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  44 +++++++++
>  2 files changed, 144 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> index c4baabbacefd..ed9fef2aec08 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -479,6 +479,105 @@ static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane)
>  	return -EINVAL;
>  }
>  
> +struct iris_hfi_gen1_id_mapping {
> +	u32 hfi_id;
> +	u32 v4l2_id;
> +};
> +
> +static const struct iris_hfi_gen1_id_mapping iris_hfi_gen1_h264_profiles[] = {
> +	{ HFI_H264_PROFILE_BASELINE, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE },
> +	{ HFI_H264_PROFILE_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN },
> +	{ HFI_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH },
> +	{ HFI_H264_PROFILE_STEREO_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH },
> +	{ HFI_H264_PROFILE_MULTIVIEW_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH },
> +	{ HFI_H264_PROFILE_CONSTRAINED_BASE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE },
> +	{ HFI_H264_PROFILE_CONSTRAINED_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH },
> +};
> +
> +static const struct iris_hfi_gen1_id_mapping iris_hfi_gen1_h264_levels[] = {
> +	{ HFI_H264_LEVEL_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 },
> +	{ HFI_H264_LEVEL_1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B },
> +	{ HFI_H264_LEVEL_11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 },
> +	{ HFI_H264_LEVEL_12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 },
> +	{ HFI_H264_LEVEL_13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 },
> +	{ HFI_H264_LEVEL_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 },
> +	{ HFI_H264_LEVEL_21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 },
> +	{ HFI_H264_LEVEL_22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 },
> +	{ HFI_H264_LEVEL_3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 },
> +	{ HFI_H264_LEVEL_31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 },
> +	{ HFI_H264_LEVEL_32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 },
> +	{ HFI_H264_LEVEL_4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 },
> +	{ HFI_H264_LEVEL_41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 },
> +	{ HFI_H264_LEVEL_42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 },
> +	{ HFI_H264_LEVEL_5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 },
> +	{ HFI_H264_LEVEL_51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
> +	{ HFI_H264_LEVEL_52, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },

Is it correct that both HFI levels 51 and 52 map to V4L2 level 5_1?

> +};
> +
> +static const struct iris_hfi_gen1_id_mapping iris_hfi_gen1_hevc_profiles[] = {
> +	{ HFI_HEVC_PROFILE_MAIN, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN },
> +	{ HFI_HEVC_PROFILE_MAIN_STILL_PIC, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE },
> +	{ HFI_HEVC_PROFILE_MAIN10, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 },
> +};
> +
> +static const struct iris_hfi_gen1_id_mapping iris_hfi_gen1_hevc_levels[] = {
> +	{ HFI_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_1 },
> +	{ HFI_HEVC_LEVEL_2, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 },
> +	{ HFI_HEVC_LEVEL_21, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 },
> +	{ HFI_HEVC_LEVEL_3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 },
> +	{ HFI_HEVC_LEVEL_31, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 },
> +	{ HFI_HEVC_LEVEL_4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 },
> +	{ HFI_HEVC_LEVEL_41, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 },
> +	{ HFI_HEVC_LEVEL_5, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 },
> +	{ HFI_HEVC_LEVEL_51, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 },
> +	{ HFI_HEVC_LEVEL_52, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 },
> +	{ HFI_HEVC_LEVEL_6, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 },
> +	{ HFI_HEVC_LEVEL_61, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 },
> +	{ HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 },
> +};
> +
> +static u32 iris_hfi_gen1_find_hfi_id(u32 v4l2_id,
> +				     const struct iris_hfi_gen1_id_mapping *array,
> +				     unsigned int array_sz)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < array_sz; i++)
> +		if (v4l2_id == array[i].v4l2_id)
> +			return array[i].hfi_id;
> +
> +	return 0;
> +}
> +
> +/*
> + * The Gen1 firmware expects profile and level as HFI enumerants, while the
> + * client provides raw V4L2 values. Translate them per codec, mirroring the
> + * mapping performed by the venus driver for the same firmware interface.
> + */
> +static void
> +iris_hfi_gen1_profile_level(struct iris_inst *inst, u32 v4l2_pf, u32 v4l2_lvl,
> +			    struct hfi_profile_level *pl)
> +{
> +	switch (inst->codec) {
> +	case V4L2_PIX_FMT_H264:
> +		pl->profile = iris_hfi_gen1_find_hfi_id(v4l2_pf, iris_hfi_gen1_h264_profiles,
> +							ARRAY_SIZE(iris_hfi_gen1_h264_profiles));
> +		pl->level = iris_hfi_gen1_find_hfi_id(v4l2_lvl, iris_hfi_gen1_h264_levels,
> +						      ARRAY_SIZE(iris_hfi_gen1_h264_levels));
> +		break;
> +	case V4L2_PIX_FMT_HEVC:
> +		pl->profile = iris_hfi_gen1_find_hfi_id(v4l2_pf, iris_hfi_gen1_hevc_profiles,
> +							ARRAY_SIZE(iris_hfi_gen1_hevc_profiles));
> +		pl->level = iris_hfi_gen1_find_hfi_id(v4l2_lvl, iris_hfi_gen1_hevc_levels,
> +						      ARRAY_SIZE(iris_hfi_gen1_hevc_levels));
> +		break;
> +	default:
> +		pl->profile = 0;
> +		pl->level = 0;
> +		break;
> +	}
> +}
> +
>  static int
>  iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet,
>  					  struct iris_inst *inst, u32 ptype, void *pdata)
> @@ -582,15 +681,7 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
>  	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: {
>  		struct hfi_profile_level *in = pdata, *pl = prop_data;
>  
> -		pl->level = in->level;
> -		pl->profile = in->profile;
> -		if (pl->profile <= 0)
> -			/* Profile not supported, falling back to high */
> -			pl->profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
> -
> -		if (!pl->level)
> -			/* Level not supported, falling back to 1 */
> -			pl->level = 1;
> +		iris_hfi_gen1_profile_level(inst, in->profile, in->level, pl);
>  
>  		packet->shdr.hdr.size += sizeof(*pl);
>  		break;
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> index bb495a1d2623..2702f255bc04 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -17,6 +17,50 @@
>  #define HFI_VIDEO_CODEC_HEVC				0x00002000
>  #define HFI_VIDEO_CODEC_VP9				0x00004000
>  
> +#define HFI_H264_PROFILE_BASELINE			0x00000001
> +#define HFI_H264_PROFILE_MAIN				0x00000002
> +#define HFI_H264_PROFILE_HIGH				0x00000004
> +#define HFI_H264_PROFILE_STEREO_HIGH			0x00000008
> +#define HFI_H264_PROFILE_MULTIVIEW_HIGH			0x00000010
> +#define HFI_H264_PROFILE_CONSTRAINED_BASE		0x00000020
> +#define HFI_H264_PROFILE_CONSTRAINED_HIGH		0x00000040
> +
> +#define HFI_H264_LEVEL_1				0x00000001
> +#define HFI_H264_LEVEL_1b				0x00000002
> +#define HFI_H264_LEVEL_11				0x00000004
> +#define HFI_H264_LEVEL_12				0x00000008
> +#define HFI_H264_LEVEL_13				0x00000010
> +#define HFI_H264_LEVEL_2				0x00000020
> +#define HFI_H264_LEVEL_21				0x00000040
> +#define HFI_H264_LEVEL_22				0x00000080
> +#define HFI_H264_LEVEL_3				0x00000100
> +#define HFI_H264_LEVEL_31				0x00000200
> +#define HFI_H264_LEVEL_32				0x00000400
> +#define HFI_H264_LEVEL_4				0x00000800
> +#define HFI_H264_LEVEL_41				0x00001000
> +#define HFI_H264_LEVEL_42				0x00002000
> +#define HFI_H264_LEVEL_5				0x00004000
> +#define HFI_H264_LEVEL_51				0x00008000
> +#define HFI_H264_LEVEL_52				0x00010000
> +
> +#define HFI_HEVC_PROFILE_MAIN				0x00000001
> +#define HFI_HEVC_PROFILE_MAIN10				0x00000002
> +#define HFI_HEVC_PROFILE_MAIN_STILL_PIC			0x00000004
> +
> +#define HFI_HEVC_LEVEL_1				0x00000001
> +#define HFI_HEVC_LEVEL_2				0x00000002
> +#define HFI_HEVC_LEVEL_21				0x00000004
> +#define HFI_HEVC_LEVEL_3				0x00000008
> +#define HFI_HEVC_LEVEL_31				0x00000010
> +#define HFI_HEVC_LEVEL_4				0x00000020
> +#define HFI_HEVC_LEVEL_41				0x00000040
> +#define HFI_HEVC_LEVEL_5				0x00000080
> +#define HFI_HEVC_LEVEL_51				0x00000100
> +#define HFI_HEVC_LEVEL_52				0x00000200
> +#define HFI_HEVC_LEVEL_6				0x00000400
> +#define HFI_HEVC_LEVEL_61				0x00000800
> +#define HFI_HEVC_LEVEL_62				0x00001000
> +
>  #define HFI_ERR_NONE					0x0
>  
>  #define HFI_CMD_SYS_INIT				0x10001

Reviewed-by: Vishnu Reddy <[email protected]>