loader: add gpu vmin and vmax patch
This commit is contained in:
@@ -89,6 +89,7 @@ volatile CustomizeTable C = {
|
|||||||
|
|
||||||
.marikoGpuUV = 0,
|
.marikoGpuUV = 0,
|
||||||
|
|
||||||
|
|
||||||
.eristaCpuUV = 0,
|
.eristaCpuUV = 0,
|
||||||
|
|
||||||
.eristaGpuUV = 0,
|
.eristaGpuUV = 0,
|
||||||
@@ -115,6 +116,7 @@ volatile CustomizeTable C = {
|
|||||||
.mem_burst_latency = 2,
|
.mem_burst_latency = 2,
|
||||||
|
|
||||||
// NOTE: These tables should NOT BE USED and are only here as placeholders. Always try and find your own optimal tables.
|
// NOTE: These tables should NOT BE USED and are only here as placeholders. Always try and find your own optimal tables.
|
||||||
|
// Ensure the voltages actually increase or stay the sameot
|
||||||
|
|
||||||
.marikoGpuVoltArray = {
|
.marikoGpuVoltArray = {
|
||||||
610 /* 76 */,
|
610 /* 76 */,
|
||||||
@@ -132,7 +134,7 @@ volatile CustomizeTable C = {
|
|||||||
675 /* 998 */,
|
675 /* 998 */,
|
||||||
710 /* 1075 */,
|
710 /* 1075 */,
|
||||||
735 /* 1152 */,
|
735 /* 1152 */,
|
||||||
785 /* 1228 */,
|
785 /* 1228 (Only safe if GPU Scheduling is on)*/,
|
||||||
0 /* 1267 (Disabled by default) */,
|
0 /* 1267 (Disabled by default) */,
|
||||||
0 /* 1305 (Disabled by default) */,
|
0 /* 1305 (Disabled by default) */,
|
||||||
0 /* 1344 (Disabled by default) */,
|
0 /* 1344 (Disabled by default) */,
|
||||||
@@ -156,7 +158,7 @@ volatile CustomizeTable C = {
|
|||||||
875 /* 691 */,
|
875 /* 691 */,
|
||||||
900 /* 768 */,
|
900 /* 768 */,
|
||||||
950 /* 844 */,
|
950 /* 844 */,
|
||||||
900 /* 921 */,
|
975 /* 921 */,
|
||||||
0 /* 998 (Disabled by default) */,
|
0 /* 998 (Disabled by default) */,
|
||||||
0 /* 1075 (Disabled by default) */,
|
0 /* 1075 (Disabled by default) */,
|
||||||
},
|
},
|
||||||
@@ -164,6 +166,12 @@ volatile CustomizeTable C = {
|
|||||||
|
|
||||||
.marikoCpuVmin = 600,
|
.marikoCpuVmin = 600,
|
||||||
|
|
||||||
|
.eristaGpuVmin = 810,
|
||||||
|
|
||||||
|
.marikoGpuVmin = 610,
|
||||||
|
|
||||||
|
.marikoGpuVmax = 800,
|
||||||
|
|
||||||
/* Advanced Settings:
|
/* Advanced Settings:
|
||||||
* - Erista CPU DVFS Table:
|
* - Erista CPU DVFS Table:
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -86,7 +86,10 @@
|
|||||||
|
|
||||||
u32 marikoCpuVmin;
|
u32 marikoCpuVmin;
|
||||||
|
|
||||||
|
u32 eristaGpuVmin;
|
||||||
|
u32 marikoGpuVmin;
|
||||||
|
u32 marikoGpuVmax;
|
||||||
|
|
||||||
CustomizeCpuDvfsTable eristaCpuDvfsTable;
|
CustomizeCpuDvfsTable eristaCpuDvfsTable;
|
||||||
CustomizeCpuDvfsTable marikoCpuDvfsTable;
|
CustomizeCpuDvfsTable marikoCpuDvfsTable;
|
||||||
CustomizeCpuDvfsTable marikoCpuDvfsTableSLT;
|
CustomizeCpuDvfsTable marikoCpuDvfsTableSLT;
|
||||||
|
|||||||
@@ -48,12 +48,17 @@ namespace ams::ldr::oc::pcv
|
|||||||
{1963500, {1675751, -38635, 27}, {1120000}},
|
{1963500, {1675751, -38635, 27}, {1120000}},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr int gpuVmax = 750;
|
||||||
|
|
||||||
|
constexpr int gpuVmin = 610;
|
||||||
|
|
||||||
constexpr u16 CpuMinVolts[] = {800, 637, 620, 610};
|
constexpr u16 CpuMinVolts[] = {800, 637, 620, 610};
|
||||||
|
|
||||||
constexpr u32 CpuClkOfficial = 1963'500;
|
constexpr u32 CpuClkOfficial = 1963'500;
|
||||||
constexpr u32 CpuVoltOfficial = 1120;
|
constexpr u32 CpuVoltOfficial = 1120;
|
||||||
|
|
||||||
|
|
||||||
constexpr cvb_entry_t GpuCvbTableDefault[] = {
|
constexpr cvb_entry_t GpuCvbTableDefault[] = {
|
||||||
// GPUB01_NA_CVB_TABLE
|
// GPUB01_NA_CVB_TABLE
|
||||||
{76800, {}, {
|
{76800, {}, {
|
||||||
@@ -184,6 +189,10 @@ namespace ams::ldr::oc::pcv
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr int gpuVmin = 810;
|
||||||
|
|
||||||
|
constexpr u32 CpuVoltOfficial = 1235;
|
||||||
|
|
||||||
constexpr u32 CpuVoltL4T = 1235'000;
|
constexpr u32 CpuVoltL4T = 1235'000;
|
||||||
|
|
||||||
constexpr u16 CpuMinVolts[] = {950, 850, 825, 810};
|
constexpr u16 CpuMinVolts[] = {950, 850, 825, 810};
|
||||||
|
|||||||
@@ -21,7 +21,33 @@
|
|||||||
|
|
||||||
namespace ams::ldr::oc::pcv::erista
|
namespace ams::ldr::oc::pcv::erista
|
||||||
{
|
{
|
||||||
|
Result CpuFreqVdd(u32* ptr) {
|
||||||
|
dvfs_rail* entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq));
|
||||||
|
|
||||||
|
R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry());
|
||||||
|
R_UNLESS(entry->min_mv == 250'000, ldr::ResultInvalidCpuFreqVddEntry());
|
||||||
|
R_UNLESS(entry->step_mv == 5000, ldr::ResultInvalidCpuFreqVddEntry());
|
||||||
|
R_UNLESS(entry->max_mv == 1525'000, ldr::ResultInvalidCpuFreqVddEntry());
|
||||||
|
|
||||||
|
if (C.eristaCpuUV) {
|
||||||
|
if(!C.enableEristaCpuUnsafeFreqs) {
|
||||||
|
PATCH_OFFSET(ptr, GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq);
|
||||||
|
} else {
|
||||||
|
PATCH_OFFSET(ptr, GetDvfsTableLastEntry(C.eristaCpuDvfsTableUnsafeFreqs)->freq);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PATCH_OFFSET(ptr, GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
Result GpuVmin(u32 *ptr)
|
||||||
|
{
|
||||||
|
if (!C.eristaGpuVmin)
|
||||||
|
R_SKIP();
|
||||||
|
PATCH_OFFSET(ptr, (int)C.eristaGpuVmin);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
Result CpuVoltRange(u32 *ptr)
|
Result CpuVoltRange(u32 *ptr)
|
||||||
{
|
{
|
||||||
u32 min_volt_got = *(ptr - 1);
|
u32 min_volt_got = *(ptr - 1);
|
||||||
@@ -41,42 +67,37 @@
|
|||||||
Result CpuVoltDfll(u32* ptr) {
|
Result CpuVoltDfll(u32* ptr) {
|
||||||
cvb_cpu_dfll_data *entry = reinterpret_cast<cvb_cpu_dfll_data *>(ptr);
|
cvb_cpu_dfll_data *entry = reinterpret_cast<cvb_cpu_dfll_data *>(ptr);
|
||||||
|
|
||||||
R_UNLESS(entry->tune0_low == 0x0000FFCF, ldr::ResultInvalidCpuVoltDfllEntry());
|
// R_UNLESS(entry->tune0_low == 0x0000FFCF, ldr::ResultInvalidCpuVoltDfllEntry());
|
||||||
R_UNLESS(entry->tune0_high == 0x00000000, ldr::ResultInvalidCpuVoltDfllEntry());
|
// R_UNLESS(entry->tune0_high == 0x00000000, ldr::ResultInvalidCpuVoltDfllEntry());
|
||||||
R_UNLESS(entry->tune1_low == 0x012207FF, ldr::ResultInvalidCpuVoltDfllEntry());
|
// R_UNLESS(entry->tune1_low == 0x012207FF, ldr::ResultInvalidCpuVoltDfllEntry());
|
||||||
R_UNLESS(entry->tune1_high == 0x03FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry());
|
// R_UNLESS(entry->tune1_high == 0x03FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry());
|
||||||
|
if(!C.eristaCpuUV) {
|
||||||
|
R_SKIP();
|
||||||
|
}
|
||||||
|
PATCH_OFFSET(&(entry->dvco_calibration_max), 0x1C);
|
||||||
|
PATCH_OFFSET(&(entry->tune1_high), 0x10);
|
||||||
|
PATCH_OFFSET(&(entry->tune_high_margin_millivolts), 0xc);
|
||||||
|
|
||||||
switch(C.eristaCpuUV) {
|
switch(C.eristaCpuUV) {
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF88); //process_id 0 // EOS UV2
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); //process_id 0 // EOS UV1
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x027007FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); //process_id 1 // EOS Uv2
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000EFFF); //process_id 1 // EOS Uv2
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x027407FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF98); //process_id 0 // EOS UV3
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000DFFF); //process_id 0 // EOS UV3
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x027807FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); //process_id 1 // EOS Uv4
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000DFDF); //process_id 1 // EOS Uv4
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x027A07FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000CFDF); // EOS UV5
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x037007FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x022217FF);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -337,9 +358,10 @@
|
|||||||
u32 GpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq);
|
u32 GpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq);
|
||||||
|
|
||||||
PatcherEntry<u32> patches[] = {
|
PatcherEntry<u32> patches[] = {
|
||||||
|
{ "CPU Freq Vdd", &CpuFreqVdd, 1, nullptr, CpuClkOSLimit },
|
||||||
{"CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, CpuCvbDefaultMaxFreq},
|
{"CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, CpuCvbDefaultMaxFreq},
|
||||||
{"CPU Volt Limit", &CpuVoltRange, 0, &CpuMaxVoltPatternFn},
|
{ "CPU Volt Limit", &CpuVoltRange, 13, nullptr, CpuVoltOfficial },
|
||||||
{ "CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0x0000FFCF },
|
{ "CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFEAD0FF },
|
||||||
{"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, GpuCvbDefaultMaxFreq},
|
{"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, GpuCvbDefaultMaxFreq},
|
||||||
{"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn},
|
{"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn},
|
||||||
{"GPU Freq PLL", &GpuFreqPllLimit, 1, nullptr, GpuClkPllLimit},
|
{"GPU Freq PLL", &GpuFreqPllLimit, 1, nullptr, GpuClkPllLimit},
|
||||||
@@ -347,6 +369,7 @@
|
|||||||
{"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit},
|
{"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit},
|
||||||
{"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit},
|
{"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit},
|
||||||
{"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS},
|
{"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS},
|
||||||
|
{"GPU Vmin", &GpuVmin, 0, nullptr, gpuVmin},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uintptr_t ptr = mapped_nso;
|
for (uintptr_t ptr = mapped_nso;
|
||||||
|
|||||||
@@ -21,6 +21,22 @@
|
|||||||
|
|
||||||
namespace ams::ldr::oc::pcv::mariko {
|
namespace ams::ldr::oc::pcv::mariko {
|
||||||
|
|
||||||
|
Result GpuVmin(u32 *ptr)
|
||||||
|
{
|
||||||
|
if (!C.marikoGpuVmin)
|
||||||
|
R_SKIP();
|
||||||
|
PATCH_OFFSET(ptr, (int)C.marikoGpuVmin);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GpuVmax(u32 *ptr)
|
||||||
|
{
|
||||||
|
if (!C.marikoGpuVmax)
|
||||||
|
R_SKIP();
|
||||||
|
PATCH_OFFSET(ptr, (int)C.marikoGpuVmax);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
Result CpuFreqVdd(u32* ptr) {
|
Result CpuFreqVdd(u32* ptr) {
|
||||||
dvfs_rail* entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq));
|
dvfs_rail* entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq));
|
||||||
|
|
||||||
@@ -78,31 +94,31 @@
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF88); //process_id 0 // EOS UV2
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF88); //process_id 0 // EOS UV1
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); //process_id 1 // EOS Uv2
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); /// EOS Uv2
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF98); //process_id 0 // EOS UV3
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF98); // EOS UV3
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); //process_id 1 // EOS Uv4
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); // EOS Uv4
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
|
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV5
|
||||||
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
||||||
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x022217FF);
|
PATCH_OFFSET(&(entry->tune1_high), 0x022217FF);
|
||||||
@@ -647,7 +663,9 @@
|
|||||||
{ "MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
|
{ "MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
|
||||||
{ "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
|
{ "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
|
||||||
{ "MEM Vddq", &EmcVddqVolt, 2, nullptr, EmcVddqDefault },
|
{ "MEM Vddq", &EmcVddqVolt, 2, nullptr, EmcVddqDefault },
|
||||||
{ "MEM Vdd2", &MemVoltHandler, 2, nullptr, MemVdd2Default }
|
{ "MEM Vdd2", &MemVoltHandler, 2, nullptr, MemVdd2Default },
|
||||||
|
{ "GPU Vmin", &GpuVmin, 0, nullptr, gpuVmin},
|
||||||
|
{ "GPU Vmax", &GpuVmax, 0, nullptr, gpuVmax},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uintptr_t ptr = mapped_nso;
|
for (uintptr_t ptr = mapped_nso;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -65,6 +65,11 @@ def populate():
|
|||||||
voltages_e = [0] + list(range(700, 1100 + 1, 5)) # 0 first for Disabled
|
voltages_e = [0] + list(range(700, 1100 + 1, 5)) # 0 first for Disabled
|
||||||
processed_voltages_e = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_e]
|
processed_voltages_e = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_e]
|
||||||
processed_voltages_default = ["Default" if v == 0 else f"{v} mV" for v in voltages]
|
processed_voltages_default = ["Default" if v == 0 else f"{v} mV" for v in voltages]
|
||||||
|
voltages_vmin = [0] + list(range(480, 650 + 1, 5)) # 0 first for Disabled
|
||||||
|
processed_voltages_vmin = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_vmin]
|
||||||
|
voltages_vmin_e = [0] + list(range(700, 850 + 1, 5)) # 0 first for Disabled
|
||||||
|
processed_voltages_vmin_e = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_vmin_e]
|
||||||
|
|
||||||
freqs_khz = [
|
freqs_khz = [
|
||||||
76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000,
|
76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000,
|
||||||
844800, 921600, 998400, 1075200, 1152000, 1228800, 1267200, 1305600, 1344000, 1382400, 1420800,
|
844800, 921600, 998400, 1075200, 1152000, 1228800, 1267200, 1305600, 1344000, 1382400, 1420800,
|
||||||
@@ -72,7 +77,7 @@ def populate():
|
|||||||
]
|
]
|
||||||
freqs_khz_e = [
|
freqs_khz_e = [
|
||||||
76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000,
|
76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000,
|
||||||
844800, 921600, 998400, 1075200, 1152000
|
844800, 921600, 998400, 1075200 #, 1152000, 1228800 # Disabled by default as these freqs can cause board damage
|
||||||
]
|
]
|
||||||
freqs_mhz = [
|
freqs_mhz = [
|
||||||
76.8, 153.6, 230.4, 307.2, 384.0, 460.8, 537.6, 614.4, 691.2, 768.0,
|
76.8, 153.6, 230.4, 307.2, 384.0, 460.8, 537.6, 614.4, 691.2, 768.0,
|
||||||
@@ -119,20 +124,28 @@ def populate():
|
|||||||
small=True,
|
small=True,
|
||||||
tag="volt_info"
|
tag="volt_info"
|
||||||
)
|
)
|
||||||
# dpg.add_combo(
|
dpg.add_combo(
|
||||||
# items=processed_voltages,
|
items=processed_voltages_vmin_e,
|
||||||
# default_value="Disabled",
|
default_value="Disabled",
|
||||||
# label="Gpu vMin",
|
label="Erista GPU vMin",
|
||||||
# callback=k.grab_kip_storage_values_no_mult,
|
callback=k.grab_kip_storage_values_no_mult,
|
||||||
# tag="g_vmin"
|
tag="eristaGpuVmin"
|
||||||
# )
|
)
|
||||||
# dpg.add_combo(
|
dpg.add_combo(
|
||||||
# items=processed_voltages,
|
items=processed_voltages_vmin,
|
||||||
# default_value="Disabled",
|
default_value="Disabled",
|
||||||
# label="Gpu vMax",
|
label="Mariko GPU vMin",
|
||||||
# callback=k.grab_kip_storage_values_no_mult,
|
callback=k.grab_kip_storage_values_no_mult,
|
||||||
# tag="g_vmax"
|
tag="marikoGpuVmin"
|
||||||
# )
|
)
|
||||||
|
|
||||||
|
dpg.add_combo(
|
||||||
|
items=processed_voltages,
|
||||||
|
default_value="Disabled",
|
||||||
|
label="Mariko GPU vMax",
|
||||||
|
callback=k.grab_kip_storage_values_no_mult,
|
||||||
|
tag="marikoGpuVmax"
|
||||||
|
)
|
||||||
|
|
||||||
dpg.add_separator(label="Undervolt")
|
dpg.add_separator(label="Undervolt")
|
||||||
|
|
||||||
|
|||||||
@@ -82,8 +82,13 @@ variables = [
|
|||||||
("g_volt_e_921600", "u32"),
|
("g_volt_e_921600", "u32"),
|
||||||
("g_volt_e_998400", "u32"),
|
("g_volt_e_998400", "u32"),
|
||||||
("g_volt_e_1075200", "u32"),
|
("g_volt_e_1075200", "u32"),
|
||||||
("g_volt_e_1152000", "u32"),
|
# ("g_volt_e_1152000", "u32"),
|
||||||
|
# ("g_volt_e_1228800", "u32"),
|
||||||
("marikoCpuVmin", "u32"),
|
("marikoCpuVmin", "u32"),
|
||||||
|
("eristaGpuVmin", "u32"),
|
||||||
|
("marikoGpuVmin", "u32"),
|
||||||
|
("marikoGpuVmax", "u32"),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
fmt_map = {
|
fmt_map = {
|
||||||
@@ -141,11 +146,14 @@ def load_all_vars():
|
|||||||
|
|
||||||
for e_freq in [
|
for e_freq in [
|
||||||
"76800", "153600", "230400", "307200", "384000", "460800", "537600",
|
"76800", "153600", "230400", "307200", "384000", "460800", "537600",
|
||||||
"614400", "691200", "768000", "844800", "921600", "998400", "1075200",
|
"614400", "691200", "768000", "844800", "921600", "998400", "1075200"# ,
|
||||||
"1152000"
|
# "1152000", "1228800"
|
||||||
]:
|
]:
|
||||||
c.load_entry_object(f"g_volt_e_{e_freq}", 3)
|
c.load_entry_object(f"g_volt_e_{e_freq}", 3)
|
||||||
c.load_entry_object("marikoCpuVmin", 3)
|
c.load_entry_object("marikoCpuVmin", 3)
|
||||||
|
c.load_entry_object("eristaGpuVmin", 3)
|
||||||
|
c.load_entry_object("marikoGpuVmin", 3)
|
||||||
|
c.load_entry_object("marikoGpuVmax", 3)
|
||||||
|
|
||||||
def freq_to_label(freq):
|
def freq_to_label(freq):
|
||||||
if freq > 1382400:
|
if freq > 1382400:
|
||||||
@@ -240,7 +248,7 @@ def write_kip():
|
|||||||
if not d.autosave:
|
if not d.autosave:
|
||||||
c.show_popup("Success", "KIP saved successfully!")
|
c.show_popup("Success", "KIP saved successfully!")
|
||||||
|
|
||||||
def read_kip(filename, debug=True):
|
def read_kip(filename):
|
||||||
MAGIC = b"CUST"
|
MAGIC = b"CUST"
|
||||||
struct_fmt = make_struct_format(variables)
|
struct_fmt = make_struct_format(variables)
|
||||||
struct_size = struct.calcsize(struct_fmt)
|
struct_size = struct.calcsize(struct_fmt)
|
||||||
@@ -254,21 +262,20 @@ def read_kip(filename, debug=True):
|
|||||||
values = struct.unpack(struct_fmt, raw)
|
values = struct.unpack(struct_fmt, raw)
|
||||||
for (attr_name, _), val in zip(variables, values):
|
for (attr_name, _), val in zip(variables, values):
|
||||||
setattr(d, attr_name, val)
|
setattr(d, attr_name, val)
|
||||||
if debug:
|
print("=== value layout ===")
|
||||||
print("=== debug KIP layout ===")
|
offset = 0
|
||||||
offset = 0
|
for (attr_name, t) in variables:
|
||||||
for (attr_name, t) in variables:
|
code = fmt_map[t]
|
||||||
code = fmt_map[t]
|
align = 8 if code == "d" else 4
|
||||||
align = 8 if code == "d" else 4
|
padding = (-offset) % align
|
||||||
padding = (-offset) % align
|
if padding:
|
||||||
if padding:
|
offset += padding
|
||||||
offset += padding
|
size = struct.calcsize(code)
|
||||||
size = struct.calcsize(code)
|
raw_bytes = raw[offset:offset + size]
|
||||||
raw_bytes = raw[offset:offset + size]
|
val = getattr(d, attr_name)
|
||||||
val = getattr(d, attr_name)
|
print(f"{attr_name:<20} | type={t:<6} | offset={offset:<4} | size={size:<2} | raw=0x{raw_bytes.hex()} | val={val}")
|
||||||
print(f"{attr_name:<20} | type={t:<6} | offset={offset:<4} | size={size:<2} | raw=0x{raw_bytes.hex()} | val={val}")
|
offset += size
|
||||||
offset += size
|
print("========================")
|
||||||
print("========================")
|
|
||||||
dpg.set_value("gpu_sched", g.check_gpu_sched())
|
dpg.set_value("gpu_sched", g.check_gpu_sched())
|
||||||
dpg.show_item("gpu_tab")
|
dpg.show_item("gpu_tab")
|
||||||
dpg.show_item("cpu_tab")
|
dpg.show_item("cpu_tab")
|
||||||
|
|||||||
@@ -90,7 +90,9 @@ with dpg.texture_registry(show=False):
|
|||||||
|
|
||||||
with dpg.file_dialog(directory_selector=False, show=False, tag="file_dialog", width=500, height=300, modal=True, callback=k.store):
|
with dpg.file_dialog(directory_selector=False, show=False, tag="file_dialog", width=500, height=300, modal=True, callback=k.store):
|
||||||
dpg.add_file_extension(".kip")
|
dpg.add_file_extension(".kip")
|
||||||
|
def refresh_drives():
|
||||||
|
setattr(ins, "drive_list", ins.get_drives())
|
||||||
|
dpg.configure_item("drive_select", items=ins.drive_list)
|
||||||
with dpg.window(label="Configurator", width=400, height=300,id="main_window"):
|
with dpg.window(label="Configurator", width=400, height=300,id="main_window"):
|
||||||
with dpg.tab_bar():
|
with dpg.tab_bar():
|
||||||
with dpg.tab(label="File"):
|
with dpg.tab(label="File"):
|
||||||
@@ -102,9 +104,11 @@ with dpg.window(label="Configurator", width=400, height=300,id="main_window"):
|
|||||||
callback=lambda: webbrowser.open("https://github.com/souldbminersmwc/Horizon-OC")
|
callback=lambda: webbrowser.open("https://github.com/souldbminersmwc/Horizon-OC")
|
||||||
)
|
)
|
||||||
dpg.add_separator(label="Installation")
|
dpg.add_separator(label="Installation")
|
||||||
|
dpg.add_button(label="Refresh Drive List", callback=refresh_drives)
|
||||||
dpg.add_combo(
|
dpg.add_combo(
|
||||||
items=ins.drive_list,
|
items=ins.drive_list,
|
||||||
default_value="Select a drive!",
|
default_value="Select a drive!",
|
||||||
|
tag="drive_select",
|
||||||
callback=ins.check_atmosphere
|
callback=ins.check_atmosphere
|
||||||
)
|
)
|
||||||
dpg.add_checkbox(label="Autosave", default_value=false, callback=ins.autosave_toggle)
|
dpg.add_checkbox(label="Autosave", default_value=false, callback=ins.autosave_toggle)
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ def set_psm_value(sender, app_data):
|
|||||||
value = next((x["value"] for x in PSM_OPTIONS if x["name"] == app_data), None)
|
value = next((x["value"] for x in PSM_OPTIONS if x["name"] == app_data), None)
|
||||||
if value:
|
if value:
|
||||||
ini.set_ini_values(str(ini_path), "psm", {"current_psm_mA": value})
|
ini.set_ini_values(str(ini_path), "psm", {"current_psm_mA": value})
|
||||||
common.show_popup("Success", f"PSM set to {app_data}")
|
common.show_popup("Success", f"Charge Limit set to {app_data}")
|
||||||
|
|
||||||
def remove_tc_entries():
|
def remove_tc_entries():
|
||||||
ini_path = get_ini_path()
|
ini_path = get_ini_path()
|
||||||
@@ -337,7 +337,7 @@ def populate():
|
|||||||
dpg.add_image("coolerhd", width=20, height=20)
|
dpg.add_image("coolerhd", width=20, height=20)
|
||||||
|
|
||||||
def set_white_tiger_clocks(app_data):
|
def set_white_tiger_clocks(app_data):
|
||||||
|
# cooler aah clocks
|
||||||
# 1400mv emc max
|
# 1400mv emc max
|
||||||
# 1375mv cpu max
|
# 1375mv cpu max
|
||||||
# 750mv vdd2 mariko max
|
# 750mv vdd2 mariko max
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ cp -vf "$ROOT_DIR/overlay/out/sys-clk-overlay.ovl" "$DIST_DIR/switch/.overlays/s
|
|||||||
echo "*** assets ***"
|
echo "*** assets ***"
|
||||||
mkdir -p "$DIST_DIR/config/sys-clk"
|
mkdir -p "$DIST_DIR/config/sys-clk"
|
||||||
cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/sys-clk/config.ini.template"
|
cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/sys-clk/config.ini.template"
|
||||||
cp -vf "$ROOT_DIR/README.md" "$DIST_DIR/README.md"
|
cp -vf "$ROOT_DIR/../../README.md" "$DIST_DIR/README.md"
|
||||||
|
|||||||
28
build.sh
28
build.sh
@@ -1,21 +1,33 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Define source and destination paths
|
|
||||||
SRC="Source/Atmosphere/stratosphere/loader/source/oc"
|
SRC="Source/Atmosphere/stratosphere/loader/source/oc"
|
||||||
DEST="build/stratosphere/loader/source/oc"
|
DEST="build/stratosphere/loader/source/oc"
|
||||||
|
mkdir -p "dist/atmosphere/kips/"
|
||||||
# Create destination directory if it doesn't exist
|
|
||||||
mkdir -p "$DEST"
|
mkdir -p "$DEST"
|
||||||
|
|
||||||
# Copy contents of oc into destination oc (safe, includes hidden files)
|
|
||||||
cp -r "$SRC"/. "$DEST"/
|
cp -r "$SRC"/. "$DEST"/
|
||||||
|
|
||||||
# Enter build directory and compile using all available cores
|
|
||||||
cd build/stratosphere/loader || exit 1
|
cd build/stratosphere/loader || exit 1
|
||||||
rm out/nintendo_nx_arm64_armv8a/release/loader.kip
|
|
||||||
rm -rf build/
|
|
||||||
make -j"$(nproc)"
|
make -j"$(nproc)"
|
||||||
hactool -t kip1 out/nintendo_nx_arm64_armv8a/release/loader.kip --uncompress=hoc.kip
|
hactool -t kip1 out/nintendo_nx_arm64_armv8a/release/loader.kip --uncompress=hoc.kip
|
||||||
rm out/nintendo_nx_arm64_armv8a/release/loader.kip
|
rm out/nintendo_nx_arm64_armv8a/release/loader.kip
|
||||||
rm -rf build/
|
cd ../../../ # exit
|
||||||
|
cp build/stratosphere/loader/hoc.kip dist/atmosphere/kips/hoc.kip
|
||||||
|
|
||||||
|
cd Source/sys-clk/
|
||||||
|
./build.sh
|
||||||
|
cp -r dist/ ../../
|
||||||
|
|
||||||
|
# cd ../../Source/configurator
|
||||||
|
|
||||||
|
# pip install -U pyinstaller
|
||||||
|
# pip install dpg
|
||||||
|
# pip install numpy
|
||||||
|
# pip install psutil
|
||||||
|
# pip install pillow
|
||||||
|
# pip install pathlib
|
||||||
|
|
||||||
|
# python3 -m PyInstaller --onefile --add-data "assets:assets" --icon=assets/icon.ico --noconsole src/main.py
|
||||||
|
|
||||||
|
# mv dist/main dist/hocconfig
|
||||||
|
# cp dist/hocconfig ../../
|
||||||
57
dist/README.md
vendored
Normal file
57
dist/README.md
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
  [](https://discord.com/invite/S3eX47dHsB)   []()
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### DISCLAIMER: THIS TOOL CAN BE DANGEROUS IF MISUSED. PROCEED WITH CAUTION
|
||||||
|
* Due to the design of Horizon OS, overclocking RAM can cause **NAND DAMAGE**. Ensure to have a NAND Backup<br>
|
||||||
|
|
||||||
|
A open source overclocking tool for Nintendo Switch consoles running Atmosphere custom firmware<br>
|
||||||
|
|
||||||
|
|
||||||
|
## Features:
|
||||||
|
CPU overclock up to 2397MHz on Mariko units, 2091MHz on Erista units<br>
|
||||||
|
GPU up to 1305MHz on Mariko units, 998MHz on Erista units<br>
|
||||||
|
RAM up to 3200MHz on Mariko units, 2360MHz on Erista units<br>
|
||||||
|
Over/undervolting<br>
|
||||||
|
Configurator<br>
|
||||||
|
Works with most homebrew<br>
|
||||||
|
|
||||||
|
*Higher (potentially dangerous) frequencies are unlockable*<br>
|
||||||
|
*The exact maximum overclock varies per console*<br>
|
||||||
|
## Installation
|
||||||
|
Ensure you have the latest version of [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere) and [Ultrahand](https://github.com/ppkantorski/Ultrahand-Overlay) installed before continuing<br>
|
||||||
|
Grab latest hoc.kip from releases tab<br>
|
||||||
|
If using hekate, edit hekate_ipl.ini to include "kip1=atmosphere/kips/*". No need for editing if using fusee<br>
|
||||||
|
Download latest Horizon OC sysmodule from releases tab<br>
|
||||||
|
Extract sysmodule into root of SD card<br>
|
||||||
|
|
||||||
|
Alternatively, you can download the configurator and click the two install buttons<br>
|
||||||
|
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
Download the latest configurator on your computer<br>
|
||||||
|
Run the file<br>
|
||||||
|
Select the drive your SD card or UMS device is mounted as<br>
|
||||||
|
Configure the kip to your liking, and in the end, save it<br>
|
||||||
|
|
||||||
|
## Building
|
||||||
|
Set up a development enviorment ready to compile Atmosphere<br>
|
||||||
|
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>
|
||||||
|
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
meha for Switch-Oc-Suite<br>
|
||||||
|
sys-clk team for sys-clk<br>
|
||||||
|
b0rd2auth for Ultrahand sys-clk fork<br>
|
||||||
|
Lightos and Sammybigio2010 for early testing<br>
|
||||||
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
Normal file
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
Normal file
Binary file not shown.
0
dist/atmosphere/contents/00FF0000636C6BFF/flags/boot2.flag
vendored
Normal file
0
dist/atmosphere/contents/00FF0000636C6BFF/flags/boot2.flag
vendored
Normal file
5
dist/atmosphere/contents/00FF0000636C6BFF/toolbox.json
vendored
Normal file
5
dist/atmosphere/contents/00FF0000636C6BFF/toolbox.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name" : "hoc-clk",
|
||||||
|
"tid" : "00FF0000636C6BFF",
|
||||||
|
"requires_reboot": false
|
||||||
|
}
|
||||||
BIN
dist/atmosphere/kips/hoc.kip
vendored
Normal file
BIN
dist/atmosphere/kips/hoc.kip
vendored
Normal file
Binary file not shown.
19
dist/config/sys-clk/config.ini.template
vendored
Normal file
19
dist/config/sys-clk/config.ini.template
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[values]
|
||||||
|
; Defines how often sys-clk log temperatures, in milliseconds (set 0 to disable)
|
||||||
|
temp_log_interval_ms=0
|
||||||
|
; Defines how often sys-clk writes to the CSV, in milliseconds (set 0 to disable)
|
||||||
|
csv_write_interval_ms=0
|
||||||
|
|
||||||
|
; Example #1: BOTW
|
||||||
|
; Overclock CPU when docked
|
||||||
|
; Overclock MEM to docked clocks when handheld
|
||||||
|
;[01007EF00011E000]
|
||||||
|
;docked_cpu=1224
|
||||||
|
;handheld_mem=1600
|
||||||
|
|
||||||
|
; Example #2: Picross
|
||||||
|
; Underclock to save battery
|
||||||
|
;[0100BA0003EEA000]
|
||||||
|
;handheld_cpu=816
|
||||||
|
;handheld_gpu=153
|
||||||
|
;handheld_mem=800
|
||||||
BIN
dist/switch/.overlays/sys-clk-overlay.ovl
vendored
Normal file
BIN
dist/switch/.overlays/sys-clk-overlay.ovl
vendored
Normal file
Binary file not shown.
BIN
dist/switch/sys-clk-manager.nro
vendored
Normal file
BIN
dist/switch/sys-clk-manager.nro
vendored
Normal file
Binary file not shown.
BIN
hocconfig.exe
Normal file
BIN
hocconfig.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user