From eed44be28b3224691418799f672d68e57ed6cdbf Mon Sep 17 00:00:00 2001 From: KazushiM <85604869+KazushiMe@users.noreply.github.com> Date: Sun, 6 Feb 2022 14:19:51 +0800 Subject: [PATCH] - Remove PLL clock limit (Mariko GPU 1300MHz, MEM 2133MHz; Erista MEM 1866MHz) - Remove partial DRAM timing customization (waste of time & mem space, import and edit from ams fusee mtc_table instead) --- README.md | 17 +- .../loader/source/ldr_oc_suite.cpp | 290 +++++------------- .../loader/source/ldr_oc_suite.hpp | 16 +- .../loader/source/mtc_timing_table.hpp | 156 ---------- Source/sys-clk-OC/README.md | 2 + 5 files changed, 102 insertions(+), 379 deletions(-) diff --git a/README.md b/README.md index a46ac108..1babbe0e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ I'd appreciate if someone is willing to contribute or upload latest binaries. Bu - There is **no dynamic frequency scaling** in HOS, which makes _overclocking acts differently than PC_ or other mobile devices. The console will be _sticking to what frequency you've set in the long term_, until you close the game or put it into sleep. -- Higher RAM clocks (> 1996.8 MHz) without proper timings could be UNSTABLE and cause graphical glitches / instabilities / filesystem corruption. **Always make backup before usage.** +- Higher RAM clocks without proper timings could be UNSTABLE and cause graphical glitches / instabilities / filesystem corruption. **Always make backup before usage.** @@ -26,13 +26,14 @@ I'd appreciate if someone is willing to contribute or upload latest binaries. Bu - Most games are **bottlenecked by RAM bandwidth** - - Timings could be auto-adjusted (default), partially customized, or overwritten with entire mtc table. - - - Safe: ≤1996.8 MHz - - 1996.8 MHz has been tested stable for all (Samsung / Micron / Hynix), with built-in timing auto-adjustment. + - Safe: + - Mariko: 1996.8 MHz has been tested stable for all (Samsung / Micron / Hynix), with built-in timing auto-adjustment. + - Erista: 1862.4 MHz. - Unsafe: > 1996.8 MHz or overvolting - - Timing customization: No GUI tool, requires [rebuilding](#Build). + - Timing: + - Timing parameters could be auto-adjusted (default) or overwritten with user-provided mtc table. + - Customization: No GUI tool, requires [rebuilding](#Build). - DRAM bus overvolting (Erista Only). - Mariko: [use this to set DRAM bus voltage](https://gist.github.com/KazushiMe/6bb0fcbefe0e03b1274079522516d56d). @@ -66,7 +67,7 @@ I'd appreciate if someone is willing to contribute or upload latest binaries. Bu - GPU: 1305 MHz (no overvolting, less than official threshold 1050 mV) - NVIDIA Official Maximum: 1267.2 MHz - - Tested with deko3d compute shaders converted from Maxwell SASS assembly. Single-precision floating point (FP32 FFMA) performance maxes out at 1305 MHz. + - ~~Tested with deko3d compute shaders converted from Maxwell SASS assembly. Single-precision floating point (FP32 FFMA) performance maxes out at 1305 MHz.~~ - 1305 MHz CANNOT be set without charger connected. - **Modded sys-clk and ReverseNX**(-RT) @@ -103,7 +104,7 @@ I'd appreciate if someone is willing to contribute or upload latest binaries. Bu | CPU OC | 2397 MHz Max | Disabled | | CPU Volt | 1220 mV Max | Disabled | | GPU OC | 1305 MHz Max | N/A | - | RAM OC | 1996 MHz Max | 1996 MHz Max | + | RAM OC | 1996 MHz Max | 1862 MHz Max | | RAM Volt | N/A | Disabled | | RAM Timing | Auto-Adjusted | Disabled | diff --git a/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.cpp b/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.cpp index 7359bed2..6744397d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.cpp @@ -26,9 +26,8 @@ namespace ams::ldr::oc { * AUTO_ADJ_MARIKO_4266: Auto adjust timings for LPDDR4X 4266 Mbps specs, 8Gb density. * ENTIRE_TABLE_ERISTA/ENTIRE_TABLE_MARIKO: * Replace the entire max mtc table with customized one. - * CUSTOMIZED_MARIKO: Override timings (partially). */ - .mtcConf = AUTO_ADJ_MARIKO_SAFE; + .mtcConf = AUTO_ADJ_MARIKO_SAFE, /* Mariko CPU: * - Max Clock in kHz: @@ -48,6 +47,18 @@ namespace ams::ldr::oc { */ .marikoGpuMaxClock = 1305600, + /* Mariko EMC: + * - RAM Clock in kHz: + * Values should be > 1600000, and divided evenly by 9600 or 12800. + * [WARNING] + * RAM overclock could be UNSTABLE if timing parameters are not suitable for your DRAM: + * - Graphical glitches + * - System instabilities + * - NAND corruption + * Timings from auto-adjustment have been tested safe for up to 1996.8 MHz for all DRAM chips. + */ + .marikoEmcMaxClock = 1996800, + /* Erista CPU: * Untested and not enabled by default. * - Enable Overclock @@ -58,25 +69,34 @@ namespace ams::ldr::oc { .eristaCpuMaxVolt = 0, /* Erista EMC: - * - RAM Voltage in mV - * Default(HOS): 1125 - * Not enabled by default. - */ - .eristaEmcVolt = 0, - - /* Common EMC: - * - RAM Clock in kHz: - * Values should be > 1600000, and divided evenly by 9600 or 12800. + * - RAM Clock in kHz * [WARNING] * RAM overclock could be UNSTABLE if timing parameters are not suitable for your DRAM: * - Graphical glitches * - System instabilities * - NAND corruption - * Timings from auto-adjustment have been tested safe for up to 1996.8 MHz for all DRAM chips. + * - RAM Voltage in mV + * Default(HOS): 1125 + * Not enabled by default. */ - .commonEmcMaxClock = 1996800, + .eristaEmcMaxClock = 1862400, + .eristaEmcVolt = 0, }; + namespace pcv { + static Result MemPllmLimitHandler(u32* ptr) { + clk_pll_param* entry = reinterpret_cast(ptr); + if (entry->max_0 != entry->max_1) + return ResultFailure(); + + // Double the max clk simply + u32 max_clk = entry->max_0 * 2; + entry->max_0 = max_clk; + entry->max_1 = max_clk; + return ResultSuccess(); + } + } + namespace pcv::Mariko { constexpr u32 CpuClkOSLimit = 1785'000; constexpr u32 CpuClkOfficial = 1963'500; @@ -84,6 +104,8 @@ namespace ams::ldr::oc { constexpr u32 GpuClkOfficial = 1267'200; constexpr u32 MemClkOSLimit = 1600'000; constexpr u32 MemClkOSAlt = 1331'200; + constexpr u32 GpuClkPllLimit = 1300'000'000; + constexpr u32 MemClkPllmLimit = 2133'000'000; constexpr u32 CommonDvfsEntryCnt = 32; /* CPU */ @@ -191,11 +213,11 @@ namespace ams::ldr::oc { constexpr u32 pll_osc_in = 38400; u32 divm {}, divn {}; - const u32 remainder = C.commonEmcMaxClock % pll_osc_in; + const u32 remainder = C.marikoEmcMaxClock % pll_osc_in; for (const auto &index : div) { if (remainder >= pll_osc_in * index.numerator / index.denominator) { divm = index.denominator; - divn = C.commonEmcMaxClock / pll_osc_in * divm + index.numerator; + divn = C.marikoEmcMaxClock / pll_osc_in * divm + index.numerator; break; } } @@ -224,7 +246,7 @@ namespace ams::ldr::oc { */ #define ADJUST_PROP(TARGET, REF) \ - (u32)(std::ceil(REF + ((C.commonEmcMaxClock-MemClkOSAlt)*(TARGET-REF))/(MemClkOSLimit-MemClkOSAlt))) + (u32)(std::ceil(REF + ((C.marikoEmcMaxClock-MemClkOSAlt)*(TARGET-REF))/(MemClkOSLimit-MemClkOSAlt))) #define ADJUST_PARAM(TARGET, REF) \ TARGET = ADJUST_PROP(TARGET, REF); @@ -268,7 +290,7 @@ namespace ams::ldr::oc { { const bool use_4266_spec = C.mtcConf == AUTO_ADJ_MARIKO_4266; // tCK_avg (average clock period) in ns - const double tCK_avg = 1000'000. / C.commonEmcMaxClock; + const double tCK_avg = 1000'000. / C.marikoEmcMaxClock; // tRPpb (row precharge time per bank) in ns const u32 tRPpb = 18; // tRPab (row precharge time all banks) in ns @@ -294,7 +316,7 @@ namespace ams::ldr::oc { // {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 = u32(std::ceil((double(tREFpb) * C.commonEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4; + const u32 REFRESH = u32(std::ceil((double(tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4; // tPDEX2WR, tPDEX2RD (timing delay from exiting powerdown mode to a write/read command) in ns const u32 tPDEX2 = 10; // [Guessed] tACT2PDEN (timing delay from an activate, MRS or EMRS command to power-down entry) in ns @@ -354,8 +376,6 @@ namespace ams::ldr::oc { table->burst_mc_regs.mc_emem_arb_timing_rfcpb = std::ceil(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV + 1); // ? } - MtcPllmbDivHandler(table); - #ifdef EXPERIMENTAL { #define ADJUST_PARAM_ROUND2_ALL_REG(TARGET_TABLE, REF_TABLE, PARAM) \ @@ -395,7 +415,7 @@ namespace ams::ldr::oc { | ADJUST_BIT(TARGET_TABLE->shadow_regs_rdwr_train.PARAM, REF_TABLE->shadow_regs_rdwr_train.PARAM, HIGH2, LOW2) << LOW2; /* For latency allowance */ - #define ADJUST_INVERSE(TARGET) (TARGET * (MemClkOSLimit / 1000) / (C.commonEmcMaxClock / 1000)) + #define ADJUST_INVERSE(TARGET) (TARGET * (MemClkOSLimit / 1000) / (C.marikoEmcMaxClock / 1000)) /* emc_wdv, emc_wsv, emc_wev, emc_wdv_mask, emc_quse, emc_quse_width, emc_ibdly, emc_obdly, @@ -693,173 +713,6 @@ namespace ams::ldr::oc { #endif } - static void MtcTableCustomize(MarikoMtcTable* table) { - #define HANDLER_COMMON(PARAM) \ - if (C.marikoTiming.common.PARAM != DO_NOT_OVERRIDE) {\ - u32 cache = C.marikoTiming.common.PARAM; \ - if (cache == OVERRIDE_WITH_ZERO) \ - cache = 0; \ - table->burst_regs.PARAM = cache; \ - table->shadow_regs_ca_train.PARAM = cache; \ - table->shadow_regs_rdwr_train.PARAM = cache; \ - } - - #define HANDLER(PARAM) \ - if (C.marikoTiming.PARAM) { \ - u32 cache = C.marikoTiming.PARAM;\ - if (cache == OVERRIDE_WITH_ZERO) \ - cache = 0; \ - table->PARAM = cache; \ - } - - HANDLER_COMMON(emc_rc); - HANDLER_COMMON(emc_rfc); - HANDLER_COMMON(emc_rfcpb); - HANDLER_COMMON(emc_ras); - HANDLER_COMMON(emc_rp); - HANDLER_COMMON(emc_r2w); - HANDLER_COMMON(emc_w2r); - HANDLER_COMMON(emc_r2p); - HANDLER_COMMON(emc_w2p); - HANDLER_COMMON(emc_trtm); - HANDLER_COMMON(emc_twtm); - HANDLER_COMMON(emc_tratm); - HANDLER_COMMON(emc_twatm); - HANDLER_COMMON(emc_rd_rcd); - HANDLER_COMMON(emc_wr_rcd); - HANDLER_COMMON(emc_rrd); - HANDLER_COMMON(emc_wdv); - HANDLER_COMMON(emc_wsv); - HANDLER_COMMON(emc_wev); - HANDLER_COMMON(emc_wdv_mask); - HANDLER_COMMON(emc_quse); - HANDLER_COMMON(emc_quse_width); - HANDLER_COMMON(emc_ibdly); - HANDLER_COMMON(emc_obdly); - HANDLER_COMMON(emc_einput); - HANDLER_COMMON(emc_einput_duration); - HANDLER_COMMON(emc_qrst); - HANDLER_COMMON(emc_qsafe); - HANDLER_COMMON(emc_rdv); - HANDLER_COMMON(emc_rdv_mask); - HANDLER_COMMON(emc_rdv_early); - HANDLER_COMMON(emc_rdv_early_mask); - HANDLER_COMMON(emc_refresh); - HANDLER_COMMON(emc_pre_refresh_req_cnt); - HANDLER_COMMON(emc_pdex2wr); - HANDLER_COMMON(emc_pdex2rd); - HANDLER_COMMON(emc_act2pden); - HANDLER_COMMON(emc_rw2pden); - HANDLER_COMMON(emc_cke2pden); - HANDLER_COMMON(emc_pdex2mrr); - HANDLER_COMMON(emc_txsr); - HANDLER_COMMON(emc_txsrdll); - HANDLER_COMMON(emc_tcke); - HANDLER_COMMON(emc_tckesr); - HANDLER_COMMON(emc_tpd); - HANDLER_COMMON(emc_tfaw); - HANDLER_COMMON(emc_trpab); - HANDLER_COMMON(emc_tclkstop); - HANDLER_COMMON(emc_trefbw); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dq_rank1_4); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dq_rank1_5); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank0_0); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank0_1); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank0_3); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank0_4); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank0_5); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank1_0); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank1_1); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank1_3); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank1_4); - HANDLER_COMMON(emc_pmacro_ob_ddll_long_dqs_rank1_5); - HANDLER_COMMON(emc_pmacro_ddll_long_cmd_0); - HANDLER_COMMON(emc_pmacro_ddll_long_cmd_1); - HANDLER_COMMON(emc_pmacro_ddll_long_cmd_2); - HANDLER_COMMON(emc_pmacro_ddll_long_cmd_3); - HANDLER_COMMON(emc_pmacro_ddll_long_cmd_4); - HANDLER_COMMON(emc_zcal_wait_cnt); - HANDLER_COMMON(emc_mrs_wait_cnt); - HANDLER_COMMON(emc_mrs_wait_cnt2); - HANDLER_COMMON(emc_auto_cal_channel); - HANDLER_COMMON(emc_pmacro_dll_cfg_2); - HANDLER_COMMON(emc_pmacro_autocal_cfg_common); - HANDLER_COMMON(emc_dyn_self_ref_control); - HANDLER_COMMON(emc_qpop); - HANDLER_COMMON(emc_pmacro_cmd_pad_tx_ctrl); - HANDLER_COMMON(emc_tr_timing_0); - HANDLER_COMMON(emc_tr_rdv); - HANDLER_COMMON(emc_tr_qpop); - HANDLER_COMMON(emc_tr_rdv_mask); - HANDLER_COMMON(emc_tr_qsafe); - HANDLER_COMMON(emc_tr_qrst); - HANDLER_COMMON(emc_training_vref_settle); - - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_0); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_1); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_2); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_3); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_4); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_5); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_0); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_1); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_2); - HANDLER(trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_3); - - HANDLER(dram_timings.rl); - - HANDLER(burst_mc_regs.mc_emem_arb_cfg); - HANDLER(burst_mc_regs.mc_emem_arb_timing_rcd); - HANDLER(burst_mc_regs.mc_emem_arb_timing_rp); - HANDLER(burst_mc_regs.mc_emem_arb_timing_rc); - HANDLER(burst_mc_regs.mc_emem_arb_timing_ras); - HANDLER(burst_mc_regs.mc_emem_arb_timing_faw); - HANDLER(burst_mc_regs.mc_emem_arb_timing_wap2pre); - HANDLER(burst_mc_regs.mc_emem_arb_timing_r2w); - HANDLER(burst_mc_regs.mc_emem_arb_timing_w2r); - HANDLER(burst_mc_regs.mc_emem_arb_timing_rfcpb); - HANDLER(burst_mc_regs.mc_emem_arb_da_turns); - HANDLER(burst_mc_regs.mc_emem_arb_da_covers); - HANDLER(burst_mc_regs.mc_emem_arb_misc0); - - HANDLER(la_scale_regs.mc_mll_mpcorer_ptsa_rate); - HANDLER(la_scale_regs.mc_ptsa_grant_decrement); - HANDLER(la_scale_regs.mc_latency_allowance_xusb_0); - HANDLER(la_scale_regs.mc_latency_allowance_xusb_1); - HANDLER(la_scale_regs.mc_latency_allowance_tsec_0); - HANDLER(la_scale_regs.mc_latency_allowance_sdmmca_0); - HANDLER(la_scale_regs.mc_latency_allowance_sdmmcaa_0); - HANDLER(la_scale_regs.mc_latency_allowance_sdmmc_0); - HANDLER(la_scale_regs.mc_latency_allowance_sdmmcab_0); - HANDLER(la_scale_regs.mc_latency_allowance_ppcs_1); - HANDLER(la_scale_regs.mc_latency_allowance_mpcore_0); - HANDLER(la_scale_regs.mc_latency_allowance_hc_0); - HANDLER(la_scale_regs.mc_latency_allowance_hc_1); - HANDLER(la_scale_regs.mc_latency_allowance_avpc_0); - HANDLER(la_scale_regs.mc_latency_allowance_gpu_0); - HANDLER(la_scale_regs.mc_latency_allowance_gpu2_0); - HANDLER(la_scale_regs.mc_latency_allowance_nvenc_0); - HANDLER(la_scale_regs.mc_latency_allowance_nvdec_0); - HANDLER(la_scale_regs.mc_latency_allowance_vic_0); - HANDLER(la_scale_regs.mc_latency_allowance_vi2_0); - HANDLER(la_scale_regs.mc_latency_allowance_isp2_1); - - HANDLER(pllm_ss_ctrl1); - HANDLER(pllm_ss_ctrl2); - HANDLER(pllmb_ss_ctrl1); - HANDLER(pllmb_ss_ctrl2); - HANDLER(pllmb_divm); - HANDLER(pllmb_divn); - HANDLER(min_mrs_wait); - HANDLER(emc_mrw); - HANDLER(emc_mrw2); - HANDLER(emc_cfg_2); - HANDLER(latency); - - if (C.marikoTiming.pllmb_divm == DO_NOT_OVERRIDE || C.marikoTiming.pllmb_divn == DO_NOT_OVERRIDE) - MtcPllmbDivHandler(table); - } - static Result CpuClockVddHandler(u32* ptr) { if (C.marikoCpuMaxClock) { u32 value_next2 = *(ptr + 2); @@ -974,15 +827,10 @@ namespace ams::ldr::oc { return ResultSuccess(); } - bool customized_timing = (C.mtcConf == CUSTOMIZED_MARIKO); - if (customized_timing) { - std::memcpy(reinterpret_cast(mtc_table_alt), reinterpret_cast(mtc_table_max), sizeof(MarikoMtcTable)); - MtcTableCustomize(mtc_table_max); - } else { - std::memcpy(reinterpret_cast(table), reinterpret_cast(mtc_table_max), sizeof(MarikoMtcTable)); - MtcTableAutoAdjust(mtc_table_max, mtc_table_alt); - std::memcpy(reinterpret_cast(mtc_table_alt), reinterpret_cast(table), sizeof(MarikoMtcTable)); - } + std::memcpy(reinterpret_cast(table), reinterpret_cast(mtc_table_max), sizeof(MarikoMtcTable)); + MtcTableAutoAdjust(mtc_table_max, mtc_table_alt); + MtcPllmbDivHandler(mtc_table_max); + std::memcpy(reinterpret_cast(mtc_table_alt), reinterpret_cast(table), sizeof(MarikoMtcTable)); return ResultSuccess(); } @@ -1015,16 +863,21 @@ namespace ams::ldr::oc { rc = DvbTableHandler(ptr); } - PatchOffset(ptr, C.commonEmcMaxClock); + PatchOffset(ptr, C.marikoEmcMaxClock); return rc; } - static void Patch(uintptr_t mapped_nso, size_t nso_size) { - if (C.custRev != CUST_REV) { - AMS_ABORT(); - __builtin_unreachable(); - } + static Result GpuPllLimitHandler(u32* ptr) { + u32 value_next = *(ptr + 1); + if (value_next != 0) + return ResultFailure(); + u32 max_clk = *(ptr) * 2; + PatchOffset(ptr, max_clk); + return ResultSuccess(); + } + + static void Patch(uintptr_t mapped_nso, size_t nso_size) { enum PatchSuccessCnt { MEM_CLOCK, CPU_CLOCK_VDD, @@ -1032,6 +885,8 @@ namespace ams::ldr::oc { GPU_TABLE, CPU_MAX_VOLT, GPU_MAX_CLOCK, + GPU_PLL_CLK, + MEM_PLL_CLK, CNT_MAX, }; @@ -1065,6 +920,14 @@ namespace ams::ldr::oc { if (R_SUCCEEDED(MemMaxClockHandler(ptr32))) cnt[MEM_CLOCK]++; continue; + case GpuClkPllLimit: [[unlikely]] + if (R_SUCCEEDED(GpuPllLimitHandler(ptr32))) + cnt[GPU_PLL_CLK]++; + continue; + case MemClkPllmLimit:[[unlikely]] + if (R_SUCCEEDED(MemPllmLimitHandler(ptr32))) + cnt[MEM_PLL_CLK]++; + continue; default: [[likely]] break; } @@ -1081,7 +944,9 @@ namespace ams::ldr::oc { || cnt[CPU_TABLE] != 1 || cnt[GPU_TABLE] != 1 || cnt[CPU_MAX_VOLT] > 13 || !cnt[CPU_MAX_VOLT] - || cnt[GPU_MAX_CLOCK] != 2) + || cnt[GPU_MAX_CLOCK] != 2 + || cnt[GPU_PLL_CLK] != 1 + || cnt[MEM_PLL_CLK] != 2) { AMS_ABORT(); __builtin_unreachable(); @@ -1096,6 +961,7 @@ namespace ams::ldr::oc { constexpr u32 CpuVoltLimit3 = 1227; constexpr u32 MemVoltHOS = 1125'000; constexpr u32 MemClkOSLimit = 1600'000; + constexpr u32 MemClkPllmLimit = 1866'000'000; constexpr cpu_freq_cvb_table_t NewCpuTables[] = { // OldCpuTables @@ -1178,7 +1044,7 @@ namespace ams::ldr::oc { rc = MtcTableHandler(ptr); } - PatchOffset(ptr, C.commonEmcMaxClock); + PatchOffset(ptr, C.eristaEmcMaxClock); return rc; } @@ -1195,6 +1061,7 @@ namespace ams::ldr::oc { CPU_MAX_VOLT, MEM_CLOCK, MEM_VOLT, + MEM_PLL_CLK, CNT_MAX, }; @@ -1226,12 +1093,16 @@ namespace ams::ldr::oc { if (R_SUCCEEDED(MemVoltHandler(ptr32))) cnt[MEM_VOLT]++; continue; + case MemClkPllmLimit: [[unlikely]] + if (R_SUCCEEDED(MemPllmLimitHandler(ptr32))) + cnt[MEM_PLL_CLK]++; + continue; default: [[likely]] break; } } - if (!cnt[MEM_CLOCK] || cnt[MEM_VOLT] != 2) { + if (!cnt[MEM_CLOCK] || cnt[MEM_VOLT] != 2 || cnt[MEM_PLL_CLK] != 2) { AMS_ABORT(); __builtin_unreachable(); } @@ -1240,6 +1111,11 @@ namespace ams::ldr::oc { namespace pcv { void Patch(uintptr_t mapped_nso, size_t nso_size) { + if (C.custRev != CUST_REV) { + AMS_ABORT(); + __builtin_unreachable(); + } + bool isMariko = (spl::GetSocType() == spl::SocType_Mariko); if (isMariko) Mariko::Patch(mapped_nso, nso_size); @@ -1260,7 +1136,7 @@ namespace ams::ldr::oc { constexpr u32 memPtmLimit = 1600'000'000; constexpr u32 memPtmAlt = 1331'200'000; constexpr u32 memPtmClamp = 1065'600'000; - const u32 memPtmMax = C.commonEmcMaxClock * 1000; + const u32 memPtmMax = C.marikoEmcMaxClock * 1000; for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(perf_conf_entry) * entryCnt; diff --git a/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.hpp b/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.hpp index 657cdfd8..2ee6f0aa 100644 --- a/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/ldr_oc_suite.hpp @@ -24,7 +24,6 @@ namespace ams::ldr::oc { AUTO_ADJ_MARIKO_4266 = 1, ENTIRE_TABLE_ERISTA = 2, ENTIRE_TABLE_MARIKO = 3, - CUSTOMIZED_MARIKO = 4, }; typedef struct { @@ -34,22 +33,17 @@ namespace ams::ldr::oc { u32 marikoCpuMaxClock; u32 marikoCpuMaxVolt; u32 marikoGpuMaxClock; + u32 marikoEmcMaxClock; u32 eristaCpuOCEnable; u32 eristaCpuMaxVolt; + u32 eristaEmcMaxClock; u32 eristaEmcVolt; - u32 commonEmcMaxClock; union { EristaMtcTable eristaMtc; MarikoMtcTable marikoMtc; - MarikoCustomizedTable marikoTiming; }; } CustomizeTable; - enum { - DO_NOT_OVERRIDE = 0, - OVERRIDE_WITH_ZERO = UINT32_MAX, - }; - inline void PatchOffset(u32* offset, u32 value) { *(offset) = value; } inline Result ResultFailure() { return -1; } @@ -81,6 +75,12 @@ namespace ams::ldr::oc { s32 volt[4] = {0}; } emc_dvb_dvfs_table_t; + typedef struct { + u32 max_0; + u32 unk[5]; + u32 max_1; + } clk_pll_param; + void Patch(uintptr_t mapped_nso, size_t nso_size); } diff --git a/Source/Atmosphere/stratosphere/loader/source/mtc_timing_table.hpp b/Source/Atmosphere/stratosphere/loader/source/mtc_timing_table.hpp index 4bef8b05..d5b2488e 100644 --- a/Source/Atmosphere/stratosphere/loader/source/mtc_timing_table.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/mtc_timing_table.hpp @@ -16,162 +16,6 @@ * from GCC preprocessor output */ -struct MarikoCustomizedTable { - struct { - uint32_t emc_rc; - uint32_t emc_rfc; - uint32_t emc_rfcpb; - uint32_t emc_ras; - uint32_t emc_rp; - uint32_t emc_r2w; - uint32_t emc_w2r; - uint32_t emc_r2p; - uint32_t emc_w2p; - uint32_t emc_trtm; - uint32_t emc_twtm; - uint32_t emc_tratm; - uint32_t emc_twatm; - uint32_t emc_rd_rcd; - uint32_t emc_wr_rcd; - uint32_t emc_rrd; - uint32_t emc_wdv; - uint32_t emc_wsv; - uint32_t emc_wev; - uint32_t emc_wdv_mask; - uint32_t emc_quse; - uint32_t emc_quse_width; - uint32_t emc_ibdly; - uint32_t emc_obdly; - uint32_t emc_einput; - uint32_t emc_einput_duration; - uint32_t emc_qrst; - uint32_t emc_qsafe; - uint32_t emc_rdv; - uint32_t emc_rdv_mask; - uint32_t emc_rdv_early; - uint32_t emc_rdv_early_mask; - uint32_t emc_refresh; - uint32_t emc_pre_refresh_req_cnt; - uint32_t emc_pdex2wr; - uint32_t emc_pdex2rd; - uint32_t emc_act2pden; - uint32_t emc_rw2pden; - uint32_t emc_cke2pden; - uint32_t emc_pdex2mrr; - uint32_t emc_txsr; - uint32_t emc_txsrdll; - uint32_t emc_tcke; - uint32_t emc_tckesr; - uint32_t emc_tpd; - uint32_t emc_tfaw; - uint32_t emc_trpab; - uint32_t emc_tclkstop; - uint32_t emc_trefbw; - uint32_t emc_pmacro_ob_ddll_long_dq_rank1_4; - uint32_t emc_pmacro_ob_ddll_long_dq_rank1_5; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_0; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_1; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_3; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_4; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_5; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_0; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_1; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_3; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_4; - uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_5; - uint32_t emc_pmacro_ddll_long_cmd_0; - uint32_t emc_pmacro_ddll_long_cmd_1; - uint32_t emc_pmacro_ddll_long_cmd_2; - uint32_t emc_pmacro_ddll_long_cmd_3; - uint32_t emc_pmacro_ddll_long_cmd_4; - uint32_t emc_zcal_wait_cnt; - uint32_t emc_mrs_wait_cnt; - uint32_t emc_mrs_wait_cnt2; - uint32_t emc_auto_cal_channel; - uint32_t emc_pmacro_dll_cfg_2; - uint32_t emc_pmacro_autocal_cfg_common; - uint32_t emc_dyn_self_ref_control; - uint32_t emc_qpop; - uint32_t emc_pmacro_cmd_pad_tx_ctrl; - uint32_t emc_tr_timing_0; - uint32_t emc_tr_rdv; - uint32_t emc_tr_qpop; - uint32_t emc_tr_rdv_mask; - uint32_t emc_tr_qsafe; - uint32_t emc_tr_qrst; - uint32_t emc_training_vref_settle; - } common; - - struct { - uint32_t emc_pmacro_ob_ddll_long_dq_rank0_0; - uint32_t emc_pmacro_ob_ddll_long_dq_rank0_1; - uint32_t emc_pmacro_ob_ddll_long_dq_rank0_2; - uint32_t emc_pmacro_ob_ddll_long_dq_rank0_3; - uint32_t emc_pmacro_ob_ddll_long_dq_rank0_4; - uint32_t emc_pmacro_ob_ddll_long_dq_rank0_5; - uint32_t emc_pmacro_ob_ddll_long_dq_rank1_0; - uint32_t emc_pmacro_ob_ddll_long_dq_rank1_1; - uint32_t emc_pmacro_ob_ddll_long_dq_rank1_2; - uint32_t emc_pmacro_ob_ddll_long_dq_rank1_3; - } trim_regs; - - struct { - uint32_t rl; - } dram_timings; - - struct { - uint32_t mc_emem_arb_cfg; - uint32_t mc_emem_arb_timing_rcd; - uint32_t mc_emem_arb_timing_rp; - uint32_t mc_emem_arb_timing_rc; - uint32_t mc_emem_arb_timing_ras; - uint32_t mc_emem_arb_timing_faw; - uint32_t mc_emem_arb_timing_wap2pre; - uint32_t mc_emem_arb_timing_r2w; - uint32_t mc_emem_arb_timing_w2r; - uint32_t mc_emem_arb_timing_rfcpb; - uint32_t mc_emem_arb_da_turns; - uint32_t mc_emem_arb_da_covers; - uint32_t mc_emem_arb_misc0; - } burst_mc_regs; - - struct { - uint32_t mc_mll_mpcorer_ptsa_rate; - uint32_t mc_ptsa_grant_decrement; - uint32_t mc_latency_allowance_xusb_0; - uint32_t mc_latency_allowance_xusb_1; - uint32_t mc_latency_allowance_tsec_0; - uint32_t mc_latency_allowance_sdmmca_0; - uint32_t mc_latency_allowance_sdmmcaa_0; - uint32_t mc_latency_allowance_sdmmc_0; - uint32_t mc_latency_allowance_sdmmcab_0; - uint32_t mc_latency_allowance_ppcs_1; - uint32_t mc_latency_allowance_mpcore_0; - uint32_t mc_latency_allowance_hc_0; - uint32_t mc_latency_allowance_hc_1; - uint32_t mc_latency_allowance_avpc_0; - uint32_t mc_latency_allowance_gpu_0; - uint32_t mc_latency_allowance_gpu2_0; - uint32_t mc_latency_allowance_nvenc_0; - uint32_t mc_latency_allowance_nvdec_0; - uint32_t mc_latency_allowance_vic_0; - uint32_t mc_latency_allowance_vi2_0; - uint32_t mc_latency_allowance_isp2_1; - } la_scale_regs; - - uint32_t pllm_ss_ctrl1; - uint32_t pllm_ss_ctrl2; - uint32_t pllmb_ss_ctrl1; - uint32_t pllmb_ss_ctrl2; - uint32_t pllmb_divm; - uint32_t pllmb_divn; - uint32_t min_mrs_wait; - uint32_t emc_mrw; - uint32_t emc_mrw2; - uint32_t emc_cfg_2; - uint32_t latency; -}; - struct MarikoMtcTable { uint32_t rev; char dvfs_ver[60]; diff --git a/Source/sys-clk-OC/README.md b/Source/sys-clk-OC/README.md index 8b2f3e27..9acc907e 100644 --- a/Source/sys-clk-OC/README.md +++ b/Source/sys-clk-OC/README.md @@ -28,6 +28,7 @@ Switch sysmodule allowing you to set cpu/gpu clocks according to the running app ### GPU clocks +* ???? * 1305 → OC max for Mariko * 1267 → official max for Mariko * 1228 @@ -53,6 +54,7 @@ Switch sysmodule allowing you to set cpu/gpu clocks according to the running app From Hekate Minerva module [sys_sdrammtc.c](https://github.com/CTCaer/hekate/blob/197ed8c319bd4132e4d7571ce037d4a27f806bba/modules/hekate_libsys_minerva/sys_sdrammtc.c#L67) +- ???? - 2131 → NOT stable: max for Erista and official max for Mariko - 2099 - 2064