* [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support
@ 2026-07-09 19:36 Dmitry Baryshkov
2026-07-09 19:36 ` [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants Dmitry Baryshkov
` (9 more replies)
0 siblings, 10 replies; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:36 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
Bring back features supported by the Venus driver, but not supported by
the Iris driver: VP8 (encoding, decoding), MPEG2 (decoding only) video
support and also support for interlaced video streams.
On the SM8250 (RB5):
debian@debian:~$ v4l2-compliance -d /dev/video0
v4l2-compliance 1.30.1, 64 bits, 64-bit time_t
Compliance test for iris_driver device /dev/video0:
Driver Info:
Driver name : iris_driver
Card type : Iris Decoder
Bus info : platform:aa00000.video-codec
Driver version : 7.2.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Detected Stateful Decoder
Required ioctls:
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/video0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 6 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK
test Composing: OK
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)
test blocking wait: OK
Total for iris_driver device /dev/video0: 48, Succeeded: 48, Failed: 0, Warnings: 0
debian@debian:~$ v4l2-compliance -d /dev/vid
v4l2-compliance 1.30.1, 64 bits, 64-bit time_t
Cannot open device /dev/vid, exiting.
debian@debian:~$ v4l2-compliance -d /dev/video1
v4l2-compliance 1.30.1, 64 bits, 64-bit time_t
Compliance test for iris_driver device /dev/video1:
Driver Info:
Driver name : iris_driver
Card type : Iris Encoder
Bus info : platform:aa00000.video-codec
Driver version : 7.2.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Detected Stateful Encoder
Required ioctls:
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/video1 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 34 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)
test blocking wait: OK
Total for iris_driver device /dev/video1: 48, Succeeded: 48, Failed: 0, Warnings: 0
|Test|FFmpeg-VP8-v4l2m2m|GStreamer-VP8-V4L2|
|-|-|-|
|TOTAL|48/61|57/61|
|NOT SUPPORTED|0/61|0/61|
|FAIL/ERROR|13/61|4/61|
|TOTAL TIME|10.558s|9.834s|
Failing with the Gstreamer and FFMpeg:
- vp80-01-intra-1411
- vp80-02-inter-1412
- vp80-03-segmentation-1413
- vp80-05-sharpness-1443
Failing only with FFmpeg
- vp80-00-comprehensive-018
- vp80-01-intra-1416
- vp80-01-intra-1417
- vp80-03-segmentation-01
- vp80-03-segmentation-02
- vp80-03-segmentation-04
- vp80-03-segmentation-1425
- vp80-03-segmentation-1436
- vp80-05-sharpness-1439
|Test|FFmpeg-MPEG2_VIDEO-v4l2m2m|GStreamer-MPEG2_VIDEO-V4L2|
|-|-|-|
|TOTAL|36/43|30/43|
|NOT SUPPORTED|0/43|0/43|
|FAIL/ERROR|7/43|13/43|
|TOTAL TIME|71.857s|62.045s|
Failing with both Gstreamer and FFmpeg:
- att
- sony-ct1
- teracom_vlc4
- tcela-18
- ccm1
- ntr_skipped_v3
Failing with Gstreamer only:
- MEI
- MEI.stream16
- sony-ct4
- sony-ct2
- sony-ct3
- tcela-16
- tcela-19
Failing with FFmpeg only:
- test
The following H.264 tests now pass because of interlaced video being
supported:
- cabac_mot_fld0_full
- cabac_mot_mbaff0_full
- cabac_mot_picaff0_full
- CAFI1_SVA_C
- CAMA1_Sony_C
- cama1_vtc_c
- cama2_vtc_b
- cama3_vtc_b
- CAMACI3_Sony_C (Gstreamer only)
- CAMASL3_Sony_B
- CAMP_MOT_MBAFF_L30
- CAMP_MOT_MBAFF_L31
- CANLMA2_Sony_C
- CANLMA3_Sony_C
- cavlc_mot_fld0_full_B
- cavlc_mot_mbaff0_full_B
- cavlc_mot_picaff0_full_B
- CVCANLMA2_Sony_C
- CVFI1_Sony_D
- CVFI1_SVA_C
- CVFI2_Sony_H
- CVFI2_SVA_C
- CVMA1_Sony_D
- CVMAPAQP3_Sony_E
- CVMAQP2_Sony_G
- CVMAQP3_Sony_D
- CVMP_MOT_FLD_L30_B
- CVMP_MOT_FRM_L31_B
- CVNLFI1_Sony_C
- CVNLFI2_Sony_H
- FI1_Sony_E
- MR6_BT_B
- MR7_BT_B
- MR8_BT_B
- MR9_BT_B
- Sharp_MP_Field_1_B
- Sharp_MP_Field_2_B
- Sharp_MP_Field_3_B
- Sharp_MP_PAFF_1r2
- Sharp_MP_PAFF_2r
- SVCHST-3-r1-L0
- HVLCFI0_Sony_B
- HVLCMFF0_Sony_B
- HVLCPFF0_Sony_B
Following tests had to be disabled because they cause firmware crashes
or IOMMU faults (this behaviour matches Venus one):
- CAMA1_TOSHIBA_B
- CAMA3_Sand_E
- CAMANL1_TOSHIBA_B
- CAMANL2_TOSHIBA_B
- CAMANL3_Sand_E
- CAPAMA3_Sand_F
- CVMA1_TOSHIBA_B
- CVMANL1_TOSHIBA_B
- CVMANL2_TOSHIBA_B
- CVPA1_TOSHIBA_B
- FREXT01_JVC_D
- FREXT02_JVC_C
- FRExt2_Panasonic_C
- FRExt4_Panasonic_B
- HCAFF1_HHI_B
- HCAMFF1_HHI_B
- HPCAFLNL_BRCM_C
- HPCAFL_BRCM_C
- HPCAMAPALQ_BRCM_B
- HPCVFLNL_BRCM_A
- HPCVFL_BRCM_A
- brcm_freh5
The summary of test results can be seen at
https://github.com/linux-msm/fluster-tests/pull/2/. Test results for
Kodiak (RB3 Gen2) mostly follow results on SM8250.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (9):
media: iris: translate Gen1 profile/level to HFI enumerants
media: iris: account for UBWC extradata in the QC08C buffer size
media: iris: add support for interlaced decoded content
media: iris: split Gen2 firmware data for vpu2-generation SoCs
media: iris: move the decode format list into the firmware data
media: iris: add VP8 decode support on Gen1 firmware
media: iris: add MPEG2 decode support on Gen1 firmware
media: iris: move the encode format list into the firmware data
media: iris: add VP8 encode support on Gen1 firmware
drivers/media/platform/qcom/iris/iris_buffer.c | 3 +-
drivers/media/platform/qcom/iris/iris_ctrls.c | 33 ++-
drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 82 ++++++
.../platform/qcom/iris/iris_hfi_gen1_command.c | 127 +++++++++-
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 51 ++++
.../platform/qcom/iris/iris_hfi_gen1_response.c | 6 +-
drivers/media/platform/qcom/iris/iris_hfi_gen2.c | 279 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_instance.h | 2 +
.../platform/qcom/iris/iris_platform_common.h | 18 +-
.../media/platform/qcom/iris/iris_platform_vpu2.c | 12 +-
.../media/platform/qcom/iris/iris_platform_vpu3x.c | 17 --
.../platform/qcom/iris/iris_platform_vpu_ar50lt.c | 8 -
drivers/media/platform/qcom/iris/iris_vb2.c | 2 -
drivers/media/platform/qcom/iris/iris_vdec.c | 10 +-
drivers/media/platform/qcom/iris/iris_venc.c | 13 +-
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 78 ++++++
drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 6 +
17 files changed, 682 insertions(+), 65 deletions(-)
---
base-commit: b9810cd75b9fb56a3425d391cba3f608502bd474
change-id: 20260708-iris-vp8-8130cdae989d
prerequisite-change-id: 20260507-iris-ar50lt-06228469aa5b:v7
prerequisite-patch-id: 8b5a1be5778fb4c7feb069452ecb60e8b8dfc3f8
prerequisite-patch-id: e669517302297a7b315c9aa4f4189e4928091e0c
prerequisite-patch-id: 922bc325dbd9a499a3a209d2f8dbbce6a4166e60
prerequisite-patch-id: a5a49cda4e21d835558fa84f2f6bd25b8f7e72b4
prerequisite-patch-id: e62e8285bcbddade64c026379f23a8c5ae70fe52
prerequisite-patch-id: cac29b25348e2e791638a0286283109f2546f9a7
prerequisite-patch-id: 4dfaff2f9644d7a168b1b35fe947660b8f464af6
prerequisite-patch-id: a26fa49eefecf2b5ba6cf964be9327eb5ba5929a
prerequisite-patch-id: d97c79463fe1487fa7bc9eebd4cfb4610713f44a
prerequisite-patch-id: 76eafea8230160a3b5e6503c68a5c9c3c2d1497e
prerequisite-patch-id: ea9cd9a8e6561321cd9cf338a76da1382ff47e13
prerequisite-patch-id: 26e9083b709cc8f2f1184edf6b39fb89f365a9f1
prerequisite-patch-id: ce4576bd3d20880939a97a1cda9bb8678808ea65
prerequisite-patch-id: 8c94bec467b385c373bd98eb9ee5a5805fc4e6a6
prerequisite-patch-id: 6e258cd475b77927d6476704cbf91bf48a63aa0d
prerequisite-patch-id: 54c8855d0721ba8667d095e6ad6556c2021f89e9
prerequisite-patch-id: f5479d2ca6b850c0c750944a8e0b05a7df2cc5a8
prerequisite-patch-id: 96dfec1c2df69f748c1a4bd741628e946cb7bec1
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
@ 2026-07-09 19:36 ` Dmitry Baryshkov
2026-08-05 16:11 ` Vishnu Reddy
2026-07-09 19:36 ` [PATCH 2/9] media: iris: account for UBWC extradata in the QC08C buffer size Dmitry Baryshkov
` (8 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:36 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
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 <dmitry.baryshkov@oss.qualcomm.com>
---
.../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 },
+};
+
+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
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/9] media: iris: account for UBWC extradata in the QC08C buffer size
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
2026-07-09 19:36 ` [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants Dmitry Baryshkov
@ 2026-07-09 19:36 ` Dmitry Baryshkov
2026-08-05 15:58 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 3/9] media: iris: add support for interlaced decoded content Dmitry Baryshkov
` (7 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:36 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
iris_yuv_buffer_size_qc08c() sums only the luma/chroma data and metadata
planes. The UBWC engine additionally writes a trailing extradata/scratch
region below the frame, so the computed size is too small for the
reconstruction (DPB) buffer. When the firmware writes that trailing region
it overruns the buffer and triggers an IOMMU fault; this is hit when
decoding interlaced content, where the reconstruction buffers are packed
with a gap after each buffer.
Add the trailing region to the buffer size, sized as the venus driver does
(max of 16K and 48 luma lines).
Fixes: cfd71b14b0d6 ("media: iris: Add support for QC08C format for decoder")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_buffer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index 246ad0abbac3..f1de4442be1f 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -261,7 +261,8 @@ static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst)
uv_plane = ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLINE_ALIGN_QC08C),
PIXELS_4K);
- return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K);
+ return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
+ max_t(u32, SZ_16K, y_stride * 48), PIXELS_4K);
}
/*
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/9] media: iris: add support for interlaced decoded content
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
2026-07-09 19:36 ` [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants Dmitry Baryshkov
2026-07-09 19:36 ` [PATCH 2/9] media: iris: account for UBWC extradata in the QC08C buffer size Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-07-09 19:37 ` [PATCH 4/9] media: iris: split Gen2 firmware data for vpu2-generation SoCs Dmitry Baryshkov
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
The Gen1 firmware can report that a decoded stream is interlaced through
the progressive_only field of HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT. So far
the driver treated any interlaced content as unsupported and moved the
instance to the error state, rejecting otherwise decodable streams.
Stop rejecting interlaced content. Track the interlaced state on the
instance, report V4L2_FIELD_INTERLACED on the capture queue when the
content is interlaced, and skip allocation of the bin (scratch) buffer
in that case, matching the venus driver behaviour. Only genuinely
unsupported content (non-8-bit depth) is still rejected.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 8 +++++++-
drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c | 6 +++++-
drivers/media/platform/qcom/iris/iris_instance.h | 2 ++
drivers/media/platform/qcom/iris/iris_vb2.c | 2 --
drivers/media/platform/qcom/iris/iris_vdec.c | 2 ++
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 7 +++++++
6 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 33a34573391a..c12fe724dfb8 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -517,7 +517,13 @@ int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
u32 work_mode = STAGE_2;
if (inst->domain == DECODER) {
- if (iris_res_is_less_than(width, height, 1280, 720))
+ /*
+ * The two-stage pipeline cannot decode interlaced or MPEG2
+ * content, so fall back to a single stage. Low resolution
+ * content also uses a single stage.
+ */
+ if (inst->is_interlaced ||
+ iris_res_is_less_than(width, height, 1280, 720))
work_mode = STAGE_1;
}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 7ad6f0bb4677..cf2cf31d5b61 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -103,11 +103,15 @@ static void iris_hfi_gen1_read_changed_params(struct iris_inst *inst,
num_properties_changed--;
} while (num_properties_changed > 0);
+ /* pic_struct carries progressive_only: 0 means the content is interlaced */
+ inst->is_interlaced = !event.pic_struct;
+
pixmp_ip->width = event.width;
pixmp_ip->height = event.height;
pixmp_op->width = ALIGN(event.width, 128);
pixmp_op->height = ALIGN(event.height, 32);
+ pixmp_op->field = inst->is_interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
pixmp_op->plane_fmt[0].bytesperline = ALIGN(event.width, 128);
pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
@@ -165,7 +169,7 @@ static void iris_hfi_gen1_read_changed_params(struct iris_inst *inst,
dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
dst_q->min_reqbufs_allocation = inst->buffers[BUF_OUTPUT].min_count;
- if (event.bit_depth || !event.pic_struct) {
+ if (event.bit_depth) {
dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n",
event.bit_depth, event.pic_struct);
iris_inst_change_state(inst, IRIS_INST_ERROR);
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
index ffdbbd20901a..67466b4d0896 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -53,6 +53,7 @@ struct iris_hfi_session_ops;
* @metadata_idx: index for metadata buffer
* @codec: codec type
* @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver
+ * @is_interlaced: a flag to indicate that decoded content is interlaced
* @last_buf_ns: start time of received input buffer for current one second FPS window
* @frame_counter: input buffer counter for current one second FPS window
* @frame_rate: frame rate of current instance
@@ -100,6 +101,7 @@ struct iris_inst {
u32 metadata_idx;
u32 codec;
bool last_buffer_dequeued;
+ bool is_interlaced;
u64 last_buf_ns;
u32 frame_counter;
u32 frame_rate;
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c
index a2ea2d67f60d..28dc269dcf0b 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -260,8 +260,6 @@ int iris_vb2_buf_prepare(struct vb2_buffer *vb)
if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
if (vbuf->field == V4L2_FIELD_ANY)
vbuf->field = V4L2_FIELD_NONE;
- if (vbuf->field != V4L2_FIELD_NONE)
- return -EINVAL;
}
if (!(inst->sub_state & IRIS_INST_SUB_DRC)) {
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
index 9fee5f28097d..9169b1335b5c 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -251,6 +251,7 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
fmt = inst->fmt_src;
fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
+ fmt->fmt.pix_mp.field = f->fmt.pix_mp.field;
inst->codec = fmt->fmt.pix_mp.pixelformat;
codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
@@ -290,6 +291,7 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
fmt = inst->fmt_dst;
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
+ fmt->fmt.pix_mp.field = f->fmt.pix_mp.field;
fmt->fmt.pix_mp.num_planes = 1;
switch (f->fmt.pix_mp.pixelformat) {
case V4L2_PIX_FMT_P010:
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index 00dbb091c54e..88f130d09a6e 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -937,6 +937,13 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst)
u32 height = f->fmt.pix_mp.height;
u32 width = f->fmt.pix_mp.width;
+ /*
+ * The bin (scratch) buffer is not used when decoding interlaced
+ * content.
+ */
+ if (inst->is_interlaced)
+ return 0;
+
if (inst->codec == V4L2_PIX_FMT_H264)
return hfi_buffer_bin_h264d(width, height, num_vpp_pipes);
else if (inst->codec == V4L2_PIX_FMT_HEVC)
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/9] media: iris: split Gen2 firmware data for vpu2-generation SoCs
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (2 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 3/9] media: iris: add support for interlaced decoded content Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-08-05 17:08 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 5/9] media: iris: move the decode format list into the firmware data Dmitry Baryshkov
` (5 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
The single iris_hfi_gen2_data instance is shared by both vpu3x SoCs
(sm8550/sm8650/sm8750/x1p42100), which support AV1, and the vpu2 SoC
sc7280, which does not. This is harmless today because the list of
advertised decode formats is kept separately in the per-SoC platform
data, but it prevents moving those format lists onto the firmware data
where they belong: a shared struct cannot describe both an AV1-capable
and an AV1-incapable generation.
Add a dedicated iris_hfi_gen2_vpu2_data instance for vpu2-generation
SoCs booting Gen2 firmware, using a decode cap table and config
parameter lists with all AV1-specific entries dropped, and point
sc7280's Gen2 firmware descriptor at it. The vpu3x SoCs keep using
iris_hfi_gen2_data unchanged.
No functional change: sc7280 already did not advertise or accept AV1.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_hfi_gen2.c | 247 +++++++++++++++++++++
.../platform/qcom/iris/iris_platform_common.h | 1 +
.../media/platform/qcom/iris/iris_platform_vpu2.c | 2 +-
3 files changed, 249 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
index f89245269e8c..110b5630902f 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
@@ -280,6 +280,189 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = {
},
};
+static const struct platform_inst_fw_cap inst_fw_cap_vpu2_gen2_dec[] = {
+ {
+ .cap_id = PROFILE_H264,
+ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_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_CONSTRAINED_HIGH),
+ .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = PROFILE_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
+ .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = PROFILE_VP9,
+ .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+ .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) |
+ BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2),
+ .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = LEVEL_H264,
+ .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_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) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
+ .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = LEVEL_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+ .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) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
+ .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = LEVEL_VP9,
+ .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0,
+ .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0),
+ .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = TIER,
+ .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
+ .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH),
+ .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+ .hfi_id = HFI_PROP_TIER,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = INPUT_BUF_HOST_MAX_COUNT,
+ .min = DEFAULT_MAX_HOST_BUF_COUNT,
+ .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+ .step_or_mask = 1,
+ .value = DEFAULT_MAX_HOST_BUF_COUNT,
+ .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
+ .flags = CAP_FLAG_INPUT_PORT,
+ .set = iris_set_u32,
+ },
+ {
+ .cap_id = STAGE,
+ .min = STAGE_1,
+ .max = STAGE_2,
+ .step_or_mask = 1,
+ .value = STAGE_2,
+ .hfi_id = HFI_PROP_STAGE,
+ .set = iris_set_stage,
+ },
+ {
+ .cap_id = PIPE,
+ /* .max, .min and .value are set via platform data */
+ .step_or_mask = 1,
+ .hfi_id = HFI_PROP_PIPE,
+ .set = iris_set_pipe,
+ },
+ {
+ .cap_id = POC,
+ .min = 0,
+ .max = 2,
+ .step_or_mask = 1,
+ .value = 1,
+ .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
+ },
+ {
+ .cap_id = CODED_FRAMES,
+ .min = CODED_FRAMES_PROGRESSIVE,
+ .max = CODED_FRAMES_PROGRESSIVE,
+ .step_or_mask = 0,
+ .value = CODED_FRAMES_PROGRESSIVE,
+ .hfi_id = HFI_PROP_CODED_FRAMES,
+ },
+ {
+ .cap_id = BIT_DEPTH,
+ .min = BIT_DEPTH_8,
+ .max = BIT_DEPTH_10,
+ .step_or_mask = 1,
+ .value = BIT_DEPTH_8,
+ .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+ },
+ {
+ .cap_id = RAP_FRAME,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 1,
+ .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
+ .flags = CAP_FLAG_INPUT_PORT,
+ .set = iris_set_u32,
+ },
+};
+
static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
{
.cap_id = PROFILE_H264,
@@ -1119,6 +1302,70 @@ const struct iris_firmware_data iris_hfi_gen2_data = {
.enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
};
+/*
+ * Firmware data for vpu2-generation SoCs (e.g. sc7280) booting Gen2 firmware.
+ * These do not support AV1, so the decode cap table and the config parameters
+ * omit all AV1-specific entries.
+ */
+const struct iris_firmware_data iris_hfi_gen2_vpu2_data = {
+ .init_hfi_ops = iris_hfi_gen2_sys_ops_init,
+
+ .core_arch = VIDEO_ARCH_LX,
+
+ .inst_fw_caps_dec = inst_fw_cap_vpu2_gen2_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_vpu2_gen2_dec),
+ .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
+
+ .dec_input_config_params_default =
+ sm8550_vdec_input_config_params_default,
+ .dec_input_config_params_default_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_params_default),
+ .dec_input_config_params_hevc =
+ sm8550_vdec_input_config_param_hevc,
+ .dec_input_config_params_hevc_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
+ .dec_input_config_params_vp9 =
+ sm8550_vdec_input_config_param_vp9,
+ .dec_input_config_params_vp9_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
+ .dec_output_config_params =
+ sm8550_vdec_output_config_params,
+ .dec_output_config_params_size =
+ ARRAY_SIZE(sm8550_vdec_output_config_params),
+
+ .enc_input_config_params =
+ sm8550_venc_input_config_params,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8550_venc_input_config_params),
+ .enc_output_config_params =
+ sm8550_venc_output_config_params,
+ .enc_output_config_params_size =
+ ARRAY_SIZE(sm8550_venc_output_config_params),
+
+ .dec_input_prop = sm8550_vdec_subscribe_input_properties,
+ .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
+ .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
+ .dec_output_prop_avc_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
+ .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
+ .dec_output_prop_hevc_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
+ .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
+ .dec_output_prop_vp9_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
+
+ .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
+ .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
+
+ .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl,
+ .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl),
+ .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
+ .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
+};
+
static const struct platform_inst_fw_cap inst_fw_cap_gen2_ar50lt_dec[] = {
{
.cap_id = PROFILE_H264,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 5afe395cc4a0..9743573ab083 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -57,6 +57,7 @@ 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_firmware_data iris_hfi_gen2_vpu2_data;
extern const struct iris_firmware_data iris_hfi_gen2_ar50lt_data;
extern const struct iris_platform_data qcm2290_data;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
index e194f67a6f48..8f01cf7f6d49 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
@@ -25,7 +25,7 @@ static const struct iris_firmware_desc iris_vpu20_p1_gen1_desc = {
};
static const struct iris_firmware_desc iris_vpu20_p1_gen2_s6_desc = {
- .firmware_data = &iris_hfi_gen2_data,
+ .firmware_data = &iris_hfi_gen2_vpu2_data,
.get_vpu_buffer_size = iris_vpu33_buf_size,
.fwname = "qcom/vpu/vpu20_p1_gen2_s6.mbn",
};
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/9] media: iris: move the decode format list into the firmware data
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (3 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 4/9] media: iris: split Gen2 firmware data for vpu2-generation SoCs Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-08-26 4:09 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 6/9] media: iris: add VP8 decode support on Gen1 firmware Dmitry Baryshkov
` (4 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
The set of supported coded formats depends on the firmware generation:
a single SoC can boot either Gen1 or Gen2 firmware, and some codecs are
only supported by one generation. The decode format list was however
kept per-SoC in iris_platform_data::inst_iris_fmts, which is too coarse
to express this - a per-SoC list cannot describe the two different format
sets the same SoC exposes depending on which firmware it booted.
Move the decode format list into struct iris_firmware_data, which is
already selected per firmware generation, and drop the per-SoC
inst_iris_fmts field. Each firmware data instance now carries the exact
set of decode formats its generation supports, so the formats advertised
to userspace always match the running firmware.
No functional change: every SoC advertises the same decode formats as
before.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 12 ++++++++++++
drivers/media/platform/qcom/iris/iris_hfi_gen2.c | 21 +++++++++++++++++++++
.../media/platform/qcom/iris/iris_platform_common.h | 12 ++++++++++--
.../media/platform/qcom/iris/iris_platform_vpu2.c | 10 ----------
.../media/platform/qcom/iris/iris_platform_vpu3x.c | 17 -----------------
.../platform/qcom/iris/iris_platform_vpu_ar50lt.c | 8 --------
drivers/media/platform/qcom/iris/iris_vdec.c | 8 ++++----
7 files changed, 47 insertions(+), 41 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
index 4f205757647a..8119c639ec24 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
@@ -419,6 +419,12 @@ static const u32 sm8250_enc_ip_int_buf_tbl[] = {
BUF_SCRATCH_2,
};
+static const u32 iris_hfi_gen1_dec_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
+ V4L2_PIX_FMT_VP9,
+};
+
const struct iris_firmware_data iris_hfi_gen1_data = {
.init_hfi_ops = &iris_hfi_gen1_sys_ops_init,
@@ -427,6 +433,9 @@ const struct iris_firmware_data iris_hfi_gen1_data = {
.inst_fw_caps_enc = inst_fw_cap_sm8250_enc,
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc),
+ .dec_fmts = iris_hfi_gen1_dec_fmts,
+ .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
+
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
.dec_input_config_params_default_size =
@@ -668,6 +677,9 @@ const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
.inst_fw_caps_enc = inst_fw_cap_gen1_ar50lt_enc,
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen1_ar50lt_enc),
+ .dec_fmts = iris_hfi_gen1_dec_fmts,
+ .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
+
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
.dec_input_config_params_default_size =
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
index 110b5630902f..6c1d562ab8c2 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
@@ -1236,6 +1236,19 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = {
BUF_SCRATCH_2,
};
+static const u32 iris_hfi_gen2_dec_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
+ V4L2_PIX_FMT_VP9,
+ V4L2_PIX_FMT_AV1,
+};
+
+static const u32 iris_hfi_gen2_vpu2_dec_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
+ V4L2_PIX_FMT_VP9,
+};
+
const struct iris_firmware_data iris_hfi_gen2_data = {
.init_hfi_ops = iris_hfi_gen2_sys_ops_init,
@@ -1246,6 +1259,9 @@ const struct iris_firmware_data iris_hfi_gen2_data = {
.inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
+ .dec_fmts = iris_hfi_gen2_dec_fmts,
+ .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_dec_fmts),
+
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.dec_input_config_params_default_size =
@@ -1317,6 +1333,9 @@ const struct iris_firmware_data iris_hfi_gen2_vpu2_data = {
.inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
+ .dec_fmts = iris_hfi_gen2_vpu2_dec_fmts,
+ .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_vpu2_dec_fmts),
+
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.dec_input_config_params_default_size =
@@ -1934,6 +1953,8 @@ const struct iris_firmware_data iris_hfi_gen2_ar50lt_data = {
.inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_gen2_ar50lt_dec),
.inst_fw_caps_enc = inst_fw_cap_gen2_ar50lt_enc,
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen2_ar50lt_enc),
+ .dec_fmts = iris_hfi_gen2_vpu2_dec_fmts,
+ .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_vpu2_dec_fmts),
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.dec_input_config_params_default_size =
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 9743573ab083..317ba48e6305 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -255,6 +255,16 @@ struct iris_firmware_data {
const struct platform_inst_fw_cap *inst_fw_caps_enc;
u32 inst_fw_caps_enc_size;
+ /*
+ * List of coded formats supported by this firmware generation, used to
+ * advertise decode (bitstream) formats to userspace. This lives in the
+ * firmware data because a single SoC can boot either firmware
+ * generation, and some codecs (e.g. VP8, MPEG2, AV1) are only supported
+ * by one generation.
+ */
+ const u32 *dec_fmts;
+ unsigned int dec_fmts_size;
+
const u32 *dec_input_config_params_default;
unsigned int dec_input_config_params_default_size;
const u32 *dec_input_config_params_hevc;
@@ -317,8 +327,6 @@ struct iris_platform_data {
const char * const *controller_rst_tbl;
unsigned int controller_rst_tbl_size;
u64 dma_mask;
- const u32 *inst_iris_fmts;
- u32 inst_iris_fmts_size;
struct platform_inst_caps *inst_caps;
const struct tz_cp_config *tz_cp_config_data;
u32 tz_cp_config_data_size;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
index 8f01cf7f6d49..37aee82a49f4 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
@@ -36,12 +36,6 @@ static const struct iris_firmware_desc iris_vpu20_p4_gen1_desc = {
.fwname = "qcom/vpu/vpu20_p4.mbn",
};
-static const u32 iris_fmts_vpu2_dec[] = {
- V4L2_PIX_FMT_H264,
- V4L2_PIX_FMT_HEVC,
- V4L2_PIX_FMT_VP9,
-};
-
static struct platform_inst_caps platform_inst_cap_vpu2 = {
.min_frame_width = 128,
.max_frame_width = 8192,
@@ -89,8 +83,6 @@ const struct iris_platform_data sc7280_data = {
.opp_clk_tbl = sc7280_opp_clk_table,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu2_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec),
.inst_caps = &platform_inst_cap_vpu2,
.tz_cp_config_data = tz_cp_config_vpu2,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
@@ -122,8 +114,6 @@ const struct iris_platform_data sm8250_data = {
.opp_clk_tbl = sm8250_opp_clk_table,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu2_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec),
.inst_caps = &platform_inst_cap_vpu2,
.tz_cp_config_data = tz_cp_config_vpu2,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
index b8099d7ce556..30c95621fa0e 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
@@ -50,13 +50,6 @@ static const struct iris_firmware_desc iris_vpu35_p4_gen2_desc = {
.fwname = "qcom/vpu/vpu35_p4.mbn",
};
-static const u32 iris_fmts_vpu3x_dec[] = {
- V4L2_PIX_FMT_H264,
- V4L2_PIX_FMT_HEVC,
- V4L2_PIX_FMT_VP9,
- V4L2_PIX_FMT_AV1,
-};
-
static const struct icc_info iris_icc_info_vpu3x[] = {
{ "cpu-cfg", 1000, 1000 },
{ "video-mem", 1000, 15000000 },
@@ -109,8 +102,6 @@ const struct iris_platform_data qcs8300_data = {
.opp_clk_tbl = iris_opp_clk_table_vpu3x,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu3x_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_qcs8300,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
@@ -140,8 +131,6 @@ const struct iris_platform_data sm8550_data = {
.opp_clk_tbl = iris_opp_clk_table_vpu3x,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu3x_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
@@ -179,8 +168,6 @@ const struct iris_platform_data sm8650_data = {
.opp_clk_tbl = iris_opp_clk_table_vpu3x,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu3x_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
@@ -210,8 +197,6 @@ const struct iris_platform_data sm8750_data = {
.opp_clk_tbl = iris_opp_clk_table_vpu3x,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu3x_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
@@ -247,8 +232,6 @@ const struct iris_platform_data x1p42100_data = {
.opp_clk_tbl = x1p42100_opp_clk_table,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_vpu3x_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
index 99c839a0424f..e569817a0c80 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
@@ -25,12 +25,6 @@ static const struct iris_firmware_desc iris_vpu_ar50lt_p1_gen2_s6_desc = {
.fwname = "qcom/vpu/ar50lt_p1_gen2_s6.mbn",
};
-static const u32 iris_fmts_ar50lt_dec[] = {
- V4L2_PIX_FMT_H264,
- V4L2_PIX_FMT_HEVC,
- V4L2_PIX_FMT_VP9,
-};
-
static const struct bw_info iris_bw_table_dec_ar50lt[] = {
{ ((1920 * 1080) / 256) * 60, 1564000, },
{ ((1920 * 1080) / 256) * 30, 791000, },
@@ -100,8 +94,6 @@ const struct iris_platform_data qcm2290_data = {
.opp_clk_tbl = iris_opp_clk_table_ar50lt,
/* Upper bound of DMA address range */
.dma_mask = 0xe0000000 - 1,
- .inst_iris_fmts = iris_fmts_ar50lt_dec,
- .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_ar50lt_dec),
.inst_caps = &platform_inst_cap_ar50lt,
.tz_cp_config_data = tz_cp_config_ar50lt,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_ar50lt),
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
index 9169b1335b5c..59200ca72ded 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -83,8 +83,8 @@ static bool check_format(struct iris_inst *inst, u32 pixfmt, u32 type)
switch (type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- fmt = inst->core->iris_platform_data->inst_iris_fmts;
- size = inst->core->iris_platform_data->inst_iris_fmts_size;
+ fmt = inst->core->iris_firmware_data->dec_fmts;
+ size = inst->core->iris_firmware_data->dec_fmts_size;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (ubwc->ubwc_enc_version) {
@@ -128,8 +128,8 @@ static u32 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
switch (type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- fmt = inst->core->iris_platform_data->inst_iris_fmts;
- size = inst->core->iris_platform_data->inst_iris_fmts_size;
+ fmt = inst->core->iris_firmware_data->dec_fmts;
+ size = inst->core->iris_firmware_data->dec_fmts_size;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (ubwc->ubwc_enc_version) {
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 6/9] media: iris: add VP8 decode support on Gen1 firmware
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (4 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 5/9] media: iris: move the decode format list into the firmware data Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-08-26 4:18 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 7/9] media: iris: add MPEG2 " Dmitry Baryshkov
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
The Gen1 firmware supports decoding VP8, but the iris driver never
advertised or wired up the codec.
Add the VP8 HFI codec code, map V4L2_PIX_FMT_VP8 to it in the Gen1
session open path, and compute the VP8 internal buffer sizes (bin,
collocated motion vector, line and probability-table persist buffers,
which reuse the shared VPX helpers). Advertise the codec through the
Gen1 decode format list and register the VP8 profile menu control.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 7 +++
drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 22 +++++++-
.../platform/qcom/iris/iris_hfi_gen1_command.c | 3 +
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 1 +
.../platform/qcom/iris/iris_platform_common.h | 1 +
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 64 ++++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 3 +
7 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index c12fe724dfb8..1bd6460a1b0a 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -28,6 +28,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return PROFILE_HEVC;
case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
return PROFILE_VP9;
+ case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
+ return PROFILE_VP8;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
return LEVEL_H264;
case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
@@ -171,6 +173,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
case PROFILE_VP9:
return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
+ case PROFILE_VP8:
+ return V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
case LEVEL_H264:
return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
case LEVEL_HEVC:
@@ -558,6 +562,9 @@ int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_
if (inst->codec == V4L2_PIX_FMT_H264) {
hfi_id = inst->fw_caps[PROFILE_H264].hfi_id;
hfi_value = inst->fw_caps[PROFILE_H264].value;
+ } else if (inst->codec == V4L2_PIX_FMT_VP8) {
+ hfi_id = inst->fw_caps[PROFILE_VP8].hfi_id;
+ hfi_value = inst->fw_caps[PROFILE_VP8].value;
} else {
hfi_id = inst->fw_caps[PROFILE_HEVC].hfi_id;
hfi_value = inst->fw_caps[PROFILE_HEVC].value;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
index 8119c639ec24..4c3aa5a03ddd 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
@@ -30,6 +30,17 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = {
.hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
.set = iris_set_stage,
},
+ {
+ .cap_id = PROFILE_VP8,
+ .min = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+ .max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_0) |
+ BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_1) |
+ BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_2) |
+ BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_3),
+ .value = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+ .flags = CAP_FLAG_MENU,
+ },
};
static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
@@ -423,6 +434,13 @@ static const u32 iris_hfi_gen1_dec_fmts[] = {
V4L2_PIX_FMT_H264,
V4L2_PIX_FMT_HEVC,
V4L2_PIX_FMT_VP9,
+ V4L2_PIX_FMT_VP8,
+};
+
+static const u32 iris_hfi_gen1_ar50lt_dec_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
+ V4L2_PIX_FMT_VP9,
};
const struct iris_firmware_data iris_hfi_gen1_data = {
@@ -677,8 +695,8 @@ const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
.inst_fw_caps_enc = inst_fw_cap_gen1_ar50lt_enc,
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen1_ar50lt_enc),
- .dec_fmts = iris_hfi_gen1_dec_fmts,
- .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
+ .dec_fmts = iris_hfi_gen1_ar50lt_dec_fmts,
+ .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_ar50lt_dec_fmts),
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
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 ed9fef2aec08..90645ed3e0d8 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -105,6 +105,9 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst)
case V4L2_PIX_FMT_HEVC:
codec = HFI_VIDEO_CODEC_HEVC;
break;
+ case V4L2_PIX_FMT_VP8:
+ codec = HFI_VIDEO_CODEC_VP8;
+ break;
case V4L2_PIX_FMT_VP9:
codec = HFI_VIDEO_CODEC_VP9;
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 2702f255bc04..13c8ff59d6e4 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -14,6 +14,7 @@
#define HFI_SESSION_TYPE_DEC 2
#define HFI_VIDEO_CODEC_H264 0x00000002
+#define HFI_VIDEO_CODEC_VP8 0x00001000
#define HFI_VIDEO_CODEC_HEVC 0x00002000
#define HFI_VIDEO_CODEC_VP9 0x00004000
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 317ba48e6305..84017b66e98f 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -115,6 +115,7 @@ enum platform_inst_fw_cap_type {
PROFILE_H264 = 1,
PROFILE_HEVC,
PROFILE_VP9,
+ PROFILE_VP8,
LEVEL_H264,
LEVEL_HEVC,
LEVEL_VP9,
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index 88f130d09a6e..ca90414e6c19 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -293,6 +293,11 @@ static u32 hfi_buffer_persist_vp9d(void)
HDR10_HIST_EXTRADATA_SIZE;
}
+static u32 hfi_buffer_persist_vp8d(void)
+{
+ return ALIGN(VP8_NUM_PROBABILITY_TABLE_BUF * VP8_PROB_TABLE_SIZE, DMA_ALIGNMENT);
+}
+
static u32 hfi_buffer_persist_vp9d_ar50lt(void)
{
return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) +
@@ -715,6 +720,57 @@ u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_mi
return _lb_size + vpss_lb_size + 4096;
}
+static inline
+u32 size_vp8d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+ return (ALIGN(frame_width, 16) + 8) * 10 * 2;
+}
+
+static inline
+u32 size_vp8d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+ return (ALIGN(frame_width, 16) >> 4) * 64;
+}
+
+static inline
+u32 size_vp8d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+ return ((ALIGN(frame_width, 16) >> 4) * 64 / 2) + 256;
+}
+
+static inline
+u32 hfi_iris_vp8d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
+{
+ return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * num_vpp_pipes +
+ ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * num_vpp_pipes +
+ ALIGN(size_vp8d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) +
+ ALIGN(size_vpxd_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
+ 2 * ALIGN(size_vpxd_lb_recon_dma_metadata_wr(frame_width, frame_height), DMA_ALIGNMENT) +
+ ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
+ ALIGN(size_vp8d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) +
+ ALIGN(size_vp8d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT);
+}
+
+static inline
+u32 hfi_buffer_line_vp8d(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes)
+{
+ u32 vpss_lb_size = 0;
+ u32 _lb_size;
+
+ _lb_size = hfi_iris_vp8d_lb_size(frame_width, frame_height, num_vpp_pipes);
+
+ if (is_opb)
+ vpss_lb_size = size_vpss_lb(frame_width, frame_height);
+
+ return _lb_size + vpss_lb_size;
+}
+
+static inline
+u32 hfi_iris_vp8d_comv_size(u32 frame_width, u32 frame_height)
+{
+ return DIV_ROUND_UP(frame_width, 16) * DIV_ROUND_UP(frame_height, 16) * 8 * 2;
+}
+
static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
bool is_opb, u32 num_vpp_pipes)
{
@@ -950,6 +1006,8 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst)
return hfi_buffer_bin_h265d(width, height, num_vpp_pipes);
else if (inst->codec == V4L2_PIX_FMT_VP9)
return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes);
+ else if (inst->codec == V4L2_PIX_FMT_VP8)
+ return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes);
else if (inst->codec == V4L2_PIX_FMT_AV1)
return hfi_buffer_bin_av1d(width, height, num_vpp_pipes);
@@ -983,6 +1041,8 @@ static u32 iris_vpu_dec_comv_size(struct iris_inst *inst)
return hfi_buffer_comv_h264d(width, height, num_comv);
else if (inst->codec == V4L2_PIX_FMT_HEVC)
return hfi_buffer_comv_h265d(width, height, num_comv);
+ else if (inst->codec == V4L2_PIX_FMT_VP8)
+ return hfi_iris_vp8d_comv_size(width, height);
return 0;
}
@@ -1021,6 +1081,8 @@ static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
return hfi_buffer_persist_h265d(0);
else if (inst->codec == V4L2_PIX_FMT_VP9)
return hfi_buffer_persist_vp9d();
+ else if (inst->codec == V4L2_PIX_FMT_VP8)
+ return hfi_buffer_persist_vp8d();
else if (inst->codec == V4L2_PIX_FMT_AV1) {
caps = inst->core->iris_platform_data->inst_caps;
if (inst->fw_caps[DRAP].value)
@@ -1101,6 +1163,8 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
else if (inst->codec == V4L2_PIX_FMT_VP9)
return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb,
num_vpp_pipes);
+ else if (inst->codec == V4L2_PIX_FMT_VP8)
+ return hfi_buffer_line_vp8d(width, height, is_opb, num_vpp_pipes);
else if (inst->codec == V4L2_PIX_FMT_AV1)
return hfi_buffer_line_av1d(width, height, is_opb, num_vpp_pipes);
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
index 2085e316a6bd..684b459c0cad 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -66,6 +66,9 @@ struct iris_inst;
#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT (32 / 8)
#define VP9_UDC_HEADER_BUF_SIZE (3 * 128)
+#define VP8_NUM_PROBABILITY_TABLE_BUF (5 + 1)
+#define VP8_PROB_TABLE_SIZE (3840)
+
#define SIZE_SEI_USERDATA 4096
#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
#define H264_CABAC_HDR_RATIO_HD_TOT 1
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 7/9] media: iris: add MPEG2 decode support on Gen1 firmware
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (5 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 6/9] media: iris: add VP8 decode support on Gen1 firmware Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-08-26 4:50 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 8/9] media: iris: move the encode format list into the firmware data Dmitry Baryshkov
` (2 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
The Gen1 firmware supports decoding MPEG2, but the iris driver never
advertised or wired up the codec.
Add the MPEG2 HFI codec code, map V4L2_PIX_FMT_MPEG2 to it in the Gen1
session open path, and compute the MPEG2 internal buffer sizes (line
buffer and the quantisation-matrix / QP-dump persist buffer). Advertise
the codec through the new Gen1 decode format list and register the MPEG2
profile and level menu controls so userspace can query them.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 15 ++++++++++++++
drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 24 ++++++++++++++++++++++
.../platform/qcom/iris/iris_hfi_gen1_command.c | 3 +++
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 1 +
.../platform/qcom/iris/iris_platform_common.h | 2 ++
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 9 +++++++-
drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 3 +++
7 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 1bd6460a1b0a..8f9347c1df2b 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -30,12 +30,16 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return PROFILE_VP9;
case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
return PROFILE_VP8;
+ case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
+ return PROFILE_MPEG2;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
return LEVEL_H264;
case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
return LEVEL_HEVC;
case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
return LEVEL_VP9;
+ case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
+ return LEVEL_MPEG2;
case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
return TIER;
case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
@@ -175,12 +179,16 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
case PROFILE_VP8:
return V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
+ case PROFILE_MPEG2:
+ return V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE;
case LEVEL_H264:
return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
case LEVEL_HEVC:
return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
case LEVEL_VP9:
return V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
+ case LEVEL_MPEG2:
+ return V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL;
case TIER:
return V4L2_CID_MPEG_VIDEO_HEVC_TIER;
case HEADER_MODE:
@@ -527,6 +535,7 @@ int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
* content also uses a single stage.
*/
if (inst->is_interlaced ||
+ inst->codec == V4L2_PIX_FMT_MPEG2 ||
iris_res_is_less_than(width, height, 1280, 720))
work_mode = STAGE_1;
}
@@ -565,6 +574,9 @@ int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_
} else if (inst->codec == V4L2_PIX_FMT_VP8) {
hfi_id = inst->fw_caps[PROFILE_VP8].hfi_id;
hfi_value = inst->fw_caps[PROFILE_VP8].value;
+ } else if (inst->codec == V4L2_PIX_FMT_MPEG2) {
+ hfi_id = inst->fw_caps[PROFILE_MPEG2].hfi_id;
+ hfi_value = inst->fw_caps[PROFILE_MPEG2].value;
} else {
hfi_id = inst->fw_caps[PROFILE_HEVC].hfi_id;
hfi_value = inst->fw_caps[PROFILE_HEVC].value;
@@ -585,6 +597,9 @@ int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
if (inst->codec == V4L2_PIX_FMT_H264) {
hfi_id = inst->fw_caps[LEVEL_H264].hfi_id;
hfi_value = inst->fw_caps[LEVEL_H264].value;
+ } else if (inst->codec == V4L2_PIX_FMT_MPEG2) {
+ hfi_id = inst->fw_caps[LEVEL_MPEG2].hfi_id;
+ hfi_value = inst->fw_caps[LEVEL_MPEG2].value;
} else {
hfi_id = inst->fw_caps[LEVEL_HEVC].hfi_id;
hfi_value = inst->fw_caps[LEVEL_HEVC].value;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
index 4c3aa5a03ddd..4b05c2a47b0b 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
@@ -41,6 +41,29 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = {
.value = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
.flags = CAP_FLAG_MENU,
},
+ {
+ .cap_id = PROFILE_MPEG2,
+ .min = V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE,
+ .max = V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH),
+ .value = V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN,
+ .flags = CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = LEVEL_MPEG2,
+ .min = V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW,
+ .max = V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440) |
+ BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH),
+ .value = V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN,
+ .flags = CAP_FLAG_MENU,
+ },
};
static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
@@ -435,6 +458,7 @@ static const u32 iris_hfi_gen1_dec_fmts[] = {
V4L2_PIX_FMT_HEVC,
V4L2_PIX_FMT_VP9,
V4L2_PIX_FMT_VP8,
+ V4L2_PIX_FMT_MPEG2,
};
static const u32 iris_hfi_gen1_ar50lt_dec_fmts[] = {
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 90645ed3e0d8..53ba48f88410 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -111,6 +111,9 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst)
case V4L2_PIX_FMT_VP9:
codec = HFI_VIDEO_CODEC_VP9;
break;
+ case V4L2_PIX_FMT_MPEG2:
+ codec = HFI_VIDEO_CODEC_MPEG2;
+ break;
}
packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
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 13c8ff59d6e4..3c8ae1c82540 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -14,6 +14,7 @@
#define HFI_SESSION_TYPE_DEC 2
#define HFI_VIDEO_CODEC_H264 0x00000002
+#define HFI_VIDEO_CODEC_MPEG2 0x00000010
#define HFI_VIDEO_CODEC_VP8 0x00001000
#define HFI_VIDEO_CODEC_HEVC 0x00002000
#define HFI_VIDEO_CODEC_VP9 0x00004000
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 84017b66e98f..3d631effe307 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -116,9 +116,11 @@ enum platform_inst_fw_cap_type {
PROFILE_HEVC,
PROFILE_VP9,
PROFILE_VP8,
+ PROFILE_MPEG2,
LEVEL_H264,
LEVEL_HEVC,
LEVEL_VP9,
+ LEVEL_MPEG2,
PROFILE_AV1,
LEVEL_AV1,
TIER_AV1,
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index ca90414e6c19..c16e2b652cf4 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -298,6 +298,11 @@ static u32 hfi_buffer_persist_vp8d(void)
return ALIGN(VP8_NUM_PROBABILITY_TABLE_BUF * VP8_PROB_TABLE_SIZE, DMA_ALIGNMENT);
}
+static u32 hfi_buffer_persist_mpeg2d(void)
+{
+ return QMATRIX_SIZE + MP2D_QPDUMP_SIZE;
+}
+
static u32 hfi_buffer_persist_vp9d_ar50lt(void)
{
return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) +
@@ -1083,6 +1088,8 @@ static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
return hfi_buffer_persist_vp9d();
else if (inst->codec == V4L2_PIX_FMT_VP8)
return hfi_buffer_persist_vp8d();
+ else if (inst->codec == V4L2_PIX_FMT_MPEG2)
+ return hfi_buffer_persist_mpeg2d();
else if (inst->codec == V4L2_PIX_FMT_AV1) {
caps = inst->core->iris_platform_data->inst_caps;
if (inst->fw_caps[DRAP].value)
@@ -1163,7 +1170,7 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
else if (inst->codec == V4L2_PIX_FMT_VP9)
return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb,
num_vpp_pipes);
- else if (inst->codec == V4L2_PIX_FMT_VP8)
+ else if (inst->codec == V4L2_PIX_FMT_VP8 || inst->codec == V4L2_PIX_FMT_MPEG2)
return hfi_buffer_line_vp8d(width, height, is_opb, num_vpp_pipes);
else if (inst->codec == V4L2_PIX_FMT_AV1)
return hfi_buffer_line_av1d(width, height, is_opb, num_vpp_pipes);
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
index 684b459c0cad..4694467677f6 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -69,6 +69,9 @@ struct iris_inst;
#define VP8_NUM_PROBABILITY_TABLE_BUF (5 + 1)
#define VP8_PROB_TABLE_SIZE (3840)
+#define QMATRIX_SIZE (sizeof(u32) * 128 + 256)
+#define MP2D_QPDUMP_SIZE (115200)
+
#define SIZE_SEI_USERDATA 4096
#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
#define H264_CABAC_HDR_RATIO_HD_TOT 1
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 8/9] media: iris: move the encode format list into the firmware data
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (6 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 7/9] media: iris: add MPEG2 " Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-07-09 19:37 ` [PATCH 9/9] media: iris: add VP8 encode support on Gen1 firmware Dmitry Baryshkov
2026-07-30 22:52 ` [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
9 siblings, 0 replies; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
Like the decode format list, the set of supported encode formats depends
on the firmware generation, but it was kept in the encoder's built-in
iris_venc_formats_cap[] array. A single static array cannot describe the
different format sets the same SoC exposes depending on which firmware it
booted.
Move the encode format list into struct iris_firmware_data next to the
decode list, and drop the static iris_venc_formats_cap[] array. Each
firmware data instance now carries the exact set of encode formats its
generation supports, so the formats advertised to userspace always match
the running firmware.
No functional change: every SoC advertises the same encode formats as
before.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 9 +++++++++
drivers/media/platform/qcom/iris/iris_hfi_gen2.c | 11 +++++++++++
drivers/media/platform/qcom/iris/iris_platform_common.h | 12 +++++++-----
drivers/media/platform/qcom/iris/iris_venc.c | 13 ++++---------
4 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
index 4b05c2a47b0b..0451ee321840 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
@@ -467,6 +467,11 @@ static const u32 iris_hfi_gen1_ar50lt_dec_fmts[] = {
V4L2_PIX_FMT_VP9,
};
+static const u32 iris_hfi_gen1_enc_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
+};
+
const struct iris_firmware_data iris_hfi_gen1_data = {
.init_hfi_ops = &iris_hfi_gen1_sys_ops_init,
@@ -477,6 +482,8 @@ const struct iris_firmware_data iris_hfi_gen1_data = {
.dec_fmts = iris_hfi_gen1_dec_fmts,
.dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
+ .enc_fmts = iris_hfi_gen1_enc_fmts,
+ .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen1_enc_fmts),
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
@@ -721,6 +728,8 @@ const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
.dec_fmts = iris_hfi_gen1_ar50lt_dec_fmts,
.dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_ar50lt_dec_fmts),
+ .enc_fmts = iris_hfi_gen1_enc_fmts,
+ .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen1_enc_fmts),
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
index 6c1d562ab8c2..665de0275a0b 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
@@ -1249,6 +1249,11 @@ static const u32 iris_hfi_gen2_vpu2_dec_fmts[] = {
V4L2_PIX_FMT_VP9,
};
+static const u32 iris_hfi_gen2_enc_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
+};
+
const struct iris_firmware_data iris_hfi_gen2_data = {
.init_hfi_ops = iris_hfi_gen2_sys_ops_init,
@@ -1261,6 +1266,8 @@ const struct iris_firmware_data iris_hfi_gen2_data = {
.dec_fmts = iris_hfi_gen2_dec_fmts,
.dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_dec_fmts),
+ .enc_fmts = iris_hfi_gen2_enc_fmts,
+ .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen2_enc_fmts),
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
@@ -1335,6 +1342,8 @@ const struct iris_firmware_data iris_hfi_gen2_vpu2_data = {
.dec_fmts = iris_hfi_gen2_vpu2_dec_fmts,
.dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_vpu2_dec_fmts),
+ .enc_fmts = iris_hfi_gen2_enc_fmts,
+ .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen2_enc_fmts),
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
@@ -1955,6 +1964,8 @@ const struct iris_firmware_data iris_hfi_gen2_ar50lt_data = {
.inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen2_ar50lt_enc),
.dec_fmts = iris_hfi_gen2_vpu2_dec_fmts,
.dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_vpu2_dec_fmts),
+ .enc_fmts = iris_hfi_gen2_enc_fmts,
+ .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen2_enc_fmts),
.dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
.dec_input_config_params_default_size =
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 3d631effe307..7e670d04c10c 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -259,14 +259,16 @@ struct iris_firmware_data {
u32 inst_fw_caps_enc_size;
/*
- * List of coded formats supported by this firmware generation, used to
- * advertise decode (bitstream) formats to userspace. This lives in the
- * firmware data because a single SoC can boot either firmware
- * generation, and some codecs (e.g. VP8, MPEG2, AV1) are only supported
- * by one generation.
+ * Lists of coded formats supported by this firmware generation, used
+ * to advertise decode (bitstream) and encode (capture) formats to
+ * userspace. These live in the firmware data because a single SoC can
+ * boot either firmware generation, and some codecs (e.g. VP8, MPEG2,
+ * AV1) are only supported by one generation.
*/
const u32 *dec_fmts;
unsigned int dec_fmts_size;
+ const u32 *enc_fmts;
+ unsigned int enc_fmts_size;
const u32 *dec_input_config_params_default;
unsigned int dec_input_config_params_default_size;
diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c
index 2f2c56bf9122..91749e580d5b 100644
--- a/drivers/media/platform/qcom/iris/iris_venc.c
+++ b/drivers/media/platform/qcom/iris/iris_venc.c
@@ -80,11 +80,6 @@ int iris_venc_inst_init(struct iris_inst *inst)
return iris_ctrls_init(inst);
}
-static const u32 iris_venc_formats_cap[] = {
- V4L2_PIX_FMT_H264,
- V4L2_PIX_FMT_HEVC,
-};
-
static const u32 iris_venc_formats_out[] = {
V4L2_PIX_FMT_NV12,
V4L2_PIX_FMT_QC08C,
@@ -111,8 +106,8 @@ static bool check_format(struct iris_inst *inst, u32 pixfmt, u32 type)
}
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- fmt = iris_venc_formats_cap;
- size = ARRAY_SIZE(iris_venc_formats_cap);
+ fmt = inst->core->iris_firmware_data->enc_fmts;
+ size = inst->core->iris_firmware_data->enc_fmts_size;
break;
default:
return false;
@@ -143,8 +138,8 @@ static u32 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
}
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- fmt = iris_venc_formats_cap;
- size = ARRAY_SIZE(iris_venc_formats_cap);
+ fmt = inst->core->iris_firmware_data->enc_fmts;
+ size = inst->core->iris_firmware_data->enc_fmts_size;
break;
default:
return 0;
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 9/9] media: iris: add VP8 encode support on Gen1 firmware
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (7 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 8/9] media: iris: move the encode format list into the firmware data Dmitry Baryshkov
@ 2026-07-09 19:37 ` Dmitry Baryshkov
2026-07-30 22:52 ` [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
9 siblings, 0 replies; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 19:37 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
The Gen1 firmware supports encoding VP8, but the iris driver never
advertised or wired up the codec.
Advertise VP8 through the Gen1 encode format list and register the VP8
profile control, sending the profile to the firmware through the
profile/level property. VP8 has no level, so only the profile is set.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 3 +++
drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 23 ++++++++++++++++++++--
.../platform/qcom/iris/iris_hfi_gen1_command.c | 12 +++++++++++
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 5 +++++
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 8f9347c1df2b..c065ebc24d7d 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -621,6 +621,9 @@ int iris_set_profile_level_gen1(struct iris_inst *inst, enum platform_inst_fw_ca
if (inst->codec == V4L2_PIX_FMT_H264) {
pl.profile = inst->fw_caps[PROFILE_H264].value;
pl.level = inst->fw_caps[LEVEL_H264].value;
+ } else if (inst->codec == V4L2_PIX_FMT_VP8) {
+ pl.profile = inst->fw_caps[PROFILE_VP8].value;
+ pl.level = 0;
} else {
pl.profile = inst->fw_caps[PROFILE_HEVC].value;
pl.level = inst->fw_caps[LEVEL_HEVC].value;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
index 0451ee321840..b3c567349a6b 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
@@ -150,6 +150,19 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
.flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
.set = iris_set_profile_level_gen1,
},
+ {
+ .cap_id = PROFILE_VP8,
+ .min = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+ .max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_0) |
+ BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_1) |
+ BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_2) |
+ BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_3),
+ .value = V4L2_MPEG_VIDEO_VP8_PROFILE_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 = HEADER_MODE,
.min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
@@ -470,6 +483,12 @@ static const u32 iris_hfi_gen1_ar50lt_dec_fmts[] = {
static const u32 iris_hfi_gen1_enc_fmts[] = {
V4L2_PIX_FMT_H264,
V4L2_PIX_FMT_HEVC,
+ V4L2_PIX_FMT_VP8,
+};
+
+static const u32 iris_hfi_gen1_ar50lt_enc_fmts[] = {
+ V4L2_PIX_FMT_H264,
+ V4L2_PIX_FMT_HEVC,
};
const struct iris_firmware_data iris_hfi_gen1_data = {
@@ -728,8 +747,8 @@ const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
.dec_fmts = iris_hfi_gen1_ar50lt_dec_fmts,
.dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_ar50lt_dec_fmts),
- .enc_fmts = iris_hfi_gen1_enc_fmts,
- .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen1_enc_fmts),
+ .enc_fmts = iris_hfi_gen1_ar50lt_enc_fmts,
+ .enc_fmts_size = ARRAY_SIZE(iris_hfi_gen1_ar50lt_enc_fmts),
.dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
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 53ba48f88410..c652c61db19d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -542,6 +542,13 @@ static const struct iris_hfi_gen1_id_mapping iris_hfi_gen1_hevc_levels[] = {
{ HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 },
};
+static const struct iris_hfi_gen1_id_mapping iris_hfi_gen1_vp8_profiles[] = {
+ { HFI_VPX_PROFILE_VERSION_0, V4L2_MPEG_VIDEO_VP8_PROFILE_0 },
+ { HFI_VPX_PROFILE_VERSION_1, V4L2_MPEG_VIDEO_VP8_PROFILE_1 },
+ { HFI_VPX_PROFILE_VERSION_2, V4L2_MPEG_VIDEO_VP8_PROFILE_2 },
+ { HFI_VPX_PROFILE_VERSION_3, V4L2_MPEG_VIDEO_VP8_PROFILE_3 },
+};
+
static u32 iris_hfi_gen1_find_hfi_id(u32 v4l2_id,
const struct iris_hfi_gen1_id_mapping *array,
unsigned int array_sz)
@@ -577,6 +584,11 @@ iris_hfi_gen1_profile_level(struct iris_inst *inst, u32 v4l2_pf, u32 v4l2_lvl,
pl->level = iris_hfi_gen1_find_hfi_id(v4l2_lvl, iris_hfi_gen1_hevc_levels,
ARRAY_SIZE(iris_hfi_gen1_hevc_levels));
break;
+ case V4L2_PIX_FMT_VP8:
+ pl->profile = iris_hfi_gen1_find_hfi_id(v4l2_pf, iris_hfi_gen1_vp8_profiles,
+ ARRAY_SIZE(iris_hfi_gen1_vp8_profiles));
+ pl->level = 0;
+ break;
default:
pl->profile = 0;
pl->level = 0;
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 3c8ae1c82540..2fe1cb7928b5 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -63,6 +63,11 @@
#define HFI_HEVC_LEVEL_61 0x00000800
#define HFI_HEVC_LEVEL_62 0x00001000
+#define HFI_VPX_PROFILE_VERSION_0 0x00000004
+#define HFI_VPX_PROFILE_VERSION_1 0x00000008
+#define HFI_VPX_PROFILE_VERSION_2 0x00000010
+#define HFI_VPX_PROFILE_VERSION_3 0x00000020
+
#define HFI_ERR_NONE 0x0
#define HFI_CMD_SYS_INIT 0x10001
--
2.47.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
` (8 preceding siblings ...)
2026-07-09 19:37 ` [PATCH 9/9] media: iris: add VP8 encode support on Gen1 firmware Dmitry Baryshkov
@ 2026-07-30 22:52 ` Dmitry Baryshkov
2026-07-31 7:37 ` Vikash Garodia
9 siblings, 1 reply; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 22:52 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On Thu, Jul 09, 2026 at 10:36:57PM +0300, Dmitry Baryshkov wrote:
> Bring back features supported by the Venus driver, but not supported by
> the Iris driver: VP8 (encoding, decoding), MPEG2 (decoding only) video
> support and also support for interlaced video streams.
Dear maintainers,
This has been sent three weeks ago. Zero reviews. This is hard to name
as an acceptable response rate.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support
2026-07-30 22:52 ` [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
@ 2026-07-31 7:37 ` Vikash Garodia
2026-07-31 12:25 ` Dmitry Baryshkov
0 siblings, 1 reply; 19+ messages in thread
From: Vikash Garodia @ 2026-07-31 7:37 UTC (permalink / raw)
To: Dmitry Baryshkov, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On 7/31/2026 4:22 AM, Dmitry Baryshkov wrote:
> On Thu, Jul 09, 2026 at 10:36:57PM +0300, Dmitry Baryshkov wrote:
>> Bring back features supported by the Venus driver, but not supported by
>> the Iris driver: VP8 (encoding, decoding), MPEG2 (decoding only) video
>> support and also support for interlaced video streams.
>
> Dear maintainers,
>
> This has been sent three weeks ago. Zero reviews. This is hard to name
> as an acceptable response rate.
>
Acknowledging the delay in review in this series, and my sincere
apologies as this had to wait.
I did not see any sashiko reviews in this. Is this all clean OR the
series was posted before sashiko was enabled for media patches ? Incase
later, might be a good idea to respin it to get the feedback while
manual reviews gets in.
Regards,
Vikash
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support
2026-07-31 7:37 ` Vikash Garodia
@ 2026-07-31 12:25 ` Dmitry Baryshkov
0 siblings, 0 replies; 19+ messages in thread
From: Dmitry Baryshkov @ 2026-07-31 12:25 UTC (permalink / raw)
To: Vikash Garodia
Cc: Dikshita Agarwal, Abhinav Kumar, Bryan O'Donoghue,
Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-arm-msm,
linux-kernel
On Fri, Jul 31, 2026 at 01:07:13PM +0530, Vikash Garodia wrote:
>
> On 7/31/2026 4:22 AM, Dmitry Baryshkov wrote:
> > On Thu, Jul 09, 2026 at 10:36:57PM +0300, Dmitry Baryshkov wrote:
> > > Bring back features supported by the Venus driver, but not supported by
> > > the Iris driver: VP8 (encoding, decoding), MPEG2 (decoding only) video
> > > support and also support for interlaced video streams.
> >
> > Dear maintainers,
> >
> > This has been sent three weeks ago. Zero reviews. This is hard to name
> > as an acceptable response rate.
> >
>
> Acknowledging the delay in review in this series, and my sincere apologies
> as this had to wait.
>
> I did not see any sashiko reviews in this. Is this all clean OR the series
> was posted before sashiko was enabled for media patches ? Incase later,
> might be a good idea to respin it to get the feedback while manual reviews
> gets in.
What is _Your_ review? AI tools are a help for the maintainers.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/9] media: iris: account for UBWC extradata in the QC08C buffer size
2026-07-09 19:36 ` [PATCH 2/9] media: iris: account for UBWC extradata in the QC08C buffer size Dmitry Baryshkov
@ 2026-08-05 15:58 ` Vishnu Reddy
0 siblings, 0 replies; 19+ messages in thread
From: Vishnu Reddy @ 2026-08-05 15:58 UTC (permalink / raw)
To: Dmitry Baryshkov, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On 7/10/2026 1:06 AM, Dmitry Baryshkov wrote:
> iris_yuv_buffer_size_qc08c() sums only the luma/chroma data and metadata
> planes. The UBWC engine additionally writes a trailing extradata/scratch
> region below the frame, so the computed size is too small for the
> reconstruction (DPB) buffer. When the firmware writes that trailing region
> it overruns the buffer and triggers an IOMMU fault; this is hit when
> decoding interlaced content, where the reconstruction buffers are packed
> with a gap after each buffer.
>
> Add the trailing region to the buffer size, sized as the venus driver does
> (max of 16K and 48 luma lines).
>
> Fixes: cfd71b14b0d6 ("media: iris: Add support for QC08C format for decoder")
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_buffer.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
> index 246ad0abbac3..f1de4442be1f 100644
> --- a/drivers/media/platform/qcom/iris/iris_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_buffer.c
> @@ -261,7 +261,8 @@ static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst)
> uv_plane = ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLINE_ALIGN_QC08C),
> PIXELS_4K);
>
> - return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K);
> + return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
> + max_t(u32, SZ_16K, y_stride * 48), PIXELS_4K);
Can max_t(u32, SZ_16K, y_stride * 48) be stored in a variable such as
trailing_region or extradata and used here?
> }
>
> /*
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants
2026-07-09 19:36 ` [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants Dmitry Baryshkov
@ 2026-08-05 16:11 ` Vishnu Reddy
0 siblings, 0 replies; 19+ messages in thread
From: Vishnu Reddy @ 2026-08-05 16:11 UTC (permalink / raw)
To: Dmitry Baryshkov, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
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 <dmitry.baryshkov@oss.qualcomm.com>
> ---
> .../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 <busanna.reddy@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/9] media: iris: split Gen2 firmware data for vpu2-generation SoCs
2026-07-09 19:37 ` [PATCH 4/9] media: iris: split Gen2 firmware data for vpu2-generation SoCs Dmitry Baryshkov
@ 2026-08-05 17:08 ` Vishnu Reddy
0 siblings, 0 replies; 19+ messages in thread
From: Vishnu Reddy @ 2026-08-05 17:08 UTC (permalink / raw)
To: Dmitry Baryshkov, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On 7/10/2026 1:07 AM, Dmitry Baryshkov wrote:
> The single iris_hfi_gen2_data instance is shared by both vpu3x SoCs
> (sm8550/sm8650/sm8750/x1p42100), which support AV1, and the vpu2 SoC
> sc7280, which does not. This is harmless today because the list of
> advertised decode formats is kept separately in the per-SoC platform
> data, but it prevents moving those format lists onto the firmware data
> where they belong: a shared struct cannot describe both an AV1-capable
> and an AV1-incapable generation.
>
> Add a dedicated iris_hfi_gen2_vpu2_data instance for vpu2-generation
> SoCs booting Gen2 firmware, using a decode cap table and config
> parameter lists with all AV1-specific entries dropped, and point
> sc7280's Gen2 firmware descriptor at it. The vpu3x SoCs keep using
> iris_hfi_gen2_data unchanged.
>
> No functional change: sc7280 already did not advertise or accept AV1.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_hfi_gen2.c | 247 +++++++++++++++++++++
> .../platform/qcom/iris/iris_platform_common.h | 1 +
> .../media/platform/qcom/iris/iris_platform_vpu2.c | 2 +-
> 3 files changed, 249 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
> index f89245269e8c..110b5630902f 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
> @@ -280,6 +280,189 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = {
> },
> };
>
> +static const struct platform_inst_fw_cap inst_fw_cap_vpu2_gen2_dec[] = {
> + {
> + .cap_id = PROFILE_H264,
> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_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_CONSTRAINED_HIGH),
> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
> + .hfi_id = HFI_PROP_PROFILE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = PROFILE_HEVC,
> + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
> + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
> + .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
> + .hfi_id = HFI_PROP_PROFILE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = PROFILE_VP9,
> + .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
> + .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) |
> + BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2),
> + .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
> + .hfi_id = HFI_PROP_PROFILE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = LEVEL_H264,
> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_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) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
> + .hfi_id = HFI_PROP_LEVEL,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = LEVEL_HEVC,
> + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
> + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
> + .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) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
> + .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
> + .hfi_id = HFI_PROP_LEVEL,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = LEVEL_VP9,
> + .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0,
> + .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) |
> + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0),
> + .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
> + .hfi_id = HFI_PROP_LEVEL,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = TIER,
> + .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
> + .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH),
> + .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
> + .hfi_id = HFI_PROP_TIER,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = INPUT_BUF_HOST_MAX_COUNT,
> + .min = DEFAULT_MAX_HOST_BUF_COUNT,
> + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
> + .step_or_mask = 1,
> + .value = DEFAULT_MAX_HOST_BUF_COUNT,
> + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
> + .flags = CAP_FLAG_INPUT_PORT,
> + .set = iris_set_u32,
> + },
> + {
> + .cap_id = STAGE,
> + .min = STAGE_1,
> + .max = STAGE_2,
> + .step_or_mask = 1,
> + .value = STAGE_2,
> + .hfi_id = HFI_PROP_STAGE,
> + .set = iris_set_stage,
> + },
> + {
> + .cap_id = PIPE,
> + /* .max, .min and .value are set via platform data */
> + .step_or_mask = 1,
> + .hfi_id = HFI_PROP_PIPE,
> + .set = iris_set_pipe,
> + },
> + {
> + .cap_id = POC,
> + .min = 0,
> + .max = 2,
> + .step_or_mask = 1,
> + .value = 1,
> + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
> + },
> + {
> + .cap_id = CODED_FRAMES,
> + .min = CODED_FRAMES_PROGRESSIVE,
> + .max = CODED_FRAMES_PROGRESSIVE,
> + .step_or_mask = 0,
> + .value = CODED_FRAMES_PROGRESSIVE,
> + .hfi_id = HFI_PROP_CODED_FRAMES,
> + },
> + {
> + .cap_id = BIT_DEPTH,
> + .min = BIT_DEPTH_8,
> + .max = BIT_DEPTH_10,
> + .step_or_mask = 1,
> + .value = BIT_DEPTH_8,
> + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
> + },
> + {
> + .cap_id = RAP_FRAME,
> + .min = 0,
> + .max = 1,
> + .step_or_mask = 1,
> + .value = 1,
> + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
> + .flags = CAP_FLAG_INPUT_PORT,
> + .set = iris_set_u32,
> + },
> +};
> +
> static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
> {
> .cap_id = PROFILE_H264,
> @@ -1119,6 +1302,70 @@ const struct iris_firmware_data iris_hfi_gen2_data = {
> .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
> };
>
> +/*
> + * Firmware data for vpu2-generation SoCs (e.g. sc7280) booting Gen2 firmware.
> + * These do not support AV1, so the decode cap table and the config parameters
> + * omit all AV1-specific entries.
> + */
> +const struct iris_firmware_data iris_hfi_gen2_vpu2_data = {
> + .init_hfi_ops = iris_hfi_gen2_sys_ops_init,
> +
> + .core_arch = VIDEO_ARCH_LX,
> +
> + .inst_fw_caps_dec = inst_fw_cap_vpu2_gen2_dec,
> + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_vpu2_gen2_dec),
> + .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
> + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
> +
> + .dec_input_config_params_default =
> + sm8550_vdec_input_config_params_default,
> + .dec_input_config_params_default_size =
> + ARRAY_SIZE(sm8550_vdec_input_config_params_default),
> + .dec_input_config_params_hevc =
> + sm8550_vdec_input_config_param_hevc,
> + .dec_input_config_params_hevc_size =
> + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
> + .dec_input_config_params_vp9 =
> + sm8550_vdec_input_config_param_vp9,
> + .dec_input_config_params_vp9_size =
> + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
> + .dec_output_config_params =
> + sm8550_vdec_output_config_params,
> + .dec_output_config_params_size =
> + ARRAY_SIZE(sm8550_vdec_output_config_params),
> +
> + .enc_input_config_params =
> + sm8550_venc_input_config_params,
> + .enc_input_config_params_size =
> + ARRAY_SIZE(sm8550_venc_input_config_params),
> + .enc_output_config_params =
> + sm8550_venc_output_config_params,
> + .enc_output_config_params_size =
> + ARRAY_SIZE(sm8550_venc_output_config_params),
> +
> + .dec_input_prop = sm8550_vdec_subscribe_input_properties,
> + .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
> + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
> + .dec_output_prop_avc_size =
> + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
> + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
> + .dec_output_prop_hevc_size =
> + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
> + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
> + .dec_output_prop_vp9_size =
> + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
> +
> + .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
> + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
> + .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
> + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
> +
> + .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl,
> + .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl),
> + .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
> + .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
> +};
> +
> static const struct platform_inst_fw_cap inst_fw_cap_gen2_ar50lt_dec[] = {
> {
> .cap_id = PROFILE_H264,
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 5afe395cc4a0..9743573ab083 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -57,6 +57,7 @@ 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_firmware_data iris_hfi_gen2_vpu2_data;
> extern const struct iris_firmware_data iris_hfi_gen2_ar50lt_data;
>
> extern const struct iris_platform_data qcm2290_data;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> index e194f67a6f48..8f01cf7f6d49 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> @@ -25,7 +25,7 @@ static const struct iris_firmware_desc iris_vpu20_p1_gen1_desc = {
> };
>
> static const struct iris_firmware_desc iris_vpu20_p1_gen2_s6_desc = {
> - .firmware_data = &iris_hfi_gen2_data,
> + .firmware_data = &iris_hfi_gen2_vpu2_data,
> .get_vpu_buffer_size = iris_vpu33_buf_size,
> .fwname = "qcom/vpu/vpu20_p1_gen2_s6.mbn",
> };
Reviewed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5/9] media: iris: move the decode format list into the firmware data
2026-07-09 19:37 ` [PATCH 5/9] media: iris: move the decode format list into the firmware data Dmitry Baryshkov
@ 2026-08-26 4:09 ` Vishnu Reddy
0 siblings, 0 replies; 19+ messages in thread
From: Vishnu Reddy @ 2026-08-26 4:09 UTC (permalink / raw)
To: Dmitry Baryshkov, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On 7/10/2026 1:07 AM, Dmitry Baryshkov wrote:
> The set of supported coded formats depends on the firmware generation:
> a single SoC can boot either Gen1 or Gen2 firmware, and some codecs are
> only supported by one generation. The decode format list was however
> kept per-SoC in iris_platform_data::inst_iris_fmts, which is too coarse
> to express this - a per-SoC list cannot describe the two different format
> sets the same SoC exposes depending on which firmware it booted.
>
> Move the decode format list into struct iris_firmware_data, which is
> already selected per firmware generation, and drop the per-SoC
> inst_iris_fmts field. Each firmware data instance now carries the exact
> set of decode formats its generation supports, so the formats advertised
> to userspace always match the running firmware.
>
> No functional change: every SoC advertises the same decode formats as
> before.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 12 ++++++++++++
> drivers/media/platform/qcom/iris/iris_hfi_gen2.c | 21 +++++++++++++++++++++
> .../media/platform/qcom/iris/iris_platform_common.h | 12 ++++++++++--
> .../media/platform/qcom/iris/iris_platform_vpu2.c | 10 ----------
> .../media/platform/qcom/iris/iris_platform_vpu3x.c | 17 -----------------
> .../platform/qcom/iris/iris_platform_vpu_ar50lt.c | 8 --------
> drivers/media/platform/qcom/iris/iris_vdec.c | 8 ++++----
> 7 files changed, 47 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> index 4f205757647a..8119c639ec24 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> @@ -419,6 +419,12 @@ static const u32 sm8250_enc_ip_int_buf_tbl[] = {
> BUF_SCRATCH_2,
> };
>
> +static const u32 iris_hfi_gen1_dec_fmts[] = {
> + V4L2_PIX_FMT_H264,
> + V4L2_PIX_FMT_HEVC,
> + V4L2_PIX_FMT_VP9,
> +};
> +
> const struct iris_firmware_data iris_hfi_gen1_data = {
> .init_hfi_ops = &iris_hfi_gen1_sys_ops_init,
>
> @@ -427,6 +433,9 @@ const struct iris_firmware_data iris_hfi_gen1_data = {
> .inst_fw_caps_enc = inst_fw_cap_sm8250_enc,
> .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc),
>
> + .dec_fmts = iris_hfi_gen1_dec_fmts,
> + .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
> +
> .dec_input_config_params_default =
> sm8250_vdec_input_config_param_default,
> .dec_input_config_params_default_size =
> @@ -668,6 +677,9 @@ const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
> .inst_fw_caps_enc = inst_fw_cap_gen1_ar50lt_enc,
> .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen1_ar50lt_enc),
>
> + .dec_fmts = iris_hfi_gen1_dec_fmts,
> + .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
> +
> .dec_input_config_params_default =
> sm8250_vdec_input_config_param_default,
> .dec_input_config_params_default_size =
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
> index 110b5630902f..6c1d562ab8c2 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c
> @@ -1236,6 +1236,19 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = {
> BUF_SCRATCH_2,
> };
>
> +static const u32 iris_hfi_gen2_dec_fmts[] = {
> + V4L2_PIX_FMT_H264,
> + V4L2_PIX_FMT_HEVC,
> + V4L2_PIX_FMT_VP9,
> + V4L2_PIX_FMT_AV1,
Kodiak supports both Gen1 and Gen2 firmware's, but AV1 decoding is not supported
on kodiak. With this change, the driver will incorrectly advertise AV1 decode
capability for kodiak platform.
> +};
> +
> +static const u32 iris_hfi_gen2_vpu2_dec_fmts[] = {
> + V4L2_PIX_FMT_H264,
> + V4L2_PIX_FMT_HEVC,
> + V4L2_PIX_FMT_VP9,
> +};
> +
> const struct iris_firmware_data iris_hfi_gen2_data = {
> .init_hfi_ops = iris_hfi_gen2_sys_ops_init,
>
> @@ -1246,6 +1259,9 @@ const struct iris_firmware_data iris_hfi_gen2_data = {
> .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
> .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
>
> + .dec_fmts = iris_hfi_gen2_dec_fmts,
> + .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_dec_fmts),
> +
> .dec_input_config_params_default =
> sm8550_vdec_input_config_params_default,
> .dec_input_config_params_default_size =
> @@ -1317,6 +1333,9 @@ const struct iris_firmware_data iris_hfi_gen2_vpu2_data = {
> .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
> .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
>
> + .dec_fmts = iris_hfi_gen2_vpu2_dec_fmts,
> + .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_vpu2_dec_fmts),
> +
> .dec_input_config_params_default =
> sm8550_vdec_input_config_params_default,
> .dec_input_config_params_default_size =
> @@ -1934,6 +1953,8 @@ const struct iris_firmware_data iris_hfi_gen2_ar50lt_data = {
> .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_gen2_ar50lt_dec),
> .inst_fw_caps_enc = inst_fw_cap_gen2_ar50lt_enc,
> .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen2_ar50lt_enc),
> + .dec_fmts = iris_hfi_gen2_vpu2_dec_fmts,
> + .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen2_vpu2_dec_fmts),
> .dec_input_config_params_default =
> sm8550_vdec_input_config_params_default,
> .dec_input_config_params_default_size =
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 9743573ab083..317ba48e6305 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -255,6 +255,16 @@ struct iris_firmware_data {
> const struct platform_inst_fw_cap *inst_fw_caps_enc;
> u32 inst_fw_caps_enc_size;
>
> + /*
> + * List of coded formats supported by this firmware generation, used to
> + * advertise decode (bitstream) formats to userspace. This lives in the
> + * firmware data because a single SoC can boot either firmware
> + * generation, and some codecs (e.g. VP8, MPEG2, AV1) are only supported
> + * by one generation.
> + */
> + const u32 *dec_fmts;
> + unsigned int dec_fmts_size;
> +
> const u32 *dec_input_config_params_default;
> unsigned int dec_input_config_params_default_size;
> const u32 *dec_input_config_params_hevc;
> @@ -317,8 +327,6 @@ struct iris_platform_data {
> const char * const *controller_rst_tbl;
> unsigned int controller_rst_tbl_size;
> u64 dma_mask;
> - const u32 *inst_iris_fmts;
> - u32 inst_iris_fmts_size;
> struct platform_inst_caps *inst_caps;
> const struct tz_cp_config *tz_cp_config_data;
> u32 tz_cp_config_data_size;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> index 8f01cf7f6d49..37aee82a49f4 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> @@ -36,12 +36,6 @@ static const struct iris_firmware_desc iris_vpu20_p4_gen1_desc = {
> .fwname = "qcom/vpu/vpu20_p4.mbn",
> };
>
> -static const u32 iris_fmts_vpu2_dec[] = {
> - V4L2_PIX_FMT_H264,
> - V4L2_PIX_FMT_HEVC,
> - V4L2_PIX_FMT_VP9,
> -};
> -
> static struct platform_inst_caps platform_inst_cap_vpu2 = {
> .min_frame_width = 128,
> .max_frame_width = 8192,
> @@ -89,8 +83,6 @@ const struct iris_platform_data sc7280_data = {
> .opp_clk_tbl = sc7280_opp_clk_table,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu2_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec),
> .inst_caps = &platform_inst_cap_vpu2,
> .tz_cp_config_data = tz_cp_config_vpu2,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
> @@ -122,8 +114,6 @@ const struct iris_platform_data sm8250_data = {
> .opp_clk_tbl = sm8250_opp_clk_table,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu2_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec),
> .inst_caps = &platform_inst_cap_vpu2,
> .tz_cp_config_data = tz_cp_config_vpu2,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
> index b8099d7ce556..30c95621fa0e 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
> @@ -50,13 +50,6 @@ static const struct iris_firmware_desc iris_vpu35_p4_gen2_desc = {
> .fwname = "qcom/vpu/vpu35_p4.mbn",
> };
>
> -static const u32 iris_fmts_vpu3x_dec[] = {
> - V4L2_PIX_FMT_H264,
> - V4L2_PIX_FMT_HEVC,
> - V4L2_PIX_FMT_VP9,
> - V4L2_PIX_FMT_AV1,
> -};
> -
> static const struct icc_info iris_icc_info_vpu3x[] = {
> { "cpu-cfg", 1000, 1000 },
> { "video-mem", 1000, 15000000 },
> @@ -109,8 +102,6 @@ const struct iris_platform_data qcs8300_data = {
> .opp_clk_tbl = iris_opp_clk_table_vpu3x,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu3x_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
> .inst_caps = &platform_inst_cap_qcs8300,
> .tz_cp_config_data = tz_cp_config_vpu3,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
> @@ -140,8 +131,6 @@ const struct iris_platform_data sm8550_data = {
> .opp_clk_tbl = iris_opp_clk_table_vpu3x,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu3x_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
> .inst_caps = &platform_inst_cap_sm8550,
> .tz_cp_config_data = tz_cp_config_vpu3,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
> @@ -179,8 +168,6 @@ const struct iris_platform_data sm8650_data = {
> .opp_clk_tbl = iris_opp_clk_table_vpu3x,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu3x_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
> .inst_caps = &platform_inst_cap_sm8550,
> .tz_cp_config_data = tz_cp_config_vpu3,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
> @@ -210,8 +197,6 @@ const struct iris_platform_data sm8750_data = {
> .opp_clk_tbl = iris_opp_clk_table_vpu3x,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu3x_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
> .inst_caps = &platform_inst_cap_sm8550,
> .tz_cp_config_data = tz_cp_config_vpu3,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
> @@ -247,8 +232,6 @@ const struct iris_platform_data x1p42100_data = {
> .opp_clk_tbl = x1p42100_opp_clk_table,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_vpu3x_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
> .inst_caps = &platform_inst_cap_sm8550,
> .tz_cp_config_data = tz_cp_config_vpu3,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
> index 99c839a0424f..e569817a0c80 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c
> @@ -25,12 +25,6 @@ static const struct iris_firmware_desc iris_vpu_ar50lt_p1_gen2_s6_desc = {
> .fwname = "qcom/vpu/ar50lt_p1_gen2_s6.mbn",
> };
>
> -static const u32 iris_fmts_ar50lt_dec[] = {
> - V4L2_PIX_FMT_H264,
> - V4L2_PIX_FMT_HEVC,
> - V4L2_PIX_FMT_VP9,
> -};
> -
> static const struct bw_info iris_bw_table_dec_ar50lt[] = {
> { ((1920 * 1080) / 256) * 60, 1564000, },
> { ((1920 * 1080) / 256) * 30, 791000, },
> @@ -100,8 +94,6 @@ const struct iris_platform_data qcm2290_data = {
> .opp_clk_tbl = iris_opp_clk_table_ar50lt,
> /* Upper bound of DMA address range */
> .dma_mask = 0xe0000000 - 1,
> - .inst_iris_fmts = iris_fmts_ar50lt_dec,
> - .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_ar50lt_dec),
> .inst_caps = &platform_inst_cap_ar50lt,
> .tz_cp_config_data = tz_cp_config_ar50lt,
> .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_ar50lt),
> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
> index 9169b1335b5c..59200ca72ded 100644
> --- a/drivers/media/platform/qcom/iris/iris_vdec.c
> +++ b/drivers/media/platform/qcom/iris/iris_vdec.c
> @@ -83,8 +83,8 @@ static bool check_format(struct iris_inst *inst, u32 pixfmt, u32 type)
>
> switch (type) {
> case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> - fmt = inst->core->iris_platform_data->inst_iris_fmts;
> - size = inst->core->iris_platform_data->inst_iris_fmts_size;
> + fmt = inst->core->iris_firmware_data->dec_fmts;
> + size = inst->core->iris_firmware_data->dec_fmts_size;
> break;
> case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
> if (ubwc->ubwc_enc_version) {
> @@ -128,8 +128,8 @@ static u32 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
>
> switch (type) {
> case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> - fmt = inst->core->iris_platform_data->inst_iris_fmts;
> - size = inst->core->iris_platform_data->inst_iris_fmts_size;
> + fmt = inst->core->iris_firmware_data->dec_fmts;
> + size = inst->core->iris_firmware_data->dec_fmts_size;
> break;
> case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
> if (ubwc->ubwc_enc_version) {
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 6/9] media: iris: add VP8 decode support on Gen1 firmware
2026-07-09 19:37 ` [PATCH 6/9] media: iris: add VP8 decode support on Gen1 firmware Dmitry Baryshkov
@ 2026-08-26 4:18 ` Vishnu Reddy
0 siblings, 0 replies; 19+ messages in thread
From: Vishnu Reddy @ 2026-08-26 4:18 UTC (permalink / raw)
To: Dmitry Baryshkov, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On 7/10/2026 1:07 AM, Dmitry Baryshkov wrote:
> The Gen1 firmware supports decoding VP8, but the iris driver never
> advertised or wired up the codec.
>
> Add the VP8 HFI codec code, map V4L2_PIX_FMT_VP8 to it in the Gen1
> session open path, and compute the VP8 internal buffer sizes (bin,
> collocated motion vector, line and probability-table persist buffers,
> which reuse the shared VPX helpers). Advertise the codec through the
> Gen1 decode format list and register the VP8 profile menu control.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 7 +++
> drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 22 +++++++-
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 3 +
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 1 +
> .../platform/qcom/iris/iris_platform_common.h | 1 +
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 64 ++++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 3 +
> 7 files changed, 99 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index c12fe724dfb8..1bd6460a1b0a 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -28,6 +28,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
> return PROFILE_HEVC;
> case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
> return PROFILE_VP9;
> + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
> + return PROFILE_VP8;
> case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
> return LEVEL_H264;
> case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
> @@ -171,6 +173,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
> return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
> case PROFILE_VP9:
> return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
> + case PROFILE_VP8:
> + return V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
> case LEVEL_H264:
> return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
> case LEVEL_HEVC:
> @@ -558,6 +562,9 @@ int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_
> if (inst->codec == V4L2_PIX_FMT_H264) {
> hfi_id = inst->fw_caps[PROFILE_H264].hfi_id;
> hfi_value = inst->fw_caps[PROFILE_H264].value;
> + } else if (inst->codec == V4L2_PIX_FMT_VP8) {
> + hfi_id = inst->fw_caps[PROFILE_VP8].hfi_id;
> + hfi_value = inst->fw_caps[PROFILE_VP8].value;
> } else {
> hfi_id = inst->fw_caps[PROFILE_HEVC].hfi_id;
> hfi_value = inst->fw_caps[PROFILE_HEVC].value;
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> index 8119c639ec24..4c3aa5a03ddd 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> @@ -30,6 +30,17 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = {
> .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
> .set = iris_set_stage,
> },
> + {
> + .cap_id = PROFILE_VP8,
> + .min = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
> + .max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_0) |
> + BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_1) |
> + BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_2) |
> + BIT(V4L2_MPEG_VIDEO_VP8_PROFILE_3),
> + .value = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
> + .flags = CAP_FLAG_MENU,
> + },
> };
>
> static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> @@ -423,6 +434,13 @@ static const u32 iris_hfi_gen1_dec_fmts[] = {
> V4L2_PIX_FMT_H264,
> V4L2_PIX_FMT_HEVC,
> V4L2_PIX_FMT_VP9,
> + V4L2_PIX_FMT_VP8,
> +};
> +
> +static const u32 iris_hfi_gen1_ar50lt_dec_fmts[] = {
> + V4L2_PIX_FMT_H264,
> + V4L2_PIX_FMT_HEVC,
> + V4L2_PIX_FMT_VP9,
> };
Similar change is needed for Kodiak Gen2 to avoid exposing AV1 decode support.
>
> const struct iris_firmware_data iris_hfi_gen1_data = {
> @@ -677,8 +695,8 @@ const struct iris_firmware_data iris_hfi_gen1_ar50lt_data = {
> .inst_fw_caps_enc = inst_fw_cap_gen1_ar50lt_enc,
> .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_gen1_ar50lt_enc),
>
> - .dec_fmts = iris_hfi_gen1_dec_fmts,
> - .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_dec_fmts),
> + .dec_fmts = iris_hfi_gen1_ar50lt_dec_fmts,
> + .dec_fmts_size = ARRAY_SIZE(iris_hfi_gen1_ar50lt_dec_fmts),
>
> .dec_input_config_params_default =
> sm8250_vdec_input_config_param_default,
> 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 ed9fef2aec08..90645ed3e0d8 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -105,6 +105,9 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst)
> case V4L2_PIX_FMT_HEVC:
> codec = HFI_VIDEO_CODEC_HEVC;
> break;
> + case V4L2_PIX_FMT_VP8:
> + codec = HFI_VIDEO_CODEC_VP8;
> + break;
> case V4L2_PIX_FMT_VP9:
> codec = HFI_VIDEO_CODEC_VP9;
> 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 2702f255bc04..13c8ff59d6e4 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -14,6 +14,7 @@
> #define HFI_SESSION_TYPE_DEC 2
>
> #define HFI_VIDEO_CODEC_H264 0x00000002
> +#define HFI_VIDEO_CODEC_VP8 0x00001000
> #define HFI_VIDEO_CODEC_HEVC 0x00002000
> #define HFI_VIDEO_CODEC_VP9 0x00004000
>
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 317ba48e6305..84017b66e98f 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -115,6 +115,7 @@ enum platform_inst_fw_cap_type {
> PROFILE_H264 = 1,
> PROFILE_HEVC,
> PROFILE_VP9,
> + PROFILE_VP8,
> LEVEL_H264,
> LEVEL_HEVC,
> LEVEL_VP9,
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> index 88f130d09a6e..ca90414e6c19 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> @@ -293,6 +293,11 @@ static u32 hfi_buffer_persist_vp9d(void)
> HDR10_HIST_EXTRADATA_SIZE;
> }
>
> +static u32 hfi_buffer_persist_vp8d(void)
> +{
> + return ALIGN(VP8_NUM_PROBABILITY_TABLE_BUF * VP8_PROB_TABLE_SIZE, DMA_ALIGNMENT);
> +}
> +
> static u32 hfi_buffer_persist_vp9d_ar50lt(void)
> {
> return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) +
> @@ -715,6 +720,57 @@ u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_mi
> return _lb_size + vpss_lb_size + 4096;
> }
>
> +static inline
> +u32 size_vp8d_lb_fe_top_data(u32 frame_width, u32 frame_height)
> +{
> + return (ALIGN(frame_width, 16) + 8) * 10 * 2;
> +}
> +
> +static inline
> +u32 size_vp8d_lb_pe_top_data(u32 frame_width, u32 frame_height)
> +{
> + return (ALIGN(frame_width, 16) >> 4) * 64;
> +}
> +
> +static inline
> +u32 size_vp8d_lb_vsp_top(u32 frame_width, u32 frame_height)
> +{
> + return ((ALIGN(frame_width, 16) >> 4) * 64 / 2) + 256;
> +}
> +
> +static inline
> +u32 hfi_iris_vp8d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
> +{
> + return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * num_vpp_pipes +
> + ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * num_vpp_pipes +
> + ALIGN(size_vp8d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) +
> + ALIGN(size_vpxd_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
> + 2 * ALIGN(size_vpxd_lb_recon_dma_metadata_wr(frame_width, frame_height), DMA_ALIGNMENT) +
> + ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
> + ALIGN(size_vp8d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) +
> + ALIGN(size_vp8d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT);
> +}
> +
> +static inline
> +u32 hfi_buffer_line_vp8d(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes)
> +{
> + u32 vpss_lb_size = 0;
> + u32 _lb_size;
> +
> + _lb_size = hfi_iris_vp8d_lb_size(frame_width, frame_height, num_vpp_pipes);
> +
> + if (is_opb)
> + vpss_lb_size = size_vpss_lb(frame_width, frame_height);
> +
> + return _lb_size + vpss_lb_size;
> +}
> +
> +static inline
> +u32 hfi_iris_vp8d_comv_size(u32 frame_width, u32 frame_height)
> +{
> + return DIV_ROUND_UP(frame_width, 16) * DIV_ROUND_UP(frame_height, 16) * 8 * 2;
> +}
> +
> static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
> bool is_opb, u32 num_vpp_pipes)
> {
> @@ -950,6 +1006,8 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst)
> return hfi_buffer_bin_h265d(width, height, num_vpp_pipes);
> else if (inst->codec == V4L2_PIX_FMT_VP9)
> return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes);
> + else if (inst->codec == V4L2_PIX_FMT_VP8)
> + return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes);
> else if (inst->codec == V4L2_PIX_FMT_AV1)
> return hfi_buffer_bin_av1d(width, height, num_vpp_pipes);
>
> @@ -983,6 +1041,8 @@ static u32 iris_vpu_dec_comv_size(struct iris_inst *inst)
> return hfi_buffer_comv_h264d(width, height, num_comv);
> else if (inst->codec == V4L2_PIX_FMT_HEVC)
> return hfi_buffer_comv_h265d(width, height, num_comv);
> + else if (inst->codec == V4L2_PIX_FMT_VP8)
> + return hfi_iris_vp8d_comv_size(width, height);
>
> return 0;
> }
> @@ -1021,6 +1081,8 @@ static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
> return hfi_buffer_persist_h265d(0);
> else if (inst->codec == V4L2_PIX_FMT_VP9)
> return hfi_buffer_persist_vp9d();
> + else if (inst->codec == V4L2_PIX_FMT_VP8)
> + return hfi_buffer_persist_vp8d();
> else if (inst->codec == V4L2_PIX_FMT_AV1) {
> caps = inst->core->iris_platform_data->inst_caps;
> if (inst->fw_caps[DRAP].value)
> @@ -1101,6 +1163,8 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
> else if (inst->codec == V4L2_PIX_FMT_VP9)
> return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb,
> num_vpp_pipes);
> + else if (inst->codec == V4L2_PIX_FMT_VP8)
> + return hfi_buffer_line_vp8d(width, height, is_opb, num_vpp_pipes);
> else if (inst->codec == V4L2_PIX_FMT_AV1)
> return hfi_buffer_line_av1d(width, height, is_opb, num_vpp_pipes);
>
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
> index 2085e316a6bd..684b459c0cad 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
> @@ -66,6 +66,9 @@ struct iris_inst;
> #define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT (32 / 8)
> #define VP9_UDC_HEADER_BUF_SIZE (3 * 128)
>
> +#define VP8_NUM_PROBABILITY_TABLE_BUF (5 + 1)
> +#define VP8_PROB_TABLE_SIZE (3840)
> +
> #define SIZE_SEI_USERDATA 4096
> #define SIZE_DOLBY_RPU_METADATA (41 * 1024)
> #define H264_CABAC_HDR_RATIO_HD_TOT 1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 7/9] media: iris: add MPEG2 decode support on Gen1 firmware
2026-07-09 19:37 ` [PATCH 7/9] media: iris: add MPEG2 " Dmitry Baryshkov
@ 2026-08-26 4:50 ` Vishnu Reddy
0 siblings, 0 replies; 19+ messages in thread
From: Vishnu Reddy @ 2026-08-26 4:50 UTC (permalink / raw)
To: Dmitry Baryshkov, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-arm-msm, linux-kernel
On 7/10/2026 1:07 AM, Dmitry Baryshkov wrote:
> The Gen1 firmware supports decoding MPEG2, but the iris driver never
> advertised or wired up the codec.
>
> Add the MPEG2 HFI codec code, map V4L2_PIX_FMT_MPEG2 to it in the Gen1
> session open path, and compute the MPEG2 internal buffer sizes (line
> buffer and the quantisation-matrix / QP-dump persist buffer). Advertise
> the codec through the new Gen1 decode format list and register the MPEG2
> profile and level menu controls so userspace can query them.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 15 ++++++++++++++
> drivers/media/platform/qcom/iris/iris_hfi_gen1.c | 24 ++++++++++++++++++++++
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 3 +++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 1 +
> .../platform/qcom/iris/iris_platform_common.h | 2 ++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 9 +++++++-
> drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 3 +++
> 7 files changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index 1bd6460a1b0a..8f9347c1df2b 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -30,12 +30,16 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
> return PROFILE_VP9;
> case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
> return PROFILE_VP8;
> + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
> + return PROFILE_MPEG2;
> case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
> return LEVEL_H264;
> case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
> return LEVEL_HEVC;
> case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
> return LEVEL_VP9;
> + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
> + return LEVEL_MPEG2;
> case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
> return TIER;
> case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
> @@ -175,12 +179,16 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
> return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
> case PROFILE_VP8:
> return V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
> + case PROFILE_MPEG2:
> + return V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE;
> case LEVEL_H264:
> return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
> case LEVEL_HEVC:
> return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
> case LEVEL_VP9:
> return V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
> + case LEVEL_MPEG2:
> + return V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL;
> case TIER:
> return V4L2_CID_MPEG_VIDEO_HEVC_TIER;
> case HEADER_MODE:
> @@ -527,6 +535,7 @@ int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
> * content also uses a single stage.
> */
> if (inst->is_interlaced ||
> + inst->codec == V4L2_PIX_FMT_MPEG2 ||
> iris_res_is_less_than(width, height, 1280, 720))
> work_mode = STAGE_1;
> }
> @@ -565,6 +574,9 @@ int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_
> } else if (inst->codec == V4L2_PIX_FMT_VP8) {
> hfi_id = inst->fw_caps[PROFILE_VP8].hfi_id;
> hfi_value = inst->fw_caps[PROFILE_VP8].value;
> + } else if (inst->codec == V4L2_PIX_FMT_MPEG2) {
> + hfi_id = inst->fw_caps[PROFILE_MPEG2].hfi_id;
> + hfi_value = inst->fw_caps[PROFILE_MPEG2].value;
> } else {
> hfi_id = inst->fw_caps[PROFILE_HEVC].hfi_id;
> hfi_value = inst->fw_caps[PROFILE_HEVC].value;
> @@ -585,6 +597,9 @@ int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
> if (inst->codec == V4L2_PIX_FMT_H264) {
> hfi_id = inst->fw_caps[LEVEL_H264].hfi_id;
> hfi_value = inst->fw_caps[LEVEL_H264].value;
> + } else if (inst->codec == V4L2_PIX_FMT_MPEG2) {
> + hfi_id = inst->fw_caps[LEVEL_MPEG2].hfi_id;
> + hfi_value = inst->fw_caps[LEVEL_MPEG2].value;
> } else {
> hfi_id = inst->fw_caps[LEVEL_HEVC].hfi_id;
> hfi_value = inst->fw_caps[LEVEL_HEVC].value;
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> index 4c3aa5a03ddd..4b05c2a47b0b 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c
> @@ -41,6 +41,29 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = {
> .value = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
> .flags = CAP_FLAG_MENU,
> },
> + {
> + .cap_id = PROFILE_MPEG2,
> + .min = V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE,
> + .max = V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH),
> + .value = V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN,
> + .flags = CAP_FLAG_MENU,
> + },
> + {
> + .cap_id = LEVEL_MPEG2,
> + .min = V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW,
> + .max = V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440) |
> + BIT(V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH),
> + .value = V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN,
> + .flags = CAP_FLAG_MENU,
> + },
> };
>
> static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> @@ -435,6 +458,7 @@ static const u32 iris_hfi_gen1_dec_fmts[] = {
> V4L2_PIX_FMT_HEVC,
> V4L2_PIX_FMT_VP9,
> V4L2_PIX_FMT_VP8,
> + V4L2_PIX_FMT_MPEG2,
> };
>
> static const u32 iris_hfi_gen1_ar50lt_dec_fmts[] = {
> 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 90645ed3e0d8..53ba48f88410 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -111,6 +111,9 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst)
> case V4L2_PIX_FMT_VP9:
> codec = HFI_VIDEO_CODEC_VP9;
> break;
> + case V4L2_PIX_FMT_MPEG2:
> + codec = HFI_VIDEO_CODEC_MPEG2;
> + break;
> }
>
> packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
> 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 13c8ff59d6e4..3c8ae1c82540 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -14,6 +14,7 @@
> #define HFI_SESSION_TYPE_DEC 2
>
> #define HFI_VIDEO_CODEC_H264 0x00000002
> +#define HFI_VIDEO_CODEC_MPEG2 0x00000010
> #define HFI_VIDEO_CODEC_VP8 0x00001000
> #define HFI_VIDEO_CODEC_HEVC 0x00002000
> #define HFI_VIDEO_CODEC_VP9 0x00004000
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 84017b66e98f..3d631effe307 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -116,9 +116,11 @@ enum platform_inst_fw_cap_type {
> PROFILE_HEVC,
> PROFILE_VP9,
> PROFILE_VP8,
> + PROFILE_MPEG2,
> LEVEL_H264,
> LEVEL_HEVC,
> LEVEL_VP9,
> + LEVEL_MPEG2,
> PROFILE_AV1,
> LEVEL_AV1,
> TIER_AV1,
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> index ca90414e6c19..c16e2b652cf4 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> @@ -298,6 +298,11 @@ static u32 hfi_buffer_persist_vp8d(void)
> return ALIGN(VP8_NUM_PROBABILITY_TABLE_BUF * VP8_PROB_TABLE_SIZE, DMA_ALIGNMENT);
> }
>
> +static u32 hfi_buffer_persist_mpeg2d(void)
> +{
> + return QMATRIX_SIZE + MP2D_QPDUMP_SIZE;
> +}
> +
> static u32 hfi_buffer_persist_vp9d_ar50lt(void)
> {
> return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) +
> @@ -1083,6 +1088,8 @@ static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
> return hfi_buffer_persist_vp9d();
> else if (inst->codec == V4L2_PIX_FMT_VP8)
> return hfi_buffer_persist_vp8d();
> + else if (inst->codec == V4L2_PIX_FMT_MPEG2)
> + return hfi_buffer_persist_mpeg2d();
> else if (inst->codec == V4L2_PIX_FMT_AV1) {
> caps = inst->core->iris_platform_data->inst_caps;
> if (inst->fw_caps[DRAP].value)
> @@ -1163,7 +1170,7 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
> else if (inst->codec == V4L2_PIX_FMT_VP9)
> return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb,
> num_vpp_pipes);
> - else if (inst->codec == V4L2_PIX_FMT_VP8)
> + else if (inst->codec == V4L2_PIX_FMT_VP8 || inst->codec == V4L2_PIX_FMT_MPEG2)
> return hfi_buffer_line_vp8d(width, height, is_opb, num_vpp_pipes);
> else if (inst->codec == V4L2_PIX_FMT_AV1)
> return hfi_buffer_line_av1d(width, height, is_opb, num_vpp_pipes);
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
> index 684b459c0cad..4694467677f6 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
> @@ -69,6 +69,9 @@ struct iris_inst;
> #define VP8_NUM_PROBABILITY_TABLE_BUF (5 + 1)
> #define VP8_PROB_TABLE_SIZE (3840)
>
> +#define QMATRIX_SIZE (sizeof(u32) * 128 + 256)
> +#define MP2D_QPDUMP_SIZE (115200)
> +
> #define SIZE_SEI_USERDATA 4096
> #define SIZE_DOLBY_RPU_METADATA (41 * 1024)
> #define H264_CABAC_HDR_RATIO_HD_TOT 1
Reviewed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-08-26 4:50 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-09 19:36 [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
2026-07-09 19:36 ` [PATCH 1/9] media: iris: translate Gen1 profile/level to HFI enumerants Dmitry Baryshkov
2026-08-05 16:11 ` Vishnu Reddy
2026-07-09 19:36 ` [PATCH 2/9] media: iris: account for UBWC extradata in the QC08C buffer size Dmitry Baryshkov
2026-08-05 15:58 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 3/9] media: iris: add support for interlaced decoded content Dmitry Baryshkov
2026-07-09 19:37 ` [PATCH 4/9] media: iris: split Gen2 firmware data for vpu2-generation SoCs Dmitry Baryshkov
2026-08-05 17:08 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 5/9] media: iris: move the decode format list into the firmware data Dmitry Baryshkov
2026-08-26 4:09 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 6/9] media: iris: add VP8 decode support on Gen1 firmware Dmitry Baryshkov
2026-08-26 4:18 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 7/9] media: iris: add MPEG2 " Dmitry Baryshkov
2026-08-26 4:50 ` Vishnu Reddy
2026-07-09 19:37 ` [PATCH 8/9] media: iris: move the encode format list into the firmware data Dmitry Baryshkov
2026-07-09 19:37 ` [PATCH 9/9] media: iris: add VP8 encode support on Gen1 firmware Dmitry Baryshkov
2026-07-30 22:52 ` [PATCH 0/9] media: iris: enable VP8, MPEG2 and interlaced video support Dmitry Baryshkov
2026-07-31 7:37 ` Vikash Garodia
2026-07-31 12:25 ` Dmitry Baryshkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox