From ad212a15c0b84fdd67b5e6c9d2b1c2d2179b0b63 Mon Sep 17 00:00:00 2001 From: Lightos1 Date: Tue, 30 Sep 2025 22:30:27 +0200 Subject: [PATCH] Add AUTO_ADJ for erista --- .../loader/source/oc/customize.cpp | 1 - .../loader/source/oc/customize.hpp | 6 +- .../loader/source/oc/mtc_timing_value.hpp | 150 ++++++++--------- .../loader/source/oc/pcv/pcv_erista.cpp | 158 +++--------------- 4 files changed, 101 insertions(+), 214 deletions(-) diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 273ff110..e2e3b629 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -91,7 +91,6 @@ volatile CustomizeTable C = { .marikoGpuUV = 0, - .eristaCpuUV = 0, .eristaGpuUV = 0, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp index a19bb026..11287b52 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp @@ -30,11 +30,7 @@ #include "mtc_timing_table.hpp" enum MtcConfig: u32 { - AUTO_ADJ_ALL = 0, - CUSTOM_ADJ_ALL = 1, - NO_ADJ_ALL = 2, - - CUSTOMIZED_ALL = 4, + AUTO_ADJ = 0, }; using CustomizeCpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit]; 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 b6057757..8f0ca68d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -21,35 +21,35 @@ #pragma once #include "oc_common.hpp" - + namespace ams::ldr::oc { #define MAX(A, B) std::max(A, B) #define MIN(A, B) std::min(A, B) #define CEIL(A) std::ceil(A) #define FLOOR(A) std::floor(A) - + //Preset One const std::array tRCD_values = {18, 17, 16, 15, 14, 13, 12, 11}; 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}; - + // Preset Two const std::array tRRD_values = {10, 7.5, 6, 5, 4, 3, 2, 1}; const std::array tFAW_values = {40, 30, 24, 16, 12}; - + // Preset Three const std::array tWR_values = {18, 15, 15, 12, 12, 8}; // TODO: identify what exactly eos tRTW even is (is it even real?) const std::array tRTP_values = {7.5, 7.5, 6, 6, 4, 4}; - + // Preset Four const std::array tRFC_values = {140, 120, 100, 80, 70, 60}; - + // Preset Five const std::array tWTR_values = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; - + // Preset Six const std::array tREFpb_values = {488, 976, 1952, 3256, 9999, 9999}; - + // const u32 TIMING_PRESET_ONE = C.ramTimingPresetOne; // const u32 TIMING_PRESET_TWO = C.ramTimingPresetTwo; const u32 TIMING_PRESET_THREE = 0; @@ -57,138 +57,137 @@ // const u32 TIMING_PRESET_FIVE = C.ramTimingPresetFive; // const u32 TIMING_PRESET_SIX = C.ramTimingPresetSix; // const u32 TIMING_PRESET_SEVEN = C.ramTimingPresetSeven; - + // Burst Length const u32 BL = 16; - + // tRFCpb (refresh cycle time per bank) in ns for 8Gb density const u32 tRFCpb = !C.t5_tRFC ? 140 : tRFC_values[C.t5_tRFC-1]; - + // tRFCab (refresh cycle time all banks) in ns for 8Gb density const u32 tRFCab = !C.t5_tRFC ? 280 : 2*tRFCpb; - + // tRAS (row active time) in ns const u32 tRAS = !C.t3_tRAS ? 42 : tRAS_values[C.t3_tRAS-1]; - + // tRPpb (row precharge time per bank) in ns const u32 tRPpb = !C.t2_tRP ? 18 : tRP_values[C.t2_tRP-1]; - + // tRPab (row precharge time all banks) in ns const u32 tRPab = !C.t2_tRP ? 21 : tRPpb + 3; - + // tRC (ACTIVATE-ACTIVATE command period same bank) in ns const u32 tRC = tRPpb + tRAS; - const u32 tRTW = !C.t6_tRTW ? 10 : tWTR_values[C.t6_tRTW-1]; // DQS output access time from CK_t/CK_c - const double tDQSCK_min = 1.5; + const double tDQSCK_min = 1.5; // TODO: Fix/remove for mariko if needed // DQS output access time from CK_t/CK_c - const double tDQSCK_max = 3.5; + const double tDQSCK_max = 3.5; // TODO: Fix/remove for mariko if needed // Write preamble (tCK) - const double tWPRE = 1.8; + const double tWPRE = 1.8; // TODO: Fix/remove for mariko if needed // Read postamble (tCK) - const double tRPST = 0.4; + const double tRPST = 0.4; // TODO: Fix/remove for mariko if needed // WRITE command to first DQS transition(max) (tCK) - const double tDQSS_max = 1.25; + const double tDQSS_max = 1.25; // TODO: Fix/remove for mariko if needed // DQ-to-DQS offset(max) (ns) - const double tDQS2DQ_max = 0.8; + const double tDQS2DQ_max = 0.8; // TODO: Fix/remove for mariko if needed // DQS_t, DQS_c to DQ skew total, per group, per access (DBI Disabled) - const double tDQSQ = 0.18; - + const double tDQSQ = 0.18; // TODO: Fix/remove for mariko if needed + // Write-to-Read delay const u32 tWTR = !C.t7_tWTR ? 10 : tWTR_values[C.t7_tWTR-1]; - + // Internal READ-to-PRE-CHARGE command delay in ns const double tRTP = !TIMING_PRESET_THREE ? 7.5 : tRTP_values[TIMING_PRESET_THREE-1]; - + // write recovery time const u32 tWR = !TIMING_PRESET_THREE ? 18 : tWR_values[TIMING_PRESET_THREE-1]; - + // Read to refresh delay const u32 tR2REF = tRTP + tRPpb; - + // tRCD (RAS-CAS delay) in ns const u32 tRCD = !C.t1_tRCD ? 18 : tRCD_values[C.t1_tRCD-1]; - + // tRRD (Active bank-A to Active bank-B) in ns const double tRRD = !C.t4_tRRD ? 10. : tRRD_values[C.t4_tRRD-1]; - + // tREFpb (average refresh interval per bank) in ns for 8Gb density const u32 tREFpb = !C.t8_tREFI ? 488 : tREFpb_values[C.t8_tREFI-1]; // tREFab (average refresh interval all 8 banks) in ns for 8Gb density // const u32 tREFab = tREFpb * 8; - + // tPDEX2WR, tPDEX2RD (timing delay from exiting powerdown mode to a write/read command) in ns // const u32 tPDEX2 = 10; // Exit power-down to next valid command delay const double tXP = 10; - + // Delay from valid command to CKE input LOW in ns - const double tCMDCKE = 1.75; - + const double tCMDCKE = 1.75; // TODO: Fix/remove for mariko if needed + // tACT2PDEN (timing delay from an activate, MRS or EMRS command to power-down entry) in ns // Valid clock and CS requirement after CKE input LOW after MRW command - const u32 tMRWCKEL = 14; - + const u32 tMRWCKEL = 14; // TODO: Fix/remove for mariko if needed + // Valid CS requirement after CKE input LOW - const double tCKELCS = 5; - + const double tCKELCS = 5; // TODO: Fix/remove for mariko if needed + // Valid CS requirement before CKE input HIGH - const double tCSCKEH = 1.75; - + const double tCSCKEH = 1.75; // TODO: Fix/remove for mariko if needed + // tXSR (SELF REFRESH exit to next valid command delay) in ns const double tXSR = tRFCab + 7.5; - + // tCKE (minimum pulse width(HIGH and LOW pulse width)) in ns - const double tCKE = 7.5; - + const double tCKE = 7.5; // TODO: Fix/remove for mariko if needed + // Minimum self refresh time (entry to exit) const u32 tSR = 15; - + // tFAW (Four-bank Activate Window) in ns const u32 tFAW = 40;// !TIMING_PRESET_TWO ? 40 : tFAW_values[TIMING_PRESET_TWO-1]; TOGO - + // Valid Clock requirement before CKE Input HIGH in ns - const double tCKCKEH = 1.75; - + const double tCKCKEH = 1.75; // TODO: Fix/remove for mariko if needed + // p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ //const u32 QUSE = RL + CEIL(tDQSCK_min/tCK_avg + tDQSQ); - + namespace pcv::erista { // tCK_avg (average clock period) in ns const double tCK_avg = 1000'000. / C.eristaEmcMaxClock; - + // Write Latency const u32 WL = 14 + C.mem_burst_latency; // Read Latency const u32 RL = 32 - C.mem_burst_latency; - + // minimum number of cycles from any read command to any write command, irrespective of bank - const u32 R2W = CEIL (RL + CEIL(tDQSCK_max/tCK_avg) + BL/2 - WL + tWPRE + FLOOR(tRPST)) + 6; - + // const u32 R2W = CEIL (RL + CEIL(tDQSCK_max/tCK_avg) + BL/2 - WL + tWPRE + FLOOR(tRPST)) + 6; + // Delay Time From WRITE-to-READ - const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg) - 6; - + // const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg) - 6; + // write-to-precharge time for commands to the same bank in cycles - const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8; - - // #_of_rows per die for 8Gb density - const u32 numOfRows = 65536; + // const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8; + + // #_of_rows per die for 16Gb density + const u32 numOfRows = 131072; // {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%] // emc_clk_period = dram_clk / 2; // 1600 MHz: 5894, but N' set to 6176 (~4.8% margin) const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4); const u32 REFBW = MIN((u32)65536, REFRESH+64); - + // Write With Auto Precharge to to Power-Down Entry - const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6; - + // const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6; + // Additional time after t XP hasexpired until the MRR commandmay be issued - const double tMRRI = tRCD + 3 * tCK_avg; - + // const double tMRRI = tRCD + 3 * tCK_avg; + // tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns - const double tPDEX2MRR = tXP + tMRRI; + // const double tPDEX2MRR = tXP + tMRRI; } namespace pcv::mariko { // tCK_avg (average clock period) in ns @@ -197,28 +196,28 @@ const u32 WL = 14 + C.mem_burst_latency; // Read Latency const u32 RL = 32 - C.mem_burst_latency; - + // minimum number of cycles from any read command to any write command, irrespective of bank const u32 R2W = WL + BL/2 + 1 + CEIL(tRTW/tCK_avg); - + // Delay Time From WRITE-to-READ const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg); - + // write-to-precharge time for commands to the same bank in cycles const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg); - + // Read-To-MRW delay const u32 RTM = RL + BL/2 + CEIL(tDQSCK_max/tCK_avg) + FLOOR(tRPST) + CEIL(7.5/tCK_avg); - + // Write-To-MRW/MRR delay const u32 WTM = WL + 1 + BL/2 + CEIL(7.5/tCK_avg); - + // Read With AP-To-MRW/MRR delay const u32 RATM = RTM + CEIL(tRTP/tCK_avg) - 8; - + // Write With AP-To-MRW/MRR delay const u32 WATM = WTM + CEIL(tWR/tCK_avg); - + // #_of_rows per die for 8Gb density const u32 numOfRows = 65536; // {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%] @@ -226,15 +225,14 @@ // 1600 MHz: 5894, but N' set to 6176 (~4.8% margin) const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4); const u32 REFBW = MIN((u32)65536, REFRESH+64); - + // Write With Auto Precharge to to Power-Down Entry const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6; - + // Additional time after t XP hasexpired until the MRR commandmay be issued const double tMRRI = tRCD + 3 * tCK_avg; - + // tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns const double tPDEX2MRR = tXP + tMRRI; } } - \ No newline at end of file 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 dd0d2711..91b2f8f5 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -21,8 +21,7 @@ #include "pcv.hpp" #include "../mtc_timing_value.hpp" - namespace ams::ldr::oc::pcv::erista - { + namespace ams::ldr::oc::pcv::erista { Result CpuFreqVdd(u32* ptr) { dvfs_rail* entry = reinterpret_cast(reinterpret_cast(ptr) - offsetof(dvfs_rail, freq)); @@ -43,18 +42,15 @@ R_SUCCEED(); } - Result GpuVmin(u32 *ptr) - { + Result GpuVmin(u32 *ptr) { if (!C.eristaGpuVmin) R_SKIP(); PATCH_OFFSET(ptr, (int)C.eristaGpuVmin); R_SUCCEED(); } - Result CpuVoltRange(u32 *ptr) - { + Result CpuVoltRange(u32 *ptr) { u32 min_volt_got = *(ptr - 1); - for (const auto &mv : CpuMinVolts) - { + for (const auto &mv : CpuMinVolts) { if (min_volt_got != mv) continue; @@ -107,8 +103,7 @@ R_SUCCEED(); } - Result GpuFreqMaxAsm(u32 *ptr32) - { + Result GpuFreqMaxAsm(u32 *ptr32) { // Check if both two instructions match the pattern u32 ins1 = *ptr32, ins2 = *(ptr32 + 1); if (!(asm_compare_no_rd(ins1, asm_pattern[0]) && asm_compare_no_rd(ins2, asm_pattern[1]))) @@ -120,8 +115,7 @@ R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); u32 max_clock; - switch (C.eristaGpuUV) - { + switch (C.eristaGpuUV) { case 0: max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq; break; @@ -132,12 +126,9 @@ max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTableHigh)->freq; break; case 3: - if(C.enableEristaGpuUnsafeFreqs) - { + if(C.enableEristaGpuUnsafeFreqs) { max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTableUv3UnsafeFreqs)->freq; - } - else - { + } else { max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq; } break; @@ -154,13 +145,11 @@ R_SUCCEED(); } - Result GpuFreqPllLimit(u32 *ptr) - { + Result GpuFreqPllLimit(u32 *ptr) { clk_pll_param *entry = reinterpret_cast(ptr); // All zero except for freq - for (size_t i = 1; i < sizeof(clk_pll_param) / sizeof(u32); i++) - { + for (size_t i = 1; i < sizeof(clk_pll_param) / sizeof(u32); i++) { R_UNLESS(*(ptr + i) == 0, ldr::ResultInvalidGpuPllEntry()); } @@ -170,9 +159,8 @@ R_SUCCEED(); } - void MemMtcTableAutoAdjust(EristaMtcTable *table) - { - if (C.mtcConf != AUTO_ADJ_ALL) + void MemMtcTableAutoAdjust(EristaMtcTable *table) { + if (C.mtcConf != AUTO_ADJ) return; #define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \ @@ -188,10 +176,7 @@ WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb)); - WRITE_PARAM_ALL_REG(table, emc_r2w, R2W); - WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); - WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); 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_rrd, GET_CYCLE_CEIL(tRRD)); @@ -199,22 +184,11 @@ WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4); WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(tXP)); WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(tXP)); - WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(tCMDCKE)); - WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(tMRWCKEL)); - WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(tCMDCKE)); - WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN); - WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(tCKELCS)); - WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(tCSCKEH)); - WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR)); WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe)); WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe)); - WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(tCKE)); WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR)); - WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tCKE)); WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); - WRITE_PARAM_ALL_REG(table, emc_tclkstable, GET_CYCLE_CEIL(tCKCKEH)); - WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tCKE) + 8); WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW); #define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE; @@ -227,98 +201,23 @@ table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; - table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV); - table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV); + //table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV); + //table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV); // table->burst_mc_regs.mc_emem_arb_timing_r2r = CEIL(table->burst_regs.emc_rext / MC_ARB_DIV) - 1 + MC_ARB_SFA; // table->burst_mc_regs.mc_emem_arb_timing_w2w = CEIL(table->burst_regs.emc_wext / MC_ARB_DIV) - 1 + MC_ARB_SFA; - table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA; - table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA; + // table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA; + // table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA; table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV); // table->burst_mc_regs.mc_emem_arb_timing_ccdmw = CEIL(tCCDMW / MC_ARB_DIV) -1 + MC_ARB_SFA; } - void MemMtcTableCustomAdjust(EristaMtcTable *table) - { - if (C.mtcConf != CUSTOM_ADJ_ALL) - return; - - constexpr u32 MC_ARB_DIV = 4; - constexpr u32 MC_ARB_SFA = 2; - - WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC)); - WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); - WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb)); - WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); - 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_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR)); - - table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV - 2); - table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV - 1); - table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA); - table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV - 2); - - WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW)); - WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); - - table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; - table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; - - - WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); - WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); - WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN); - - table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV); - table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV); - - - WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab)); - WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); - WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe)); - WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe)); - - table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV); - - - WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); - - table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA; - - WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH); - WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4); - WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW); - WRITE_PARAM_ALL_REG(table, emc_r2w, R2W); - WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); - WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); - WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN); - - table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV); - table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA; - table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA; - - u32 DA_TURNS = 0; - DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; // R2W TURN - DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; // W2R TURN - WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_da_turns, DA_TURNS); - u32 DA_COVERS = 0; - u8 R_COVER = (table->burst_mc_regs.mc_emem_arb_timing_rap2pre + table->burst_mc_regs.mc_emem_arb_timing_rp + table->burst_mc_regs.mc_emem_arb_timing_rcd) / 2; - u8 W_COVER = (table->burst_mc_regs.mc_emem_arb_timing_wap2pre + table->burst_mc_regs.mc_emem_arb_timing_rp + table->burst_mc_regs.mc_emem_arb_timing_rcd) / 2; - DA_COVERS |= (u8)(table->burst_mc_regs.mc_emem_arb_timing_rc / 2); // RC COVER - DA_COVERS |= (R_COVER << 8); // RCD_R COVER - DA_COVERS |= (W_COVER << 16); // RCD_W COVER - WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_da_covers, DA_COVERS); - } - - Result MemFreqMtcTable(u32 *ptr) - { + Result MemFreqMtcTable(u32 *ptr) { u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800}; u32 khz_list_size = sizeof(khz_list) / sizeof(u32); // Generate list for mtc table pointers EristaMtcTable *table_list[khz_list_size]; - for (u32 i = 0; i < khz_list_size; i++) - { + for (u32 i = 0; i < khz_list_size; i++) { u8 *table = reinterpret_cast(ptr) - offsetof(EristaMtcTable, rate_khz) - i * sizeof(EristaMtcTable); table_list[i] = reinterpret_cast(table); R_UNLESS(table_list[i]->rate_khz == khz_list[i], ldr::ResultInvalidMtcTable()); @@ -344,8 +243,7 @@ R_SUCCEED(); } - Result MemFreqMax(u32 *ptr) - { + Result MemFreqMax(u32 *ptr) { if (C.eristaEmcMaxClock <= EmcClkOSLimit) R_SKIP(); @@ -354,16 +252,15 @@ R_SUCCEED(); } - void Patch(uintptr_t mapped_nso, size_t nso_size) - { + void Patch(uintptr_t mapped_nso, size_t nso_size) { u32 CpuCvbDefaultMaxFreq = static_cast(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq); u32 GpuCvbDefaultMaxFreq = static_cast(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq); PatcherEntry patches[] = { - { "CPU Freq Vdd", &CpuFreqVdd, 1, nullptr, CpuClkOSLimit }, + {"CPU Freq Vdd", &CpuFreqVdd, 1, nullptr, CpuClkOSLimit }, {"CPU Freq Table", CpuFreqCvbTable, 1, nullptr, CpuCvbDefaultMaxFreq}, - { "CPU Volt Limit", &CpuVoltRange, 13, nullptr, CpuVoltOfficial }, - { "CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFEAD0FF }, + {"CPU Volt Limit", &CpuVoltRange, 13, nullptr, CpuVoltOfficial }, + {"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFEAD0FF }, {"GPU Freq Table", GpuFreqCvbTable, 1, nullptr, GpuCvbDefaultMaxFreq}, {"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn}, {"GPU Freq PLL", &GpuFreqPllLimit, 1, nullptr, GpuClkPllLimit}, @@ -376,18 +273,15 @@ for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(EristaMtcTable); - ptr += sizeof(u32)) - { + ptr += sizeof(u32)) { u32 *ptr32 = reinterpret_cast(ptr); - for (auto &entry : patches) - { + for (auto &entry : patches) { if (R_SUCCEEDED(entry.SearchAndApply(ptr32))) break; } } - for (auto &entry : patches) - { + for (auto &entry : patches) { LOGGING("%s Count: %zu", entry.description, entry.patched_count); if (R_FAILED(entry.CheckResult())) CRASH(entry.description);