Loading drivers/media/platform/msm/vidc/msm_vdec.c +31 −6 Original line number Diff line number Diff line Loading @@ -413,7 +413,16 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = OPERATING_FRAME_RATE_STEP, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, .name = "Set Decoder Frame rate", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE, Loading Loading @@ -1127,11 +1136,27 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (((ctrl->val >> 16) < inst->capability.frame_rate.min || (ctrl->val >> 16) > inst->capability.frame_rate.max) && ctrl->val != INT_MAX) { dprintk(VIDC_ERR, "Invalid operating rate %u\n", (ctrl->val >> 16)); rc = -ENOTSUPP; } else if (ctrl->val == INT_MAX) { dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n", inst); inst->clk_data.turbo_mode = true; } else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) { dprintk(VIDC_ERR, "Failed to set operating rate\n"); rc = -ENOTSUPP; } else { dprintk(VIDC_DBG, "inst(%pK) operating rate changed from %d to %d\n", inst, inst->clk_data.operating_rate >> 16, ctrl->val >> 16); inst->clk_data.operating_rate = ctrl->val; inst->clk_data.turbo_mode = false; } break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: if (ctrl->val == Loading drivers/media/platform/msm/vidc/msm_venc.c +30 −6 Original line number Diff line number Diff line Loading @@ -909,7 +909,16 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = OPERATING_FRAME_RATE_STEP, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, .name = "Set Encoder Frame rate", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE, Loading Loading @@ -1825,12 +1834,27 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (((ctrl->val >> 16) < inst->capability.frame_rate.min || (ctrl->val >> 16) > inst->capability.frame_rate.max) && ctrl->val != INT_MAX) { dprintk(VIDC_ERR, "Invalid operating rate %u\n", (ctrl->val >> 16)); rc = -ENOTSUPP; } else if (ctrl->val == INT_MAX) { dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n", inst); inst->clk_data.turbo_mode = true; } else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) { dprintk(VIDC_ERR, "Failed to set operating rate\n"); rc = -ENOTSUPP; } else { dprintk(VIDC_DBG, "inst(%pK) operating rate changed from %d to %d\n", inst, inst->clk_data.operating_rate >> 16, ctrl->val >> 16); inst->clk_data.operating_rate = ctrl->val; inst->clk_data.turbo_mode = false; } break; case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE: { Loading drivers/media/platform/msm/vidc/msm_vidc.c +4 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,10 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl) case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: msm_vidc_ctrl_get_range(ctrl, &inst->capability.slice_bytes); break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: msm_vidc_ctrl_get_range(ctrl, &inst->capability.frame_rate); break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE: case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: Loading drivers/media/platform/msm/vidc/msm_vidc_clocks.c +66 −43 Original line number Diff line number Diff line Loading @@ -569,6 +569,12 @@ static int msm_vidc_set_clocks(struct msm_vidc_core *core) mutex_lock(&core->lock); list_for_each_entry(temp, &core->instances, list) { freq += temp->clk_data.curr_freq; if (temp->clk_data.turbo_mode) { dprintk(VIDC_PROF, "Found an instance with Turbo request\n"); freq = msm_vidc_max_freq(core); break; } } for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { rate = allowed_clks_tbl[i].clock_rate; Loading @@ -587,19 +593,22 @@ static int msm_vidc_set_clocks(struct msm_vidc_core *core) return rc; } int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst) int msm_vidc_validate_operating_rate(struct msm_vidc_inst *inst, u32 operating_rate) { struct v4l2_ctrl *ctrl = NULL; struct msm_vidc_inst *temp; struct msm_vidc_core *core; unsigned long max_freq, freq_left, ops_left, load, cycles, freq = 0; unsigned long mbs_per_second; int rc = 0; u32 curr_operating_rate = 0; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s Invalid args\n", __func__); return -EINVAL; } core = inst->core; curr_operating_rate = inst->clk_data.operating_rate >> 16; mutex_lock(&core->lock); max_freq = msm_vidc_max_freq(core); Loading @@ -614,51 +623,35 @@ int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst) freq_left = max_freq - freq; list_for_each_entry(temp, &core->instances, list) { if (!temp || temp->state < MSM_VIDC_START_DONE || temp->state >= MSM_VIDC_RELEASE_RESOURCES_DONE) continue; mbs_per_second = msm_comm_get_inst_load_per_core(temp, mbs_per_second = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); cycles = temp->clk_data.entry->vpp_cycles; if (temp->session_type == MSM_VIDC_ENCODER) cycles = temp->flags & VIDC_LOW_POWER ? temp->clk_data.entry->low_power_cycles : cycles = inst->clk_data.entry->vpp_cycles; if (inst->session_type == MSM_VIDC_ENCODER) cycles = inst->flags & VIDC_LOW_POWER ? inst->clk_data.entry->low_power_cycles : cycles; load = cycles * mbs_per_second; ops_left = load ? (freq_left / load) : 0; /* Convert remaining operating rate to Q16 format */ ops_left = ops_left << 16; ctrl = v4l2_ctrl_find(&temp->ctrl_handler, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); if (ctrl) { dprintk(VIDC_DBG, "%s: Before Range = %lld --> %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum); dprintk(VIDC_DBG, "%s: Before Def value = %lld Cur val = %d\n", ctrl->name, ctrl->default_value, ctrl->val); v4l2_ctrl_modify_range(ctrl, ctrl->minimum, ctrl->val + ops_left, ctrl->step, ctrl->default_value); operating_rate = operating_rate >> 16; if ((curr_operating_rate + ops_left) >= operating_rate) { dprintk(VIDC_DBG, "%s: Updated Range = %lld --> %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum); "Requestd operating rate is valid %u\n", operating_rate); rc = 0; } else { dprintk(VIDC_DBG, "%s: Updated Def value = %lld Cur val = %d\n", ctrl->name, ctrl->default_value, ctrl->val); } "Current load is high for requested settings. Cannot set operating rate to %u\n", operating_rate); rc = -EINVAL; } mutex_unlock(&core->lock); return 0; return rc; } int msm_comm_scale_clocks(struct msm_vidc_inst *inst) Loading Loading @@ -980,8 +973,8 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, return 0; } mbs_per_frame = msm_vidc_get_mbs_per_frame(inst); if (mbs_per_frame >= inst->core->resources.max_hq_mbs_per_frame || inst->prop.fps >= inst->core->resources.max_hq_fps) { if (mbs_per_frame > inst->core->resources.max_hq_mbs_per_frame || inst->prop.fps > inst->core->resources.max_hq_fps) { enable = true; } Loading Loading @@ -1184,7 +1177,37 @@ int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst) rc = msm_comm_scale_clocks_and_bus(inst); msm_print_core_status(core, VIDC_CORE_ID_1); msm_print_core_status(core, VIDC_CORE_ID_2); return rc; } void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) { struct msm_vidc_inst *inst = NULL; dprintk(VIDC_PROF, "Instances running on core %u", core_id); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { if (!((inst->clk_data.core_id & core_id) || (inst->clk_data.core_id & VIDC_CORE_ID_3))) continue; dprintk(VIDC_PROF, "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s\n", inst, inst->prop.width[OUTPUT_PORT], inst->prop.height[OUTPUT_PORT], inst->prop.width[CAPTURE_PORT], inst->prop.height[CAPTURE_PORT], inst->prop.fps, inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC", inst->clk_data.work_mode == VIDC_WORK_MODE_1 ? "WORK_MODE_1" : "WORK_MODE_2", inst->flags & VIDC_LOW_POWER ? "LP" : "HQ", inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime"); } mutex_unlock(&core->lock); } drivers/media/platform/msm/vidc/msm_vidc_clocks.h +3 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 void msm_clock_data_reset(struct msm_vidc_inst *inst); int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst); int msm_vidc_validate_operating_rate(struct msm_vidc_inst *inst, u32 operating_rate); int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); Loading @@ -31,6 +32,7 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); void msm_comm_free_freq_table(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst); void msm_print_core_status(struct msm_vidc_core *core, u32 core_id); void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst, u32 device_addr); void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst); Loading Loading
drivers/media/platform/msm/vidc/msm_vdec.c +31 −6 Original line number Diff line number Diff line Loading @@ -413,7 +413,16 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = OPERATING_FRAME_RATE_STEP, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, .name = "Set Decoder Frame rate", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE, Loading Loading @@ -1127,11 +1136,27 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (((ctrl->val >> 16) < inst->capability.frame_rate.min || (ctrl->val >> 16) > inst->capability.frame_rate.max) && ctrl->val != INT_MAX) { dprintk(VIDC_ERR, "Invalid operating rate %u\n", (ctrl->val >> 16)); rc = -ENOTSUPP; } else if (ctrl->val == INT_MAX) { dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n", inst); inst->clk_data.turbo_mode = true; } else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) { dprintk(VIDC_ERR, "Failed to set operating rate\n"); rc = -ENOTSUPP; } else { dprintk(VIDC_DBG, "inst(%pK) operating rate changed from %d to %d\n", inst, inst->clk_data.operating_rate >> 16, ctrl->val >> 16); inst->clk_data.operating_rate = ctrl->val; inst->clk_data.turbo_mode = false; } break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: if (ctrl->val == Loading
drivers/media/platform/msm/vidc/msm_venc.c +30 −6 Original line number Diff line number Diff line Loading @@ -909,7 +909,16 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = OPERATING_FRAME_RATE_STEP, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, .name = "Set Encoder Frame rate", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = INT_MAX, .default_value = 0, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE, Loading Loading @@ -1825,12 +1834,27 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (((ctrl->val >> 16) < inst->capability.frame_rate.min || (ctrl->val >> 16) > inst->capability.frame_rate.max) && ctrl->val != INT_MAX) { dprintk(VIDC_ERR, "Invalid operating rate %u\n", (ctrl->val >> 16)); rc = -ENOTSUPP; } else if (ctrl->val == INT_MAX) { dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n", inst); inst->clk_data.turbo_mode = true; } else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) { dprintk(VIDC_ERR, "Failed to set operating rate\n"); rc = -ENOTSUPP; } else { dprintk(VIDC_DBG, "inst(%pK) operating rate changed from %d to %d\n", inst, inst->clk_data.operating_rate >> 16, ctrl->val >> 16); inst->clk_data.operating_rate = ctrl->val; inst->clk_data.turbo_mode = false; } break; case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE: { Loading
drivers/media/platform/msm/vidc/msm_vidc.c +4 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,10 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl) case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: msm_vidc_ctrl_get_range(ctrl, &inst->capability.slice_bytes); break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: msm_vidc_ctrl_get_range(ctrl, &inst->capability.frame_rate); break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE: case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: Loading
drivers/media/platform/msm/vidc/msm_vidc_clocks.c +66 −43 Original line number Diff line number Diff line Loading @@ -569,6 +569,12 @@ static int msm_vidc_set_clocks(struct msm_vidc_core *core) mutex_lock(&core->lock); list_for_each_entry(temp, &core->instances, list) { freq += temp->clk_data.curr_freq; if (temp->clk_data.turbo_mode) { dprintk(VIDC_PROF, "Found an instance with Turbo request\n"); freq = msm_vidc_max_freq(core); break; } } for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { rate = allowed_clks_tbl[i].clock_rate; Loading @@ -587,19 +593,22 @@ static int msm_vidc_set_clocks(struct msm_vidc_core *core) return rc; } int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst) int msm_vidc_validate_operating_rate(struct msm_vidc_inst *inst, u32 operating_rate) { struct v4l2_ctrl *ctrl = NULL; struct msm_vidc_inst *temp; struct msm_vidc_core *core; unsigned long max_freq, freq_left, ops_left, load, cycles, freq = 0; unsigned long mbs_per_second; int rc = 0; u32 curr_operating_rate = 0; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s Invalid args\n", __func__); return -EINVAL; } core = inst->core; curr_operating_rate = inst->clk_data.operating_rate >> 16; mutex_lock(&core->lock); max_freq = msm_vidc_max_freq(core); Loading @@ -614,51 +623,35 @@ int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst) freq_left = max_freq - freq; list_for_each_entry(temp, &core->instances, list) { if (!temp || temp->state < MSM_VIDC_START_DONE || temp->state >= MSM_VIDC_RELEASE_RESOURCES_DONE) continue; mbs_per_second = msm_comm_get_inst_load_per_core(temp, mbs_per_second = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); cycles = temp->clk_data.entry->vpp_cycles; if (temp->session_type == MSM_VIDC_ENCODER) cycles = temp->flags & VIDC_LOW_POWER ? temp->clk_data.entry->low_power_cycles : cycles = inst->clk_data.entry->vpp_cycles; if (inst->session_type == MSM_VIDC_ENCODER) cycles = inst->flags & VIDC_LOW_POWER ? inst->clk_data.entry->low_power_cycles : cycles; load = cycles * mbs_per_second; ops_left = load ? (freq_left / load) : 0; /* Convert remaining operating rate to Q16 format */ ops_left = ops_left << 16; ctrl = v4l2_ctrl_find(&temp->ctrl_handler, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); if (ctrl) { dprintk(VIDC_DBG, "%s: Before Range = %lld --> %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum); dprintk(VIDC_DBG, "%s: Before Def value = %lld Cur val = %d\n", ctrl->name, ctrl->default_value, ctrl->val); v4l2_ctrl_modify_range(ctrl, ctrl->minimum, ctrl->val + ops_left, ctrl->step, ctrl->default_value); operating_rate = operating_rate >> 16; if ((curr_operating_rate + ops_left) >= operating_rate) { dprintk(VIDC_DBG, "%s: Updated Range = %lld --> %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum); "Requestd operating rate is valid %u\n", operating_rate); rc = 0; } else { dprintk(VIDC_DBG, "%s: Updated Def value = %lld Cur val = %d\n", ctrl->name, ctrl->default_value, ctrl->val); } "Current load is high for requested settings. Cannot set operating rate to %u\n", operating_rate); rc = -EINVAL; } mutex_unlock(&core->lock); return 0; return rc; } int msm_comm_scale_clocks(struct msm_vidc_inst *inst) Loading Loading @@ -980,8 +973,8 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, return 0; } mbs_per_frame = msm_vidc_get_mbs_per_frame(inst); if (mbs_per_frame >= inst->core->resources.max_hq_mbs_per_frame || inst->prop.fps >= inst->core->resources.max_hq_fps) { if (mbs_per_frame > inst->core->resources.max_hq_mbs_per_frame || inst->prop.fps > inst->core->resources.max_hq_fps) { enable = true; } Loading Loading @@ -1184,7 +1177,37 @@ int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst) rc = msm_comm_scale_clocks_and_bus(inst); msm_print_core_status(core, VIDC_CORE_ID_1); msm_print_core_status(core, VIDC_CORE_ID_2); return rc; } void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) { struct msm_vidc_inst *inst = NULL; dprintk(VIDC_PROF, "Instances running on core %u", core_id); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { if (!((inst->clk_data.core_id & core_id) || (inst->clk_data.core_id & VIDC_CORE_ID_3))) continue; dprintk(VIDC_PROF, "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s\n", inst, inst->prop.width[OUTPUT_PORT], inst->prop.height[OUTPUT_PORT], inst->prop.width[CAPTURE_PORT], inst->prop.height[CAPTURE_PORT], inst->prop.fps, inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC", inst->clk_data.work_mode == VIDC_WORK_MODE_1 ? "WORK_MODE_1" : "WORK_MODE_2", inst->flags & VIDC_LOW_POWER ? "LP" : "HQ", inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime"); } mutex_unlock(&core->lock); }
drivers/media/platform/msm/vidc/msm_vidc_clocks.h +3 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 void msm_clock_data_reset(struct msm_vidc_inst *inst); int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst); int msm_vidc_validate_operating_rate(struct msm_vidc_inst *inst, u32 operating_rate); int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); Loading @@ -31,6 +32,7 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); void msm_comm_free_freq_table(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst); void msm_print_core_status(struct msm_vidc_core *core, u32 core_id); void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst, u32 device_addr); void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst); Loading