diff --git a/Source/sys-clk/common/include/sysclk/board.h b/Source/sys-clk/common/include/sysclk/board.h index c4175041..1fb55b8e 100644 --- a/Source/sys-clk/common/include/sysclk/board.h +++ b/Source/sys-clk/common/include/sysclk/board.h @@ -137,6 +137,12 @@ typedef enum { GpuSchedulingMode_EnumMax, } GpuSchedulingMode; +typedef enum { + GpuSchedulingOverrideMethod_Ini = 0, + GpuSchedulingOverrideMethod_NvService, + GpuSchedulingOverrideMethod_EnumMax, +} GpuSchedulingOverrideMethod; + typedef enum { GovernorState_DoNotOverride = 0, GovernorState_Disabled, diff --git a/Source/sys-clk/common/include/sysclk/config.h b/Source/sys-clk/common/include/sysclk/config.h index c0aba13e..3351df41 100644 --- a/Source/sys-clk/common/include/sysclk/config.h +++ b/Source/sys-clk/common/include/sysclk/config.h @@ -62,7 +62,7 @@ typedef enum { HorizonOCConfigValue_EnableExperimentalSettings, HorizonOCConfigValue_GPUScheduling, - + HorizonOCConfigValue_GPUSchedulingMethod, KipConfigValue_custRev, // KipConfigValue_mtcConf, KipConfigValue_hpMode, @@ -235,6 +235,9 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr case HorizonOCConfigValue_GPUScheduling: return pretty ? "GPU Scheduling" : "gpu_scheduling"; + case HorizonOCConfigValue_GPUSchedulingMethod: + return pretty ? "GPU Scheduling Method" : "gpu_sched_method"; + case HorizonOCConfigValue_LiveCpuUv: return pretty ? "Live CPU Undervolt" : "live_cpu_uv"; @@ -420,6 +423,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val) case HorizonOCConfigValue_EnableUnsafeDisplayFreqs: case HorizonOCConfigValue_GPUScheduling: case HorizonOCConfigValue_LiveCpuUv: + case HorizonOCConfigValue_GPUSchedulingMethod: return 0ULL; case HocClkConfigValue_EristaMaxCpuClock: return 1785ULL; @@ -468,6 +472,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in case HocClkConfigValue_IsFirstLoad: case HorizonOCConfigValue_EnableExperimentalSettings: case HorizonOCConfigValue_LiveCpuUv: + case HorizonOCConfigValue_GPUSchedulingMethod: return (input & 0x1) == input; case KipConfigValue_custRev: 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 67466b82..0ec1c7a1 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -251,7 +251,27 @@ void MiscGui::listUI() this->listElement->addItem(new tsl::elm::CategoryHeader("Settings")); addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr); - + std::vector gpuSchedValues = { + NamedValue("Do not override", GpuSchedulingMode_DoNotOverride), + NamedValue("Enabled", GpuSchedulingMode_Enabled, "96.5% limit"), + NamedValue("Disabled", GpuSchedulingMode_Disabled, "99.7% limit"), + }; + tsl::elm::CustomDrawer* gpuSchedInfoText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { + renderer->drawString("\uE150 This option requires a reboot", false, x + 20, y + 30, 18, tsl::style::color::ColorText); + renderer->drawString("to take effect", false, x + 20, y + 50, 18, tsl::style::color::ColorText); + }); + gpuSchedInfoText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70); + this->listElement->addItem(gpuSchedInfoText); + addConfigButton( + HorizonOCConfigValue_GPUScheduling, + "GPU Scheduling Override", + ValueRange(0, 0, 1, "", 0), + "GPU Scheduling Override", + &thresholdsDisabled, + {}, + gpuSchedValues, + false + ); this->listElement->addItem(new tsl::elm::CategoryHeader("Safety Settings")); addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr); @@ -411,25 +431,18 @@ void MiscGui::listUI() this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); addConfigToggle(HorizonOCConfigValue_LiveCpuUv, nullptr); - std::vector gpuSchedValues = { - NamedValue("Do not override", GpuSchedulingMode_DoNotOverride), - NamedValue("Enabled", GpuSchedulingMode_Enabled, "96.5% limit"), - NamedValue("Disabled", GpuSchedulingMode_Disabled, "99.7% limit"), + std::vector gpuSchedMethodValues = { + NamedValue("INI", GpuSchedulingOverrideMethod_Ini), + NamedValue("NV Service", GpuSchedulingOverrideMethod_NvService), }; - tsl::elm::CustomDrawer* gpuSchedInfoText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { - renderer->drawString("\uE150 This option requires a reboot", false, x + 20, y + 30, 18, tsl::style::color::ColorText); - renderer->drawString("to take effect", false, x + 20, y + 50, 18, tsl::style::color::ColorText); - }); - gpuSchedInfoText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70); - this->listElement->addItem(gpuSchedInfoText); addConfigButton( - HorizonOCConfigValue_GPUScheduling, - "GPU Scheduling Override", + HorizonOCConfigValue_GPUSchedulingMethod, + "GPU Scheduling Override Method", ValueRange(0, 0, 1, "", 0), - "GPU Scheduling Override", + "GPU Scheduling Override Method", &thresholdsDisabled, {}, - gpuSchedValues, + gpuSchedMethodValues, false ); tsl::elm::CustomDrawer* chargeWarningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { diff --git a/Source/sys-clk/sysmodule/src/board.cpp b/Source/sys-clk/sysmodule/src/board.cpp index 650c4c39..a94dd529 100644 --- a/Source/sys-clk/sysmodule/src/board.cpp +++ b/Source/sys-clk/sysmodule/src/board.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #define MAX(A, B) std::max(A, B) #define MIN(A, B) std::min(A, B) @@ -1159,25 +1160,48 @@ bool Board::IsDram8GB() { return args.X[1] == 0x00002000 ? true : false; } -void Board::SetGpuSchedulingMode(GpuSchedulingMode mode) { - if (nvCheck_sched == 1) { +void Board::SetGpuSchedulingMode(GpuSchedulingMode mode, GpuSchedulingOverrideMethod method) { + if (nvCheck_sched == 1 && method == GpuSchedulingOverrideMethod_NvService) { return; } u32 temp; + bool enabled = false; switch(mode) { case GpuSchedulingMode_DoNotOverride: + if (method == GpuSchedulingOverrideMethod_Ini) { + const char* ini_path = "sdmc:/atmosphere/config/system_settings.ini"; + const char* section = "am.gpu"; + const char* key = "gpu_scheduling_enabled"; + + // Remove the key from the INI + ini_puts(section, key, NULL, ini_path); + } return; case GpuSchedulingMode_Disabled: - nvIoctl(fd2, NVSCHED_CTRL_DISABLE, &temp); + if(method == GpuSchedulingOverrideMethod_NvService) + nvIoctl(fd2, NVSCHED_CTRL_DISABLE, &temp); + else + enabled = false; break; case GpuSchedulingMode_Enabled: - nvIoctl(fd2, NVSCHED_CTRL_ENABLE, &temp); + if(method == GpuSchedulingOverrideMethod_NvService) + nvIoctl(fd2, NVSCHED_CTRL_ENABLE, &temp); + else + enabled = true; break; default: ASSERT_ENUM_VALID(GpuSchedulingMode, mode); } -} + if(method == GpuSchedulingOverrideMethod_Ini) { + const char* ini_path = "sdmc:/atmosphere/config/system_settings.ini"; + const char* section = "am.gpu"; + const char* key = "gpu_scheduling_enabled"; + + const char* value = enabled ? "u8!0x1" : "u8!0x0"; + ini_puts(section, key, value, ini_path); + } +} void Board::SetDisplayRefreshDockedState(bool docked) { if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag) { DisplayRefresh_SetDockedState(docked); diff --git a/Source/sys-clk/sysmodule/src/board.h b/Source/sys-clk/sysmodule/src/board.h index 4b7a28c3..4aaaaf44 100644 --- a/Source/sys-clk/sysmodule/src/board.h +++ b/Source/sys-clk/sysmodule/src/board.h @@ -64,7 +64,7 @@ class Board static u8 GetFanRotationLevel(); static u8 GetDramID(); static bool IsDram8GB(); - static void SetGpuSchedulingMode(GpuSchedulingMode mode); + static void SetGpuSchedulingMode(GpuSchedulingMode mode, GpuSchedulingOverrideMethod method); static void SetDisplayRefreshDockedState(bool docked); static void SetCpuUvLevel(u32 levelLow, u32 levelHigh, u32 tbreakPoint); static u32 CalculateTbreak(u32 table); diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index 313499fa..a9324848 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -128,7 +128,7 @@ ClockManager::ClockManager() this->context->dramID = Board::GetDramID(); this->context->isDram8GB = Board::IsDram8GB(); previousRamHz = Board::GetHz(SysClkModule_MEM); - Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling)); + Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling), (GpuSchedulingOverrideMethod)this->config->GetConfigValue(HorizonOCConfigValue_GPUSchedulingMethod)); this->context->gpuSchedulingMode = (GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling); this->context->isSysDockInstalled = this->sysDockIntegration->getCurrentSysDockState(); } @@ -683,6 +683,9 @@ void ClockManager::Tick() if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) { I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)); } + if((GpuSchedulingOverrideMethod)this->config->GetConfigValue(HorizonOCConfigValue_GPUSchedulingMethod) == GpuSchedulingOverrideMethod_Ini) + Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling), (GpuSchedulingOverrideMethod)this->config->GetConfigValue(HorizonOCConfigValue_GPUSchedulingMethod)); + std::uint32_t targetHz = 0; std::uint32_t maxHz = 0; std::uint32_t nearestHz = 0;