diff --git a/Source/sys-clk/common/include/sysclk/board.h b/Source/sys-clk/common/include/sysclk/board.h index 16b709c9..cda69da7 100644 --- a/Source/sys-clk/common/include/sysclk/board.h +++ b/Source/sys-clk/common/include/sysclk/board.h @@ -140,6 +140,13 @@ enum { DVFSMode_EnumMax, }; +typedef enum { + GpuSchedulingMode_DoNotOverride = 0, + GpuSchedulingMode_Enabled, + GpuSchedulingMode_Disabled, + GpuSchedulingMode_EnumMax, +} GpuSchedulingMode; + #define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax) static inline const char* sysclkFormatModule(SysClkModule module, bool pretty) diff --git a/Source/sys-clk/common/include/sysclk/config.h b/Source/sys-clk/common/include/sysclk/config.h index fdc1f739..342e048a 100644 --- a/Source/sys-clk/common/include/sysclk/config.h +++ b/Source/sys-clk/common/include/sysclk/config.h @@ -59,6 +59,8 @@ typedef enum { HorizonOCConfigValue_DVFSMode, HorizonOCConfigValue_DVFSOffset, + HorizonOCConfigValue_GPUScheduling, + KipConfigValue_custRev, // KipConfigValue_mtcConf, KipConfigValue_hpMode, @@ -226,6 +228,8 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr case HorizonOCConfigValue_DVFSOffset: return pretty ? "DVFS Offset" : "dvfs_offset"; + case HorizonOCConfigValue_GPUScheduling: + return pretty ? "GPU Scheduling" : "gpu_scheduling"; // KIP config values case KipConfigValue_custRev: return pretty ? "Custom Revision" : "kip_cust_rev"; @@ -399,6 +403,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val) case HorizonOCConfigValue_BatteryChargeCurrent: case HorizonOCConfigValue_OverwriteRefreshRate: case HorizonOCConfigValue_EnableUnsafeDisplayFreqs: + case HorizonOCConfigValue_GPUScheduling: return 0ULL; case HocClkConfigValue_EristaMaxCpuClock: return 1785ULL; @@ -541,6 +546,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in case KipCrc32: case HorizonOCConfigValue_DVFSMode: case HorizonOCConfigValue_DVFSOffset: + case HorizonOCConfigValue_GPUScheduling: return true; case HorizonOCConfigValue_BatteryChargeCurrent: return ((input >= 1024) && (input <= 3072)) || !input; 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 711b2c92..a0e1c6e8 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -394,8 +394,30 @@ void MiscGui::listUI() // NamedValue("2816mA", 2816), // NamedValue("3072mA", 3072), // }; + this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); + + 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 + ); if(!IsHoag()) { - this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); // std::vector chargerCurrents = { // NamedValue("Disabled", 0), // NamedValue("1024mA", 1024), diff --git a/Source/sys-clk/sysmodule/src/board.cpp b/Source/sys-clk/sysmodule/src/board.cpp index 1f5e1411..16d5a467 100644 --- a/Source/sys-clk/sysmodule/src/board.cpp +++ b/Source/sys-clk/sysmodule/src/board.cpp @@ -65,11 +65,14 @@ #define HOSSVC_HAS_CLKRST (hosversionAtLeast(8,0,0)) #define HOSSVC_HAS_TC (hosversionAtLeast(5,0,0)) #define NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD 0x80044715 +#define NVSCHED_CTRL_ENABLE 0x00000601 +#define NVSCHED_CTRL_DISABLE 0x00000602 constexpr u64 CpuTimeOutNs = 500'000'000; constexpr double Systemtickfrequency = 19200000.0 * (static_cast(CpuTimeOutNs) / 1'000'000'000.0); - +Result nvInitialize_rc; Result nvCheck = 1; +Result nvCheck_sched = 1; LEvent threadexit; Thread gpuLThread; @@ -86,7 +89,7 @@ Result pwmDutyCycleCheck = 1; double Rotation_Duty = 0; u8 fanLevel; -uint32_t GPU_Load_u = 0, fd = 0; +uint32_t GPU_Load_u = 0, fd = 0, fd2 = 0; BatteryChargeInfo info; static SysClkSocType g_socType = SysClkSocType_Erista; @@ -238,8 +241,11 @@ void Board::Initialize() rc = tmp451Initialize(); ASSERT_RESULT_OK(rc, "tmp451Initialize"); - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); + nvInitialize_rc = nvInitialize(); + if (R_SUCCEEDED(nvInitialize_rc)) { + nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); + nvCheck_sched = nvOpen(&fd2, "/dev/nvsched-ctrl"); + } rc = rgltrInitialize(); ASSERT_RESULT_OK(rc, "rgltrInitialize"); @@ -402,6 +408,7 @@ void Board::Exit() rgltrExit(); batteryInfoExit(); pmdmntExit(); + nvExit(); if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag) DisplayRefresh_Shutdown(); } @@ -1142,3 +1149,22 @@ bool Board::IsDram8GB() { } else return args.X[1] == 0x00002000 ? true : false; } + +void Board::SetGpuSchedulingMode(GpuSchedulingMode mode) { + if (nvCheck_sched == 1) { + return; + } + u32 temp; + switch(mode) { + case GpuSchedulingMode_DoNotOverride: + return; + case GpuSchedulingMode_Disabled: + nvIoctl(fd2, NVSCHED_CTRL_DISABLE, &temp); + break; + case GpuSchedulingMode_Enabled: + nvIoctl(fd2, NVSCHED_CTRL_ENABLE, &temp); + break; + default: + ASSERT_ENUM_VALID(GpuSchedulingMode, mode); + } +} \ No newline at end of file diff --git a/Source/sys-clk/sysmodule/src/board.h b/Source/sys-clk/sysmodule/src/board.h index 5f515797..9e3f5b2f 100644 --- a/Source/sys-clk/sysmodule/src/board.h +++ b/Source/sys-clk/sysmodule/src/board.h @@ -64,6 +64,7 @@ class Board static u8 GetFanRotationLevel(); static u8 GetDramID(); static bool IsDram8GB(); + static void SetGpuSchedulingMode(GpuSchedulingMode mode); protected: static void FetchHardwareInfos(); static PcvModule GetPcvModule(SysClkModule sysclkModule); diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index 3711f3a9..b4a60783 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -112,6 +112,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)); } ClockManager::~ClockManager()