From 7ad5c1ffe87c466937be6f0eeef6faabeffe6b4b Mon Sep 17 00:00:00 2001 From: Lightos1 <124387232+Lightos1@users.noreply.github.com> Date: Sun, 23 Nov 2025 12:00:41 +0100 Subject: [PATCH] Fix timings; kip not booting + compiler errors --- .../loader/source/oc/customize.cpp | 10 +- .../loader/source/oc/customize.hpp | 134 +++++++++--------- .../loader/source/oc/mtc_timing_value.hpp | 22 +-- .../stratosphere/loader/source/oc/pcv/pcv.hpp | 4 +- .../loader/source/oc/pcv/pcv_erista.cpp | 22 +-- .../loader/source/oc/pcv/pcv_mariko.cpp | 40 ++++-- 6 files changed, 124 insertions(+), 108 deletions(-) diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 8781b4f6..9a570f5a 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -76,7 +76,9 @@ volatile CustomizeTable C = { // .mem_burst_latency = 0, // 0 - 1600l, 1 = 1866bl, 2 = 2133bl /* TODO: Remove/fix. */ -.marikoCpuVmin = 600, +.marikoCpuHighVmin = 750, + +.marikoCpuLowVmin = 600, .eristaGpuVmin = 810, @@ -318,8 +320,8 @@ volatile CustomizeTable C = { { 921600, { }, { 1191317, 8144, -940, 808, -21583, 226 } }, { 960000, { }, { 1233208, 8144, -940, 808, -21583, 226 } }, { 998400, { }, { 1233208, 8144, -940, 808, -21583, 226 } }, - { 1036800, { }, { 1275100, 8144, -940, 808, -21583, 226 } }, - { 1075200, { }, { 1275100, 8144, -940, 808, -21583, 226 } }, + { 1036800, { }, { 1275100, 8144, -940, 808, -21583, 226 } }, + { 1075200, { }, { 1275100, 8144, -940, 808, -21583, 226 } }, }, /* - Mariko GPU DVFS Table: @@ -348,7 +350,7 @@ volatile CustomizeTable C = { }, .marikoGpuDvfsTableSLT = { - { 76800, {}, { 600000, } }, + { 76800, {}, { 600000, } }, { 153600, {}, { 600000, } }, { 230400, {}, { 600000, } }, { 307200, {}, { 600000, } }, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp index 2dcdaff4..a0018d30 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp @@ -16,96 +16,90 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ +*/ - #pragma once +#pragma once - #define CUST_REV 11 +#define CUST_REV 11 - #include "oc_common.hpp" - #include "pcv/pcv_common.hpp" +#include "oc_common.hpp" +#include "pcv/pcv_common.hpp" - namespace ams::ldr::oc { +namespace ams::ldr::oc { - #include "mtc_timing_table.hpp" +#include "mtc_timing_table.hpp" - enum MtcConfig: u32 { - AUTO_ADJ = 0, - AUTO_ADJ_BL = 1, - }; +enum MtcConfig: u32 { + AUTO_ADJ = 0, + AUTO_ADJ_BL = 1, +}; - using CustomizeCpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit]; - using CustomizeGpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit]; - static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(CustomizeGpuDvfsTable)); - static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(pcv::cvb_entry_t) * pcv::DvfsTableEntryLimit); +using CustomizeCpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit]; +using CustomizeGpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit]; +static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(CustomizeGpuDvfsTable)); +static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(pcv::cvb_entry_t) * pcv::DvfsTableEntryLimit); - constexpr uint32_t ERISTA_MTC_MAGIC = 0x43544D45; // EMTC - constexpr uint32_t MARIKO_MTC_MAGIC = 0x43544D4D; // MMTC +constexpr uint32_t ERISTA_MTC_MAGIC = 0x43544D45; // EMTC +constexpr uint32_t MARIKO_MTC_MAGIC = 0x43544D4D; // MMTC - typedef struct CustomizeTable { - u8 cust[4] = {'C', 'U', 'S', 'T'}; - u32 custRev = CUST_REV; - u32 mtcConf = AUTO_ADJ; - u32 hpMode; - u32 commonCpuBoostClock; - u32 commonEmcMemVolt; - u32 eristaCpuMaxVolt; - u32 eristaEmcMaxClock; - u32 marikoCpuMaxVolt; - u32 marikoEmcMaxClock; - u32 marikoEmcVddqVolt; - u32 marikoCpuUV; - u32 marikoGpuUV; +typedef struct CustomizeTable { + u8 cust[4] = {'C', 'U', 'S', 'T'}; + u32 custRev = CUST_REV; + u32 mtcConf = AUTO_ADJ; + u32 hpMode; + u32 commonCpuBoostClock; + u32 commonEmcMemVolt; + u32 eristaCpuMaxVolt; + u32 eristaEmcMaxClock; + u32 marikoCpuMaxVolt; + u32 marikoEmcMaxClock; + u32 marikoEmcVddqVolt; + u32 marikoCpuUV; + u32 marikoGpuUV; - u32 eristaCpuUV; - u32 eristaGpuUV; + u32 eristaCpuUV; + u32 eristaGpuUV; - u32 commonGpuVoltOffset; + u32 commonGpuVoltOffset; - u32 EmcDvbShift; + u32 EmcDvbShift; - // advanced config - u32 t1_tRCD; - u32 t2_tRP; - u32 t3_tRAS; - u32 t4_tRRD; - u32 t5_tRFC; - u32 t6_tRTW; - u32 t7_tWTR; - u32 t8_tREFI; - u32 mem_burst_latency; + // advanced config + u32 t1_tRCD; + u32 t2_tRP; + u32 t3_tRAS; + u32 t4_tRRD; + u32 t5_tRFC; + u32 t6_tRTW; + u32 t7_tWTR; + u32 t8_tREFI; + u32 mem_burst_latency; - u32 marikoCpuVmin; + u32 marikoCpuHighVmin; + u32 marikoCpuLowVmin; - u32 eristaGpuVmin; - u32 marikoGpuVmin; - u32 marikoGpuVmax; + u32 eristaGpuVmin; + u32 marikoGpuVmin; + u32 marikoGpuVmax; - u32 marikoGpuVoltArray[24]; - u32 eristaGpuVoltArray[27]; + u32 marikoGpuVoltArray[24]; + u32 eristaGpuVoltArray[27]; - CustomizeCpuDvfsTable eristaCpuDvfsTable; - CustomizeCpuDvfsTable marikoCpuDvfsTable; - CustomizeCpuDvfsTable marikoCpuDvfsTableSLT; + CustomizeCpuDvfsTable eristaCpuDvfsTable; + CustomizeCpuDvfsTable marikoCpuDvfsTable; + CustomizeCpuDvfsTable marikoCpuDvfsTableSLT; - CustomizeGpuDvfsTable eristaGpuDvfsTable; - CustomizeGpuDvfsTable eristaGpuDvfsTableSLT; - CustomizeGpuDvfsTable eristaGpuDvfsTableHigh; + CustomizeGpuDvfsTable eristaGpuDvfsTable; + CustomizeGpuDvfsTable eristaGpuDvfsTableSLT; + CustomizeGpuDvfsTable eristaGpuDvfsTableHigh; - CustomizeGpuDvfsTable marikoGpuDvfsTable; - CustomizeGpuDvfsTable marikoGpuDvfsTableSLT; - CustomizeGpuDvfsTable marikoGpuDvfsTableHiOPT; - //EristaMtcTable* eristaMtcTable; - //MarikoMtcTable* marikoMtcTable; - } CustomizeTable; - //static_assert(sizeof(CustomizeTable) == sizeof(u8) * 4 + sizeof(u32) * 10 + sizeof(CustomizeCpuDvfsTable) * 5 + sizeof(void*) * 2); - //static_assert(sizeof(CustomizeTable) == 7000); + CustomizeGpuDvfsTable marikoGpuDvfsTable; + CustomizeGpuDvfsTable marikoGpuDvfsTableSLT; + CustomizeGpuDvfsTable marikoGpuDvfsTableHiOPT; +} CustomizeTable; - extern volatile CustomizeTable C; +extern volatile CustomizeTable C; - //extern volatile EristaMtcTable EristaMtcTablePlaceholder; - //extern volatile MarikoMtcTable MarikoMtcTablePlaceholder; - - } +} diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp index 08c987b7..c99a3277 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -1,6 +1,8 @@ /* * Copyright (c) 2023 hanai3Bi * + * Copyright (c) 2025 Lightos_ + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -37,15 +39,18 @@ namespace ams::ldr::oc { /* Set to 4 read and 2 write for 1866bl. */ /* For 2131bl: 8 read and 4 write. */ - const u32 latency_offset_read = 0; - const u32 latency_offset_write = 0; + const u32 rl_offset = 8; + const u32 wl_offset = 4; + + const u32 RL = 28 + rl_offset; + const u32 WL = 14 + wl_offset; /* Precharge to Precharge Delay. (Cycles) */ const u32 tPPD = 4; /* DQS output access time from CK_t/CK_c. */ const double tDQSCK_max = 3.5; - const double tWPRE = 1.8; + const u32 tWPRE = 2; /* tCK Read postamble. */ const double tRPST = 0.5; @@ -63,9 +68,6 @@ namespace ams::ldr::oc { namespace pcv::erista { const double tCK_avg = 1000'000.0 / C.eristaEmcMaxClock; - const u32 RL = 28 + latency_offset_read; - const u32 WL = 14 + latency_offset_write; - /* Primary timings. */ const u32 tRCD = tRCD_values[C.t1_tRCD]; const u32 tRPpb = tRP_values[C.t2_tRP]; @@ -111,9 +113,6 @@ namespace ams::ldr::oc { const u32 tRFCpb = tRFC_values[C.t5_tRFC]; const u32 tWTR = tWTR_values[C.t7_tWTR]; - const u32 RL = 36; - const u32 WL = 18; - const u32 tRC = tRAS + tRPpb; const u32 tRFCab = tRFCpb * 2; const double tXSR = (double) (tRFCab + 7.5); @@ -134,6 +133,11 @@ namespace ams::ldr::oc { const double tMMRI = tRCD + (tCK_avg * 3); const double tPDEX2MRR = tMMRI + 10; const u32 tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6.0; + + inline u32 obdly = 0x10000002 + wl_offset; + const u32 wdv = 0xE + wl_offset; + const u32 wsv = 0xC + wl_offset; + const u32 wev = 0xA + wl_offset; } } diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp index 525dcbe7..33f8d72d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp @@ -94,9 +94,7 @@ namespace ams::ldr::oc::pcv {}, }; - constexpr u32 GpuClkPllLimit = 2600'000; - - constexpr u32 GpuClkMax = 1300'000'000; + constexpr u32 GpuClkPllLimit = 1300'000'000; /* GPU Max Clock asm Pattern: * diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp index 15f3db19..3b1aca4a 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -23,24 +23,25 @@ namespace ams::ldr::oc::pcv::erista { + /* Remove? */ Result CpuFreqVdd(u32* ptr) { dvfs_rail* entry = reinterpret_cast(reinterpret_cast(ptr) - offsetof(dvfs_rail, freq)); - 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_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()); + R_SUCCEED(); } Result GpuVmin(u32 *ptr) { - if (!C.eristaGpuVmin) + if (!C.eristaGpuVmin) { R_SKIP(); - PATCH_OFFSET(ptr, (int)C.eristaGpuVmin); - R_SUCCEED(); + } + + PATCH_OFFSET(ptr, (int)C.eristaGpuVmin); + R_SUCCEED(); } Result CpuVoltRange(u32 *ptr) { @@ -68,6 +69,7 @@ Result GpuVmin(u32 *ptr) { 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); diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp index beec6db3..1acee14c 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -66,10 +66,10 @@ namespace ams::ldr::oc::pcv::mariko { // Patch vmin for slt if (C.marikoCpuUV) { if (*(ptr - 5) == 620) { - PATCH_OFFSET((ptr - 5), C.marikoCpuVmin); + PATCH_OFFSET((ptr - 5), C.marikoCpuHighVmin); // hf vmin } if (*(ptr - 1) == 620) { - PATCH_OFFSET((ptr - 1), 600); + PATCH_OFFSET((ptr - 1), C.marikoCpuLowVmin); // lf vmin } } R_SUCCEED(); @@ -180,8 +180,16 @@ namespace ams::ldr::oc::pcv::mariko { } Result GpuFreqPllLimit(u32 *ptr) { - int UPPER_GPU_FREQ = -1; // uncap the gpu frequency - PATCH_OFFSET(ptr, UPPER_GPU_FREQ); + clk_pll_param *entry = reinterpret_cast(ptr); + + // All zero except for freq + for (size_t i = 1; i < sizeof(clk_pll_param) / sizeof(u32); i++) { + R_UNLESS(*(ptr + i) == 0, ldr::ResultInvalidGpuPllEntry()); + } + + // Double the max clk simply + u32 max_clk = entry->freq * 2; + entry->freq = max_clk; R_SUCCEED(); } @@ -190,7 +198,7 @@ namespace ams::ldr::oc::pcv::mariko { R_SUCCEED(); } - void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) { +void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) { #define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \ TABLE->burst_regs.PARAM = VALUE; \ TABLE->shadow_regs_ca_train.PARAM = VALUE; \ @@ -213,6 +221,15 @@ namespace ams::ldr::oc::pcv::mariko { u32 trefbw = refresh_raw + 0x40; trefbw = MIN(trefbw, static_cast(0x3FFF)); + /* TODO: Make this less uggly and actually work by finding real clocks */ + if (C.marikoEmcMaxClock > 3'100'000) { + obdly -= 2; + } + + if (C.marikoEmcMaxClock > 2'500'000) { + obdly -= 2; + } + WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC)); @@ -253,14 +270,14 @@ namespace ams::ldr::oc::pcv::mariko { WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN); WRITE_PARAM_ALL_REG(table, emc_einput, 0xF); WRITE_PARAM_ALL_REG(table, emc_einput_duration, 0x31); - WRITE_PARAM_ALL_REG(table, emc_obdly, 0x10000002); + WRITE_PARAM_ALL_REG(table, emc_obdly, obdly); WRITE_PARAM_ALL_REG(table, emc_ibdly, 0x1000001C); - WRITE_PARAM_ALL_REG(table, emc_wdv_mask, 0x12); + WRITE_PARAM_ALL_REG(table, emc_wdv_mask, wdv); WRITE_PARAM_ALL_REG(table, emc_quse_width, 0xD); WRITE_PARAM_ALL_REG(table, emc_quse, 0x2F); - WRITE_PARAM_ALL_REG(table, emc_wdv, 0x12); - WRITE_PARAM_ALL_REG(table, emc_wsv, 0x10); - WRITE_PARAM_ALL_REG(table, emc_wev, 0xE); + WRITE_PARAM_ALL_REG(table, emc_wdv, wdv); + WRITE_PARAM_ALL_REG(table, emc_wsv, wsv); + WRITE_PARAM_ALL_REG(table, emc_wev, wev); WRITE_PARAM_ALL_REG(table, emc_qrst, 0x00080005); WRITE_PARAM_ALL_REG(table, emc_qsafe, 0x44); WRITE_PARAM_ALL_REG(table, emc_tr_qpop, 0x3B); @@ -640,8 +657,7 @@ namespace ams::ldr::oc::pcv::mariko { {"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0x0000FFCF}, {"GPU Freq Table", GpuFreqCvbTable, 1, nullptr, GpuCvbDefaultMaxFreq}, {"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn}, - {"GPU Freq Max (Patch 1)", &GpuFreqMax, 1, nullptr, GpuClkMax}, - {"GPU Freq PLL (Patch 2)", &GpuFreqPllLimit, 0, nullptr, GpuClkPllLimit}, + {"GPU Freq PLL", &GpuFreqPllLimit, 1, nullptr, GpuClkPllLimit}, {"MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit}, {"MEM Freq Dvb", &MemFreqDvbTable, 1, nullptr, EmcClkOSLimit}, {"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit},