FreeBSD/sys/arm/nvidia/tegra124/tegra124_cpufreq.c
/*
 * Compute requesetd voltage for given frequency and SoC process variations,
 * - compute base voltage from speedo value using speedo table
 * - round up voltage to next regulator step
 * - clamp it to regulator limits
 */
Compute requesetd voltage for given frequency and SoC process variations,
- compute base voltage from speedo value using speedo table
- round up voltage to next regulator step
- clamp it to regulator limits
Compute requesetd voltage for given frequency and SoC process variations - compute base voltage from speedo value using speedo table - round up voltage to next regulator step - clamp it to regulator limits
static int
freq_to_voltage(struct tegra124_cpufreq_softc *sc, uint64_t freq)
{
	int uv, scale, min_uvolt, max_uvolt, step_uvolt;
	struct speedo_entry *ent;
	int i;
	ent = NULL;
	for (i = 0; i < sc->cpu_def->speedo_nitems; i++) {
		if (sc->cpu_def->speedo_tbl[i].freq >= freq) {
			ent = &sc->cpu_def->speedo_tbl[i];
			break;
		}
	}
	if (ent == NULL)
		ent = &sc->cpu_def->speedo_tbl[sc->cpu_def->speedo_nitems - 1];
	scale = sc->cpu_def->speedo_scale;
	uv = DIV_ROUND_CLOSEST(ent->c2 * sc->speedo_value, scale);
	uv = DIV_ROUND_CLOSEST((uv + ent->c1) * sc->speedo_value, scale) +
	    ent->c0;
	step_uvolt = sc->cpu_def->step_uvolt;
	uv = ROUND_UP(uv, step_uvolt);
	min_uvolt = ROUND_UP(sc->cpu_def->min_uvolt, step_uvolt);
	max_uvolt = ROUND_DOWN(sc->cpu_def->max_uvolt, step_uvolt);
	if (uv < min_uvolt)
		uv =  min_uvolt;
	if (uv > max_uvolt)
		uv =  max_uvolt;
	return (uv);
}
static int freq_to_voltage ( struct tegra124_cpufreq_softc * sc , uint64_t freq ) { int uv , scale , min_uvolt , max_uvolt , step_uvolt ; struct speedo_entry * ent ; int i ; ent = NULL ; for ( i = 0 ; i < sc -> cpu_def -> speedo_nitems ; i ++ ) { if ( sc -> cpu_def -> speedo_tbl [ i ] . freq >= freq ) { ent = & sc -> cpu_def -> speedo_tbl [ i ] ; break ; } } if ( ent == NULL ) ent = & sc -> cpu_def -> speedo_tbl [ sc -> cpu_def -> speedo_nitems - 1 ] ; scale = sc -> cpu_def -> speedo_scale ; uv = DIV_ROUND_CLOSEST ( ent -> c2 * sc -> speedo_value , scale ) ; uv = DIV_ROUND_CLOSEST ( ( uv + ent -> c1 ) * sc -> speedo_value , scale ) + ent -> c0 ; step_uvolt = sc -> cpu_def -> step_uvolt ; uv = ROUND_UP ( uv , step_uvolt ) ; min_uvolt = ROUND_UP ( sc -> cpu_def -> min_uvolt , step_uvolt ) ; max_uvolt = ROUND_DOWN ( sc -> cpu_def -> max_uvolt , step_uvolt ) ; if ( uv < min_uvolt ) uv = min_uvolt ; if ( uv > max_uvolt ) uv = max_uvolt ; return ( uv ) ; }
Compute requesetd voltage for given frequency and SoC process variations,
 - compute base voltage from speedo value using speedo table
 - round up voltage to next regulator step
 - clamp it to regulator limits
Compute requesetd voltage for given frequency and SoC process variations - compute base voltage from speedo value using speedo table - round up voltage to next regulator step - clamp it to regulator limits
/* Get speedo entry with higher frequency */ /* uV = (c2 * speedo / scale + c1) * speedo / scale + c0) */ /* Round up it to next regulator step */ /* Clamp result */