@@ -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;
@@ -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 =
@@ -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 =
@@ -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))