u32 res_trk_download_firmware(void) { const struct firmware *fw_video = NULL; int rc = 0; u32 status = true; VCDRES_MSG_HIGH("%s(): Request firmware download\n", __func__); mutex_lock(&resource_context.lock); rc = request_firmware(&fw_video, VIDC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_FW, rc); status = false; goto bail_out; } if (fw_video) { vidc_video_codec_fw = (unsigned char *)fw_video->data; vidc_video_codec_fw_size = (u32) fw_video->size; } bail_out: mutex_unlock(&resource_context.lock); return status; }
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 (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_HIGH("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_HIGH("%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_HIGH("%s() set perl level : %d", __func__, *pn_set_perf_lvl); return true; }
u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, struct vcd_clnt_ctxt *cctxt) { u32 vidc_freq = 0; if (!pn_set_perf_lvl) { VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", __func__); return false; } VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); if (cctxt) { 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_HIGH("\n VIDC: vidc_freq = %u, req_perf_lvl = %u", vidc_freq, req_perf_lvl); } else { VCDRES_MSG_HIGH("%s() WARNING:: cctxt is NULL", __func__); return true; } #ifdef USE_RES_TRACKER if (req_perf_lvl != RESTRK_1080P_MIN_PERF_LEVEL) { VCDRES_MSG_HIGH("\n %s(): Setting vidc freq to %u", __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_HIGH("%s() set perl level : %d", __func__, *pn_set_perf_lvl); return true; }
u32 res_trk_enable_clocks(void) { VCDRES_MSG_LOW("clk_regime_msm_enable"); VCDRES_MSG_HIGH("\n in res_trk_enable_clocks()"); mutex_lock(&resource_context.lock); if (!resource_context.clock_enabled) { VCDRES_MSG_LOW("Enabling IRQ in %s()\n", __func__); enable_irq(resource_context.irq_num); VCDRES_MSG_LOW("%s(): Enabling the clocks ...\n", __func__); if (clk_enable(resource_context.pclk)) { VCDRES_MSG_ERROR("vidc pclk Enable failed \n"); clk_put(resource_context.hclk); clk_put(resource_context.hclk_div2); mutex_unlock(&resource_context.lock); return FALSE; } if (clk_enable(resource_context.hclk)) { VCDRES_MSG_ERROR("vidc hclk Enable failed \n"); clk_put(resource_context.pclk); clk_put(resource_context.hclk_div2); mutex_unlock(&resource_context.lock); return FALSE; } if (clk_enable(resource_context.hclk_div2)) { VCDRES_MSG_ERROR("vidc hclk Enable failed \n"); clk_put(resource_context.hclk); clk_put(resource_context.pclk); mutex_unlock(&resource_context.lock); return FALSE; } } resource_context.clock_enabled = 1; mutex_unlock(&resource_context.lock); return TRUE; }
u32 res_trk_disable_clocks(void) { VCDRES_MSG_LOW("clk_regime_msm_disable"); VCDRES_MSG_HIGH("in res_trk_disable_clocks()\n"); mutex_lock(&resource_context.lock); if (!resource_context.clock_enabled) { mutex_unlock(&resource_context.lock); return FALSE; } VCDRES_MSG_LOW("Disabling IRQ in %s()\n", __func__); disable_irq_nosync(resource_context.irq_num); VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__); resource_context.clock_enabled = 0; clk_disable(resource_context.hclk); clk_disable(resource_context.hclk_div2); clk_disable(resource_context.pclk); mutex_unlock(&resource_context.lock); return TRUE; }
u32 res_trk_download_firmware(void) { const struct firmware *fw_boot = NULL; const struct firmware *fw_mpg4_dec = NULL; const struct firmware *fw_h263_dec = NULL; const struct firmware *fw_h264_dec = NULL; const struct firmware *fw_mpg4_enc = NULL; const struct firmware *fw_h264_enc = NULL; const struct firmware *fw_vc1_dec = NULL; int rc = 0; u32 status = true; VCDRES_MSG_HIGH("%s(): Request firmware download\n", __func__); mutex_lock(&resource_context.lock); rc = request_firmware(&fw_boot, VIDC_BOOT_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_BOOT_FW, rc); mutex_unlock(&resource_context.lock); return false; } vidc_command_control_fw = (unsigned char *)fw_boot->data; vidc_command_control_fw_size = (u32) fw_boot->size; rc = request_firmware(&fw_mpg4_dec, VIDC_MPG4_DEC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_MPG4_DEC_FW, rc); status = false; goto boot_fw_free; } vidc_mpg4_dec_fw = (unsigned char *)fw_mpg4_dec->data; vidc_mpg4_dec_fw_size = (u32) fw_mpg4_dec->size; rc = request_firmware(&fw_h263_dec, VIDC_H263_DEC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_H263_DEC_FW, rc); status = false; goto mp4dec_fw_free; } vidc_h263_dec_fw = (unsigned char *)fw_h263_dec->data; vidc_h263_dec_fw_size = (u32) fw_h263_dec->size; rc = request_firmware(&fw_h264_dec, VIDC_H264_DEC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_H264_DEC_FW, rc); status = false; goto h263dec_fw_free; } vidc_h264_dec_fw = (unsigned char *)fw_h264_dec->data; vidc_h264_dec_fw_size = (u32) fw_h264_dec->size; rc = request_firmware(&fw_mpg4_enc, VIDC_MPG4_ENC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_MPG4_ENC_FW, rc); status = false; goto h264dec_fw_free; } vidc_mpg4_enc_fw = (unsigned char *)fw_mpg4_enc->data; vidc_mpg4_enc_fw_size = (u32) fw_mpg4_enc->size; rc = request_firmware(&fw_h264_enc, VIDC_H264_ENC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_H264_ENC_FW, rc); status = false; goto mp4enc_fw_free; } vidc_h264_enc_fw = (unsigned char *)fw_h264_enc->data; vidc_h264_enc_fw_size = (u32) fw_h264_enc->size; rc = request_firmware(&fw_vc1_dec, VIDC_VC1_DEC_FW, resource_context.device); if (rc) { VCDRES_MSG_ERROR("request_firmware for %s error %d\n", VIDC_VC1_DEC_FW, rc); status = false; goto h264enc_fw_free; } vidc_vc1_dec_fw = (unsigned char *)fw_vc1_dec->data; vidc_vc1_dec_fw_size = (u32) fw_vc1_dec->size; mutex_unlock(&resource_context.lock); return status; h264enc_fw_free: release_firmware(fw_h264_enc); mp4enc_fw_free: release_firmware(fw_mpg4_enc); h264dec_fw_free: release_firmware(fw_h264_dec); h263dec_fw_free: release_firmware(fw_h263_dec); mp4dec_fw_free: release_firmware(fw_mpg4_dec); boot_fw_free: release_firmware(fw_boot); mutex_unlock(&resource_context.lock); return false; }
u32 res_trk_set_perf_level(u32 n_req_perf_lvl, u32 *pn_set_perf_lvl, struct vcd_clnt_ctxt_type_t *p_cctxt) { u32 axi_freq = 0, mfc_freq = 0, calc_mfc_freq = 0; int rc = -1; if (!pn_set_perf_lvl) { VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", __func__); return FALSE; } VCDRES_MSG_LOW("%s(), n_req_perf_lvl = %d", __func__, n_req_perf_lvl); if (p_cctxt) { calc_mfc_freq = res_trk_convert_perf_lvl_to_freq( (u64)n_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; if (!p_cctxt->b_decoding) { if (n_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_HIGH("\n ENCODER: axi_freq = %u" ", mfc_freq = %u, calc_mfc_freq = %u," " n_req_perf_lvl = %u", axi_freq, mfc_freq, calc_mfc_freq, n_req_perf_lvl); } else { if (n_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 (n_req_perf_lvl <= VGA_PERF_LEVEL) mfc_freq = mfc_clk_freq_table[0]; else if (n_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_HIGH("\n DECODER: axi_freq = %u" ", mfc_freq = %u, calc_mfc_freq = %u," " n_req_perf_lvl = %u", axi_freq, mfc_freq, calc_mfc_freq, n_req_perf_lvl); } } else { VCDRES_MSG_HIGH("%s() WARNING:: p_cctxt is NULL", __func__); return TRUE; } #ifdef AXI_CLK_SCALING if (n_req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { VCDRES_MSG_HIGH("\n %s(): Setting AXI freq to %u", __func__, axi_freq); rc = pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ, MSM_AXI_QOS_NAME, axi_freq); if (rc < 0) { VCDRES_MSG_ERROR("\n Update AXI bus QOS fails," "rc = %d\n", rc); return FALSE; } } #endif #ifdef USE_RES_TRACKER if (n_req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { VCDRES_MSG_HIGH("\n %s(): Setting MFC freq to %u", __func__, mfc_freq); if (!vid_c_sel_clk_rate(mfc_freq)) { VCDRES_MSG_ERROR("%s(): vid_c_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; bool turbo_supported = !resource_context.vidc_platform_data->disable_turbo; 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); if (!turbo_supported && req_perf_lvl > RESTRK_1080P_MAX_PERF_LEVEL) { VCDRES_MSG_ERROR("%s(): Turbo not supported! dev_ctxt(%p)\n", __func__, dev_ctxt); } if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) { if (turbo_supported) req_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL; else req_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; VCDRES_MSG_MED("Set initial perf level to %u", req_perf_lvl); } 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 (!turbo_supported && *pn_set_perf_lvl == RESTRK_1080P_TURBO_PERF_LEVEL) { 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_HIGH("VIDC: vidc_freq = %u, req_perf_lvl = %u, "\ "set_perf_lvl = %u\n", vidc_freq, req_perf_lvl, (u32)*pn_set_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 #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]) { VCDRES_MSG_MED("%s(): Setting vidc freq "\ "to %u\n", __func__, (u32)vidc_clk_table[3]); 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; }
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; int higer_bus_bw = resource_context.vidc_platform_data->vote_high_bw; 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; if (!client_type && (bus_clk_index == 2) && higer_bus_bw && turbo_supported) { VCDRES_MSG_HIGH("%s(): request more bus BW", __func__); bus_clk_index = 3; } 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; }