revert timings

more recalculation must be done
This commit is contained in:
souldbminersmwc committed 2026-07-30 18:22:47 -04:00
1 parent 4582e07d39
commit 8476969576
8 files changed
+45 -82

No files matched your search

@@ -94,16 +94,6 @@ namespace ams::ldr::hoc {
inline u32 tWTPDEN;
inline u32 tW2R;
inline u32 rdv;
inline u32 qpop;
inline u32 quse_width;
inline u32 quse;
inline u32 einput_duration;
inline u32 einput;
inline u32 qrst;
inline u32 ibdly;
inline u32 qsafe;
inline u32 wdv;
inline u32 wsv;
inline u32 wev;
@@ -123,7 +113,7 @@ namespace ams::ldr::hoc {
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
const std::array<double, 8> tRRD_values = { 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 };
const std::array<double, 7> tRRD_values = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? 8gb uses 7.5 tRRD on >=1331. */
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
@@ -120,24 +120,11 @@ namespace ams::ldr::hoc::pcv::erista {
CalculateMrw2();
tR2P = CEIL((RL * 0.426) - 2.0);
tR2W = (2 * WL) + (2 * FLOOR(48.0 / WL)) + 4 + FLOOR((5.653 / tCK_avg) + 0.265) - FLOOR(2.0 / tCK_avg) - (C.t6_tRTW * 3) + finetRTW;
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW;
tW2P = (CEIL(WL * 1.7303) * 2) - 5;
tWTPDEN = CEIL(((1.800 / tCK_avg) + MAX(RL + (2.550 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
tW2R = FLOOR(MAX((5.087 / tCK_avg) + 1.030, WL - MAX(-CEIL(0.258 * (WL - RL)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
rdv = RL + FLOOR((5.678 / tCK_avg) + 18.962);
qpop = rdv - 16;
u32 quseSum = RL + FLOOR(5.659 / tCK_avg) + 4;
quse_width = CEIL((5.363 / tCK_avg) + 4.020) - FLOOR(3.100 / tCK_avg);
quse = quseSum - quse_width;
einput_duration = FLOOR(9.998 / tCK_avg) + 5.0 + quse_width;
einput = quse - (FLOOR(9.998 / tCK_avg) + 1);
u32 qrst_duration = FLOOR((1.398 / tCK_avg) + 4.5);
u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0));
qrst = PACK_U32(qrst_duration, qrstLow);
ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast<double>(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;
@@ -147,8 +134,8 @@ namespace ams::ldr::hoc::pcv::erista {
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((7.5 / tCK_avg) + 0.998) + FLOOR(1.75 / tCK_avg) + FLOOR(1.0 / tCK_avg);
tCLKSTOP = FLOOR(MIN(8.4996 / tCK_avg, 23.0)) + 7.0 + MIN(CEIL(1.75 / tCK_avg) - 3.0, 1.0);
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;
const double tMMRI = tRCD + (tCK_avg * 3);
pdex2mrr = tMMRI + 10;
@@ -94,7 +94,7 @@ namespace ams::ldr::hoc::pcv::erista {
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_trpab, MIN(GET_CYCLE_CEIL(tRPab), static_cast<u32>(0x3F)));
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(tXP) + MIN(GET_CYCLE_CEIL(1.75) - 2, 2u));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(7.425) + 2);
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tXP));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, tCLKSTOP);
WRITE_PARAM_ALL_REG(table, emc_r2p, tR2P);
@@ -109,15 +109,16 @@ namespace ams::ldr::hoc::pcv::erista {
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.763));
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, MAX(GET_CYCLE_CEIL(1.75) - 2, 2u));
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(1.05));
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(14.0));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(8.5));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(8.499));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(pdex2mrr));
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);
@@ -141,6 +142,8 @@ namespace ams::ldr::hoc::pcv::erista {
// 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<u32>(mrw2);
// table->dram_timings.rl = RL;
// #endif
constexpr double MC_ARB_DIV = 4.0;
constexpr u32 MC_ARB_SFA = 2;
@@ -15,19 +15,18 @@
*/
#include <stratosphere.hpp>
#include "../pcv.hpp"
#include "../../mtc_timing_value.hpp"
#include "timing_tables.hpp"
namespace ams::ldr::hoc::pcv::mariko {
void GetRext(u32 freq) {
if (auto r = FindRext(freq)) {
void GetRext() {
if (auto r = FindRext()) {
rext = r->rext;
return;
}
/* Fallback */
/* > 3200 */
rext = 0x1E;
}
@@ -47,10 +46,9 @@ namespace ams::ldr::hoc::pcv::mariko {
}
void AutoLatency(volatile u32 &latency, u32 freq, u32 latencyStep) {
if (freq > 1600'000 && freq <= 1866'000) { /* 1866tRWL */
if (freq > 1600'000 && freq <= 1862'400) { /* 1866tRWL */
latency += latencyStep * 2;
} else { /* 2133tRWL */
// Note: JEDEC/Datasheet mandates 2133 for >1866, even if <2133
latency += latencyStep * 3;
}
}
@@ -132,7 +130,7 @@ namespace ams::ldr::hoc::pcv::mariko {
HandleLatency(freq);
GetRext(freq);
GetRext();
/* At 1333WL, for some reason (incorrect ram timing config in mtc table?), tRP causes crashes at high reductions - 2 seems to be the most common limit. */
/* This is a lazy workaround until I find the issue... */
@@ -153,7 +151,7 @@ namespace ams::ldr::hoc::pcv::mariko {
u32 tREFI = lowFreq ? C.low_t8_tREFI : C.t8_tREFI;
refresh_raw = 0xFFFF;
if (tREFI != 6) {
refresh_raw = ROUND(tREFpb_values[tREFI] / tCK_avg) - 0x40;
refresh_raw = CEIL(tREFpb_values[tREFI] / tCK_avg) - 0x40;
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
}
@@ -164,26 +162,25 @@ namespace ams::ldr::hoc::pcv::mariko {
tRPab = tRPpb + 3;
tR2P = CEIL((RL * 0.426) - 2.0);
tR2W = RL + 2 * (FLOOR(48.0 / WL) - 2) + CEIL((5.036 / tCK_avg) + 0.418) - FLOOR((1.5 / tCK_avg) + 0.002) - (tRTW * 3) + finetRTW;
tRTM = FLOOR((10.0 + RL) + (3.496 / tCK_avg)) + FLOOR(7.430 / tCK_avg);
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (tRTW * 3) + finetRTW;
tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg);
tRATM = CEIL((tRTM - 10.0) + (RL * 0.426));
rdv = RL + FLOOR((5.109 / tCK_avg) + 17.003);
rdv = RL + FLOOR((5.105 / tCK_avg) + 17.017);
qpop = rdv - 14;
u32 quseSum = RL + FLOOR(5.110 / tCK_avg) + 4;
quse_width = CEIL(MAX((4.7980 / tCK_avg) + 4.046, (5.0680 / tCK_avg) + 3.276)) - FLOOR(2.55 / tCK_avg);
quse = quseSum - quse_width;
einput_duration = FLOOR(9.998 / tCK_avg) + 5.0 + quse_width;
einput = quse - (FLOOR(9.998 / tCK_avg) + 1);
u32 qrst_duration = FLOOR((1.398 / tCK_avg) + 4.5);
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);
u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0));
qrst = PACK_U32(qrst_duration, qrstLow);
ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
tW2P = (CEIL(WL * 1.7303) * 2) - 5;
tWTPDEN = CEIL(((1.800 / tCK_avg) + MAX(RL + (2.550 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
tW2R = FLOOR(MAX((5.087 / tCK_avg) + 1.030, WL - MAX(-CEIL(0.258 * (WL - RL)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
tWTM = CEIL(WL + ((7.386 / tCK_avg) + 9.150));
tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast<double>(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;
tWTM = CEIL(WL + ((7.570 / tCK_avg) + 8.753));
tWATM = (tWTM + (FLOOR(WL / 0.816) * 2.0)) - 4.0;
wdv = WL;
@@ -194,9 +191,9 @@ namespace ams::ldr::hoc::pcv::mariko {
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((7.5 / tCK_avg) + 0.998) + FLOOR(1.75 / tCK_avg) + FLOOR(1.0 / tCK_avg);
pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));
tCLKSTOP = FLOOR(MIN(8.4996 / tCK_avg, 23.0)) + 7.0 + MIN(CEIL(1.75 / tCK_avg) - 3.0, 1.0);
tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;
u32 tMMRI = tRCD + (tCK_avg * 3);
pdex2mrr = tMMRI + 10;
@@ -56,30 +56,27 @@ namespace ams::ldr::hoc::pcv::mariko {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0xF3200000);
}
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000);
CalculateTimings(tCK_avg, table->rate_khz);
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
const u32 ras_cyc = MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F));
const u32 rp_cyc = GET_CYCLE_CEIL(tRPpb);
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, MIN(GET_CYCLE_CEIL(tRC), ras_cyc + rp_cyc));
WRITE_PARAM_ALL_REG(table, emc_ras, ras_cyc);
WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB9)));
WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F)));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rp, rp_cyc);
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_trpab, MIN(GET_CYCLE_CEIL(tRPab), static_cast<u32>(0x3F)));
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(tXP) + MIN(GET_CYCLE_CEIL(1.75) - 2, 2u));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(7.425) + 2);
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tXP));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, tCLKSTOP);
WRITE_PARAM_ALL_REG(table, emc_r2p, tR2P);
@@ -98,11 +95,11 @@ namespace ams::ldr::hoc::pcv::mariko {
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.763));
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, MAX(GET_CYCLE_CEIL(1.75) - 2, 2u));
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(1.05));
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(14.0));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(8.5));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(8.499));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(pdex2mrr));
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN);
WRITE_PARAM_ALL_REG(table, emc_einput, einput);
@@ -26,8 +26,6 @@
namespace ams::ldr::hoc::pcv::mariko {
DramId GetDramId();
void MtcGenerateFreqTables();
Result MemFreqMtcTable(u32 *ptr);
Result MemFreqDvbTable(u32 *ptr);
@@ -20,11 +20,6 @@
namespace ams::ldr::hoc::pcv::mariko {
const ReplacePatch g_rext_table[] = {
{1'633'000, 0x17}, {1'666'000, 0x18}, {1'700'000, 0x18},
{1'733'000, 0x18}, {1'766'000, 0x18}, {1'800'000, 0x1A},
{1'833'000, 0x1A}, {1'866'000, 0x1A}, {1'900'000, 0x19},
{1'933'000, 0x19}, {1'966'000, 0x19}, {2'000'000, 0x19},
{2'033'000, 0x19}, {2'066'000, 0x19}, {2'100'000, 0x1A},
{2'133'000, 0x1A}, {2'166'000, 0x19}, {2'200'000, 0x19},
{2'233'000, 0x19}, {2'266'000, 0x1A}, {2'300'000, 0x1B},
{2'333'000, 0x1B}, {2'366'000, 0x1B}, {2'400'000, 0x1B},
@@ -36,17 +31,13 @@ namespace ams::ldr::hoc::pcv::mariko {
{2'933'000, 0x1C}, {2'966'000, 0x1D}, {3'000'000, 0x1D},
{3'033'000, 0x1D}, {3'066'000, 0x1D}, {3'100'000, 0x1D},
{3'133'000, 0x1D}, {3'166'000, 0x1C}, {3'200'000, 0x1C},
{3'233'000, 0x1E}, {3'266'000, 0x1F}, {3'300'000, 0x1E},
{3'333'000, 0x1F}, {3'366'000, 0x1F}, {3'400'000, 0x1F},
{3'433'000, 0x1F}, {3'466'000, 0x1F}, {3'500'000, 0x1E},
};
const u32 g_rext_table_size = sizeof(g_rext_table) / sizeof(g_rext_table[0]);
const ReplacePatch *FindRext(u32 rate_khz) {
const ReplacePatch *FindRext() {
for (u32 i = 0; i < g_rext_table_size; i++) {
if (g_rext_table[i].freq >= rate_khz) {
if (g_rext_table[i].freq >= C.marikoEmcMaxClock) {
return &g_rext_table[i];
}
}
@@ -26,6 +26,6 @@ namespace ams::ldr::hoc::pcv::mariko {
extern const ReplacePatch g_rext_table[];
extern const u32 g_rext_table_size;
const ReplacePatch *FindRext(u32 rate_khz);
const ReplacePatch *FindRext();
}