#!/bin/bash

# Default CPU scaling governor to try.  Some possible choices are:
# performance:  The CPUfreq governor "performance" sets the CPU statically
#             to the highest frequency within the borders of scaling_min_freq
#             and scaling_max_freq.
# powersave:  The CPUfreq governor "powersave" sets the CPU statically to the
#             lowest frequency within the borders of scaling_min_freq and
#             scaling_max_freq.
# userspace:  The CPUfreq governor "userspace" allows the user, or any
#             userspace program running with UID "root", to set the CPU to a
#             specific frequency by making a sysfs file "scaling_setspeed"
#             available in the CPU-device directory.
# ondemand:   The CPUfreq governor "ondemand" sets the CPU depending on the
#             current usage.
# conservative:  The CPUfreq governor "conservative", much like the "ondemand"
#             governor, sets the CPU depending on the current usage.  It
#             differs in behaviour in that it gracefully increases and
#             decreases the CPU speed rather than jumping to max speed the
#             moment there is any load on the CPU.
# schedutil:  The CPUfreq governor "schedutil" aims at better integration with
#             the Linux kernel scheduler. Load estimation is achieved through
#             the scheduler's Per-Entity Load Tracking (PELT) mechanism, which
#             also provides information about the recent load.
SCALING_GOVERNOR=ondemand

# For CPUs using intel_pstate, always use the performance governor. This also
# provides power savings on Intel processors while avoiding the ramp-up lag
# present when using the powersave governor (which is the default if ondemand
# is requested on these machines):
if [ "$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver 2> /dev/null)" = "intel_pstate" ]; then
  SCALING_GOVERNOR="performance"
fi

# Default frequence settings
MIN_FREQ=""
MAX_FREQ=""
FREQ=""

# Default perf bias setting
PERF_BIAS=""

# Load configuration
if [ -r /etc/default/cpupower ]; then
  . /etc/default/cpupower
fi

# If you need to load a specific CPUFreq driver, load it here.  Most likely you don't.
#/sbin/modprobe acpi-cpufreq

# Attempt to apply the CPU scaling governor setting.  This may or may not
# actually override the default value depending on if the choice is supported
# by the architecture, processor, or underlying CPUFreq driver.  For example,
# processors that use the Intel P-state driver will only be able to set
# performance or powersave
# Also attempt to set frequency limits, if any are configured
PARAMS="-g $SCALING_GOVERNOR"

if ! [ -z "$MIN_FREQ" ]; then
  PARAMS="$PARAMS -d $MIN_FREQ"
fi
if ! [ -z "$MAX_FREQ" ]; then
  PARAMS="$PARAMS -u $MAX_FREQ"
fi
if ! [ -z "$FREQ" ]; then
  PARAMS="$PARAMS -f $FREQ"
fi
/usr/bin/cpupower frequency-set $PARAMS 1> /dev/null 2> /dev/null

# Report what CPU scaling governor is in use after applying the setting:
if [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then
  echo "Enabled CPU frequency scaling governor:  $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)"
fi

unset SCALING_GOVERNOR
unset MIN_FREQ
unset MAX_FREQ
unset FREQ

# Attempt to set cpu options, if any are configured
PARAMS=""

if ! [ -z "$PERF_BIAS" ]; then
  PARAMS="$PARAMS -b $PERF_BIAS"
fi

if ! [ -z "$PARAMS" ]; then
  /usr/bin/cpupower set $PARAMS 1> /dev/null 2> /dev/null
fi

unset PERF_BIAS
