From 12947d3dc4f21647b1e74288b64538d26a344f5f Mon Sep 17 00:00:00 2001 From: souldbminersmwc Date: Sun, 21 Dec 2025 12:56:36 -0500 Subject: [PATCH] sysclk: refactor misc gui --- .../sys-clk/overlay/src/ui/gui/misc_gui.cpp | 1421 ++++++++--------- Source/sys-clk/overlay/src/ui/gui/misc_gui.h | 4 +- .../sys-clk/sysmodule/src/clock_manager.cpp | 2 +- .../contents/00FF0000636C6BFF/exefs.nsp | Bin 199582 -> 199531 bytes 4 files changed, 699 insertions(+), 728 deletions(-) diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp index 350ffd5b..7745e7a3 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -1,7 +1,4 @@ /* - * Copyright (C) Switch-OC-Suite - * - * Copyright (c) 2023 hanai3Bi * * Copyright (c) Souldbminer and Horizon OC Contributors * @@ -27,6 +24,13 @@ #include #include +class RamSubmenuGui; +class RamTimingsSubmenuGui; +class RamLatenciesSubmenuGui; +class CpuSubmenuGui; +class GpuSubmenuGui; +class GpuCustomTableSubmenuGui; + MiscGui::MiscGui() { this->configList = new SysClkConfigValueList {}; @@ -71,14 +75,25 @@ void MiscGui::addConfigButton(SysClkConfigValue configVal, uint64_t currentValue = this->configList->values[configVal]; char valueText[32]; - if (currentValue == 0) { + if (currentValue == 0 && showDefaultValue) { snprintf(valueText, sizeof(valueText), "%s", VALUE_DEFAULT_TEXT); } else { - uint64_t displayValue = currentValue / range.divisor; - if (!range.suffix.empty()) { - snprintf(valueText, sizeof(valueText), "%lu %s", displayValue, range.suffix.c_str()); - } else { - snprintf(valueText, sizeof(valueText), "%lu", displayValue); + bool foundNamedValue = false; + for (const auto& namedValue : namedValues) { + if (currentValue == namedValue.value) { + snprintf(valueText, sizeof(valueText), "%s", namedValue.name.c_str()); + foundNamedValue = true; + break; + } + } + + if (!foundNamedValue) { + uint64_t displayValue = currentValue / range.divisor; + if (!range.suffix.empty()) { + snprintf(valueText, sizeof(valueText), "%lu %s", displayValue, range.suffix.c_str()); + } else { + snprintf(valueText, sizeof(valueText), "%lu", displayValue); + } } } listItem->setValue(valueText); @@ -242,8 +257,7 @@ void MiscGui::listUI() {2295000000, "Absolute Max"}, }; - // ========== MISC CATEGORY (TOP) ========== - this->listElement->addItem(new tsl::elm::CategoryHeader("Misc Settings")); + this->listElement->addItem(new tsl::elm::CategoryHeader("Settings")); addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr); addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr); @@ -275,7 +289,7 @@ void MiscGui::listUI() ValueRange(4000, 8000, 100, "mW", 1), "Power", &tdpThresholdsLite, - labels_pwr_r + labels_pwr_l ); ValueThresholds throttleThresholds(70, 80); @@ -328,718 +342,38 @@ void MiscGui::listUI() }); this->listElement->addItem(saveBtn); - this->listElement->addItem(new tsl::elm::CategoryHeader("RAM/Memory Settings")); + tsl::elm::ListItem* ramSubmenu = new tsl::elm::ListItem("RAM Settings"); + ramSubmenu->setClickListener([](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo(); + return true; + } + return false; + }); + this->listElement->addItem(ramSubmenu); - addConfigButton( - KipConfigValue_emcDvbShift, - "DVB Shift", - ValueRange(0, 10, 1, "", 1), - "DVB Shift", - &thresholdsDisabled, - {}, - {}, - false - ); + tsl::elm::ListItem* cpuSubmenu = new tsl::elm::ListItem("CPU Settings"); + cpuSubmenu->setClickListener([](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo(); + return true; + } + return false; + }); + this->listElement->addItem(cpuSubmenu); + + tsl::elm::ListItem* gpuSubmenu = new tsl::elm::ListItem("GPU Settings"); + gpuSubmenu->setClickListener([](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo(); + return true; + } + return false; + }); + this->listElement->addItem(gpuSubmenu); + + this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); - std::map emc_freq_label_e = { - {133120000, "Handheld"}, - {160000000, "Docked & Safe Max"}, - {213100000, "JEDEC Max"}, - {236000000, "Absolute Max"}, - }; - - std::map emc_freq_label_m = { - {133120000, "Handheld"}, - {160000000, "Docked"}, - {186600000, "Safe Max (3733MT/s)"}, - {213300000, "Safe Max (4266MT/s)"}, - {320000000, "Unsafe Max"}, - {350000000, "Absolute Max"}, - }; - - // Uncomment these if you want max memory clock options - // if(IsMariko()) { - // addFreqButton(HocClkConfigValue_MarikoMaxMemClock, nullptr, SysClkModule_MEM, emc_freq_label_m); - // } else { - // addFreqButton(HocClkConfigValue_EristaMaxMemClock, nullptr, SysClkModule_MEM, emc_freq_label_e); - // } - - // std::vector autoAdjOptions = { - // NamedValue("AUTO_ADJ", 0), - // NamedValue("AUTO_ADJ_BL", 1) - // }; - - // addConfigButton( - // KipConfigValue_mtcConf, - // "MTC Configuration", - // ValueRange(0, 1, 1, "", 1), - // "MTC Configuration", - // &thresholdsDisabled, - // {}, - // autoAdjOptions, - // false - // ); - - addConfigToggle(KipConfigValue_hpMode, "HP Mode"); - - std::map emc_voltage_label = { - {1100000, "Default (Mariko)"}, - {1125000, "Default (Erista)"}, - {1175000, "Rating"}, - {1212500, "Safe Max (Mariko)"}, - {1237500, "Safe Max (Erista)"}, - {1250000, "Unsafe Max"}, - }; - - ValueThresholds vdd2Thresholds(1212500, 1250000); - addConfigButton( - KipConfigValue_commonEmcMemVolt, - "EMC VDD2 Voltage", - ValueRange(912500, 1350000, 12500, "mV", 1000, 1), - "Voltage", - &vdd2Thresholds, - emc_voltage_label, - noNamedValues, - false - ); - - std::vector marikoMaxEmcClock = { - NamedValue("1600MHz", 1600000), - NamedValue("1633MHz", 1633000), - NamedValue("1666MHz", 1666000), - NamedValue("1700MHz", 1700000), - NamedValue("1733MHz", 1733000), - NamedValue("1766MHz", 1766000), - NamedValue("1800MHz", 1800000), - NamedValue("1833MHz", 1833000), - NamedValue("1862MHz", 1862400), - NamedValue("1866MHz", 1866000), - NamedValue("1900MHz", 1900000), - NamedValue("1933MHz", 1933000), - NamedValue("1966MHz", 1966000), - NamedValue("1996MHz", 1996800), - NamedValue("2000MHz", 2000000), - NamedValue("2033MHz", 2033000), - NamedValue("2066MHz", 2066000), - NamedValue("2100MHz", 2100000), - NamedValue("2133MHz", 2133000), - NamedValue("2166MHz", 2166000), - NamedValue("2200MHz", 2200000), - NamedValue("2233MHz", 2233000), - NamedValue("2266MHz", 2266000), - NamedValue("2300MHz", 2300000), - NamedValue("2333MHz", 2333000), - NamedValue("2366MHz", 2366000), - NamedValue("2400MHz", 2400000), - NamedValue("2433MHz", 2433000), - NamedValue("2466MHz", 2466000), - NamedValue("2500MHz", 2500000), - NamedValue("2533MHz", 2533000), - NamedValue("2566MHz", 2566000), - NamedValue("2600MHz", 2600000), - NamedValue("2633MHz", 2633000), - NamedValue("2666MHz", 2666000), - NamedValue("2700MHz", 2700000), - NamedValue("2733MHz", 2733000), - NamedValue("2766MHz", 2766000), - NamedValue("2800MHz", 2800000), - NamedValue("2833MHz", 2833000), - NamedValue("2866MHz", 2866000), - NamedValue("2900MHz", 2900000), - NamedValue("2933MHz", 2933000), - NamedValue("2966MHz", 2966000), - NamedValue("3000MHz", 3000000), - NamedValue("3033MHz", 3033000), - NamedValue("3066MHz", 3066000), - NamedValue("3100MHz", 3100000), - NamedValue("3133MHz", 3133000), - NamedValue("3166MHz", 3166000), - NamedValue("3200MHz", 3200000), - NamedValue("3233MHz (Needs high Speedo/PLL)", 3233000), - NamedValue("3266MHz (Needs high Speedo/PLL)", 3266000), - NamedValue("3300MHz (Needs high Speedo/PLL)", 3300000), - NamedValue("3333MHz (Needs extreme Speedo/PLL)", 3333000), - NamedValue("3366MHz (Needs extreme Speedo/PLL)", 3366000), - NamedValue("3400MHz (Needs extreme Speedo/PLL)", 3400000), - NamedValue("3433MHz (Needs ridiculous Speedo/PLL)", 3433000), - NamedValue("3466MHz (Needs ridiculous Speedo/PLL)", 3466000), - NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000), - }; - - std::vector eristaMaxEmcClock = { - NamedValue("1600MHz", 1600000), - NamedValue("1633MHz", 1633000), - NamedValue("1666MHz", 1666000), - NamedValue("1700MHz", 1700000), - NamedValue("1733MHz", 1733000), - NamedValue("1766MHz", 1766000), - NamedValue("1800MHz", 1800000), - NamedValue("1833MHz", 1833000), - NamedValue("1866MHz", 1866000), - NamedValue("1900MHz", 1900000), - NamedValue("1933MHz", 1933000), - NamedValue("1966MHz", 1966000), - NamedValue("2000MHz", 2000000), - NamedValue("2033MHz", 2033000), - NamedValue("2066MHz", 2066000), - NamedValue("2100MHz", 2100000), - NamedValue("2133MHz", 2133000), - NamedValue("2166MHz", 2166000), - NamedValue("2200MHz (high power draw!)", 2200000), - NamedValue("2233MHz (high power draw!)", 2233000), - NamedValue("2266MHz (high power draw!)", 2266000), - NamedValue("2300MHz (high power draw!)", 2300000), - NamedValue("2333MHz (high power draw!)", 2333000), - NamedValue("2366MHz (high power draw!)", 2366000), - NamedValue("2400MHz (high power draw!)", 2400000), - }; - - if(IsErista()) { - addConfigButton( - KipConfigValue_eristaEmcMaxClock, - "EMC Max Clock", - ValueRange(0, 1, 1, "", 1), - "EMC Max Clock", - &thresholdsDisabled, - {}, - eristaMaxEmcClock, - false - ); - } else { - addConfigButton( - KipConfigValue_marikoEmcMaxClock, - "EMC Max Clock", - ValueRange(0, 1, 1, "", 1), - "EMC Max Clock", - &thresholdsDisabled, - {}, - marikoMaxEmcClock, - false - ); - addConfigButton( - KipConfigValue_marikoEmcVddqVolt, - "EMC VDDQ Voltage", - ValueRange(550000, 700000, 5000, "mV", 1000), - "EMC VDDQ Voltage", - &thresholdsDisabled, - {}, - {}, - false - ); - } - - // Memory Timings - addConfigButton(KipConfigValue_t1_tRCD, "t1 tRCD", ValueRange(0, 8, 1, "", 1), "tRCD", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t2_tRP, "t2 tRP", ValueRange(0, 8, 1, "", 1), "tRP", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t3_tRAS, "t3 tRAS", ValueRange(0, 10, 1, "", 1), "tRAS", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t4_tRRD, "t4 tRRD", ValueRange(0, 7, 1, "", 1), "tRRD", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t5_tRFC, "t5 tRFC", ValueRange(0, 11, 1, "", 1), "tRFC", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t6_tRTW, "t6 tRTW", ValueRange(0, 10, 1, "", 1), "tRTW", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t7_tWTR, "t7 tWTR", ValueRange(0, 10, 1, "", 1), "tWTR", &thresholdsDisabled, {}, {}, false); - addConfigButton(KipConfigValue_t8_tREFI, "t8 tREFI", ValueRange(0, 6, 1, "", 1), "tREFI", &thresholdsDisabled, {}, {}, false); - - std::vector rlLabels = { - NamedValue("1600BL", 0), - NamedValue("1866BL", 4), - NamedValue("2133BL", 8) - }; - - std::vector wlLabels = { - NamedValue("1600BL", 0), - NamedValue("1866BL", 2), - NamedValue("2133BL", 4) - }; - - addConfigButton( - KipConfigValue_mem_burst_read_latency, - "Read Latency", - ValueRange(0, 6, 1, "", 0), - "Read Latency", - &thresholdsDisabled, - {}, - rlLabels, - false - ); - - addConfigButton( - KipConfigValue_mem_burst_write_latency, - "Write Latency", - ValueRange(0, 6, 1, "", 0), - "Write Latency", - &thresholdsDisabled, - {}, - wlLabels, - false - ); - - - - this->listElement->addItem(new tsl::elm::CategoryHeader("CPU Settings")); - - ValueThresholds mCpuVoltThresholds(1160, 1180); - - if(IsErista()) { - addConfigButton( - KipConfigValue_eristaCpuUV, - "CPU UV", - ValueRange(0, 5, 1, "", 1), - "CPU UV", - &thresholdsDisabled, - {}, - {}, - true - ); - addConfigButton( - KipConfigValue_eristaCpuMaxVolt, - "CPU Max Voltage", - ValueRange(1120, 1235, 5, "mV", 1), - "CPU Max Voltage", - &thresholdsDisabled, - {}, - {}, - false - ); - addConfigButton( - KipConfigValue_eristaCpuVmin, - "CPU VMIN", - ValueRange(700, 900, 5, "mV", 1), - "CPU VMIN", - &thresholdsDisabled, - {}, - {}, - false - ); - addConfigToggle(KipConfigValue_eristaCpuUnlock, "CPU Unlock"); - } else { - std::vector marikoTableConf = { - NamedValue("Auto", 0), - NamedValue("Default", 1), - NamedValue("1581MHz Tbreak", 2), - NamedValue("1683MHz Tbreak", 3), - NamedValue("Extreme UV Table", 4) - }; - - addConfigButton( - KipConfigValue_tableConf, - "CPU UV Table", - ValueRange(0, 12, 1, "", 0), - "CPU UV Table", - &thresholdsDisabled, - {}, - marikoTableConf, - false - ); - addConfigButton( - KipConfigValue_marikoCpuUVLow, - "CPU Low UV", - ValueRange(0, 8, 1, "", 1), - "CPU Low UV", - &thresholdsDisabled, - {}, - {}, - false - ); - addConfigButton( - KipConfigValue_marikoCpuUVHigh, - "CPU High UV", - ValueRange(0, 12, 1, "", 1), - "CPU High UV", - &thresholdsDisabled, - {}, - {}, - false - ); - addConfigButton( - KipConfigValue_marikoCpuMaxVolt, - "CPU Max Voltage", - ValueRange(1000, 1235, 5, "mV", 1), - "CPU Max Voltage", - &mCpuVoltThresholds, - {}, - {}, - false - ); - - std::vector maxClkOptions = { - NamedValue("1963MHz", 1963000), - NamedValue("2397MHz", 2397000), - NamedValue("2499MHz", 2499000), - NamedValue("2601MHz", 2601000), - NamedValue("2703MHz", 2703000), - }; - - addConfigButton( - KipConfigValue_marikoCpuMaxClock, - "CPU Max Clock", - ValueRange(0, 0, 1, "", 1), - "CPU Max Voltage", - &thresholdsDisabled, - {}, - maxClkOptions, - false - ); - - addConfigButton( - KipConfigValue_marikoCpuLowVmin, - "CPU Low VMIN", - ValueRange(550, 750, 5, "mV", 1), - "CPU VMIN", - &thresholdsDisabled, - {}, - {}, - false - ); - - addConfigButton( - KipConfigValue_marikoCpuHighVmin, - "CPU High VMIN", - ValueRange(650, 850, 5, "mV", 1), - "CPU VMIN", - &thresholdsDisabled, - {}, - {}, - false - ); - } - - - // ========== GPU CATEGORY ========== - this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Settings")); - - std::map gpu_freq_label_e = { - {76800000, "Boost Mode"}, - {307200000, "Handheld"}, - {384000000, "Handheld"}, - {460800000, "Handheld Safe Max"}, - {768000000, "Docked"}, - {844000000, "Safe Max"}, - {998400000, "Unsafe Max"}, - {1075200000, "Absolute Max"}, - }; - - std::map gpu_freq_label_m = { - {76800000, "Boost Mode"}, - {307200000, "Handheld"}, - {384000000, "Handheld"}, - {460800000, "Handheld"}, - {614400000, "Handheld Safe Max"}, - {768000000, "Docked"}, - {1075200000, "Safe Max"}, - {1305600000, "Unsafe Max"}, - {1536000000, "Absolute Max"}, - }; - - // Uncomment these if you want max GPU clock options - // if(IsMariko()) { - // addFreqButton(HocClkConfigValue_MarikoMaxGpuClock, nullptr, SysClkModule_GPU, gpu_freq_label_m); - // } else { - // addFreqButton(HocClkConfigValue_EristaMaxGpuClock, nullptr, SysClkModule_GPU, gpu_freq_label_e); - // } - - std::vector gpuUvConf = { - NamedValue("No UV", 0), - NamedValue("SLT Table", 1), - NamedValue("HiOPT Table", 2), - }; - - ValueThresholds MgpuVmaxThresholds(800, 850); - ValueThresholds EgpuVmaxThresholds(950, 975); - - if(IsErista()) { - addConfigButton( - KipConfigValue_eristaGpuUV, - "GPU Undervolt Table", - ValueRange(0, 1, 1, "", 1), - "GPU Undervolt Table", - &thresholdsDisabled, - {}, - gpuUvConf, - false - ); - addConfigButton( - KipConfigValue_eristaGpuVmin, - "GPU VMIN", - ValueRange(700, 875, 5, "mV", 1), - "GPU VMIN", - &thresholdsDisabled, - {}, - {}, - false - ); - } else { - addConfigButton( - KipConfigValue_marikoGpuUV, - "GPU Undervolt Table", - ValueRange(0, 1, 1, "", 1), - "GPU Undervolt Table", - &thresholdsDisabled, - {}, - gpuUvConf, - false - ); - - addConfigButton( - KipConfigValue_marikoGpuVmin, - "GPU VMIN", - ValueRange(480, 825, 5, "mV", 1), - "GPU VMIN", - &thresholdsDisabled, - {}, - {}, - false - ); - - addConfigButton( - KipConfigValue_marikoGpuVmax, - "GPU VMAX", - ValueRange(750, 960, 5, "mV", 1), - "GPU VMAX", - &MgpuVmaxThresholds, - {}, - {}, - false - ); - } - - addConfigButton( - KipConfigValue_commonGpuVoltOffset, - "GPU Volt Offset", - ValueRange(0, 50, 5, "mV", 1), - "GPU Volt Offset", - &thresholdsDisabled, - {}, - {}, - false - ); - - if(IsMariko()) - addConfigToggle(KipConfigValue_marikoGpuFullUnlock, "GPU Full Unlock"); - - // GPU Custom Table - this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Custom Table")); - - std::vector mGpuVolts = { - NamedValue("Disabled", 2000), - NamedValue("Auto", 0), - NamedValue("480mV", 480), - NamedValue("485mV", 485), - NamedValue("490mV", 490), - NamedValue("495mV", 495), - NamedValue("500mV", 500), - NamedValue("505mV", 505), - NamedValue("510mV", 510), - NamedValue("515mV", 515), - NamedValue("520mV", 520), - NamedValue("525mV", 525), - NamedValue("530mV", 530), - NamedValue("535mV", 535), - NamedValue("540mV", 540), - NamedValue("545mV", 545), - NamedValue("550mV", 550), - NamedValue("555mV", 555), - NamedValue("560mV", 560), - NamedValue("565mV", 565), - NamedValue("570mV", 570), - NamedValue("575mV", 575), - NamedValue("580mV", 580), - NamedValue("585mV", 585), - NamedValue("590mV", 590), - NamedValue("595mV", 595), - NamedValue("600mV", 600), - NamedValue("605mV", 605), - NamedValue("610mV", 610), - NamedValue("615mV", 615), - NamedValue("620mV", 620), - NamedValue("625mV", 625), - NamedValue("630mV", 630), - NamedValue("635mV", 635), - NamedValue("640mV", 640), - NamedValue("645mV", 645), - NamedValue("650mV", 650), - NamedValue("655mV", 655), - NamedValue("660mV", 660), - NamedValue("665mV", 665), - NamedValue("670mV", 670), - NamedValue("675mV", 675), - NamedValue("680mV", 680), - NamedValue("685mV", 685), - NamedValue("690mV", 690), - NamedValue("695mV", 695), - NamedValue("700mV", 700), - NamedValue("705mV", 705), - NamedValue("710mV", 710), - NamedValue("715mV", 715), - NamedValue("720mV", 720), - NamedValue("725mV", 725), - NamedValue("730mV", 730), - NamedValue("735mV", 735), - NamedValue("740mV", 740), - NamedValue("745mV", 745), - NamedValue("750mV", 750), - NamedValue("755mV", 755), - NamedValue("760mV", 760), - NamedValue("765mV", 765), - NamedValue("770mV", 770), - NamedValue("775mV", 775), - NamedValue("780mV", 780), - NamedValue("785mV", 785), - NamedValue("790mV", 790), - NamedValue("795mV", 795), - NamedValue("800mV", 800), - NamedValue("805mV", 805), - NamedValue("810mV", 810), - NamedValue("815mV", 815), - NamedValue("820mV", 820), - NamedValue("825mV", 825), - NamedValue("830mV", 830), - NamedValue("835mV", 835), - NamedValue("840mV", 840), - NamedValue("845mV", 845), - NamedValue("850mV", 850), - NamedValue("855mV", 855), - NamedValue("860mV", 860), - NamedValue("865mV", 865), - NamedValue("870mV", 870), - NamedValue("875mV", 875), - NamedValue("880mV", 880), - NamedValue("885mV", 885), - NamedValue("890mV", 890), - NamedValue("895mV", 895), - NamedValue("900mV", 900), - NamedValue("905mV", 905), - NamedValue("910mV", 910), - NamedValue("915mV", 915), - NamedValue("920mV", 920), - NamedValue("925mV", 925), - NamedValue("930mV", 930), - NamedValue("935mV", 935), - NamedValue("940mV", 940), - NamedValue("945mV", 945), - NamedValue("950mV", 950), - NamedValue("955mV", 955), - NamedValue("960mV", 960), - }; - - std::vector eGpuVolts = { - NamedValue("Disabled", 2000), - NamedValue("Auto", 0), - NamedValue("700mV", 700), - NamedValue("705mV", 705), - NamedValue("710mV", 710), - NamedValue("715mV", 715), - NamedValue("720mV", 720), - NamedValue("725mV", 725), - NamedValue("730mV", 730), - NamedValue("735mV", 735), - NamedValue("740mV", 740), - NamedValue("745mV", 745), - NamedValue("750mV", 750), - NamedValue("755mV", 755), - NamedValue("760mV", 760), - NamedValue("765mV", 765), - NamedValue("770mV", 770), - NamedValue("775mV", 775), - NamedValue("780mV", 780), - NamedValue("785mV", 785), - NamedValue("790mV", 790), - NamedValue("795mV", 795), - NamedValue("800mV", 800), - NamedValue("805mV", 805), - NamedValue("810mV", 810), - NamedValue("815mV", 815), - NamedValue("820mV", 820), - NamedValue("825mV", 825), - NamedValue("830mV", 830), - NamedValue("835mV", 835), - NamedValue("840mV", 840), - NamedValue("845mV", 845), - NamedValue("850mV", 850), - NamedValue("855mV", 855), - NamedValue("860mV", 860), - NamedValue("865mV", 865), - NamedValue("870mV", 870), - NamedValue("875mV", 875), - NamedValue("880mV", 880), - NamedValue("885mV", 885), - NamedValue("890mV", 890), - NamedValue("895mV", 895), - NamedValue("900mV", 900), - NamedValue("905mV", 905), - NamedValue("910mV", 910), - NamedValue("915mV", 915), - NamedValue("920mV", 920), - NamedValue("925mV", 925), - NamedValue("930mV", 930), - NamedValue("935mV", 935), - NamedValue("940mV", 940), - NamedValue("945mV", 945), - NamedValue("950mV", 950), - NamedValue("955mV", 955), - NamedValue("960mV", 960), - NamedValue("965mV", 965), - NamedValue("970mV", 970), - NamedValue("975mV", 975), - NamedValue("980mV", 980), - NamedValue("985mV", 985), - NamedValue("990mV", 990), - NamedValue("995mV", 995), - }; - - if (IsMariko()) { - addConfigButton(KipConfigValue_g_volt_76800, "GPU Voltage (76.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_153600, "GPU Voltage (153.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_230400, "GPU Voltage (230.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_307200, "GPU Voltage (307.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_384000, "GPU Voltage (384.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_460800, "GPU Voltage (460.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_537600, "GPU Voltage (537.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_614400, "GPU Voltage (614.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_691200, "GPU Voltage (691.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_768000, "GPU Voltage (768.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_844800, "GPU Voltage (844.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_921600, "GPU Voltage (921.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_998400, "GPU Voltage (998.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1075200, "GPU Voltage (1075.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1152000, "GPU Voltage (1152.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1228800, "GPU Voltage (1228.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1267200, "GPU Voltage (1267.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1305600, "GPU Voltage (1305.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1344000, "GPU Voltage (1344.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1382400, "GPU Voltage (1382.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1420800, "GPU Voltage (1420.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1459200, "GPU Voltage (1459.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1497600, "GPU Voltage (1497.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_1536000, "GPU Voltage (1536.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); - } else { - addConfigButton(KipConfigValue_g_volt_e_76800, "GPU Voltage (76.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_115200, "GPU Voltage (115.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_153600, "GPU Voltage (153.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_192000, "GPU Voltage (192.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_230400, "GPU Voltage (230.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_268800, "GPU Voltage (268.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_307200, "GPU Voltage (307.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_345600, "GPU Voltage (345.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_384000, "GPU Voltage (384.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_422400, "GPU Voltage (422.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_460800, "GPU Voltage (460.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_499200, "GPU Voltage (499.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_537600, "GPU Voltage (537.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_576000, "GPU Voltage (576.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_614400, "GPU Voltage (614.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_652800, "GPU Voltage (652.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_691200, "GPU Voltage (691.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_729600, "GPU Voltage (729.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_768000, "GPU Voltage (768.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_806400, "GPU Voltage (806.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_844800, "GPU Voltage (844.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_883200, "GPU Voltage (883.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_921600, "GPU Voltage (921.6MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_960000, "GPU Voltage (960.0MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_998400, "GPU Voltage (998.4MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_1036800, "GPU Voltage (1036.8MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - addConfigButton(KipConfigValue_g_volt_e_1075200, "GPU Voltage (1075.2MHz)", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); - } - std::vector chargerCurrents = { NamedValue("Disabled", 0), NamedValue("1024mA", 1024), @@ -1054,9 +388,6 @@ void MiscGui::listUI() }; ValueThresholds chargerThresholds(2048, 2560); - - // ========== EXPERIMENTAL CATEGORY (BOTTOM) ========== - this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); addConfigButton( HorizonOCConfigValue_BatteryChargeCurrent, @@ -1073,6 +404,646 @@ void MiscGui::listUI() } +class RamSubmenuGui : public MiscGui { +public: + RamSubmenuGui() { } + +protected: + void listUI() override { + ValueThresholds thresholdsDisabled(0, 0); + std::vector noNamedValues = {}; + + this->listElement->addItem(new tsl::elm::CategoryHeader("RAM Settings")); + + addConfigToggle(KipConfigValue_hpMode, "HP Mode"); + + std::vector marikoMaxEmcClock = { + NamedValue("1600MHz", 1600000), + NamedValue("1633MHz", 1633000), + NamedValue("1666MHz", 1666000), + NamedValue("1700MHz", 1700000), + NamedValue("1733MHz", 1733000), + NamedValue("1766MHz", 1766000), + NamedValue("1800MHz", 1800000), + NamedValue("1833MHz", 1833000), + NamedValue("1862MHz", 1862400), + NamedValue("1866MHz", 1866000), + NamedValue("1900MHz", 1900000), + NamedValue("1933MHz", 1933000), + NamedValue("1966MHz", 1966000), + NamedValue("1996MHz", 1996800), + NamedValue("2000MHz", 2000000), + NamedValue("2033MHz", 2033000), + NamedValue("2066MHz", 2066000), + NamedValue("2100MHz", 2100000), + NamedValue("2133MHz", 2133000), + NamedValue("2166MHz", 2166000), + NamedValue("2200MHz", 2200000), + NamedValue("2233MHz", 2233000), + NamedValue("2266MHz", 2266000), + NamedValue("2300MHz", 2300000), + NamedValue("2333MHz", 2333000), + NamedValue("2366MHz", 2366000), + NamedValue("2400MHz", 2400000), + NamedValue("2433MHz", 2433000), + NamedValue("2466MHz", 2466000), + NamedValue("2500MHz", 2500000), + NamedValue("2533MHz", 2533000), + NamedValue("2566MHz", 2566000), + NamedValue("2600MHz", 2600000), + NamedValue("2633MHz", 2633000), + NamedValue("2666MHz", 2666000), + NamedValue("2700MHz", 2700000), + NamedValue("2733MHz", 2733000), + NamedValue("2766MHz", 2766000), + NamedValue("2800MHz", 2800000), + NamedValue("2833MHz", 2833000), + NamedValue("2866MHz", 2866000), + NamedValue("2900MHz", 2900000), + NamedValue("2933MHz", 2933000), + NamedValue("2966MHz", 2966000), + NamedValue("3000MHz", 3000000), + NamedValue("3033MHz", 3033000), + NamedValue("3066MHz", 3066000), + NamedValue("3100MHz", 3100000), + NamedValue("3133MHz", 3133000), + NamedValue("3166MHz", 3166000), + NamedValue("3200MHz", 3200000), + NamedValue("3233MHz (Needs high Speedo/PLL)", 3233000), + NamedValue("3266MHz (Needs high Speedo/PLL)", 3266000), + NamedValue("3300MHz (Needs high Speedo/PLL)", 3300000), + NamedValue("3333MHz (Needs extreme Speedo/PLL)", 3333000), + NamedValue("3366MHz (Needs extreme Speedo/PLL)", 3366000), + NamedValue("3400MHz (Needs extreme Speedo/PLL)", 3400000), + NamedValue("3433MHz (Needs ridiculous Speedo/PLL)", 3433000), + NamedValue("3466MHz (Needs ridiculous Speedo/PLL)", 3466000), + NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000), + }; + + std::vector eristaMaxEmcClock = { + NamedValue("1600MHz", 1600000), + NamedValue("1633MHz", 1633000), + NamedValue("1666MHz", 1666000), + NamedValue("1700MHz", 1700000), + NamedValue("1733MHz", 1733000), + NamedValue("1766MHz", 1766000), + NamedValue("1800MHz", 1800000), + NamedValue("1833MHz", 1833000), + NamedValue("1866MHz", 1866000), + NamedValue("1900MHz", 1900000), + NamedValue("1933MHz", 1933000), + NamedValue("1966MHz", 1966000), + NamedValue("2000MHz", 2000000), + NamedValue("2033MHz", 2033000), + NamedValue("2066MHz", 2066000), + NamedValue("2100MHz", 2100000), + NamedValue("2133MHz", 2133000), + NamedValue("2166MHz", 2166000), + NamedValue("2200MHz (high power draw!)", 2200000), + NamedValue("2233MHz (high power draw!)", 2233000), + NamedValue("2266MHz (high power draw!)", 2266000), + NamedValue("2300MHz (high power draw!)", 2300000), + NamedValue("2333MHz (high power draw!)", 2333000), + NamedValue("2366MHz (high power draw!)", 2366000), + NamedValue("2400MHz (high power draw!)", 2400000), + }; + + if(IsErista()) { + addConfigButton( + KipConfigValue_eristaEmcMaxClock, + "EMC Max Clock", + ValueRange(0, 1, 1, "", 1), + "EMC Max Clock", + &thresholdsDisabled, + {}, + eristaMaxEmcClock, + false + ); + } else { + addConfigButton( + KipConfigValue_marikoEmcMaxClock, + "EMC Max Clock", + ValueRange(0, 1, 1, "", 1), + "EMC Max Clock", + &thresholdsDisabled, + {}, + marikoMaxEmcClock, + false + ); + } + + std::map emc_voltage_label = { + {1100000, "Default (Mariko)"}, + {1125000, "Default (Erista)"}, + {1175000, "Rating"}, + {1212500, "Safe Max (Mariko)"}, + {1237500, "Safe Max (Erista)"}, + {1250000, "Unsafe Max"}, + }; + + ValueThresholds vdd2Thresholds(1212500, 1250000); + addConfigButton( + KipConfigValue_commonEmcMemVolt, + "EMC VDD2 Voltage", + ValueRange(912500, 1350000, 12500, "mV", 1000, 1), + "Voltage", + &vdd2Thresholds, + emc_voltage_label, + noNamedValues, + false + ); + + if(IsMariko()) { + addConfigButton( + KipConfigValue_marikoEmcVddqVolt, + "EMC VDDQ Voltage", + ValueRange(550000, 700000, 5000, "mV", 1000), + "EMC VDDQ Voltage", + &thresholdsDisabled, + {}, + {}, + false + ); + } + + addConfigButton( + KipConfigValue_emcDvbShift, + "DVB Shift", + ValueRange(0, 10, 1, "", 1), + "DVB Shift", + &thresholdsDisabled, + {}, + {}, + false + ); + + tsl::elm::ListItem* timingsSubmenu = new tsl::elm::ListItem("Memory Timings"); + timingsSubmenu->setClickListener([](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo(); + return true; + } + return false; + }); + this->listElement->addItem(timingsSubmenu); + + tsl::elm::ListItem* latenciesSubmenu = new tsl::elm::ListItem("Memory Latencies"); + latenciesSubmenu->setClickListener([](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo(); + return true; + } + return false; + }); + this->listElement->addItem(latenciesSubmenu); + } +}; + +class RamTimingsSubmenuGui : public MiscGui { +public: + RamTimingsSubmenuGui() { } + +protected: + void listUI() override { + ValueThresholds thresholdsDisabled(0, 0); + + this->listElement->addItem(new tsl::elm::CategoryHeader("Memory Timings")); + + addConfigButton(KipConfigValue_t1_tRCD, "t1 tRCD", ValueRange(0, 8, 1, "", 1), "tRCD", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t2_tRP, "t2 tRP", ValueRange(0, 8, 1, "", 1), "tRP", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t3_tRAS, "t3 tRAS", ValueRange(0, 10, 1, "", 1), "tRAS", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t4_tRRD, "t4 tRRD", ValueRange(0, 7, 1, "", 1), "tRRD", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t5_tRFC, "t5 tRFC", ValueRange(0, 11, 1, "", 1), "tRFC", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t6_tRTW, "t6 tRTW", ValueRange(0, 10, 1, "", 1), "tRTW", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t7_tWTR, "t7 tWTR", ValueRange(0, 10, 1, "", 1), "tWTR", &thresholdsDisabled, {}, {}, false); + addConfigButton(KipConfigValue_t8_tREFI, "t8 tREFI", ValueRange(0, 6, 1, "", 1), "tREFI", &thresholdsDisabled, {}, {}, false); + } +}; + +class RamLatenciesSubmenuGui : public MiscGui { +public: + RamLatenciesSubmenuGui() { } + +protected: + void listUI() override { + ValueThresholds thresholdsDisabled(0, 0); + + this->listElement->addItem(new tsl::elm::CategoryHeader("Memory Latencies")); + + std::vector rlLabels = { + NamedValue("1600BL", 0), + NamedValue("1866BL", 4), + NamedValue("2133BL", 8) + }; + + std::vector wlLabels = { + NamedValue("1600BL", 0), + NamedValue("1866BL", 2), + NamedValue("2133BL", 4) + }; + + addConfigButton( + KipConfigValue_mem_burst_read_latency, + "Read Latency", + ValueRange(0, 6, 1, "", 0), + "Read Latency", + &thresholdsDisabled, + {}, + rlLabels, + false + ); + + addConfigButton( + KipConfigValue_mem_burst_write_latency, + "Write Latency", + ValueRange(0, 6, 1, "", 0), + "Write Latency", + &thresholdsDisabled, + {}, + wlLabels, + false + ); + } +}; + +class CpuSubmenuGui : public MiscGui { +public: + CpuSubmenuGui() { } + +protected: + void listUI() override { + ValueThresholds thresholdsDisabled(0, 0); + + this->listElement->addItem(new tsl::elm::CategoryHeader("CPU Settings")); + + if(IsErista()) { + addConfigButton( + KipConfigValue_eristaCpuUV, + "CPU UV", + ValueRange(0, 5, 1, "", 1), + "CPU UV", + &thresholdsDisabled, + {}, + {}, + true + ); + addConfigToggle(KipConfigValue_eristaCpuUnlock, "CPU Unlock"); + addConfigButton( + KipConfigValue_eristaCpuVmin, + "CPU VMIN", + ValueRange(700, 900, 5, "mV", 1), + "CPU VMIN", + &thresholdsDisabled, + {}, + {}, + false + ); + addConfigButton( + KipConfigValue_eristaCpuMaxVolt, + "CPU Max Voltage", + ValueRange(1120, 1235, 5, "mV", 1), + "CPU Max Voltage", + &thresholdsDisabled, + {}, + {}, + false + ); + } else { + std::vector marikoTableConf = { + NamedValue("Auto", 0), + NamedValue("Default", 1), + NamedValue("1581MHz Tbreak", 2), + NamedValue("1683MHz Tbreak", 3), + NamedValue("Extreme UV Table", 4) + }; + + addConfigButton( + KipConfigValue_tableConf, + "CPU UV Table", + ValueRange(0, 12, 1, "", 0), + "CPU UV Table", + &thresholdsDisabled, + {}, + marikoTableConf, + false + ); + addConfigButton( + KipConfigValue_marikoCpuUVLow, + "CPU Low UV", + ValueRange(0, 8, 1, "", 1), + "CPU Low UV", + &thresholdsDisabled, + {}, + {}, + false + ); + addConfigButton( + KipConfigValue_marikoCpuUVHigh, + "CPU High UV", + ValueRange(0, 12, 1, "", 1), + "CPU High UV", + &thresholdsDisabled, + {}, + {}, + false + ); + + std::vector maxClkOptions = { + NamedValue("1963MHz", 1963000), + NamedValue("2397MHz", 2397000), + NamedValue("2499MHz", 2499000), + NamedValue("2601MHz", 2601000), + NamedValue("2703MHz", 2703000), + }; + + addConfigButton( + KipConfigValue_marikoCpuMaxClock, + "CPU Max Clock", + ValueRange(0, 0, 1, "", 1), + "CPU Max Clock", + &thresholdsDisabled, + {}, + maxClkOptions, + false + ); + + addConfigButton( + KipConfigValue_marikoCpuLowVmin, + "CPU Low VMIN", + ValueRange(550, 750, 5, "mV", 1), + "CPU VMIN", + &thresholdsDisabled, + {}, + {}, + false + ); + + addConfigButton( + KipConfigValue_marikoCpuHighVmin, + "CPU High VMIN", + ValueRange(650, 850, 5, "mV", 1), + "CPU VMIN", + &thresholdsDisabled, + {}, + {}, + false + ); + + ValueThresholds mCpuVoltThresholds(1160, 1180); + addConfigButton( + KipConfigValue_marikoCpuMaxVolt, + "CPU Max Voltage", + ValueRange(1000, 1235, 5, "mV", 1), + "CPU Max Voltage", + &mCpuVoltThresholds, + {}, + {}, + false + ); + } + } +}; + +class GpuSubmenuGui : public MiscGui { +public: + GpuSubmenuGui() { } + +protected: + void listUI() override { + ValueThresholds thresholdsDisabled(0, 0); + std::vector noNamedValues = {}; + + this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Settings")); + + std::vector gpuUvConf = { + NamedValue("No UV", 0), + NamedValue("SLT Table", 1), + NamedValue("HiOPT Table", 2), + }; + + if(IsErista()) { + addConfigButton( + KipConfigValue_eristaGpuUV, + "GPU Undervolt Table", + ValueRange(0, 1, 1, "", 1), + "GPU Undervolt Table", + &thresholdsDisabled, + {}, + gpuUvConf, + false + ); + addConfigButton( + KipConfigValue_eristaGpuVmin, + "GPU VMIN", + ValueRange(700, 875, 5, "mV", 1), + "GPU VMIN", + &thresholdsDisabled, + {}, + {}, + false + ); + } else { + addConfigButton( + KipConfigValue_marikoGpuUV, + "GPU Undervolt Table", + ValueRange(0, 1, 1, "", 1), + "GPU Undervolt Table", + &thresholdsDisabled, + {}, + gpuUvConf, + false + ); + + addConfigButton( + KipConfigValue_marikoGpuVmin, + "GPU VMIN", + ValueRange(480, 825, 5, "mV", 1), + "GPU VMIN", + &thresholdsDisabled, + {}, + {}, + false + ); + + ValueThresholds MgpuVmaxThresholds(800, 850); + addConfigButton( + KipConfigValue_marikoGpuVmax, + "GPU VMAX", + ValueRange(750, 960, 5, "mV", 1), + "GPU VMAX", + &MgpuVmaxThresholds, + {}, + {}, + false + ); + } + + addConfigButton( + KipConfigValue_commonGpuVoltOffset, + "GPU Volt Offset", + ValueRange(0, 50, 5, "mV", 1), + "GPU Volt Offset", + &thresholdsDisabled, + {}, + {}, + false + ); + + tsl::elm::ListItem* customTableSubmenu = new tsl::elm::ListItem("GPU Custom Table"); + customTableSubmenu->setClickListener([](u64 keys) { + if (keys & HidNpadButton_A) { + tsl::changeTo(); + return true; + } + return false; + }); + this->listElement->addItem(customTableSubmenu); + + addConfigToggle(KipConfigValue_marikoGpuFullUnlock, "GPU Full Unlock"); + tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { + renderer->drawString("\uE150 GPU Full Unlock can cause", false, x + 20, y + 30, 18, tsl::style::color::ColorText); + renderer->drawString("PERMANANT damage to your Switch!", false, x + 20, y + 50, 18, tsl::style::color::ColorText); + renderer->drawString("Only enable if you know what", false, x + 20, y + 80, 16, tsl::style::color::ColorText); + renderer->drawString("you're doing. Proceed at your", false, x + 20, y + 100, 16, tsl::style::color::ColorText); + renderer->drawString("own risk!", false, x + 20, y + 120, 16, tsl::style::color::ColorText); + }); + warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 150); + this->listElement->addItem(warningText); + } +}; + +class GpuCustomTableSubmenuGui : public MiscGui { +public: + GpuCustomTableSubmenuGui() { } + +protected: + void listUI() override { + this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Custom Table (mV)")); + + ValueThresholds MgpuVmaxThresholds(800, 850); + ValueThresholds EgpuVmaxThresholds(950, 975); + + std::vector mGpuVolts = { + NamedValue("Disabled", 2000), + NamedValue("Auto", 0), + NamedValue("480mV", 480), NamedValue("485mV", 485), NamedValue("490mV", 490), + NamedValue("495mV", 495), NamedValue("500mV", 500), NamedValue("505mV", 505), + NamedValue("510mV", 510), NamedValue("515mV", 515), NamedValue("520mV", 520), + NamedValue("525mV", 525), NamedValue("530mV", 530), NamedValue("535mV", 535), + NamedValue("540mV", 540), NamedValue("545mV", 545), NamedValue("550mV", 550), + NamedValue("555mV", 555), NamedValue("560mV", 560), NamedValue("565mV", 565), + NamedValue("570mV", 570), NamedValue("575mV", 575), NamedValue("580mV", 580), + NamedValue("585mV", 585), NamedValue("590mV", 590), NamedValue("595mV", 595), + NamedValue("600mV", 600), NamedValue("605mV", 605), NamedValue("610mV", 610), + NamedValue("615mV", 615), NamedValue("620mV", 620), NamedValue("625mV", 625), + NamedValue("630mV", 630), NamedValue("635mV", 635), NamedValue("640mV", 640), + NamedValue("645mV", 645), NamedValue("650mV", 650), NamedValue("655mV", 655), + NamedValue("660mV", 660), NamedValue("665mV", 665), NamedValue("670mV", 670), + NamedValue("675mV", 675), NamedValue("680mV", 680), NamedValue("685mV", 685), + NamedValue("690mV", 690), NamedValue("695mV", 695), NamedValue("700mV", 700), + NamedValue("705mV", 705), NamedValue("710mV", 710), NamedValue("715mV", 715), + NamedValue("720mV", 720), NamedValue("725mV", 725), NamedValue("730mV", 730), + NamedValue("735mV", 735), NamedValue("740mV", 740), NamedValue("745mV", 745), + NamedValue("750mV", 750), NamedValue("755mV", 755), NamedValue("760mV", 760), + NamedValue("765mV", 765), NamedValue("770mV", 770), NamedValue("775mV", 775), + NamedValue("780mV", 780), NamedValue("785mV", 785), NamedValue("790mV", 790), + NamedValue("795mV", 795), NamedValue("800mV", 800), NamedValue("805mV", 805), + NamedValue("810mV", 810), NamedValue("815mV", 815), NamedValue("820mV", 820), + NamedValue("825mV", 825), NamedValue("830mV", 830), NamedValue("835mV", 835), + NamedValue("840mV", 840), NamedValue("845mV", 845), NamedValue("850mV", 850), + NamedValue("855mV", 855), NamedValue("860mV", 860), NamedValue("865mV", 865), + NamedValue("870mV", 870), NamedValue("875mV", 875), NamedValue("880mV", 880), + NamedValue("885mV", 885), NamedValue("890mV", 890), NamedValue("895mV", 895), + NamedValue("900mV", 900), NamedValue("905mV", 905), NamedValue("910mV", 910), + NamedValue("915mV", 915), NamedValue("920mV", 920), NamedValue("925mV", 925), + NamedValue("930mV", 930), NamedValue("935mV", 935), NamedValue("940mV", 940), + NamedValue("945mV", 945), NamedValue("950mV", 950), NamedValue("955mV", 955), + NamedValue("960mV", 960), + }; + + std::vector eGpuVolts = { + NamedValue("Disabled", 2000), + NamedValue("Auto", 0), + NamedValue("700mV", 700), NamedValue("705mV", 705), NamedValue("710mV", 710), + NamedValue("715mV", 715), NamedValue("720mV", 720), NamedValue("725mV", 725), + NamedValue("730mV", 730), NamedValue("735mV", 735), NamedValue("740mV", 740), + NamedValue("745mV", 745), NamedValue("750mV", 750), NamedValue("755mV", 755), + NamedValue("760mV", 760), NamedValue("765mV", 765), NamedValue("770mV", 770), + NamedValue("775mV", 775), NamedValue("780mV", 780), NamedValue("785mV", 785), + NamedValue("790mV", 790), NamedValue("795mV", 795), NamedValue("800mV", 800), + NamedValue("805mV", 805), NamedValue("810mV", 810), NamedValue("815mV", 815), + NamedValue("820mV", 820), NamedValue("825mV", 825), NamedValue("830mV", 830), + NamedValue("835mV", 835), NamedValue("840mV", 840), NamedValue("845mV", 845), + NamedValue("850mV", 850), NamedValue("855mV", 855), NamedValue("860mV", 860), + NamedValue("865mV", 865), NamedValue("870mV", 870), NamedValue("875mV", 875), + NamedValue("880mV", 880), NamedValue("885mV", 885), NamedValue("890mV", 890), + NamedValue("895mV", 895), NamedValue("900mV", 900), NamedValue("905mV", 905), + NamedValue("910mV", 910), NamedValue("915mV", 915), NamedValue("920mV", 920), + NamedValue("925mV", 925), NamedValue("930mV", 930), NamedValue("935mV", 935), + NamedValue("940mV", 940), NamedValue("945mV", 945), NamedValue("950mV", 950), + NamedValue("955mV", 955), NamedValue("960mV", 960), NamedValue("965mV", 965), + NamedValue("970mV", 970), NamedValue("975mV", 975), NamedValue("980mV", 980), + NamedValue("985mV", 985), NamedValue("990mV", 990), NamedValue("995mV", 995), + }; + + if (IsMariko()) { + addConfigButton(KipConfigValue_g_volt_76800, "76.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_153600, "153.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_230400, "230.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_307200, "307.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_384000, "384.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_460800, "460.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_537600, "537.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_614400, "614.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_691200, "691.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_768000, "768.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_844800, "844.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_921600, "921.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1152000, "1152.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1228800, "1228.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1267200, "1267.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1305600, "1305.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1344000, "1344.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1382400, "1382.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1420800, "1420.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1459200, "1459.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1497600, "1497.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_1536000, "1536.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false); + } else { + addConfigButton(KipConfigValue_g_volt_e_76800, "76.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_115200, "115.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_153600, "153.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_192000, "192.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_230400, "230.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_268800, "268.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_307200, "307.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_345600, "345.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_384000, "384.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_422400, "422.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_460800, "460.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_499200, "499.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_537600, "537.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_576000, "576.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_614400, "614.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_652800, "652.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_691200, "691.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_729600, "729.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_768000, "768.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_806400, "806.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_844800, "844.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_883200, "883.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_921600, "921.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_960000, "960.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_1036800, "1036.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + addConfigButton(KipConfigValue_g_volt_e_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false); + } + } +}; + + static std::string getValueDisplayText(uint64_t currentValue, const ValueRange& range, const std::vector& namedValues) diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.h b/Source/sys-clk/overlay/src/ui/gui/misc_gui.h index 14ca541d..84706b50 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.h @@ -17,8 +17,8 @@ public: protected: std::map configButtons; - std::map configRanges; // Store ranges for refresh - std::map> configNamedValues; // NEW — Store named values for refresh + std::map configRanges; + std::map> configNamedValues; SysClkConfigValueList* configList; std::map configToggles; std::map>> configTrackbars; diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index b0964785..c018fee0 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -142,7 +142,7 @@ bool ClockManager::IsAssignableHz(SysClkModule module, std::uint32_t hz) case SysClkModule_CPU: return hz >= 400000000; case SysClkModule_MEM: - return hz == 204000000 || hz >= 665600000; + return hz >= 665600000; default: return true; } diff --git a/dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp b/dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp index b121716cbfac0321aa6bef843c5d668120f2bbfb..d542422110aa0f82273608bd5ec05a9cc108e98c 100644 GIT binary patch delta 20894 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 delta 20916 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