1#!/bin/bash
2
3# shim system-level operations to allow for unit testing
4function MkDir() { mkdir     "$@"; }
5function Mv() { mv        "$@"; }
6function Sleep() { sleep     "$@"; }
7function SystemCtl() { systemctl "$@"; }
8
9# Store commanded rpm as thermal set-point.
10#
11# Arg:
12#   rpm - rpm set-point.
13function CommandRpm() {
14    printf '%d\n' "$1" > /etc/thermal.d/set-point
15}
16
17# Sweep or step rpm over range.
18#
19# Args:
20#   start_rpm: start RPM value
21#   stop_rpm: stop RPM value
22#   num_steps: number of control steps; i.e., not including start.
23#   dwell: dwell time at each point, in seconds
24function RunRpmSteps() {
25    local -i start_rpm=$1
26    local -i stop_rpm=$2
27    local -i num_steps=$3
28    local -i dwell=$4
29
30    # Rounding offset when dividing range into num_steps
31    local -i h=$((num_steps / 2))
32
33    # To avoid asymmetrical division behavior for negative numbers,
34    # rearrange negative slope to positive slope running backward;
35    # I.e., to run using loop variable p: {num_steps downto 0}.
36    local -i rpm0=$((start_rpm))
37    local -i range=$((stop_rpm - start_rpm))
38    local -i s=1
39    if ((range < 0)); then
40        ((rpm0 = stop_rpm))
41        ((range = -range))
42        ((s = -1))
43    fi
44
45    echo "Running RPM from ${start_rpm} to ${stop_rpm} in ${num_steps} steps"
46    CommandRpm "${start_rpm}"
47    SystemCtl start phosphor-pid-control.service
48    Sleep 60
49
50    local i
51    for ((i = 0; i <= num_steps; ++i)); do
52        local -i p=$((s < 0 ? num_steps - i : i))
53        local -i rpm=$((rpm0 + (range * p + h) / num_steps))
54        echo "Setting RPM to ${rpm} and sleep ${dwell} seconds"
55        CommandRpm "${rpm}"
56        Sleep "${dwell}"
57    done
58
59    SystemCtl stop phosphor-pid-control.service
60    Mv /tmp/swampd.log ~/"${start_rpm}_${stop_rpm}_${num_steps}_${dwell}.csv"
61    echo "Done!!"
62}
63
64# Sweep and step fans from min to max and max to min.
65#
66# Args:
67#   min_rpm: min RPM for the platform
68#   max_rpm: max RPM for the platform
69function main() {
70    local min_rpm=$1
71    local max_rpm=$2
72
73    if ((min_rpm < 1 || max_rpm < min_rpm)); then
74        echo "Invalid arguments. Usage: fan_rpm_loop_test.sh <MIN_RPM> <MAX_RPM>"
75        return 1
76    fi
77
78    MkDir -p /etc/thermal.d/
79    SystemCtl stop phosphor-pid-control.service
80
81    RunRpmSteps "${min_rpm}" "${max_rpm}" 10 30
82    RunRpmSteps "${max_rpm}" "${min_rpm}" 10 30
83    RunRpmSteps "${min_rpm}" "${max_rpm}"  1 30
84    RunRpmSteps "${max_rpm}" "${min_rpm}"  1 30
85}
86
87if [ "$0" = "${BASH_SOURCE[0]}" ]; then
88    # not sourced, execute main function
89    main "$@"
90fi
91