loader: refactor ram frequency calculation logic

This commit is contained in:
souldbminersmwc
2026-01-01 16:51:11 -05:00
parent ce97087baa
commit ea20003df0
14 changed files with 192 additions and 116 deletions

View File

@@ -19,7 +19,7 @@
#include "timing_tables.hpp"
namespace ams::ldr::oc::pcv::mariko {
u32 calcClock;
u32 GetRext() {
if (auto r = FindRext()) {
return r->correct;
@@ -35,7 +35,7 @@ namespace ams::ldr::oc::pcv::mariko {
for (u32 i = 0; i < g_misc_table_size; i++) {
const auto& e = g_misc_table[i];
if (C.marikoEmcMaxClock >= e.min_freq) {
if (calcClock >= e.min_freq) {
rdv += e.rdv_inc;
if (e.einput) einput_duration = e.einput;
if (e.quse_width) quse_width = e.quse_width;
@@ -64,8 +64,8 @@ namespace ams::ldr::oc::pcv::mariko {
void CalculateTWTPDEN() {
tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6;
if (C.marikoEmcMaxClock >= 2'233'000 && C.marikoEmcMaxClock < 2'533'000) tWTPDEN++;
if (C.marikoEmcMaxClock >= 2'433'000 && C.marikoEmcMaxClock < 2'800'000) tWTPDEN--;
if (calcClock >= 2'233'000 && calcClock < 2'533'000) tWTPDEN++;
if (calcClock >= 2'433'000 && calcClock < 2'800'000) tWTPDEN--;
}
void CalculateTR2W() {
@@ -78,12 +78,12 @@ namespace ams::ldr::oc::pcv::mariko {
void CalculateQrst() {
qrst = 0x00070000;
u32 qrst_calc = ROUND(22.1 - (C.marikoEmcMaxClock / 1000000.0) * 8.0) + C.mem_burst_read_latency;
u32 qrst_calc = ROUND(22.1 - (calcClock / 1000000.0) * 8.0) + C.mem_burst_read_latency;
u32 qrst_low = MAX(static_cast<u32>(0), qrst_calc);
if (C.marikoEmcMaxClock >= 2'533'000) {
if (calcClock >= 2'533'000) {
qrst = INCREMENT_HIGH_BYTES_BY(qrst, 1);
} else if (C.marikoEmcMaxClock == 2'800'000) {
} else if (calcClock == 2'800'000) {
qrst = SET_HIGH_BYTES(qrst, 6);
}
@@ -95,20 +95,20 @@ namespace ams::ldr::oc::pcv::mariko {
}
void CalculateQsafe() {
qsafe = ROUND((C.marikoEmcMaxClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency;
qsafe = ROUND((calcClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency;
if (auto patch = FindQsafePatch()) {
qsafe += patch->adjust;
}
}
void CalculateQpop() {
qpop = FLOOR(((C.marikoEmcMaxClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency;
qpop = FLOOR(((calcClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency;
if (C.marikoEmcMaxClock >= 3'133'000) qpop++;
if (calcClock >= 3'133'000) qpop++;
}
void CalculatePdex2rw() {
double freq_mhz = C.marikoEmcMaxClock / 1000.0;
double freq_mhz = calcClock / 1000.0;
double pdex_local = (0.011 * freq_mhz) - 1.443;
pdex2rw = static_cast<u32>(ROUND(pdex_local));
@@ -122,14 +122,16 @@ namespace ams::ldr::oc::pcv::mariko {
}
void CalculateCke2pden() {
cke2pden = (static_cast<double>((C.marikoEmcMaxClock / 1000.0) * 0.00875) - 0.65);
cke2pden = (static_cast<double>((calcClock / 1000.0) * 0.00875) - 0.65);
if (auto patch = FindCke2pdenPatch()) {
cke2pden += patch->adjust;
}
}
void CalculateTimings() {
void CalculateTimings(u32 rate_khz) {
calcClock = rate_khz;
SetTableMaxClock(rate_khz);
CalculateMiscTimings();
CalculateIbdly();
CalculateObdly();
@@ -142,4 +144,4 @@ namespace ams::ldr::oc::pcv::mariko {
CalculateCke2pden();
}
}
}

View File

@@ -17,7 +17,5 @@
#pragma once
namespace ams::ldr::oc::pcv::mariko {
void CalculateTimings();
}
void CalculateTimings(u32 rate_khz);
}

View File

@@ -18,7 +18,11 @@
#include "timing_tables.hpp"
namespace ams::ldr::oc::pcv::mariko {
u32 clkMax;
void SetTableMaxClock(u32 maxClock) {
clkMax = maxClock;
}
const MiscTimings g_misc_table[] = {
{1'866'000, 1, 0x20, 0x9, },
{2'133'000, 1, 0x24, 0xA, },
@@ -65,7 +69,7 @@ namespace ams::ldr::oc::pcv::mariko {
const ReplacePatch *FindRext() {
for (u32 i = 0; i < g_rext_table_size; i++)
if (g_rext_table[i].freq == C.marikoEmcMaxClock)
if (g_rext_table[i].freq == clkMax)
return &g_rext_table[i];
return nullptr;
}
@@ -92,7 +96,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindIbdlyPatch() {
for (u32 i = 0; i < g_ibdly_table_size; i++)
if (g_ibdly_patches[i].freq == C.marikoEmcMaxClock)
if (g_ibdly_patches[i].freq == clkMax)
return &g_ibdly_patches[i];
return nullptr;
}
@@ -125,7 +129,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindObdlyPatch() {
for (u32 i = 0; i < g_obdly_table_size; i++)
if (g_obdly_patches[i].freq == C.marikoEmcMaxClock)
if (g_obdly_patches[i].freq == clkMax)
return &g_obdly_patches[i];
return nullptr;
}
@@ -143,7 +147,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindTR2WPatch() {
for (u32 i = 0; i < g_tr2w_table_size; i++)
if (g_tr2w_patches[i].freq == C.marikoEmcMaxClock)
if (g_tr2w_patches[i].freq == clkMax)
return &g_tr2w_patches[i];
return nullptr;
}
@@ -178,7 +182,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindQrstPatch() {
for (u32 i = 0; i < g_qrst_table_size; i++)
if (g_qrst_patches[i].freq == C.marikoEmcMaxClock)
if (g_qrst_patches[i].freq == clkMax)
return &g_qrst_patches[i];
return nullptr;
}
@@ -209,7 +213,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindQsafePatch() {
for (u32 i = 0; i < g_qsafe_table_size; i++)
if (g_qsafe_patches[i].freq == C.marikoEmcMaxClock)
if (g_qsafe_patches[i].freq == clkMax)
return &g_qsafe_patches[i];
return nullptr;
}
@@ -234,7 +238,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindPdex2rwPatch() {
for (u32 i = 0; i < g_pdex2rw_table_size; i++)
if (g_pdex2rw_patches[i].freq == C.marikoEmcMaxClock)
if (g_pdex2rw_patches[i].freq == clkMax)
return &g_pdex2rw_patches[i];
return nullptr;
}
@@ -260,9 +264,9 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindCke2pdenPatch() {
for (u32 i = 0; i < g_cke2pden_table_size; i++)
if (g_cke2pden_patches[i].freq == C.marikoEmcMaxClock)
if (g_cke2pden_patches[i].freq == clkMax)
return &g_cke2pden_patches[i];
return nullptr;
}
}
}

View File

@@ -18,7 +18,7 @@
#include "../mtc_timing_value.hpp"
namespace ams::ldr::oc::pcv::mariko {
void SetTableMaxClock(u32 maxClock);
struct ReplacePatch {
u32 freq;
u32 correct;
@@ -71,4 +71,4 @@ namespace ams::ldr::oc::pcv::mariko {
extern const MiscTimings g_misc_table[];
extern const u32 g_misc_table_size;
}
}