Esempio n. 1
0
/* ------------------------------------------------------------------------*//**
 * @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;
}
Esempio n. 2
0
/* ------------------------------------------------------------------------*//**
 * @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;
}