summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDikshita Agarwal <quic_dikshita@quicinc.com>2025-08-25 12:30:40 +0530
committerHans Verkuil <hverkuil+cisco@kernel.org>2025-09-10 09:02:36 +0200
commita6882431a138ac352a6e20ec3b85f97f84501329 (patch)
tree55c1cf1ad3d62af99cae623ba7a8f630afb63b1c
parent63357cf8a9c09c527ba8c7f8befe57b3144c45e3 (diff)
media: iris: Add support for ENUM_FRAMESIZES/FRAMEINTERVALS for encoder
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>
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_common.h5
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_gen2.c3
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_sm8250.c1
-rw-r--r--drivers/media/platform/qcom/iris/iris_vdec.c13
-rw-r--r--drivers/media/platform/qcom/iris/iris_vdec.h1
-rw-r--r--drivers/media/platform/qcom/iris/iris_venc.c13
-rw-r--r--drivers/media/platform/qcom/iris/iris_venc.h1
-rw-r--r--drivers/media/platform/qcom/iris/iris_vidc.c58
8 files changed, 91 insertions, 4 deletions
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index fd5a6e69e01c..b555542c870f 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -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;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index c7c384fce233..39c46c8b972f 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -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 =
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
index 8d0816a67ae0..2a3cbe1f2d4b 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
@@ -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 =
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
index b4ad5df62bcd..f1bc928043ac 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -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;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h
index b24932dc511a..097e02bfa72b 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -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);
diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c
index 40f7990cd162..55938050249f 100644
--- a/drivers/media/platform/qcom/iris/iris_venc.c
+++ b/drivers/media/platform/qcom/iris/iris_venc.c
@@ -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;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_venc.h b/drivers/media/platform/qcom/iris/iris_venc.h
index eb26a3ecbd98..04fd41275547 100644
--- a/drivers/media/platform/qcom/iris/iris_venc.h
+++ b/drivers/media/platform/qcom/iris/iris_venc.h
@@ -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
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c
index 7adb82186cac..3f641782e932 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -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)