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 67c1370f..9ec9f726 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -75,6 +75,8 @@ namespace ams::ldr::hoc::pcv { /* Round trace routing delay(?) Guessed based on tK1 (ns) */ const double roundTripDelay = 0.5; + const double tODTon = 1.5; + inline u32 RL; inline u32 WL; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.cpp index 1c5f98f3..e55a0520 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.cpp @@ -123,7 +123,7 @@ namespace ams::ldr::hoc::pcv { } } - u32 GetWdqsOn() { + u32 GetOdtLon() { /* Set A. */ switch (WL) { case WL_1333: diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.hpp index e6d37e18..76bda88e 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/common/calculate_timings_common.hpp @@ -26,7 +26,7 @@ namespace ams::ldr::hoc::pcv { void HandleLatency(u32 freq); u32 GetRlFrequency(); u32 GetWlFrequency(); - u32 GetWdqsOn(); + u32 GetOdtLon(); u32 CalculateNWr(); u32 CalculateNTRTP(); u8 CalculateMrw2(); 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 63454858..e10a5fea 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 @@ -56,10 +56,8 @@ namespace ams::ldr::hoc::pcv::erista { double fullRoundDelay = flyByTime + tDQSCK_max; /* Read to write turnaround. */ - /* Nvidia seem to use a 0.25 constant here for tK1, I am 99% certain this is tDQSTA. */ - /* This still left a mismatch; after some brute forcing I got GET_CYCLE_FLOOR(1.5) - 8 (using a static latency) as the cleanest result. */ - /* The latency definitely is not WL, but when testing for every latency, it lines up perfectly with wqsOn and wl seems to cancel out? */ - tR2W = RL + (BL / 2) + CEIL((fullRoundDelay / tCK_avg) + tDQSTA) - GET_CYCLE_FLOOR(1.5) - GetWdqsOn() + tWPRE - (C.t6_tRTW * 3) + finetRTW; + /* Switch seemingly uses odt. */ + tR2W = RL + (BL / 2) + CEIL((fullRoundDelay / tCK_avg) + tDQSTA) - GET_CYCLE_FLOOR(tODTon) - GetOdtLon() + tWPRE - (C.t6_tRTW * 3) + finetRTW; /* Read data valid: Read command -> data ready to be latched into the registers. */ rdv = RL + GET_CYCLE_CEIL(fullRoundDelay) + 18; 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 a939a2d4..4b433ce7 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 @@ -86,10 +86,8 @@ namespace ams::ldr::hoc::pcv::mariko { tR2P = CalculateNTRTP(); /* Read to write turnaround. */ - /* Nvidia seem to use a 0.25 constant here for tK1, I am 99% certain this is tDQSTA. */ - /* This still left a mismatch; after some brute forcing I got GET_CYCLE_FLOOR(1.5) - 8 (using a static latency) as the cleanest result. */ - /* The latency definitely is not WL, but when testing for every latency, it lines up perfectly with wqsOn and wl seems to cancel out? */ - tR2W = RL + (BL / 2) + CEIL((fullRoundDelay / tCK_avg) + tDQSTA) - GET_CYCLE_FLOOR(1.5) - GetWdqsOn() - (tRTW * 3) + finetRTW; + /* Switch seemingly uses odt. */ + tR2W = RL + (BL / 2) + CEIL((fullRoundDelay / tCK_avg) + tDQSTA) - GET_CYCLE_FLOOR(tODTon) - GetOdtLon() - (tRTW * 3) + finetRTW; tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + GET_CYCLE_FLOOR(7.489); tRATM = CEIL((tRTM - 10.0) + (RL * 0.426)); diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp index f95f5484..69172f85 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp @@ -235,6 +235,9 @@ namespace ams::ldr::hoc::pcv::mariko { const u32 tRFCabStock = tRFC_values[0] * 2; table->dram_timings.t_rfc = tRFCabStock; + /* dram_timings.rl is used on Erista to calculate specific RL related timings during memory training for a workaround. */ + /* See fusee or minerva for more details. */ + /* This is unused on Mariko but we will set it regardless for completion. */ table->dram_timings.rl = RL; table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast(mrw2); table->emc_mrw = (table->emc_mrw & ~0x70u) | 0x40; /* nWR */