Ejemplo n.º 1
0
static unsigned long scaling_state_check(struct devfreq *df, ktime_t time)
{
	struct podgov_info_rec *podgov = df->data;
	unsigned long dt;
	long max_boost, load, damp, freq, boost, res;

	dt = (unsigned long) ktime_us_delta(time, podgov->last_scale);
	if (dt < podgov->p_block_window || df->previous_freq == 0)
		return 0;

	/* convert to mhz to avoid overflow */
	freq = df->previous_freq / 1000000;
	max_boost = (df->max_freq/3) / 1000000;

	/* calculate and trace load */
	load = 1000 - podgov->idle_avg;
	trace_podgov_busy(load);
	damp = podgov->p_damp;

	if ((1000 - podgov->idle) > podgov->p_load_max) {
		/* if too busy, scale up max/3, do not damp */
		boost = max_boost;
		damp = 10;

	} else {
		/* boost = bias * freq * (load - target)/target */
		boost = (load - podgov->p_load_target);
		boost *= (podgov->p_bias * freq);
		boost /= (100 * podgov->p_load_target);

		/* clamp to max boost */
		boost = (boost < max_boost) ? boost : max_boost;
	}

	/* calculate new request */
	res = freq + boost;

	/* Maintain average request */
	podgov->freq_avg = (podgov->freq_avg * podgov->p_smooth) + res;
	podgov->freq_avg /= (podgov->p_smooth+1);

	/* Applying damping to frequencies */
	res = ((damp * res) + ((10 - damp)*podgov->freq_avg)) / 10;

	/* Convert to hz, limit, and apply */
	res = res * 1000000;
	scaling_limit(df, &res);
	trace_podgov_scaling_state_check(df->previous_freq, res);
	return res;
}
Ejemplo n.º 2
0
static unsigned long scaling_state_check(struct devfreq *df, ktime_t time)
{
	struct podgov_info_rec *podgov = df->data;
	unsigned long dt;

	/* adjustment: set scale parameters (idle_min, idle_max) +/- 25%
	 * based on ratio of scale up to scale down hints
	 */
	if (podgov->p_adjust)
		scaling_adjust(podgov, time);
	else {
		podgov->idle_min = podgov->p_idle_min;
		podgov->idle_max = podgov->p_idle_max;
	}

	dt = (unsigned long) ktime_us_delta(time, podgov->last_scale);
	if (dt < podgov->p_estimation_window)
		return 0;

	podgov->last_scale = time;

	/* if too busy, scale up */
	if (podgov->idle_estimate < podgov->idle_min) {
		podgov->is_scaled = 0;
		podgov->fast_up_count++;

		trace_podgov_busy(1000 - podgov->idle_estimate);
		trace_podgov_scaling_state_check(df->previous_freq,
			df->max_freq);

		return df->max_freq;

	}

	trace_podgov_idle(podgov->idle_estimate);

	if (podgov->idle_estimate > podgov->idle_max) {
		if (!podgov->is_scaled)
			podgov->is_scaled = 1;

		podgov->slow_down_count++;
		/* if idle time is high, clock down */
		podgov->scale =
			100 - (podgov->idle_estimate - podgov->idle_min) / 10;
		schedule_work(&podgov->work);
	}

	return 0;
}