u32 res_trk_enable_clocks(void) { VCDRES_MSG_LOW("\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; }
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_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; 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 && bus_clk_index == 3) bus_clk_index = 2; 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"); res_trk_pmem_unmap(&resource_context.firmware_addr); #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_disable_clocks(void) { VCDRES_MSG_LOW("in res_trk_disable_clocks()\n"); mutex_lock(&resource_context.lock); if (clock_enabled == 1) { mutex_unlock(&resource_context.lock); return true; } 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.vcodec_clk); mutex_unlock(&resource_context.lock); return true; }
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(); }
void res_trk_init(struct device *device, u32 irq) { VCDRES_MSG_LOW("%s", __func__); if (resource_context.device || resource_context.irq_num || !device) { VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", __func__); return; } memset(&resource_context, 0, sizeof(resource_context)); mutex_init(&resource_context.lock); resource_context.device = device; resource_context.irq_num = irq; resource_context.core_type = VCD_CORE_720P; resource_context.regulator = regulator_get(NULL, "fs_mfc"); resource_context.vidc_platform_data = (struct msm_vidc_platform_data *) device->platform_data; if (resource_context.vidc_platform_data) { resource_context.memtype = resource_context.vidc_platform_data->memtype; VCDRES_MSG_LOW("%s(): resource_context.memtype = 0x%x", __func__, (u32)resource_context.memtype); if (res_trk_get_enable_ion()) { resource_context.res_ion_client = res_trk_create_ion_client(); if (!(resource_context.res_ion_client)) { VCDRES_MSG_ERROR("%s()ION createfail\n", __func__); return; } VCDRES_MSG_LOW("%s(): ion_client = 0x%x", __func__, (u32)resource_context.res_ion_client); } } else { resource_context.memtype = -1; VCDRES_MSG_ERROR("%s(): vidc_platform_data is NULL", __func__); } }
u32 res_trk_disable_clocks(void) { u32 status = false; VCDRES_MSG_LOW("in res_trk_disable_clocks()\n"); mutex_lock(&resource_context.lock); if (resource_context.clock_enabled) { 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; if (resource_context.vcodec_clk) clk_disable(resource_context.vcodec_clk); if (resource_context.vcodec_pclk) clk_disable(resource_context.vcodec_pclk); if (resource_context.vcodec_axi_a_clk) clk_disable(resource_context.vcodec_axi_a_clk); if (resource_context.vcodec_axi_b_clk) clk_disable(resource_context.vcodec_axi_b_clk); status = true; } 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 (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_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_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_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; }
static u32 res_trk_shutdown_vidc(void) { mutex_lock(&resource_context.lock); if (resource_context.clock_enabled) { mutex_unlock(&resource_context.lock); VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n"); res_trk_disable_clocks(); mutex_lock(&resource_context.lock); } res_trk_put_clk(); if (resource_context.footswitch) { if (regulator_disable(resource_context.footswitch)) VCDRES_MSG_ERROR("Regulator disable failed\n"); regulator_put(resource_context.footswitch); resource_context.footswitch = NULL; } if (pm_runtime_put(resource_context.device) < 0) VCDRES_MSG_ERROR("Error : pm_runtime_put failed"); mutex_unlock(&resource_context.lock); 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; }
static u32 res_trk_disable_pwr_rail(void) { int rc = -1; mutex_lock(&resource_context.lock); if (resource_context.clock_enabled) { mutex_unlock(&resource_context.lock); VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n"); res_trk_disable_clocks(); mutex_lock(&resource_context.lock); } if (!resource_context.rail_enabled) { mutex_unlock(&resource_context.lock); return false; } resource_context.rail_enabled = 0; rc = clk_reset(resource_context.pclk, CLK_RESET_ASSERT); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } msleep(20); rc = internal_pwr_rail_ctl(PWR_RAIL_MFC_CLK, 0); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } clk_put(resource_context.hclk_div2); clk_put(resource_context.hclk); clk_put(resource_context.pclk); mutex_unlock(&resource_context.lock); return true; }
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; }
static u32 res_trk_disable_pwr_rail(void) { mutex_lock(&resource_context.lock); if (clock_enabled == 1) { mutex_unlock(&resource_context.lock); return true; } if (resource_context.clock_enabled) { mutex_unlock(&resource_context.lock); VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n"); res_trk_disable_clocks(); mutex_lock(&resource_context.lock); } clk_put(resource_context.vcodec_clk); /*TODO: Power rail functions needs to added here*/ if (!resource_context.rail_enabled) { mutex_unlock(&resource_context.lock); return false; } resource_context.rail_enabled = 0; mutex_unlock(&resource_context.lock); return true; }
static u32 res_trk_disable_videocore(void) { int rc = -1; mutex_lock(&resource_context.lock); if (!resource_context.rail_enabled) { mutex_unlock(&resource_context.lock); return false; } if (!resource_context.clock_enabled && resource_context.pclk && resource_context.hclk && resource_context.hclk_div2) { VCDRES_MSG_LOW("\nEnabling clk before disabling pwr rail\n"); if (clk_set_rate(resource_context.hclk, mfc_clk_freq_table[0])) { VCDRES_MSG_ERROR("\n pwr_rail_disable:" " set clk rate failed\n"); goto bail_out; } if (clk_prepare_enable(resource_context.pclk)) { VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); goto bail_out; } if (clk_prepare_enable(resource_context.hclk)) { VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); goto disable_pclk; } if (clk_prepare_enable(resource_context.hclk_div2)) { VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); goto disable_hclk; } } else { VCDRES_MSG_ERROR("\ndisabling pwr rail: Enabling clk failed\n"); goto bail_out; } resource_context.rail_enabled = 0; rc = clk_reset(resource_context.pclk, CLK_RESET_ASSERT); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } msleep(20); clk_disable_unprepare(resource_context.pclk); clk_disable_unprepare(resource_context.hclk); clk_disable_unprepare(resource_context.hclk_div2); clk_put(resource_context.hclk_div2); clk_put(resource_context.hclk); clk_put(resource_context.pclk); rc = regulator_disable(resource_context.regulator); if (rc) { VCDRES_MSG_ERROR("\n regulator disable failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } resource_context.hclk_div2 = NULL; resource_context.hclk = NULL; resource_context.pclk = NULL; mutex_unlock(&resource_context.lock); return true; disable_hclk: clk_disable_unprepare(resource_context.hclk); disable_pclk: clk_disable_unprepare(resource_context.pclk); bail_out: if (resource_context.pclk) { clk_put(resource_context.pclk); resource_context.pclk = NULL; } if (resource_context.hclk) { clk_put(resource_context.hclk); resource_context.hclk = NULL; } if (resource_context.hclk_div2) { clk_put(resource_context.hclk_div2); resource_context.hclk_div2 = NULL; } mutex_unlock(&resource_context.lock); return false; }
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; }
//static u32 res_trk_enable_pwr_rail(void) static u32 res_trk_enable_videocore(void) /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ { mutex_lock(&resource_context.lock); if (!resource_context.rail_enabled) { int rc = -1; rc = internal_pwr_rail_mode(PWR_RAIL_MFC_CLK, PWR_RAIL_CTL_MANUAL); if (rc) { VCDRES_MSG_ERROR("%s(): internal_pwr_rail_mode \ failed %d\n", __func__, rc); mutex_unlock(&resource_context.lock); return false; } VCDRES_MSG_LOW("%s(): internal_pwr_rail_mode Success %d\n", __func__, rc); resource_context.pclk = clk_get(resource_context.device, "mfc_pclk"); if (IS_ERR(resource_context.pclk)) { VCDRES_MSG_ERROR("%s(): mfc_pclk get failed\n" , __func__); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // mutex_unlock(&resource_context.lock); // return false; goto bail_out; /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ } resource_context.hclk = clk_get(resource_context.device, "mfc_clk"); if (IS_ERR(resource_context.hclk)) { VCDRES_MSG_ERROR("%s(): mfc_clk get failed\n" , __func__); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // clk_put(resource_context.pclk); // mutex_unlock(&resource_context.lock); // return false; goto release_pclk; /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ } resource_context.hclk_div2 = clk_get(resource_context.device, "mfc_div2_clk"); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // if (IS_ERR(resource_context.pclk)) { if (IS_ERR(resource_context.hclk_div2)) { /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ VCDRES_MSG_ERROR("%s(): mfc_div2_clk get failed\n" , __func__); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // clk_put(resource_context.pclk); // clk_put(resource_context.hclk); // mutex_unlock(&resource_context.lock); // return false; goto release_hclk_pclk; /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ } #ifdef PATCH0330 /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // clk_set_rate(resource_context.hclk, // mfc_clk_freq_table[0]); // // clk_enable(resource_context.pclk); // clk_enable(resource_context.hclk); // clk_enable(resource_context.hclk_div2); if (clk_set_rate(resource_context.hclk, mfc_clk_freq_table[0])) { VCDRES_MSG_ERROR("\n pwr_rail_enable:" " set clk rate failed\n"); goto release_all_clks; } if (clk_enable(resource_context.pclk)) { VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); goto release_all_clks; } if (clk_enable(resource_context.hclk)) { VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); goto disable_pclk; } if (clk_enable(resource_context.hclk_div2)) { VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); goto disable_hclk_pclk; } /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ #endif /* PATCH0330 */ rc = internal_pwr_rail_ctl(PWR_RAIL_MFC_CLK, 1); if (rc) { VCDRES_MSG_ERROR("\n internal_pwr_rail_ctl failed %d\n" , rc); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // mutex_unlock(&resource_context.lock); // return false; goto disable_and_release_all_clks; /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ } VCDRES_MSG_LOW("%s(): internal_pwr_rail_ctl Success %d\n" , __func__, rc); msleep(20); rc = clk_reset(resource_context.pclk, CLK_RESET_DEASSERT); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // mutex_unlock(&resource_context.lock); // return false; goto disable_and_release_all_clks; /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ } msleep(20); #ifdef PATCH0330 clk_disable(resource_context.pclk); clk_disable(resource_context.hclk); clk_disable(resource_context.hclk_div2); #endif /* PATCH0330 */ }
//static u32 res_trk_disable_pwr_rail(void) static u32 res_trk_disable_videocore(void) /* 20110511 Y.Yagami -S vidc: vdec: Generate output done in reconfig. */ { int rc = -1; mutex_lock(&resource_context.lock); #ifdef PATCH0330 #else if (resource_context.clock_enabled) { mutex_unlock(&resource_context.lock); VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n"); res_trk_disable_clocks(); mutex_lock(&resource_context.lock); } #endif /* PATCH0330 */ if (!resource_context.rail_enabled) { mutex_unlock(&resource_context.lock); return false; } #ifdef PATCH0330 if (!resource_context.clock_enabled && resource_context.pclk && resource_context.hclk && resource_context.hclk_div2) { VCDRES_MSG_LOW("\nEnabling clk before disabling pwr rail\n"); /* 20110511 Y.Yagami CHG-S msm: vidc: Fix video core clock power up/down sequence */ // clk_set_rate(resource_context.hclk, // mfc_clk_freq_table[0]); if (clk_set_rate(resource_context.hclk, mfc_clk_freq_table[0])) { VCDRES_MSG_ERROR("\n pwr_rail_disable:" " set clk rate failed\n"); goto bail_out; } /* 20110511 Y.Yagami CHG-E msm: vidc: Fix video core clock power up/down sequence */ if (clk_enable(resource_context.pclk)) { VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); goto bail_out; } if (clk_enable(resource_context.hclk)) { VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); goto disable_pclk; } if (clk_enable(resource_context.hclk_div2)) { VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); goto disable_hclk; } } else { VCDRES_MSG_ERROR("\ndisabling pwr rail: Enabling clk failed\n"); goto bail_out; } #endif /* PATCH0330 */ resource_context.rail_enabled = 0; rc = clk_reset(resource_context.pclk, CLK_RESET_ASSERT); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } msleep(20); rc = internal_pwr_rail_ctl(PWR_RAIL_MFC_CLK, 0); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } #ifdef PATCH0330 clk_disable(resource_context.pclk); clk_disable(resource_context.hclk); clk_disable(resource_context.hclk_div2); #endif /* PATCH0330 */ clk_put(resource_context.hclk_div2); clk_put(resource_context.hclk); clk_put(resource_context.pclk); #ifdef PATCH0330 resource_context.hclk_div2 = NULL; resource_context.hclk = NULL; resource_context.pclk = NULL; #endif /* PATCH0330 */ mutex_unlock(&resource_context.lock); return true; #ifdef PATCH0330 disable_hclk: clk_disable(resource_context.hclk); disable_pclk: clk_disable(resource_context.pclk); bail_out: if (resource_context.pclk) { clk_put(resource_context.pclk); resource_context.pclk = NULL; } if (resource_context.hclk) { clk_put(resource_context.hclk); resource_context.hclk = NULL; } if (resource_context.hclk_div2) { clk_put(resource_context.hclk_div2); resource_context.hclk_div2 = NULL; } mutex_unlock(&resource_context.lock); return false; #endif /* PATCH0330 */ }
static u32 res_trk_enable_videocore(void) { mutex_lock(&resource_context.lock); if (!resource_context.rail_enabled) { int rc = -1; rc = regulator_enable(resource_context.regulator); if (rc) { VCDRES_MSG_ERROR("%s(): regulator_enable failed %d\n", __func__, rc); goto bail_out; } VCDRES_MSG_LOW("%s(): regulator enable Success %d\n", __func__, rc); resource_context.pclk = clk_get(resource_context.device, "iface_clk"); if (IS_ERR(resource_context.pclk)) { VCDRES_MSG_ERROR("%s(): iface_clk get failed\n" , __func__); goto disable_regulator; } resource_context.hclk = clk_get(resource_context.device, "core_clk"); if (IS_ERR(resource_context.hclk)) { VCDRES_MSG_ERROR("%s(): core_clk get failed\n" , __func__); goto release_pclk; } resource_context.hclk_div2 = clk_get(resource_context.device, "core_div2_clk"); if (IS_ERR(resource_context.hclk_div2)) { VCDRES_MSG_ERROR("%s(): core_div2_clk get failed\n" , __func__); goto release_hclk_pclk; } if (clk_set_rate(resource_context.hclk, mfc_clk_freq_table[0])) { VCDRES_MSG_ERROR("\n pwr_rail_enable:" " set clk rate failed\n"); goto release_all_clks; } if (clk_prepare_enable(resource_context.pclk)) { VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); goto release_all_clks; } if (clk_prepare_enable(resource_context.hclk)) { VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); goto disable_pclk; } if (clk_prepare_enable(resource_context.hclk_div2)) { VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); goto disable_hclk_pclk; } rc = clk_reset(resource_context.pclk, CLK_RESET_DEASSERT); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); goto disable_and_release_all_clks; } msleep(20); clk_disable_unprepare(resource_context.pclk); clk_disable_unprepare(resource_context.hclk); clk_disable_unprepare(resource_context.hclk_div2); } resource_context.rail_enabled = 1; mutex_unlock(&resource_context.lock); return true; disable_and_release_all_clks: clk_disable_unprepare(resource_context.hclk_div2); disable_hclk_pclk: clk_disable_unprepare(resource_context.hclk); disable_pclk: clk_disable_unprepare(resource_context.pclk); release_all_clks: clk_put(resource_context.hclk_div2); resource_context.hclk_div2 = NULL; release_hclk_pclk: clk_put(resource_context.hclk); resource_context.hclk = NULL; release_pclk: clk_put(resource_context.pclk); resource_context.pclk = NULL; disable_regulator: regulator_disable(resource_context.regulator); bail_out: mutex_unlock(&resource_context.lock); return false; }
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; }
static struct ion_client *res_trk_create_ion_client(void){ struct ion_client *video_client; VCDRES_MSG_LOW("%s", __func__); video_client = msm_ion_client_create(-1, "video_client"); return video_client; }
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; }
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; }
static u32 res_trk_enable_pwr_rail(void) { mutex_lock(&resource_context.lock); if (!resource_context.rail_enabled) { int rc = -1; rc = internal_pwr_rail_mode(PWR_RAIL_MFC_CLK, PWR_RAIL_CTL_MANUAL); if (rc) { VCDRES_MSG_ERROR("%s(): internal_pwr_rail_mode \ failed %d\n", __func__, rc); mutex_unlock(&resource_context.lock); return false; } VCDRES_MSG_LOW("%s(): internal_pwr_rail_mode Success %d\n", __func__, rc); resource_context.pclk = clk_get(resource_context.device, "mfc_pclk"); if (IS_ERR(resource_context.pclk)) { VCDRES_MSG_ERROR("%s(): mfc_pclk get failed\n" , __func__); mutex_unlock(&resource_context.lock); return false; } resource_context.hclk = clk_get(resource_context.device, "mfc_clk"); if (IS_ERR(resource_context.hclk)) { VCDRES_MSG_ERROR("%s(): mfc_clk get failed\n" , __func__); clk_put(resource_context.pclk); mutex_unlock(&resource_context.lock); return false; } resource_context.hclk_div2 = clk_get(resource_context.device, "mfc_div2_clk"); if (IS_ERR(resource_context.pclk)) { VCDRES_MSG_ERROR("%s(): mfc_div2_clk get failed\n" , __func__); clk_put(resource_context.pclk); clk_put(resource_context.hclk); mutex_unlock(&resource_context.lock); return false; } rc = internal_pwr_rail_ctl(PWR_RAIL_MFC_CLK, 1); if (rc) { VCDRES_MSG_ERROR("\n internal_pwr_rail_ctl failed %d\n" , rc); mutex_unlock(&resource_context.lock); return false; } VCDRES_MSG_LOW("%s(): internal_pwr_rail_ctl Success %d\n" , __func__, rc); msleep(20); rc = clk_reset(resource_context.pclk, CLK_RESET_DEASSERT); if (rc) { VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); mutex_unlock(&resource_context.lock); return false; } msleep(20); }