#!/bin/bash
do {
	#////////////////////////////////////
	# DietPi CPU Gov Script
	#
	#////////////////////////////////////
	# Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com
	#
	#////////////////////////////////////
	#
	# Info:
	# - Runs at boot up /DietPi/dietpi/boot
	# - Sets CPU governor | ondemand | powersave | performance etc
	# - Sets CPU governor user prefs | throttle up percent etc
	#////////////////////////////////////

	#Import DietPi-Globals ---------------------------------------------------------------
	source /DietPi/dietpi/func/dietpi-globals
	G_CHECK_ROOT_USER
	export G_PROGRAM_NAME='DietPi-CPU_set'
	#Import DietPi-Globals ---------------------------------------------------------------

	#Exit path for VM
	if (( $G_HW_MODEL == 20 )) {

		echo -e "\nNotice: CPU Governors are not available for VM.\n"
		exit

	}

	setvar CPU_GOVERNOR = $(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_GOVERNOR=' | sed 's/.*=//')
	setvar CPU_MAX_FREQ = $(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_MAX_FREQ=' | sed 's/.*=//')
	setvar CPU_MIN_FREQ = $(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_MIN_FREQ=' | sed 's/.*=//')

	proc Check_GPU_Gov_Available {

		#Check if target Gov is available on system.
		if (( ! $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | grep -ci -m1 "$CPU_GOVERNOR") )) {

			G_DIETPI-NOTIFY 1 "CPU gov: $CPU_GOVERNOR, not supported by kernel"

			if (( $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | grep -ci -m1 'ondemand') )) {

				setvar CPU_GOVERNOR = ''ondemand''

			} elif (( $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | grep -ci -m1 'interactive') )) {

				setvar CPU_GOVERNOR = ''interactive''

			} else {

				setvar CPU_GOVERNOR = ''performance''

			}

			G_DIETPI-NOTIFY 2 "Switching to CPU gov: $CPU_GOVERNOR"

			# - Update dietpi.txt
			sed -i "/^CONFIG_CPU_GOVERNOR=/c\CONFIG_CPU_GOVERNOR=$CPU_GOVERNOR" /DietPi/dietpi.txt

		}

	}

	proc Apply_CPU_Gov {

		local input_gov_name=$1
		local input_core_start=$2
		local input_core_end=$3

		#Apply the Gov
		for ((i=$input_core_start; i<$input_core_end; i++))
		do
			echo "$input_gov_name" > /sys/devices/system/cpu/cpu"$i"/cpufreq/scaling_governor
		done

		#Apply CPU max frequency (if set)
		if [[ $CPU_MAX_FREQ =~ ^-?[0-9]+$ ]] &&
			(( $CPU_MAX_FREQ > 0 )) {

			local converted_hz_value=$(( $CPU_MAX_FREQ * 1000 ))

			for ((i=$input_core_start; i<$input_core_end; i++))
			do

				echo "$converted_hz_value" > /sys/devices/system/cpu/cpu"$i"/cpufreq/scaling_max_freq

			done

			G_DIETPI-NOTIFY 2 "Setting CPU max freq: $CPU_MAX_FREQ MHz"

		}

		#Apply CPU min frequency (if set)
		if [[ $CPU_MIN_FREQ =~ ^-?[0-9]+$ ]] &&
			(( $CPU_MIN_FREQ > 0 )) {

			local converted_hz_value=$(( $CPU_MIN_FREQ * 1000 ))

			for ((i=$input_core_start; i<$input_core_end; i++))
			do

				echo "$converted_hz_value" > /sys/devices/system/cpu/cpu"$i"/cpufreq/scaling_min_freq

			done

			G_DIETPI-NOTIFY 2 "Setting CPU min freq: $CPU_MIN_FREQ MHz"

		}

		local cpu_throttle_up_percent=$(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_USAGE_THROTTLE_UP=' | sed 's/.*=//')

		#Set CPU governor interactive settings
		if test $input_gov_name = interactive {

			#Set hispeed_load, if available on system (eg: XU4 kernel lacks this feature)
			if test -f /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load {

				G_DIETPI-NOTIFY 2 "Setting go_hispeed_load: $cpu_throttle_up_percent %"
				echo $cpu_throttle_up_percent > /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load

			}

		#Set CPU governor ondemand settings
		} elif test $input_gov_name = ondemand {

			local cpu_ondemand_sampling_rate=$(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_ONDEMAND_SAMPLE_RATE=' | sed 's/.*=//')
			local cpu_ondemand_sampling_down_factor=$(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_ONDEMAND_SAMPLE_DOWNFACTOR=' | sed 's/.*=//')

			G_DIETPI-NOTIFY 2 "Setting up_threshold: $cpu_throttle_up_percent %"
			G_DIETPI-NOTIFY 2 "Setting sampling_rate: $cpu_ondemand_sampling_rate microseconds"
			G_DIETPI-NOTIFY 2 "Setting sampling_down_factor: $cpu_ondemand_sampling_down_factor"

			#Check for different possible locations
			#	All
			if test -f /sys/devices/system/cpu/cpufreq/ondemand/up_threshold {

				echo $cpu_throttle_up_percent > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold
				echo $cpu_ondemand_sampling_rate > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
				echo $cpu_ondemand_sampling_down_factor > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor

			#	XU4 3.x kernel
			} else {

				#	Apply to all cores
				for ((i=$input_core_start; i<$input_core_end; i++))
				do
					echo "$cpu_throttle_up_percent" > /sys/devices/system/cpu/cpu"$i"/cpufreq/ondemand/up_threshold
					echo "$cpu_ondemand_sampling_rate" > /sys/devices/system/cpu/cpu"$i"/cpufreq/ondemand/sampling_rate
					echo "$cpu_ondemand_sampling_down_factor" > /sys/devices/system/cpu/cpu"$i"/cpufreq/ondemand/sampling_down_factor
				done
			}

		#Set CPU governor conservative settings
		} elif test $input_gov_name = 'conservative' {

			setvar cpu_throttle_up_percent = $(cat /DietPi/dietpi.txt | grep -m1 '^CONFIG_CPU_USAGE_THROTTLE_UP=' | sed 's/.*=//')

			#XU3/4 different path (must apply to each core)
			if (( $G_HW_MODEL == 11 )) {

				for ((i=$input_core_start; i<$input_core_end; i++))
				do

					echo "$cpu_throttle_up_percent" > /sys/devices/system/cpu/cpu"$i"/cpufreq/conservative/up_threshold

				done

			} else {

				echo $cpu_throttle_up_percent > /sys/devices/system/cpu/cpufreq/conservative/up_threshold

			}

		}

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main Loop
	#/////////////////////////////////////////////////////////////////////////////////////
	#-----------------------------------------------------------------------------------
	G_DIETPI-NOTIFY 3 DietPi-Cpu_Set "Applying CPU gov"
	#-----------------------------------------------------------------------------------
	Check_GPU_Gov_Available

	#Apply CPU0 gov to all cores (if required)
	Apply_CPU_Gov $CPU_GOVERNOR 0 $G_HW_CPU_CORES

	G_DIETPI-NOTIFY 0 "CPU gov applied: $CPU_GOVERNOR\n"

	#-----------------------------------------------------------------------------------
	exit
	#-----------------------------------------------------------------------------------
}