mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-02 02:48:51 -05:00
Multiple fixes of clock switching related stability issues: * added RC oscillator hysteresis as in NXP example; * changed DCDC converter config; * configure PLL2 to be able to run on any CPU frequency level; * added switching to 1.275V (overdrive) voltage when applying any clock change above 12MHz as well as LDO or bandgap switching, as done in Mbed OS' lpm.c for RT1050; * changed BMCR AXI queues weighs for SDRAM in JLink scripts to disable operations reordering, as it is known to cause data integrity issues; * extracted some code to separate files; * smaller or bigger code cleanups.
85 lines
3.1 KiB
C++
85 lines
3.1 KiB
C++
// 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
|