add sloppy configurator: todo fix crap
This commit is contained in:
@@ -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 := 1.3.0
|
APP_VERSION := 2.0.0
|
||||||
TARGET_VERSION := $(APP_VERSION)
|
TARGET_VERSION := $(APP_VERSION)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -876,6 +876,14 @@ protected:
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
std::vector<NamedValue> stepMode = {
|
||||||
|
NamedValue("66MHz", 0),
|
||||||
|
NamedValue("100MHz", 1),
|
||||||
|
NamedValue("Jedec", 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
addConfigButton(KipConfigValue_stepMode, "Step Mode", ValueRange(0, 0, 2, "", 0), "Step Mode", &thresholdsDisabled, {}, stepMode, false, true);
|
||||||
|
|
||||||
if (IsErista()) {
|
if (IsErista()) {
|
||||||
tsl::elm::ListItem* freqSubmenu = new tsl::elm::ListItem("RAM Frequency Editor");
|
tsl::elm::ListItem* freqSubmenu = new tsl::elm::ListItem("RAM Frequency Editor");
|
||||||
freqSubmenu->setTextColor(tsl::Color(255, 165, 0, 255));
|
freqSubmenu->setTextColor(tsl::Color(255, 165, 0, 255));
|
||||||
@@ -958,6 +966,7 @@ protected:
|
|||||||
addConfigButton(KipConfigValue_marikoEmcMaxClock, "Ram Max Clock", ValueRange(0, 1, 1, "", 1), "Ram Max Clock", &thresholdsDisabled, {}, marikoMaxEmcClock, false, true);
|
addConfigButton(KipConfigValue_marikoEmcMaxClock, "Ram Max Clock", ValueRange(0, 1, 1, "", 1), "Ram Max Clock", &thresholdsDisabled, {}, marikoMaxEmcClock, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tsl::elm::ListItem* latenciesSubmenu = new tsl::elm::ListItem("RAM Latency Editor");
|
tsl::elm::ListItem* latenciesSubmenu = new tsl::elm::ListItem("RAM Latency Editor");
|
||||||
latenciesSubmenu->setTextColor(tsl::Color(255, 165, 0, 255));
|
latenciesSubmenu->setTextColor(tsl::Color(255, 165, 0, 255));
|
||||||
latenciesSubmenu->setClickListener([](u64 keys) {
|
latenciesSubmenu->setClickListener([](u64 keys) {
|
||||||
@@ -1033,48 +1042,256 @@ public:
|
|||||||
RamLatenciesSubmenuGui() { }
|
RamLatenciesSubmenuGui() { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void normalizeLatencies(const HocClkConfigValue keysArr[4]) {
|
||||||
|
uint32_t maxClock = (uint32_t)this->configList->values[KipConfigValue_marikoEmcMaxClock];
|
||||||
|
uint32_t vals[4];
|
||||||
|
|
||||||
|
// 1. Fetch and resolve 0xFFFFFFFF
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
vals[i] = (uint32_t)this->configList->values[keysArr[i]];
|
||||||
|
if (vals[i] == 0xFFFFFFFFu) vals[i] = maxClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Backward Pass: If a higher tier is set, lower tiers must be <= that tier
|
||||||
|
uint32_t currentLimit = 0;
|
||||||
|
for (int i = 3; i >= 0; i--) {
|
||||||
|
if (vals[i] != 0) {
|
||||||
|
if (currentLimit != 0 && vals[i] > currentLimit) {
|
||||||
|
vals[i] = currentLimit;
|
||||||
|
}
|
||||||
|
currentLimit = vals[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Forward Pass: Ensure monotonic increase for active tiers
|
||||||
|
uint32_t last = 0;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (vals[i] == 0) continue;
|
||||||
|
|
||||||
|
if (vals[i] < last) vals[i] = last;
|
||||||
|
if (vals[i] > maxClock) vals[i] = maxClock;
|
||||||
|
|
||||||
|
last = vals[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Save back to config
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
this->configList->values[keysArr[i]] = vals[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void listUI() override {
|
void listUI() override {
|
||||||
ValueThresholds thresholdsDisabled(0, 0);
|
ValueThresholds thresholdsDisabled(0, 0);
|
||||||
|
|
||||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Memory Latencies"));
|
if (IsErista()) {
|
||||||
|
std::vector<NamedValue> rlLabels = { NamedValue("1333 RL", 28), NamedValue("1600 RL", 32), NamedValue("1866 RL", 36), NamedValue("2133 RL", 40) };
|
||||||
|
std::vector<NamedValue> wlLabels = { NamedValue("1333 WL", 12), NamedValue("1600 WL", 14), NamedValue("1866 WL", 16), NamedValue("2133 WL", 18) };
|
||||||
|
|
||||||
std::vector<NamedValue> rlLabels = {
|
addConfigButton(KipConfigValue_mem_burst_read_latency, "Read Latency", ValueRange(0, 6, 1, "", 0), "Read Latency", &thresholdsDisabled, {}, rlLabels, false, true);
|
||||||
NamedValue("1333 RL", 28),
|
addConfigButton(KipConfigValue_mem_burst_write_latency, "Write Latency", ValueRange(0, 6, 1, "", 0), "Write Latency", &thresholdsDisabled, {}, wlLabels, false, true);
|
||||||
NamedValue("1600 RL", 32),
|
return;
|
||||||
NamedValue("1866 RL", 36),
|
}
|
||||||
NamedValue("2133 RL", 40)
|
|
||||||
|
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||||
|
if (R_FAILED(rc)) [[unlikely]] {
|
||||||
|
FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t maxClock = (uint32_t)this->configList->values[KipConfigValue_marikoEmcMaxClock];
|
||||||
|
RamDisplayUnit unit = (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit];
|
||||||
|
|
||||||
|
static const std::vector<uint32_t> kFreqOptions = {
|
||||||
|
1633000, 1666000, 1700000, 1733000, 1766000, 1800000,
|
||||||
|
1833000, 1866000, 1900000, 1933000, 1966000, 1996800, 2000000,
|
||||||
|
2033000, 2066000, 2100000, 2133000, 2166000, 2200000, 2233000,
|
||||||
|
2266000, 2300000, 2333000, 2366000, 2400000, 2433000, 2466000,
|
||||||
|
2500000, 2533000, 2566000, 2600000, 2633000, 2666000, 2700000,
|
||||||
|
2733000, 2766000, 2800000, 2833000, 2866000, 2900000, 2933000,
|
||||||
|
2966000, 3000000, 3033000, 3066000, 3100000, 3133000, 3166000,
|
||||||
|
3200000, 3233000, 3266000, 3300000,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<NamedValue> wlLabels = {
|
static const HocClkConfigValue kLatencyRKeys[4] = {
|
||||||
NamedValue("1333 WL", 12),
|
KipConfigValue_read_latency_1333,
|
||||||
NamedValue("1600 WL", 14),
|
KipConfigValue_read_latency_1600,
|
||||||
NamedValue("1866 WL", 16),
|
KipConfigValue_read_latency_1866,
|
||||||
NamedValue("2133 WL", 18)
|
KipConfigValue_read_latency_2133,
|
||||||
|
};
|
||||||
|
static const HocClkConfigValue kLatencyWKeys[4] = {
|
||||||
|
KipConfigValue_write_latency_1333,
|
||||||
|
KipConfigValue_write_latency_1600,
|
||||||
|
KipConfigValue_write_latency_1866,
|
||||||
|
KipConfigValue_write_latency_2133,
|
||||||
};
|
};
|
||||||
|
|
||||||
addConfigButton(
|
static const char* kTierLabels[4] = { "1333 Latency Max", "1600 Latency Max", "1866 Latency Max", "2133 Latency Max" };
|
||||||
KipConfigValue_mem_burst_read_latency,
|
|
||||||
"Read Latency",
|
|
||||||
ValueRange(0, 6, 1, "", 0),
|
|
||||||
"Read Latency",
|
|
||||||
&thresholdsDisabled,
|
|
||||||
{},
|
|
||||||
rlLabels,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
addConfigButton(
|
auto buildNamedValues = [&](int tierIdx) -> std::vector<NamedValue> {
|
||||||
KipConfigValue_mem_burst_write_latency,
|
std::vector<NamedValue> nv;
|
||||||
"Write Latency",
|
nv.push_back(NamedValue("-", 0u));
|
||||||
ValueRange(0, 6, 1, "", 0),
|
if (tierIdx == 3) {
|
||||||
"Write Latency",
|
nv.push_back(NamedValue(formatMemClockKhzLabel(maxClock, unit), maxClock));
|
||||||
&thresholdsDisabled,
|
nv.push_back(NamedValue(formatMemClockKhzLabel(maxClock, unit), 0xFFFFFFFFu));
|
||||||
{},
|
} else {
|
||||||
wlLabels,
|
for (uint32_t freq : kFreqOptions) {
|
||||||
false,
|
if (freq > maxClock) continue;
|
||||||
true
|
nv.push_back(NamedValue(formatMemClockKhzLabel(freq, unit), freq));
|
||||||
);
|
}
|
||||||
|
nv.push_back(NamedValue(formatMemClockKhzLabel(maxClock, unit), maxClock));
|
||||||
|
nv.push_back(NamedValue(formatMemClockKhzLabel(maxClock, unit), 0xFFFFFFFFu));
|
||||||
|
}
|
||||||
|
return nv;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto makeValueText = [&](uint32_t rawVal) -> std::string {
|
||||||
|
if (rawVal == 0) return "-";
|
||||||
|
if (rawVal == 0xFFFFFFFFu) return formatMemClockKhzLabel(maxClock, unit);
|
||||||
|
return formatMemClockKhzLabel(rawVal, unit);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto addLatencyRow = [&](const char* label, int tierIdx, const HocClkConfigValue keysArr[4]) {
|
||||||
|
HocClkConfigValue thisKey = keysArr[tierIdx];
|
||||||
|
uint32_t currentVal = (uint32_t)this->configList->values[thisKey];
|
||||||
|
|
||||||
|
tsl::elm::ListItem* item = new tsl::elm::ListItem(label);
|
||||||
|
item->setTextColor(tsl::Color(255, 165, 0, 255));
|
||||||
|
item->setValue(makeValueText(currentVal));
|
||||||
|
|
||||||
|
item->setClickListener([this, tierIdx, thisKey, keysArr](u64 keys) -> bool {
|
||||||
|
if ((keys & HidNpadButton_A) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32_t vals[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
vals[i] = (uint32_t)this->configList->values[keysArr[i]];
|
||||||
|
|
||||||
|
uint32_t maxClock = (uint32_t)this->configList->values[KipConfigValue_marikoEmcMaxClock];
|
||||||
|
RamDisplayUnit unit = (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit];
|
||||||
|
|
||||||
|
auto resolveVal = [maxClock](uint32_t v) -> uint32_t {
|
||||||
|
return (v == 0xFFFFFFFFu) ? maxClock : v;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tierIdx == 3) {
|
||||||
|
bool maxOccupied = false;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (resolveVal(vals[i]) == maxClock) {
|
||||||
|
maxOccupied = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<NamedValue> opts;
|
||||||
|
opts.push_back(NamedValue("-", 0u));
|
||||||
|
|
||||||
|
if (!maxOccupied) {
|
||||||
|
opts.push_back(NamedValue(formatMemClockKhzLabel(maxClock, unit), maxClock));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t displayCurrent = resolveVal(vals[3]);
|
||||||
|
if (maxOccupied && displayCurrent == maxClock) {
|
||||||
|
displayCurrent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsl::changeTo<ValueChoiceGui>(
|
||||||
|
displayCurrent,
|
||||||
|
ValueRange(0, 0, 1, "", 1),
|
||||||
|
std::string("2133 Latency Max"),
|
||||||
|
[this, thisKey, keysArr](uint32_t chosen) -> bool {
|
||||||
|
this->configList->values[thisKey] = chosen;
|
||||||
|
Result rc = hocclkIpcSetConfigValues(this->configList);
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sendKipData();
|
||||||
|
this->lastContextUpdate = armGetSystemTick();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
ValueThresholds(), false,
|
||||||
|
std::map<uint32_t, std::string>{},
|
||||||
|
opts,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lowerBound = 0;
|
||||||
|
for (int i = 0; i < tierIdx; i++) {
|
||||||
|
uint32_t v = resolveVal(vals[i]);
|
||||||
|
if (v != 0 && v > lowerBound)
|
||||||
|
lowerBound = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t upperBound = 0;
|
||||||
|
for (int i = tierIdx + 1; i < 4; i++) {
|
||||||
|
uint32_t v;
|
||||||
|
if (i == 3) {
|
||||||
|
uint32_t r = resolveVal(vals[i]);
|
||||||
|
v = (r != 0) ? maxClock : 0;
|
||||||
|
} else {
|
||||||
|
v = resolveVal(vals[i]);
|
||||||
|
}
|
||||||
|
if (v != 0 && (upperBound == 0 || v < upperBound))
|
||||||
|
upperBound = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<NamedValue> opts;
|
||||||
|
opts.push_back(NamedValue("-", 0u));
|
||||||
|
for (uint32_t freq : kFreqOptions) {
|
||||||
|
if (freq <= lowerBound) continue;
|
||||||
|
if (freq > maxClock) continue;
|
||||||
|
if (upperBound != 0 && freq >= upperBound) continue;
|
||||||
|
opts.push_back(NamedValue(formatMemClockKhzLabel(freq, unit), freq));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t displayCurrent = resolveVal(vals[tierIdx]);
|
||||||
|
bool currentInList = false;
|
||||||
|
for (auto& nv : opts)
|
||||||
|
if (nv.value == displayCurrent) { currentInList = true; break; }
|
||||||
|
if (!currentInList) displayCurrent = 0;
|
||||||
|
|
||||||
|
tsl::changeTo<ValueChoiceGui>(
|
||||||
|
displayCurrent,
|
||||||
|
ValueRange(0, 0, 1, "", 1),
|
||||||
|
std::string("Latency Max"),
|
||||||
|
[this, thisKey, keysArr](uint32_t chosen) -> bool {
|
||||||
|
this->configList->values[thisKey] = chosen;
|
||||||
|
normalizeLatencies(keysArr);
|
||||||
|
Result rc = hocclkIpcSetConfigValues(this->configList);
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sendKipData();
|
||||||
|
this->lastContextUpdate = armGetSystemTick();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
ValueThresholds(), false,
|
||||||
|
std::map<uint32_t, std::string>{},
|
||||||
|
opts,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
this->listElement->addItem(item);
|
||||||
|
this->configButtons[thisKey] = item;
|
||||||
|
this->configRanges[thisKey] = ValueRange(0, 0, 1, "", 1);
|
||||||
|
this->configNamedValues[thisKey] = buildNamedValues(tierIdx);
|
||||||
|
};
|
||||||
|
|
||||||
|
this->listElement->addItem(new tsl::elm::CategoryHeader("Read Latency"));
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
addLatencyRow(kTierLabels[i], i, kLatencyRKeys);
|
||||||
|
|
||||||
|
this->listElement->addItem(new tsl::elm::CategoryHeader("Write Latency"));
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
addLatencyRow(kTierLabels[i], i, kLatencyWKeys);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user