Merge remote-tracking branch 'origin/main' into erista-mrf-shit
This commit is contained in:
@@ -147,7 +147,7 @@ namespace ams::ldr::hoc::pcv {
|
||||
{ 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 */
|
||||
{ C.eristaEmcMaxClock, 1600'000, 2600'000, panic::Emc, },
|
||||
{ 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, },
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include "pcv.hpp"
|
||||
#include "../mtc_timing_value.hpp"
|
||||
#include "../erista/calculate_timings_erista.hpp"
|
||||
@@ -216,7 +215,7 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000);
|
||||
|
||||
CalculateTimings(tCK_avg, table->rate_khz);
|
||||
CalculateTimings(tCK_avg);
|
||||
|
||||
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
|
||||
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
|
||||
@@ -361,176 +360,65 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
table->min_volt = std::clamp(900 + (C.emcDvbShift * 25), 900, 1050);
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::vector<u32> newEmcList;
|
||||
u32 *nsoStart;
|
||||
}
|
||||
|
||||
/* The silicon instructs; the children obey... */
|
||||
void MtcGenerateFreqTables() {
|
||||
newEmcList.clear();
|
||||
newEmcList.reserve(DvfsTableEntryCount);
|
||||
newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault));
|
||||
|
||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is scuffed, but Eristas step rate is... weird? */
|
||||
/* 1766MHz seems to cause crashes with other freqs near it... why is anyones guess... */
|
||||
u32 freqsLow[] = { 1633000, 1666000, 1700000, 1733000, 1800000, 1833000, 1862400, };
|
||||
constexpr size_t freqsLowSize = std::size(freqsLow);
|
||||
|
||||
for (size_t i = 0; i < freqsLowSize; ++i) {
|
||||
if (freqsLow[i] <= C.eristaEmcMaxClock) {
|
||||
newEmcList.push_back(freqsLow[i]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (C.eristaEmcMaxClock <= freqsLow[freqsLowSize - 1]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* High range. */
|
||||
constexpr u32 StepRate = 38400;
|
||||
while (newEmcList.back() + StepRate < C.eristaEmcMaxClock) {
|
||||
newEmcList.push_back(newEmcList.back() + StepRate);
|
||||
}
|
||||
|
||||
if (newEmcList.back() != C.eristaEmcMaxClock) {
|
||||
newEmcList.push_back(static_cast<u32>(C.eristaEmcMaxClock));
|
||||
}
|
||||
|
||||
constexpr u32 PllmToggleFrequency = 19200;
|
||||
|
||||
/* A step of 19.2khz will cause hangs, crashes and other weirdness. */
|
||||
/* Why? ¯\_(ツ)_/¯ */
|
||||
if (C.eristaEmcMaxClock - newEmcList[newEmcList.size() - 2] <= PllmToggleFrequency) {
|
||||
newEmcList.erase(newEmcList.begin() + newEmcList.size() - 2);
|
||||
}
|
||||
|
||||
newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit));
|
||||
}
|
||||
|
||||
/* TODO: Template this */
|
||||
Result VerifyMtcTable(EristaMtcTable *tableStart, u32 expectedFreq) {
|
||||
R_UNLESS(tableStart->rate_khz == expectedFreq, ldr::ResultInvalidMtcTable());
|
||||
R_UNLESS(tableStart->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* TODO: Template this */
|
||||
Result MtcValidateAllTables(EristaMtcTable *tableStart, const u32 *validationList, u32 tableCount) {
|
||||
for (u32 i = 0; i < tableCount; ++i) {
|
||||
R_TRY(VerifyMtcTable(&tableStart[i], validationList[i]));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* TODO: Put this into common. */
|
||||
DramId GetDramId() {
|
||||
u64 id64;
|
||||
splGetConfig(SplConfigItem_DramId, &id64);
|
||||
return static_cast<DramId>(id64);
|
||||
}
|
||||
|
||||
MtcTableIndex GetMtcDramIndex(DramId dramId) {
|
||||
for (u32 i = 0; i < std::size(mtcIndexTable); ++i) {
|
||||
if (mtcIndexTable[i].dramId == dramId) {
|
||||
return mtcIndexTable[i].index;
|
||||
}
|
||||
}
|
||||
|
||||
return MtcTableIndex_Invalid;
|
||||
}
|
||||
|
||||
NORETURN void AbortInvalidMtc(const char *crashMsg) {
|
||||
panic::SmcError(panic::Emc);
|
||||
CRASH(crashMsg);
|
||||
}
|
||||
|
||||
u32 GetMtcOffset(MtcTableIndex index) {
|
||||
if (index < T210SdevEmcDvfsTableS6gb01) {
|
||||
return index * erista::MtcFullTableSize;
|
||||
}
|
||||
|
||||
/* Account for the weird in between mariko table. */
|
||||
return index * erista::MtcFullTableSize + mariko::MtcFullTableSize;
|
||||
}
|
||||
|
||||
void PrepareMtcMemoryRegion(u8 *firstTable, EristaMtcTable *usedTable) {
|
||||
memmove(firstTable, usedTable, erista::MtcFullTableSize);
|
||||
|
||||
/* Clear all other tables. */
|
||||
/* The used table is excluded. */
|
||||
constexpr size_t RemainingRegionSize = (mariko::MtcFullTableSize) * (mariko::MtcFullTableCount) + (erista::MtcFullTableSize * (erista::MtcFullTableCount - 1));
|
||||
memset(firstTable + erista::MtcFullTableSize, 0, RemainingRegionSize);
|
||||
}
|
||||
|
||||
void MtcExtendTables(EristaMtcTable *table) {
|
||||
for (u32 i = erista::MtcTableCountDefault; i < newEmcList.size(); ++i) {
|
||||
std::memcpy(&table[i], &table[i - 1], sizeof(EristaMtcTable));
|
||||
table[i].rate_khz = newEmcList[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Probably more intuitive to point to 40800 rather than 1600000, but oh well. */
|
||||
Result MemFreqMtcTable(u32 *ptr) {
|
||||
static const DramId dramId = [] {
|
||||
DramId id = GetDramId();
|
||||
return id;
|
||||
}();
|
||||
u32 khz_list[] = { 40800, 68000, 102000, 204000, 408000, 665600, 800000, 1065600, 1331200, 1600000 };
|
||||
std::sort(maxEmcClocks, maxEmcClocks + std::size(maxEmcClocks));
|
||||
u32 khz_list_size = std::size(khz_list);
|
||||
|
||||
static const MtcTableIndex mtcIndex = [] {
|
||||
MtcTableIndex idx = GetMtcDramIndex(dramId);
|
||||
/* If for some reason this happens, there is no chance of recovering this. */
|
||||
if (idx == MtcTableIndex_Invalid) {
|
||||
AbortInvalidMtc("Invalid dramId");
|
||||
}
|
||||
return idx;
|
||||
}();
|
||||
|
||||
static const u32 mtcOffset = GetMtcOffset(mtcIndex);
|
||||
|
||||
constexpr u32 StartAdjustment = offsetof(EristaMtcTable, rate_khz) + sizeof(EristaMtcTable) * (erista::MtcTableCountDefault - 1);
|
||||
u8 *startPtr = reinterpret_cast<u8 *>(ptr) - StartAdjustment;
|
||||
|
||||
EristaMtcTable *table = reinterpret_cast<EristaMtcTable *>(startPtr + mtcOffset);
|
||||
R_TRY(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault));
|
||||
|
||||
PrepareMtcMemoryRegion(startPtr, table);
|
||||
table = reinterpret_cast<EristaMtcTable *>(startPtr);
|
||||
|
||||
if (R_FAILED(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault))) {
|
||||
AbortInvalidMtc("Failed mtc validation");
|
||||
// Generate list for mtc table pointers
|
||||
EristaMtcTable *table_list[khz_list_size];
|
||||
for (u32 i = 0; i < khz_list_size; i++) {
|
||||
u32 mtcIndex = khz_list_size - 1 - i;
|
||||
u8 *table = reinterpret_cast<u8 *>(ptr) - offsetof(EristaMtcTable, rate_khz) - i * sizeof(EristaMtcTable);
|
||||
table_list[mtcIndex] = reinterpret_cast<EristaMtcTable *>(table);
|
||||
R_UNLESS(table_list[mtcIndex]->rate_khz == khz_list[mtcIndex], ldr::ResultInvalidMtcTable());
|
||||
R_UNLESS(table_list[mtcIndex]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
|
||||
}
|
||||
|
||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit) {
|
||||
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
MtcExtendTables(table);
|
||||
|
||||
if (R_FAILED(MtcValidateAllTables(table, newEmcList.data(), newEmcList.size()))) {
|
||||
AbortInvalidMtc("Failed mtc validation");
|
||||
/* If we oc ram at all, tables are always shifted by at least 1. */
|
||||
u32 tableShifts = 1;
|
||||
for (u32 i = 0; i < std::size(maxEmcClocks) - 1; ++i) {
|
||||
/* Duplicated mtc tables may cause pcv to not select frequencies properly, causing issues. */
|
||||
if (maxEmcClocks[i] != maxEmcClocks[i + 1] && maxEmcClocks[i] > EmcClkOSLimit) {
|
||||
++tableShifts;
|
||||
} else {
|
||||
maxEmcClocks[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = erista::MtcTableCountDefault; i < newEmcList.size(); ++i) {
|
||||
MemMtcTableAutoAdjust(&table[i]);
|
||||
/* Erista has extra, useless mtc tables, such as 40.8 Mhz, overwrite them to make room for oc freqs. */
|
||||
/* More than 3 tables can be overwritten, but 3 is plenty. */
|
||||
std::memmove(table_list[0], table_list[tableShifts], sizeof(EristaMtcTable) * (khz_list_size - tableShifts));
|
||||
|
||||
/* Since we're not scaling r/w latency properly on Erista, we first overwrite the tables with the 1600 MHz table before scaling it. */
|
||||
for (u32 i = 0; i < tableShifts; ++i) {
|
||||
std::memcpy(table_list[khz_list_size - i - 1], table_list[khz_list_size - tableShifts - 1], sizeof(EristaMtcTable));
|
||||
}
|
||||
|
||||
for (u32 i = tableShifts, j = 0; i > 0 && j < std::size(maxEmcClocks); ++j) {
|
||||
if (!maxEmcClocks[j]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
table_list[khz_list_size - i]->rate_khz = maxEmcClocks[j];
|
||||
MemMtcTableAutoAdjust(table_list[khz_list_size - i]);
|
||||
--i;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MemFreqMax(u32 *ptr) {
|
||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit) {
|
||||
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
|
||||
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxEmcClocks));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -562,6 +450,7 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
// R_SUCCEED();
|
||||
// }
|
||||
|
||||
|
||||
Result MemMtcTableAsm(u32 *ptr) {
|
||||
/* This is a mess but the compiler made this painful to patch so we must do it this way */
|
||||
constexpr s32 GoodAdrpOffset = -1;
|
||||
@@ -610,9 +499,6 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
}
|
||||
|
||||
void Patch(uintptr_t mapped_nso, size_t nso_size) {
|
||||
nsoStart = reinterpret_cast<u32 *>(mapped_nso);
|
||||
MtcGenerateFreqTables();
|
||||
|
||||
u32 CpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq);
|
||||
u32 GpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq);
|
||||
|
||||
@@ -627,7 +513,7 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
{"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn },
|
||||
{"GPU PLL Max", & GpuFreqPllMax, 1, nullptr, GpuClkPllMax },
|
||||
// {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit },
|
||||
{"MEM Freq Mtc", &MemFreqMtcTable, 1, nullptr, EmcClkOSLimit },
|
||||
{"MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit },
|
||||
{"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
|
||||
{"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
|
||||
{"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS },
|
||||
@@ -646,7 +532,7 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
// ViewLog();
|
||||
|
||||
for (auto &entry : patches) {
|
||||
LOGGING("%s Count: %zu\n", entry.description, entry.patched_count);
|
||||
LOGGING("%s Count: %zu", entry.description, entry.patched_count);
|
||||
if (R_FAILED(entry.CheckResult())) {
|
||||
// ViewLog();
|
||||
panic::SmcError(panic::Patch);
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
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[] = {
|
||||
// CPU_PLL_CVB_TABLE_ODN
|
||||
{ 204000, {721094}, { } },
|
||||
@@ -106,11 +109,8 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
{ },
|
||||
};
|
||||
|
||||
constexpr u32 EmcListDefault[] = { 40800, 68000, 102000, 204000, 408000, 665600, 800000, 1065600, 1331200, 1600000, };
|
||||
constexpr u32 EmcListSizeDefault = std::size(EmcListDefault);
|
||||
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
|
||||
|
||||
constexpr u32 MemVoltHOS = 1125'000;
|
||||
constexpr u32 EmcClkMinFreq = 40800; /* 40.8 MHz table only exists on erista. */
|
||||
constexpr u32 EmcClkPllmLimit = 1866'000'000;
|
||||
|
||||
constexpr u32 MTC_TABLE_REV = 7;
|
||||
|
||||
@@ -50,15 +50,18 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
R_THROW(ldr::ResultInvalidGpuDvfs());
|
||||
}
|
||||
|
||||
if (!C.marikoGpuVmin) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
PATCH_OFFSET(ptr, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 3, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 6, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 9, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 12, C.marikoGpuVmin);
|
||||
if(C.marikoGpuBootVolt) {
|
||||
PATCH_OFFSET(ptr - 3, C.marikoGpuBootVolt);
|
||||
}
|
||||
|
||||
if (C.marikoGpuVmin) {
|
||||
PATCH_OFFSET(ptr, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 3, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 6, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 9, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 12, C.marikoGpuVmin);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -635,14 +638,14 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
}
|
||||
|
||||
void MtcGenerateFreqTables() {
|
||||
newEmcList.clear();
|
||||
newEmcList.reserve(DvfsTableEntryCount);
|
||||
newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault));
|
||||
|
||||
if (C.marikoEmcMaxClock <= EmcClkOSLimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
newEmcList.clear();
|
||||
newEmcList.reserve(DvfsTableEntryCount);
|
||||
newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault));
|
||||
|
||||
u32 stepRate = 0;
|
||||
switch (C.stepMode) {
|
||||
case StepMode_66MHz:
|
||||
@@ -764,6 +767,10 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
MarikoMtcTable *table = reinterpret_cast<MarikoMtcTable *>(startPtr + mtcOffset);
|
||||
R_TRY(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault));
|
||||
|
||||
if (C.marikoEmcMaxClock <= EmcClkOSLimit) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
PrepareMtcMemoryRegion(startPtr, table);
|
||||
table = reinterpret_cast<MarikoMtcTable *>(startPtr);
|
||||
|
||||
@@ -771,10 +778,6 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
AbortInvalidMtc("Failed mtc validation");
|
||||
}
|
||||
|
||||
if (C.marikoEmcMaxClock <= EmcClkOSLimit) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
MtcExtendTables(table);
|
||||
|
||||
if (R_FAILED(MtcValidateAllTables(table, newEmcList.data(), newEmcList.size()))) {
|
||||
@@ -834,18 +837,18 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
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)) }, },
|
||||
{ 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)) }, },
|
||||
{ 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)) }, },
|
||||
|
||||
@@ -148,6 +148,8 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
constexpr u32 EmcListDefault[] = { 204000, 1331200, 1600000, };
|
||||
constexpr u32 EmcListSizeDefault = std::size(EmcListDefault);
|
||||
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
|
||||
constexpr u32 EmcRateStep = 33'000;
|
||||
constexpr u32 EmcRateStepScale = 33'200;
|
||||
|
||||
constexpr u32 EmcClkOSAlt = 1331'200;
|
||||
constexpr u32 EmcClkPllmLimit = 2133'000'000;
|
||||
|
||||
Reference in New Issue
Block a user