diff --git a/Source/sys-clk/common/include/sysclk/board.h b/Source/sys-clk/common/include/sysclk/board.h index 7741ecfa..e4acaf10 100644 --- a/Source/sys-clk/common/include/sysclk/board.h +++ b/Source/sys-clk/common/include/sysclk/board.h @@ -30,7 +30,7 @@ #include #include #include - +#include typedef enum { SysClkSocType_Erista = 0, @@ -142,19 +142,12 @@ typedef enum { GpuSchedulingOverrideMethod_NvService, GpuSchedulingOverrideMethod_EnumMax, } GpuSchedulingOverrideMethod; - typedef enum { - GovernorState_DoNotOverride = 0, - GovernorState_Disabled, - GovernorState_Enabled_CpuGpuVrr, - GovernorState_Enabled_CpuVrr, - GovernorState_Enabled_GpuVrr, - GovernorState_Enabled_CpuGpu, - GovernorState_Enabled_Cpu, - GovernorState_Enabled_Gpu, - GovernorState_Enabled_Vrr, - GovernorState_EnumMax, -} GovernorState; + ComponentGovernor_DoNotOverride = 0, + ComponentGovernor_Enabled = 1, + ComponentGovernor_Disabled = 2, + ComponentGovernor_EnumMax, +} ComponentGovernorState; typedef enum { RamDisplayMode_VDD2VDDQ = 0, RamDisplayMode_VDD2Usage, @@ -164,6 +157,25 @@ typedef enum { #define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax) +// Packed u32 +// Bits 0-7 - CPU +// Bits 8-15 - GPU +// Bits 16-23 - VRR +// Bits 24-32 - unused + +inline u32 GovernorStatePack(u8 cpu, u8 gpu, u8 vrr) { + return (u32)cpu | ((u32)gpu << 8) | ((u32)vrr << 16); +} +inline u8 GovernorStateCpu(u32 p) { + return (u8)(p & 0xFF); +} +inline u8 GovernorStateGpu(u32 p) { + return (u8)((p >> 8) & 0xFF); +} +inline u8 GovernorStateVrr(u32 p) { + return (u8)((p >> 16) & 0xFF); +} + static inline const char* sysclkFormatModule(SysClkModule module, bool pretty) { switch(module) @@ -177,7 +189,7 @@ static inline const char* sysclkFormatModule(SysClkModule module, bool pretty) case HorizonOCModule_Display: return pretty ? "Display" : "display"; case HorizonOCModule_Governor: - return pretty ? "Governor" : "gov"; + return pretty ? "Governor" : "governor"; default: return "null"; } diff --git a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp index 0ee58361..e0f7ef45 100644 --- a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp @@ -277,6 +277,56 @@ void AppProfileGui::addModuleListItemValue( this->listElement->addItem(listItem); } +class GovernorProfileSubMenuGui : public BaseMenuGui { + uint64_t applicationId; + SysClkTitleProfileList* profileList; + SysClkProfile profile; +public: + GovernorProfileSubMenuGui(uint64_t appId, SysClkTitleProfileList* pList, SysClkProfile prof) + : applicationId(appId), profileList(pList), profile(prof) {} + + void listUI() override { + this->listElement->addItem(new tsl::elm::CategoryHeader("Governor")); + + static constexpr struct { const char* label; int shift; } kAll[] = { + {"CPU", 0}, {"GPU", 8}, {"VRR", 16} + }; + int count = IsHoag() ? 2 : 3; + + for (int i = 0; i < count; i++) { + u8 cur = (this->profileList->mhzMap[this->profile][HorizonOCModule_Governor] >> kAll[i].shift) & 0xFF; + auto* bar = new tsl::elm::NamedStepTrackBar( + "", {"Do Not Override", "Enabled", "Disabled"}, + true, kAll[i].label + ); + bar->setProgress(cur); + int shift = kAll[i].shift; + bar->setValueChangedListener([this, shift](u8 value) { + u32& packed = this->profileList->mhzMap[this->profile][HorizonOCModule_Governor]; + packed = (packed & ~(0xFFu << shift)) | ((u32)value << shift); + Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList); + if (R_FAILED(rc)) FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc); + }); + this->listElement->addItem(bar); + } + } +}; + +void AppProfileGui::addGovernorSection(SysClkProfile profile) { + auto* item = new tsl::elm::ListItem("Governor"); + item->setValue("\u2192"); // Right arrow + item->setClickListener([this, profile](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo( + this->applicationId, this->profileList, profile + ); + return true; + } + return false; + }); + this->listElement->addItem(item); +} + void AppProfileGui::addProfileUI(SysClkProfile profile) { BaseMenuGui::refresh(); @@ -367,27 +417,7 @@ void AppProfileGui::addProfileUI(SysClkProfile profile) } } #endif - std::vector governorSettingsE = { - NamedValue("Do Not Override", GovernorState_DoNotOverride), - NamedValue("Disabled", GovernorState_Disabled), - NamedValue("CPU + GPU + VRR", GovernorState_Enabled_CpuGpuVrr), - NamedValue("CPU + VRR", GovernorState_Enabled_CpuVrr), - NamedValue("GPU + VRR", GovernorState_Enabled_GpuVrr), - NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu), - NamedValue("CPU", GovernorState_Enabled_Cpu), - NamedValue("GPU", GovernorState_Enabled_Gpu), - NamedValue("VRR", GovernorState_Enabled_Vrr), - }; - - std::vector governorSettingsH = { - NamedValue("Do Not Override", GovernorState_DoNotOverride), - NamedValue("Disabled", GovernorState_Disabled), - NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu), - NamedValue("CPU", GovernorState_Enabled_Cpu), - NamedValue("GPU", GovernorState_Enabled_Gpu), - }; - - this->addModuleListItemValue(profile, HorizonOCModule_Governor, "Governor", 0, 0, 1, "", 1, 0, ValueThresholds(), IsHoag() ? governorSettingsH : governorSettingsE, false); + this->addGovernorSection(profile); } void AppProfileGui::listUI() diff --git a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h index 4981cb72..e261282f 100644 --- a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h @@ -70,6 +70,7 @@ class AppProfileGui : public BaseMenuGui std::vector namedValues = {}, bool showDefaultValue = true ); + void addGovernorSection(SysClkProfile profile); void addProfileUI(SysClkProfile profile); public: AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList); diff --git a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp index f694bb79..b0f56e79 100644 --- a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp @@ -15,11 +15,13 @@ * along with this program. If not, see . * */ + #include "../format.h" #include "fatal_gui.h" #include "global_override_gui.h" #include "value_choice_gui.h" #include "labels.h" + GlobalOverrideGui::GlobalOverrideGui() { for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) { @@ -291,25 +293,51 @@ void GlobalOverrideGui::addModuleToggleItem(SysClkModule module) this->listItems[module] = toggle; } -std::vector governorSettingsE = { - NamedValue("Do Not Override", GovernorState_DoNotOverride), - NamedValue("Disabled", GovernorState_Disabled), - NamedValue("CPU + GPU + VRR", GovernorState_Enabled_CpuGpuVrr), - NamedValue("CPU + VRR", GovernorState_Enabled_CpuVrr), - NamedValue("GPU + VRR", GovernorState_Enabled_GpuVrr), - NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu), - NamedValue("CPU", GovernorState_Enabled_Cpu), - NamedValue("GPU", GovernorState_Enabled_Gpu), - NamedValue("VRR", GovernorState_Enabled_Vrr), +class GovernorOverrideSubMenuGui : public BaseMenuGui { + u32 packed; +public: + GovernorOverrideSubMenuGui(u32 initialPacked) : packed(initialPacked) {} + + void listUI() override { + this->listElement->addItem(new tsl::elm::CategoryHeader("Governor")); + + static constexpr struct { const char* label; int shift; } kAll[] = { + {"CPU", 0}, {"GPU", 8}, {"VRR", 16} + }; + int count = IsHoag() ? 2 : 3; + + for (int i = 0; i < count; i++) { + u8 cur = (this->packed >> kAll[i].shift) & 0xFF; + auto* bar = new tsl::elm::NamedStepTrackBar( + "", {"Do Not Override", "Enabled", "Disabled"}, + true, kAll[i].label + ); + bar->setProgress(cur); + int shift = kAll[i].shift; + bar->setValueChangedListener([this, shift](u8 value) { + this->packed = (this->packed & ~(0xFFu << shift)) | ((u32)value << shift); + Result rc = sysclkIpcSetOverride(HorizonOCModule_Governor, this->packed); + if (R_FAILED(rc)) FatalGui::openWithResultCode("sysclkIpcSetOverride", rc); + this->lastContextUpdate = armGetSystemTick(); + }); + this->listElement->addItem(bar); + } + } }; -std::vector governorSettingsH = { - NamedValue("Do Not Override", GovernorState_DoNotOverride), - NamedValue("Disabled", GovernorState_Disabled), - NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu), - NamedValue("CPU", GovernorState_Enabled_Cpu), - NamedValue("GPU", GovernorState_Enabled_Gpu), -}; +void GlobalOverrideGui::addGovernorSection() { + auto* item = new tsl::elm::ListItem("Governor"); + item->setValue("\u2192"); // right arrow + item->setClickListener([this](u64 keys) { + if (keys & HidNpadButton_A) { + u32 packed = this->context ? this->context->overrideFreqs[HorizonOCModule_Governor] : 0; + tsl::changeTo(packed); + return true; + } + return false; + }); + this->listElement->addItem(item); +} void GlobalOverrideGui::listUI() { @@ -330,7 +358,7 @@ void GlobalOverrideGui::listUI() this->addModuleListItemValue(HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds); #endif - this->addModuleListItemValue(HorizonOCModule_Governor, "Governor", 0, 0, 1, "", 1, 0, ValueThresholds(), IsHoag() ? governorSettingsH : governorSettingsE, false); + this->addGovernorSection(); } void GlobalOverrideGui::refresh() @@ -342,23 +370,7 @@ void GlobalOverrideGui::refresh() for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) { if (m == HorizonOCModule_Governor) { - if (this->listItems[m] != nullptr && - this->listHz[m] != this->context->overrideFreqs[m]) { - - std::string displayText = FREQ_DEFAULT_TEXT; - std::uint32_t currentValue = this->context->overrideFreqs[m]; - - - for (const auto& setting : governorSettingsE) { - if (setting.value == currentValue) { - displayText = setting.name; - break; - } - } - - this->listItems[m]->setValue(displayText); - this->listHz[m] = currentValue; - } + this->listHz[m] = this->context->overrideFreqs[m]; continue; } diff --git a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h index 3c198851..9e5d6db9 100644 --- a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h @@ -36,8 +36,8 @@ class GlobalOverrideGui : public BaseMenuGui std::map> customFormatModules; tsl::elm::ListItem* listItems[SysClkModule_EnumMax]; std::uint32_t listHz[SysClkModule_EnumMax]; - bool isGovernorEnabled; void openFreqChoiceGui(SysClkModule module); + void addGovernorSection(); void addModuleListItem(SysClkModule module); void addModuleToggleItem(SysClkModule module); void openValueChoiceGui( diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp index c18c1ab5..7bf149d7 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -30,6 +30,7 @@ #define A_BTN "\ue0e0" #define R_ARROW "\u2192" + class GeneralSettingsSubMenuGui; class GovernorSettingsSubMenuGui; class DisplaySubMenuGui; diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index 502da48c..b3e16b1b 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -566,18 +566,6 @@ void ClockManager::VRRThread(void* arg) { } -GovernorState ClockManager::GetEffectiveGovernorState(GovernorState appState, GovernorState tempState) -{ - if (tempState == GovernorState_Disabled) - { - return GovernorState_Disabled; - } - if (tempState != GovernorState_DoNotOverride) - { - return tempState; - } - return appState; -} void ClockManager::HandleSafetyFeatures() { AppletOperationMode opMode = appletGetOperationMode(); @@ -608,37 +596,32 @@ void ClockManager::HandleMiscFeatures() { } void ClockManager::HandleGovernor(uint32_t targetHz) { - GovernorState appGovernorState = (GovernorState)targetHz; - u32 tempTargetHz = this->context->overrideFreqs[HorizonOCModule_Governor]; if (!tempTargetHz) { tempTargetHz = this->config->GetAutoClockHz(this->context->applicationId, HorizonOCModule_Governor, this->context->profile, true); - if(!tempTargetHz) + if (!tempTargetHz) tempTargetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, HorizonOCModule_Governor, this->context->profile, true); } - GovernorState tempGovernorState = (GovernorState)tempTargetHz; - GovernorState effectiveState = this->GetEffectiveGovernorState(appGovernorState, tempGovernorState); + auto resolve = [](u8 app, u8 temp) -> u8 { + if (temp == ComponentGovernor_Disabled) return ComponentGovernor_Disabled; + if (temp != ComponentGovernor_DoNotOverride) return temp; + return app; + }; - bool newCpuGovernorState = (effectiveState == GovernorState_Enabled_CpuGpuVrr || - effectiveState == GovernorState_Enabled_CpuVrr || - effectiveState == GovernorState_Enabled_CpuGpu || - effectiveState == GovernorState_Enabled_Cpu); + u8 effectiveCpu = resolve(GovernorStateCpu(targetHz), GovernorStateCpu(tempTargetHz)); + u8 effectiveGpu = resolve(GovernorStateGpu(targetHz), GovernorStateGpu(tempTargetHz)); + u8 effectiveVrr = resolve(GovernorStateVrr(targetHz), GovernorStateVrr(tempTargetHz)); - bool newGpuGovernorState = (effectiveState == GovernorState_Enabled_CpuGpuVrr || - effectiveState == GovernorState_Enabled_GpuVrr || - effectiveState == GovernorState_Enabled_CpuGpu || - effectiveState == GovernorState_Enabled_Gpu); - - bool newVrrGovernorState = (effectiveState == GovernorState_Enabled_CpuGpuVrr || - effectiveState == GovernorState_Enabled_CpuVrr || - effectiveState == GovernorState_Enabled_GpuVrr || - effectiveState == GovernorState_Enabled_Vrr); + bool newCpuGovernorState = (effectiveCpu == ComponentGovernor_Enabled); + bool newGpuGovernorState = (effectiveGpu == ComponentGovernor_Enabled); + bool newVrrGovernorState = (effectiveVrr == ComponentGovernor_Enabled); isCpuGovernorEnabled = newCpuGovernorState; isGpuGovernorEnabled = newGpuGovernorState; isVRREnabled = newVrrGovernorState; + if(newCpuGovernorState == false && lastCpuGovernorState == true) { svcSleepThread(50'000'000); // thread syncing. probably a cleaner way to do this but hey, it works! Board::ResetToStockCpu(); diff --git a/Source/sys-clk/sysmodule/src/clock_manager.h b/Source/sys-clk/sysmodule/src/clock_manager.h index c287db17..b09d10e1 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.h +++ b/Source/sys-clk/sysmodule/src/clock_manager.h @@ -192,14 +192,6 @@ class ClockManager */ static void VRRThread(void* arg); - /** - * Gets the effective governor state from application/temporary override - * - * @param appState Governor state from app - * @param tempState Governor state from temporary override - */ - GovernorState GetEffectiveGovernorState(GovernorState appState, GovernorState tempState); - /** * Frequency table *