sysclk: finish display refresh rate change support
This commit is contained in:
@@ -77,7 +77,7 @@ typedef enum
|
|||||||
SysClkModule_GPU,
|
SysClkModule_GPU,
|
||||||
SysClkModule_MEM,
|
SysClkModule_MEM,
|
||||||
HorizonOCModule_Governor,
|
HorizonOCModule_Governor,
|
||||||
HorizonOCModule_LCD,
|
HorizonOCModule_Display,
|
||||||
SysClkModule_EnumMax,
|
SysClkModule_EnumMax,
|
||||||
} SysClkModule;
|
} SysClkModule;
|
||||||
|
|
||||||
@@ -131,6 +131,8 @@ static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
|
|||||||
return pretty ? "GPU" : "gpu";
|
return pretty ? "GPU" : "gpu";
|
||||||
case SysClkModule_MEM:
|
case SysClkModule_MEM:
|
||||||
return pretty ? "Memory" : "mem";
|
return pretty ? "Memory" : "mem";
|
||||||
|
case HorizonOCModule_Display:
|
||||||
|
return pretty ? "Display" : "display";
|
||||||
case HorizonOCModule_Governor:
|
case HorizonOCModule_Governor:
|
||||||
return pretty ? "Governor" : "gov";
|
return pretty ? "Governor" : "gov";
|
||||||
default:
|
default:
|
||||||
@@ -148,6 +150,11 @@ static inline const char* sysclkFormatThermalSensor(SysClkThermalSensor thermSen
|
|||||||
return pretty ? "PCB" : "pcb";
|
return pretty ? "PCB" : "pcb";
|
||||||
case SysClkThermalSensor_Skin:
|
case SysClkThermalSensor_Skin:
|
||||||
return pretty ? "Skin" : "skin";
|
return pretty ? "Skin" : "skin";
|
||||||
|
case HorizonOCThermalSensor_Battery:
|
||||||
|
return pretty ? "BAT" : "battery";
|
||||||
|
case HorizonOCThermalSensor_PMIC:
|
||||||
|
return pretty ? "PMIC" : "pmic";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
#define FREQ_DEFAULT_TEXT "Default"
|
#define FREQ_DEFAULT_TEXT "Default"
|
||||||
|
|
||||||
static inline std::string formatListFreqMHz(std::uint32_t mhz)
|
static inline std::string formatListFreqMHz(std::uint32_t mhz)
|
||||||
|
|||||||
@@ -67,6 +67,32 @@ void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfil
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppProfileGui::openValueChoiceGui(
|
||||||
|
tsl::elm::ListItem* listItem,
|
||||||
|
std::uint32_t currentValue,
|
||||||
|
const ValueRange& range,
|
||||||
|
const std::string& categoryName,
|
||||||
|
ValueChoiceListener listener,
|
||||||
|
const ValueThresholds& thresholds,
|
||||||
|
bool enableThresholds,
|
||||||
|
const std::map<std::uint32_t, std::string>& labels,
|
||||||
|
const std::vector<NamedValue>& namedValues,
|
||||||
|
bool showDefaultValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tsl::changeTo<ValueChoiceGui>(
|
||||||
|
currentValue,
|
||||||
|
range,
|
||||||
|
categoryName,
|
||||||
|
listener,
|
||||||
|
thresholds,
|
||||||
|
enableThresholds,
|
||||||
|
labels,
|
||||||
|
namedValues,
|
||||||
|
showDefaultValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void AppProfileGui::addModuleListItem(SysClkProfile profile, SysClkModule module)
|
void AppProfileGui::addModuleListItem(SysClkProfile profile, SysClkModule module)
|
||||||
{
|
{
|
||||||
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(sysclkFormatModule(module, true));
|
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(sysclkFormatModule(module, true));
|
||||||
@@ -83,7 +109,6 @@ void AppProfileGui::addModuleListItem(SysClkProfile profile, SysClkModule module
|
|||||||
this->profileList->mhzMap[profile][module] = 0;
|
this->profileList->mhzMap[profile][module] = 0;
|
||||||
listItem->setValue(formatListFreqMHz(0));
|
listItem->setValue(formatListFreqMHz(0));
|
||||||
|
|
||||||
// Save the updated profile
|
|
||||||
Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList);
|
Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList);
|
||||||
if(R_FAILED(rc))
|
if(R_FAILED(rc))
|
||||||
{
|
{
|
||||||
@@ -117,12 +142,137 @@ void AppProfileGui::addModuleListItemToggle(SysClkProfile profile, SysClkModule
|
|||||||
this->listElement->addItem(toggle);
|
this->listElement->addItem(toggle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppProfileGui::addModuleListItemValue(
|
||||||
|
SysClkProfile profile,
|
||||||
|
SysClkModule module,
|
||||||
|
const std::string& categoryName,
|
||||||
|
std::uint32_t min,
|
||||||
|
std::uint32_t max,
|
||||||
|
std::uint32_t step,
|
||||||
|
const std::string& suffix,
|
||||||
|
std::uint32_t divisor,
|
||||||
|
int decimalPlaces
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tsl::elm::ListItem* listItem =
|
||||||
|
new tsl::elm::ListItem(sysclkFormatModule(module, true));
|
||||||
|
|
||||||
|
std::uint32_t storedValue = this->profileList->mhzMap[profile][module];
|
||||||
|
if (storedValue == 0) {
|
||||||
|
listItem->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
} else {
|
||||||
|
char buf[32];
|
||||||
|
if (decimalPlaces > 0) {
|
||||||
|
double displayValue = (double)storedValue / divisor;
|
||||||
|
snprintf(buf, sizeof(buf), "%.*f%s", decimalPlaces, displayValue, suffix.c_str());
|
||||||
|
} else {
|
||||||
|
snprintf(buf, sizeof(buf), "%u%s", storedValue / divisor, suffix.c_str());
|
||||||
|
}
|
||||||
|
listItem->setValue(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
listItem->setClickListener(
|
||||||
|
[this,
|
||||||
|
listItem,
|
||||||
|
profile,
|
||||||
|
module,
|
||||||
|
categoryName,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
suffix,
|
||||||
|
divisor,
|
||||||
|
decimalPlaces](u64 keys)
|
||||||
|
{
|
||||||
|
if ((keys & HidNpadButton_A) == HidNpadButton_A)
|
||||||
|
{
|
||||||
|
std::uint32_t currentValue =
|
||||||
|
this->profileList->mhzMap[profile][module] * divisor;
|
||||||
|
|
||||||
|
ValueRange range(
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
suffix,
|
||||||
|
divisor,
|
||||||
|
decimalPlaces
|
||||||
|
);
|
||||||
|
|
||||||
|
this->openValueChoiceGui(
|
||||||
|
listItem,
|
||||||
|
currentValue,
|
||||||
|
range,
|
||||||
|
categoryName,
|
||||||
|
|
||||||
|
[this, listItem, profile, module, divisor, suffix, decimalPlaces](std::uint32_t value) -> bool
|
||||||
|
{
|
||||||
|
this->profileList->mhzMap[profile][module] = value / divisor;
|
||||||
|
|
||||||
|
if (value == 0) {
|
||||||
|
listItem->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
} else {
|
||||||
|
char buf[32];
|
||||||
|
if (decimalPlaces > 0) {
|
||||||
|
double displayValue = (double)value / divisor;
|
||||||
|
snprintf(buf, sizeof(buf), "%.*f%s",
|
||||||
|
decimalPlaces, displayValue, suffix.c_str());
|
||||||
|
} else {
|
||||||
|
snprintf(buf, sizeof(buf), "%u%s",
|
||||||
|
value / divisor, suffix.c_str());
|
||||||
|
}
|
||||||
|
listItem->setValue(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc =
|
||||||
|
sysclkIpcSetProfiles(this->applicationId,
|
||||||
|
this->profileList);
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
{
|
||||||
|
FatalGui::openWithResultCode(
|
||||||
|
"sysclkIpcSetProfiles", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
ValueThresholds(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if ((keys & HidNpadButton_Y) == HidNpadButton_Y)
|
||||||
|
{
|
||||||
|
this->profileList->mhzMap[profile][module] = 0;
|
||||||
|
listItem->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
|
||||||
|
Result rc =
|
||||||
|
sysclkIpcSetProfiles(this->applicationId,
|
||||||
|
this->profileList);
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
{
|
||||||
|
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this->listElement->addItem(listItem);
|
||||||
|
}
|
||||||
|
|
||||||
void AppProfileGui::addProfileUI(SysClkProfile profile)
|
void AppProfileGui::addProfileUI(SysClkProfile profile)
|
||||||
{
|
{
|
||||||
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true) + std::string(" ") + ult::DIVIDER_SYMBOL + " Reset"));
|
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true) + std::string(" ") + ult::DIVIDER_SYMBOL + " Reset"));
|
||||||
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, 60, 5, " Hz", 1, 0);
|
||||||
this->addModuleListItemToggle(profile, HorizonOCModule_Governor);
|
this->addModuleListItemToggle(profile, HorizonOCModule_Governor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "../../ipc.h"
|
#include "../../ipc.h"
|
||||||
#include "base_menu_gui.h"
|
#include "base_menu_gui.h"
|
||||||
#include "freq_choice_gui.h"
|
#include "freq_choice_gui.h"
|
||||||
|
#include "value_choice_gui.h"
|
||||||
#define SYSCLK_GLOBAL_PROFILE_TID 0xA111111111111111
|
#define SYSCLK_GLOBAL_PROFILE_TID 0xA111111111111111
|
||||||
|
|
||||||
class AppProfileGui : public BaseMenuGui
|
class AppProfileGui : public BaseMenuGui
|
||||||
@@ -41,6 +42,29 @@ class AppProfileGui : public BaseMenuGui
|
|||||||
void openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfile profile, SysClkModule module);
|
void openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfile profile, SysClkModule module);
|
||||||
void addModuleListItem(SysClkProfile profile, SysClkModule module);
|
void addModuleListItem(SysClkProfile profile, SysClkModule module);
|
||||||
void addModuleListItemToggle(SysClkProfile profile, SysClkModule module);
|
void addModuleListItemToggle(SysClkProfile profile, SysClkModule module);
|
||||||
|
void openValueChoiceGui(
|
||||||
|
tsl::elm::ListItem* listItem,
|
||||||
|
std::uint32_t currentValue,
|
||||||
|
const ValueRange& range,
|
||||||
|
const std::string& categoryName,
|
||||||
|
ValueChoiceListener listener,
|
||||||
|
const ValueThresholds& thresholds = ValueThresholds(),
|
||||||
|
bool enableThresholds = false,
|
||||||
|
const std::map<std::uint32_t, std::string>& labels = {},
|
||||||
|
const std::vector<NamedValue>& namedValues = {},
|
||||||
|
bool showDefaultValue = true
|
||||||
|
);
|
||||||
|
void addModuleListItemValue(
|
||||||
|
SysClkProfile profile,
|
||||||
|
SysClkModule module,
|
||||||
|
const std::string& categoryName,
|
||||||
|
std::uint32_t min,
|
||||||
|
std::uint32_t max,
|
||||||
|
std::uint32_t step,
|
||||||
|
const std::string& suffix,
|
||||||
|
std::uint32_t divisor,
|
||||||
|
int decimalPlaces
|
||||||
|
);
|
||||||
void addProfileUI(SysClkProfile profile);
|
void addProfileUI(SysClkProfile profile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
|
|||||||
|
|
||||||
// All constants pre-calculated and cached
|
// All constants pre-calculated and cached
|
||||||
static constexpr const char* const labels[] = {
|
static constexpr const char* const labels[] = {
|
||||||
"App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "BAT", "PMIC", "FAN"
|
"App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "BAT", "PMIC", "FAN", "DISP"
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1};
|
static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1};
|
||||||
@@ -163,6 +163,10 @@ 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[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimized refresh - now does all the string formatting once per second
|
// Optimized refresh - now does all the string formatting once per second
|
||||||
@@ -268,6 +272,8 @@ void BaseMenuGui::refresh()
|
|||||||
|
|
||||||
sprintf(displayStrings[24], "%u%%", context->PartLoad[HocClkPartLoad_FAN]);
|
sprintf(displayStrings[24], "%u%%", context->PartLoad[HocClkPartLoad_FAN]);
|
||||||
|
|
||||||
|
sprintf(displayStrings[25], "%u Hz", context->realFreqs[HorizonOCModule_Display]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tsl::elm::Element* BaseMenuGui::baseUI()
|
tsl::elm::Element* BaseMenuGui::baseUI()
|
||||||
|
|||||||
@@ -1,39 +1,11 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Souldbminer and Horizon OC Contributors
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
||||||
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
|
|
||||||
* wrote this file. As long as you retain this notice you can do whatever you
|
|
||||||
* want with this stuff. If you meet any of us some day, and you think this
|
|
||||||
* stuff is worth it, you can buy us a beer in return. - The sys-clk authors
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "global_override_gui.h"
|
|
||||||
|
|
||||||
#include "fatal_gui.h"
|
|
||||||
#include "../format.h"
|
#include "../format.h"
|
||||||
|
#include "fatal_gui.h"
|
||||||
|
#include "global_override_gui.h"
|
||||||
|
#include "value_choice_gui.h"
|
||||||
|
|
||||||
GlobalOverrideGui::GlobalOverrideGui()
|
GlobalOverrideGui::GlobalOverrideGui()
|
||||||
{
|
{
|
||||||
for(std::uint16_t m = 0; m < SysClkModule_EnumMax; m++)
|
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) {
|
||||||
{
|
|
||||||
this->listItems[m] = nullptr;
|
this->listItems[m] = nullptr;
|
||||||
this->listHz[m] = 0;
|
this->listHz[m] = 0;
|
||||||
}
|
}
|
||||||
@@ -43,16 +15,17 @@ void GlobalOverrideGui::openFreqChoiceGui(SysClkModule module)
|
|||||||
{
|
{
|
||||||
std::uint32_t hzList[SYSCLK_FREQ_LIST_MAX];
|
std::uint32_t hzList[SYSCLK_FREQ_LIST_MAX];
|
||||||
std::uint32_t hzCount;
|
std::uint32_t hzCount;
|
||||||
Result rc = sysclkIpcGetFreqList(module, &hzList[0], SYSCLK_FREQ_LIST_MAX, &hzCount);
|
Result rc =
|
||||||
if(R_FAILED(rc))
|
sysclkIpcGetFreqList(module, &hzList[0], SYSCLK_FREQ_LIST_MAX, &hzCount);
|
||||||
{
|
if (R_FAILED(rc)) {
|
||||||
FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc);
|
FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tsl::changeTo<FreqChoiceGui>(this->context->overrideFreqs[module], hzList, hzCount, module, [this, module](std::uint32_t hz) {
|
tsl::changeTo<FreqChoiceGui>(
|
||||||
|
this->context->overrideFreqs[module], hzList, hzCount, module,
|
||||||
|
[this, module](std::uint32_t hz) {
|
||||||
Result rc = sysclkIpcSetOverride(module, hz);
|
Result rc = sysclkIpcSetOverride(module, hz);
|
||||||
if(R_FAILED(rc))
|
if (R_FAILED(rc)) {
|
||||||
{
|
|
||||||
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
|
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -61,78 +34,228 @@ void GlobalOverrideGui::openFreqChoiceGui(SysClkModule module)
|
|||||||
this->context->overrideFreqs[module] = hz;
|
this->context->overrideFreqs[module] = hz;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}, true);
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalOverrideGui::openValueChoiceGui(
|
||||||
|
tsl::elm::ListItem* listItem,
|
||||||
|
std::uint32_t currentValue,
|
||||||
|
const ValueRange& range,
|
||||||
|
const std::string& categoryName,
|
||||||
|
ValueChoiceListener listener,
|
||||||
|
const ValueThresholds& thresholds,
|
||||||
|
bool enableThresholds,
|
||||||
|
const std::map<std::uint32_t, std::string>& labels,
|
||||||
|
const std::vector<NamedValue>& namedValues,
|
||||||
|
bool showDefaultValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tsl::changeTo<ValueChoiceGui>(
|
||||||
|
currentValue,
|
||||||
|
range,
|
||||||
|
categoryName,
|
||||||
|
listener,
|
||||||
|
thresholds,
|
||||||
|
enableThresholds,
|
||||||
|
labels,
|
||||||
|
namedValues,
|
||||||
|
showDefaultValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalOverrideGui::addModuleListItemValue(
|
||||||
|
SysClkModule module,
|
||||||
|
const std::string& categoryName,
|
||||||
|
std::uint32_t min,
|
||||||
|
std::uint32_t max,
|
||||||
|
std::uint32_t step,
|
||||||
|
const std::string& suffix,
|
||||||
|
std::uint32_t divisor,
|
||||||
|
int decimalPlaces
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
this->customFormatModules[module] = std::make_tuple(suffix, divisor, decimalPlaces);
|
||||||
|
|
||||||
|
tsl::elm::ListItem* listItem =
|
||||||
|
new tsl::elm::ListItem(sysclkFormatModule(module, true));
|
||||||
|
|
||||||
|
listItem->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
|
||||||
|
listItem->setClickListener(
|
||||||
|
[this,
|
||||||
|
listItem,
|
||||||
|
module,
|
||||||
|
categoryName,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
suffix,
|
||||||
|
divisor,
|
||||||
|
decimalPlaces](u64 keys)
|
||||||
|
{
|
||||||
|
if ((keys & HidNpadButton_A) == HidNpadButton_A)
|
||||||
|
{
|
||||||
|
if (!this->context) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t currentValue =
|
||||||
|
this->context->overrideFreqs[module] * divisor;
|
||||||
|
|
||||||
|
ValueRange range(
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
suffix,
|
||||||
|
divisor,
|
||||||
|
decimalPlaces
|
||||||
|
);
|
||||||
|
|
||||||
|
this->openValueChoiceGui(
|
||||||
|
listItem,
|
||||||
|
currentValue,
|
||||||
|
range,
|
||||||
|
categoryName,
|
||||||
|
|
||||||
|
[this, listItem, module, divisor, suffix, decimalPlaces](std::uint32_t value) -> bool
|
||||||
|
{
|
||||||
|
if (!this->context) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->context->overrideFreqs[module] = value / divisor;
|
||||||
|
this->listHz[module] = value / divisor;
|
||||||
|
|
||||||
|
if (value == 0) {
|
||||||
|
listItem->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
} else {
|
||||||
|
char buf[32];
|
||||||
|
if (decimalPlaces > 0) {
|
||||||
|
double displayValue = (double)value / divisor;
|
||||||
|
snprintf(buf, sizeof(buf), "%.*f%s",
|
||||||
|
decimalPlaces, displayValue, suffix.c_str());
|
||||||
|
} else {
|
||||||
|
snprintf(buf, sizeof(buf), "%u%s",
|
||||||
|
value / divisor, suffix.c_str());
|
||||||
|
}
|
||||||
|
listItem->setValue(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc =
|
||||||
|
sysclkIpcSetOverride(module, this->context->overrideFreqs[module]);
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
{
|
||||||
|
FatalGui::openWithResultCode(
|
||||||
|
"sysclkIpcSetOverride", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->lastContextUpdate = armGetSystemTick();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
ValueThresholds(),
|
||||||
|
false,
|
||||||
|
std::map<std::uint32_t, std::string>(),
|
||||||
|
std::vector<NamedValue>(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if ((keys & HidNpadButton_Y) == HidNpadButton_Y)
|
||||||
|
{
|
||||||
|
if (!this->context) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->context->overrideFreqs[module] = 0;
|
||||||
|
this->listHz[module] = 0;
|
||||||
|
listItem->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
|
||||||
|
Result rc = sysclkIpcSetOverride(module, 0);
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
{
|
||||||
|
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->lastContextUpdate = armGetSystemTick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this->listElement->addItem(listItem);
|
||||||
|
this->listItems[module] = listItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalOverrideGui::addModuleListItem(SysClkModule module)
|
void GlobalOverrideGui::addModuleListItem(SysClkModule module)
|
||||||
{
|
{
|
||||||
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(sysclkFormatModule(module, true));
|
tsl::elm::ListItem *listItem =
|
||||||
|
new tsl::elm::ListItem(sysclkFormatModule(module, true));
|
||||||
listItem->setValue(formatListFreqMHz(0));
|
listItem->setValue(formatListFreqMHz(0));
|
||||||
listItem->setClickListener([this, module](u64 keys) {
|
listItem->setClickListener([this, module](u64 keys) {
|
||||||
if((keys & HidNpadButton_A) == HidNpadButton_A)
|
if ((keys & HidNpadButton_A) == HidNpadButton_A) {
|
||||||
{
|
|
||||||
this->openFreqChoiceGui(module);
|
this->openFreqChoiceGui(module);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if ((keys & HidNpadButton_Y) == HidNpadButton_Y) {
|
||||||
else if((keys & HidNpadButton_Y) == HidNpadButton_Y)
|
|
||||||
{
|
|
||||||
// Reset override to "Default" (0 Hz)
|
|
||||||
Result rc = sysclkIpcSetOverride(module, 0);
|
Result rc = sysclkIpcSetOverride(module, 0);
|
||||||
if(R_FAILED(rc))
|
if (R_FAILED(rc)) {
|
||||||
{
|
|
||||||
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
|
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update context and tracking variables
|
|
||||||
this->lastContextUpdate = armGetSystemTick();
|
this->lastContextUpdate = armGetSystemTick();
|
||||||
this->context->overrideFreqs[module] = 0;
|
this->context->overrideFreqs[module] = 0;
|
||||||
this->listHz[module] = 0;
|
this->listHz[module] = 0;
|
||||||
|
|
||||||
// Update display
|
|
||||||
this->listItems[module]->setValue(formatListFreqHz(0));
|
this->listItems[module]->setValue(formatListFreqHz(0));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
this->listElement->addItem(listItem);
|
this->listElement->addItem(listItem);
|
||||||
this->listItems[module] = listItem;
|
this->listItems[module] = listItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalOverrideGui::addModuleToggleItem(SysClkModule module)
|
void GlobalOverrideGui::addModuleToggleItem(SysClkModule module)
|
||||||
{
|
{
|
||||||
const char* moduleName = sysclkFormatModule(module, true);
|
const char *moduleName = sysclkFormatModule(module, true);
|
||||||
bool isOn = this->listHz[module];
|
bool isOn = this->listHz[module];
|
||||||
|
|
||||||
// Create a ToggleListItem
|
|
||||||
tsl::elm::ToggleListItem* toggle = new tsl::elm::ToggleListItem(moduleName, isOn);
|
|
||||||
|
|
||||||
toggle->setStateChangedListener([this, module, toggle](bool state) {
|
|
||||||
|
|
||||||
|
tsl::elm::ToggleListItem *toggle =
|
||||||
|
new tsl::elm::ToggleListItem(moduleName, isOn);
|
||||||
|
|
||||||
|
toggle->setStateChangedListener([this, module, toggle](bool state) {
|
||||||
Result rc = sysclkIpcSetOverride(module, state ? 1 : 0);
|
Result rc = sysclkIpcSetOverride(module, state ? 1 : 0);
|
||||||
if(R_FAILED(rc))
|
if (R_FAILED(rc)) {
|
||||||
{
|
|
||||||
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
|
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
|
||||||
}
|
}
|
||||||
this->lastContextUpdate = armGetSystemTick();
|
this->lastContextUpdate = armGetSystemTick();
|
||||||
this->context->overrideFreqs[module] = 0;
|
this->context->overrideFreqs[module] = 0;
|
||||||
this->listHz[module] = 0;
|
this->listHz[module] = 0;
|
||||||
|
|
||||||
});
|
});
|
||||||
// Add to list and track
|
|
||||||
this->listElement->addItem(toggle);
|
this->listElement->addItem(toggle);
|
||||||
this->listItems[module] = toggle;
|
this->listItems[module] = toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GlobalOverrideGui::listUI()
|
void GlobalOverrideGui::listUI()
|
||||||
{
|
{
|
||||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Temporary Overrides " + ult::DIVIDER_SYMBOL + " Reset"));
|
this->listElement->addItem(new tsl::elm::CategoryHeader(
|
||||||
|
"Temporary Overrides " + ult::DIVIDER_SYMBOL + " Reset"));
|
||||||
this->addModuleListItem(SysClkModule_CPU);
|
this->addModuleListItem(SysClkModule_CPU);
|
||||||
this->addModuleListItem(SysClkModule_GPU);
|
this->addModuleListItem(SysClkModule_GPU);
|
||||||
this->addModuleListItem(SysClkModule_MEM);
|
this->addModuleListItem(SysClkModule_MEM);
|
||||||
|
this->addModuleListItemValue(HorizonOCModule_Display, "Display", 40, 60, 5, " Hz", 1, 0);
|
||||||
this->addModuleToggleItem(HorizonOCModule_Governor);
|
this->addModuleToggleItem(HorizonOCModule_Governor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,18 +266,16 @@ void GlobalOverrideGui::refresh()
|
|||||||
if (!this->context)
|
if (!this->context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++)
|
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) {
|
||||||
{
|
if (m == HorizonOCModule_Governor) {
|
||||||
if (m == HorizonOCModule_Governor)
|
auto *toggle =
|
||||||
{
|
static_cast<tsl::elm::ToggleListItem *>(this->listItems[m]);
|
||||||
auto* toggle = static_cast<tsl::elm::ToggleListItem*>(this->listItems[m]);
|
|
||||||
if (!toggle)
|
if (!toggle)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool newState = this->context->overrideFreqs[m] != 0;
|
bool newState = this->context->overrideFreqs[m] != 0;
|
||||||
|
|
||||||
if (toggle->getState() != newState)
|
if (toggle->getState() != newState) {
|
||||||
{
|
|
||||||
toggle->setState(newState);
|
toggle->setState(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,11 +283,33 @@ void GlobalOverrideGui::refresh()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->listItems[m] != nullptr &&
|
if (this->listItems[m] != nullptr &&
|
||||||
this->listHz[m] != this->context->overrideFreqs[m])
|
this->listHz[m] != this->context->overrideFreqs[m]) {
|
||||||
{
|
|
||||||
this->listItems[m]->setValue(
|
auto it = this->customFormatModules.find((SysClkModule)m);
|
||||||
formatListFreqHz(this->context->overrideFreqs[m])
|
if (it != this->customFormatModules.end()) {
|
||||||
);
|
std::string suffix = std::get<0>(it->second);
|
||||||
|
std::uint32_t divisor = std::get<1>(it->second);
|
||||||
|
int decimalPlaces = std::get<2>(it->second);
|
||||||
|
|
||||||
|
if (this->context->overrideFreqs[m] == 0) {
|
||||||
|
this->listItems[m]->setValue(FREQ_DEFAULT_TEXT);
|
||||||
|
} else {
|
||||||
|
char buf[32];
|
||||||
|
if (decimalPlaces > 0) {
|
||||||
|
double displayValue = (double)this->context->overrideFreqs[m] / divisor;
|
||||||
|
snprintf(buf, sizeof(buf), "%.*f%s",
|
||||||
|
decimalPlaces, displayValue, suffix.c_str());
|
||||||
|
} else {
|
||||||
|
snprintf(buf, sizeof(buf), "%u%s",
|
||||||
|
this->context->overrideFreqs[m] / divisor, suffix.c_str());
|
||||||
|
}
|
||||||
|
this->listItems[m]->setValue(buf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->listItems[m]->setValue(
|
||||||
|
formatListFreqHz(this->context->overrideFreqs[m]));
|
||||||
|
}
|
||||||
|
|
||||||
this->listHz[m] = this->context->overrideFreqs[m];
|
this->listHz[m] = this->context->overrideFreqs[m];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,19 +30,44 @@
|
|||||||
#include "../../ipc.h"
|
#include "../../ipc.h"
|
||||||
#include "base_menu_gui.h"
|
#include "base_menu_gui.h"
|
||||||
#include "freq_choice_gui.h"
|
#include "freq_choice_gui.h"
|
||||||
|
#include <string>
|
||||||
|
#include "value_choice_gui.h"
|
||||||
class GlobalOverrideGui : public BaseMenuGui
|
class GlobalOverrideGui : public BaseMenuGui
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
std::map<SysClkModule, std::tuple<std::string, std::uint32_t, int>> customFormatModules;
|
||||||
tsl::elm::ListItem* listItems[SysClkModule_EnumMax];
|
tsl::elm::ListItem* listItems[SysClkModule_EnumMax];
|
||||||
std::uint32_t listHz[SysClkModule_EnumMax];
|
std::uint32_t listHz[SysClkModule_EnumMax];
|
||||||
bool isGovernorEnabled;
|
bool isGovernorEnabled;
|
||||||
void openFreqChoiceGui(SysClkModule module);
|
void openFreqChoiceGui(SysClkModule module);
|
||||||
void addModuleListItem(SysClkModule module);
|
void addModuleListItem(SysClkModule module);
|
||||||
void addModuleToggleItem(SysClkModule module);
|
void addModuleToggleItem(SysClkModule module);
|
||||||
|
void openValueChoiceGui(
|
||||||
|
tsl::elm::ListItem* listItem,
|
||||||
|
std::uint32_t currentValue,
|
||||||
|
const ValueRange& range,
|
||||||
|
const std::string& categoryName,
|
||||||
|
ValueChoiceListener listener,
|
||||||
|
const ValueThresholds& thresholds,
|
||||||
|
bool enableThresholds,
|
||||||
|
const std::map<std::uint32_t, std::string>& labels,
|
||||||
|
const std::vector<NamedValue>& namedValues,
|
||||||
|
bool showDefaultValue
|
||||||
|
);
|
||||||
|
void addModuleListItemValue(
|
||||||
|
SysClkModule module,
|
||||||
|
const std::string& categoryName,
|
||||||
|
std::uint32_t min,
|
||||||
|
std::uint32_t max,
|
||||||
|
std::uint32_t step,
|
||||||
|
const std::string& suffix,
|
||||||
|
std::uint32_t divisor,
|
||||||
|
int decimalPlaces
|
||||||
|
);
|
||||||
public:
|
public:
|
||||||
GlobalOverrideGui();
|
GlobalOverrideGui();
|
||||||
~GlobalOverrideGui() {}
|
~GlobalOverrideGui() {}
|
||||||
void listUI() override;
|
void listUI() override;
|
||||||
void refresh() override;
|
void refresh() override;
|
||||||
|
void setModuleCustomFormat(SysClkModule module, const std::string& suffix, std::uint32_t divisor, int decimalPlaces);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -229,15 +229,14 @@ void Board::Initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 clkVirtAddr, dsiVirtAddr, outsize;
|
u64 clkVirtAddr, dsiVirtAddr, outsize;
|
||||||
Result rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000);
|
rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000);
|
||||||
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (clk)");
|
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (clk)");
|
||||||
Result 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};
|
||||||
|
|
||||||
DisplayRefresh_Initialize(&cfg);
|
DisplayRefresh_Initialize(&cfg);
|
||||||
|
|
||||||
FetchHardwareInfos();
|
FetchHardwareInfos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +307,11 @@ void Board::SetHz(SysClkModule module, std::uint32_t hz)
|
|||||||
{
|
{
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
|
|
||||||
|
if(module == HorizonOCModule_Display) {
|
||||||
|
DisplayRefresh_SetRate(hz);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(HOSSVC_HAS_CLKRST)
|
if(HOSSVC_HAS_CLKRST)
|
||||||
{
|
{
|
||||||
ClkrstSession session = {0};
|
ClkrstSession session = {0};
|
||||||
@@ -332,6 +336,11 @@ std::uint32_t Board::GetHz(SysClkModule module)
|
|||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
std::uint32_t hz = 0;
|
std::uint32_t hz = 0;
|
||||||
|
|
||||||
|
if(module == HorizonOCModule_Display) {
|
||||||
|
DisplayRefresh_GetRate(&hz, false);
|
||||||
|
return hz;
|
||||||
|
}
|
||||||
|
|
||||||
if(HOSSVC_HAS_CLKRST)
|
if(HOSSVC_HAS_CLKRST)
|
||||||
{
|
{
|
||||||
ClkrstSession session = {0};
|
ClkrstSession session = {0};
|
||||||
@@ -355,6 +364,7 @@ std::uint32_t Board::GetHz(SysClkModule module)
|
|||||||
|
|
||||||
std::uint32_t Board::GetRealHz(SysClkModule module)
|
std::uint32_t Board::GetRealHz(SysClkModule module)
|
||||||
{
|
{
|
||||||
|
u32 hz = 0;
|
||||||
switch(module)
|
switch(module)
|
||||||
{
|
{
|
||||||
case SysClkModule_CPU:
|
case SysClkModule_CPU:
|
||||||
@@ -363,6 +373,9 @@ std::uint32_t Board::GetRealHz(SysClkModule module)
|
|||||||
return t210ClkGpuFreq();
|
return t210ClkGpuFreq();
|
||||||
case SysClkModule_MEM:
|
case SysClkModule_MEM:
|
||||||
return t210ClkMemFreq();
|
return t210ClkMemFreq();
|
||||||
|
case HorizonOCModule_Display:
|
||||||
|
DisplayRefresh_GetRate(&hz, false);
|
||||||
|
return hz;
|
||||||
default:
|
default:
|
||||||
ASSERT_ENUM_VALID(SysClkModule, module);
|
ASSERT_ENUM_VALID(SysClkModule, module);
|
||||||
}
|
}
|
||||||
@@ -377,6 +390,8 @@ void Board::GetFreqList(SysClkModule module, std::uint32_t* outList, std::uint32
|
|||||||
s32 tmpInMaxCount = maxCount;
|
s32 tmpInMaxCount = maxCount;
|
||||||
s32 tmpOutCount = 0;
|
s32 tmpOutCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(HOSSVC_HAS_CLKRST)
|
if(HOSSVC_HAS_CLKRST)
|
||||||
{
|
{
|
||||||
ClkrstSession session = {0};
|
ClkrstSession session = {0};
|
||||||
@@ -552,6 +567,11 @@ void Board::ResetToStockGpu()
|
|||||||
ASSERT_RESULT_OK(rc, "apmExtSysRequestPerformanceMode");
|
ASSERT_RESULT_OK(rc, "apmExtSysRequestPerformanceMode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Board::ResetToStockDisplay() {
|
||||||
|
DisplayRefresh_SetRate(60);
|
||||||
|
}
|
||||||
|
|
||||||
std::uint32_t Board::GetTemperatureMilli(SysClkThermalSensor sensor)
|
std::uint32_t Board::GetTemperatureMilli(SysClkThermalSensor sensor)
|
||||||
{
|
{
|
||||||
std::int32_t millis = 0;
|
std::int32_t millis = 0;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class Board
|
|||||||
static void ResetToStockCpu();
|
static void ResetToStockCpu();
|
||||||
static void ResetToStockMem();
|
static void ResetToStockMem();
|
||||||
static void ResetToStockGpu();
|
static void ResetToStockGpu();
|
||||||
|
static void ResetToStockDisplay();
|
||||||
|
|
||||||
static SysClkProfile GetProfile();
|
static SysClkProfile GetProfile();
|
||||||
static void SetHz(SysClkModule module, std::uint32_t hz);
|
static void SetHz(SysClkModule module, std::uint32_t hz);
|
||||||
|
|||||||
@@ -312,7 +312,8 @@ void ClockManager::GovernorThread(void* arg)
|
|||||||
targetHz = mgr->config->GetAutoClockHz(
|
targetHz = mgr->config->GetAutoClockHz(
|
||||||
mgr->context->applicationId,
|
mgr->context->applicationId,
|
||||||
SysClkModule_GPU,
|
SysClkModule_GPU,
|
||||||
mgr->context->profile
|
mgr->context->profile,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!targetHz)
|
if (!targetHz)
|
||||||
@@ -320,7 +321,8 @@ void ClockManager::GovernorThread(void* arg)
|
|||||||
targetHz = mgr->config->GetAutoClockHz(
|
targetHz = mgr->config->GetAutoClockHz(
|
||||||
GLOBAL_PROFILE_ID,
|
GLOBAL_PROFILE_ID,
|
||||||
SysClkModule_GPU,
|
SysClkModule_GPU,
|
||||||
mgr->context->profile
|
mgr->context->profile,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,15 +412,19 @@ void ClockManager::Tick()
|
|||||||
ResetToStockClocks();
|
ResetToStockClocks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool returnRaw = false;
|
||||||
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||||
{
|
{
|
||||||
|
if(module > SysClkModule_MEM)
|
||||||
|
returnRaw = true;
|
||||||
|
else
|
||||||
|
returnRaw = false;
|
||||||
targetHz = this->context->overrideFreqs[module];
|
targetHz = this->context->overrideFreqs[module];
|
||||||
if (!targetHz)
|
if (!targetHz)
|
||||||
{
|
{
|
||||||
targetHz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile);
|
targetHz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile, returnRaw);
|
||||||
if(!targetHz)
|
if(!targetHz)
|
||||||
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, (SysClkModule)module, this->context->profile);
|
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, (SysClkModule)module, this->context->profile, returnRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(module == HorizonOCModule_Governor) {
|
if(module == HorizonOCModule_Governor) {
|
||||||
@@ -427,14 +433,20 @@ void ClockManager::Tick()
|
|||||||
FileUtils::LogLine("[mgr] Governor state changed: %s", newGovernorState ? "enabled" : "disabled");
|
FileUtils::LogLine("[mgr] Governor state changed: %s", newGovernorState ? "enabled" : "disabled");
|
||||||
lastGovernorState = newGovernorState;
|
lastGovernorState = newGovernorState;
|
||||||
|
|
||||||
// Force a "context refresh" like on app/profile change
|
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
this->context->enabled = this->GetConfig()->Enabled();
|
this->context->enabled = this->GetConfig()->Enabled();
|
||||||
Board::ResetToStock(); // optional: reset clocks before re-applying
|
Board::ResetToStock();
|
||||||
}
|
}
|
||||||
isGovernorEnabled = newGovernorState;
|
isGovernorEnabled = newGovernorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(module == HorizonOCModule_Display) {
|
||||||
|
if(targetHz)
|
||||||
|
Board::SetHz(HorizonOCModule_Display, targetHz);
|
||||||
|
else
|
||||||
|
Board::ResetToStockDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
// Skip GPU if governor handles it
|
// Skip GPU if governor handles it
|
||||||
if(module > SysClkModule_MEM) {
|
if(module > SysClkModule_MEM) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ std::uint32_t Config::FindClockMHz(std::uint64_t tid, SysClkModule module, SysCl
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t Config::FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles)
|
std::uint32_t Config::FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles, u32 mhzMultiplier)
|
||||||
{
|
{
|
||||||
std::uint32_t mhz = 0;
|
std::uint32_t mhz = 0;
|
||||||
|
|
||||||
@@ -155,23 +155,23 @@ std::uint32_t Config::FindClockHzFromProfiles(std::uint64_t tid, SysClkModule mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::max((std::uint32_t)0, mhz * 1000000);
|
return std::max((std::uint32_t)0, mhz * mhzMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t Config::GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile)
|
std::uint32_t Config::GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile, bool returnRaw)
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{this->configMutex};
|
std::scoped_lock lock{this->configMutex};
|
||||||
switch(profile)
|
switch(profile)
|
||||||
{
|
{
|
||||||
case SysClkProfile_Handheld:
|
case SysClkProfile_Handheld:
|
||||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Handheld});
|
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Handheld}, returnRaw ? 1 : 1000000);
|
||||||
case SysClkProfile_HandheldCharging:
|
case SysClkProfile_HandheldCharging:
|
||||||
case SysClkProfile_HandheldChargingUSB:
|
case SysClkProfile_HandheldChargingUSB:
|
||||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingUSB, SysClkProfile_HandheldCharging, SysClkProfile_Handheld});
|
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingUSB, SysClkProfile_HandheldCharging, SysClkProfile_Handheld}, returnRaw ? 1 : 1000000);
|
||||||
case SysClkProfile_HandheldChargingOfficial:
|
case SysClkProfile_HandheldChargingOfficial:
|
||||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingOfficial, SysClkProfile_HandheldCharging, SysClkProfile_Handheld});
|
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingOfficial, SysClkProfile_HandheldCharging, SysClkProfile_Handheld}, returnRaw ? 1 : 1000000);
|
||||||
case SysClkProfile_Docked:
|
case SysClkProfile_Docked:
|
||||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Docked});
|
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Docked}, returnRaw ? 1 : 1000000);
|
||||||
default:
|
default:
|
||||||
ERROR_THROW("Unhandled SysClkProfile: %u", profile);
|
ERROR_THROW("Unhandled SysClkProfile: %u", profile);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class Config
|
|||||||
std::uint8_t GetProfileCount(std::uint64_t tid);
|
std::uint8_t GetProfileCount(std::uint64_t tid);
|
||||||
void GetProfiles(std::uint64_t tid, SysClkTitleProfileList* out_profiles);
|
void GetProfiles(std::uint64_t tid, SysClkTitleProfileList* out_profiles);
|
||||||
bool SetProfiles(std::uint64_t tid, SysClkTitleProfileList* profiles, bool immediate);
|
bool SetProfiles(std::uint64_t tid, SysClkTitleProfileList* profiles, bool immediate);
|
||||||
std::uint32_t GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile);
|
std::uint32_t GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile, bool returnRaw);
|
||||||
|
|
||||||
void SetEnabled(bool enabled);
|
void SetEnabled(bool enabled);
|
||||||
bool Enabled();
|
bool Enabled();
|
||||||
@@ -76,7 +76,7 @@ class Config
|
|||||||
bool kipOverride[SysClkConfigValue_EnumMax];
|
bool kipOverride[SysClkConfigValue_EnumMax];
|
||||||
time_t CheckModificationTime();
|
time_t CheckModificationTime();
|
||||||
std::uint32_t FindClockMHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile);
|
std::uint32_t FindClockMHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile);
|
||||||
std::uint32_t FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles);
|
std::uint32_t FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles, u32 mhzMultiplier = 1000000);
|
||||||
static int BrowseIniFunc(const char* section, const char* key, const char* value, void* userdata);
|
static int BrowseIniFunc(const char* section, const char* key, const char* value, void* userdata);
|
||||||
|
|
||||||
std::map<std::tuple<std::uint64_t, SysClkProfile, SysClkModule>, std::uint32_t> profileMHzMap;
|
std::map<std::tuple<std::uint64_t, SysClkProfile, SysClkModule>, std::uint32_t> profileMHzMap;
|
||||||
|
|||||||
Reference in New Issue
Block a user