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; }
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; }