Loading drivers/media/platform/msm/vidc/msm_vdec.c +1 −1 Original line number Diff line number Diff line Loading @@ -878,7 +878,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = (bool)ctrl->val; inst->clk_data.low_latency_mode = !!ctrl->val; break; default: dprintk(VIDC_ERR, Loading drivers/media/platform/msm/vidc/msm_venc.c +1 −35 Original line number Diff line number Diff line Loading @@ -1444,7 +1444,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = (bool)ctrl->val; inst->clk_data.low_latency_mode = !!ctrl->val; break; case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO: { u32 info_type = (ctrl->val >> 28); Loading Loading @@ -2857,37 +2857,6 @@ int msm_venc_set_video_csc(struct msm_vidc_inst *inst) return rc; } int msm_venc_set_low_latency_mode(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hal_enable enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; ctrl = msm_venc_get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE); if (!ctrl) { dprintk(VIDC_ERR, "%s: get lowlatency mode failed\n", __func__); return -EINVAL; } enable.enable = !!ctrl->val; dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HAL_PARAM_VENC_LOW_LATENCY, &enable); if (rc) dprintk(VIDC_ERR, "%s: set property failed\n", __func__); return rc; } int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) { int rc = 0; Loading Loading @@ -3382,9 +3351,6 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_vpx_error_resilience(inst); if (rc) goto exit; rc = msm_venc_set_low_latency_mode(inst); if (rc) goto exit; rc = msm_venc_set_video_signal_info(inst); Loading drivers/media/platform/msm/vidc/msm_vidc.c +9 −19 Original line number Diff line number Diff line Loading @@ -943,13 +943,7 @@ int msm_vidc_set_internal_config(struct msm_vidc_inst *inst) rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size); latency.enable = true; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VENC_LOW_LATENCY, (void *)&latency); inst->clk_data.low_latency_mode = latency.enable; inst->clk_data.low_latency_mode = true; } /* Update Slice Config */ Loading Loading @@ -1144,19 +1138,20 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } /* Decide work route for current session */ rc = call_core_op(inst->core, decide_work_route, inst); /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); if (rc) { dprintk(VIDC_ERR, "Failed to decide work route for session %pK\n", inst); "Failed to decide work mode for session %pK\n", inst); goto fail_start; } /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); /* Decide work route for current session */ rc = call_core_op(inst->core, decide_work_route, inst); if (rc) { dprintk(VIDC_ERR, "Failed to decide work mode for session %pK\n", inst); "Failed to decide work route for session %pK\n", inst); goto fail_start; } Loading Loading @@ -1898,17 +1893,12 @@ void *msm_vidc_open(int core_id, int session_type) inst->session_type = session_type; inst->state = MSM_VIDC_CORE_UNINIT_DONE; inst->core = core; inst->clk_data.min_freq = 0; inst->clk_data.curr_freq = 0; inst->clk_data.ddr_bw = 0; inst->clk_data.sys_cache_bw = 0; inst->clk_data.bitrate = 0; inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; inst->bit_depth = MSM_VIDC_BIT_DEPTH_8; inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE; inst->colour_space = MSM_VIDC_BT601_6_525; inst->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN; inst->entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; inst->smem_ops = &msm_vidc_smem_ops; Loading drivers/media/platform/msm/vidc/msm_vidc_clocks.c +237 −13 Original line number Diff line number Diff line Loading @@ -14,22 +14,30 @@ #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) #define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, u32 filled_len); static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, u32 filled_len); static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len); struct msm_vidc_core_ops core_ops_vpu4 = { struct msm_vidc_core_ops core_ops_ar50 = { .calc_freq = msm_vidc_calc_freq_ar50, .decide_work_route = NULL, .decide_work_mode = msm_vidc_decide_work_mode_ar50, }; struct msm_vidc_core_ops core_ops_vpu5 = { .calc_freq = msm_vidc_calc_freq, .decide_work_route = msm_vidc_decide_work_route, .decide_work_mode = msm_vidc_decide_work_mode, struct msm_vidc_core_ops core_ops_iris1 = { .calc_freq = msm_vidc_calc_freq_iris1, .decide_work_route = msm_vidc_decide_work_route_iris1, .decide_work_mode = msm_vidc_decide_work_mode_iris1, }; struct msm_vidc_core_ops core_ops_iris2 = { .calc_freq = msm_vidc_calc_freq_iris2, .decide_work_route = msm_vidc_decide_work_route_iris2, .decide_work_mode = msm_vidc_decide_work_mode_iris2, }; static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) Loading Loading @@ -609,7 +617,99 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, return (unsigned long) freq; } static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, u32 filled_len) { u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; u32 vpp_cycles_per_mb; u32 mbs_per_second; struct msm_vidc_core *core = NULL; int i = 0; struct allowed_clock_rates_table *allowed_clks_tbl = NULL; u64 rate = 0, fps; struct clock_data *dcvs = NULL; u32 operating_rate, vsp_factor_num = 10, vsp_factor_den = 5; core = inst->core; dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); fps = msm_vidc_get_fps(inst); /* * Calculate vpp, vsp, fw cycles separately for encoder and decoder. * Even though, most part is common now, in future it may change * between them. */ if (inst->session_type == MSM_VIDC_ENCODER) { vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; vpp_cycles = mbs_per_second * vpp_cycles_per_mb; /* 21 / 20 is overhead factor */ vpp_cycles = (vpp_cycles * 21)/ (inst->clk_data.work_route * 20); vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* bitrate is based on fps, scale it using operating rate */ operating_rate = inst->clk_data.operating_rate >> 16; if (operating_rate > inst->prop.fps && inst->prop.fps) { vsp_factor_num *= operating_rate; vsp_factor_den *= inst->prop.fps; } vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / vsp_factor_den; fw_cycles = fps * inst->core->resources.fw_cycles; } else if (inst->session_type == MSM_VIDC_DECODER) { vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles; /* 21 / 20 is overhead factor */ vpp_cycles = (vpp_cycles * 21)/ (inst->clk_data.work_route * 20); vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* vsp perf is about 0.5 bits/cycle */ vsp_cycles += ((fps * filled_len * 8) * 10) / 5; fw_cycles = fps * inst->core->resources.fw_cycles; } else { dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); return msm_vidc_max_freq(inst->core); } freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); allowed_clks_tbl = core->resources.allowed_clks_tbl; for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { rate = allowed_clks_tbl[i].clock_rate; if (rate >= freq) break; } dcvs->load_norm = rate; dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm; dprintk(VIDC_PROF, "%s: inst %pK: %x : filled len %d required freq %lu load_norm %lu\n", __func__, inst, hash32_ptr(inst->session), filled_len, freq, dcvs->load_norm); return (unsigned long) freq; } static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len) { u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; Loading Loading @@ -1131,7 +1231,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, return count; } int msm_vidc_decide_work_route(struct msm_vidc_inst *inst) int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; Loading Loading @@ -1209,6 +1309,71 @@ int msm_vidc_decide_work_route(struct msm_vidc_inst *inst) return rc; } int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct hal_video_work_route pdata; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; pdata.video_work_route = 4; if (inst->session_type == MSM_VIDC_DECODER) { if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) pdata.video_work_route = 1; } else if (inst->session_type == MSM_VIDC_ENCODER) { u32 slice_mode, rc_mode; u32 output_width, output_height, fps, mbps; bool cbr_plus; if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { pdata.video_work_route = 1; goto decision_done; } rc_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); slice_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); output_height = inst->prop.height[CAPTURE_PORT]; output_width = inst->prop.width[CAPTURE_PORT]; fps = inst->prop.fps; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); cbr_plus = ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps > CBR_MB_LIMIT) || (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps > CBR_VFR_MB_LIMIT)); if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || ((mbps <= NUM_MBS_PER_SEC(1920, 1088, 60)) && !cbr_plus) ) { pdata.video_work_route = 1; dprintk(VIDC_DBG, "Configured work route = 1"); } } else { return -EINVAL; } decision_done: inst->clk_data.work_route = pdata.video_work_route; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VIDEO_WORK_ROUTE, (void *)&pdata); if (rc) dprintk(VIDC_WARN, " Failed to configure work route %pK\n", inst); return rc; } static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) { int rc = 0; Loading Loading @@ -1274,7 +1439,7 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) return rc; } int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst) int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; Loading Loading @@ -1354,6 +1519,63 @@ int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst) return rc; } int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct hal_video_work_mode pdata; struct hal_enable latency; u32 num_mbs = 0; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; pdata.video_work_mode = VIDC_WORK_MODE_2; if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = VIDC_WORK_MODE_1; dprintk(VIDC_DBG, "Configured work mode = 1"); } else if (inst->session_type == MSM_VIDC_DECODER) { num_mbs = NUM_MBS_PER_FRAME( inst->prop.height[OUTPUT_PORT], inst->prop.width[OUTPUT_PORT]); if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || (inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || (num_mbs < NUM_MBS_PER_FRAME(720, 1280))) pdata.video_work_mode = VIDC_WORK_MODE_1; } else if (inst->session_type == MSM_VIDC_ENCODER && inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { pdata.video_work_mode = VIDC_WORK_MODE_1; /* For WORK_MODE_1, set Low Latency mode by default to HW. */ inst->clk_data.low_latency_mode = true; } else { return -EINVAL; } inst->clk_data.work_mode = pdata.video_work_mode; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VIDEO_WORK_MODE, (void *)&pdata); if (rc) dprintk(VIDC_WARN, " Failed to configure Work Mode %pK\n", inst); if (inst->clk_data.low_latency_mode && inst->session_type == MSM_VIDC_ENCODER){ latency.enable = true; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VENC_LOW_LATENCY, (void *)&latency); } return rc; } static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, bool enable) { Loading Loading @@ -1608,10 +1830,12 @@ void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) if (!core) return; if (core->platform_data->vpu_ver == VPU_VERSION_4) core->core_ops = &core_ops_vpu4; if (core->platform_data->vpu_ver == VPU_VERSION_AR50) core->core_ops = &core_ops_ar50; else if (core->platform_data->vpu_ver == VPU_VERSION_IRIS1) core->core_ops = &core_ops_iris1; else core->core_ops = &core_ops_vpu5; core->core_ops = &core_ops_iris2; } void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) Loading drivers/media/platform/msm/vidc/msm_vidc_clocks.h +4 −2 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); 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_route(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris2(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, Loading Loading
drivers/media/platform/msm/vidc/msm_vdec.c +1 −1 Original line number Diff line number Diff line Loading @@ -878,7 +878,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = (bool)ctrl->val; inst->clk_data.low_latency_mode = !!ctrl->val; break; default: dprintk(VIDC_ERR, Loading
drivers/media/platform/msm/vidc/msm_venc.c +1 −35 Original line number Diff line number Diff line Loading @@ -1444,7 +1444,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = (bool)ctrl->val; inst->clk_data.low_latency_mode = !!ctrl->val; break; case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO: { u32 info_type = (ctrl->val >> 28); Loading Loading @@ -2857,37 +2857,6 @@ int msm_venc_set_video_csc(struct msm_vidc_inst *inst) return rc; } int msm_venc_set_low_latency_mode(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hal_enable enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; ctrl = msm_venc_get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE); if (!ctrl) { dprintk(VIDC_ERR, "%s: get lowlatency mode failed\n", __func__); return -EINVAL; } enable.enable = !!ctrl->val; dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HAL_PARAM_VENC_LOW_LATENCY, &enable); if (rc) dprintk(VIDC_ERR, "%s: set property failed\n", __func__); return rc; } int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) { int rc = 0; Loading Loading @@ -3382,9 +3351,6 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_vpx_error_resilience(inst); if (rc) goto exit; rc = msm_venc_set_low_latency_mode(inst); if (rc) goto exit; rc = msm_venc_set_video_signal_info(inst); Loading
drivers/media/platform/msm/vidc/msm_vidc.c +9 −19 Original line number Diff line number Diff line Loading @@ -943,13 +943,7 @@ int msm_vidc_set_internal_config(struct msm_vidc_inst *inst) rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size); latency.enable = true; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VENC_LOW_LATENCY, (void *)&latency); inst->clk_data.low_latency_mode = latency.enable; inst->clk_data.low_latency_mode = true; } /* Update Slice Config */ Loading Loading @@ -1144,19 +1138,20 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } /* Decide work route for current session */ rc = call_core_op(inst->core, decide_work_route, inst); /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); if (rc) { dprintk(VIDC_ERR, "Failed to decide work route for session %pK\n", inst); "Failed to decide work mode for session %pK\n", inst); goto fail_start; } /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); /* Decide work route for current session */ rc = call_core_op(inst->core, decide_work_route, inst); if (rc) { dprintk(VIDC_ERR, "Failed to decide work mode for session %pK\n", inst); "Failed to decide work route for session %pK\n", inst); goto fail_start; } Loading Loading @@ -1898,17 +1893,12 @@ void *msm_vidc_open(int core_id, int session_type) inst->session_type = session_type; inst->state = MSM_VIDC_CORE_UNINIT_DONE; inst->core = core; inst->clk_data.min_freq = 0; inst->clk_data.curr_freq = 0; inst->clk_data.ddr_bw = 0; inst->clk_data.sys_cache_bw = 0; inst->clk_data.bitrate = 0; inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; inst->bit_depth = MSM_VIDC_BIT_DEPTH_8; inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE; inst->colour_space = MSM_VIDC_BT601_6_525; inst->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN; inst->entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; inst->smem_ops = &msm_vidc_smem_ops; Loading
drivers/media/platform/msm/vidc/msm_vidc_clocks.c +237 −13 Original line number Diff line number Diff line Loading @@ -14,22 +14,30 @@ #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) #define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, u32 filled_len); static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, u32 filled_len); static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len); struct msm_vidc_core_ops core_ops_vpu4 = { struct msm_vidc_core_ops core_ops_ar50 = { .calc_freq = msm_vidc_calc_freq_ar50, .decide_work_route = NULL, .decide_work_mode = msm_vidc_decide_work_mode_ar50, }; struct msm_vidc_core_ops core_ops_vpu5 = { .calc_freq = msm_vidc_calc_freq, .decide_work_route = msm_vidc_decide_work_route, .decide_work_mode = msm_vidc_decide_work_mode, struct msm_vidc_core_ops core_ops_iris1 = { .calc_freq = msm_vidc_calc_freq_iris1, .decide_work_route = msm_vidc_decide_work_route_iris1, .decide_work_mode = msm_vidc_decide_work_mode_iris1, }; struct msm_vidc_core_ops core_ops_iris2 = { .calc_freq = msm_vidc_calc_freq_iris2, .decide_work_route = msm_vidc_decide_work_route_iris2, .decide_work_mode = msm_vidc_decide_work_mode_iris2, }; static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) Loading Loading @@ -609,7 +617,99 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, return (unsigned long) freq; } static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst, static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, u32 filled_len) { u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; u32 vpp_cycles_per_mb; u32 mbs_per_second; struct msm_vidc_core *core = NULL; int i = 0; struct allowed_clock_rates_table *allowed_clks_tbl = NULL; u64 rate = 0, fps; struct clock_data *dcvs = NULL; u32 operating_rate, vsp_factor_num = 10, vsp_factor_den = 5; core = inst->core; dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); fps = msm_vidc_get_fps(inst); /* * Calculate vpp, vsp, fw cycles separately for encoder and decoder. * Even though, most part is common now, in future it may change * between them. */ if (inst->session_type == MSM_VIDC_ENCODER) { vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; vpp_cycles = mbs_per_second * vpp_cycles_per_mb; /* 21 / 20 is overhead factor */ vpp_cycles = (vpp_cycles * 21)/ (inst->clk_data.work_route * 20); vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* bitrate is based on fps, scale it using operating rate */ operating_rate = inst->clk_data.operating_rate >> 16; if (operating_rate > inst->prop.fps && inst->prop.fps) { vsp_factor_num *= operating_rate; vsp_factor_den *= inst->prop.fps; } vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / vsp_factor_den; fw_cycles = fps * inst->core->resources.fw_cycles; } else if (inst->session_type == MSM_VIDC_DECODER) { vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles; /* 21 / 20 is overhead factor */ vpp_cycles = (vpp_cycles * 21)/ (inst->clk_data.work_route * 20); vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* vsp perf is about 0.5 bits/cycle */ vsp_cycles += ((fps * filled_len * 8) * 10) / 5; fw_cycles = fps * inst->core->resources.fw_cycles; } else { dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); return msm_vidc_max_freq(inst->core); } freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); allowed_clks_tbl = core->resources.allowed_clks_tbl; for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { rate = allowed_clks_tbl[i].clock_rate; if (rate >= freq) break; } dcvs->load_norm = rate; dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm; dprintk(VIDC_PROF, "%s: inst %pK: %x : filled len %d required freq %lu load_norm %lu\n", __func__, inst, hash32_ptr(inst->session), filled_len, freq, dcvs->load_norm); return (unsigned long) freq; } static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len) { u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; Loading Loading @@ -1131,7 +1231,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, return count; } int msm_vidc_decide_work_route(struct msm_vidc_inst *inst) int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; Loading Loading @@ -1209,6 +1309,71 @@ int msm_vidc_decide_work_route(struct msm_vidc_inst *inst) return rc; } int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct hal_video_work_route pdata; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; pdata.video_work_route = 4; if (inst->session_type == MSM_VIDC_DECODER) { if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) pdata.video_work_route = 1; } else if (inst->session_type == MSM_VIDC_ENCODER) { u32 slice_mode, rc_mode; u32 output_width, output_height, fps, mbps; bool cbr_plus; if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { pdata.video_work_route = 1; goto decision_done; } rc_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); slice_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); output_height = inst->prop.height[CAPTURE_PORT]; output_width = inst->prop.width[CAPTURE_PORT]; fps = inst->prop.fps; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); cbr_plus = ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps > CBR_MB_LIMIT) || (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps > CBR_VFR_MB_LIMIT)); if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || ((mbps <= NUM_MBS_PER_SEC(1920, 1088, 60)) && !cbr_plus) ) { pdata.video_work_route = 1; dprintk(VIDC_DBG, "Configured work route = 1"); } } else { return -EINVAL; } decision_done: inst->clk_data.work_route = pdata.video_work_route; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VIDEO_WORK_ROUTE, (void *)&pdata); if (rc) dprintk(VIDC_WARN, " Failed to configure work route %pK\n", inst); return rc; } static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) { int rc = 0; Loading Loading @@ -1274,7 +1439,7 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) return rc; } int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst) int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; Loading Loading @@ -1354,6 +1519,63 @@ int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst) return rc; } int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct hal_video_work_mode pdata; struct hal_enable latency; u32 num_mbs = 0; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; pdata.video_work_mode = VIDC_WORK_MODE_2; if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = VIDC_WORK_MODE_1; dprintk(VIDC_DBG, "Configured work mode = 1"); } else if (inst->session_type == MSM_VIDC_DECODER) { num_mbs = NUM_MBS_PER_FRAME( inst->prop.height[OUTPUT_PORT], inst->prop.width[OUTPUT_PORT]); if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || (inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || (num_mbs < NUM_MBS_PER_FRAME(720, 1280))) pdata.video_work_mode = VIDC_WORK_MODE_1; } else if (inst->session_type == MSM_VIDC_ENCODER && inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { pdata.video_work_mode = VIDC_WORK_MODE_1; /* For WORK_MODE_1, set Low Latency mode by default to HW. */ inst->clk_data.low_latency_mode = true; } else { return -EINVAL; } inst->clk_data.work_mode = pdata.video_work_mode; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VIDEO_WORK_MODE, (void *)&pdata); if (rc) dprintk(VIDC_WARN, " Failed to configure Work Mode %pK\n", inst); if (inst->clk_data.low_latency_mode && inst->session_type == MSM_VIDC_ENCODER){ latency.enable = true; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HAL_PARAM_VENC_LOW_LATENCY, (void *)&latency); } return rc; } static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, bool enable) { Loading Loading @@ -1608,10 +1830,12 @@ void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) if (!core) return; if (core->platform_data->vpu_ver == VPU_VERSION_4) core->core_ops = &core_ops_vpu4; if (core->platform_data->vpu_ver == VPU_VERSION_AR50) core->core_ops = &core_ops_ar50; else if (core->platform_data->vpu_ver == VPU_VERSION_IRIS1) core->core_ops = &core_ops_iris1; else core->core_ops = &core_ops_vpu5; core->core_ops = &core_ops_iris2; } void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) Loading
drivers/media/platform/msm/vidc/msm_vidc_clocks.h +4 −2 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); 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_route(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris2(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, Loading