u32 res_trk_power_down(void) { VCDRES_MSG_LOW("clk_regime_rail_disable"); #ifdef AXI_CLK_SCALING VCDRES_MSG_MED("\n res_trk_power_down()::" "Calling AXI remove requirement\n"); clk_disable_unprepare(ebi1_clk); clk_put(ebi1_clk); #endif VCDRES_MSG_MED("\n res_trk_power_down():: Calling " "res_trk_disable_videocore()\n"); return res_trk_disable_videocore(); }
static u32 res_trk_convert_perf_lvl_to_freq(u64 perf_lvl) { u64 freq, temp; VCDRES_MSG_MED("\n %s():: perf_lvl = %u\n", __func__, (u32)perf_lvl); temp = (perf_lvl * VCD_RESTRK_HZ_PER_1000_PERFLVL) + 999; do_div(temp, 1000); freq = (u32)temp; VCDRES_MSG_MED("\n %s(): freq = %u\n", __func__, (u32)freq); return (u32)freq; }
u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, struct vcd_dev_ctxt *dev_ctxt) { u32 vidc_freq = 0; if (!pn_set_perf_lvl || !dev_ctxt) { VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", __func__, dev_ctxt); return false; } VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); #ifdef CONFIG_MSM_BUS_SCALING if (!res_trk_update_bus_perf_level(dev_ctxt, req_perf_lvl) < 0) { VCDRES_MSG_ERROR("%s(): update buf perf level failed\n", __func__); return false; } #endif if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) req_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; if (req_perf_lvl <= RESTRK_1080P_VGA_PERF_LEVEL) { vidc_freq = vidc_clk_table[0]; *pn_set_perf_lvl = RESTRK_1080P_VGA_PERF_LEVEL; } else if (req_perf_lvl <= RESTRK_1080P_720P_PERF_LEVEL) { vidc_freq = vidc_clk_table[1]; *pn_set_perf_lvl = RESTRK_1080P_720P_PERF_LEVEL; } else { vidc_freq = vidc_clk_table[2]; *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; } resource_context.perf_level = *pn_set_perf_lvl; VCDRES_MSG_MED("VIDC: vidc_freq = %u, req_perf_lvl = %u\n", vidc_freq, req_perf_lvl); #ifdef USE_RES_TRACKER if (req_perf_lvl != RESTRK_1080P_MIN_PERF_LEVEL) { VCDRES_MSG_MED("%s(): Setting vidc freq to %u\n", __func__, vidc_freq); if (!res_trk_sel_clk_rate(vidc_freq)) { VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", __func__); *pn_set_perf_lvl = 0; return false; } } #endif VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl); return true; }
u32 res_trk_power_down(void) { VCDRES_MSG_LOW("clk_regime_rail_disable"); VCDRES_MSG_MED("\n res_trk_power_down():: Calling " "res_trk_disable_pwr_rail()\n"); return res_trk_disable_pwr_rail(); }
u32 res_trk_power_down(void) { VCDRES_MSG_LOW("clk_regime_rail_disable"); #ifdef AXI_CLK_SCALING VCDRES_MSG_MED("\n res_trk_power_down()::" "Calling AXI remove requirement\n"); pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ, MSM_AXI_QOS_NAME); #endif #ifdef USE_RES_TRACKER VCDRES_MSG_MED("\n res_trk_power_down():: Calling " "vid_c_disable_pwr_rail()\n"); return vid_c_disable_pwr_rail(); #endif return TRUE; }
u32 res_trk_power_up(void) { VCDRES_MSG_LOW("clk_regime_rail_enable"); VCDRES_MSG_LOW("clk_regime_sel_rail_control"); VCDRES_MSG_MED("\n res_trk_power_up():: Calling " "vidc_enable_pwr_rail()\n"); return res_trk_enable_pwr_rail(); }
static u32 res_trk_convert_freq_to_perf_lvl(u64 n_freq) { u64 n_perf_lvl; u64 n_temp; VCDRES_MSG_MED("\n %s():: n_freq = %u\n", __func__, (u32)n_freq); if (!n_freq) return 0; n_temp = n_freq * 1000; do_div(n_temp, VCD_RESTRK_HZ_PER_1000_PERFLVL); n_perf_lvl = (u32)n_temp; VCDRES_MSG_MED("\n %s(): n_perf_lvl = %u\n", __func__, (u32)n_perf_lvl); return (u32)n_perf_lvl; }
static u32 res_trk_convert_freq_to_perf_lvl(u64 freq) { u64 perf_lvl; u64 temp; VCDRES_MSG_MED("\n %s():: freq = %u\n", __func__, (u32)freq); if (!freq) return 0; temp = freq * 1000; do_div(temp, VCD_RESTRK_HZ_PER_1000_PERFLVL); perf_lvl = (u32)temp; VCDRES_MSG_MED("\n %s(): perf_lvl = %u\n", __func__, (u32)perf_lvl); return (u32)perf_lvl; }
u32 res_trk_enable_clocks(void) { VCDRES_MSG_LOW("clk_regime_msm_enable"); #ifdef USE_RES_TRACKER VCDRES_MSG_MED("\n res_trk_enable_clocks():: Calling " "vid_c_enable_clk()\n"); return vid_c_enable_clk(); #endif return TRUE; }
int res_trk_update_bus_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_level) { struct vcd_clnt_ctxt *cctxt_itr = NULL; u32 enc_perf_level = 0, dec_perf_level = 0; u32 bus_clk_index, client_type = 0; int rc = 0; bool turbo_enabled = false; bool turbo_supported = !resource_context.vidc_platform_data->disable_turbo; cctxt_itr = dev_ctxt->cctxt_list_head; while (cctxt_itr) { if (cctxt_itr->decoding) dec_perf_level += cctxt_itr->reqd_perf_lvl; else enc_perf_level += cctxt_itr->reqd_perf_lvl; if (cctxt_itr->is_turbo_enabled) turbo_enabled = true; cctxt_itr = cctxt_itr->next; } if (!enc_perf_level) client_type = 1; if (perf_level <= RESTRK_1080P_VGA_PERF_LEVEL) bus_clk_index = 0; else if (perf_level <= RESTRK_1080P_720P_PERF_LEVEL) bus_clk_index = 1; else if (perf_level <= RESTRK_1080P_MAX_PERF_LEVEL) bus_clk_index = 2; else bus_clk_index = 3; if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) bus_clk_index = 2; else if ((!turbo_supported || !turbo_enabled) && bus_clk_index == 3) { if (!turbo_supported) VCDRES_MSG_MED("Warning: Turbo mode not supported "\ " falling back to 1080p bus\n"); bus_clk_index = 2; } if (bus_clk_index == 3) dev_ctxt->turbo_mode_set = true; else dev_ctxt->turbo_mode_set = false; bus_clk_index = (bus_clk_index << 1) + (client_type + 1); VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index); VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl); VCDRES_MSG_LOW("%s(), bus_perf_level = %x", __func__, perf_level); rc = msm_bus_scale_client_update_request(resource_context.pcl, bus_clk_index); return rc; }
u32 res_trk_power_down(void) { VCDRES_MSG_LOW("clk_regime_rail_disable"); #ifdef CONFIG_MSM_BUS_SCALING msm_bus_scale_client_update_request(resource_context.pcl, 0); msm_bus_scale_unregister_client(resource_context.pcl); #endif VCDRES_MSG_MED("res_trk_power_down():: Calling " "res_trk_shutdown_vidc()\n"); return res_trk_shutdown_vidc(); }
u32 res_trk_power_up(void) { VCDRES_MSG_LOW("clk_regime_rail_enable"); VCDRES_MSG_LOW("clk_regime_sel_rail_control"); #ifdef AXI_CLK_SCALING { VCDRES_MSG_MED("\n res_trk_power_up():: " "Calling AXI add requirement\n"); ebi1_clk = clk_get(resource_context.device, "mem_clk"); if (IS_ERR(ebi1_clk)) { VCDRES_MSG_ERROR("Request AXI bus QOS fails."); return false; } clk_prepare_enable(ebi1_clk); } #endif VCDRES_MSG_MED("\n res_trk_power_up():: Calling " "vidc_enable_pwr_rail()\n"); return res_trk_enable_videocore(); }
u32 res_trk_estimate_perf_level(u32 pn_perf_lvl) { VCDRES_MSG_MED("%s(), req_perf_lvl = %d", __func__, pn_perf_lvl); if ((pn_perf_lvl >= RESTRK_1080P_VGA_PERF_LEVEL) && (pn_perf_lvl < RESTRK_1080P_720P_PERF_LEVEL)) { return RESTRK_1080P_720P_PERF_LEVEL; } else if ((pn_perf_lvl >= RESTRK_1080P_720P_PERF_LEVEL) && (pn_perf_lvl < RESTRK_1080P_MAX_PERF_LEVEL)) { return RESTRK_1080P_MAX_PERF_LEVEL; } else { return pn_perf_lvl; } }
u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl) { bool turbo_supported = !resource_context.vidc_platform_data->disable_turbo; if (!pn_max_perf_lvl) { VCDRES_MSG_ERROR("%s(): pn_max_perf_lvl is NULL\n", __func__); return false; } if (turbo_supported) *pn_max_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL; else *pn_max_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; VCDRES_MSG_MED("%s: %u", __func__, (u32)*pn_max_perf_lvl); return true; }
u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl) { unsigned long freq; if (!pn_perf_lvl) { VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", __func__); return false; } VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz"); if (!res_trk_get_clk_rate(&freq)) { VCDRES_MSG_ERROR("%s(): res_trk_get_clk_rate FAILED\n", __func__); *pn_perf_lvl = 0; return false; } *pn_perf_lvl = resource_context.perf_level; VCDRES_MSG_MED("%s(): freq = %lu, *pn_perf_lvl = %u", __func__, freq, *pn_perf_lvl); return true; }
u32 res_trk_estimate_perf_level(u32 pn_perf_lvl) { bool turbo_supported = !resource_context.vidc_platform_data->disable_turbo; VCDRES_MSG_MED("%s(): pn_perf_lvl = %d, turbo support = %d", __func__, pn_perf_lvl, turbo_supported); if ((pn_perf_lvl >= RESTRK_1080P_VGA_PERF_LEVEL) && (pn_perf_lvl < RESTRK_1080P_720P_PERF_LEVEL)) { return RESTRK_1080P_720P_PERF_LEVEL; } else if ((pn_perf_lvl >= RESTRK_1080P_720P_PERF_LEVEL) && (pn_perf_lvl < RESTRK_1080P_MAX_PERF_LEVEL)) { return RESTRK_1080P_MAX_PERF_LEVEL; } else if ((pn_perf_lvl >= RESTRK_1080P_MAX_PERF_LEVEL) && (pn_perf_lvl < RESTRK_1080P_TURBO_PERF_LEVEL) && turbo_supported) { return RESTRK_1080P_TURBO_PERF_LEVEL; } else { return pn_perf_lvl; } }
u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl) { unsigned long n_freq; if (!pn_perf_lvl) { VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", __func__); return FALSE; } VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz"); if (!vid_c_get_clk_rate(&n_freq)) { VCDRES_MSG_ERROR("%s(): vid_c_get_clk_rate FAILED\n", __func__); *pn_perf_lvl = 0; return FALSE; } *pn_perf_lvl = res_trk_convert_freq_to_perf_lvl((u64) n_freq); VCDRES_MSG_MED("%s(): n_freq = %lu, *pn_perf_lvl = %u", __func__, n_freq, *pn_perf_lvl); return TRUE; }
u32 get_res_trk_perf_level(enum vcd_perf_level perf_level) { u32 res_trk_perf_level; switch (perf_level) { case VCD_PERF_LEVEL0: res_trk_perf_level = RESTRK_1080P_VGA_PERF_LEVEL; break; case VCD_PERF_LEVEL1: res_trk_perf_level = RESTRK_1080P_720P_PERF_LEVEL; break; case VCD_PERF_LEVEL2: res_trk_perf_level = RESTRK_1080P_MAX_PERF_LEVEL; break; case VCD_PERF_LEVEL_TURBO: res_trk_perf_level = RESTRK_1080P_TURBO_PERF_LEVEL; break; default: VCD_MSG_ERROR("Invalid perf level: %d\n", perf_level); res_trk_perf_level = -EINVAL; } VCDRES_MSG_MED("%s: res_trk_perf_level = %u", __func__, res_trk_perf_level); return res_trk_perf_level; }
u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, struct vcd_dev_ctxt *dev_ctxt) { struct vcd_clnt_ctxt *cctxt_itr = NULL; u32 axi_freq = 0, mfc_freq = 0, calc_mfc_freq = 0; u8 enc_clnt_present = false; if (!pn_set_perf_lvl || !dev_ctxt) { VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", __func__, dev_ctxt); return false; } VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); calc_mfc_freq = res_trk_convert_perf_lvl_to_freq( (u64)req_perf_lvl); if (calc_mfc_freq < VCD_RESTRK_MIN_FREQ_POINT) calc_mfc_freq = VCD_RESTRK_MIN_FREQ_POINT; else if (calc_mfc_freq > VCD_RESTRK_MAX_FREQ_POINT) calc_mfc_freq = VCD_RESTRK_MAX_FREQ_POINT; cctxt_itr = dev_ctxt->cctxt_list_head; while (cctxt_itr) { VCDRES_MSG_LOW("\n cctxt_itr = %p", cctxt_itr); if (!cctxt_itr->decoding) { VCDRES_MSG_LOW("\n Encoder client"); enc_clnt_present = true; break; } else { VCDRES_MSG_LOW("\n Decoder client"); } cctxt_itr = cctxt_itr->next; } if (enc_clnt_present) { if (req_perf_lvl >= VGA_PERF_LEVEL) { mfc_freq = mfc_clk_freq_table[2]; axi_freq = axi_clk_freq_table_enc[1]; } else { mfc_freq = mfc_clk_freq_table[0]; axi_freq = axi_clk_freq_table_enc[0]; } VCDRES_MSG_MED("\n ENCODER: axi_freq = %u" ", mfc_freq = %u, calc_mfc_freq = %u," " req_perf_lvl = %u", axi_freq, mfc_freq, calc_mfc_freq, req_perf_lvl); } else { if (req_perf_lvl <= QVGA_PERF_LEVEL) { mfc_freq = mfc_clk_freq_table[0]; axi_freq = axi_clk_freq_table_dec[0]; } else { axi_freq = axi_clk_freq_table_dec[0]; if (req_perf_lvl <= VGA_PERF_LEVEL) mfc_freq = mfc_clk_freq_table[0]; else if (req_perf_lvl <= WVGA_PERF_LEVEL) mfc_freq = mfc_clk_freq_table[1]; else { mfc_freq = mfc_clk_freq_table[2]; axi_freq = axi_clk_freq_table_dec[1]; } } VCDRES_MSG_MED("\n DECODER: axi_freq = %u" ", mfc_freq = %u, calc_mfc_freq = %u," " req_perf_lvl = %u", axi_freq, mfc_freq, calc_mfc_freq, req_perf_lvl); } #ifdef AXI_CLK_SCALING if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { VCDRES_MSG_MED("\n %s(): Setting AXI freq to %u", __func__, axi_freq); clk_set_rate(ebi1_clk, axi_freq * 1000); } #endif #ifdef USE_RES_TRACKER if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { VCDRES_MSG_MED("\n %s(): Setting MFC freq to %u", __func__, mfc_freq); if (!res_trk_sel_clk_rate(mfc_freq)) { VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", __func__); *pn_set_perf_lvl = 0; return false; } } #endif *pn_set_perf_lvl = res_trk_convert_freq_to_perf_lvl((u64) mfc_freq); return true; }
u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, struct vcd_dev_ctxt *dev_ctxt) { u32 vidc_freq = 0; if (!pn_set_perf_lvl || !dev_ctxt) { VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", __func__, dev_ctxt); return false; } if (dev_ctxt->turbo_mode_set && (req_perf_lvl < RESTRK_1080P_TURBO_PERF_LEVEL)) { VCDRES_MSG_MED("%s(): TURBO MODE!!\n", __func__); return true; } VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); if (resource_context.vidc_platform_data->disable_turbo && req_perf_lvl > RESTRK_1080P_MAX_PERF_LEVEL) { VCDRES_MSG_ERROR("%s(): Turbo not supported! dev_ctxt(%p)\n", __func__, dev_ctxt); } #ifdef CONFIG_MSM_BUS_SCALING if (!res_trk_update_bus_perf_level(dev_ctxt, req_perf_lvl) < 0) { VCDRES_MSG_ERROR("%s(): update buf perf level failed\n", __func__); return false; } #endif if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) req_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; if (req_perf_lvl <= RESTRK_1080P_VGA_PERF_LEVEL) { vidc_freq = vidc_clk_table[0]; *pn_set_perf_lvl = RESTRK_1080P_VGA_PERF_LEVEL; } else if (req_perf_lvl <= RESTRK_1080P_720P_PERF_LEVEL) { vidc_freq = vidc_clk_table[1]; *pn_set_perf_lvl = RESTRK_1080P_720P_PERF_LEVEL; } else if (req_perf_lvl <= RESTRK_1080P_MAX_PERF_LEVEL) { vidc_freq = vidc_clk_table[2]; *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; } else { vidc_freq = vidc_clk_table[4]; *pn_set_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL; } if (resource_context.vidc_platform_data->disable_turbo && *pn_set_perf_lvl == RESTRK_1080P_TURBO_PERF_LEVEL) { VCDRES_MSG_ERROR("Warning: Turbo mode not supported " " falling back to 1080p clocks\n"); vidc_freq = vidc_clk_table[2]; *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; } resource_context.perf_level = *pn_set_perf_lvl; VCDRES_MSG_MED("VIDC: vidc_freq = %u, req_perf_lvl = %u\n", vidc_freq, req_perf_lvl); #ifdef USE_RES_TRACKER if (req_perf_lvl != RESTRK_1080P_MIN_PERF_LEVEL) { VCDRES_MSG_MED("%s(): Setting vidc freq to %u\n", __func__, vidc_freq); if (!res_trk_sel_clk_rate(vidc_freq)) { if (vidc_freq == vidc_clk_table[4]) { if (res_trk_sel_clk_rate(vidc_clk_table[3])) goto ret; } VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", __func__); *pn_set_perf_lvl = 0; return false; } } #endif ret: VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl); return true; }