[BH-990] Adjist CPU frequency chages

Adjusted Bell frequency low-power mode changes
This commit is contained in:
Wojtek Rzepecki
2021-10-11 17:17:44 +02:00
committed by Wojciech Rzepecki
parent a93105d7af
commit 6e69eb6aa6
21 changed files with 146 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ target_sources(module-bsp
keypad_backlight/keypad_backlight.cpp
light_sensor/light_sensor.cpp
lpm/LinuxLPM.cpp
lpm/PowerProfile.cpp
magnetometer/magnetometer.cpp
rtc/rtc.cpp
torch/torch.cpp

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <bsp/lpm/PowerProfile.hpp>
namespace bsp
{
const PowerProfile getPowerProfile()
{
PowerProfile linuxPowerProfile;
linuxPowerProfile.frequencyShiftLowerThreshold = 40;
linuxPowerProfile.frequencyShiftUpperThreshold = 60;
linuxPowerProfile.maxBelowThresholdCount = 30;
linuxPowerProfile.maxBelowThresholdInRowCount = 10;
linuxPowerProfile.maxAboveThresholdCount = 3;
linuxPowerProfile.minimalFrequency = CpuFrequencyHz::Level_1;
linuxPowerProfile.frequencyIncreaseIntermediateStep = false;
return linuxPowerProfile;
}
} // namespace bsp

View File

@@ -19,6 +19,7 @@ target_sources(
bsp/bell_temp_sensor/bell_temp_sensor.cpp
bsp/battery-charger/battery-charger.cpp
bsp/fuel_gauge/fuel_gauge.cpp
bsp/lpm/PowerProfile.cpp
pin_mux.c
clock_config.cpp
irq_gpio.cpp

View File

@@ -28,7 +28,7 @@ namespace bsp::fuel_gauge
(static_cast<uint8_t>(FuelGaugeAlertCapacityPercent) << static_cast<uint8_t>(CONFIG::shift)) &
static_cast<uint8_t>(CONFIG::mask);
constexpr auto POLL_INTERVAL_MS = 60U * 1000U;
constexpr auto POLL_INTERVAL_MS = 5U * 60U * 1000U;
enum class CW201xRetCode : int
{

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <bsp/lpm/PowerProfile.hpp>
namespace bsp
{
const PowerProfile getPowerProfile()
{
PowerProfile bellPowerProfile;
bellPowerProfile.frequencyShiftLowerThreshold = 50;
bellPowerProfile.frequencyShiftUpperThreshold = 90;
bellPowerProfile.maxBelowThresholdCount = 10;
bellPowerProfile.maxBelowThresholdInRowCount = 5;
bellPowerProfile.maxAboveThresholdCount = 3;
bellPowerProfile.minimalFrequency = CpuFrequencyHz::Level_0;
bellPowerProfile.frequencyIncreaseIntermediateStep = true;
return bellPowerProfile;
}
} // namespace bsp

View File

@@ -15,6 +15,14 @@ namespace bsp
DCDC_AdjustTargetVoltage(DCDC, VDDRun_1275_mV, VDDStandby_925_mV);
switch (freq) {
case CpuClock::CpuClock_Osc_4_Mhz:
/* Set PERIPH_CLK2_PODF. */
CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 2);
/* Set AHB_PODF. */
CLOCK_SetDiv(kCLOCK_AhbDiv, 1); // CBCDR
DCDC_AdjustTargetVoltage(DCDC, VDDRun_900_mV, VDDStandby_925_mV);
break;
case CpuClock::CpuClock_Osc_12_Mhz:
/* Set PERIPH_CLK2_PODF. */
CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0);
@@ -53,7 +61,8 @@ namespace bsp
break;
}
if (freq == CpuClock::CpuClock_Osc_12_Mhz || freq == CpuClock::CpuClock_Osc_24_Mhz) {
if (freq == CpuClock::CpuClock_Osc_4_Mhz || freq == CpuClock::CpuClock_Osc_12_Mhz ||
freq == CpuClock::CpuClock_Osc_24_Mhz) {
/* Set periph clock source. */
CLOCK_SetMux(kCLOCK_PeriphMux, 1);
}

View File

@@ -23,6 +23,7 @@ namespace bsp
public:
enum class CpuClock
{
CpuClock_Osc_4_Mhz,
CpuClock_Osc_12_Mhz,
CpuClock_Osc_24_Mhz,
CpuClock_Pll2_66_Mhz,

View File

@@ -72,6 +72,9 @@ namespace bsp
{
currentFrequency = freq;
switch (freq) {
case bsp::CpuFrequencyHz::Level_0:
CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_4_Mhz);
break;
case bsp::CpuFrequencyHz::Level_1:
CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_12_Mhz);
break;

View File

@@ -15,6 +15,7 @@ target_sources(
bsp/battery_charger/battery_charger.cpp
bsp/eink/eink_pin_config.cpp
bsp/keyboard/keyboard.cpp
bsp/lpm/PowerProfile.cpp
pin_mux.c
clock_config.cpp
irq_gpio.cpp

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <bsp/lpm/PowerProfile.hpp>
namespace bsp
{
const PowerProfile getPowerProfile()
{
PowerProfile purePowerProfile;
purePowerProfile.frequencyShiftLowerThreshold = 40;
purePowerProfile.frequencyShiftUpperThreshold = 60;
purePowerProfile.maxBelowThresholdCount = 30;
purePowerProfile.maxBelowThresholdInRowCount = 10;
purePowerProfile.maxAboveThresholdCount = 3;
purePowerProfile.minimalFrequency = CpuFrequencyHz::Level_1;
purePowerProfile.frequencyIncreaseIntermediateStep = false;
return purePowerProfile;
}
} // namespace bsp

View File

@@ -15,6 +15,7 @@ namespace bsp
/// Only a few thresholds are available in the current configuration
enum class CpuFrequencyHz
{
Level_0 = 4000000,
Level_1 = 12000000,
Level_2 = 24000000,
Level_3 = 66000000,

View File

@@ -0,0 +1,23 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include <bsp/common.hpp>
#include <cstdint>
namespace bsp
{
struct PowerProfile
{
std::uint32_t frequencyShiftLowerThreshold;
std::uint32_t frequencyShiftUpperThreshold;
std::uint32_t maxBelowThresholdCount;
std::uint32_t maxBelowThresholdInRowCount;
std::uint32_t maxAboveThresholdCount;
CpuFrequencyHz minimalFrequency;
bool frequencyIncreaseIntermediateStep;
};
const PowerProfile getPowerProfile();
} // namespace bsp

View File

@@ -9,7 +9,7 @@ namespace sys
{
GovernorSentinel::GovernorSentinel(std::shared_ptr<CpuSentinel> newSentinel)
: sentinelPtr(newSentinel), requestedFrequency(bsp::CpuFrequencyHz::Level_1)
: sentinelPtr(newSentinel), requestedFrequency(bsp::CpuFrequencyHz::Level_0)
{}
[[nodiscard]] auto GovernorSentinel::GetSentinel() const noexcept -> SentinelPointer
@@ -77,12 +77,12 @@ namespace sys
void CpuGovernor::ResetCpuFrequencyRequest(std::string sentinelName)
{
SetCpuFrequencyRequest(sentinelName, bsp::CpuFrequencyHz::Level_1);
SetCpuFrequencyRequest(sentinelName, bsp::CpuFrequencyHz::Level_0);
}
[[nodiscard]] auto CpuGovernor::GetMinimumFrequencyRequested() const noexcept -> bsp::CpuFrequencyHz
{
bsp::CpuFrequencyHz minFrequency = bsp::CpuFrequencyHz::Level_1;
bsp::CpuFrequencyHz minFrequency = bsp::CpuFrequencyHz::Level_0;
for (auto &sentinel : sentinels) {
const auto sentinelFrequency = sentinel->GetRequestedFrequency();

View File

@@ -29,10 +29,10 @@ namespace sys
void CpuSentinel::ReleaseMinimumFrequency()
{
if (currentFrequencyToHold != bsp::CpuFrequencyHz::Level_1) {
if (currentFrequencyToHold != bsp::CpuFrequencyHz::Level_0) {
auto msg = std::make_shared<sys::ReleaseCpuFrequencyMessage>(GetName());
owner->bus.sendUnicast(std::move(msg), service::name::system_manager);
currentFrequencyToHold = bsp::CpuFrequencyHz::Level_1;
currentFrequencyToHold = bsp::CpuFrequencyHz::Level_0;
}
}

View File

@@ -9,11 +9,6 @@ namespace sys
{
namespace
{
inline constexpr uint32_t frequencyShiftLowerThreshold{40};
inline constexpr uint32_t frequencyShiftUpperThreshold{60};
inline constexpr uint32_t maxBelowThresholdCount{30};
inline constexpr uint32_t maxBelowThresholdInRowCount{10};
inline constexpr uint32_t maxAboveThresholdCount{3};
constexpr auto lowestLevelName{"lowestCpuFrequency"};
constexpr auto middleLevelName{"middleCpuFrequency"};
constexpr auto highestLevelName{"highestCpuFrequency"};
@@ -38,7 +33,7 @@ namespace sys
totalTicksCount += ticks;
}
PowerManager::PowerManager()
PowerManager::PowerManager() : powerProfile{bsp::getPowerProfile()}
{
lowPowerControl = bsp::LowPowerMode::Create().value_or(nullptr);
driverSEMC = drivers::DriverSEMC::Create("ExternalRAM");
@@ -81,11 +76,12 @@ namespace sys
const auto currentCpuFreq = lowPowerControl->GetCurrentFrequencyLevel();
const auto minFrequencyRequested = cpuGovernor->GetMinimumFrequencyRequested();
if (cpuLoad > frequencyShiftUpperThreshold && currentCpuFreq < bsp::CpuFrequencyHz::Level_6) {
if (cpuLoad > powerProfile.frequencyShiftUpperThreshold && currentCpuFreq < bsp::CpuFrequencyHz::Level_6) {
aboveThresholdCounter++;
belowThresholdCounter = 0;
}
else if (cpuLoad < frequencyShiftLowerThreshold && currentCpuFreq > bsp::CpuFrequencyHz::Level_1) {
else if (cpuLoad < powerProfile.frequencyShiftLowerThreshold &&
currentCpuFreq > powerProfile.minimalFrequency) {
belowThresholdCounter++;
aboveThresholdCounter = 0;
}
@@ -101,13 +97,19 @@ namespace sys
ResetFrequencyShiftCounter();
IncreaseCpuFrequency(minFrequencyRequested);
}
else if (aboveThresholdCounter >= maxAboveThresholdCount) {
ResetFrequencyShiftCounter();
IncreaseCpuFrequency(bsp::CpuFrequencyHz::Level_6);
else if (aboveThresholdCounter >= powerProfile.maxAboveThresholdCount) {
if (powerProfile.frequencyIncreaseIntermediateStep && currentCpuFreq < bsp::CpuFrequencyHz::Level_4) {
ResetFrequencyShiftCounter();
IncreaseCpuFrequency(bsp::CpuFrequencyHz::Level_4);
}
else {
ResetFrequencyShiftCounter();
IncreaseCpuFrequency(bsp::CpuFrequencyHz::Level_6);
}
}
else {
if (belowThresholdCounter >=
(isFrequencyLoweringInProgress ? maxBelowThresholdInRowCount : maxBelowThresholdCount) &&
if (belowThresholdCounter >= (isFrequencyLoweringInProgress ? powerProfile.maxBelowThresholdInRowCount
: powerProfile.maxBelowThresholdCount) &&
currentCpuFreq > minFrequencyRequested) {
ResetFrequencyShiftCounter();
DecreaseCpuFrequency();
@@ -119,7 +121,7 @@ namespace sys
{
const auto freq = lowPowerControl->GetCurrentFrequencyLevel();
if (freq == bsp::CpuFrequencyHz::Level_1) {
if ((freq <= bsp::CpuFrequencyHz::Level_1) && (newFrequency > bsp::CpuFrequencyHz::Level_1)) {
// connect internal the load resistor
lowPowerControl->ConnectInternalLoadResistor();
// turn off power save mode for DCDC inverter
@@ -148,7 +150,7 @@ namespace sys
void PowerManager::DecreaseCpuFrequency()
{
const auto freq = lowPowerControl->GetCurrentFrequencyLevel();
auto level = bsp::CpuFrequencyHz::Level_1;
auto level = powerProfile.minimalFrequency;
switch (freq) {
case bsp::CpuFrequencyHz::Level_6:
@@ -164,9 +166,11 @@ namespace sys
level = bsp::CpuFrequencyHz::Level_2;
break;
case bsp::CpuFrequencyHz::Level_2:
level = bsp::CpuFrequencyHz::Level_1;
level = powerProfile.minimalFrequency;
break;
case bsp::CpuFrequencyHz::Level_1:
[[fallthrough]];
case bsp::CpuFrequencyHz::Level_0:
break;
}
@@ -175,7 +179,7 @@ namespace sys
SetCpuFrequency(level);
}
if (level == bsp::CpuFrequencyHz::Level_1) {
if (level <= bsp::CpuFrequencyHz::Level_1) {
// Enable weak 2P5 and 1P1 LDO and Turn off regular 2P5 and 1P1 LDO
lowPowerControl->SwitchToLowPowerModeLDO();
@@ -233,7 +237,7 @@ namespace sys
void PowerManager::UpdateCpuFrequencyMonitor(bsp::CpuFrequencyHz currentFreq)
{
auto ticks = xTaskGetTickCount();
auto levelName = currentFreq == bsp::CpuFrequencyHz::Level_1
auto levelName = currentFreq == powerProfile.minimalFrequency
? lowestLevelName
: (currentFreq == bsp::CpuFrequencyHz::Level_6 ? highestLevelName : middleLevelName);

View File

@@ -670,7 +670,7 @@ namespace sys
void SystemManagerCommon::UpdateResourcesAfterCpuFrequencyChange(bsp::CpuFrequencyHz newFrequency)
{
if (newFrequency == bsp::CpuFrequencyHz::Level_1) {
if (newFrequency <= bsp::CpuFrequencyHz::Level_1) {
purefs::subsystem::disk_mgr()->pm_control(purefs::blkdev::pm_state::suspend);
}
else {

View File

@@ -31,7 +31,7 @@ namespace sys
protected:
const std::string name;
bsp::CpuFrequencyHz currentFrequencyToHold{bsp::CpuFrequencyHz::Level_1};
bsp::CpuFrequencyHz currentFrequencyToHold{bsp::CpuFrequencyHz::Level_0};
sys::Service *owner{nullptr};
/// function called from the PowerManager context

View File

@@ -9,6 +9,7 @@
#include "bsp/lpm/bsp_lpm.hpp"
#include "drivers/semc/DriverSEMC.hpp"
#include "CpuGovernor.hpp"
#include <bsp/lpm/PowerProfile.hpp>
#include <vector>
namespace sys
@@ -78,6 +79,7 @@ namespace sys
std::unique_ptr<bsp::LowPowerMode> lowPowerControl;
std::shared_ptr<drivers::DriverSEMC> driverSEMC;
std::unique_ptr<CpuGovernor> cpuGovernor;
const bsp::PowerProfile powerProfile;
};
} // namespace sys

View File

@@ -39,7 +39,7 @@ TEST_CASE("Power Manager CPU sentinels governor test")
governor->RegisterNewSentinel(testSentinel_1);
governor->RegisterNewSentinel(testSentinel_2);
REQUIRE(governor->GetMinimumFrequencyRequested() == bsp::CpuFrequencyHz::Level_1);
REQUIRE(governor->GetMinimumFrequencyRequested() == bsp::CpuFrequencyHz::Level_0);
governor->SetCpuFrequencyRequest("testSentinel_1", bsp::CpuFrequencyHz::Level_4);
REQUIRE(governor->GetMinimumFrequencyRequested() == bsp::CpuFrequencyHz::Level_4);
@@ -56,7 +56,10 @@ TEST_CASE("Power Manager CPU sentinels governor test")
governor->SetCpuFrequencyRequest("bedNameSentinel", bsp::CpuFrequencyHz::Level_6);
REQUIRE(governor->GetMinimumFrequencyRequested() == bsp::CpuFrequencyHz::Level_2);
governor->ResetCpuFrequencyRequest("testSentinel_1");
governor->SetCpuFrequencyRequest("testSentinel_1", bsp::CpuFrequencyHz::Level_1);
REQUIRE(governor->GetMinimumFrequencyRequested() == bsp::CpuFrequencyHz::Level_1);
governor->ResetCpuFrequencyRequest("testSentinel_1");
REQUIRE(governor->GetMinimumFrequencyRequested() == bsp::CpuFrequencyHz::Level_0);
}
}

View File

@@ -29,7 +29,7 @@ namespace sys
private:
std::string sentinelName;
bsp::CpuFrequencyHz frequencyRequested = bsp::CpuFrequencyHz::Level_1;
bsp::CpuFrequencyHz frequencyRequested = bsp::CpuFrequencyHz::Level_0;
};
class ReleaseCpuFrequencyMessage : public sys::DataMessage

View File

@@ -9,7 +9,7 @@ namespace service::eink
{
namespace
{
constexpr auto RedrawEinkCpuFrequency = bsp::CpuFrequencyHz::Level_6;
constexpr auto RedrawEinkCpuFrequency = bsp::CpuFrequencyHz::Level_5;
} // namespace
EinkSentinel::EinkSentinel(std::string name, sys::Service *service) : sys::CpuSentinel(name, service)