From 63c7fb211d99b2377ac58468df09e94e7e3a5149 Mon Sep 17 00:00:00 2001 From: Lightos1 <124387232+Lightos1@users.noreply.github.com> Date: Tue, 19 May 2026 20:02:09 +0200 Subject: [PATCH] Code cleanup and improved dvb tables. Thanks to: jimmy for testing and b3711 for many additional voltage scale improvements. Co-Authored-By: halop <4215938+halop@users.noreply.github.com> --- .../loader/source/oc/customize.cpp | 53 +++++----- .../loader/source/oc/customize.hpp | 22 +--- .../loader/source/oc/oc_common.hpp | 22 ++-- .../stratosphere/loader/source/oc/pcv/pcv.cpp | 100 +++++++++--------- .../stratosphere/loader/source/oc/pcv/pcv.hpp | 72 +++++-------- .../loader/source/oc/pcv/pcv_common.hpp | 10 +- .../loader/source/oc/pcv/pcv_erista.cpp | 29 +++-- .../loader/source/oc/pcv/pcv_mariko.cpp | 44 +++++--- 8 files changed, 166 insertions(+), 186 deletions(-) diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 69bf226d..28a8a5ff 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -35,8 +35,8 @@ volatile CustomizeTable C = { /* Disables RAM powerdown */ .hpMode = DISABLED, -.commonEmcMemVolt = 1175000, /* LPDDR4(X) JEDEC Specification */ -.eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */ +.commonEmcMemVolt = 1175000, /* LPDDR4(X) JEDEC Specification */ +.eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */ .eristaEmcMaxClock1 = 1600000, .eristaEmcMaxClock2 = 1600000, @@ -47,7 +47,7 @@ volatile CustomizeTable C = { .marikoEmcMaxClock = 2133000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */ .marikoEmcVddqVolt = 600000, -.emcDvbShift = 0, +.emcDvbShift = 0, .marikoSocVmax = 0, /* 0 = stock limits (1450 - 1597 is 1050mV, 1598-1708 is 1025mV, 1709+ is 1000mV). */ /* Primary. */ @@ -86,35 +86,37 @@ volatile CustomizeTable C = { /* You can mix and match different latencies if needed */ /* - * Read: - * 2133RL = 40 - * 1866RL = 36 - * 1600RL = 32 - * 1331RL = 28 - * Write: - * 2133WL = 18 - * 1866WL = 16 - * 1600WL = 14 - * 1331WL = 12 + * Read: + * 2133RL = 40 + * 1866RL = 36 + * 1600RL = 32 + * 1331RL = 28 + * Write: + * 2133WL = 18 + * 1866WL = 16 + * 1600WL = 14 + * 1331WL = 12 */ -.mem_burst_read_latency = RL_1600, +/* Erista only. */ +.mem_burst_read_latency = RL_1600, .mem_burst_write_latency = WL_1600, -.eristaCpuUV = 0, -.eristaCpuVmin = 800, +.eristaCpuUV = 0, +.eristaCpuVmin = 800, .eristaCpuMaxVolt = 1200, /* Unlocks up to 2397 Mhz CPU, usage is not recommended. */ -.eristaCpuUnlock = DISABLED, +.eristaCpuUnlock = DISABLED, -.marikoCpuUVLow = 0, // No undervolt +.marikoCpuUVLow = 0, // No undervolt .marikoCpuUVHigh = 0, // No undervolt -.tableConf = TBREAK_1683, -.marikoCpuLowVmin = 620, +.tableConf = TBREAK_1683, +.marikoCpuLowVmin = 620, .marikoCpuHighVmin = 750, + /* 1120mV is NVIDIA rating */ -.marikoCpuMaxVolt = 1120, +.marikoCpuMaxVolt = 1120, /* Supported values: 1963500, 2091000, 2193000, 2295000, 2397000, 2499000, 2601000, 2703000. */ /* 1963500 is official rating of T214/Mariko, fully safe. */ @@ -125,17 +127,15 @@ volatile CustomizeTable C = { /* 2703000 is potentially dangerous and not advised. */ .marikoCpuMaxClock = 1963500, -.eristaCpuBoostClock = 1785000, // Default boost clock -.marikoCpuBoostClock = 1963500, // Default boost clock +.eristaCpuBoostClock = 1785000, /* Default boost clock */ +.marikoCpuBoostClock = 1963500, /* Default boost clock */ -.eristaGpuUV = 0, +.eristaGpuUV = 0, .eristaGpuVmin = 810, .marikoGpuUV = 0, - /* Vmin past 795mV won't work due boot voltage being 800mV. */ .marikoGpuVmin = 610, - .marikoGpuVmax = 800, .commonGpuVoltOffset = 0, @@ -147,7 +147,6 @@ volatile CustomizeTable C = { /* AUTO: Voltage is optimally chosen; with commonGpuVoltOffset applied. */ /* AUTO only works up to 1305 GPU on Mariko and 998 GPU on Erista (it is reccomended to manually set your 998MHz voltage though) */ /* You can overwrite auto with any voltage (in mv) of your choice - offset will not be applied. */ - .eristaGpuVoltArray = { AUTO /* 76 */, AUTO /* 115 */, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp index 3a3d9ddb..83ad1600 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp @@ -30,8 +30,8 @@ namespace ams::ldr::hoc { enum TableConfig: u32 { DEFAULT_TABLE = 1, - TBREAK_1581 = 2, - TBREAK_1683 = 3, + TBREAK_1581 = 2, + TBREAK_1683 = 3, EXTREME_TABLE = 4, }; @@ -42,19 +42,6 @@ enum StepMode: u32 { StepMode_133MHz = 3, }; -/* - * Read: - * 2133RL = 40 - * 1866RL = 36 - * 1600RL = 32 - * 1331RL = 28 - * Write: - * 2133WL = 18 - * 1866WL = 16 - * 1600WL = 14 - * 1331WL = 12 - */ - enum ReadLatency: u32 { RL_2133 = 40, RL_1866 = 36, @@ -74,11 +61,8 @@ using CustomizeGpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit]; static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(CustomizeGpuDvfsTable)); static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(pcv::cvb_entry_t) * pcv::DvfsTableEntryLimit); -constexpr uint32_t ERISTA_MTC_MAGIC = 0x43544D45; // EMTC -constexpr uint32_t MARIKO_MTC_MAGIC = 0x43544D4D; // MMTC - struct CustomizeTable { - u8 cust[4] = {'C', 'U', 'S', 'T'}; + u8 cust[4] = {'C', 'U', 'S', 'T'}; u32 custRev = CUST_REV; u32 kipVersion = KIP_VERSION; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp index 80d2db11..a56588e6 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp @@ -66,27 +66,32 @@ namespace ams::ldr::hoc { size_t maximum_patched_count = 0; patternFn pattern_search_fn = nullptr; Pointer value_search; - size_t patched_count = 0; - Result Apply(Pointer* ptr) { + Result Apply(Pointer *ptr) { Result res = patcher_fn(ptr); - if (R_SUCCEEDED(res)) + if (R_SUCCEEDED(res)) { patched_count++; + } return res; } - Result SearchAndApply(Pointer* ptr) { + Result SearchAndApply(Pointer *ptr) { bool searchOk = false; if (pattern_search_fn) { - if (pattern_search_fn(ptr)) searchOk = true; + if (pattern_search_fn(ptr)) { + searchOk = true; + } } else { - if (value_search == *(ptr)) searchOk = true; + if (value_search == *(ptr)) { + searchOk = true; + } } - if (searchOk) + if (searchOk) { return Apply(ptr); + } R_THROW(ldr::ResultUnsuccessfulPatcher()); } @@ -94,8 +99,9 @@ namespace ams::ldr::hoc { Result CheckResult() { R_UNLESS(patched_count > 0, ldr::ResultUnsuccessfulPatcher()); - if (maximum_patched_count) + if (maximum_patched_count) { R_UNLESS(patched_count <= maximum_patched_count, ldr::ResultUnsuccessfulPatcher()); + } R_SUCCEED(); } diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp index 96ab2180..a34c2dd6 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp @@ -22,20 +22,20 @@ namespace ams::ldr::hoc::pcv { - Result MemFreqPllmLimit(u32* ptr) { - clk_pll_param* entry = reinterpret_cast(ptr); + Result MemFreqPllmLimit(u32 *ptr) { + clk_pll_param *entry = reinterpret_cast(ptr); R_UNLESS(entry->freq == entry->vco_max, ldr::ResultInvalidMemPllmEntry()); // Double the max clk simply - u32 max_clk = entry->freq * 2; - entry->freq = max_clk; + u32 max_clk = entry->freq * 2; + entry->freq = max_clk; entry->vco_max = max_clk; R_SUCCEED(); } - Result MemVoltHandler(u32* ptr) { + Result MemVoltHandler(u32 *ptr) { // ptr value might be default_uv or max_uv - regulator* entries[2] = { + regulator *entries[2] = { reinterpret_cast(reinterpret_cast(ptr) - offsetof(regulator, type_1.default_uv)), reinterpret_cast(reinterpret_cast(ptr) - offsetof(regulator, type_1.max_uv)), }; @@ -44,16 +44,16 @@ namespace ams::ldr::hoc::pcv { constexpr u32 uv_min = 600'000; auto validator = [](regulator* entry) { - R_UNLESS(entry->id == 1, ldr::ResultInvalidRegulatorEntry()); - R_UNLESS(entry->type == 1, ldr::ResultInvalidRegulatorEntry()); + R_UNLESS(entry->id == 1, ldr::ResultInvalidRegulatorEntry()); + R_UNLESS(entry->type == 1, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.volt_reg == 0x17, ldr::ResultInvalidRegulatorEntry()); - R_UNLESS(entry->type_1.step_uv == uv_step, ldr::ResultInvalidRegulatorEntry()); - R_UNLESS(entry->type_1.min_uv == uv_min, ldr::ResultInvalidRegulatorEntry()); + R_UNLESS(entry->type_1.step_uv == uv_step, ldr::ResultInvalidRegulatorEntry()); + R_UNLESS(entry->type_1.min_uv == uv_min, ldr::ResultInvalidRegulatorEntry()); R_SUCCEED(); }; - regulator* entry = nullptr; - for (auto& i : entries) { + regulator *entry = nullptr; + for (auto &i : entries) { if (R_SUCCEEDED(validator(i))) { entry = i; } @@ -76,24 +76,25 @@ namespace ams::ldr::hoc::pcv { } void SafetyCheck() { - // if (C.custRev != CUST_REV) - // CRASH("Triggered"); - struct sValidator { volatile u32 value; u32 min; u32 max; - bool value_required = false; u32 panic; + bool value_required = false; Result check() { - if (!value_required && !value) + if (!value_required && !value) { R_SUCCEED(); + } - if (min && value < min) + if (min && value < min) { R_THROW(ldr::ResultSafetyCheckFailure()); - if (max && value > max) + } + + if (max && value > max) { R_THROW(ldr::ResultSafetyCheckFailure()); + } R_SUCCEED(); } @@ -102,28 +103,24 @@ namespace ams::ldr::hoc::pcv { u32 eristaCpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq); u32 marikoCpuDvfsMaxFreq; if (C.marikoCpuUVHigh) { - marikoCpuDvfsMaxFreq = static_cast( - GetDvfsTableLastEntry(C.marikoCpuDvfsTableSLT)->freq - ); + marikoCpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.marikoCpuDvfsTableSLT)->freq); } else { - marikoCpuDvfsMaxFreq = static_cast( - GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq - ); + marikoCpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq); } u32 eristaGpuDvfsMaxFreq; switch (C.eristaGpuUV) { - case 0: - eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); - break; - case 1: - eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTableSLT)->freq); - break; - case 2: - eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTableHiOPT)->freq); - break; - default: - eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); - break; + case 0: + eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); + break; + case 1: + eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTableSLT)->freq); + break; + case 2: + eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTableHiOPT)->freq); + break; + default: + eristaGpuDvfsMaxFreq = static_cast(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); + break; } u32 marikoGpuDvfsMaxFreq; @@ -142,22 +139,21 @@ namespace ams::ldr::hoc::pcv { break; } - using namespace ams::ldr::hoc::pcv; sValidator validators[] = { - { C.eristaCpuBoostClock, 1020'000, 2397'000, true, panic::Cpu }, - { C.marikoCpuBoostClock, 1020'000, 2703'000, true, panic::Cpu }, - { C.eristaCpuMaxVolt, 1000, 1260, false, panic::Cpu }, - { C.marikoCpuMaxVolt, 1000, 1200, false, panic::Cpu }, - { eristaCpuDvfsMaxFreq, 1785'000, 2397'000, false, panic::Cpu }, - { marikoCpuDvfsMaxFreq, 1785'000, 2703'000, false, panic::Cpu }, - { C.commonEmcMemVolt, 912'500, 1350'000, false, panic::Emc }, // Official burst vmax for the RAMs is 1500mV - { GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000, false, panic::Emc }, - { C.marikoEmcMaxClock, 1600'000, 3500'000, false, panic::Emc }, - { C.marikoEmcVddqVolt, 400'000, 750'000, false, panic::Emc }, - { C.marikoSocVmax, 1000, 1200, false, panic::Emc }, - { eristaGpuDvfsMaxFreq, 768'000, 1152'000, false, panic::Gpu }, - { marikoGpuDvfsMaxFreq, 768'000, 1536'000, false, panic::Gpu }, - { C.marikoGpuVmax, 800, 960, false, panic::Gpu }, + { C.eristaCpuBoostClock, 1020'000, 2397'000, panic::Cpu, true }, + { C.marikoCpuBoostClock, 1020'000, 2703'000, panic::Cpu, true }, + { C.eristaCpuMaxVolt, 1000, 1260, panic::Cpu, }, + { C.marikoCpuMaxVolt, 1000, 1200, panic::Cpu, }, + { eristaCpuDvfsMaxFreq, 1785'000, 2397'000, panic::Cpu, }, + { marikoCpuDvfsMaxFreq, 1785'000, 2703'000, panic::Cpu, }, + { C.commonEmcMemVolt, 912'500, 1350'000, panic::Emc, }, /* Official vmax for the RAMs is 1400-1500mV */ + { GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000, panic::Emc, }, + { C.marikoEmcMaxClock, 1600'000, 3500'000, panic::Emc, }, + { C.marikoEmcVddqVolt, 400'000, 750'000, panic::Emc, }, + { C.marikoSocVmax, 1000, 1200, panic::Emc, }, + { eristaGpuDvfsMaxFreq, 768'000, 1152'000, panic::Gpu, }, + { marikoGpuDvfsMaxFreq, 768'000, 1536'000, panic::Gpu, }, + { C.marikoGpuVmax, 800, 960, panic::Gpu, }, }; for (auto &v : validators) { diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp index a0a06777..3bd40045 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.hpp @@ -118,34 +118,34 @@ namespace ams::ldr::hoc::pcv { cvb_entry_t *customize_table; if (isMariko) { switch (C.marikoGpuUV) { - case 0: - customize_table = const_cast(C.marikoGpuDvfsTable); - break; - case 1: - customize_table = const_cast(C.marikoGpuDvfsTableSLT); - break; - case 2: - customize_table = const_cast(C.marikoGpuDvfsTableHiOPT); - break; - default: - customize_table = const_cast(C.marikoGpuDvfsTable); - break; - } + case 0: + customize_table = const_cast(C.marikoGpuDvfsTable); + break; + case 1: + customize_table = const_cast(C.marikoGpuDvfsTableSLT); + break; + case 2: + customize_table = const_cast(C.marikoGpuDvfsTableHiOPT); + break; + default: + customize_table = const_cast(C.marikoGpuDvfsTable); + break; + } } else { switch (C.eristaGpuUV) { - case 0: - customize_table = const_cast(C.eristaGpuDvfsTable); - break; - case 1: - customize_table = const_cast(C.eristaGpuDvfsTableSLT); - break; - case 2: - customize_table = const_cast(C.eristaGpuDvfsTableHiOPT); - break; - default: - customize_table = const_cast(C.eristaGpuDvfsTable); - break; - } + case 0: + customize_table = const_cast(C.eristaGpuDvfsTable); + break; + case 1: + customize_table = const_cast(C.eristaGpuDvfsTableSLT); + break; + case 2: + customize_table = const_cast(C.eristaGpuDvfsTableHiOPT); + break; + default: + customize_table = const_cast(C.eristaGpuDvfsTable); + break; + } } size_t default_entry_count = GetDvfsTableEntryCount(default_table); @@ -195,26 +195,6 @@ namespace ams::ldr::hoc::pcv { Result MemFreqPllmLimit(u32 *ptr); Result MemVoltHandler(u32 *ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2 - template - Result MemMtcCustomizeTable(T *dst, T *src) { - constexpr u32 mtc_magic = std::is_same_v ? MARIKO_MTC_MAGIC : ERISTA_MTC_MAGIC; - R_UNLESS(src->rev == mtc_magic, ldr::ResultInvalidMtcMagic()); - - constexpr u32 ZERO_VAL = UINT32_MAX; - // Skip params from dvfs_ver to clock_src; - for (size_t offset = offsetof(T, clk_src_emc); offset < sizeof(T); offset += sizeof(u32)) { - u32 *src_ent = reinterpret_cast(reinterpret_cast(src) + offset); - u32 *dst_ent = reinterpret_cast(reinterpret_cast(dst) + offset); - u32 src_val = *src_ent; - - if (src_val){ - PATCH_OFFSET(dst_ent, src_val == ZERO_VAL ? 0 : src_val); - } - } - - R_SUCCEED(); - }; - void SafetyCheck(); void Patch(uintptr_t mapped_nso, size_t nso_size); diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp index 3ba1d333..2482c80c 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp @@ -145,11 +145,11 @@ namespace ams::ldr::hoc::pcv { constexpr size_t DvfsTableEntryLimit = DvfsTableEntryCount - 1; template - size_t GetDvfsTableEntryCount(T* table_head) { + size_t GetDvfsTableEntryCount(T *table_head) { using NT = std::remove_const_t>; auto is_empty = [](NT* entry) { - uint8_t* m = reinterpret_cast(entry); + u8 *m = reinterpret_cast(entry); for (size_t i = 0; i < sizeof(NT); i++) { if (*(m + i)) { return false; @@ -158,7 +158,7 @@ namespace ams::ldr::hoc::pcv { return true; }; - NT* table = const_cast(table_head); + NT *table = const_cast(table_head); size_t count = 0; while (count < DvfsTableEntryLimit) { if (is_empty(table++)) { @@ -170,10 +170,10 @@ namespace ams::ldr::hoc::pcv { } template - T* GetDvfsTableLastEntry(T* table_head) { + T *GetDvfsTableLastEntry(T *table_head) { using NT = std::remove_const_t>; - NT* table = const_cast(table_head); + NT *table = const_cast(table_head); size_t count = GetDvfsTableEntryCount(table_head); if (!count) { return nullptr; 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 0d42cd67..85ef4de2 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -136,17 +136,13 @@ namespace ams::ldr::hoc::pcv::erista { Result GpuFreqMaxAsm(u32 *ptr32) { // Check if both two instructions match the pattern u32 ins1 = *ptr32, ins2 = *(ptr32 + 1); - if (!(asm_compare_no_rd(ins1, GpuAsmPattern[0]) && asm_compare_no_rd(ins2, GpuAsmPattern[1]))) + if (!(asm_compare_no_rd(ins1, GpuAsmPattern[0]) && asm_compare_no_rd(ins2, GpuAsmPattern[1]))) { R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); + } // Both instructions should operate on the same register u8 rd = asm_get_rd(ins1); - if (rd != asm_get_rd(ins2)) - R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); - - /* Verify the limit. */ - /* TODO: Make this a little bit cleaner at some point. */ - if (AsmGetImm16(ins1) != (GpuClkOsLimit & 0xFFFF) || AsmGetImm16(ins2) != (GpuClkOsLimit >> 16)) { + if (rd != asm_get_rd(ins2)) { R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); } @@ -165,6 +161,7 @@ namespace ams::ldr::hoc::pcv::erista { max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq; break; } + u32 asm_patch[2] = { asm_set_rd(asm_set_imm16(GpuAsmPattern[0], max_clock), rd), asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd) @@ -279,22 +276,20 @@ namespace ams::ldr::hoc::pcv::erista { // WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv); // WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2); // WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv); - // ams::ldr::hoc::pcv::mariko::CalculateMrw2(); // table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast(mrw2); // table->dram_timings.rl = RL; - /* This needs some clean up. */ constexpr double MC_ARB_DIV = 4.0; constexpr u32 MC_ARB_SFA = 2; - table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV; - 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_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1; - 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_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_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1; + table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV; + 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_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1; + 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_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_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA; 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 a5b2e5e5..1200ceb4 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -822,8 +822,8 @@ namespace ams::ldr::hoc::pcv::mariko { auto DvbVolt = [&](s32 zero, s32 one, s32 two) { return std::array{ ClampVolt(zero, max0), - ClampVolt(one, max1), - ClampVolt(two, max2) + ClampVolt(one, max1), + ClampVolt(two, max2) }; }; @@ -832,16 +832,36 @@ namespace ams::ldr::hoc::pcv::mariko { static_cast((v)[1]), \ static_cast((v)[2]) DvbEntry emcDvbOcTableBrackets[] = { - { 204000, { 637, 637, 637, }, }, - { 1331200, { 650, 637, 637, }, }, - { 1600000, { 675, 650, 637, }, }, - { 1866000, { DVB(DvbVolt( 700, 675, 650)) }, }, - { 2133000, { DVB(DvbVolt( 725, 700, 675)) }, }, - { 2400000, { DVB(DvbVolt( 750, 725, 700)) }, }, - { 2666000, { DVB(DvbVolt( 850, 825, 800)) }, }, - { 2933000, { DVB(DvbVolt( 950, 925, 900)) }, }, - { 3200000, { DVB(DvbVolt(1050, 1025, 1000)) }, }, - { ~0u, { }, }, + { 204000, { 637, 637, 637, }, }, + { 1331200, { 650, 637, 637, }, }, + { 1600000, { 675, 650, 637, }, }, + { 1866000, { DVB(DvbVolt( 700, 675, 650)) }, }, + { 2133000, { DVB(DvbVolt( 725, 700, 675)) }, }, + { 2246000, { DVB(DvbVolt( 750, 725, 700)) }, }, + { 2400000, { DVB(DvbVolt( 775, 750, 725)) }, }, + { 2466000, { DVB(DvbVolt( 800, 775, 750)) }, }, + { 2533000, { DVB(DvbVolt( 810, 785, 760)) }, }, + { 2566000, { DVB(DvbVolt( 820, 795, 770)) }, }, + { 2600000, { DVB(DvbVolt( 830, 805, 780)) }, }, + { 2633000, { DVB(DvbVolt( 840, 815, 790)) }, }, + { 2666000, { DVB(DvbVolt( 850, 825, 800)) }, }, + { 2700000, { DVB(DvbVolt( 860, 835, 810)) }, }, + { 2733000, { DVB(DvbVolt( 870, 845, 820)) }, }, + { 2766000, { DVB(DvbVolt( 880, 855, 830)) }, }, + { 2800000, { DVB(DvbVolt( 895, 865, 840)) }, }, + { 2833000, { DVB(DvbVolt( 900, 875, 850)) }, }, + { 2866000, { DVB(DvbVolt( 910, 885, 860)) }, }, + { 2900000, { DVB(DvbVolt( 920, 895, 870)) }, }, + { 2933000, { DVB(DvbVolt( 950, 905, 880)) }, }, + { 2966000, { DVB(DvbVolt( 960, 915, 890)) }, }, + { 3000000, { DVB(DvbVolt( 970, 925, 900)) }, }, + { 3033000, { DVB(DvbVolt( 980, 940, 910)) }, }, + { 3066000, { DVB(DvbVolt(1000, 955, 920)) }, }, + { 3100000, { DVB(DvbVolt(1010, 990, 930)) }, }, + { 3133000, { DVB(DvbVolt(1025, 1005, 940)) }, }, + { 3166000, { DVB(DvbVolt(1035, 1015, 950)) }, }, + { 3200000, { DVB(DvbVolt(1050, 1025, 960)) }, }, + { ~0u, { }, }, }; #undef DVB DvbEntry emcDvbTableOc[newEmcList.size()];