]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: iris: Add support for ENUM_FRAMESIZES/FRAMEINTERVALS for encoder
authorDikshita Agarwal <quic_dikshita@quicinc.com>
Mon, 25 Aug 2025 07:00:40 +0000 (12:30 +0530)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Wed, 10 Sep 2025 07:02:36 +0000 (09:02 +0200)
Add support for frame size and frame interval enumeration by
implementing ENUM_FRAMESIZES/FRAMEINTERVALS V4L2 ioctls for encoder
video device with necessary hooks.

This allows userspace application to query encoder capabilities and
adapt encoding configurations accordingly.

Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # X1E80100
Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e80100-crd
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/qcom/iris/iris_platform_common.h
drivers/media/platform/qcom/iris/iris_platform_gen2.c
drivers/media/platform/qcom/iris/iris_platform_sm8250.c
drivers/media/platform/qcom/iris/iris_vdec.c
drivers/media/platform/qcom/iris/iris_vdec.h
drivers/media/platform/qcom/iris/iris_venc.c
drivers/media/platform/qcom/iris/iris_venc.h
drivers/media/platform/qcom/iris/iris_vidc.c

index fd5a6e69e01cfd00253f4ffb282d40112b93073b..b555542c870f372f72609e7fda3f368d08ac7500 100644 (file)
@@ -21,7 +21,8 @@ struct iris_inst;
 #define DEFAULT_MAX_HOST_BUF_COUNT             64
 #define DEFAULT_MAX_HOST_BURST_BUF_COUNT       256
 #define DEFAULT_FPS                            30
-#define NUM_MBS_8K                             ((8192 * 4352) / 256)
+#define MAXIMUM_FPS                            480
+#define NUM_MBS_8K                             ((8192 * 4352) / 256)
 
 enum stage_type {
        STAGE_1 = 1,
@@ -183,6 +184,8 @@ struct iris_platform_data {
        u32 max_session_count;
        /* max number of macroblocks per frame supported */
        u32 max_core_mbpf;
+       /* max number of macroblocks per second supported */
+       u32 max_core_mbps;
        const u32 *input_config_params_default;
        unsigned int input_config_params_default_size;
        const u32 *input_config_params_hevc;
index c7c384fce2332255ea96da69ef4dc0bc1a24771c..39c46c8b972f7bc87d9a9e3db8833df3efb8fcea 100644 (file)
@@ -356,6 +356,7 @@ struct iris_platform_data sm8550_data = {
        .num_vpp_pipe = 4,
        .max_session_count = 16,
        .max_core_mbpf = NUM_MBS_8K * 2,
+       .max_core_mbps = ((7680 * 4320) / 256) * 60,
        .input_config_params_default =
                sm8550_vdec_input_config_params_default,
        .input_config_params_default_size =
@@ -431,6 +432,7 @@ struct iris_platform_data sm8650_data = {
        .num_vpp_pipe = 4,
        .max_session_count = 16,
        .max_core_mbpf = NUM_MBS_8K * 2,
+       .max_core_mbps = ((7680 * 4320) / 256) * 60,
        .input_config_params_default =
                sm8550_vdec_input_config_params_default,
        .input_config_params_default_size =
@@ -568,6 +570,7 @@ struct iris_platform_data qcs8300_data = {
        .num_vpp_pipe = 2,
        .max_session_count = 16,
        .max_core_mbpf = ((4096 * 2176) / 256) * 4,
+       .max_core_mbps = (((3840 * 2176) / 256) * 120),
        .input_config_params_default =
                sm8550_vdec_input_config_params_default,
        .input_config_params_default_size =
index 8d0816a67ae0b6886204ce93fa5ccafaac10392a..2a3cbe1f2d4b27d3cce9e9cdad1525801d71a041 100644 (file)
@@ -128,6 +128,7 @@ struct iris_platform_data sm8250_data = {
        .num_vpp_pipe = 4,
        .max_session_count = 16,
        .max_core_mbpf = NUM_MBS_8K,
+       .max_core_mbps = ((7680 * 4320) / 256) * 60,
        .input_config_params_default =
                sm8250_vdec_input_config_param_default,
        .input_config_params_default_size =
index b4ad5df62bcd1ee390ce4f7c1c58c8693d0ab0ca..f1bc928043acea9aae7bbb960448adec9e7a4880 100644 (file)
@@ -263,6 +263,19 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
        return 0;
 }
 
+int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat)
+{
+       const struct iris_fmt *fmt = NULL;
+
+       if (pixelformat != V4L2_PIX_FMT_NV12) {
+               fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+               if (!fmt)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
 {
        int ret = 0;
index b24932dc511a65017b1cadbcb984544475bd0723..097e02bfa72b5ac4e46e66c61842df1d9dd4565b 100644 (file)
@@ -13,6 +13,7 @@ void iris_vdec_inst_deinit(struct iris_inst *inst);
 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat);
 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub);
 void iris_vdec_src_change(struct iris_inst *inst);
 int iris_vdec_streamon_input(struct iris_inst *inst);
index 40f7990cd162ad400711d729917b7e2577d562b2..55938050249fa1a041b835214e79028ae0b35e36 100644 (file)
@@ -273,3 +273,16 @@ int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
                return -EINVAL;
        }
 }
+
+int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat)
+{
+       const struct iris_fmt *fmt = NULL;
+
+       if (pixelformat != V4L2_PIX_FMT_NV12) {
+               fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+               if (!fmt)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
index eb26a3ecbd98b3f02dfdea0dfc41bcd3a90904b6..04fd41275547c40c359c6ea04dfe4ee31d2d0df6 100644 (file)
@@ -13,5 +13,6 @@ void iris_venc_inst_deinit(struct iris_inst *inst);
 int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
 int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat);
 
 #endif
index 7adb82186cac540919463fd6d6be85b42eeb73db..3f641782e932a30af46c631003a72d7dd2b4386e 100644 (file)
@@ -371,13 +371,18 @@ static int iris_enum_framesizes(struct file *filp, void *fh,
 {
        struct iris_inst *inst = iris_get_inst(filp);
        struct platform_inst_caps *caps;
+       int ret = 0;
 
        if (fsize->index)
                return -EINVAL;
 
-       if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
-           fsize->pixel_format != V4L2_PIX_FMT_NV12)
-               return -EINVAL;
+       if (inst->domain == DECODER)
+               ret = iris_vdec_validate_format(inst, fsize->pixel_format);
+       else
+               ret = iris_venc_validate_format(inst, fsize->pixel_format);
+
+       if (ret)
+               return ret;
 
        caps = inst->core->iris_platform_data->inst_caps;
 
@@ -389,6 +394,51 @@ static int iris_enum_framesizes(struct file *filp, void *fh,
        fsize->stepwise.max_height = caps->max_frame_height;
        fsize->stepwise.step_height = STEP_HEIGHT;
 
+       return ret;
+}
+
+static int iris_enum_frameintervals(struct file *filp, void *fh,
+                                   struct v4l2_frmivalenum *fival)
+
+{
+       struct iris_inst *inst = iris_get_inst(filp);
+       struct iris_core *core = inst->core;
+       struct platform_inst_caps *caps;
+       u32 fps, mbpf;
+       int ret = 0;
+
+       if (inst->domain == DECODER)
+               return -ENOTTY;
+
+       if (fival->index)
+               return -EINVAL;
+
+       ret = iris_venc_validate_format(inst, fival->pixel_format);
+       if (ret)
+               return ret;
+
+       if (!fival->width || !fival->height)
+               return -EINVAL;
+
+       caps = inst->core->iris_platform_data->inst_caps;
+       if (fival->width > caps->max_frame_width ||
+           fival->width < caps->min_frame_width ||
+           fival->height > caps->max_frame_height ||
+           fival->height < caps->min_frame_height)
+               return -EINVAL;
+
+       mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width);
+       fps = DIV_ROUND_UP(core->iris_platform_data->max_core_mbps, mbpf);
+
+       fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+       fival->stepwise.min.numerator = 1;
+       fival->stepwise.min.denominator =
+                       min_t(u32, fps, MAXIMUM_FPS);
+       fival->stepwise.max.numerator = 1;
+       fival->stepwise.max.denominator = 1;
+       fival->stepwise.step.numerator = 1;
+       fival->stepwise.step.denominator = MAXIMUM_FPS;
+
        return 0;
 }
 
@@ -523,6 +573,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_enc = {
        .vidioc_s_fmt_vid_out_mplane    = iris_s_fmt_vid_mplane,
        .vidioc_g_fmt_vid_cap_mplane    = iris_g_fmt_vid_mplane,
        .vidioc_g_fmt_vid_out_mplane    = iris_g_fmt_vid_mplane,
+       .vidioc_enum_framesizes         = iris_enum_framesizes,
+       .vidioc_enum_frameintervals     = iris_enum_frameintervals,
 };
 
 void iris_init_ops(struct iris_core *core)