diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index fcfe8b275ace..cea3b470f408 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -107,6 +107,11 @@ enum session_type { MSM_VIDC_MAX_DEVICES = MSM_VIDC_UNKNOWN, }; +enum load_type { + MSM_VIDC_VIDEO = 0, + MSM_VIDC_IMAGE, +}; + union msm_v4l2_cmd { struct v4l2_decoder_cmd dec; struct v4l2_encoder_cmd enc; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3b4587f375d6..4c2e6f207b70 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -766,7 +766,8 @@ int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, } int msm_comm_get_device_load(struct msm_vidc_core *core, - enum session_type type, enum load_calc_quirks quirks) + enum session_type sess_type, enum load_type load_type, + enum load_calc_quirks quirks) { struct msm_vidc_inst *inst = NULL; int num_mbs_per_sec = 0; @@ -778,7 +779,12 @@ int msm_comm_get_device_load(struct msm_vidc_core *core, mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { - if (inst->session_type != type) + if (inst->session_type != sess_type) + continue; + + if (load_type == MSM_VIDC_VIDEO && !is_video_session(inst)) + continue; + else if (load_type == MSM_VIDC_IMAGE && !is_grid_session(inst)) continue; num_mbs_per_sec += msm_comm_get_inst_load(inst, quirks); @@ -3406,8 +3412,9 @@ static int msm_vidc_load_resources(int flipped_state, { int rc = 0; struct hfi_device *hdev; - int num_mbs_per_sec = 0, max_load_adj = 0; struct msm_vidc_core *core; + int max_video_load = 0, max_image_load = 0; + int video_load = 0, image_load = 0; enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (!inst || !inst->core || !inst->core->device) { @@ -3426,18 +3433,33 @@ static int msm_vidc_load_resources(int flipped_state, } core = inst->core; - num_mbs_per_sec = - msm_comm_get_device_load(core, MSM_VIDC_DECODER, quirks) + - msm_comm_get_device_load(core, MSM_VIDC_ENCODER, quirks); + image_load = msm_comm_get_device_load(core, + MSM_VIDC_ENCODER, MSM_VIDC_IMAGE, + quirks); + video_load = msm_comm_get_device_load(core, + MSM_VIDC_DECODER, MSM_VIDC_VIDEO, + quirks); + video_load += msm_comm_get_device_load(core, + MSM_VIDC_ENCODER, MSM_VIDC_VIDEO, + quirks); - max_load_adj = core->resources.max_load + - inst->capability.cap[CAP_MBS_PER_FRAME].max; + max_video_load = inst->core->resources.max_load + + inst->capability.cap[CAP_MBS_PER_FRAME].max; + max_image_load = inst->core->resources.max_image_load; - if (num_mbs_per_sec > max_load_adj) { - s_vpr_e(inst->sid, "HW is overloaded, needed: %d max: %d\n", - num_mbs_per_sec, max_load_adj); - msm_vidc_print_running_insts(core); - msm_comm_kill_session(inst); + if (video_load > max_video_load) { + s_vpr_e(inst->sid, + "H/W is overloaded. needed: %d max: %d\n", + video_load, max_video_load); + msm_vidc_print_running_insts(inst->core); + return -EBUSY; + } + + if (video_load + image_load > max_video_load + max_image_load) { + s_vpr_e(inst->sid, + "H/W is overloaded. needed: [video + image][%d + %d], max: [video + image][%d + %d]\n", + video_load, image_load, max_video_load, max_image_load); + msm_vidc_print_running_insts(inst->core); return -EBUSY; } @@ -5814,19 +5836,37 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) { - int num_mbs_per_sec = 0, max_load_adj = 0; + int max_video_load = 0, max_image_load = 0; + int video_load = 0, image_load = 0; enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (inst->state == MSM_VIDC_OPEN_DONE) { - max_load_adj = inst->core->resources.max_load; - num_mbs_per_sec = msm_comm_get_device_load(inst->core, - MSM_VIDC_DECODER, quirks); - num_mbs_per_sec += msm_comm_get_device_load(inst->core, - MSM_VIDC_ENCODER, quirks); - if (num_mbs_per_sec > max_load_adj) { + image_load = msm_comm_get_device_load(inst->core, + MSM_VIDC_ENCODER, MSM_VIDC_IMAGE, + quirks); + video_load = msm_comm_get_device_load(inst->core, + MSM_VIDC_DECODER, MSM_VIDC_VIDEO, + quirks); + video_load += msm_comm_get_device_load(inst->core, + MSM_VIDC_ENCODER, MSM_VIDC_VIDEO, + quirks); + + max_video_load = inst->core->resources.max_load; + max_image_load = inst->core->resources.max_image_load; + + if (video_load > max_video_load) { s_vpr_e(inst->sid, "H/W is overloaded. needed: %d max: %d\n", - num_mbs_per_sec, max_load_adj); + video_load, max_video_load); + msm_vidc_print_running_insts(inst->core); + return -EBUSY; + } + + if (video_load + image_load > max_video_load + max_image_load) { + s_vpr_e(inst->sid, + "H/W is overloaded. needed: [video + image][%d + %d], max: [video + image][%d + %d]\n", + video_load, image_load, + max_video_load, max_image_load); msm_vidc_print_running_insts(inst->core); return -EBUSY; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 124edf58c036..fa48aa7ae830 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -115,6 +115,11 @@ static inline bool is_grid_session(struct msm_vidc_inst *inst) } return 0; } + +static inline bool is_video_session(struct msm_vidc_inst *inst) +{ + return !is_grid_session(inst); +} static inline bool is_realtime_session(struct msm_vidc_inst *inst) { struct v4l2_ctrl *ctrl; @@ -260,7 +265,9 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); int msm_comm_get_device_load(struct msm_vidc_core *core, - enum session_type type, enum load_calc_quirks quirks); + enum session_type sess_type, + enum load_type load_type, + enum load_calc_quirks quirks); int msm_comm_set_color_format(struct msm_vidc_inst *inst, enum hal_buffer buffer_type, int fourcc); int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 43e7aad5b168..f86c1d0f8013 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -358,6 +358,10 @@ static struct msm_vidc_common_data lahaina_common_data[] = { * 8192x4320@48fps */ }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 173056, /* (8192x4320)/256 + (4096x2176)/256*/ @@ -472,6 +476,10 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { .key = "qcom,max-hw-load", .value = 489600, }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160, @@ -531,6 +539,10 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { .key = "qcom,max-hw-load", .value = 244800, }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160, diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 82343b0ae837..c565ee6ec708 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -757,6 +757,9 @@ int read_platform_resources_from_drv_data( res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); + res->max_image_load = find_key_value(platform_data, + "qcom,max-image-load"); + res->max_mbpf = find_key_value(platform_data, "qcom,max-mbpf"); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index a192430bbabe..c8f20b258ac2 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -154,6 +154,7 @@ struct msm_vidc_platform_resources { struct addr_set qdss_addr_set; struct buffer_usage_set buffer_usage_set; uint32_t max_load; + uint32_t max_image_load; uint32_t max_mbpf; uint32_t max_hq_mbs_per_frame; uint32_t max_hq_mbs_per_sec;