hocclk: significantly reduce memory usage
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
"title_id": "0x00FF0000636C6BFF",
|
"title_id": "0x00FF0000636C6BFF",
|
||||||
"title_id_range_min": "0x00FF0000636C6BFF",
|
"title_id_range_min": "0x00FF0000636C6BFF",
|
||||||
"title_id_range_max": "0x00FF0000636C6BFF",
|
"title_id_range_max": "0x00FF0000636C6BFF",
|
||||||
"main_thread_stack_size": "0x0000F000",
|
"main_thread_stack_size": "0x0000B000",
|
||||||
"main_thread_priority": 16,
|
"main_thread_priority": 16,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 1,
|
"process_category": 1,
|
||||||
|
|||||||
@@ -292,8 +292,23 @@ namespace clockManager {
|
|||||||
{
|
{
|
||||||
if (board::GetSocType() == HocClkSocType_Mariko && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) {
|
if (board::GetSocType() == HocClkSocType_Mariko && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) {
|
||||||
board::PcvHijackGpuVolts(0); // Reset to vMin
|
board::PcvHijackGpuVolts(0); // Reset to vMin
|
||||||
|
|
||||||
|
u32 targetHz = gContext.overrideFreqs[HocClkModule_GPU];
|
||||||
|
if (!targetHz) {
|
||||||
|
targetHz = config::GetAutoClockHz(gContext.applicationId, HocClkModule_GPU, gContext.profile, false);
|
||||||
|
if (!targetHz) {
|
||||||
|
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_GPU, gContext.profile, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u32 maxHz = GetMaxAllowedHz(HocClkModule_GPU, gContext.profile);
|
||||||
|
u32 nearestHz = GetNearestHz(HocClkModule_GPU, targetHz, maxHz);
|
||||||
|
|
||||||
board::SetHz(HocClkModule_GPU, ~0);
|
board::SetHz(HocClkModule_GPU, ~0);
|
||||||
board::ResetToStockGpu();
|
if (targetHz) {
|
||||||
|
board::SetHz(HocClkModule_GPU, nearestHz);
|
||||||
|
} else {
|
||||||
|
board::ResetToStockGpu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +460,11 @@ namespace clockManager {
|
|||||||
// restore clocks to stock values on app or profile change
|
// restore clocks to stock values on app or profile change
|
||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
board::ResetToStock();
|
board::ResetToStock();
|
||||||
DVFSReset();
|
if (board::GetSocType() == HocClkSocType_Mariko && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) {
|
||||||
|
board::PcvHijackGpuVolts(0);
|
||||||
|
board::SetHz(HocClkModule_GPU, ~0);
|
||||||
|
board::ResetToStockGpu();
|
||||||
|
}
|
||||||
WaitForNextTick();
|
WaitForNextTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,9 @@ namespace governor {
|
|||||||
bool isCpuGovernorInBoostMode = false;
|
bool isCpuGovernorInBoostMode = false;
|
||||||
bool isVRREnabled = false;
|
bool isVRREnabled = false;
|
||||||
|
|
||||||
// thread handles
|
Thread governorTHREAD;
|
||||||
Thread cpuGovernorTHREAD;
|
|
||||||
Thread gpuGovernorTHREAD;
|
|
||||||
Thread vrrTHREAD;
|
|
||||||
|
|
||||||
void HandleGovernor(uint32_t targetHz)
|
void HandleGovernor(uint32_t targetHz) {
|
||||||
{
|
|
||||||
u32 tempTargetHz = clockManager::gContext.overrideFreqs[HocClkModule_Governor];
|
u32 tempTargetHz = clockManager::gContext.overrideFreqs[HocClkModule_Governor];
|
||||||
if (!tempTargetHz) {
|
if (!tempTargetHz) {
|
||||||
tempTargetHz = config::GetAutoClockHz(clockManager::gContext.applicationId, HocClkModule_Governor, clockManager::gContext.profile, true);
|
tempTargetHz = config::GetAutoClockHz(clockManager::gContext.applicationId, HocClkModule_Governor, clockManager::gContext.profile, true);
|
||||||
@@ -65,18 +61,13 @@ namespace governor {
|
|||||||
isGpuGovernorEnabled = newGpuGovernorState;
|
isGpuGovernorEnabled = newGpuGovernorState;
|
||||||
isVRREnabled = newVrrGovernorState;
|
isVRREnabled = newVrrGovernorState;
|
||||||
|
|
||||||
if (newCpuGovernorState == false && lastCpuGovernorState == true) {
|
if (newCpuGovernorState == false && lastCpuGovernorState == true)
|
||||||
svcSleepThread(100'000'000); // thread syncing. probably a cleaner way to do this but hey, it works!
|
|
||||||
board::ResetToStockCpu();
|
board::ResetToStockCpu();
|
||||||
}
|
if (newGpuGovernorState == false && lastGpuGovernorState == true)
|
||||||
if (newGpuGovernorState == false && lastGpuGovernorState == true) {
|
|
||||||
svcSleepThread(100'000'000);
|
|
||||||
board::ResetToStockGpu();
|
board::ResetToStockGpu();
|
||||||
}
|
if (newVrrGovernorState == false && lastVrrGovernorState == true)
|
||||||
if (newVrrGovernorState == false && lastVrrGovernorState == true) {
|
|
||||||
svcSleepThread(100'000'000);
|
|
||||||
board::ResetToStockDisplay();
|
board::ResetToStockDisplay();
|
||||||
}
|
|
||||||
if (newCpuGovernorState != lastCpuGovernorState || newGpuGovernorState != lastGpuGovernorState || newVrrGovernorState != lastVrrGovernorState) {
|
if (newCpuGovernorState != lastCpuGovernorState || newGpuGovernorState != lastGpuGovernorState || newVrrGovernorState != lastVrrGovernorState) {
|
||||||
fileUtils::LogLine("[mgr] Governor state changed: CPU %s, GPU %s, VRR %s", newCpuGovernorState ? "enabled" : "disabled", newGpuGovernorState ? "enabled" : "disabled", newVrrGovernorState ? "enabled" : "disabled");
|
fileUtils::LogLine("[mgr] Governor state changed: CPU %s, GPU %s, VRR %s", newCpuGovernorState ? "enabled" : "disabled", newGpuGovernorState ? "enabled" : "disabled", newVrrGovernorState ? "enabled" : "disabled");
|
||||||
lastCpuGovernorState = newCpuGovernorState;
|
lastCpuGovernorState = newCpuGovernorState;
|
||||||
@@ -85,22 +76,19 @@ namespace governor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 SchedutilTargetHz(u32 util, u32 tableMaxHz)
|
u32 SchedutilTargetHz(u32 util, u32 tableMaxHz) {
|
||||||
{
|
|
||||||
u64 hz = (u64)tableMaxHz * util / STEP_UTIL;
|
u64 hz = (u64)tableMaxHz * util / STEP_UTIL;
|
||||||
return (u32)(std::min(hz, static_cast<u64>(tableMaxHz)));
|
return (u32)(std::min(hz, static_cast<u64>(tableMaxHz)));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 TableIndexForHz(const clockManager::FreqTable& table, u32 targetHz)
|
u32 TableIndexForHz(const clockManager::FreqTable& table, u32 targetHz) {
|
||||||
{
|
|
||||||
for (u32 i = 0; i < table.count; i++)
|
for (u32 i = 0; i < table.count; i++)
|
||||||
if (table.list[i] >= targetHz)
|
if (table.list[i] >= targetHz)
|
||||||
return i;
|
return i;
|
||||||
return table.count - 1;
|
return table.count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ResolveTargetHz(HocClkModule module)
|
u32 ResolveTargetHz(HocClkModule module) {
|
||||||
{
|
|
||||||
u32 hz = clockManager::gContext.overrideFreqs[module];
|
u32 hz = clockManager::gContext.overrideFreqs[module];
|
||||||
if (!hz)
|
if (!hz)
|
||||||
hz = config::GetAutoClockHz(
|
hz = config::GetAutoClockHz(
|
||||||
@@ -113,244 +101,184 @@ namespace governor {
|
|||||||
return hz;
|
return hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CpuGovernorThread(void* arg)
|
void GovernorThread(void* arg) {
|
||||||
{
|
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|
||||||
u32 downHoldRemaining = 0;
|
u32 cpuDownHoldRemaining = 0;
|
||||||
u32 lastHz = 0;
|
u32 cpuLastHz = 0;
|
||||||
|
u32 gpuDownHoldRemaining = 0;
|
||||||
|
u32 gpuLastHz = 0;
|
||||||
u32 minHz = 612;
|
u32 minHz = 612;
|
||||||
u32 tick = 0;
|
u32 cpuTick = 0;
|
||||||
|
u8 vrrTick = 0;
|
||||||
|
u8 vrrFocusTick = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!clockManager::gRunning || !isCpuGovernorEnabled) {
|
|
||||||
downHoldRemaining = 0;
|
if (!clockManager::gRunning) {
|
||||||
lastHz = 0;
|
cpuDownHoldRemaining = 0;
|
||||||
|
cpuLastHz = 0;
|
||||||
|
gpuDownHoldRemaining = 0;
|
||||||
|
gpuLastHz = 0;
|
||||||
svcSleepThread(POLL_NS);
|
svcSleepThread(POLL_NS);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 mode = 0;
|
if (isCpuGovernorEnabled) {
|
||||||
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
|
u32 mode = 0;
|
||||||
|
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc) && apmExtIsBoostMode(mode)) {
|
if (R_SUCCEEDED(rc) && apmExtIsBoostMode(mode)) {
|
||||||
isCpuGovernorInBoostMode = true;
|
isCpuGovernorInBoostMode = true;
|
||||||
downHoldRemaining = 0;
|
cpuDownHoldRemaining = 0;
|
||||||
lastHz = 0;
|
cpuLastHz = 0;
|
||||||
continue; // TODO: figure out a way to get boost clock easily and set it instead of just skipping the governor
|
} else {
|
||||||
} else if (!apmExtIsBoostMode(mode)) {
|
isCpuGovernorInBoostMode = false;
|
||||||
|
|
||||||
|
auto& table = clockManager::gFreqTable[HocClkModule_CPU];
|
||||||
|
std::scoped_lock lock{clockManager::gContextMutex};
|
||||||
|
|
||||||
|
u32 cpuLoad = board::GetPartLoad(HocClkPartLoad_CPUMax);
|
||||||
|
u32 tableMaxHz = table.list[table.count - 1];
|
||||||
|
u32 desiredHz = SchedutilTargetHz(cpuLoad, tableMaxHz);
|
||||||
|
u32 targetHz = ResolveTargetHz(HocClkModule_CPU);
|
||||||
|
u32 maxHz = clockManager::GetMaxAllowedHz(HocClkModule_CPU, clockManager::gContext.profile);
|
||||||
|
|
||||||
|
if (targetHz && desiredHz > targetHz)
|
||||||
|
desiredHz = targetHz;
|
||||||
|
if (maxHz && desiredHz > maxHz)
|
||||||
|
desiredHz = maxHz;
|
||||||
|
|
||||||
|
u32 newHz = table.list[TableIndexForHz(table, desiredHz)];
|
||||||
|
bool goingDown = (cpuLastHz != 0) && (newHz < cpuLastHz);
|
||||||
|
|
||||||
|
if (!goingDown)
|
||||||
|
cpuDownHoldRemaining = 0;
|
||||||
|
else if (cpuDownHoldRemaining == 0)
|
||||||
|
cpuDownHoldRemaining = DOWN_HOLD_TICKS;
|
||||||
|
|
||||||
|
if (cpuDownHoldRemaining > 0)
|
||||||
|
cpuDownHoldRemaining--;
|
||||||
|
|
||||||
|
if (++cpuTick > 50) {
|
||||||
|
minHz = config::GetConfigValue(HocClkConfigValue_CpuGovernorMinimumFreq);
|
||||||
|
cpuTick = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newHz < minHz)
|
||||||
|
newHz = minHz;
|
||||||
|
|
||||||
|
if ((!goingDown || (cpuDownHoldRemaining == 0)) && clockManager::IsAssignableHz(HocClkModule_CPU, newHz)) {
|
||||||
|
board::SetHz(HocClkModule_CPU, newHz);
|
||||||
|
clockManager::gContext.freqs[HocClkModule_CPU] = newHz;
|
||||||
|
cpuLastHz = newHz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
isCpuGovernorInBoostMode = false;
|
isCpuGovernorInBoostMode = false;
|
||||||
|
cpuDownHoldRemaining = 0;
|
||||||
|
cpuLastHz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& table = clockManager::gFreqTable[HocClkModule_CPU];
|
if (isGpuGovernorEnabled) {
|
||||||
|
auto& table = clockManager::gFreqTable[HocClkModule_GPU];
|
||||||
|
std::scoped_lock lock{clockManager::gContextMutex};
|
||||||
|
|
||||||
if (table.count == 0)
|
u32 gpuLoad = board::GetPartLoad(HocClkPartLoad_GPU);
|
||||||
continue;
|
u32 tableMaxHz = table.list[table.count - 1];
|
||||||
|
u32 desiredHz = SchedutilTargetHz(gpuLoad, tableMaxHz);
|
||||||
|
u32 targetHz = ResolveTargetHz(HocClkModule_GPU);
|
||||||
|
u32 maxHz = clockManager::GetMaxAllowedHz(HocClkModule_GPU, clockManager::gContext.profile);
|
||||||
|
|
||||||
std::scoped_lock lock{clockManager::gContextMutex};
|
if (targetHz && desiredHz > targetHz)
|
||||||
|
desiredHz = targetHz;
|
||||||
|
if (maxHz && desiredHz > maxHz)
|
||||||
|
desiredHz = maxHz;
|
||||||
|
|
||||||
u32 cpuLoad = board::GetPartLoad(HocClkPartLoad_CPUMax);
|
u32 newHz = table.list[TableIndexForHz(table, desiredHz)];
|
||||||
|
bool goingDown = (gpuLastHz != 0) && (newHz < gpuLastHz);
|
||||||
|
|
||||||
u32 tableMaxHz = table.list[table.count - 1];
|
if (!goingDown)
|
||||||
u32 desiredHz = SchedutilTargetHz(cpuLoad, tableMaxHz);
|
gpuDownHoldRemaining = 0;
|
||||||
u32 targetHz = ResolveTargetHz(HocClkModule_CPU);
|
else if (gpuDownHoldRemaining == 0)
|
||||||
u32 maxHz = clockManager::GetMaxAllowedHz(HocClkModule_CPU, clockManager::gContext.profile);
|
gpuDownHoldRemaining = DOWN_HOLD_TICKS;
|
||||||
|
|
||||||
if (targetHz && desiredHz > targetHz)
|
if (gpuDownHoldRemaining > 0)
|
||||||
desiredHz = targetHz;
|
gpuDownHoldRemaining--;
|
||||||
|
|
||||||
if (maxHz && desiredHz > maxHz)
|
if ((!goingDown || (gpuDownHoldRemaining == 0)) && clockManager::IsAssignableHz(HocClkModule_GPU, newHz)) {
|
||||||
desiredHz = maxHz;
|
board::SetHz(HocClkModule_GPU, newHz);
|
||||||
|
clockManager::gContext.freqs[HocClkModule_GPU] = newHz;
|
||||||
u32 newHz = table.list[TableIndexForHz(table, desiredHz)];
|
gpuLastHz = newHz;
|
||||||
|
}
|
||||||
// ramp up fast, go down slow
|
} else {
|
||||||
bool goingDown = (lastHz != 0) && (newHz < lastHz);
|
gpuDownHoldRemaining = 0;
|
||||||
|
gpuLastHz = 0;
|
||||||
if (!goingDown)
|
|
||||||
downHoldRemaining = 0;
|
|
||||||
else if (downHoldRemaining == 0)
|
|
||||||
downHoldRemaining = DOWN_HOLD_TICKS;
|
|
||||||
|
|
||||||
if (downHoldRemaining > 0)
|
|
||||||
downHoldRemaining--;
|
|
||||||
|
|
||||||
if (++tick > 50) {
|
|
||||||
minHz = config::GetConfigValue(HocClkConfigValue_CpuGovernorMinimumFreq);
|
|
||||||
tick = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newHz < minHz)
|
if (isVRREnabled && clockManager::gContext.profile != HocClkProfile_Docked && clockManager::gContext.isSaltyNXInstalled) {
|
||||||
newHz = minHz;
|
bool skipVrr = false;
|
||||||
|
|
||||||
if ((!goingDown || (downHoldRemaining == 0)) && clockManager::IsAssignableHz(HocClkModule_CPU, newHz)) {
|
if (++vrrFocusTick > 100) {
|
||||||
board::SetHz(HocClkModule_CPU, newHz);
|
vrrFocusTick = 0;
|
||||||
clockManager::gContext.freqs[HocClkModule_CPU] = newHz;
|
bool isApplicationOutOfFocus = false;
|
||||||
lastHz = newHz;
|
Result rc = processManagement::isApplicationOutOfFocus(&isApplicationOutOfFocus);
|
||||||
}
|
if (R_FAILED(rc) || isApplicationOutOfFocus) {
|
||||||
|
board::ResetToStockDisplay();
|
||||||
svcSleepThread(POLL_NS);
|
skipVrr = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void GovernorThread(void* arg)
|
|
||||||
{
|
|
||||||
(void)arg;
|
|
||||||
|
|
||||||
u32 downHoldRemaining = 0;
|
|
||||||
u32 lastHz = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (!clockManager::gRunning || !isGpuGovernorEnabled) {
|
|
||||||
downHoldRemaining = 0;
|
|
||||||
lastHz = 0;
|
|
||||||
svcSleepThread(POLL_NS);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& table = clockManager::gFreqTable[HocClkModule_GPU];
|
|
||||||
if (table.count == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::scoped_lock lock{clockManager::gContextMutex};
|
|
||||||
|
|
||||||
u32 gpuLoad = board::GetPartLoad(HocClkPartLoad_GPU);
|
|
||||||
u32 tableMaxHz = table.list[table.count - 1];
|
|
||||||
u32 desiredHz = SchedutilTargetHz(gpuLoad, tableMaxHz);
|
|
||||||
u32 targetHz = ResolveTargetHz(HocClkModule_GPU);
|
|
||||||
u32 maxHz = clockManager::GetMaxAllowedHz(HocClkModule_GPU, clockManager::gContext.profile);
|
|
||||||
|
|
||||||
if (targetHz && desiredHz > targetHz)
|
|
||||||
desiredHz = targetHz;
|
|
||||||
|
|
||||||
if (maxHz && desiredHz > maxHz)
|
|
||||||
desiredHz = maxHz;
|
|
||||||
|
|
||||||
u32 newHz = table.list[TableIndexForHz(table, desiredHz)];
|
|
||||||
bool goingDown = (lastHz != 0) && (newHz < lastHz);
|
|
||||||
|
|
||||||
if (!goingDown)
|
|
||||||
downHoldRemaining = 0;
|
|
||||||
else if (downHoldRemaining == 0)
|
|
||||||
downHoldRemaining = DOWN_HOLD_TICKS;
|
|
||||||
|
|
||||||
if (downHoldRemaining > 0)
|
|
||||||
downHoldRemaining--;
|
|
||||||
|
|
||||||
if ((!goingDown || (downHoldRemaining == 0)) && clockManager::IsAssignableHz(HocClkModule_GPU, newHz)) {
|
|
||||||
board::SetHz(HocClkModule_GPU, newHz);
|
|
||||||
clockManager::gContext.freqs[HocClkModule_GPU] = newHz;
|
|
||||||
lastHz = newHz;
|
|
||||||
}
|
|
||||||
|
|
||||||
svcSleepThread(POLL_NS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VRRThread(void* arg)
|
|
||||||
{
|
|
||||||
(void)arg;
|
|
||||||
|
|
||||||
u8 tick = 0, tick2 = 0;
|
|
||||||
for (;;) {
|
|
||||||
if (!clockManager::gRunning || clockManager::gContext.profile == HocClkProfile_Docked || !isVRREnabled) {
|
|
||||||
svcSleepThread(POLL_NS);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::scoped_lock lock{clockManager::gContextMutex};
|
|
||||||
|
|
||||||
if(++tick2 > 100) {
|
|
||||||
bool isApplicationOutOfFocus = false;
|
|
||||||
Result rc = processManagement::isApplicationOutOfFocus(&isApplicationOutOfFocus);
|
|
||||||
if(R_FAILED(rc)) {
|
|
||||||
svcSleepThread(POLL_NS);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isApplicationOutOfFocus) {
|
if (!skipVrr) {
|
||||||
board::ResetToStockDisplay();
|
u8 fps = integrations::GetSaltyNXFPS();
|
||||||
svcSleepThread(POLL_NS);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 fps;
|
if (fps != 254) {
|
||||||
|
std::scoped_lock lock{clockManager::gContextMutex};
|
||||||
|
|
||||||
if (clockManager::gContext.isSaltyNXInstalled) {
|
u32 targetHz = clockManager::gContext.overrideFreqs[HocClkModule_Display];
|
||||||
fps = integrations::GetSaltyNXFPS();
|
if (!targetHz) {
|
||||||
} else {
|
targetHz = config::GetAutoClockHz(clockManager::gContext.applicationId, HocClkModule_Display, clockManager::gContext.profile, false);
|
||||||
svcSleepThread(~0ULL); // effectively disable the thread if SaltyNX isn't installed, as there's no point in it running
|
if (!targetHz)
|
||||||
continue;
|
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_Display, clockManager::gContext.profile, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fps == 254) {
|
u8 maxDisplay = targetHz ? (u8)targetHz : 60;
|
||||||
svcSleepThread(POLL_NS);
|
u8 minDisplay = board::GetConsoleType() == HocClkConsoleType_Aula ? 45 : 40;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// if(appletGetFocusState() != AppletFocusState_InFocus) {
|
|
||||||
// board::ResetToStockDisplay();
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
u32 targetHz = clockManager::gContext.overrideFreqs[HocClkModule_Display];
|
if (maxDisplay != minDisplay) {
|
||||||
if (!targetHz) {
|
if (fps >= minDisplay && fps <= maxDisplay) {
|
||||||
targetHz = config::GetAutoClockHz(clockManager::gContext.applicationId, HocClkModule_Display, clockManager::gContext.profile, false);
|
board::SetHz(HocClkModule_Display, fps);
|
||||||
if (!targetHz)
|
clockManager::gContext.freqs[HocClkModule_Display] = fps;
|
||||||
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_Display, clockManager::gContext.profile, false);
|
clockManager::gContext.realFreqs[HocClkModule_Display] = fps;
|
||||||
}
|
} else {
|
||||||
|
for (u32 i = 0; i < 10; i++) {
|
||||||
|
u32 compareHz = fps * i;
|
||||||
|
if (compareHz >= minDisplay && compareHz <= maxDisplay) {
|
||||||
|
board::SetHz(HocClkModule_Display, compareHz);
|
||||||
|
clockManager::gContext.freqs[HocClkModule_Display] = compareHz;
|
||||||
|
clockManager::gContext.realFreqs[HocClkModule_Display] = compareHz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u8 maxDisplay;
|
if (++vrrTick > 50) {
|
||||||
if (targetHz) {
|
vrrTick = 0;
|
||||||
maxDisplay = targetHz;
|
board::SetHz(HocClkModule_Display, maxDisplay);
|
||||||
} else {
|
svcSleepThread(50'000'000);
|
||||||
maxDisplay = 60; // don't assume display stuff!
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 minDisplay = board::GetConsoleType() == HocClkConsoleType_Aula ? 45 : 40;
|
|
||||||
if (maxDisplay == minDisplay)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fps >= minDisplay && fps <= maxDisplay) {
|
|
||||||
board::SetHz(HocClkModule_Display, fps);
|
|
||||||
clockManager::gContext.freqs[HocClkModule_Display] = fps;
|
|
||||||
clockManager::gContext.realFreqs[HocClkModule_Display] = fps;
|
|
||||||
} else {
|
|
||||||
for (u32 i = 0; i < 10; i++) {
|
|
||||||
u32 compareHz = fps * i;
|
|
||||||
if (compareHz >= minDisplay && compareHz <= maxDisplay) {
|
|
||||||
board::SetHz(HocClkModule_Display, compareHz);
|
|
||||||
clockManager::gContext.freqs[HocClkModule_Display] = compareHz;
|
|
||||||
clockManager::gContext.realFreqs[HocClkModule_Display] = compareHz;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++tick > 50) {
|
|
||||||
board::SetHz(HocClkModule_Display, maxDisplay);
|
|
||||||
tick = 0;
|
|
||||||
svcSleepThread(50'000'000);
|
|
||||||
}
|
|
||||||
|
|
||||||
svcSleepThread(POLL_NS);
|
svcSleepThread(POLL_NS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void startThreads() {
|
void startThreads() {
|
||||||
|
|
||||||
threadCreate(
|
threadCreate(
|
||||||
&cpuGovernorTHREAD,
|
&governorTHREAD,
|
||||||
CpuGovernorThread,
|
|
||||||
nullptr,
|
|
||||||
NULL,
|
|
||||||
0x2000,
|
|
||||||
0x3F,
|
|
||||||
-2
|
|
||||||
);
|
|
||||||
|
|
||||||
threadCreate(
|
|
||||||
&gpuGovernorTHREAD,
|
|
||||||
GovernorThread,
|
GovernorThread,
|
||||||
nullptr,
|
nullptr,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -358,25 +286,10 @@ namespace governor {
|
|||||||
0x3F,
|
0x3F,
|
||||||
-2
|
-2
|
||||||
);
|
);
|
||||||
|
threadStart(&governorTHREAD);
|
||||||
threadCreate(
|
|
||||||
&vrrTHREAD,
|
|
||||||
VRRThread,
|
|
||||||
nullptr,
|
|
||||||
NULL,
|
|
||||||
0x2000,
|
|
||||||
0x3F,
|
|
||||||
-2
|
|
||||||
);
|
|
||||||
|
|
||||||
threadStart(&cpuGovernorTHREAD);
|
|
||||||
threadStart(&gpuGovernorTHREAD);
|
|
||||||
threadStart(&vrrTHREAD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void exitThreads() {
|
void exitThreads() {
|
||||||
threadClose(&cpuGovernorTHREAD);
|
threadClose(&governorTHREAD);
|
||||||
threadClose(&gpuGovernorTHREAD);
|
|
||||||
threadClose(&vrrTHREAD);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,5 +38,4 @@ namespace governor {
|
|||||||
void startThreads();
|
void startThreads();
|
||||||
void exitThreads();
|
void exitThreads();
|
||||||
void HandleGovernor(uint32_t targetHz);
|
void HandleGovernor(uint32_t targetHz);
|
||||||
void GovernorThread(void* arg);
|
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#include "ipc_service.hpp"
|
#include "ipc_service.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
|
||||||
#define INNER_HEAP_SIZE 0x4A000
|
#define INNER_HEAP_SIZE 0x3A000
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user