From: Vedang Nagar <quic_vnagar@xxxxxxxxxxx> Based on the hardware capabilities, add check to restrict whether the video session is supported or not by the hardware during start_streaming and queue_setup. Signed-off-by: Vedang Nagar <quic_vnagar@xxxxxxxxxxx> Signed-off-by: Dikshita Agarwal <quic_dikshita@xxxxxxxxxxx> --- .../platform/qcom/iris/iris_platform_common.h | 1 + .../platform/qcom/iris/iris_platform_sm8250.c | 1 + .../platform/qcom/iris/iris_platform_sm8550.c | 1 + drivers/media/platform/qcom/iris/iris_vb2.c | 80 ++++++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 30bc3c0e57a2..2abc96d56a4b 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -156,6 +156,7 @@ struct iris_platform_data { struct ubwc_config_data *ubwc_config; u32 num_vpp_pipe; u32 max_session_count; + u32 max_mbpf; const u32 *input_config_params; unsigned int input_config_params_size; const u32 *output_config_params; diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c index 8316f7081ce0..81f8366bcdd2 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c @@ -141,6 +141,7 @@ struct iris_platform_data sm8250_data = { .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .num_vpp_pipe = 4, .max_session_count = 16, + .max_mbpf = (8192 * 4352) / 256, .input_config_params = sm8250_vdec_input_config_param, .input_config_params_size = diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c index 3d84e1a6796c..1b7644fdd21b 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c @@ -262,6 +262,7 @@ struct iris_platform_data sm8550_data = { .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, + .max_mbpf = ((8192 * 4352) / 256) * 2, .input_config_params = sm8550_vdec_input_config_params, .input_config_params_size = diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c index 8bed24cf610e..9dfbd0d66b61 100644 --- a/drivers/media/platform/qcom/iris/iris_vb2.c +++ b/drivers/media/platform/qcom/iris/iris_vb2.c @@ -12,6 +12,78 @@ #include "iris_vb2.h" #include "iris_vdec.h" #include "iris_vpu_buffer.h" + +static int iris_check_core_mbpf(struct iris_inst *inst) +{ + struct iris_core *core = inst->core; + struct iris_inst *instance; + u32 total_mbpf = 0; + + mutex_lock(&core->lock); + list_for_each_entry(instance, &core->instances, list) + total_mbpf += iris_get_mbpf(instance); + mutex_unlock(&core->lock); + + if (total_mbpf > core->iris_platform_data->max_mbpf) + return -ENOMEM; + + return 0; +} + +static int iris_check_inst_mbpf(struct iris_inst *inst) +{ + u32 mbpf, max_mbpf; + + max_mbpf = inst->driver_cap[MBPF].max; + mbpf = iris_get_mbpf(inst); + if (mbpf > max_mbpf) + return -ENOMEM; + + return 0; +} + +static int iris_check_resolution_supported(struct iris_inst *inst) +{ + u32 width, height, min_width, min_height, max_width, max_height; + + width = inst->fmt_src->fmt.pix_mp.width; + height = inst->fmt_src->fmt.pix_mp.height; + + min_width = inst->driver_cap[FRAME_WIDTH].min; + max_width = inst->driver_cap[FRAME_WIDTH].max; + min_height = inst->driver_cap[FRAME_HEIGHT].min; + max_height = inst->driver_cap[FRAME_HEIGHT].max; + + if (!(min_width <= width && width <= max_width) || + !(min_height <= height && height <= max_height)) + return -EINVAL; + + return 0; +} + +static int iris_check_session_supported(struct iris_inst *inst) +{ + int ret; + + ret = iris_check_core_mbpf(inst); + if (ret) + goto exit; + + ret = iris_check_inst_mbpf(inst); + if (ret) + goto exit; + + ret = iris_check_resolution_supported(inst); + if (ret) + goto exit; + + return 0; +exit: + dev_err(inst->core->dev, "current session not supported(%d)\n", ret); + + return ret; +} + int iris_vb2_buf_init(struct vb2_buffer *vb2) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); @@ -69,6 +141,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q, goto unlock; } + ret = iris_check_session_supported(inst); + if (ret) + goto unlock; + if (!inst->once_per_session_set) { inst->once_per_session_set = true; @@ -144,6 +220,10 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) goto error; } + ret = iris_check_session_supported(inst); + if (ret) + goto error; + if (V4L2_TYPE_IS_OUTPUT(q->type)) ret = iris_vdec_streamon_input(inst); else if (V4L2_TYPE_IS_CAPTURE(q->type)) -- 2.34.1