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 3bbe4f84..5252f606 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -73,7 +73,7 @@ namespace ams::ldr::hoc { const std::array tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 }; const std::array tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 }; const std::array tRRD_values = { 10.0, 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; - const std::array tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 }; + const std::array tRFC_values = { 90, 80, 70, 60, 50, 40 }; const std::array tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; const std::array tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 }; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp index b969179a..d4551292 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp @@ -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 }, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp index 0da748c4..3975b5b9 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp @@ -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[] = { diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp index 282ceadd..364b3fde 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -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(227), (table->rate_khz / 1600000) * 208); + u32 mpcorer_ptsa_rate = MIN(static_cast(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(31), (table->rate_khz / 1600000) * 24); + u32 ftop_ptsa_rate = MIN(static_cast(31), (table->rate_khz / 1600000) * 24); table->la_scale_regs.mc_ftop_ptsa_rate = ftop_ptsa_rate; - u32 grant_decrement = MAX(static_cast(6143), (table->rate_khz / 1600000) * 4611); + u32 grant_decrement = MIN(static_cast(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(table_list[i]), static_cast(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(table_list[i]), static_cast(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 { } } } + } diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp index 9a62f222..1b29de62 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -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;