sys-clk: add menu toggles
This commit is contained in:
@@ -46,11 +46,12 @@ Git clone Atmosphere, and move the cloned folder into build/<br>
|
||||
Insert Source/stratosphere folder into build/<br>
|
||||
Run build.sh
|
||||
|
||||
To build the configurator, clone it's repo (souldbminersmwc/ocs2-configurator)<br>
|
||||
Run build.bat or cd into folder and run "python -m PyInstaller --onefile --add-data "assets;assets" --icon=assets/icon.ico --noconsole src/main.py"<br>
|
||||
To build the configurator, cd into Source/Configurator<br>
|
||||
Run build.bat or run "python -m PyInstaller --onefile --add-data "assets;assets" --icon=assets/icon.ico --noconsole src/main.py"<br>
|
||||
|
||||
|
||||
## Credits
|
||||
Lightos for RAM timings<br>
|
||||
meha for Switch-Oc-Suite<br>
|
||||
sys-clk team for sys-clk<br>
|
||||
b0rd2death for Ultrahand sys-clk fork<br>
|
||||
|
||||
@@ -474,7 +474,7 @@ volatile CustomizeTable C = {
|
||||
{ 2091000, { 1235000 }, { 5400873, -289186, 4847 } },
|
||||
{ 2193000, { 1235000 }, { 5500873, -299186, 4947 } },
|
||||
{ 2295000, { 1235000 }, { 5600873, -239186, 5047 } },
|
||||
{ 2397000, { 1235000 }, { 5700873, -249186, 5047 } },
|
||||
// { 2397000, { 1235000 }, { 5700873, -249186, 5047 } },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef struct
|
||||
uint32_t temps[SysClkThermalSensor_EnumMax];
|
||||
int32_t power[SysClkPowerSensor_EnumMax];
|
||||
uint32_t ramLoad[SysClkRamLoad_EnumMax];
|
||||
uint32_t perfConfId;
|
||||
} SysClkContext;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -19,6 +19,8 @@ typedef enum {
|
||||
SysClkConfigValue_FreqLogIntervalMs,
|
||||
SysClkConfigValue_PowerLogIntervalMs,
|
||||
SysClkConfigValue_CsvWriteIntervalMs,
|
||||
HocClkConfigValue_UncappedClocks,
|
||||
HocClkConfigValue_OverwriteBoostMode,
|
||||
SysClkConfigValue_EnumMax,
|
||||
} SysClkConfigValue;
|
||||
|
||||
@@ -40,6 +42,10 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
|
||||
return pretty ? "Power logging interval (ms)" : "power_log_interval_ms";
|
||||
case SysClkConfigValue_CsvWriteIntervalMs:
|
||||
return pretty ? "CSV write interval (ms)" : "csv_write_interval_ms";
|
||||
case HocClkConfigValue_UncappedClocks:
|
||||
return pretty ? "Uncapped Clocks" : "uncapped_clocks";
|
||||
case HocClkConfigValue_OverwriteBoostMode:
|
||||
return pretty ? "Overwrite Boost Mode" : "ow_boost";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -55,6 +61,8 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
|
||||
case SysClkConfigValue_FreqLogIntervalMs:
|
||||
case SysClkConfigValue_PowerLogIntervalMs:
|
||||
case SysClkConfigValue_CsvWriteIntervalMs:
|
||||
case HocClkConfigValue_UncappedClocks:
|
||||
case HocClkConfigValue_OverwriteBoostMode:
|
||||
return 0ULL;
|
||||
default:
|
||||
return 0ULL;
|
||||
@@ -72,6 +80,9 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
|
||||
case SysClkConfigValue_PowerLogIntervalMs:
|
||||
case SysClkConfigValue_CsvWriteIntervalMs:
|
||||
return input >= 0;
|
||||
case HocClkConfigValue_OverwriteBoostMode:
|
||||
case HocClkConfigValue_UncappedClocks:
|
||||
return (input & 0x1) == input;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -7,436 +7,54 @@
|
||||
|
||||
MiscGui::MiscGui()
|
||||
{
|
||||
|
||||
// Load current config values
|
||||
configValues["uncapped_clocks"] = getConfigValue("uncapped_clocks");
|
||||
configValues["override_boost_mode"] = getConfigValue("override_boost_mode");
|
||||
configValues["auto_cpu_boost"] = getConfigValue("auto_cpu_boost");
|
||||
configValues["sync_reversenx"] = getConfigValue("sync_reversenx");
|
||||
// gpu_dvfs is handled separately as it's now a trackbar with integer values
|
||||
this->configList = new SysClkConfigValueList {};
|
||||
}
|
||||
|
||||
MiscGui::~MiscGui()
|
||||
{
|
||||
delete this->configList;
|
||||
this->configToggles.clear();
|
||||
}
|
||||
|
||||
bool MiscGui::getConfigValue(const std::string& iniKey)
|
||||
{
|
||||
FILE* file = fopen("/config/sys-clk/config.ini", "r");
|
||||
if (!file) {
|
||||
// Return default values if file doesn't exist
|
||||
return (iniKey == "gpu_dvfs"); // gpu_dvfs defaults to true, others default to false
|
||||
}
|
||||
|
||||
char line[512];
|
||||
bool inValuesSection = false;
|
||||
void MiscGui::addConfigToggle(SysClkConfigValue configVal, const char* altName = nullptr) {
|
||||
const char* configName = altName ? altName : sysclkFormatConfigValue(configVal, true);
|
||||
tsl::elm::ToggleListItem* toggle = new tsl::elm::ToggleListItem(configName, this->configList->values[configVal]);
|
||||
toggle->setStateChangedListener([this, configVal](bool state) {
|
||||
this->configList->values[configVal] = uint64_t(state);
|
||||
Result rc = sysclkIpcSetConfigValues(this->configList);
|
||||
if (R_FAILED(rc))
|
||||
FatalGui::openWithResultCode("sysclkIpcSetConfigValues", rc);
|
||||
|
||||
size_t len;
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
// Remove newline if present
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
|
||||
// Trim whitespace
|
||||
char* start = line;
|
||||
while (*start == ' ' || *start == '\t') start++;
|
||||
char* end = start + strlen(start) - 1;
|
||||
while (end > start && (*end == ' ' || *end == '\t')) {
|
||||
*end = '\0';
|
||||
end--;
|
||||
}
|
||||
|
||||
// Check for [values] section
|
||||
if (strcmp(start, "[values]") == 0) {
|
||||
inValuesSection = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for new section
|
||||
if (strlen(start) > 0 && start[0] == '[') {
|
||||
inValuesSection = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse key=value in values section
|
||||
if (inValuesSection) {
|
||||
char* equalPos = strchr(start, '=');
|
||||
if (equalPos != nullptr) {
|
||||
*equalPos = '\0'; // Split the string
|
||||
char* key = start;
|
||||
char* value = equalPos + 1;
|
||||
|
||||
if(iniKey == "uncapped_clocks") {
|
||||
Result rc = sysclkIpcSetEnabled(value);
|
||||
}
|
||||
|
||||
// Trim key
|
||||
char* keyEnd = key + strlen(key) - 1;
|
||||
while (keyEnd > key && (*keyEnd == ' ' || *keyEnd == '\t')) {
|
||||
*keyEnd = '\0';
|
||||
keyEnd--;
|
||||
}
|
||||
|
||||
// Trim value
|
||||
while (*value == ' ' || *value == '\t') value++;
|
||||
char* valueEnd = value + strlen(value) - 1;
|
||||
while (valueEnd > value && (*valueEnd == ' ' || *valueEnd == '\t')) {
|
||||
*valueEnd = '\0';
|
||||
valueEnd--;
|
||||
}
|
||||
|
||||
if (iniKey == key) {
|
||||
bool result = (strcmp(value, "1") == 0);
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Return default values if key not found
|
||||
return (iniKey == "gpu_dvfs"); // gpu_dvfs defaults to true, others default to false
|
||||
}
|
||||
|
||||
int MiscGui::getConfigIntValue(const std::string& iniKey, int defaultValue)
|
||||
{
|
||||
FILE* file = fopen("/config/sys-clk/config.ini", "r");
|
||||
if (!file) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
char line[512];
|
||||
bool inValuesSection = false;
|
||||
|
||||
size_t len;
|
||||
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
// Remove newline if present
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
|
||||
// Trim whitespace
|
||||
char* start = line;
|
||||
while (*start == ' ' || *start == '\t') start++;
|
||||
char* end = start + strlen(start) - 1;
|
||||
while (end > start && (*end == ' ' || *end == '\t')) {
|
||||
*end = '\0';
|
||||
end--;
|
||||
}
|
||||
|
||||
// Check for [values] section
|
||||
if (strcmp(start, "[values]") == 0) {
|
||||
inValuesSection = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for new section
|
||||
if (strlen(start) > 0 && start[0] == '[') {
|
||||
inValuesSection = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse key=value in values section
|
||||
if (inValuesSection) {
|
||||
char* equalPos = strchr(start, '=');
|
||||
if (equalPos != nullptr) {
|
||||
*equalPos = '\0'; // Split the string
|
||||
char* key = start;
|
||||
char* value = equalPos + 1;
|
||||
|
||||
// Trim key
|
||||
char* keyEnd = key + strlen(key) - 1;
|
||||
while (keyEnd > key && (*keyEnd == ' ' || *keyEnd == '\t')) {
|
||||
*keyEnd = '\0';
|
||||
keyEnd--;
|
||||
}
|
||||
|
||||
// Trim value
|
||||
while (*value == ' ' || *value == '\t') value++;
|
||||
char* valueEnd = value + strlen(value) - 1;
|
||||
while (valueEnd > value && (*valueEnd == ' ' || *valueEnd == '\t')) {
|
||||
*valueEnd = '\0';
|
||||
valueEnd--;
|
||||
}
|
||||
|
||||
if (iniKey == key) {
|
||||
int result = atoi(value);
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void MiscGui::setConfigValue(const std::string& iniKey, bool value)
|
||||
{
|
||||
if(iniKey == "uncapped_clocks") {
|
||||
Result rc = sysclkIpcSetEnabled(value);
|
||||
}
|
||||
// Read the entire file
|
||||
FILE* file = fopen("/config/sys-clk/config.ini", "r");
|
||||
std::vector<std::string> lines;
|
||||
|
||||
if (file) {
|
||||
char line[512];
|
||||
size_t len;
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
// Remove newline if present
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
lines.push_back(std::string(line));
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
// Find and update the value
|
||||
bool inValuesSection = false;
|
||||
bool keyFound = false;
|
||||
int valuesSectionIndex = -1;
|
||||
|
||||
std::string trimmedLine;
|
||||
size_t equalPos;
|
||||
std::string key;
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
trimmedLine = lines[i];
|
||||
trimmedLine.erase(0, trimmedLine.find_first_not_of(" \t"));
|
||||
trimmedLine.erase(trimmedLine.find_last_not_of(" \t") + 1);
|
||||
|
||||
if (trimmedLine == "[values]") {
|
||||
inValuesSection = true;
|
||||
valuesSectionIndex = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trimmedLine.length() > 0 && trimmedLine[0] == '[') {
|
||||
inValuesSection = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inValuesSection) {
|
||||
equalPos = trimmedLine.find('=');
|
||||
if (equalPos != std::string::npos) {
|
||||
key = trimmedLine.substr(0, equalPos);
|
||||
key.erase(0, key.find_first_not_of(" \t"));
|
||||
key.erase(key.find_last_not_of(" \t") + 1);
|
||||
|
||||
if (key == iniKey) {
|
||||
lines[i] = iniKey + "=" + (value ? "1" : "0");
|
||||
keyFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If key wasn't found, add it to the values section
|
||||
if (!keyFound) {
|
||||
if (valuesSectionIndex == -1) {
|
||||
// Add [values] section if it doesn't exist
|
||||
lines.push_back("[values]");
|
||||
lines.push_back(iniKey + "=" + (value ? "1" : "0"));
|
||||
} else {
|
||||
// Add to existing values section
|
||||
lines.insert(lines.begin() + valuesSectionIndex + 1, iniKey + "=" + (value ? "1" : "0"));
|
||||
}
|
||||
}
|
||||
|
||||
// Write the file back
|
||||
FILE* outFile = fopen("/config/sys-clk/config.ini", "w");
|
||||
if (outFile) {
|
||||
for (const auto& fileLine : lines) {
|
||||
fprintf(outFile, "%s\n", fileLine.c_str());
|
||||
}
|
||||
fclose(outFile);
|
||||
}
|
||||
}
|
||||
|
||||
void MiscGui::setConfigIntValue(const std::string& iniKey, int value)
|
||||
{
|
||||
// Read the entire file
|
||||
FILE* file = fopen("/config/sys-clk/config.ini", "r");
|
||||
std::vector<std::string> lines;
|
||||
|
||||
if (file) {
|
||||
char line[512];
|
||||
size_t len;
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
// Remove newline if present
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
lines.push_back(std::string(line));
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
// Find and update the value
|
||||
bool inValuesSection = false;
|
||||
bool keyFound = false;
|
||||
int valuesSectionIndex = -1;
|
||||
|
||||
std::string trimmedLine;
|
||||
size_t equalPos;
|
||||
std::string key;
|
||||
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
trimmedLine = lines[i];
|
||||
trimmedLine.erase(0, trimmedLine.find_first_not_of(" \t"));
|
||||
trimmedLine.erase(trimmedLine.find_last_not_of(" \t") + 1);
|
||||
|
||||
if (trimmedLine == "[values]") {
|
||||
inValuesSection = true;
|
||||
valuesSectionIndex = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trimmedLine.length() > 0 && trimmedLine[0] == '[') {
|
||||
inValuesSection = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inValuesSection) {
|
||||
equalPos = trimmedLine.find('=');
|
||||
if (equalPos != std::string::npos) {
|
||||
key = trimmedLine.substr(0, equalPos);
|
||||
key.erase(0, key.find_first_not_of(" \t"));
|
||||
key.erase(key.find_last_not_of(" \t") + 1);
|
||||
|
||||
if (key == iniKey) {
|
||||
lines[i] = iniKey + "=" + std::to_string(value);
|
||||
keyFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If key wasn't found, add it to the values section
|
||||
if (!keyFound) {
|
||||
if (valuesSectionIndex == -1) {
|
||||
// Add [values] section if it doesn't exist
|
||||
lines.push_back("[values]");
|
||||
lines.push_back(iniKey + "=" + std::to_string(value));
|
||||
} else {
|
||||
// Add to existing values section
|
||||
lines.insert(lines.begin() + valuesSectionIndex + 1, iniKey + "=" + std::to_string(value));
|
||||
}
|
||||
}
|
||||
|
||||
// Write the file back
|
||||
FILE* outFile = fopen("/config/sys-clk/config.ini", "w");
|
||||
if (outFile) {
|
||||
for (const auto& fileLine : lines) {
|
||||
fprintf(outFile, "%s\n", fileLine.c_str());
|
||||
}
|
||||
fclose(outFile);
|
||||
}
|
||||
}
|
||||
|
||||
void MiscGui::addConfigToggle(const std::string& iniKey, const char* displayName) {
|
||||
tsl::elm::ToggleListItem* toggle = new tsl::elm::ToggleListItem(displayName, configValues[iniKey]);
|
||||
toggle->setStateChangedListener([this, iniKey](bool state) {
|
||||
configValues[iniKey] = state;
|
||||
setConfigValue(iniKey, state);
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
});
|
||||
this->listElement->addItem(toggle);
|
||||
this->configToggles[iniKey] = toggle;
|
||||
this->configToggles[configVal] = toggle;
|
||||
}
|
||||
|
||||
void MiscGui::updateConfigToggles() {
|
||||
for (const auto& [key, toggle] : this->configToggles) {
|
||||
if (toggle != nullptr) {
|
||||
bool currentValue = getConfigValue(key);
|
||||
configValues[key] = currentValue;
|
||||
toggle->setState(currentValue);
|
||||
}
|
||||
for (const auto& [value, toggle] : this->configToggles) {
|
||||
if (toggle != nullptr)
|
||||
toggle->setState(this->configList->values[value]);
|
||||
}
|
||||
}
|
||||
|
||||
void MiscGui::listUI()
|
||||
{
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Config"));
|
||||
addConfigToggle(HocClkConfigValue_UncappedClocks);
|
||||
addConfigToggle(HocClkConfigValue_OverwriteBoostMode);
|
||||
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Settings"));
|
||||
|
||||
this->enabledToggle = new tsl::elm::ToggleListItem("Enable", false);
|
||||
enabledToggle->setStateChangedListener([this](bool state) {
|
||||
Result rc = sysclkIpcSetEnabled(state);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
FatalGui::openWithResultCode("sysclkIpcSetEnabled", rc);
|
||||
}
|
||||
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
this->context->enabled = state;
|
||||
});
|
||||
this->listElement->addItem(this->enabledToggle);
|
||||
|
||||
// Add the 4 boolean config toggles using INI keys
|
||||
addConfigToggle("uncapped_clocks", "Uncapped Clocks");
|
||||
addConfigToggle("override_boost_mode", "Override Boost Mode");
|
||||
addConfigToggle("auto_cpu_boost", "Auto CPU Boost");
|
||||
addConfigToggle("reversenx_sync", "Sync ReverseNX");
|
||||
|
||||
// Add GPU DVFS as a NamedStepTrackBar with V2 style
|
||||
this->gpuDvfsTrackbar = new tsl::elm::NamedStepTrackBar("", {
|
||||
"Off",
|
||||
"Official Service Method",
|
||||
"Hijack Method"
|
||||
}, true, "GPU DVFS");
|
||||
|
||||
// Set initial value (default is 0 if not set)
|
||||
int currentDvfsValue = getConfigIntValue("gpu_dvfs", 1);
|
||||
// Ensure the value is within valid range (0-2)
|
||||
currentDvfsValue = std::max(0, std::min(2, currentDvfsValue));
|
||||
this->gpuDvfsTrackbar->setProgress(static_cast<u8>(currentDvfsValue));
|
||||
|
||||
// Set up the value change listener to update the INI file
|
||||
this->gpuDvfsTrackbar->setValueChangedListener([this](u8 value) {
|
||||
// Ensure value is within expected range
|
||||
const int intValue = static_cast<int>(std::min(static_cast<u8>(2), value));
|
||||
setConfigIntValue("gpu_dvfs", intValue);
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
});
|
||||
|
||||
this->listElement->addItem(this->gpuDvfsTrackbar);
|
||||
}
|
||||
|
||||
void MiscGui::refresh() {
|
||||
BaseMenuGui::refresh();
|
||||
|
||||
// Update the enabled toggle state
|
||||
if(this->context)
|
||||
{
|
||||
this->enabledToggle->setState(this->context->enabled);
|
||||
}
|
||||
|
||||
// Update config values and toggle states every 60 frames (once per second at 60fps)
|
||||
if (this->context && ++frameCounter >= 60)
|
||||
{
|
||||
frameCounter = 0;
|
||||
sysclkIpcGetConfigValues(this->configList);
|
||||
updateConfigToggles();
|
||||
|
||||
// Update GPU DVFS trackbar
|
||||
if (this->gpuDvfsTrackbar != nullptr) {
|
||||
int currentDvfsValue = getConfigIntValue("gpu_dvfs", 1);
|
||||
// Ensure the value is within valid range (0-2)
|
||||
currentDvfsValue = std::max(0, std::min(2, currentDvfsValue));
|
||||
this->gpuDvfsTrackbar->setProgress(static_cast<u8>(currentDvfsValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,22 +9,17 @@ class MiscGui : public BaseMenuGui
|
||||
public:
|
||||
MiscGui();
|
||||
~MiscGui();
|
||||
|
||||
void listUI() override;
|
||||
void refresh() override;
|
||||
protected:
|
||||
SysClkConfigValueList* configList;
|
||||
|
||||
std::unordered_map<std::string, tsl::elm::ToggleListItem*> configToggles;
|
||||
std::unordered_map<std::string, bool> configValues;
|
||||
|
||||
void addConfigToggle(const std::string& iniKey, const char* displayName);
|
||||
std::map<SysClkConfigValue, tsl::elm::ToggleListItem*> configToggles;
|
||||
void addConfigToggle(SysClkConfigValue, const char*);
|
||||
void updateConfigToggles();
|
||||
bool getConfigValue(const std::string& iniKey);
|
||||
void setConfigValue(const std::string& iniKey, bool value);
|
||||
int getConfigIntValue(const std::string& iniKey, int defaultValue);
|
||||
void setConfigIntValue(const std::string& iniKey, int value);
|
||||
|
||||
tsl::elm::ToggleListItem* enabledToggle;
|
||||
tsl::elm::NamedStepTrackBar* gpuDvfsTrackbar; // Add this line
|
||||
|
||||
u8 frameCounter = 60;
|
||||
};
|
||||
@@ -23,6 +23,18 @@ void apmExtExit(void);
|
||||
Result apmExtGetPerformanceMode(u32* out_mode);
|
||||
Result apmExtSysRequestPerformanceMode(u32 mode);
|
||||
Result apmExtGetCurrentPerformanceConfiguration(u32* out_conf);
|
||||
Result apmExtSysRequestPerformanceMode(u32 mode);
|
||||
Result apmExtSysSetCpuBoostMode(u32 mode);
|
||||
|
||||
Result apmExtGetPerformanceMode(u32 *out_mode);
|
||||
Result apmExtGetCurrentPerformanceConfiguration(u32 *out_conf);
|
||||
|
||||
inline bool apmExtIsCPUBoosted(u32 conf_id) { // CPU boosted to 1785 MHz
|
||||
return (conf_id == 0x92220009 || conf_id == 0x9222000A);
|
||||
};
|
||||
inline bool apmExtIsBoostMode(u32 conf_id) { // GPU throttled to 76.8 MHz
|
||||
return (conf_id >= 0x92220009 && conf_id <= 0x9222000C);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -86,7 +86,25 @@ bool ClockManager::IsAssignableHz(SysClkModule module, std::uint32_t hz)
|
||||
|
||||
std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile profile)
|
||||
{
|
||||
return 4294967294; // Integer limit, uncapped clocks ON
|
||||
if (this->config->GetConfigValue(HocClkConfigValue_UncappedClocks))
|
||||
{
|
||||
return 4294967294; // Integer limit, uncapped clocks ON
|
||||
}
|
||||
else
|
||||
{
|
||||
if(module == SysClkModule_GPU)
|
||||
{
|
||||
if(profile < SysClkProfile_HandheldCharging)
|
||||
{
|
||||
return Board::GetSocType() == SysClkSocType_Mariko ? 614400000 : 460800000;
|
||||
}
|
||||
else if(profile <= SysClkProfile_HandheldChargingUSB)
|
||||
{
|
||||
return 768000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::uint32_t ClockManager::GetNearestHz(SysClkModule module, std::uint32_t inHz, std::uint32_t maxHz)
|
||||
@@ -177,7 +195,7 @@ void ClockManager::Tick()
|
||||
maxHz = this->GetMaxAllowedHz((SysClkModule)module, this->context->profile);
|
||||
nearestHz = this->GetNearestHz((SysClkModule)module, targetHz, maxHz);
|
||||
|
||||
if (nearestHz != this->context->freqs[module] && this->context->enabled)
|
||||
if (nearestHz != this->context->freqs[module] && this->context->enabled && !apmExtIsBoostMode(this->context->perfConfId) && this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode))
|
||||
{
|
||||
FileUtils::LogLine(
|
||||
"[mgr] %s clock set : %u.%u MHz (target = %u.%u MHz)",
|
||||
@@ -187,6 +205,9 @@ void ClockManager::Tick()
|
||||
|
||||
Board::SetHz((SysClkModule)module, nearestHz);
|
||||
this->context->freqs[module] = nearestHz;
|
||||
} else {
|
||||
Board::ResetToStockCpu();
|
||||
Board::ResetToStockGpu();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,16 +275,17 @@ bool ClockManager::RefreshContext()
|
||||
else
|
||||
{
|
||||
FileUtils::LogLine("[mgr] %s override disabled", Board::GetModuleName((SysClkModule)module, true));
|
||||
switch(module) {
|
||||
case SysClkModule_CPU:
|
||||
Board::ResetToStockCpu();
|
||||
break;
|
||||
case SysClkModule_GPU:
|
||||
Board::ResetToStockGpu();
|
||||
break;
|
||||
case SysClkModule_MEM:
|
||||
Board::ResetToStockMem();
|
||||
break;
|
||||
switch (module)
|
||||
{
|
||||
case SysClkModule_CPU:
|
||||
Board::ResetToStockCpu();
|
||||
break;
|
||||
case SysClkModule_GPU:
|
||||
Board::ResetToStockGpu();
|
||||
break;
|
||||
case SysClkModule_MEM:
|
||||
Board::ResetToStockMem();
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->context->overrideFreqs[module] = hz;
|
||||
|
||||
BIN
dist/atmosphere/kips/hoc.kip
vendored
BIN
dist/atmosphere/kips/hoc.kip
vendored
Binary file not shown.
BIN
hocconfig.exe
BIN
hocconfig.exe
Binary file not shown.
Reference in New Issue
Block a user