From 0d5558f876f28ce3873350778bca079a672121e9 Mon Sep 17 00:00:00 2001 From: Lightos1 <124387232+Lightos1@users.noreply.github.com> Date: Sat, 30 May 2026 17:39:49 +0200 Subject: [PATCH] pcv_erista: add experimental proper write timings --- .../oc/erista/calculate_timings_erista.cpp | 39 +++++++++++++++++++ .../loader/source/oc/mtc_timing_value.hpp | 8 ++++ .../loader/source/oc/pcv/pcv_erista.cpp | 12 +++--- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/erista/calculate_timings_erista.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/erista/calculate_timings_erista.cpp index 74e0cb91..a8106726 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/erista/calculate_timings_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/erista/calculate_timings_erista.cpp @@ -82,11 +82,42 @@ namespace ams::ldr::hoc::pcv::erista { } } + void CalculateMrw2() { + static const u8 rlMapDBI[8] = { + 6, 12, 16, 22, 28, 32, 36, 40 + }; + + static const u8 wlMapSetA[8] = { + 4, 6, 8, 10, 12, 14, 16, 18 + }; + + u32 rlIndex = 0; + u32 wlIndex = 0; + + for (u32 i = 0; i < std::size(rlMapDBI); ++i) { + if (rlMapDBI[i] == 32) { + rlIndex = i; + break; + } + } + + for (u32 i = 0; i < std::size(wlMapSetA); ++i) { + if (wlMapSetA[i] == WL) { + wlIndex = i; + break; + } + } + + /* DBI is always enabled. */ + mrw2 = static_cast(((rlIndex & 0x7) | ((wlIndex & 0x7) << 3) | ((0 & 0x1) << 6))); + } + void CalculateTimings(double tCK_avg, u32 freq) { RL = RL_1331; WL = WL_1331; HandleLatency(freq); + CalculateMrw2(); tR2P = CEIL((RL * 0.426) - 2.0); tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW; @@ -95,6 +126,14 @@ namespace ams::ldr::hoc::pcv::erista { tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast(tW2P))) + (BL / 2)); tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR; + wdv = WL; + wsv = WL - 2; + wev = 0xA + (WL - 14); + + u32 obdlyHigh = 3 / FLOOR(MIN(static_cast(2), tCK_avg * (WL - 7))); + u32 obdlyLow = MAX(WL - FLOOR((126.0 / CEIL(tCK_avg + 8.601))), 0.0); + obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow); + pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361))); tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0; 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 15da084e..623c18a0 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -94,11 +94,19 @@ namespace ams::ldr::hoc { inline u32 tWTPDEN; inline u32 tW2R; + inline u32 wdv; + inline u32 wsv; + inline u32 wev; + + inline u32 obdly; + inline u32 pdex2rw; inline u32 tCLKSTOP; inline double pdex2mrr; + + inline u8 mrw2; } namespace pcv::mariko { 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 e0348295..b453aea0 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -257,16 +257,17 @@ namespace ams::ldr::hoc::pcv::erista { WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN); /* Accept imperfection or prepare for suffering. */ + #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) // WRITE_PARAM_ALL_REG(table, emc_einput, einput); // WRITE_PARAM_ALL_REG(table, emc_einput_duration, einput_duration); - // WRITE_PARAM_ALL_REG(table, emc_obdly, obdly); + WRITE_PARAM_ALL_REG(table, emc_obdly, obdly); // WRITE_PARAM_ALL_REG(table, emc_ibdly, ibdly); // WRITE_PARAM_ALL_REG(table, emc_wdv_mask, wdv); // WRITE_PARAM_ALL_REG(table, emc_quse_width, quse_width); // WRITE_PARAM_ALL_REG(table, emc_quse, quse); - // 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_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, qrst); // WRITE_PARAM_ALL_REG(table, emc_tr_qrst, qrst); // WRITE_PARAM_ALL_REG(table, emc_qsafe, qsafe); @@ -279,8 +280,9 @@ namespace ams::ldr::hoc::pcv::erista { // WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv); // WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2); // WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv); - // table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast(mrw2); + table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast(mrw2); // table->dram_timings.rl = RL; + #endif constexpr double MC_ARB_DIV = 4.0; constexpr u32 MC_ARB_SFA = 2;