~aleteoryx/muditaos

ref: 3cbbeff551230786ae13c23a7bf4fa8c50099896 muditaos/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp -rw-r--r-- 3.1 KiB
3cbbeff5 — Lefucjusz [MOS-1011] Fix frequency switching stability 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FrequencyStepping.hpp"
#include "SystemManager/CpuGovernor.hpp"

namespace sys::cpu
{

    FrequencyStepping::FrequencyStepping(const bsp::PowerProfile &powerProfile, CpuGovernor &cpuGovernor)
        : powerProfile(powerProfile), cpuGovernor(cpuGovernor)
    {}

    bsp::CpuFrequencyMHz stepDown(bsp::CpuFrequencyMHz freq, const bsp::PowerProfile &profile)
    {
        switch (freq) {
        case bsp::CpuFrequencyMHz::Level_6:
            return bsp::CpuFrequencyMHz::Level_5;
        case bsp::CpuFrequencyMHz::Level_5:
            return bsp::CpuFrequencyMHz::Level_4;
        case bsp::CpuFrequencyMHz::Level_4:
            return bsp::CpuFrequencyMHz::Level_3;
        case bsp::CpuFrequencyMHz::Level_3:
            return bsp::CpuFrequencyMHz::Level_2;
        case bsp::CpuFrequencyMHz::Level_2:
        case bsp::CpuFrequencyMHz::Level_1:
        case bsp::CpuFrequencyMHz::Level_0:
            return profile.minimalFrequency;
        }
        return freq;
    }

    AlgorithmResult FrequencyStepping::calculateImplementation(const AlgorithmData &data)
    {
        const auto load           = data.CPUload;
        const auto startFrequency = data.curentFrequency;
        const auto min            = cpuGovernor.GetMinimumFrequencyRequested();

        if (load > powerProfile.frequencyShiftUpperThreshold && startFrequency < bsp::CpuFrequencyMHz::Level_6) {
            aboveThresholdCounter++;
            belowThresholdCounter = 0;
        }
        else if (load < powerProfile.frequencyShiftLowerThreshold && startFrequency > powerProfile.minimalFrequency) {
            belowThresholdCounter++;
            aboveThresholdCounter = 0;
        }
        else {
            reset();
        }

        if (belowThresholdCounter == 0u) {
            isFrequencyDownscalingInProgress = false;
        }

        if (min.frequency > startFrequency) {}
        else if (aboveThresholdCounter >= powerProfile.maxAboveThresholdCount) {
            if (startFrequency < bsp::CpuFrequencyMHz::Level_4) {
                reset();
                return {algorithm::Change::UpScaled, bsp::CpuFrequencyMHz::Level_4};
            }
            else {
                reset();
                return {algorithm::Change::UpScaled, bsp::CpuFrequencyMHz::Level_6};
            }
        }
        else {
            if (belowThresholdCounter >= (isFrequencyDownscalingInProgress ? powerProfile.maxBelowThresholdInRowCount
                                                                           : powerProfile.maxBelowThresholdCount) &&
                startFrequency > min.frequency) {
                isFrequencyDownscalingInProgress = true;
                reset();
                return {algorithm::Change::Downscaled, stepDown(startFrequency, powerProfile)};
            }
        }

        return {algorithm::Change::NoChange, startFrequency};
    }

    void FrequencyStepping::resetImplementation()
    {
        aboveThresholdCounter = 0;
        belowThresholdCounter = 0;
    }
} // namespace sys::cpu