From 1521858134d0de81e142a7fe37313748a8b25013 Mon Sep 17 00:00:00 2001 From: Maciej-Mudita Date: Fri, 8 Jan 2021 16:00:56 +0100 Subject: [PATCH] [EGD-4887] Add PLL2 clock switching Pll2 will be disabled at the lowest CPU frequency, which will save power --- changelog.md | 1 + module-bsp/board/linux/lpm/LinuxLPM.cpp | 5 ++++ module-bsp/board/linux/lpm/LinuxLPM.h | 1 + module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp | 24 +++++++++++++++ module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp | 3 +- module-bsp/bsp/lpm/bsp_lpm.cpp | 5 ++++ module-bsp/bsp/lpm/bsp_lpm.hpp | 9 ++++++ module-sys/SystemManager/PowerManager.cpp | 30 ++++++++++++++----- 8 files changed, 69 insertions(+), 9 deletions(-) diff --git a/changelog.md b/changelog.md index 09f41905c9356733f62104f900b86ac48ec9466f..59458f9bde433d6566d0332c789587ebffb53d64 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ * Battery Brownout detection * VoLTE ON/OFF switch in Settings Network window +* Add PLL2 clock switching ### Changed diff --git a/module-bsp/board/linux/lpm/LinuxLPM.cpp b/module-bsp/board/linux/lpm/LinuxLPM.cpp index 9bd4ff419eaee7314b018ede46762077ecfa1fe8..db440c9c1400ebbc0183f2aa6ea7828166e37f99 100644 --- a/module-bsp/board/linux/lpm/LinuxLPM.cpp +++ b/module-bsp/board/linux/lpm/LinuxLPM.cpp @@ -29,4 +29,9 @@ namespace bsp { currentOscSource = source; } + + void LinuxLPM::SwitchPll2State(bsp::LowPowerMode::Pll2State state) + { + currentPll2State = state; + } } // namespace bsp diff --git a/module-bsp/board/linux/lpm/LinuxLPM.h b/module-bsp/board/linux/lpm/LinuxLPM.h index 5ee1d8c3f10de76b9cb52927bb6da76a527bb228..f3b6d4dad6d4a5558510c928ed2a872655128e24 100644 --- a/module-bsp/board/linux/lpm/LinuxLPM.h +++ b/module-bsp/board/linux/lpm/LinuxLPM.h @@ -17,6 +17,7 @@ namespace bsp int32_t Reboot() override final; void SetCpuFrequency(CpuFrequency freq) final; void SwitchOscillatorSource(OscillatorSource source) final; + void SwitchPll2State(Pll2State state) final; }; } // namespace bsp diff --git a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp index 3cb8a23be73927e9294fc8cea4d8a14c18647b0d..e15b9da4a108e06850380e029c01c50345fcd8c3 100644 --- a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp +++ b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp @@ -7,6 +7,7 @@ #include "log/log.hpp" #include "bsp/BoardDefinitions.hpp" #include "bsp/watchdog/watchdog.hpp" +#include #include #include @@ -101,6 +102,29 @@ namespace bsp currentOscSource = source; } + void RT1051LPM::SwitchPll2State(bsp::LowPowerMode::Pll2State state) + { + if (state == bsp::LowPowerMode::Pll2State::Disable) { + if (IsClockEnabled(kCLOCK_Lpspi1) || IsClockEnabled(kCLOCK_Lpspi2) || IsClockEnabled(kCLOCK_Lpspi3) || + IsClockEnabled(kCLOCK_Lpspi4) || IsClockEnabled(kCLOCK_Usdhc1) || IsClockEnabled(kCLOCK_Usdhc2)) { + return; + } + + /// First switch external RAM clock + CLOCK_SetMux(kCLOCK_SemcMux, 0); + /// Then turn off PLL2 + clkPLL2setup(CLK_DISABLE); + } + else { + /// First turn on PLL2 + clkPLL2setup(CLK_ENABLE); + /// Then switch external RAM clock + CLOCK_SetMux(kCLOCK_SemcMux, 1); + } + + currentPll2State = state; + } + bool RT1051LPM::IsClockEnabled(clock_ip_name_t name) const noexcept { const auto index = static_cast(name) >> CCM_TupleShift; diff --git a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp index 68754d1155a43cd90e10dbf6e40e2c3fd22d42e4..4e9c7e6242556758e02ea12ef90dea1d6915b692 100644 --- a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp +++ b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp @@ -14,7 +14,7 @@ namespace bsp inline constexpr uint8_t OscillatorReadyCounterValue{127}; inline constexpr uint8_t CCM_TupleShift{8}; inline constexpr uint8_t CCM_TupleMask{0x1F}; - inline constexpr uint32_t ClockNeededRunWaitMode{3}; + inline constexpr uint32_t ClockNeededRunWaitMode{kCLOCK_ClockNeededRunWait}; class RT1051LPM : public LowPowerMode { @@ -24,6 +24,7 @@ namespace bsp int32_t Reboot() override final; void SetCpuFrequency(CpuFrequency freq) final; void SwitchOscillatorSource(OscillatorSource source) final; + void SwitchPll2State(Pll2State state) final; private: [[nodiscard]] bool IsClockEnabled(clock_ip_name_t name) const noexcept; diff --git a/module-bsp/bsp/lpm/bsp_lpm.cpp b/module-bsp/bsp/lpm/bsp_lpm.cpp index da90e0eabc2fc4984df65b135e211cdcdd9c015c..39fd726f39c0db3f0124bb50d17204a4b6da112e 100644 --- a/module-bsp/bsp/lpm/bsp_lpm.cpp +++ b/module-bsp/bsp/lpm/bsp_lpm.cpp @@ -35,4 +35,9 @@ namespace bsp{ { return currentOscSource; } + + LowPowerMode::Pll2State LowPowerMode::GetCurrentPll2State() const noexcept + { + return currentPll2State; + } } diff --git a/module-bsp/bsp/lpm/bsp_lpm.hpp b/module-bsp/bsp/lpm/bsp_lpm.hpp index 0f7705a6820d770ecaff83fe85c5ebf01587cc3d..03ed25da2188f4824a09cc71973510dfce310a91 100644 --- a/module-bsp/bsp/lpm/bsp_lpm.hpp +++ b/module-bsp/bsp/lpm/bsp_lpm.hpp @@ -23,6 +23,11 @@ namespace bsp { External, Internal }; + enum class Pll2State + { + Enable, + Disable + }; LowPowerMode() = default; virtual ~LowPowerMode() = default; @@ -38,9 +43,13 @@ namespace bsp { virtual void SwitchOscillatorSource(OscillatorSource source) = 0; [[nodiscard]] OscillatorSource GetCurrentOscillatorSource() const noexcept; + virtual void SwitchPll2State(Pll2State state) = 0; + [[nodiscard]] Pll2State GetCurrentPll2State() const noexcept; + protected: CpuFrequency currentFrequency = CpuFrequency::Level_6; OscillatorSource currentOscSource = OscillatorSource::External; + Pll2State currentPll2State = Pll2State::Enable; }; } // namespace bsp diff --git a/module-sys/SystemManager/PowerManager.cpp b/module-sys/SystemManager/PowerManager.cpp index e6f47dc0c866d9f341a38e15af0d5bf1fe069b55..006fd1b7fe2910cb270116efaf113a52b30f1ea3 100644 --- a/module-sys/SystemManager/PowerManager.cpp +++ b/module-sys/SystemManager/PowerManager.cpp @@ -55,14 +55,20 @@ namespace sys { const auto freq = lowPowerControl->GetCurrentFrequency(); const auto oscSource = lowPowerControl->GetCurrentOscillatorSource(); + const auto pll2State = lowPowerControl->GetCurrentPll2State(); - /// switch osc source first + // switch osc source first if (freq == bsp::LowPowerMode::CpuFrequency::Level_1 && oscSource == bsp::LowPowerMode::OscillatorSource::Internal) { lowPowerControl->SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::External); } - /// then increase frequency + // then turn on pll2 + if (pll2State == bsp::LowPowerMode::Pll2State::Disable) { + lowPowerControl->SwitchPll2State(bsp::LowPowerMode::Pll2State::Enable); + } + + // and increase frequency if (freq < bsp::LowPowerMode::CpuFrequency::Level_6) { lowPowerControl->SetCpuFrequency(bsp::LowPowerMode::CpuFrequency::Level_6); } @@ -71,7 +77,6 @@ namespace sys void PowerManager::DecreaseCpuFrequency() const { const auto freq = lowPowerControl->GetCurrentFrequency(); - const auto oscSource = lowPowerControl->GetCurrentOscillatorSource(); auto level = bsp::LowPowerMode::CpuFrequency::Level_1; switch (freq) { @@ -94,15 +99,24 @@ namespace sys break; } - /// decrease frequency first + // decrease frequency first if (level != freq) { lowPowerControl->SetCpuFrequency(level); } - /// then switch osc source - if (level == bsp::LowPowerMode::CpuFrequency::Level_1 && - oscSource == bsp::LowPowerMode::OscillatorSource::External) { - lowPowerControl->SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::Internal); + if (level == bsp::LowPowerMode::CpuFrequency::Level_1) { + const auto oscSource = lowPowerControl->GetCurrentOscillatorSource(); + const auto pll2State = lowPowerControl->GetCurrentPll2State(); + + // then switch osc source + if (oscSource == bsp::LowPowerMode::OscillatorSource::External) { + lowPowerControl->SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::Internal); + } + + // and turn off pll2 + if (pll2State == bsp::LowPowerMode::Pll2State::Enable) { + lowPowerControl->SwitchPll2State(bsp::LowPowerMode::Pll2State::Disable); + } } }