Erista: MRf and timing fixes

This commit is contained in:
Lightos1
2026-02-20 07:32:10 +01:00
parent 0f608b1702
commit 1209337af6
5 changed files with 29 additions and 26 deletions

View File

@@ -73,7 +73,7 @@ namespace ams::ldr::hoc {
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 = { 10.0, 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 };
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
const std::array<u32, 6> tRFC_values = { 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 };

View File

@@ -144,7 +144,7 @@ void SafetyCheck() {
{ C.marikoCpuBoostClock, 1020'000, 2703'000, true },
{ C.commonEmcMemVolt, 912'500, 1350'000 }, // Official burst vmax for the RAMs is 1500mV
{ C.eristaCpuMaxVolt, 1000, 1257 },
{ GET_MAX_OF_ARR(erista::maxClocks), 1600'000, 2600'000 },
{ GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000 },
{ C.marikoCpuMaxVolt, 1000, 1235 },
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
{ C.marikoEmcVddqVolt, 250'000, 700'000 },

View File

@@ -178,7 +178,7 @@ namespace ams::ldr::hoc::pcv {
}
namespace erista {
const u32 maxClocks[] = { C.eristaEmcMaxClock2, C.eristaEmcMaxClock1, C.eristaEmcMaxClock, };
static u32 maxEmcClocks[] = { C.eristaEmcMaxClock2, C.eristaEmcMaxClock1, C.eristaEmcMaxClock, };
#define GET_MAX_OF_ARR(ARR) (*std::max_element(ARR, ARR + std::size(ARR)))
constexpr cvb_entry_t CpuCvbTableDefault[] = {

View File

@@ -324,13 +324,13 @@ namespace ams::ldr::hoc::pcv::erista {
table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xFFE08000) | (table->burst_mc_regs.mc_emem_arb_timing_rc + 1);
u32 mpcorer_ptsa_rate = MAX(static_cast<u32>(227), (table->rate_khz / 1600000) * 208);
u32 mpcorer_ptsa_rate = MIN(static_cast<u32>(227), (table->rate_khz / 1600000) * 208);
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = mpcorer_ptsa_rate;
u32 ftop_ptsa_rate = MAX(static_cast<u32>(31), (table->rate_khz / 1600000) * 24);
u32 ftop_ptsa_rate = MIN(static_cast<u32>(31), (table->rate_khz / 1600000) * 24);
table->la_scale_regs.mc_ftop_ptsa_rate = ftop_ptsa_rate;
u32 grant_decrement = MAX(static_cast<u32>(6143), (table->rate_khz / 1600000) * 4611);
u32 grant_decrement = MIN(static_cast<u32>(6143), (table->rate_khz / 1600000) * 4611);
table->la_scale_regs.mc_ptsa_grant_decrement = grant_decrement;
constexpr u32 MaskHigh = 0xFF00FFFF;
@@ -370,7 +370,12 @@ namespace ams::ldr::hoc::pcv::erista {
}
Result MemFreqMtcTable(u32 *ptr) {
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) {
R_SKIP();
}
u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800};
std::sort(maxEmcClocks, maxEmcClocks + std::size(maxEmcClocks), std::greater<>());
u32 khz_list_size = sizeof(khz_list) / sizeof(u32);
// Generate list for mtc table pointers
@@ -382,32 +387,37 @@ namespace ams::ldr::hoc::pcv::erista {
R_UNLESS(table_list[i]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
}
if (GET_MAX_OF_ARR(maxClocks) <= EmcClkOSLimit) {
R_SKIP();
u32 additionalFreqs = 0;
for (u32 i = 0; i < std::size(maxEmcClocks); ++i) {
if (maxEmcClocks[i] > EmcClkOSLimit) {
++additionalFreqs;
} else {
break;
}
}
// Make room for new mtc table, discarding useless 40.8, 68000 and 102000 MHz table
// 40800 overwritten by 68000, ..., 1331200 overwritten by 1600000, leaving table_list[0], table_list[1] and table_list[2] not overwritten
for (u32 i = khz_list_size - 1; i > 2; --i) {
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - 3]), sizeof(EristaMtcTable));
// 40800 overwritten by 204000, ..., 1331200 overwritten by 1600000, leaving table_list[0], table_list[1] and table_list[2] not overwritten
for (u32 i = khz_list_size - 1; i > additionalFreqs - 1; --i) {
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - additionalFreqs]), sizeof(EristaMtcTable));
}
for (u32 i = 0; i < std::size(maxClocks); ++i) {
if (maxClocks[i] > EmcClkOSLimit) {
table_list[i]->rate_khz = maxClocks[i];
MemMtcTableAutoAdjust(table_list[i]);
}
for (u32 i = 0; i < additionalFreqs; ++i) {
/* Since we're not scaling latency timings properly, copy over the 1600Mhz table to get the closest timings. */
std::memcpy(table_list[i], table_list[additionalFreqs], sizeof(EristaMtcTable));
table_list[i]->rate_khz = maxEmcClocks[i];
MemMtcTableAutoAdjust(table_list[i]);
}
R_SUCCEED();
}
Result MemFreqMax(u32 *ptr) {
if (GET_MAX_OF_ARR(maxClocks) <= EmcClkOSLimit) {
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) {
R_SKIP();
}
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxClocks));
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxEmcClocks));
R_SUCCEED();
}
@@ -445,4 +455,5 @@ namespace ams::ldr::hoc::pcv::erista {
}
}
}
}

View File

@@ -575,14 +575,6 @@ namespace ams::ldr::hoc::pcv::mariko {
table->emc_cfg_2 = 0x11083D;
}
// WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE(10.0));
// WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE(10.0));
// WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE(1.75));
// WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE(1.75));
// WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE(1.75));
// WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE(14.0));
// WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE(5.0));
void MemMtcPllmbDivisor(MarikoMtcTable *table) {
constexpr u32 PllOscInKHz = 38400;
constexpr u32 PllOscHalfKHz = 19200;