hocclk: peak emc bw and mem display unit option

also correct bw reading to keep it accurate
This commit is contained in:
souldbminersmwc
2026-04-11 20:56:35 -04:00
parent d2a46e1202
commit 037f011c9b
13 changed files with 199 additions and 44 deletions

View File

@@ -35,6 +35,7 @@ tsl::elm::ListItem* dispVoltItem = NULL;
tsl::elm::ListItem* ramBWItemAll = NULL;
tsl::elm::ListItem* ramBWItemCpu = NULL;
tsl::elm::ListItem* ramBWItemGpu = NULL;
tsl::elm::ListItem* ramBWItemMax = NULL;
ImageElement* CatImage = NULL;
HideableCategoryHeader* CatHeader = NULL;
@@ -75,17 +76,21 @@ void AboutGui::listUI()
this->listElement->addItem(
new tsl::elm::CategoryHeader("RAM Bandwidth")
);
ramBWItemMax =
new tsl::elm::ListItem("RAM BW (Peak):");
this->listElement->addItem(ramBWItemMax);
ramBWItemAll =
new tsl::elm::ListItem("Ram BW (All):");
new tsl::elm::ListItem("RAM BW (All):");
this->listElement->addItem(ramBWItemAll);
ramBWItemCpu =
new tsl::elm::ListItem("Ram BW (CPU):");
new tsl::elm::ListItem("RAM BW (CPU):");
this->listElement->addItem(ramBWItemCpu);
ramBWItemGpu =
new tsl::elm::ListItem("Ram BW (GPU):");
new tsl::elm::ListItem("RAM BW (GPU):");
this->listElement->addItem(ramBWItemGpu);
@@ -374,5 +379,7 @@ void AboutGui::refresh()
sprintf(strings[8], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWGpu]);
ramBWItemGpu->setValue(strings[8]);
sprintf(strings[9], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWPeak]);
ramBWItemMax->setValue(strings[9]);
}

View File

@@ -59,9 +59,11 @@ void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, HocClkProfil
} else if (module == HocClkModule_GPU) {
labels = IsMariko() ? *(marikoUV[configList.values[KipConfigValue_marikoGpuUV]]) : *(eristaUV[configList.values[KipConfigValue_eristaGpuUV]]);
}
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module](std::uint32_t hz) {
MemDisplayUnit memUnit = (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit];
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module, memUnit](std::uint32_t hz) {
this->profileList->mhzMap[profile][module] = hz / 1000000;
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
std::uint32_t mhz = this->profileList->mhzMap[profile][module];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(mhz, memUnit) : formatListFreqMHz(mhz));
Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))
{
@@ -104,8 +106,10 @@ void AppProfileGui::openValueChoiceGui(
void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module)
{
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(hocclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
listItem->setClickListener([this, listItem, profile, module](u64 keys) {
MemDisplayUnit memUnit = (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit];
std::uint32_t mhz = this->profileList->mhzMap[profile][module];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(mhz, memUnit) : formatListFreqMHz(mhz));
listItem->setClickListener([this, listItem, profile, module, memUnit](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A)
{
this->openFreqChoiceGui(listItem, profile, module);
@@ -115,7 +119,7 @@ void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module
{
// Reset to "Default" (0 MHz)
this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(formatListFreqMHz(0));
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, memUnit) : formatListFreqMHz(0));
Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))

View File

@@ -27,6 +27,7 @@
#include "base_menu_gui.h"
#include "fatal_gui.h"
#include "../format.h"
// Cache hardware model to avoid repeated syscalls
@@ -229,7 +230,21 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[HocClkModule_MEM]; // MEM
sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
std::uint32_t unit = configList.values[HocClkConfigValue_MemDisplayUnit];
std::uint32_t mhz = hz / 1000000U;
std::uint32_t mts = mhz * 2;
std::uint32_t tenth = (hz / 100000U) % 10U;
if(unit == MemDisplayUnit_MTs)
sprintf(displayStrings[4], "%u MT/s", mts);
else if(unit == MemDisplayUnit_MHz)
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
else if(unit == MemDisplayUnit_Both) {
hz = context->realFreqs[HocClkModule_MEM];
mhz = hz / 1000000U;
mhz * 2;
tenth = (hz / 100000U) % 10U;
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
}
// Real frequencies
hz = context->realFreqs[HocClkModule_CPU]; // CPU
@@ -239,7 +254,14 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[HocClkModule_MEM]; // MEM
sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
std::uint32_t unit = configList.values[HocClkConfigValue_MemDisplayUnit];
std::uint32_t mhz = hz / 1000000U;
std::uint32_t mts = mhz * 2;
std::uint32_t tenth = (hz / 100000U) % 10U;
if(unit == MemDisplayUnit_MTs || unit == MemDisplayUnit_Both)
sprintf(displayStrings[7], "%u MT/s", mts);
else
sprintf(displayStrings[7], "%u.%u MHz", mhz, tenth);
// Voltages
sprintf(displayStrings[8], "%.1f mV", context->voltages[HocClkVoltage_CPU] / 1000.0);

View File

@@ -55,10 +55,11 @@ FreqChoiceGui::~FreqChoiceGui()
tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety)
{
std::string text = formatListFreqHz(hz);
if(module == HocClkModule_MEM && hz != 0)
text += " (" + std::to_string(hz / 500000) + " MT/s)";
std::string text;
if(module == HocClkModule_MEM)
text = formatListFreqHzMem(hz, (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit]);
else
text = formatListFreqHz(hz);
std::string rightText = "";
auto it = labels.find(hz);

View File

@@ -246,7 +246,8 @@ void GlobalOverrideGui::addModuleListItem(HocClkModule module)
{
tsl::elm::ListItem *listItem =
new tsl::elm::ListItem(hocclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(0));
MemDisplayUnit memUnit = (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, memUnit) : formatListFreqMHz(0));
listItem->setClickListener([this, module](u64 keys) {
if ((keys & HidNpadButton_A) == HidNpadButton_A) {
this->openFreqChoiceGui(module);
@@ -262,7 +263,7 @@ void GlobalOverrideGui::addModuleListItem(HocClkModule module)
this->context->overrideFreqs[module] = 0;
this->listHz[module] = 0;
this->listItems[module]->setValue(formatListFreqHz(0));
this->listItems[module]->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit]) : formatListFreqHz(0));
return true;
}
@@ -409,7 +410,9 @@ void GlobalOverrideGui::refresh()
}
} else {
this->listItems[m]->setValue(
formatListFreqHz(this->context->overrideFreqs[m]));
m == HocClkModule_MEM
? formatListFreqHzMem(this->context->overrideFreqs[m], (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit])
: formatListFreqHz(this->context->overrideFreqs[m]));
}
this->listHz[m] = this->context->overrideFreqs[m];

View File

@@ -147,13 +147,18 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
ValueThresholds thresholdsCopy = (thresholds ? *thresholds : ValueThresholds{});
listItem->setClickListener(
[this, configVal, range, categoryName, thresholdsCopy, labels, namedValues, showDefaultValue, kip](u64 keys)
[this, configVal, range, categoryName, thresholdsCopy, labels, showDefaultValue, kip](u64 keys)
{
if ((keys & HidNpadButton_A) == 0)
return false;
std::uint32_t currentValue = this->configList->values[configVal];
// Look up live namedValues so relabeling in refresh() is reflected
auto nvIt = this->configNamedValues.find(configVal);
const std::vector<NamedValue>& liveNamedValues = (nvIt != this->configNamedValues.end())
? nvIt->second : std::vector<NamedValue>();
if (thresholdsCopy.warning != 0 || thresholdsCopy.danger != 0) {
tsl::changeTo<ValueChoiceGui>(
@@ -176,7 +181,7 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
thresholdsCopy,
true,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
} else {
@@ -201,7 +206,7 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
ValueThresholds(),
false,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
}
@@ -260,13 +265,18 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
ValueThresholds thresholdsCopy = (thresholds ? *thresholds : ValueThresholds{});
listItem->setClickListener(
[this, configVal, range, categoryName, thresholdsCopy, labels, namedValues, showDefaultValue, kip](u64 keys)
[this, configVal, range, categoryName, thresholdsCopy, labels, showDefaultValue, kip](u64 keys)
{
if ((keys & HidNpadButton_A) == 0)
return false;
std::uint32_t currentValue = this->configList->values[configVal];
// Look up live namedValues so relabeling in refresh() is reflected
auto nvIt = this->configNamedValues.find(configVal);
const std::vector<NamedValue>& liveNamedValues = (nvIt != this->configNamedValues.end())
? nvIt->second : std::vector<NamedValue>();
if (thresholdsCopy.warning != 0 || thresholdsCopy.danger != 0) {
tsl::changeTo<ValueChoiceGui>(
@@ -289,7 +299,7 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
thresholdsCopy,
true,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
} else {
@@ -314,7 +324,7 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
ValueThresholds(),
false,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
}
@@ -530,6 +540,22 @@ protected:
addConfigButton(HocClkConfigValue_RAMVoltDisplayMode, "RAM Voltage Display Mode", ValueRange(0, 12, 1, "", 0), "RAM Voltage Display Mode", &thresholdsDisabled, {}, ramVoltDispModes, false);
}
std::vector<NamedValue> memDisplayUnitValues = {
NamedValue("MHz", MemDisplayUnit_MHz),
NamedValue("MT/s", MemDisplayUnit_MTs),
NamedValue("Both", MemDisplayUnit_Both),
};
addConfigButton(
HocClkConfigValue_MemDisplayUnit,
"RAM Display Unit",
ValueRange(0, 0, 2, "", 0),
"RAM Display Unit",
&thresholdsDisabled,
{},
memDisplayUnitValues,
false
);
addConfigButton(
HocClkConfigValue_PollingIntervalMs,
"Polling Interval",
@@ -594,7 +620,6 @@ protected:
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);
@@ -865,7 +890,7 @@ protected:
this->listElement->addItem(freqSubmenu);
} else {
std::vector<NamedValue> marikoMaxEmcClock = {
NamedValue("Disabled", 1600000),
NamedValue("1600 MHz", 1600000),
NamedValue("1633 MHz", 1633000),
NamedValue("1666 MHz", 1666000),
NamedValue("1700 MHz", 1700000),
@@ -926,6 +951,11 @@ protected:
// NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000),
};
MemDisplayUnit unit = (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit];
for (auto& nv : marikoMaxEmcClock)
if (nv.name != "Disabled")
nv.name = formatMemClockKhzLabel(nv.value, unit);
addConfigButton(KipConfigValue_marikoEmcMaxClock, "Ram Max Clock", ValueRange(0, 1, 1, "", 1), "Ram Max Clock", &thresholdsDisabled, {}, marikoMaxEmcClock, false, true);
}
@@ -1291,21 +1321,13 @@ protected:
ValueThresholds thresholdsDisabled(0, 0);
// 1600000, 1331200, 1065600, 800000, 665600, 408000, 204000
MemDisplayUnit unit = (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit];
tsl::elm::ListItem* ramItem665 = new tsl::elm::ListItem("665 MHz");
this->listElement->addItem(ramItem665);
tsl::elm::ListItem* ramItem800 = new tsl::elm::ListItem("800 MHz");
this->listElement->addItem(ramItem800);
tsl::elm::ListItem* ramItem1065 = new tsl::elm::ListItem("1065 MHz");
this->listElement->addItem(ramItem1065);
tsl::elm::ListItem* ramItem1331 = new tsl::elm::ListItem("1331 MHz");
this->listElement->addItem(ramItem1331);
tsl::elm::ListItem* ramItem1600 = new tsl::elm::ListItem("1600 MHz");
this->listElement->addItem(ramItem1600);
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(665600, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(800000, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(1065600, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(1331200, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(1600000, unit)));
ValueThresholds eristaRamThresholds(2208000, 2304000);
@@ -1349,6 +1371,10 @@ protected:
NamedValue("2400 MHz", 2400000, "JEDEC."),
};
for (auto& nv : eristaMaxEmcClock)
if (nv.name != "Disabled")
nv.name = formatMemClockKhzLabel(nv.value, unit);
addConfigButtonS(KipConfigValue_eristaEmcMaxClock, "", ValueRange(0, 1, 1, "", 1), "", &eristaRamThresholds, {}, eristaMaxEmcClock, false, A_BTN, true);
addConfigButtonS(KipConfigValue_eristaEmcMaxClock1, "", ValueRange(0, 1, 1, "", 1), "", &eristaRamThresholds, {}, eristaMaxEmcClock, false, A_BTN, true);
addConfigButtonS(KipConfigValue_eristaEmcMaxClock2, "", ValueRange(0, 1, 1, "", 1), "", &eristaRamThresholds, {}, eristaMaxEmcClock, false, A_BTN, true);
@@ -1829,6 +1855,23 @@ void MiscGui::refresh() {
}
updateConfigToggles();
// relabel when display unit changes
MemDisplayUnit unit = (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit];
constexpr HocClkConfigValue emcKeys[] = {
KipConfigValue_marikoEmcMaxClock,
KipConfigValue_eristaEmcMaxClock,
KipConfigValue_eristaEmcMaxClock1,
KipConfigValue_eristaEmcMaxClock2,
};
for (auto key : emcKeys) {
auto it = this->configNamedValues.find(key);
if (it != this->configNamedValues.end()) {
for (auto& nv : it->second)
if (nv.value != 1600000)
nv.name = formatMemClockKhzLabel(nv.value, unit);
}
}
for (const auto& [configVal, button] : this->configButtons) {
uint64_t currentValue = this->configList->values[configVal];
const ValueRange& range = this->configRanges[configVal];

View File

@@ -41,6 +41,7 @@ protected:
std::map<HocClkConfigValue, std::tuple<tsl::elm::TrackBar*, tsl::elm::ListItem*, std::vector<uint64_t>>> configTrackbars;
std::set<HocClkConfigValue> configButtonSKeys;
std::map<HocClkConfigValue, std::string> configButtonSSubtext;
std::set<HocClkConfigValue> emcClockConfigs;
void addConfigToggle(HocClkConfigValue configVal, const char* altName, bool kip = false);
void addConfigButton(HocClkConfigValue configVal,