/* ------------------------------------------------------------------------*//** * @FUNCTION opp54xx_by_rate_get * @BRIEF return the current voltage domain OPP name, * searched by clock rates. * @RETURNS current voltage domain OPP name (as defined in opp.h) * NULL pointer in case of error or not found * @param[in] vdd_id: voltage domain ID * @DESCRIPTION return the current voltage domain OPP name, * searched by clock rates. *//*------------------------------------------------------------------------ */ const char *opp54xx_by_rate_get(voltdm54xx_id vdd_id) { const char *opp_name = NULL; int opp_id; const char *module_name; double rate = 0.0, rate_por = 0.0; double rate_dsp = 0.0, rate_dsp_por = 0.0; double rate_gpu = 0.0, rate_gpu_por = 0.0; opp_t opp; const genlist *opp_list; int i, ret, opp_count; CHECK_CPU(54xx, NULL); CHECK_ARG_LESS_THAN(vdd_id, VDD54XX_ID_MAX, NULL); /* * Determine current OPPs by getting MPU / IVA / L3 / SARRAM rate * and comparing it to POR rate. */ switch (vdd_id) { case VDD54XX_WKUP: module_name = MOD_L4_WKUP_INTERCONNECT; break; case VDD54XX_MPU: module_name = MOD_MPU; break; case VDD54XX_MM: module_name = MOD_IVA; break; case VDD54XX_CORE: module_name = MOD_L3_MAIN1_INTERCONNECT; break; default: return NULL; } /* * If the DPLL clocking the selected module is stopped, * reported speed will be 0 and OPP cannot be detected. * Hence, ignore DPLL status. */ rate = (double) module_clk_rate_get(module_name, 1) / 1000.0; if (rate < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): %s rate is %lfMHz\n", __func__, voltdm54xx_name_get(vdd_id), clk54xx_name_get(module_clk_get(module_name)), rate); if (vdd_id == VDD54XX_MM) { rate_dsp = (double) module_clk_rate_get(MOD_DSP, 1) / 1000.0; if (rate_dsp < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): DSP rate is %lfMHz\n", __func__, voltdm54xx_name_get(vdd_id), rate_dsp); rate_gpu = (double) module_clk_rate_get(MOD_GPU, 1) / 1000.0; if (rate_gpu < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): GPU rate is %lfMHz\n", __func__, voltdm54xx_name_get(vdd_id), rate_gpu); } opp_list = opp54xx_list_get(vdd_id); if (opp_list == NULL) { dprintf("%s(): could not retrieve OPP list!\n", __func__); goto opp54xx_by_rate_get_end; } opp_count = opp54xx_count_get(vdd_id); if (opp_count <= 0) { dprintf("%s(): could not retrieve OPP count!\n", __func__); goto opp54xx_by_rate_get_end; } for (i = 0; i < opp_count; i++) { ret = genlist_get((genlist *) opp_list, i, (opp_t *) &opp); if (ret != 0) { dprintf("%s(): could not retrieve OPP from list!\n", __func__); goto opp54xx_by_rate_get_end; } opp_id = opp54xx_id_get(opp.name); if (opp_id < 0) { dprintf( "%s(): could not retrieve OPP ID from OPP name!\n", __func__); goto opp54xx_by_rate_get_end; } rate_por = (double) module_por_clk_rate_get(module_name, opp.name) / 1000.0; if (rate_por < 0) { dprintf( "%s(): could not get %s %s POR speed! (%d)\n", __func__, module_name, opp.name, ret); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): %s POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(vdd_id), module_name, opp.name, rate_por); if (vdd_id == VDD54XX_MM) { rate_dsp_por = (double) module_por_clk_rate_get(MOD_DSP, opp.name) / 1000.0; if (rate_dsp_por < 0) { dprintf( "%s(): could not get DSP %s POR speed! (%d)\n", __func__, opp.name, ret); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): DSP POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(vdd_id), opp.name, rate_dsp_por); rate_gpu_por = (double) module_por_clk_rate_get(MOD_GPU, opp.name) / 1000.0; if (rate_gpu_por < 0) { dprintf( "%s(): could not get GPU %s POR speed! (%d)\n", __func__, opp.name, ret); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): GPU POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(vdd_id), opp.name, rate_gpu_por); if (((int) rate <= (int) rate_por) && ((int) rate_dsp <= (int) rate_dsp_por) && ((int) rate_gpu <= (int) rate_gpu_por)) { opp_name = opp.name; goto opp54xx_by_rate_get_end; } } else { if ((int) rate <= (int) rate_por) { opp_name = opp.name; goto opp54xx_by_rate_get_end; } } } dprintf("%s(%s): OPP not found!\n", __func__, voltdm54xx_name_get(vdd_id)); opp54xx_by_rate_get_end: #ifdef OPP54XX_DEBUG if (opp_name == NULL) printf("%s(%s): OPP not found!\n", __func__, voltdm54xx_name_get(vdd_id)); else printf("%s(%s): OPP found: %s\n", __func__, voltdm54xx_name_get(vdd_id), opp_name); #endif return opp_name; }
/* ------------------------------------------------------------------------*//** * @FUNCTION voltdm54xx_opp_get * @BRIEF find the current voltage domain OPP * @RETURNS valid OPP ID in case of success * OPP54XX_ID_MAX in case of error * @param[in] id: voltage domain ID * @DESCRIPTION find the current voltage domain OPP *//*------------------------------------------------------------------------ */ opp54xx_id voltdm54xx_opp_get(voltdm54xx_id id) { opp54xx_id opp_id; mod54xx_id module_id; dpll54xx_id dpll_id; dpll_status status; double rate = 0.0, rate_por = 0.0; CHECK_CPU(54xx, OPP54XX_ID_MAX); CHECK_ARG_LESS_THAN(id, VDD54XX_ID_MAX, OPP54XX_ID_MAX); /* * Determine current OPPs by getting MPU / IVA / L3 / SARRAM rate * and comparing it to POR rate. */ switch (id) { case VDD54XX_WKUP: module_id = OMAP5_L4WKUP_INTERCONNECT; dpll_id = DPLL54XX_CORE; break; case VDD54XX_MPU: module_id = OMAP5_MPU; dpll_id = DPLL54XX_MPU; break; case VDD54XX_MM: module_id = OMAP5_IVA; dpll_id = DPLL54XX_IVA; break; case VDD54XX_CORE: module_id = OMAP5_L3_MAIN1_INTERCONNECT; dpll_id = DPLL54XX_CORE; break; default: return OPP54XX_ID_MAX; } /* if the DPLL clocking the selected module is stopped, * reported speed will be 0 and OPP cannot be detected. * Hence, if DPLL is stopped, ignore DPLL status to get * the speed when the DPLL is running. */ status = dpll54xx_status_get(dpll_id); if (status == DPLL_STATUS_STOPPED) rate = mod54xx_clk_rate_get(module_id, 1); else rate = mod54xx_clk_rate_get(module_id, 0); dprintf("%s(%s): %s rate is %lfMHz\n", __func__, voltdm54xx_name_get(id), clk54xx_name_get(mod54xx_clk_get(module_id)), rate); for (opp_id = OPP54XX_DPLL_CASC; opp_id < OPP54XX_ID_MAX; opp_id++) { rate_por = mod54xx_por_clk_rate_get(module_id, opp_id); dprintf("%s(%s): %s POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(id), mod54xx_name_get(module_id), opp54xx_name_get(opp_id), rate_por); if ((int) rate == (int) rate_por) { dprintf("%s(%s): OPP found: %s\n", __func__, voltdm54xx_name_get(id), opp54xx_name_get(opp_id)); return opp_id; } } dprintf("%s(%s): OPP not found!\n", __func__, voltdm54xx_name_get(id)); return OPP54XX_ID_MAX; }