~aleteoryx/muditaos

0cc2af0850ddea4a348294c895dc188cb72b56ae — Maciej Gibowicz 5 years ago 84d61d6
[EGD-4472] PowerManagement: Separation of CPU clock into separate clock domain (#1125)

Change CPU clock into separate clock domain

We can control the CPU frequency independently of the peripherals.
M changelog.md => changelog.md +1 -0
@@ 14,6 14,7 @@

* `[desktop]` Windows refactor
* `[notes]` A note characters limit set to 4'000.
* `[PowerManagement]` Separation of CPU clock into separate clock domain

### Fixed


M module-bsp/board/linux/lpm/LinuxLPM.cpp => module-bsp/board/linux/lpm/LinuxLPM.cpp +3 -0
@@ 25,4 25,7 @@ namespace bsp
    {
        return 0;
    }

    void LinuxLPM::SetCpuFrequency(bsp::LowPowerMode::CpuFrequency freq)
    {}
} // namespace bsp

M module-bsp/board/linux/lpm/LinuxLPM.h => module-bsp/board/linux/lpm/LinuxLPM.h +1 -0
@@ 16,6 16,7 @@ namespace bsp
        int32_t Switch(const Mode mode) override final;
        int32_t PowerOff() override final;
        int32_t Reboot() override final;
        void SetCpuFrequency(CpuFrequency freq) final;
    };

} // namespace bsp

A module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp => module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp +68 -0
@@ 0,0 1,68 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "CpuFreqLPM.hpp"
#include "log/log.hpp"
#include "fsl_dcdc.h"

namespace bsp
{
    CpuFreqLPM::CpuFreqLPM()
    {}

    void CpuFreqLPM::SetCpuFrequency(CpuFreqLPM::CpuClock freq)
    {
        DCDC_AdjustTargetVoltage(DCDC, VDDRun_1275_mV, VDDStandby_925_mV);

        switch (freq) {
        case CpuClock::CpuClock_Osc_12_Mhz:
            /* Set PERIPH_CLK2_PODF. */
            CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0);
            /* Set AHB_PODF. */
            CLOCK_SetDiv(kCLOCK_AhbDiv, 1); // CBCDR

            DCDC_AdjustTargetVoltage(DCDC, VDDRun_900_mV, VDDStandby_925_mV);
            break;
        case CpuClock::CpuClock_Osc_24_Mhz:
            /* Set PERIPH_CLK2_PODF. */
            CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0);
            /* Set AHB_PODF. */
            CLOCK_SetDiv(kCLOCK_AhbDiv, 0); // CBCDR

            DCDC_AdjustTargetVoltage(DCDC, VDDRun_1050_mV, VDDStandby_925_mV);
            break;
        case CpuClock::CpuClock_Pll2_66_Mhz:
            /* Set AHB_PODF. */
            CLOCK_SetDiv(kCLOCK_AhbDiv, 7); // CBCDR
            DCDC_AdjustTargetVoltage(DCDC, VDDRun_1075_mV, VDDStandby_925_mV);
            break;
        case CpuClock::CpuClock_Pll2_132_Mhz:
            /* Set AHB_PODF. */
            CLOCK_SetDiv(kCLOCK_AhbDiv, 3); // CBCDR
            DCDC_AdjustTargetVoltage(DCDC, VDDRun_1100_mV, VDDStandby_925_mV);
            break;
        case CpuClock::CpuClock_Pll2_264_Mhz:
            /* Set AHB_PODF. */
            CLOCK_SetDiv(kCLOCK_AhbDiv, 1); // CBCDR
            DCDC_AdjustTargetVoltage(DCDC, VDDRun_1125_mV, VDDStandby_925_mV);
            break;
        case CpuClock::CpuClock_Pll2_528_Mhz:
            /* Set AHB_PODF. */
            CLOCK_SetDiv(kCLOCK_AhbDiv, 0); // CBCDR
            DCDC_AdjustTargetVoltage(DCDC, VDDRun_1150_mV, VDDStandby_925_mV);
            break;
        }

        if (freq == CpuClock::CpuClock_Osc_12_Mhz || freq == CpuClock::CpuClock_Osc_24_Mhz) {
            /* Set periph clock source. */
            CLOCK_SetMux(kCLOCK_PeriphMux, 1);
        }
        else {
            /* Set periph clock source. */
            CLOCK_SetMux(kCLOCK_PeriphMux, 0);
        }

        /* Set SystemCoreClock variable. */
        SystemCoreClockUpdate();
    }
} // namespace bsp

A module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp => module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp +39 -0
@@ 0,0 1,39 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#ifndef PUREPHONE_CPUFREQLPM_HPP
#define PUREPHONE_CPUFREQLPM_HPP

#include <cstdint>

namespace bsp
{
    inline constexpr uint32_t VDDRun_900_mV  = 0x4;
    inline constexpr uint32_t VDDRun_1050_mV = 0xa;
    inline constexpr uint32_t VDDRun_1075_mV = 0xb;
    inline constexpr uint32_t VDDRun_1100_mV = 0xc;
    inline constexpr uint32_t VDDRun_1125_mV = 0xd;
    inline constexpr uint32_t VDDRun_1150_mV = 0xe;
    inline constexpr uint32_t VDDRun_1275_mV = 0x13;

    inline constexpr uint32_t VDDStandby_925_mV = 0x1;

    class CpuFreqLPM
    {
      public:
        enum class CpuClock
        {
            CpuClock_Osc_12_Mhz,
            CpuClock_Osc_24_Mhz,
            CpuClock_Pll2_66_Mhz,
            CpuClock_Pll2_132_Mhz,
            CpuClock_Pll2_264_Mhz,
            CpuClock_Pll2_528_Mhz
        };

        CpuFreqLPM();
        void SetCpuFrequency(CpuClock freq);
    };
} // namespace bsp

#endif // PUREPHONE_CPUFREQLPM_HPP

M module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp +27 -0
@@ 24,6 24,8 @@ namespace bsp
                                          .pin = static_cast<uint32_t>(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON)});

        gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON), 1);

        CpuFreq = std::make_unique<CpuFreqLPM>();
    }

    int32_t RT1051LPM::Switch(const bsp::LowPowerMode::Mode mode)


@@ 78,4 80,29 @@ namespace bsp
    {
        return 0;
    }

    void RT1051LPM::SetCpuFrequency(bsp::LowPowerMode::CpuFrequency freq)
    {
        switch (freq) {
        case bsp::LowPowerMode::CpuFrequency::Level_1:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_12_Mhz);
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_2:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_24_Mhz);
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_3:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_66_Mhz);
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_4:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_132_Mhz);
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_5:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_264_Mhz);
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_6:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_528_Mhz);
            break;
        }
        LOG_INFO("CPU frequency changed to %lu", CLOCK_GetFreq(kCLOCK_CpuClk));
    }
} // namespace bsp

M module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp +3 -0
@@ 6,6 6,7 @@

#include "bsp/lpm/bsp_lpm.hpp"
#include "drivers/gpio/DriverGPIO.hpp"
#include "CpuFreqLPM.hpp"

namespace bsp
{


@@ 17,6 18,7 @@ namespace bsp
        int32_t Switch(const Mode mode) override final;
        int32_t PowerOff() override final;
        int32_t Reboot() override final;
        void SetCpuFrequency(CpuFrequency freq) final;

      private:
        int32_t EnterLowPowerRun();


@@ 25,6 27,7 @@ namespace bsp
        int32_t EnterSuspend();

        std::shared_ptr<drivers::DriverGPIO> gpio;
        std::unique_ptr<bsp::CpuFreqLPM> CpuFreq;
    };

} // namespace bsp

M module-bsp/bsp/lpm/bsp_lpm.hpp => module-bsp/bsp/lpm/bsp_lpm.hpp +11 -1
@@ 18,6 18,16 @@ namespace bsp {
            Suspend

        };
        enum class CpuFrequency
        {
            Level_1, // 12 MHz
            Level_2, // 24 MHz
            Level_3, // 66 MHz
            Level_4, // 132 MHz
            Level_5, // 264 MHz
            Level_6  // 528 MHz
        };

        LowPowerMode()          = default;
        virtual ~LowPowerMode() = default;



@@ 28,7 38,7 @@ namespace bsp {

        virtual int32_t PowerOff() = 0;
        virtual int32_t Reboot() = 0;

        virtual void SetCpuFrequency(CpuFrequency freq) = 0;

    protected:
      Mode currentMode = Mode::FullSpeed;

M module-bsp/targets/Target_RT1051.cmake => module-bsp/targets/Target_RT1051.cmake +1 -0
@@ 51,6 51,7 @@ set(BOARD_SOURCES ${BOARD_SOURCES}
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/vibrator/vibrator.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/watchdog/watchdog.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/lpm/RT1051LPM.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/lpm/CpuFreqLPM.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bluetooth/BluetoothCommon.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bluetooth/BlueKitchen.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/rtc/rtc.cpp"

M module-sys/SystemManager/PowerManager.cpp => module-sys/SystemManager/PowerManager.cpp +5 -0
@@ 49,4 49,9 @@ namespace sys
        return lowPowerControl->Reboot();
    }

    void PowerManager::SetCpuFrequency(const bsp::LowPowerMode::CpuFrequency freq)
    {
        lowPowerControl->SetCpuFrequency(freq);
    }

} // namespace sys

M module-sys/SystemManager/PowerManager.hpp => module-sys/SystemManager/PowerManager.hpp +2 -0
@@ 31,6 31,8 @@ namespace sys
        int32_t PowerOff();
        int32_t Reboot();

        void SetCpuFrequency(const bsp::LowPowerMode::CpuFrequency freq);

        Mode GetCurrentMode()
        {
            return currentPowerMode;