From 8514d3c95b1b3f973fe70aba166b6651b14ced88 Mon Sep 17 00:00:00 2001 From: Lightos1 <124387232+Lightos1@users.noreply.github.com> Date: Wed, 26 Aug 2026 19:56:08 +0200 Subject: [PATCH] add proper quse timing --- .../pcv/erista/calculate_timings_erista.cpp | 20 ++++++++++++++++--- .../pcv/mariko/calculate_timings_mariko.cpp | 17 +++++++++++++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/erista/calculate_timings_erista.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/erista/calculate_timings_erista.cpp index 04ec6830..7562a721 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/erista/calculate_timings_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/erista/calculate_timings_erista.cpp @@ -122,11 +122,25 @@ namespace ams::ldr::hoc::pcv::erista { 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; - rdv = RL + 19 + CEIL((flyByTime + tDQSCK_max) / tCK_avg); - qpop = rdv - 16; + u32 fullRoundDelay = CEIL((flyByTime + tDQSCK_max) / tCK_avg); + rdv = RL + fullRoundDelay + 19; + qpop = rdv - 16; + + constexpr double TrimmerStepPs = 3.0; + constexpr double MaxTrimmerSteps = 96.0; + + double tCkAvgPs = tCK_avg * 1000.0; + double tckDerated = tCkAvgPs * 0.85; + u32 derateStepCount = MIN(FLOOR(tckDerated / TrimmerStepPs), MaxTrimmerSteps); + double deratedNsDelay = (derateStepCount * TrimmerStepPs) / 1000.0; + u32 fullTripDerating = fullRoundDelay - CEIL((flyByTime + tDQSCK_max - deratedNsDelay) / tCK_avg); + u32 readEyeStart = FLOOR((flyByTime + 0.94) / tCK_avg) + RL; + + /* Data valid window, quse aligns with the start of the read eye (probably). */ + /* DQS needs to be logically and'ed with quse in order to be valid. */ + quse = readEyeStart + fullTripDerating - 2; quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782); - quse = FLOOR(RL + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg); einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width; einput = quse - CEIL(9.928 / tCK_avg); u32 qrst_duration = FLOOR(8.399 - tCK_avg); diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/calculate_timings_mariko.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/calculate_timings_mariko.cpp index ef09d423..abdac84d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/calculate_timings_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/calculate_timings_mariko.cpp @@ -164,12 +164,27 @@ namespace ams::ldr::hoc::pcv::mariko { tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg); tRATM = CEIL((tRTM - 10.0) + (RL * 0.426)); + u32 fullRoundDelay = CEIL((flyByTime + tDQSCK_max) / tCK_avg); /* Read data valid: Read command -> data ready to be latched into the registers. */ - rdv = RL + 16 + CEIL((flyByTime + tDQSCK_max) / tCK_avg); + rdv = RL + fullRoundDelay + 16; /* Read command -> data poppable at the pad macros, 14 cycles ahead of rdv. */ qpop = rdv - 14; + constexpr double TrimmerStepPs = 3.0; + constexpr double MaxTrimmerSteps = 96.0; + + double tCkAvgPs = tCK_avg * 1000.0; + double tckDerated = tCkAvgPs * 0.85; + u32 derateStepCount = MIN(FLOOR(tckDerated / TrimmerStepPs), MaxTrimmerSteps); + double deratedNsDelay = (derateStepCount * TrimmerStepPs) / 1000.0; + u32 fullTripDerating = fullRoundDelay - CEIL((flyByTime + tDQSCK_max - deratedNsDelay) / tCK_avg); + u32 readEyeStart = FLOOR((flyByTime + 0.94) / tCK_avg) + RL; + + /* Data valid window, quse aligns with the start of the read eye (probably). */ + /* DQS needs to be logically and'ed with quse in order to be valid. */ + quse = readEyeStart + fullTripDerating - 2; + quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782); quse = FLOOR(RL + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg); einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width;