sysclk: fix refresh rate on lite

also increase heap size due to larger ipc packets
This commit is contained in:
souldbminersmwc
2026-03-20 20:03:36 -04:00
parent 2454afd58f
commit 95e68bd27e
8 changed files with 62 additions and 77 deletions

View File

@@ -286,12 +286,17 @@ public:
: applicationId(appId), profileList(pList), profile(prof) {} : applicationId(appId), profileList(pList), profile(prof) {}
void listUI() override { void listUI() override {
Result rc = sysclkIpcGetConfigValues(&configList);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader("Governor")); this->listElement->addItem(new tsl::elm::CategoryHeader("Governor"));
static constexpr struct { const char* label; int shift; } kAll[] = { static constexpr struct { const char* label; int shift; } kAll[] = {
{"CPU", 0}, {"GPU", 8}, {"VRR", 16} {"CPU", 0}, {"GPU", 8}, {"VRR", 16}
}; };
int count = IsHoag() ? 2 : 3; int count = configList.values[HorizonOCConfigValue_OverwriteRefreshRate] ? 2 : 3;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
u8 cur = (this->profileList->mhzMap[this->profile][HorizonOCModule_Governor] >> kAll[i].shift) & 0xFF; u8 cur = (this->profileList->mhzMap[this->profile][HorizonOCModule_Governor] >> kAll[i].shift) & 0xFF;
@@ -411,7 +416,7 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
NamedValue("115 Hz", 115), NamedValue("115 Hz", 115),
NamedValue("120 Hz", 120) NamedValue("120 Hz", 120)
}; };
if(configList.values[HorizonOCConfigValue_OverwriteRefreshRate] && !IsHoag()) if(configList.values[HorizonOCConfigValue_OverwriteRefreshRate])
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsStandard); this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsStandard);
} }
} }

View File

@@ -154,11 +154,11 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_Battery]); // Battery renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_Battery]); // Battery
if(!IsHoag()) {
renderer->drawString(labels[13], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq renderer->drawString(labels[13], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
}
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq
renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label
renderer->drawString(displayStrings[24], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed renderer->drawString(displayStrings[24], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed

View File

@@ -304,7 +304,7 @@ public:
static constexpr struct { const char* label; int shift; } kAll[] = { static constexpr struct { const char* label; int shift; } kAll[] = {
{"CPU", 0}, {"GPU", 8}, {"VRR", 16} {"CPU", 0}, {"GPU", 8}, {"VRR", 16}
}; };
int count = IsHoag() ? 2 : 3; int count = configList.values[HorizonOCConfigValue_OverwriteRefreshRate] ? 2 : 3;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
u8 cur = (this->packed >> kAll[i].shift) & 0xFF; u8 cur = (this->packed >> kAll[i].shift) & 0xFF;
@@ -354,7 +354,7 @@ void GlobalOverrideGui::listUI()
this->addModuleListItem(SysClkModule_MEM); this->addModuleListItem(SysClkModule_MEM);
#if IS_MINIMAL == 0 #if IS_MINIMAL == 0
ValueThresholds lcdThresholds(60, 65); ValueThresholds lcdThresholds(60, 65);
if(configList.values[HorizonOCConfigValue_OverwriteRefreshRate] && !IsHoag()) if(configList.values[HorizonOCConfigValue_OverwriteRefreshRate])
this->addModuleListItemValue(HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds); this->addModuleListItemValue(HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
#endif #endif

View File

@@ -446,18 +446,17 @@ void MiscGui::listUI()
}); });
gpuSubmenu->setValue(R_ARROW); gpuSubmenu->setValue(R_ARROW);
this->listElement->addItem(gpuSubmenu); this->listElement->addItem(gpuSubmenu);
if(!IsHoag()) {
tsl::elm::ListItem* displaySubMenu = new tsl::elm::ListItem("Display Settings"); tsl::elm::ListItem* displaySubMenu = new tsl::elm::ListItem("Display Settings");
displaySubMenu->setClickListener([](u64 keys) { displaySubMenu->setClickListener([](u64 keys) {
if (keys & HidNpadButton_A) { if (keys & HidNpadButton_A) {
tsl::changeTo<DisplaySubMenuGui>(); tsl::changeTo<DisplaySubMenuGui>();
return true; return true;
} }
return false; return false;
}); });
displaySubMenu->setValue(R_ARROW); displaySubMenu->setValue(R_ARROW);
this->listElement->addItem(displaySubMenu); this->listElement->addItem(displaySubMenu);
}
#if IS_MINIMAL == 0 #if IS_MINIMAL == 0
// std::vector<NamedValue> chargerCurrents = { // std::vector<NamedValue> chargerCurrents = {

View File

@@ -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": "0x0000C000", "main_thread_stack_size": "0x0000D000",
"main_thread_priority": 16, "main_thread_priority": 16,
"default_cpu_id": 3, "default_cpu_id": 3,
"process_category": 1, "process_category": 1,

View File

@@ -24,8 +24,6 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
// Note: Hoag crashes on display refresh rate init while in sleep mode
#include <nxExt.h> #include <nxExt.h>
#include "board.h" #include "board.h"
#include "errors.h" #include "errors.h"
@@ -282,17 +280,15 @@ void Board::Initialize()
pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001);
} }
if(!IsHoag()) { u64 clkVirtAddr, dsiVirtAddr, outsize;
u64 clkVirtAddr, dsiVirtAddr, outsize; rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000);
rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000); ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (clk)");
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (clk)"); rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000); ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr}; DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = IsHoag()};
DisplayRefresh_Initialize(&cfg); DisplayRefresh_Initialize(&cfg);
}
rc = svcQueryMemoryMapping(&cldvfs, &cldvfs_temp, CLDVFS_REGION_BASE, CLDVFS_REGION_SIZE); rc = svcQueryMemoryMapping(&cldvfs, &cldvfs_temp, CLDVFS_REGION_BASE, CLDVFS_REGION_SIZE);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (cldvfs)"); ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (cldvfs)");
@@ -420,14 +416,15 @@ void Board::Exit()
// threadClose(&cpuCore3Thread); // threadClose(&cpuCore3Thread);
threadClose(&miscThread); threadClose(&miscThread);
DisplayRefresh_Shutdown();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);
pwmExit(); pwmExit();
rgltrExit(); rgltrExit();
batteryInfoExit(); batteryInfoExit();
pmdmntExit(); pmdmntExit();
nvExit(); nvExit();
if(!IsHoag())
DisplayRefresh_Shutdown();
} }
SysClkProfile Board::GetProfile() SysClkProfile Board::GetProfile()
@@ -462,8 +459,7 @@ void Board::SetHz(SysClkModule module, std::uint32_t hz)
{ {
Result rc = 0; Result rc = 0;
if(module == HorizonOCModule_Display) { if(module == HorizonOCModule_Display) {
if(!IsHoag()) DisplayRefresh_SetRate(hz);
DisplayRefresh_SetRate(hz);
return; return;
} }
if(module > SysClkModule_MEM) if(module > SysClkModule_MEM)
@@ -501,10 +497,7 @@ std::uint32_t Board::GetHz(SysClkModule module)
std::uint32_t hz = 0; std::uint32_t hz = 0;
if(module == HorizonOCModule_Display) { if(module == HorizonOCModule_Display) {
if(!IsHoag()) DisplayRefresh_GetRate(&hz, false);
DisplayRefresh_GetRate(&hz, false);
else
hz = 60;
return hz; return hz;
} }
@@ -541,10 +534,7 @@ std::uint32_t Board::GetRealHz(SysClkModule module)
case SysClkModule_MEM: case SysClkModule_MEM:
return t210ClkMemFreq(); return t210ClkMemFreq();
case HorizonOCModule_Display: case HorizonOCModule_Display:
if(!IsHoag()) DisplayRefresh_GetRate(&hz, false);
DisplayRefresh_GetRate(&hz, false);
else
hz = 60;
return hz; return hz;
default: default:
ASSERT_ENUM_VALID(SysClkModule, module); ASSERT_ENUM_VALID(SysClkModule, module);
@@ -739,8 +729,7 @@ void Board::ResetToStockGpu()
} }
void Board::ResetToStockDisplay() { void Board::ResetToStockDisplay() {
if(!IsHoag()) DisplayRefresh_SetRate(60);
DisplayRefresh_SetRate(60);
} }
u8 Board::GetHighestDockedDisplayRate() { u8 Board::GetHighestDockedDisplayRate() {

View File

@@ -495,11 +495,6 @@ void ClockManager::VRRThread(void* arg) {
continue; continue;
} }
if(Board::IsHoag()) { // don't do anything on lite
svcSleepThread(~0ULL);
continue;
}
std::scoped_lock lock{mgr->contextMutex}; std::scoped_lock lock{mgr->contextMutex};
u8 fps; u8 fps;
@@ -566,7 +561,7 @@ void ClockManager::VRRThread(void* arg) {
} }
u8 cached_RR = 60;
void ClockManager::HandleSafetyFeatures() { void ClockManager::HandleSafetyFeatures() {
AppletOperationMode opMode = appletGetOperationMode(); AppletOperationMode opMode = appletGetOperationMode();
if(this->config->GetConfigValue(HocClkConfigValue_HandheldTDP) && opMode == AppletOperationMode_Handheld) { if(this->config->GetConfigValue(HocClkConfigValue_HandheldTDP) && opMode == AppletOperationMode_Handheld) {
@@ -730,7 +725,7 @@ void ClockManager::HandleFreqReset(SysClkModule module, bool isBoost) {
DVFSReset(); DVFSReset();
break; break;
case HorizonOCModule_Display: case HorizonOCModule_Display:
if(this->config->GetConfigValue(HorizonOCConfigValue_OverwriteRefreshRate) && !Board::IsHoag()) { if(this->config->GetConfigValue(HorizonOCConfigValue_OverwriteRefreshRate)) {
Board::ResetToStockDisplay(); Board::ResetToStockDisplay();
} }
break; break;
@@ -776,17 +771,15 @@ void ClockManager::SetClocks(bool isBoost) {
bool noCPU = isCpuGovernorEnabled; bool noCPU = isCpuGovernorEnabled;
bool noGPU = isGpuGovernorEnabled; bool noGPU = isGpuGovernorEnabled;
if(!Board::IsHoag()) { bool noDisp = isVRREnabled;
bool noDisp = isVRREnabled; if(noDisp && module == HorizonOCModule_Display)
if(noDisp && module == HorizonOCModule_Display) continue;
continue;
if(module == HorizonOCModule_Display && this->config->GetConfigValue(HorizonOCConfigValue_OverwriteRefreshRate)) { if(module == HorizonOCModule_Display && this->config->GetConfigValue(HorizonOCConfigValue_OverwriteRefreshRate)) {
if(targetHz) if(targetHz)
Board::SetHz(HorizonOCModule_Display, targetHz); Board::SetHz(HorizonOCModule_Display, targetHz);
else else
Board::ResetToStockDisplay(); Board::ResetToStockDisplay();
}
} }
// Skip GPU and CPU if governors handle them // Skip GPU and CPU if governors handle them
@@ -991,20 +984,19 @@ bool ClockManager::RefreshContext()
} }
// this->context->maxDisplayFreq = Board::GetHighestDockedDisplayRate(); // this->context->maxDisplayFreq = Board::GetHighestDockedDisplayRate();
if(!Board::IsHoag()) { u32 targetHz = this->context->overrideFreqs[HorizonOCModule_Display];
u32 targetHz = this->context->overrideFreqs[HorizonOCModule_Display]; if (!targetHz)
if (!targetHz) {
{ targetHz = this->config->GetAutoClockHz(this->context->applicationId, HorizonOCModule_Display, this->context->profile, true);
targetHz = this->config->GetAutoClockHz(this->context->applicationId, HorizonOCModule_Display, this->context->profile, true); if(!targetHz)
if(!targetHz) targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, HorizonOCModule_Display, this->context->profile, true);
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, HorizonOCModule_Display, this->context->profile, true);
}
if(targetHz && this->context->realFreqs[HorizonOCModule_Display] > targetHz && this->context->profile != SysClkProfile_Docked)
this->context->realFreqs[HorizonOCModule_Display] = targetHz; // clean up display real freqs, should probably be moved to the real freqs loop?
Board::SetDisplayRefreshDockedState(this->context->profile == SysClkProfile_Docked);
} }
if(targetHz && this->context->realFreqs[HorizonOCModule_Display] > targetHz && this->context->profile != SysClkProfile_Docked)
this->context->realFreqs[HorizonOCModule_Display] = targetHz; // clean up display real freqs, should probably be moved to the real freqs loop?
if(!Board::IsHoag())
Board::SetDisplayRefreshDockedState(this->context->profile == SysClkProfile_Docked);
if(this->context->isSaltyNXInstalled) if(this->context->isSaltyNXInstalled)
this->context->fps = saltyNXIntegration->GetFPS(); this->context->fps = saltyNXIntegration->GetFPS();
else else

View File

@@ -36,7 +36,7 @@
#include "process_management.h" #include "process_management.h"
#include "clock_manager.h" #include "clock_manager.h"
#include "ipc_service.h" #include "ipc_service.h"
#define INNER_HEAP_SIZE 0x40000 #define INNER_HEAP_SIZE 0x45000
extern "C" extern "C"