sysclk: remove reversenx mode, some code cleanup, display upto 240hz, experemental settings config option, remove max display clock , bump version

This commit is contained in:
souldbminersmwc
2026-02-15 17:43:41 -05:00
parent b9156d6861
commit 7525baf567
20 changed files with 280 additions and 287 deletions

View File

@@ -153,12 +153,6 @@ Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* o
); );
} }
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetReverseNXRTMode, mode);
}
Result hocClkIpcSetKipData() Result hocClkIpcSetKipData()
{ {
u32 temp = 0; u32 temp = 0;

View File

@@ -108,16 +108,6 @@ typedef enum
SysClkPartLoad_EnumMax SysClkPartLoad_EnumMax
} SysClkPartLoad; } SysClkPartLoad;
typedef enum
{
ReverseNX_NotFound = 0,
ReverseNX_SystemDefault = 0,
ReverseNX_Handheld,
ReverseNX_Docked,
} ReverseNXMode;
typedef enum { typedef enum {
HorizonOCSpeedo_CPU = 0, HorizonOCSpeedo_CPU = 0,
HorizonOCSpeedo_GPU, HorizonOCSpeedo_GPU,

View File

@@ -48,7 +48,6 @@ Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles);
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues); Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues);
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues); Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues);
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount); Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount);
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode);
Result hocClkIpcSetKipData(); Result hocClkIpcSetKipData();
Result hocClkIpcGetKipData(); Result hocClkIpcGetKipData();
Result hocClkIpcUpdateEmcRegs(); Result hocClkIpcUpdateEmcRegs();

View File

@@ -59,6 +59,8 @@ typedef enum {
HorizonOCConfigValue_DVFSMode, HorizonOCConfigValue_DVFSMode,
HorizonOCConfigValue_DVFSOffset, HorizonOCConfigValue_DVFSOffset,
HorizonOCConfigValue_EnableExperimentalSettings,
HorizonOCConfigValue_GPUScheduling, HorizonOCConfigValue_GPUScheduling,
KipConfigValue_custRev, KipConfigValue_custRev,
@@ -230,6 +232,10 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case HorizonOCConfigValue_GPUScheduling: case HorizonOCConfigValue_GPUScheduling:
return pretty ? "GPU Scheduling" : "gpu_scheduling"; return pretty ? "GPU Scheduling" : "gpu_scheduling";
case HorizonOCConfigValue_EnableExperimentalSettings:
return pretty ? "Enable Experimental Settings" : "enable_experimental_settings";
// 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";
@@ -450,6 +456,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case HorizonOCConfigValue_OverwriteRefreshRate: case HorizonOCConfigValue_OverwriteRefreshRate:
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs: case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
case HocClkConfigValue_IsFirstLoad: case HocClkConfigValue_IsFirstLoad:
case HorizonOCConfigValue_EnableExperimentalSettings:
return (input & 0x1) == input; return (input & 0x1) == input;
case KipConfigValue_custRev: case KipConfigValue_custRev:

View File

@@ -48,9 +48,8 @@ enum SysClkIpcCmd
SysClkIpcCmd_GetConfigValues = 9, SysClkIpcCmd_GetConfigValues = 9,
SysClkIpcCmd_SetConfigValues = 10, SysClkIpcCmd_SetConfigValues = 10,
SysClkIpcCmd_GetFreqList = 11, SysClkIpcCmd_GetFreqList = 11,
SysClkIpcCmd_SetReverseNXRTMode = 12, HocClkIpcCmd_SetKipData = 12,
HocClkIpcCmd_SetKipData = 13, HocClkIpcCmd_GetKipData = 13,
HocClkIpcCmd_GetKipData = 14,
}; };

View File

@@ -153,12 +153,6 @@ Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* o
); );
} }
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetReverseNXRTMode, mode);
}
Result hocClkIpcSetKipData() Result hocClkIpcSetKipData()
{ {
u32 temp = 0; u32 temp = 0;

View File

@@ -42,10 +42,25 @@ static bool g_canChangeRefreshRateDocked = false;
static uint8_t g_lastVActiveSet = 0; static uint8_t g_lastVActiveSet = 0;
// Refresh rate tables // Refresh rate tables
static const uint8_t g_dockedRefreshRates[] = {40, 45, 50, 55, 60, 70, 72, 75, 80, 90, 95, 100, 110, 120, 130, 144, 150, 160, 165, 170, 180, 190, 200, 210, 220, 230, 240}; static const uint8_t g_dockedRefreshRates[] = {40, 45, 50, 55, 60, 70, 72, 75, 80, 90, 95, 100, 110, 120, 130, 140, 144, 150, 160, 165, 170, 180, 190, 200, 210, 220, 230, 240};
static bool g_dockedAllowed[sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0])] = {0}; static bool g_dockedAllowed[sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0])] = {0};
static bool g_dockedAllowed720p[sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0])] = {0}; static bool g_dockedAllowed720p[sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0])] = {0};
// Calculate with this tool:
// https://tomverbeure.github.io/video_timings_calculator?horiz_pixels=1920&vert_pixels=1080&refresh_rate=240&margins=false&interlaced=false&bpc=8&color_fmt=rgb444&video_opt=false&custom_hblank=80&custom_vblank=6
/*
typedef struct {
uint16_t hFrontPorch;
uint8_t hSyncWidth;
uint8_t hBackPorch;
uint8_t vFrontPorch;
uint8_t vSyncWidth;
uint8_t vBackPorch;
uint8_t VIC;
uint32_t pixelClock_kHz;
} DockedTimings;
*/
static const DockedTimings g_dockedTimings1080p[] = { static const DockedTimings g_dockedTimings1080p[] = {
{8, 32, 40, 7, 8, 6, 0, 88080}, // 40Hz {8, 32, 40, 7, 8, 6, 0, 88080}, // 40Hz
{8, 32, 40, 9, 8, 6, 0, 99270}, // 45Hz {8, 32, 40, 9, 8, 6, 0, 99270}, // 45Hz
@@ -60,7 +75,21 @@ static const DockedTimings g_dockedTimings1080p[] = {
{8, 32, 40, 36, 8, 6, 0, 214700}, // 95Hz {8, 32, 40, 36, 8, 6, 0, 214700}, // 95Hz
{528, 44, 148, 4, 5, 36, 64, 297000}, // 100Hz {528, 44, 148, 4, 5, 36, 64, 297000}, // 100Hz
{8, 32, 40, 44, 8, 6, 0, 250360}, // 110Hz {8, 32, 40, 44, 8, 6, 0, 250360}, // 110Hz
{88, 44, 148, 4, 5, 36, 63, 297000} // 120Hz {88, 44, 148, 4, 5, 36, 63, 297000}, // 120Hz
{8, 32, 40, 55, 8, 6, 0, 298750}, //130Hz CVT-RBv2
{8, 32, 40, 61, 8, 6, 0, 323400}, //140Hz CVT-RBv2
{8, 32, 40, 63, 8, 6, 0, 333216}, //144Hz CVT-RBv2
{8, 32, 40, 67, 8, 6, 0, 348300}, //150Hz CVT-RBv2
{8, 32, 40, 72, 8, 6, 0, 373120}, //160Hz CVT-RBv2
{8, 32, 40, 75, 8, 6, 0, 385770}, //165Hz CVT-RBv2
{8, 32, 40, 78, 8, 6, 0, 398480}, //170Hz CVT-RBv2
{8, 32, 40, 84, 8, 6, 0, 424080}, //180Hz CVT-RBv2
{8, 32, 40, 90, 8, 6, 0, 449920}, //190Hz CVT-RBv2
{8, 32, 40, 96, 8, 6, 0, 476000}, //200Hz CVT-RBv2
{8, 32, 40, 102, 8, 6, 0, 502320}, //210Hz CVT-RBv2
{8, 32, 40, 108, 8, 6, 0, 528880}, //220Hz CVT-RBv2
{8, 32, 40, 114, 8, 6, 0, 555680}, //230Hz CVT-RBv2
{8, 32, 40, 121, 8, 6, 0, 583200}, //240Hz CVT-RBv2
}; };
static const HandheldTimings g_handheldTimingsRETRO[] = { static const HandheldTimings g_handheldTimingsRETRO[] = {

View File

@@ -39,7 +39,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk
# version control constants # version control constants
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
#TARGET_VERSION := $(shell git describe --dirty --always --tags) #TARGET_VERSION := $(shell git describe --dirty --always --tags)
APP_VERSION := 0.39 APP_VERSION := 0.40
TARGET_VERSION := $(APP_VERSION) TARGET_VERSION := $(APP_VERSION)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@@ -95,7 +95,8 @@ void AppProfileGui::openValueChoiceGui(
enableThresholds, enableThresholds,
labels, labels,
namedValues, namedValues,
showDefaultValue showDefaultValue,
true
); );
} }
@@ -158,12 +159,12 @@ void AppProfileGui::addModuleListItemValue(
const std::string& suffix, const std::string& suffix,
std::uint32_t divisor, std::uint32_t divisor,
int decimalPlaces, int decimalPlaces,
ValueThresholds thresholds ValueThresholds thresholds,
std::vector<NamedValue> namedValues
) )
{ {
tsl::elm::ListItem* listItem = tsl::elm::ListItem* listItem =
new tsl::elm::ListItem(sysclkFormatModule(module, true)); new tsl::elm::ListItem(sysclkFormatModule(module, true));
std::uint32_t storedValue = this->profileList->mhzMap[profile][module]; std::uint32_t storedValue = this->profileList->mhzMap[profile][module];
if (storedValue == 0) { if (storedValue == 0) {
listItem->setValue(FREQ_DEFAULT_TEXT); listItem->setValue(FREQ_DEFAULT_TEXT);
@@ -177,7 +178,6 @@ void AppProfileGui::addModuleListItemValue(
} }
listItem->setValue(buf); listItem->setValue(buf);
} }
listItem->setClickListener( listItem->setClickListener(
[this, [this,
listItem, listItem,
@@ -190,13 +190,13 @@ void AppProfileGui::addModuleListItemValue(
suffix, suffix,
divisor, divisor,
decimalPlaces, decimalPlaces,
thresholds](u64 keys) thresholds,
namedValues](u64 keys)
{ {
if ((keys & HidNpadButton_A) == HidNpadButton_A) if ((keys & HidNpadButton_A) == HidNpadButton_A)
{ {
std::uint32_t currentValue = std::uint32_t currentValue =
this->profileList->mhzMap[profile][module] * divisor; this->profileList->mhzMap[profile][module] * divisor;
ValueRange range( ValueRange range(
min, min,
max, max,
@@ -205,17 +205,14 @@ void AppProfileGui::addModuleListItemValue(
divisor, divisor,
decimalPlaces decimalPlaces
); );
this->openValueChoiceGui( this->openValueChoiceGui(
listItem, listItem,
currentValue, currentValue,
range, range,
categoryName, categoryName,
[this, listItem, profile, module, divisor, suffix, decimalPlaces, thresholds](std::uint32_t value) -> bool [this, listItem, profile, module, divisor, suffix, decimalPlaces, thresholds](std::uint32_t value) -> bool
{ {
this->profileList->mhzMap[profile][module] = value / divisor; this->profileList->mhzMap[profile][module] = value / divisor;
if (value == 0) { if (value == 0) {
listItem->setValue(FREQ_DEFAULT_TEXT); listItem->setValue(FREQ_DEFAULT_TEXT);
} else { } else {
@@ -230,11 +227,9 @@ void AppProfileGui::addModuleListItemValue(
} }
listItem->setValue(buf); listItem->setValue(buf);
} }
Result rc = Result rc =
sysclkIpcSetProfiles(this->applicationId, sysclkIpcSetProfiles(this->applicationId,
this->profileList); this->profileList);
if (R_FAILED(rc)) if (R_FAILED(rc))
{ {
FatalGui::openWithResultCode( FatalGui::openWithResultCode(
@@ -243,34 +238,30 @@ void AppProfileGui::addModuleListItemValue(
} }
return true; return true;
}, },
thresholds, thresholds,
false false,
{},
namedValues,
true
); );
return true; return true;
} }
else if ((keys & HidNpadButton_Y) == HidNpadButton_Y) else if ((keys & HidNpadButton_Y) == HidNpadButton_Y)
{ {
this->profileList->mhzMap[profile][module] = 0; this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(FREQ_DEFAULT_TEXT); listItem->setValue(FREQ_DEFAULT_TEXT);
Result rc = Result rc =
sysclkIpcSetProfiles(this->applicationId, sysclkIpcSetProfiles(this->applicationId,
this->profileList); this->profileList);
if (R_FAILED(rc)) if (R_FAILED(rc))
{ {
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc); FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
return false; return false;
} }
return true; return true;
} }
return false; return false;
}); });
this->listElement->addItem(listItem); this->listElement->addItem(listItem);
} }
@@ -279,7 +270,7 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
BaseMenuGui::refresh(); BaseMenuGui::refresh();
if(!this->context) if(!this->context)
return; return;
Result rc = sysclkIpcGetConfigValues(&configList); // idk why this is needed, probably some refreshing issue Result rc = sysclkIpcGetConfigValues(&configList);
if (R_FAILED(rc)) [[unlikely]] { if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc); FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return; return;
@@ -291,10 +282,77 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
#if IS_MINIMAL == 0 #if IS_MINIMAL == 0
ValueThresholds lcdThresholds(60, 65); ValueThresholds lcdThresholds(60, 65);
if(!IsHoag() && configList.values[HorizonOCConfigValue_OverwriteRefreshRate]) { if(!IsHoag() && configList.values[HorizonOCConfigValue_OverwriteRefreshRate]) {
if(profile != SysClkProfile_Docked) if(profile != SysClkProfile_Docked) {
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds); this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
else } else {
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, IsAula() ? this->context->isSysDockInstalled ? 120 : 75 : 120, 5, " Hz", 1, 0); if(IsAula() && this->context->isSysDockInstalled) {
std::vector<NamedValue> dockedFreqs = {
NamedValue("40 Hz", 40),
NamedValue("45 Hz", 45),
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75),
NamedValue("80 Hz", 80),
NamedValue("90 Hz", 90),
NamedValue("95 Hz", 95),
NamedValue("100 Hz", 100),
NamedValue("110 Hz", 110),
NamedValue("120 Hz", 120),
NamedValue("130 Hz", 130),
NamedValue("140 Hz", 140),
NamedValue("144 Hz", 144),
NamedValue("150 Hz", 150),
NamedValue("160 Hz", 160),
NamedValue("165 Hz", 165),
NamedValue("170 Hz", 170),
NamedValue("180 Hz", 180),
NamedValue("190 Hz", 190),
NamedValue("200 Hz", 200),
NamedValue("210 Hz", 210),
NamedValue("220 Hz", 220),
NamedValue("230 Hz", 230),
NamedValue("240 Hz", 240)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, 240, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqs);
} else if (IsAula() && !this->context->isSysDockInstalled) {
std::vector<NamedValue> dockedFreqsLimited = {
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("65 Hz", 65),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 75, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsLimited);
} else {
std::vector<NamedValue> dockedFreqsStandard = {
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("65 Hz", 65),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75),
NamedValue("80 Hz", 80),
NamedValue("85 Hz", 85),
NamedValue("90 Hz", 90),
NamedValue("95 Hz", 95),
NamedValue("100 Hz", 100),
NamedValue("105 Hz", 105),
NamedValue("110 Hz", 110),
NamedValue("115 Hz", 115),
NamedValue("120 Hz", 120)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsStandard);
}
}
} }
#endif #endif
this->addModuleListItemToggle(profile, HorizonOCModule_Governor); this->addModuleListItemToggle(profile, HorizonOCModule_Governor);

View File

@@ -64,7 +64,8 @@ class AppProfileGui : public BaseMenuGui
const std::string& suffix, const std::string& suffix,
std::uint32_t divisor, std::uint32_t divisor,
int decimalPlaces, int decimalPlaces,
ValueThresholds thresholds = {} ValueThresholds thresholds,
std::vector<NamedValue> namedValues = {}
); );
void addProfileUI(SysClkProfile profile); void addProfileUI(SysClkProfile profile);

View File

@@ -118,32 +118,32 @@ void FreqChoiceGui::listUI()
std::uint32_t hz = this->hzList[i]; std::uint32_t hz = this->hzList[i];
uint32_t mhz = hz / 1000000; uint32_t mhz = hz / 1000000;
if (checkMax && IsMariko()) { // if (checkMax && IsMariko()) {
if (moduleName == "cpu" && // if (moduleName == "cpu" &&
this->configList->values[HocClkConfigValue_MarikoMaxCpuClock] < mhz) // this->configList->values[HocClkConfigValue_MarikoMaxCpuClock] < mhz)
continue; // continue;
// if (moduleName == "gpu" && // // if (moduleName == "gpu" &&
// this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz) // // this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz)
// continue; // // continue;
// if (moduleName == "mem" && // // if (moduleName == "mem" &&
// this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz) // // this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz)
// continue; // // continue;
} else if (checkMax && IsErista()) { // } else if (checkMax && IsErista()) {
if (moduleName == "cpu" && // if (moduleName == "cpu" &&
this->configList->values[HocClkConfigValue_EristaMaxCpuClock] < mhz) // this->configList->values[HocClkConfigValue_EristaMaxCpuClock] < mhz)
continue; // continue;
// if (moduleName == "gpu" && // // if (moduleName == "gpu" &&
// this->configList->values[HocClkConfigValue_EristaMaxGpuClock] < mhz) // // this->configList->values[HocClkConfigValue_EristaMaxGpuClock] < mhz)
// continue; // // continue;
// if (moduleName == "mem" && // // if (moduleName == "mem" &&
// this->configList->values[HocClkConfigValue_EristaMaxMemClock] < mhz) // // this->configList->values[HocClkConfigValue_EristaMaxMemClock] < mhz)
// continue; // // continue;
} // }
if (moduleName == "mem" && mhz <= 600) if (moduleName == "mem" && mhz <= 600)
continue; continue;

View File

@@ -239,15 +239,22 @@ void MiscGui::addFreqButton(SysClkConfigValue configVal,
void MiscGui::listUI() void MiscGui::listUI()
{ {
Result rc = sysclkIpcGetConfigValues(configList);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
ValueThresholds thresholdsDisabled(0, 0); ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> noNamedValues = {}; std::vector<NamedValue> noNamedValues = {};
this->listElement->addItem(new tsl::elm::CategoryHeader("Settings")); this->listElement->addItem(new tsl::elm::CategoryHeader("Settings"));
addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr);
addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr); addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr);
this->listElement->addItem(new tsl::elm::CategoryHeader("Safety Settings"));
addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr);
addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr); addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr);
addConfigToggle(HocClkConfigValue_HandheldTDP, nullptr); addConfigToggle(HocClkConfigValue_HandheldTDP, nullptr);
// addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr); // addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr);
@@ -289,13 +296,8 @@ void MiscGui::listUI()
); );
#endif #endif
if(IsMariko()) {
addFreqButton(HocClkConfigValue_MarikoMaxCpuClock, nullptr, SysClkModule_CPU, cpu_freq_label_m);
} else {
addFreqButton(HocClkConfigValue_EristaMaxCpuClock, nullptr, SysClkModule_CPU, cpu_freq_label_e);
}
if (IsMariko()) { if (IsMariko()) {
this->listElement->addItem(new tsl::elm::CategoryHeader("DVFS"));
std::vector<NamedValue> dvfsValues = { std::vector<NamedValue> dvfsValues = {
NamedValue("Disabled", DVFSMode_Disabled), NamedValue("Disabled", DVFSMode_Disabled),
NamedValue("PCV Hijack", DVFSMode_Hijack), NamedValue("PCV Hijack", DVFSMode_Hijack),
@@ -331,8 +333,20 @@ void MiscGui::listUI()
}; };
addConfigButton(HorizonOCConfigValue_DVFSOffset, "GPU DVFS Offset", ValueRange(0, 12, 1, "", 0), "GPU DVFS Offset", &thresholdsDisabled, {}, dvfsOffset, false); addConfigButton(HorizonOCConfigValue_DVFSOffset, "GPU DVFS Offset", ValueRange(0, 12, 1, "", 0), "GPU DVFS Offset", &thresholdsDisabled, {}, dvfsOffset, false);
} }
this->listElement->addItem(new tsl::elm::CategoryHeader("Display"));
addConfigToggle(HorizonOCConfigValue_OverwriteRefreshRate, nullptr);
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Enabling unsafe display", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("refresh rates may cause stress", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
renderer->drawString("or damage to your display! ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
});
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 110);
this->listElement->addItem(warningText);
addConfigToggle(HorizonOCConfigValue_EnableUnsafeDisplayFreqs, nullptr);
this->listElement->addItem(new tsl::elm::CategoryHeader("KIP")); this->listElement->addItem(new tsl::elm::CategoryHeader("KIP"));
@@ -394,92 +408,92 @@ void MiscGui::listUI()
// NamedValue("2816mA", 2816), // NamedValue("2816mA", 2816),
// NamedValue("3072mA", 3072), // NamedValue("3072mA", 3072),
// }; // };
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); if(this->configList->values[HorizonOCConfigValue_EnableExperimentalSettings]) {
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
std::vector<NamedValue> gpuSchedValues = {
NamedValue("Do not override", GpuSchedulingMode_DoNotOverride), std::vector<NamedValue> gpuSchedValues = {
NamedValue("Enabled", GpuSchedulingMode_Enabled, "96.5% limit"), NamedValue("Do not override", GpuSchedulingMode_DoNotOverride),
NamedValue("Disabled", GpuSchedulingMode_Disabled, "99.7% limit"), 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); tsl::elm::CustomDrawer* gpuSchedInfoText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("to take effect", false, x + 20, y + 50, 18, tsl::style::color::ColorText); 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()) {
// std::vector<NamedValue> chargerCurrents = {
// NamedValue("Disabled", 0),
// NamedValue("1024mA", 1024),
// NamedValue("1280mA", 1280),
// NamedValue("1536mA", 1536),
// NamedValue("1792mA", 1792),
// NamedValue("2048mA", 2048),
// NamedValue("2304mA", 2304),
// NamedValue("2560mA", 2560),
// NamedValue("2816mA", 2816),
// NamedValue("3072mA", 3072),
// };
// ValueThresholds chargerThresholds(2048, 2560);
// addConfigButton(
// HorizonOCConfigValue_BatteryChargeCurrent,
// "Charge Current Override",
// ValueRange(0, 0, 1, "", 0),
// "Charge Current Override",
// &chargerThresholds,
// {},
// chargerCurrents,
// false
// );
addConfigToggle(HorizonOCConfigValue_OverwriteRefreshRate, nullptr);
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Enabling unsafe display", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("refresh rates may cause stress", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
renderer->drawString("or damage to your display! ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
}); });
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 110); gpuSchedInfoText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70);
this->listElement->addItem(warningText); this->listElement->addItem(gpuSchedInfoText);
addConfigToggle(HorizonOCConfigValue_EnableUnsafeDisplayFreqs, nullptr); addConfigButton(
HorizonOCConfigValue_GPUScheduling,
"GPU Scheduling Override",
ValueRange(0, 0, 1, "", 0),
"GPU Scheduling Override",
&thresholdsDisabled,
{},
gpuSchedValues,
false
);
tsl::elm::CustomDrawer* chargeWarningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Overriding the charge current", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("can be dangerous and may cause", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
renderer->drawString("damage to your battery or charger!", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
});
chargeWarningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 90);
this->listElement->addItem(chargeWarningText);
if(!IsHoag()) {
std::vector<NamedValue> chargerCurrents = {
NamedValue("Disabled", 0),
NamedValue("1024mA", 1024),
NamedValue("1280mA", 1280),
NamedValue("1536mA", 1536),
NamedValue("1792mA", 1792),
NamedValue("2048mA", 2048),
NamedValue("2304mA", 2304),
NamedValue("2560mA", 2560),
NamedValue("2816mA", 2816),
NamedValue("3072mA", 3072),
};
ValueThresholds chargerThresholds(2048, 2049);
addConfigButton(
HorizonOCConfigValue_BatteryChargeCurrent,
"Charge Current Override",
ValueRange(0, 0, 1, "", 0),
"Charge Current Override",
&chargerThresholds,
{},
chargerCurrents,
false
);
}
else {
std::vector<NamedValue> chargerCurrents = {
NamedValue("Disabled", 0),
NamedValue("1024mA", 1024),
NamedValue("1280mA", 1280),
NamedValue("1536mA", 1536),
NamedValue("1792mA", 1792),
NamedValue("2048mA", 2048),
NamedValue("2304mA", 2304),
NamedValue("2560mA", 2560),
};
ValueThresholds chargerThresholds(1792, 1793);
addConfigButton(
HorizonOCConfigValue_BatteryChargeCurrent,
"Charge Current Override",
ValueRange(0, 0, 1, "", 0),
"Charge Current Override",
&chargerThresholds,
{},
chargerCurrents,
false
);
}
} }
// else {
// std::vector<NamedValue> chargerCurrents = {
// NamedValue("Disabled", 0),
// NamedValue("1024mA", 1024),
// NamedValue("1280mA", 1280),
// NamedValue("1536mA", 1536),
// NamedValue("1792mA", 1792),
// NamedValue("2048mA", 2048),
// NamedValue("2304mA", 2304),
// NamedValue("2560mA", 2560),
// };
// ValueThresholds chargerThresholds(1792, 2048);
// addConfigButton(
// HorizonOCConfigValue_BatteryChargeCurrent,
// "Charge Current Override",
// ValueRange(0, 0, 1, "", 0),
// "Charge Current Override",
// &chargerThresholds,
// {},
// chargerCurrents,
// false
// );
// }
#endif #endif
} }

View File

@@ -30,7 +30,8 @@ ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
bool enableThresholds, bool enableThresholds,
std::map<std::uint32_t, std::string> labels, std::map<std::uint32_t, std::string> labels,
std::vector<NamedValue> namedValues, std::vector<NamedValue> namedValues,
bool showDefaultValue) bool showDefaultValue,
bool showDNO)
: selectedValue(selectedValue), : selectedValue(selectedValue),
range(range), range(range),
categoryName(categoryName), categoryName(categoryName),
@@ -39,7 +40,8 @@ ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
enableThresholds(enableThresholds), enableThresholds(enableThresholds),
labels(labels), labels(labels),
namedValues(namedValues), namedValues(namedValues),
showDefaultValue(showDefaultValue) showDefaultValue(showDefaultValue),
showDNO(showDNO)
{ {
} }
@@ -52,7 +54,7 @@ std::string ValueChoiceGui::formatValue(std::uint32_t value)
std::ostringstream oss; std::ostringstream oss;
if(showDefaultValue) { if(showDefaultValue) {
if (value == 0) { if (value == 0) {
return VALUE_DEFAULT_TEXT; return this->showDNO ? FREQ_DEFAULT_TEXT : VALUE_DEFAULT_TEXT;
} }
} }
double displayValue = static_cast<double>(value) / static_cast<double>(range.divisor); double displayValue = static_cast<double>(value) / static_cast<double>(range.divisor);
@@ -164,17 +166,16 @@ void ValueChoiceGui::listUI()
if (!categoryName.empty()) { if (!categoryName.empty()) {
this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName)); this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName));
} }
if (showDefaultValue) {
this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
}
for (const auto& namedValue : namedValues) { for (const auto& namedValue : namedValues) {
int safety = enableThresholds ? getSafetyLevel(namedValue.value) : 0; int safety = enableThresholds ? getSafetyLevel(namedValue.value) : 0;
bool selected = (namedValue.value == this->selectedValue); bool selected = (namedValue.value == this->selectedValue);
this->listElement->addItem(this->createNamedValueListItem(namedValue, selected, safety)); this->listElement->addItem(this->createNamedValueListItem(namedValue, selected, safety));
} }
if (showDefaultValue) {
this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
}
if (namedValues.empty()) { if (namedValues.empty()) {
for (std::uint32_t value = range.min; value <= range.max; value += range.step) for (std::uint32_t value = range.min; value <= range.max; value += range.step)
{ {

View File

@@ -71,7 +71,7 @@ protected:
std::vector<NamedValue> namedValues; std::vector<NamedValue> namedValues;
bool showDefaultValue = true; bool showDefaultValue = true;
bool showDNO = false;
tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety); tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety);
tsl::elm::ListItem* createNamedValueListItem(const NamedValue& namedValue, bool selected, int safety); tsl::elm::ListItem* createNamedValueListItem(const NamedValue& namedValue, bool selected, int safety);
std::string formatValue(std::uint32_t value); std::string formatValue(std::uint32_t value);
@@ -86,7 +86,8 @@ public:
bool enableThresholds = false, bool enableThresholds = false,
std::map<std::uint32_t, std::string> labels = {}, std::map<std::uint32_t, std::string> labels = {},
std::vector<NamedValue> namedValues = {}, std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true); bool showDefaultValue = true,
bool showDNO = false);
~ValueChoiceGui(); ~ValueChoiceGui();
void addNamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "") void addNamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "")

View File

@@ -39,7 +39,6 @@
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <crc32.h> #include <crc32.h>
#include <sys/stat.h>
#define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0)) #define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0))
bool isGovernorEnabled = false; // to avoid thread messes bool isGovernorEnabled = false; // to avoid thread messes
@@ -90,7 +89,7 @@ ClockManager::ClockManager()
this->lastTempLogNs = 0; this->lastTempLogNs = 0;
this->lastCsvWriteNs = 0; this->lastCsvWriteNs = 0;
this->rnxSync = new ReverseNXSync; this->sysDockIntegration = new SysDockIntegration;
memset(&initialConfigValues, 0, sizeof(initialConfigValues)); memset(&initialConfigValues, 0, sizeof(initialConfigValues));
this->GetKipData(); this->GetKipData();
threadCreate( threadCreate(
@@ -115,13 +114,7 @@ ClockManager::ClockManager()
previousRamHz = Board::GetHz(SysClkModule_MEM); previousRamHz = Board::GetHz(SysClkModule_MEM);
Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling)); Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling));
this->context->gpuSchedulingMode = (GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling); this->context->gpuSchedulingMode = (GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling);
this->context->isSysDockInstalled = this->sysDockIntegration->getCurrentSysDockState();
struct stat st = {0};
if (stat("sdmc:/atmosphere/contents/42000000000000A0", &st) == 0 && S_ISDIR(st.st_mode)) {
this->context->isSysDockInstalled = true;
} else {
this->context->isSysDockInstalled = false;
}
} }
ClockManager::~ClockManager() ClockManager::~ClockManager()
@@ -615,7 +608,6 @@ bool ClockManager::RefreshContext()
FileUtils::LogLine("[mgr] TitleID change: %016lX", applicationId); FileUtils::LogLine("[mgr] TitleID change: %016lX", applicationId);
this->context->applicationId = applicationId; this->context->applicationId = applicationId;
hasChanged = true; hasChanged = true;
this->rnxSync->Reset(applicationId);
} }
SysClkProfile profile = Board::GetProfile(); SysClkProfile profile = Board::GetProfile();
@@ -629,7 +621,6 @@ bool ClockManager::RefreshContext()
// restore clocks to stock values on app or profile change // restore clocks to stock values on app or profile change
if (hasChanged) if (hasChanged)
{ {
// this->rnxSync->ToggleSync(this->GetConfig()->GetConfigValue(HocClkConfigValue_SyncReverseNXMode));
Board::ResetToStock(); Board::ResetToStock();
if (Board::GetSocType() == SysClkSocType_Mariko && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) { if (Board::GetSocType() == SysClkSocType_Mariko && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) {
Board::PcvHijackDvfs(0); Board::PcvHijackDvfs(0);
@@ -773,11 +764,6 @@ bool ClockManager::RefreshContext()
return hasChanged; return hasChanged;
} }
void ClockManager::SetRNXRTMode(ReverseNXMode mode)
{
this->rnxSync->SetRTMode(mode);
}
void ClockManager::SetKipData() { void ClockManager::SetKipData() {
// TODO: figure out if this REALLY causes issues (i doubt it) // TODO: figure out if this REALLY causes issues (i doubt it)
// if(Board::GetSocType() == SysClkSocType_Mariko) { // if(Board::GetSocType() == SysClkSocType_Mariko) {

View File

@@ -37,7 +37,7 @@
#include "integrations.h" #include "integrations.h"
void governorThread(void*); void governorThread(void*);
class ReverseNXSync; class SysDockIntegration;
class ClockManager class ClockManager
{ {
@@ -58,7 +58,6 @@ class ClockManager
void Tick(); void Tick();
void ResetToStockClocks(); void ResetToStockClocks();
void WaitForNextTick(); void WaitForNextTick();
void SetRNXRTMode(ReverseNXMode mode);
void SetKipData(); void SetKipData();
void GetKipData(); void GetKipData();
static void GovernorThread(void* arg); static void GovernorThread(void* arg);
@@ -87,5 +86,5 @@ class ClockManager
std::uint64_t lastFreqLogNs; std::uint64_t lastFreqLogNs;
std::uint64_t lastPowerLogNs; std::uint64_t lastPowerLogNs;
std::uint64_t lastCsvWriteNs; std::uint64_t lastCsvWriteNs;
ReverseNXSync *rnxSync; SysDockIntegration *sysDockIntegration;
}; };

View File

@@ -17,68 +17,16 @@
#include "integrations.h" #include "integrations.h"
#include <sys/stat.h>
ReverseNXSync::ReverseNXSync() SysDockIntegration::SysDockIntegration() {
: m_rt_mode(ReverseNX_NotFound), m_tool_mode(ReverseNX_NotFound) {
FILE *fp = fopen("/atmosphere/contents/0000000000534C56/flags/boot2.flag", "r");
m_tool_enabled = fp ? true : false;
if (fp)
fclose(fp);
} }
SysClkProfile ReverseNXSync::GetProfile(SysClkProfile real) { bool SysDockIntegration::getCurrentSysDockState() {
switch (this->GetMode()) { struct stat st = {0};
case ReverseNX_Docked: if (stat("sdmc:/atmosphere/contents/42000000000000A0", &st) == 0 && S_ISDIR(st.st_mode)) {
return SysClkProfile_Docked; return true;
case ReverseNX_Handheld: } else {
if (real == SysClkProfile_Docked) return false;
return SysClkProfile_HandheldChargingOfficial;
default:
return real;
} }
}
ReverseNXMode ReverseNXSync::GetMode() {
if (!this->m_sync_enabled)
return ReverseNX_NotFound;
if (this->m_rt_mode)
return this->m_rt_mode;
return this->m_tool_mode;
}
ReverseNXMode ReverseNXSync::GetToolModeFromPatch(const char* patch_path) {
constexpr uint32_t DOCKED_MAGIC = 0x320003E0;
constexpr uint32_t HANDHELD_MAGIC = 0x52A00000;
FILE *fp = fopen(patch_path, "rb");
if (fp) {
uint32_t buf = 0;
fread(&buf, sizeof(buf), 1, fp);
fclose(fp);
if (buf == DOCKED_MAGIC)
return ReverseNX_Docked;
if (buf == HANDHELD_MAGIC)
return ReverseNX_Handheld;
}
return ReverseNX_NotFound;
}
ReverseNXMode ReverseNXSync::RecheckToolMode() {
ReverseNXMode mode = ReverseNX_NotFound;
if (this->m_tool_enabled) {
const char* fileName = "_ZN2nn2oe18GetPerformanceModeEv.asm64"; // or _ZN2nn2oe18GetPerformanceModeEv.asm64
const char* filePath = new char[72];
SCOPE_EXIT { delete[] filePath; };
/* Check per-game patch */
snprintf((char*)filePath, 72, "/SaltySD/patches/%016lX/%s", this->m_app_id, fileName);
mode = this->GetToolModeFromPatch(filePath);
if (!mode) {
/* Check global patch */
snprintf((char*)filePath, 72, "/SaltySD/patches/%s", fileName);
mode = this->GetToolModeFromPatch(filePath);
}
}
return mode;
} }

View File

@@ -29,25 +29,9 @@
#include "clock_manager.h" #include "clock_manager.h"
class ReverseNXSync { class SysDockIntegration {
public: public:
ReverseNXSync (); SysDockIntegration();
void ToggleSync(bool enable) { m_sync_enabled = enable; }; bool getCurrentSysDockState();
void Reset(uint64_t app_id) { m_app_id = app_id; SetRTMode(ReverseNX_NotFound); GetToolMode(); }
ReverseNXMode GetRTMode() { return m_rt_mode; };
void SetRTMode(ReverseNXMode mode) { m_rt_mode = mode; };
ReverseNXMode GetToolMode() { return m_tool_mode = RecheckToolMode(); };
SysClkProfile GetProfile(SysClkProfile real);
ReverseNXMode GetMode();
protected:
std::atomic<ReverseNXMode> m_rt_mode;
ReverseNXMode m_tool_mode;
uint64_t m_app_id = 0;
bool m_tool_enabled;
bool m_sync_enabled;
ReverseNXMode GetToolModeFromPatch(const char* patch_path);
ReverseNXMode RecheckToolMode();
}; };

View File

@@ -198,12 +198,6 @@ Result IpcService::ServiceHandlerFunc(void* arg, const IpcServerRequest* r, u8*
); );
} }
break; break;
case SysClkIpcCmd_SetReverseNXRTMode:
if (r->data.size >= sizeof(ReverseNXMode)) {
ReverseNXMode mode = *((ReverseNXMode*)r->data.ptr);
return ipcSrv->SetReverseNXRTMode(mode);
}
break;
case HocClkIpcCmd_SetKipData: case HocClkIpcCmd_SetKipData:
if (r->data.size >= 0) { if (r->data.size >= 0) {
return ipcSrv->SetKipData(); return ipcSrv->SetKipData();
@@ -361,10 +355,6 @@ Result IpcService::GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t*
return 0; return 0;
} }
Result IpcService::SetReverseNXRTMode(ReverseNXMode mode) {
return 0;
}
Result IpcService::SetKipData() { Result IpcService::SetKipData() {
this->clockMgr->SetKipData(); this->clockMgr->SetKipData();

View File

@@ -54,7 +54,6 @@ class IpcService
Result GetConfigValues(SysClkConfigValueList* out_configValues); Result GetConfigValues(SysClkConfigValueList* out_configValues);
Result SetConfigValues(SysClkConfigValueList* configValues); Result SetConfigValues(SysClkConfigValueList* configValues);
Result GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t* out_list, std::size_t size, std::uint32_t* out_count); Result GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t* out_list, std::size_t size, std::uint32_t* out_count);
Result SetReverseNXRTMode(ReverseNXMode mode);
Result SetKipData(); Result SetKipData();
Result GetKipData(); Result GetKipData();
bool running; bool running;