sysclk: make display change togglable and increase battery life in sleep mode

This commit is contained in:
souldbminersmwc
2025-12-24 19:19:58 -05:00
parent c65543ed26
commit a78fca1b91
10 changed files with 45 additions and 15 deletions

View File

@@ -43,9 +43,8 @@ typedef struct
uint32_t PartLoad[SysClkPartLoad_EnumMax]; uint32_t PartLoad[SysClkPartLoad_EnumMax];
uint32_t voltages[HocClkVoltage_EnumMax]; uint32_t voltages[HocClkVoltage_EnumMax];
uint32_t perfConfId; uint32_t perfConfId;
u8 maxDisplayFreq;
u8 fps; u8 fps;
u8 lcdFreq;
u8 fanLevel;
} SysClkContext; } SysClkContext;
typedef struct typedef struct

View File

@@ -62,6 +62,8 @@ typedef enum {
HorizonOCConfigValue_BatteryChargeCurrent, HorizonOCConfigValue_BatteryChargeCurrent,
HorizonOCConfigValue_OverwriteRefreshRate,
KipConfigValue_custRev, KipConfigValue_custRev,
KipConfigValue_mtcConf, KipConfigValue_mtcConf,
KipConfigValue_hpMode, KipConfigValue_hpMode,
@@ -230,6 +232,9 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case HorizonOCConfigValue_BatteryChargeCurrent: case HorizonOCConfigValue_BatteryChargeCurrent:
return pretty ? "Battery Charge Current" : "bat_charge_current"; return pretty ? "Battery Charge Current" : "bat_charge_current";
case HorizonOCConfigValue_OverwriteRefreshRate:
return pretty ? "Display Refresh Rate Changing" : "drr_changing";
// KIP config values // KIP config values
case KipConfigValue_custRev: case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev"; return pretty ? "Custom Revision" : "kip_cust_rev";
@@ -425,6 +430,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
case HocClkConfigValue_LiteTDPLimit: case HocClkConfigValue_LiteTDPLimit:
return 6400ULL; return 6400ULL;
case HorizonOCConfigValue_BatteryChargeCurrent: case HorizonOCConfigValue_BatteryChargeCurrent:
case HorizonOCConfigValue_OverwriteRefreshRate:
return 0ULL; return 0ULL;
default: default:
return 0ULL; return 0ULL;
@@ -458,6 +464,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case HocClkConfigValue_EnforceBoardLimit: case HocClkConfigValue_EnforceBoardLimit:
case HocClkConfigValue_KipEditing: case HocClkConfigValue_KipEditing:
case HocClkConfigValue_KipFileName: case HocClkConfigValue_KipFileName:
case HorizonOCConfigValue_OverwriteRefreshRate:
return (input & 0x1) == input; return (input & 0x1) == input;
case KipConfigValue_custRev: case KipConfigValue_custRev:

View File

@@ -29,7 +29,6 @@
#include "../format.h" #include "../format.h"
#include "fatal_gui.h" #include "fatal_gui.h"
AppProfileGui::AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList) AppProfileGui::AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList)
{ {
this->applicationId = applicationId; this->applicationId = applicationId;
@@ -272,7 +271,10 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
this->addModuleListItem(profile, SysClkModule_CPU); this->addModuleListItem(profile, SysClkModule_CPU);
this->addModuleListItem(profile, SysClkModule_GPU); this->addModuleListItem(profile, SysClkModule_GPU);
this->addModuleListItem(profile, SysClkModule_MEM); this->addModuleListItem(profile, SysClkModule_MEM);
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, 72, 5, " Hz", 1, 0); if(profile != SysClkProfile_Docked)
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, 72, 1, " Hz", 1, 0);
else
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 5, " Hz", 1, 0);
this->addModuleListItemToggle(profile, HorizonOCModule_Governor); this->addModuleListItemToggle(profile, HorizonOCModule_Governor);
} }

View File

@@ -154,6 +154,10 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
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
renderer->drawString(displayStrings[22], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_PMIC]); // PMIC renderer->drawString(displayStrings[22], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_PMIC]); // PMIC
renderer->drawString(labels[13], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq
y+=20; y+=20;
renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage
@@ -163,9 +167,8 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
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
renderer->drawString(labels[13], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label renderer->drawString(displayStrings[26], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp volt
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
} }
@@ -186,11 +189,13 @@ void BaseMenuGui::refresh()
} }
// === SYSCLK CONTEXT UPDATE === // === SYSCLK CONTEXT UPDATE ===
const Result rc = sysclkIpcGetCurrentContext(this->context); Result rc = sysclkIpcGetCurrentContext(this->context);
if (R_FAILED(rc)) [[unlikely]] { if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetCurrentContext", rc); FatalGui::openWithResultCode("sysclkIpcGetCurrentContext", rc);
return; return;
} }
sysclkIpcGetConfigValues(this->configList);
// dockedHighestAllowedRefreshRate = this->context->maxDisplayFreq;
// === FORMAT ALL DISPLAY STRINGS (once per second) === // === FORMAT ALL DISPLAY STRINGS (once per second) ===
// App ID (hex conversion) // App ID (hex conversion)
@@ -274,6 +279,8 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[25], "%u Hz", context->realFreqs[HorizonOCModule_Display]); sprintf(displayStrings[25], "%u Hz", context->realFreqs[HorizonOCModule_Display]);
sprintf(displayStrings[26], "%u.%u mV", context->voltages[HocClkVoltage_Display] / 1000U, context->voltages[HocClkVoltage_Display] % 1000U);
} }
tsl::elm::Element* BaseMenuGui::baseUI() tsl::elm::Element* BaseMenuGui::baseUI()

View File

@@ -33,10 +33,12 @@
class BaseMenuGui : public BaseGui class BaseMenuGui : public BaseGui
{ {
protected: protected:
SysClkContext* context;
std::uint64_t lastContextUpdate;
public: public:
// u8 dockedHighestAllowedRefreshRate = 60;
SysClkContext* context;
std::uint64_t lastContextUpdate;
SysClkConfigValueList* configList;
bool g_hardwareModelCached = false; bool g_hardwareModelCached = false;
bool g_isMariko = false; bool g_isMariko = false;

View File

@@ -398,6 +398,8 @@ void MiscGui::listUI()
chargerCurrents, chargerCurrents,
false false
); );
addConfigToggle(HorizonOCConfigValue_OverwriteRefreshRate, nullptr);
} }
@@ -1076,7 +1078,7 @@ void MiscGui::refresh() {
if (this->context && ++frameCounter >= 60) { if (this->context && ++frameCounter >= 60) {
frameCounter = 0; frameCounter = 0;
sysclkIpcGetConfigValues(this->configList); // sysclkIpcGetConfigValues(this->configList);
updateConfigToggles(); updateConfigToggles();

View File

@@ -19,7 +19,6 @@ protected:
std::map<SysClkConfigValue, tsl::elm::ListItem*> configButtons; std::map<SysClkConfigValue, tsl::elm::ListItem*> configButtons;
std::map<SysClkConfigValue, ValueRange> configRanges; std::map<SysClkConfigValue, ValueRange> configRanges;
std::map<SysClkConfigValue, std::vector<NamedValue>> configNamedValues; std::map<SysClkConfigValue, std::vector<NamedValue>> configNamedValues;
SysClkConfigValueList* configList;
std::map<SysClkConfigValue, tsl::elm::ToggleListItem*> configToggles; std::map<SysClkConfigValue, tsl::elm::ToggleListItem*> configToggles;
std::map<SysClkConfigValue, std::tuple<tsl::elm::TrackBar*, tsl::elm::ListItem*, std::vector<uint64_t>>> configTrackbars; std::map<SysClkConfigValue, std::tuple<tsl::elm::TrackBar*, tsl::elm::ListItem*, std::vector<uint64_t>>> configTrackbars;

View File

@@ -572,6 +572,10 @@ void Board::ResetToStockDisplay() {
DisplayRefresh_SetRate(60); DisplayRefresh_SetRate(60);
} }
u8 Board::GetHighestDockedDisplayRate() {
return DisplayRefresh_GetDockedHighestAllowed();
}
std::uint32_t Board::GetTemperatureMilli(SysClkThermalSensor sensor) std::uint32_t Board::GetTemperatureMilli(SysClkThermalSensor sensor)
{ {
std::int32_t millis = 0; std::int32_t millis = 0;

View File

@@ -44,7 +44,7 @@ class Board
static void ResetToStockMem(); static void ResetToStockMem();
static void ResetToStockGpu(); static void ResetToStockGpu();
static void ResetToStockDisplay(); static void ResetToStockDisplay();
static u8 GetHighestDockedDisplayRate();
static SysClkProfile GetProfile(); static SysClkProfile GetProfile();
static void SetHz(SysClkModule module, std::uint32_t hz); static void SetHz(SysClkModule module, std::uint32_t hz);
static std::uint32_t GetHz(SysClkModule module); static std::uint32_t GetHz(SysClkModule module);

View File

@@ -440,7 +440,7 @@ void ClockManager::Tick()
isGovernorEnabled = newGovernorState; isGovernorEnabled = newGovernorState;
} }
if(module == HorizonOCModule_Display) { 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
@@ -487,7 +487,10 @@ void ClockManager::ResetToStockClocks() {
void ClockManager::WaitForNextTick() void ClockManager::WaitForNextTick()
{ {
svcSleepThread(this->GetConfig()->GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL); if(!(Board::GetHz(SysClkModule_MEM) < 665000000))
svcSleepThread(this->GetConfig()->GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL);
else
svcSleepThread(5000 * 1000000ULL); // 5 seconds in sleep mode
} }
bool ClockManager::RefreshContext() bool ClockManager::RefreshContext()
@@ -623,6 +626,11 @@ bool ClockManager::RefreshContext()
FileUtils::WriteContextToCsv(this->context); FileUtils::WriteContextToCsv(this->context);
} }
if(this->context->profile == SysClkProfile_Docked)
this->context->maxDisplayFreq = Board::GetHighestDockedDisplayRate();
else
this->context->maxDisplayFreq = 60;
return hasChanged; return hasChanged;
} }