Better timing scaling (breaks erista, will fix later)

This commit is contained in:
Lightos1
2025-11-30 21:42:48 +01:00
parent 8b25efe4e5
commit a87f1fbee0
9 changed files with 1468 additions and 710 deletions

View File

@@ -33,25 +33,25 @@ volatile CustomizeTable C = {
.mtcConf = AUTO_ADJ_BL,
.hpMode = DISABLED,
.hpMode = ENABLED,
.commonCpuBoostClock = 1785000, // Default boost clock
.commonCpuBoostClock = 2397000, // Default boost clock
.commonEmcMemVolt = 1175000, // LPDDR4X JEDEC Specification
.commonEmcMemVolt = 1250000, // LPDDR4X JEDEC Specification
.eristaCpuMaxVolt = 1235,
.eristaEmcMaxClock = 1862400, // Maximum HB-MGCH ram rating
.marikoCpuMaxVolt = 1120,
.marikoCpuMaxVolt = 1185,
.marikoEmcMaxClock = 2700000, // Hynix NME and Samsung AM-MGCJ Rating (others are 4766MT, 2133MHz)
.marikoEmcMaxClock = 2900000, // Hynix NME and Samsung AM-MGCJ Rating (others are 4766MT, 2133MHz)
.marikoEmcVddqVolt = 640000,
.marikoCpuUV = 0, // No undervolt
.marikoGpuUV = 2,
.marikoGpuUV = 3,
.eristaCpuUV = 0,
@@ -59,26 +59,27 @@ volatile CustomizeTable C = {
.commonGpuVoltOffset = 0,
.EmcDvbShift = 5,
// Defaults - Zeroed
.EmcDvbShift = 10,
// Primary
.t1_tRCD = 4,
.t2_tRP = 3,
.t3_tRAS = 8,
.t1_tRCD = 3,
.t2_tRP = 2,
.t3_tRAS = 4,
// Secondary
.t4_tRRD = 2,
.t5_tRFC = 5,
.t6_tRTW = 4,
.t7_tWTR = 4,
.t8_tREFI= 6,
.t4_tRRD = 2,
.t5_tRFC = 4,
.t6_tRTW = 4,
.t7_tWTR = 4,
.t8_tREFI = 6,
// .mem_burst_latency = 0, // 0 - 1600l, 1 = 1866bl, 2 = 2133bl /* TODO: Remove/fix. */
/* Set to 4 read and 2 write for 1866bl. */
/* For 2131bl: 8 read and 4 write. */
.mem_burst_read_latency = 8,
.mem_burst_write_latency = 4,
.marikoCpuHighVmin = 800,
.marikoCpuHighVmin = 750,
.marikoCpuLowVmin = 650,
.marikoCpuLowVmin = 600,
.eristaGpuVmin = 810,
@@ -86,7 +87,7 @@ volatile CustomizeTable C = {
.marikoGpuVmax = 850,
// NOTE: These tables should NOT BE USED and are only here as placeholders. Always try and find your own optimal tables.
// Ensure the voltages actually increase or stay the same
// Ensure the voltages actually increase or stay the sameot
.marikoGpuVoltArray = {
610 /* 76 */,
@@ -99,18 +100,18 @@ volatile CustomizeTable C = {
610 /* 614 */,
610 /* 691 */,
610 /* 768 */,
610 /* 844 */,
625 /* 921 */,
655 /* 998 */,
685 /* 1075 */,
725 /* 1152 */,
750 /* 1228 */,
765 /* 1267 (Disabled by default) */,
790 /* 1305 (Disabled by default) */,
0 /* 1344 (Disabled by default) */,
0 /* 1382 (Disabled by default) */,
0 /* 1420 (Disabled by default) */,
0 /* 1459 (Disabled by default) */,
620 /* 844 */,
640 /* 921 */,
675 /* 998 */,
710 /* 1075 */,
735 /* 1152 */,
785 /* 1228 */,
785 /* 1267 (Disabled by default) */,
780 /* 1305 (Disabled by default) */,
960 /* 1344 (Disabled by default) */,
960 /* 1382 (Disabled by default) */,
960 /* 1420 (Disabled by default) */,
960 /* 1459 (Disabled by default) */,
0 /* 1497 (Disabled by default) */,
0 /* 1536 (Disabled by default) */,
@@ -204,30 +205,34 @@ volatile CustomizeTable C = {
},
.marikoCpuDvfsTableSLT = {
{ 612000, { 853926, -20775, 113 }, {} },
{ 714000, { 889361, -21625, 113 }, {} },
{ 816000, { 926862, -22485, 113 }, {} },
{ 918000, { 966431, -23345, 113 }, {} },
{ 1020000, { 1008066, -24205, 113 }, { 1120000 } },
{ 1122000, { 1051768, -25065, 113 }, { 1120000 } },
{ 1224000, { 1097537, -25925, 113 }, { 1120000 } },
{ 1326000, { 1145373, -26785, 113 }, { 1120000 } },
{ 1428000, { 1195276, -27645, 113 }, { 1120000 } },
{ 1581000, { 1274006, -28935, 113 }, { 1120000 } },
{ 1683000, { 1329076, -29795, 113 }, { 1120000 } },
{ 1785000, { 1386213, -30655, 113 }, { 1120000 } },
{ 1887000, { 1445416, -31515, 113 }, { 1120000 } },
{ 1963500, { 1490873, -32155, 113 }, { 1120000 } },
// Appending table
{ 2091000, { 1580725, -33235, 113 }, { 1235000 } },
{ 2193000, { 1580725, -33235, 113 }, { 1235000 } },
{ 2295000, { 1635431, -34095, 113 }, { 1235000 } },
{ 2397000, { 1702903, -34955, 113 }, { 1235000 } },
{ 2499000, { 1754400, -35643, 113 }, { 1235000 } },
{ 2601000, { 1805897, -36331, 113 }, { 1235000 } },
{ 2703000, { 1857394, -37019, 113 }, { 1235000 } },
{ 2805000, { 1908891, -37707, 113 }, { 1235000 } },
{ 2907000, { 1960388, -38395, 113 }, { 1250000 } },
// { 204000, { 732856, -17335, 113 }, { } },
// { 306000, { 760024, -18195, 113 }, { } },
// { 408000, { 789258, -19055, 113 }, { } },
// { 510000, { 789258, -19915, 113 }, { } },
{ 612000, { 789258, -19055, 113 }, { } },
{ 714000, { 820558, -19915, 113 }, { } },
{ 816000, { 853926, -20775, 113 }, { } },
{ 918000, { 889361, -21625, 113 }, { } },
{ 1020000, { 926862, -22485, 113 }, { 1120000 } },
{ 1122000, { 926862, -22485, 113 }, { 1120000 } },
{ 1224000, { 926862, -22485, 113 }, { 1120000 } },
{ 1326000, { 966431, -23345, 113 }, { 1120000 } },
{ 1428000, { 1008066, -24205, 113 }, { 1120000 } },
{ 1581000, { 1051768, -25065, 113 }, { 1120000 } },
{ 1683000, { 1097537, -25925, 113 }, { 1120000 } },
{ 1785000, { 1145373, -26785, 113 }, { 1120000 } },
{ 1887000, { 1195276, -27645, 113 }, { 1120000 } },
{ 1963500, { 1274006, -29795, 113 }, { 1120000 } },
{ 2091000, { 1349076, -33235, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2193000, { 1386213, -33235, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2295000, { 1445416, -34095, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2397000, { 1490873, -34955, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2499000, { 1580725, -35815, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2601000, { 1702903, -36675, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2703000, { 1748360, -37535, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2805000, { 1793817, -38395, 113 }, { CPU_MAX_MAX_VOLT } },
{ 2907000, { 1839274, -39255, 113 }, { CPU_MAX_MAX_VOLT } },
{ 3009000, { 1884731, -40115, 113 }, { CPU_MAX_MAX_VOLT } },
},
/* - Erista GPU DVFS Table:
@@ -392,9 +397,6 @@ volatile CustomizeTable C = {
{ 1536000, { }, { 1275148, -12688, -648, 0, 1077, 40 }, },
},
//.eristaMtcTable = const_cast<EristaMtcTable *>(&EristaMtcTablePlaceholder),
//.marikoMtcTable = const_cast<MarikoMtcTable *>(&MarikoMtcTablePlaceholder),
};
}

View File

@@ -74,7 +74,9 @@ typedef struct CustomizeTable {
u32 t6_tRTW;
u32 t7_tWTR;
u32 t8_tREFI;
u32 mem_burst_latency;
u32 mem_burst_read_latency;
u32 mem_burst_write_latency;
u32 marikoCpuHighVmin;
u32 marikoCpuLowVmin;

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) Lightos_
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../oc_common.hpp"
#include "../mtc_timing_value.hpp"
#include "timing_tables.hpp"
namespace ams::ldr::oc::pcv::mariko {
s32 FixEinput(s32 val) {
if (auto patch = FindEinput()) {
return patch->correct;
}
return val;
}
u32 GetRext() {
if (auto r = FindRext()) {
return r->correct;
}
return 0x1A;
}
/* TODO: This function is quite uggly, refactor! */
void CalculateMiscTimings() {
tW2P = 0x2d;
rdv = 0x39 + C.mem_burst_read_latency;
obdly = 0x10000002 + C.mem_burst_write_latency;
einput_duration = 0x1C;
quse_width = 0x8;
for (u32 i = 0; i < g_misc_table_size; i++) {
const auto& e = g_misc_table[i];
if (C.marikoEmcMaxClock >= e.min_freq) {
rdv += e.rdv_inc;
if (e.einput) einput_duration = e.einput;
if (e.quse_width) quse_width = e.quse_width;
obdly += e.obdly_delta;
}
}
if (WL >= 16) tW2P += 6;
if (WL >= 18) tW2P += 8;
s32 einput_calc = quse_width - (0.010182 * (C.marikoEmcMaxClock / 1000.0) - 0.0879) + 0.5;
einput = FixEinput(einput_calc);
rext = GetRext();
}
void CalculateIbdly() {
/* Ibdly is so inconsistent, I am using the most common value and then checking with a lookup table. */
ibdly = 0x1000001D + C.mem_burst_read_latency;
if (auto patch = FindIbdlyPatch()) {
ibdly += patch->adjust;
}
}
void CalculateTWTPDEN() {
tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6;
if (C.marikoEmcMaxClock >= 2'233'000 && C.marikoEmcMaxClock < 2'533'000) tWTPDEN++;
if (C.marikoEmcMaxClock >= 2'433'000 && C.marikoEmcMaxClock < 2'800'000) tWTPDEN--;
}
void CalculateTR2W() {
tR2W = CEIL(RL_DBI + (tDQSCK_max / tCK_avg) + (BL / 2) - WL + tWPRE + FLOOR(tRPST) + 9.0);
if (auto patch = FindTR2WPatch()) {
tR2W += patch->adjust;
}
}
void CalculateTW2R() {
tW2R = WL + (BL / 2) - 6 + CEIL(tWTR / tCK_avg);
const FreqTW2R* t = FindTW2R();
if (!t) return;
tW2R += t->adjust;
if (t->min_val) {
tW2R = MAX(tW2R, t->min_val);
}
if (t->max_val) {
tW2R = MIN(tW2R, t->max_val);
}
}
void CalculateTW2RDerivedWriteTimings() {
tWTM = WL + (BL / 2) + 1 + CEIL(tW2R / tCK_avg);
tWATM = tWTM + CEIL(tWR / tCK_avg);
}
void CalculateQuse() {
quse = ROUND(0.002266 * (C.marikoEmcMaxClock / 1000.0) + 31.88) + C.mem_burst_read_latency;
if (auto patch = FindQusePatch()) {
quse += patch->adjust;
}
}
void CalculateQrst() {
qrst = 0x00070000;
u32 qrst_calc = ROUND(22.1 - (C.marikoEmcMaxClock / 1000000.0) * 8.0) + C.mem_burst_read_latency;
u32 qrst_low = MAX(static_cast<u32>(0), qrst_calc);
if (C.marikoEmcMaxClock >= 2'533'000) {
qrst = INCREMENT_HIGH_BYTES_BY(qrst, 1);
} else if (C.marikoEmcMaxClock == 2'800'000) {
qrst = SET_HIGH_BYTES(qrst, 6);
}
qrst = SET_LOW_BYTES(qrst, qrst_low);
if (auto patch = FindQrstPatch()) {
qrst = INCREMENT_LOW_BYTES_BY(qrst, patch->adjust);
}
}
void CalculateQsafe() {
qsafe = ROUND((C.marikoEmcMaxClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency;
if (auto patch = FindQsafePatch()) {
qsafe += patch->adjust;
}
}
void CalculateQpop() {
qpop = FLOOR(((C.marikoEmcMaxClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency;
if (C.marikoEmcMaxClock >= 3'100'000) qpop = 0x2B; /* TODO: Check if this is actually true. */
else if (C.marikoEmcMaxClock >= 3'133'000) ++qpop;
}
void CalculatePdex2rw() {
double freq_mhz = C.marikoEmcMaxClock / 1000.0;
double pdex_local = (0.011 * freq_mhz) - 1.443;
pdex2rw = static_cast<u32>(ROUND(pdex_local));
if (pdex2rw < 22) pdex2rw = 22;
if (pdex2rw > 33) pdex2rw = 33;
if (auto patch = FindPdex2rwPatch()) {
pdex2rw += patch->adjust;
}
}
void CalculateCke2pden() {
cke2pden = (static_cast<double>((C.marikoEmcMaxClock / 1000.0) * 0.00875) - 0.65);
if (auto patch = FindCke2pdenPatch()) {
cke2pden += patch->adjust;
}
}
void CalculateTimings() {
CalculateMiscTimings();
CalculateIbdly();
CalculateTWTPDEN();
CalculateTR2W();
CalculateTW2R();
CalculateTW2RDerivedWriteTimings();
CalculateQuse();
CalculateQrst();
CalculateQsafe();
CalculateQpop();
CalculatePdex2rw();
CalculateCke2pden();
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) Lightos_
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace ams::ldr::oc::pcv::mariko {
void CalculateTimings();
}

View File

@@ -0,0 +1,309 @@
/*
* Copyright (c) Lightos_
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../mtc_timing_value.hpp"
#include "timing_tables.hpp"
namespace ams::ldr::oc::pcv::mariko {
const MiscTimings g_misc_table[] = {
{1'866'000, 1, 0x20, 0x9, 0},
{2'133'000, 1, 0x24, 0xA, 0},
{2'166'000, 1, 0, 0, 0},
{2'233'000, 0, 0x25, 0, 0},
{2'300'000, 0, 0x26, 0xB, 0},
{2'333'000, 0, 0x27, 0, 0},
{2'366'000, 1, 0x26, 0xA, 0},
{2'433'000, 0, 0x27, 0, 0},
{2'466'000, 0, 0x2A, 0, 0},
{2'500'000, 0, 0x28, 0xB, 0},
{2'533'000, 0, 0x29, 0, -2},
{2'566'000, 1, 0, 0, 0},
{2'633'000, 0, 0x2A, 0, 0},
{2'700'000, 0, 0x2B, 0xC, 0},
{2'733'000, 0, 0x2C, 0, 0},
{2'766'000, 1, 0x2B, 0xB, 0},
{2'833'000, 0, 0x2C, 0, -2},
{2'866'000, 0, 0, 0, -2},
{2'900'000, 0, 0, 0, -2},
{2'933'000, 0, 0x2E, 0xC, 0},
{2'966'000, 1, 0, 0, 0},
{3'033'000, 0, 0x2F, 0, 0},
{3'100'000, 0, 0, 0, -2},
{3'133'000, 1, 0x31, 0xD, 0},
};
const u32 g_misc_table_size = sizeof(g_misc_table) / sizeof(g_misc_table[0]);
const ReplacePatch g_einput_patches[] = {
{2'133'000, 0x16}, {2'166'000, 0x17}, {2'200'000, 0x17},
{2'233'000, 0x16}, {2'266'000, 0x16}, {2'300'000, 0x15},
{2'333'000, 0x14}, {2'366'000, 0x16}, {2'400'000, 0x16},
{2'433'000, 0x15}, {2'466'000, 0x15}, {2'500'000, 0x14},
{2'533'000, 0x13}, {2'566'000, 0x14}, {2'600'000, 0x14},
{2'633'000, 0x13}, {2'666'000, 0x13}, {2'700'000, 0x12},
{2'733'000, 0x11}, {2'766'000, 0x13}, {2'800'000, 0x13},
{2'833'000, 0x12}, {2'866'000, 0x12}, {2'900'000, 0x12},
{2'933'000, 0x10}, {2'966'000, 0x11}, {3'000'000, 0x11},
{3'033'000, 0x10}, {3'066'000, 0x10}, {3'100'000, 0x10},
{3'133'000, 0x0F},
};
const u32 g_einput_patches_size = sizeof(g_einput_patches) / sizeof(g_einput_patches[0]);
const ReplacePatch *FindEinput() {
for (u32 i = 0; i < g_einput_patches_size; i++)
if (g_einput_patches[i].freq == C.marikoEmcMaxClock)
return &g_einput_patches[i];
return nullptr;
}
const ReplacePatch g_rext_table[] = {
{2'133'000, 0x1A}, {2'166'000, 0x19}, {2'200'000, 0x19},
{2'233'000, 0x19}, {2'266'000, 0x1A}, {2'300'000, 0x1B},
{2'333'000, 0x1B}, {2'366'000, 0x1B}, {2'400'000, 0x1B},
{2'433'000, 0x1B}, {2'466'000, 0x1B}, {2'500'000, 0x1A},
{2'533'000, 0x1C}, {2'566'000, 0x1B}, {2'600'000, 0x17},
{2'633'000, 0x1B}, {2'666'000, 0x1B}, {2'700'000, 0x1C},
{2'733'000, 0x1C}, {2'766'000, 0x1D}, {2'800'000, 0x1D},
{2'833'000, 0x1D}, {2'866'000, 0x1D}, {2'900'000, 0x1D},
{2'933'000, 0x1C}, {2'966'000, 0x1D}, {3'000'000, 0x1D},
{3'033'000, 0x1D}, {3'066'000, 0x1D}, {3'100'000, 0x1D},
{3'133'000, 0x1D},
};
const u32 g_rext_table_size = sizeof(g_rext_table) / sizeof(g_rext_table[0]);
const ReplacePatch *FindRext() {
for (u32 i = 0; i < g_rext_table_size; i++)
if (g_rext_table[i].freq == C.marikoEmcMaxClock)
return &g_rext_table[i];
return nullptr;
}
const FreqTW2R g_tw2r_table[] = {
{2'300'000, 0x2B, 0xFFFFFFFF, 0},
{2'400'000, 0, 0x2B, 0},
{2'500'000, 0x2C, 0xFFFFFFFF, -1},
{2'566'000, 0x2D, 0xFFFFFFFF, -1},
{2'700'000, 0x2E, 0xFFFFFFFF, -1},
{2'800'000, 0x2F, 0xFFFFFFFF, -1},
{2'900'000, 0x30, 0xFFFFFFFF, -1},
{3'000'000, 0x31, 0xFFFFFFFF, -1},
{3'100'000, 0x32, 0xFFFFFFFF, -1},
{0xFFFFFFFF, 0, 0x33, 0},
};
const u32 g_tw2r_table_size = sizeof(g_tw2r_table) / sizeof(g_tw2r_table[0]);
const FreqTW2R *FindTW2R() {
for (u32 i = 0; i < g_tw2r_table_size; i++)
if (C.marikoEmcMaxClock <= g_tw2r_table[i].max_freq)
return &g_tw2r_table[i];
return nullptr;
}
const AdjustPatch g_ibdly_patches[] = {
{2'133'000, -2},
{2'166'000, -1},
{2'200'000, -1},
{2'233'000, -1},
{2'266'000, -1},
{2'300'000, -2},
{2'333'000, -2},
{2'500'000, -1},
{2'533'000, -2},
{2'566'000, -1},
{2'633'000, -1},
{2'666'000, -1},
{2'700'000, -2},
{2'733'000, -2},
{2'833'000, -9},
{2'933'000, -1},
{3'100'000, -9},
{3'133'000, -9},
};
const u32 g_ibdly_table_size = sizeof(g_ibdly_patches) / sizeof(g_ibdly_patches[0]);
const AdjustPatch *FindIbdlyPatch() {
for (u32 i = 0; i < g_ibdly_table_size; i++)
if (g_ibdly_patches[i].freq == C.marikoEmcMaxClock)
return &g_ibdly_patches[i];
return nullptr;
}
const AdjustPatch g_tr2w_patches[] = {
{2'500'000, 1},
{2'533'000, 1},
{2'566'000, 1},
{2'866'000, -1},
{3'100'000, 1},
{3'133'000, 1},
};
const u32 g_tr2w_table_size = sizeof(g_tr2w_patches) / sizeof(g_tr2w_patches[0]);
const AdjustPatch *FindTR2WPatch() {
for (u32 i = 0; i < g_tr2w_table_size; i++)
if (g_tr2w_patches[i].freq == C.marikoEmcMaxClock)
return &g_tr2w_patches[i];
return nullptr;
}
const AdjustPatch g_quse_patches[] = {
{2'133'000, -1},
{2'300'000, -1},
{2'333'000, -1},
{2'366'000, +1},
{2'400'000, +1},
{2'433'000, +1},
{2'466'000, +1},
{2'500'000, -1},
{2'533'000, -1},
{2'700'000, -1},
{2'733'000, -1},
{2'766'000, +1},
{2'800'000, +1},
{2'833'000, +1},
{2'866'000, +1},
{2'900'000, +1},
{2'933'000, -1},
};
const u32 g_quse_table_size = sizeof(g_quse_patches) / sizeof(g_quse_patches[0]);
const AdjustPatch *FindQusePatch() {
for (u32 i = 0; i < g_quse_table_size; i++)
if (g_quse_patches[i].freq == C.marikoEmcMaxClock)
return &g_quse_patches[i];
return nullptr;
}
const AdjustPatch g_qrst_patches[] = {
{2'166'000, 1},
{2'200'000, 1},
{2'233'000, 1},
{2'266'000, 1},
{2'366'000, 2},
{2'400'000, 2},
{2'433'000, 1},
{2'466'000, 2},
{2'500'000, 1},
{2'533'000, -1},
{2'700'000, -1},
{2'733'000, -1},
{2'766'000, 1},
{2'800'000, 4},
{2'833'000, 1},
{2'866'000, 1},
{2'900'000, 1},
{2'933'000, -1},
{2'966'000, 1},
{3'000'000, 1},
{3'100'000, 1},
};
const u32 g_qrst_table_size = sizeof(g_qrst_patches) / sizeof(g_qrst_patches[0]);
const AdjustPatch *FindQrstPatch() {
for (u32 i = 0; i < g_qrst_table_size; i++)
if (g_qrst_patches[i].freq == C.marikoEmcMaxClock)
return &g_qrst_patches[i];
return nullptr;
}
const AdjustPatch g_qsafe_patches[] = {
{2'166'000, 1},
{2'200'000, 1},
{2'500'000, -1},
{2'533'000, -1},
{2'666'000, -1},
{2'700'000, -1},
{2'733'000, -1},
{2'800'000, -1},
{2'833'000, -1},
{2'866'000, -1},
{2'900'000, -1},
{2'933'000, -2},
{2'966'000, -1},
{3'000'000, -1},
{3'033'000, -1},
{3'066'000, -2},
{3'100'000, -2},
};
const u32 g_qsafe_table_size = sizeof(g_qsafe_patches) / sizeof(g_qsafe_patches[0]);
const AdjustPatch *FindQsafePatch() {
for (u32 i = 0; i < g_qsafe_table_size; i++)
if (g_qsafe_patches[i].freq == C.marikoEmcMaxClock)
return &g_qsafe_patches[i];
return nullptr;
}
const AdjustPatch g_pdex2rw_patches[] = {
{2'166'000, 1},
{2'300'000, 1},
{2'333'000, 1},
{2'433'000, 1},
{2'533'000, 0},
{2'633'000, -1},
{2'666'000, -1},
{2'733'000, -1},
{2'766'000, -1},
{2'800'000, -1},
{2'833'000, -1},
{2'933'000, -1},
{3'066'000, 1},
};
const u32 g_pdex2rw_table_size = sizeof(g_pdex2rw_patches) / sizeof(g_pdex2rw_patches[0]);
const AdjustPatch *FindPdex2rwPatch() {
for (u32 i = 0; i < g_pdex2rw_table_size; i++)
if (g_pdex2rw_patches[i].freq == C.marikoEmcMaxClock)
return &g_pdex2rw_patches[i];
return nullptr;
}
const AdjustPatch g_cke2pden_patches[] = {
{2'133'000, 1},
{2'166'000, 1},
{2'266'000, 1},
{2'300'000, 1},
{2'366'000, 1},
{2'400'000, 1},
{2'500'000, 1},
{2'633'000, 1},
{2'733'000, 1},
{2'833'000, 1},
{2'866'000, 1},
{2'966'000, 1},
{3'066'000, 1},
{3'100'000, 1},
};
const u32 g_cke2pden_table_size = sizeof(g_cke2pden_patches) / sizeof(g_cke2pden_patches[0]);
const AdjustPatch *FindCke2pdenPatch() {
for (u32 i = 0; i < g_cke2pden_table_size; i++)
if (g_cke2pden_patches[i].freq == C.marikoEmcMaxClock)
return &g_cke2pden_patches[i];
return nullptr;
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) Lightos_
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../mtc_timing_value.hpp"
namespace ams::ldr::oc::pcv::mariko {
struct ReplacePatch {
u32 freq;
u32 correct;
};
extern const ReplacePatch g_einput_patches[];
extern const u32 g_einput_patches_size;
const ReplacePatch *FindEinput();
extern const ReplacePatch g_rext_table[];
extern const u32 g_rext_table_size;
const ReplacePatch *FindRext();
struct AdjustPatch {
u32 freq;
s32 adjust;
};
extern const AdjustPatch g_ibdly_patches[];
extern const u32 g_ibdly_table_size;
const AdjustPatch *FindIbdlyPatch();
extern const AdjustPatch g_tr2w_patches[];
extern const u32 g_tr2w_table_size;
const AdjustPatch *FindTR2WPatch();
extern const AdjustPatch g_quse_patches[];
extern const u32 g_quse_table_size;
const AdjustPatch *FindQusePatch();
extern const AdjustPatch g_qrst_patches[];
extern const u32 q_qrst_table_size;
const AdjustPatch *FindQrstPatch();
extern const AdjustPatch g_qsafe_patches[];
extern const u32 g_qsafe_table_size;
const AdjustPatch *FindQsafePatch();
extern const AdjustPatch g_pdex2rw_patches[];
extern const u32 g_pdex2rw_table_size;
const AdjustPatch *FindPdex2rwPatch();
extern const AdjustPatch g_cke2pden_patches[];
extern const u32 g_cke2pden_table_size;
const AdjustPatch *FindCke2pdenPatch();
struct MiscTimings {
u32 min_freq;
u32 rdv_inc;
u32 einput;
u32 quse_width;
s32 obdly_delta;
};
extern const MiscTimings g_misc_table[];
extern const u32 g_misc_table_size;
struct FreqTW2R {
u32 max_freq;
u32 min_val;
u32 max_val;
s32 adjust;
};
extern const FreqTW2R g_tw2r_table[];
extern const u32 g_tw2r_table_size;
const FreqTW2R *FindTW2R();
}

View File

@@ -25,25 +25,30 @@ namespace ams::ldr::oc {
#define MIN(A, B) std::min(A, B)
#define CEIL(A) std::ceil(A)
#define FLOOR(A) std::floor(A)
#define ROUND(A) std::lround(A)
#define GET_LOW_BYTES(x) ((u16)((x) & 0xFFFF))
#define SET_LOW_BYTES(x, val) (((x) & 0xFFFF0000) | ((u32)(val) & 0xFFFF))
#define INCREMENT_LOW_BYTES_BY(x, n) SET_LOW_BYTES((x), (GET_LOW_BYTES(x) + (n)))
#define GET_HIGH_BYTES(x) ((u16)(((x) >> 16) & 0xFFFF))
#define SET_HIGH_BYTES(x, val) (((x) & 0x0000FFFF) | (((u32)(val) & 0xFFFF) << 16))
#define INCREMENT_HIGH_BYTES_BY(x, n) SET_HIGH_BYTES((x), (GET_HIGH_BYTES(x) + (n)))
/* Primary timings. */
const std::array<u32, 8> tRCD_values = {18, 17, 16, 15, 14, 13, 12, 11};
const std::array<u32, 8> tRP_values = {18, 17, 16, 15, 14, 13, 12, 11};
const std::array<u32, 10> tRAS_values = {42, 36, 34, 32, 30, 28, 26, 24, 22, 20};
const std::array<double, 8> tRRD_values = {10.0, 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0};
const std::array<double, 7> tRRD_values = {/*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0}; /* 10.0 is used for <2133mhz; do we care? */
const std::array<u32, 11> tRFC_values = {140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40};
const std::array<u32, 10> tWTR_values = {10, 9, 8, 7, 6, 5, 4, 3, 3, 1};
const std::array<u32, 6> tREFpb_values = {3900, 5850, 7800, 11700, 15600, 99999};
const u32 BL = 16;
/* Set to 4 read and 2 write for 1866bl. */
/* For 2131bl: 8 read and 4 write. */
const u32 rl_offset = 8;
const u32 wl_offset = 4;
const u32 RL = 28 + C.mem_burst_read_latency;
const u32 WL = 14 + C.mem_burst_write_latency;
const u32 RL = 28 + rl_offset;
const u32 WL = 14 + wl_offset;
const u32 RL_DBI = RL + 4;
/* Precharge to Precharge Delay. (Cycles) */
const u32 tPPD = 4;
@@ -64,43 +69,45 @@ namespace ams::ldr::oc {
const double tDQSS_max = 1.25;
const double tDQS2DQ_max = 0.8;
const u32 tWR = 18;
/* TOOD: Fix erista */
namespace pcv::erista {
const double tCK_avg = 1000'000.0 / C.eristaEmcMaxClock;
/* Primary timings. */
const u32 tRCD = tRCD_values[C.t1_tRCD];
const u32 tRPpb = tRP_values[C.t2_tRP];
const u32 tRAS = tRAS_values[C.t3_tRAS];
/* Secondary timings. */
const double tRRD = tRRD_values[C.t4_tRRD];
const u32 tRFCpb = tRFC_values[C.t5_tRFC];
const u32 tWTR = tWTR_values[C.t7_tWTR];
const u32 tREFpb = tREFpb_values[C.t8_tREFI];
/* Four-bank ACTIVATE Window */
const u32 tFAW = (u32) (tRRD * 4.0);
/* Latency stuff. */
const int tR2W = (int)((3.5 / tCK_avg) + 32 + (BL / 2) - 14 - 6 + tWPRE + 12 - (C.t6_tRTW * 3));
const int tW2R = (int)((tWTR / tCK_avg) + 18 - (BL / 2));
const int tRW2PDEN = (int)((tDQSS_max / tCK_avg) + 46 + (tDQS2DQ_max / tCK_avg) + 6);
/* Refresh Cycle time. (All Banks) */
const u32 tRFCab = tRFCpb * 2;
/* ACTIVATE-to-ACTIVATE command period. (same bank) */
const u32 tRC = tRAS + tRPpb;
/* SELF REFRESH exit to next valid command delay. */
const double tXSR = (double) (tRFCab + 7.5);
/* u32ernal READ to PRECHARGE command delay. */
const int pdex2mrr = (tCK_avg * 3.0) + tRCD_values[C.t1_tRCD] + 1;
/* Row Precharge Time. (all banks) */
const u32 tRPab = tRPpb + 3;
// const double tCK_avg = 1000'000.0 / C.eristaEmcMaxClock;
//
// /* Primary timings. */
// const u32 tRCD = tRCD_values[C.t1_tRCD];
// const u32 tRPpb = tRP_values[C.t2_tRP];
// const u32 tRAS = tRAS_values[C.t3_tRAS];
//
// /* Secondary timings. */
// const double tRRD = tRRD_values[C.t4_tRRD];
// const u32 tRFCpb = tRFC_values[C.t5_tRFC];
// const u32 tWTR = tWTR_values[C.t7_tWTR];
// const u32 tREFpb = tREFpb_values[C.t8_tREFI];
//
// /* Four-bank ACTIVATE Window */
// const u32 tFAW = (u32) (tRRD * 4.0);
//
// /* Latency stuff. */
// const int tR2W = (int)((3.5 / tCK_avg) + 32 + (BL / 2) - 14 - 6 + tWPRE + 12 - (C.t6_tRTW * 3));
// const int tW2R = (int)((tWTR / tCK_avg) + 18 - (BL / 2));
// const int tRW2PDEN = (int)((tDQSS_max / tCK_avg) + 46 + (tDQS2DQ_max / tCK_avg) + 6);
//
// /* Refresh Cycle time. (All Banks) */
// const u32 tRFCab = tRFCpb * 2;
//
// /* ACTIVATE-to-ACTIVATE command period. (same bank) */
// const u32 tRC = tRAS + tRPpb;
//
// /* SELF REFRESH exit to next valid command delay. */
// const double tXSR = (double) (tRFCab + 7.5);
//
// /* u32ernal READ to PRECHARGE command delay. */
// const int pdex2mrr = (tCK_avg * 3.0) + tRCD_values[C.t1_tRCD] + 1;
//
// /* Row Precharge Time. (all banks) */
// const u32 tRPab = tRPpb + 3;
}
namespace pcv::mariko {
@@ -119,25 +126,37 @@ namespace ams::ldr::oc {
const u32 tFAW = (u32) (tRRD * 4.0);
const double tRPab = tRPpb + 3;
const double tR2P = 7.5; /* Tighten up? */
const u32 tR2W = CEIL(RL + (tDQSCK_max / tCK_avg) + (BL / 2) - WL + tWPRE + FLOOR(tRPST)); /* TODO */
const u32 tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(7.5 / tCK_avg);
const u32 tR2P = 12 + (C.mem_burst_read_latency / 2);
inline u32 tR2W;
const u32 tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(tR2P / tCK_avg);
const u32 tRATM = tRTM + CEIL(tR2P / tCK_avg) - (BL / 2);
inline u32 rdv;
inline u32 einput;
inline u32 einput_duration;
inline u32 ibdly;
inline u32 obdly;
inline u32 quse;
inline u32 quse_width;
inline u32 rext;
inline u32 qrst;
inline u32 qsafe;
inline u32 qpop;
/* Note: Dividing WL is probably incorect but it works out by pure chance :) */
const u32 tW2P = WL + (BL / 2) + 1 + CEIL(WL / tCK_avg); /* Tighten? */
const u32 tW2R = WL + (BL / 2) + 1 + CEIL(tWTR / tCK_avg);
const u32 tWTM = WL + (BL / 2) + 1 + CEIL(7.5 / tCK_avg);
const u32 tWATM = tWTM + CEIL(WL / tCK_avg);
inline u32 tW2P;
inline u32 tWTPDEN;
inline u32 tW2R;
inline u32 tWTM;
inline u32 tWATM;
const u32 wdv = 0xE + C.mem_burst_write_latency;
const u32 wsv = 0xC + C.mem_burst_write_latency;
const u32 wev = 0xA + C.mem_burst_write_latency;
inline u32 pdex2rw;
inline u32 cke2pden;
const double tMMRI = tRCD + (tCK_avg * 3);
const double tPDEX2MRR = tMMRI + 10;
const u32 tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6.0;
inline u32 obdly = 0x10000002 + wl_offset;
const u32 wdv = 0xE + wl_offset;
const u32 wsv = 0xC + wl_offset;
const u32 wev = 0xA + wl_offset;
const double pdex2mrr = tMMRI + 10; /* Do this properly? */
}
}

View File

@@ -162,7 +162,7 @@ namespace ams::ldr::oc::pcv::erista {
TABLE->shadow_regs_quse_train.PARAM = VALUE; \
TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
#define GET_CYCLE(PARAM) ((u32)((double)(PARAM) / tCK_avg))
// #define GET_CYCLE(PARAM) ((u32)((double)(PARAM) / tCK_avg))
/* This condition is insane but it's done in eos. */
/* Need to clean up at some point. */
@@ -185,284 +185,284 @@ namespace ams::ldr::oc::pcv::erista {
// wext = 25;
// }
u32 refresh_raw = 0xFFFF;
u32 trefbw = 0;
// u32 refresh_raw = 0xFFFF;
// u32 trefbw = 0;
//
// if (C.t8_tREFI != 6) {
// refresh_raw = static_cast<u32>(std::floor(static_cast<double>(tREFpb_values[C.t8_tREFI]) / tCK_avg)) - 0x40;
// refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
// }
//
// trefbw = refresh_raw + 0x40;
// trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
//
// if (C.hpMode) {
// WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
// } else {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0xF3200000);
// }
if (C.t8_tREFI != 6) {
refresh_raw = static_cast<u32>(std::floor(static_cast<double>(tREFpb_values[C.t8_tREFI]) / tCK_avg)) - 0x40;
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
}
trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
if (C.hpMode) {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
} else {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0xF3200000);
}
WRITE_PARAM_ALL_REG(table, emc_rc, /*0x00000060*/ GET_CYCLE(tRC));
WRITE_PARAM_ALL_REG(table, emc_rfc, /*0x00000120*/ GET_CYCLE(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_ras, /*0x00000044*/ GET_CYCLE(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, /*0x0000001D*/ GET_CYCLE(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_r2w, /*0x0000002A*/ tR2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, /*0x00000021*/ tW2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, 0x0000000C);
WRITE_PARAM_ALL_REG(table, emc_w2p, 0x0000002D);
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, /*0x0000001D*/ GET_CYCLE(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, /*0x0000001D*/ GET_CYCLE(tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, /*0x00000010*/ GET_CYCLE(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rext, 0x00000017);
WRITE_PARAM_ALL_REG(table, emc_wdv, 0x0000000E);
WRITE_PARAM_ALL_REG(table, emc_quse, 0x00000024);
WRITE_PARAM_ALL_REG(table, emc_qrst, 0x0006000C);
WRITE_PARAM_ALL_REG(table, emc_qsafe, 0x00000034);
WRITE_PARAM_ALL_REG(table, emc_rdv, 0x0000003C);
WRITE_PARAM_ALL_REG(table, emc_refresh, /*0x00001820*/ refresh_raw);
WRITE_PARAM_ALL_REG(table, emc_burst_refresh_num, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, 0x00000010);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, 0x00000010);
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, 0x00000003);
WRITE_PARAM_ALL_REG(table, emc_act2pden, 0x00000003);
WRITE_PARAM_ALL_REG(table, emc_ar2pden, 0x00000003);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, /*0x00000038*/ GET_CYCLE(tRW2PDEN));
WRITE_PARAM_ALL_REG(table, emc_txsr, /*0x0000012C*/ MIN(GET_CYCLE(tXSR), (u32) 1022));
WRITE_PARAM_ALL_REG(table, emc_tcke, 0x0000000D);
WRITE_PARAM_ALL_REG(table, emc_tfaw, /*0x00000040*/ GET_CYCLE(tFAW));
WRITE_PARAM_ALL_REG(table, emc_trpab, /*0x00000022*/ GET_CYCLE(tRPab));
WRITE_PARAM_ALL_REG(table, emc_tclkstable, 0x00000004);
WRITE_PARAM_ALL_REG(table, emc_tclkstop, 0x00000014);
WRITE_PARAM_ALL_REG(table, emc_trefbw, /* 0x00001860*/ trefbw);
WRITE_PARAM_ALL_REG(table, emc_tppd, 0x00000004);
WRITE_PARAM_ALL_REG(table, emc_odt_write, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, /*0x0000002E*/ GET_CYCLE(pdex2mrr));
WRITE_PARAM_ALL_REG(table, emc_wext, 0x00000016);
WRITE_PARAM_ALL_REG(table, emc_rfc_slr, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt2, 0x01900017);
WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt, 0x0640002F);
// table->emc_mrs = 0x00000000;
// table->emc_emrs = 0x00000000;
// table->emc_mrw = 0x00170040;
WRITE_PARAM_ALL_REG(table, emc_fbio_spare, 0x00000012);
WRITE_PARAM_ALL_REG(table, emc_fbio_cfg5, 0x9960A00D);
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, 0x00000002);
WRITE_PARAM_ALL_REG(table, emc_cke2pden, 0x0000000E);
// table->emc_emrs2 = 0x00000000;
// table->emc_mrw2 = 0x0802002D;
// table->emc_mrw3 = 0x0C0D00C0;
// table->emc_mrw4 = 0xC0000000;
WRITE_PARAM_ALL_REG(table, emc_r2r, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_einput, 0x00000014);
WRITE_PARAM_ALL_REG(table, emc_einput_duration, 0x0000001D);
WRITE_PARAM_ALL_REG(table, emc_puterm_extra, 0x0000001F);
WRITE_PARAM_ALL_REG(table, emc_tckesr, 0x00000018);
WRITE_PARAM_ALL_REG(table, emc_tpd, 0x0000000C);
table->emc_auto_cal_config = 0x201A51D8;
table->emc_cfg_2 = 0x00110835;
WRITE_PARAM_ALL_REG(table, emc_cfg_dig_dll, 0x002C03A9);
WRITE_PARAM_ALL_REG(table, emc_cfg_dig_dll_period, 0x00008000);
WRITE_PARAM_ALL_REG(table, emc_rdv_mask, 0x0000003E);
WRITE_PARAM_ALL_REG(table, emc_wdv_mask, 0x0000000E);
WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, 0x0000003C);
WRITE_PARAM_ALL_REG(table, emc_rdv_early, 0x0000003A);
table->emc_auto_cal_config8 = 0x00770000;
WRITE_PARAM_ALL_REG(table, emc_zcal_interval, 0x00064000);
WRITE_PARAM_ALL_REG(table, emc_zcal_wait_cnt, 0x00310640);
WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_dq, 0x8020221F);
WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_cmd, 0x0220F40F);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_brick_ctrl_fdpd, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_data_brick_ctrl_fdpd, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_brick_ctrl_rfu1, 0x1FFF1FFF);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_brick_ctrl_rfu2, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_tr_timing_0, 0x01186190);
// WRITE_PARAM_ALL_REG(table, emc_tr_ctrl_1, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_tr_rdv, 0x0000003C);
table->emc_sel_dpd_ctrl = 0x00040000;
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, /*0x00000608*/ (u32) (refresh_raw / 4));
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, 0x8000308C);
WRITE_PARAM_ALL_REG(table, emc_txsrdll, /*0x0000012C*/ MIN(GET_CYCLE(tXSR), (u32) 1022));
WRITE_PARAM_ALL_REG(table, emc_tr_qpop, 0x0000002C);
WRITE_PARAM_ALL_REG(table, emc_tr_rdv_mask, 0x0000003E);
WRITE_PARAM_ALL_REG(table, emc_tr_qsafe, 0x00000034);
WRITE_PARAM_ALL_REG(table, emc_tr_qrst, 0x0006000C);
table->emc_auto_cal_config2 = 0x05500000;
table->emc_auto_cal_config3 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_tr_dvfs, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_auto_cal_channel, 0xC1E0030A);
WRITE_PARAM_ALL_REG(table, emc_ibdly, 0x1000001C);
WRITE_PARAM_ALL_REG(table, emc_obdly, 0x10000002);
WRITE_PARAM_ALL_REG(table, emc_txdsrvttgen, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_we_duration, 0x0000000D);
WRITE_PARAM_ALL_REG(table, emc_ws_duration, 0x00000008);
WRITE_PARAM_ALL_REG(table, emc_wev, 0x0000000A);
WRITE_PARAM_ALL_REG(table, emc_wsv, 0x0000000C);
WRITE_PARAM_ALL_REG(table, emc_cfg_3, 0x00000040);
// WRITE_PARAM_ALL_REG(table, emc_mrw6, 0x08037171);
// WRITE_PARAM_ALL_REG(table, emc_mrw7, 0x48037171);
// WRITE_PARAM_ALL_REG(table, emc_mrw8, 0x080B6666);
// table->emc_mrw9 = 0x0C0E7272;
// table->emc_mrw10 = 0x880C4848;
// table->emc_mrw11 = 0x480C4848; /* Check them maybe */
// table->emc_mrw12 = 0x880E1718;
// table->emc_mrw13 = 0x480E1814;
// WRITE_PARAM_ALL_REG(table, emc_mrw14, 0x08161414);
// WRITE_PARAM_ALL_REG(table, emc_mrw15, 0x48161414);
// table->emc_fdpd_ctrl_cmd_no_ramp = 0x00000001;
WRITE_PARAM_ALL_REG(table, emc_wdv_chk, 0x00000006);
// WRITE_PARAM_ALL_REG(table, emc_cfg_pipe_2, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_cfg_pipe_1, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_cfg_pipe, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_qpop, 0x0000002C);
WRITE_PARAM_ALL_REG(table, emc_quse_width, 0x00000009);
WRITE_PARAM_ALL_REG(table, emc_puterm_width, 0x0000000E);
table->emc_auto_cal_config7 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_refctrl2, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_fbio_cfg7, 0x00003BFF);
WRITE_PARAM_ALL_REG(table, emc_rfcpb, /*0x00000090*/ GET_CYCLE(tRFCpb));
// WRITE_PARAM_ALL_REG(table, emc_dqs_brlshft_0, 0x00000000); /* brlshft may or may not be important, I don't think it matters but who knows. */
// WRITE_PARAM_ALL_REG(table, emc_dqs_brlshft_1, 0x00000000);
table->emc_auto_cal_config4 = 0x00770000;
table->emc_auto_cal_config5 = 0x00770000;
WRITE_PARAM_ALL_REG(table, emc_ccdmw, 0x00000020);
table->emc_auto_cal_config6 = 0x00770000;
WRITE_PARAM_ALL_REG(table, emc_dll_cfg_0, 0x1F13612F);
WRITE_PARAM_ALL_REG(table, emc_dll_cfg_1, 0x00000014);
WRITE_PARAM_ALL_REG(table, emc_config_sample_delay, 0x00000020);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_0, 0x10000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_1, 0x08000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_2, 0x08000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_3, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_4, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_5, 0x00001000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_bypass, 0xEFFF2210);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_0, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_1, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_2, 0xDCDCDCDC);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_0, 0x0A0A0A0A);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_1, 0x0A0A0A0A);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_2, 0x000A0A0A);
// table->trim_regs.emc_pmacro_ib_vref_dq_0 = 0x15171414;
// table->trim_regs.emc_pmacro_ib_vref_dq_1 = 0x15131513;
// table->trim_regs.emc_pmacro_ib_vref_dqs_0 = 0x11111111;
// table->trim_regs.emc_pmacro_ib_vref_dqs_1 = 0x11111111;
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_0, 0x000C000C);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_1, 0x000B000B);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_2, 0x000A000A);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_3, 0x000C000C);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_4, 0x0000000C);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_0, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_1, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_2, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_0, 0x00030808);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_1, 0x00015C00);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_bg_bias_ctrl_0, 0x00000034);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_pad_cfg_ctrl, 0x00020000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_zctrl, 0x00000550);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_pad_rx_ctrl, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_data_pad_rx_ctrl, 0x00000033);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_rx_term_mode, 0x00003000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_data_rx_term_mode, 0x00000011);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_pad_tx_ctrl, 0x02000000);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_data_pad_tx_ctrl, 0x02000101);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_common_pad_tx_ctrl, 0x00000007);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_autocal_cfg_common, 0x0000080D);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_2, 0x00102020);
// WRITE_PARAM_ALL_REG(table, emc_pmacro_ib_rxrt, 0x00000055);
WRITE_PARAM_ALL_REG(table, emc_training_ctrl, 0x00009080);
WRITE_PARAM_ALL_REG(table, emc_training_quse_cors_ctrl, 0x01124000);
WRITE_PARAM_ALL_REG(table, emc_training_quse_fine_ctrl, 0x01125B6A);
WRITE_PARAM_ALL_REG(table, emc_training_quse_ctrl_misc, 0x0F081000);
WRITE_PARAM_ALL_REG(table, emc_training_write_fine_ctrl, 0x1114FC00);
WRITE_PARAM_ALL_REG(table, emc_training_write_ctrl_misc, 0x07004300);
WRITE_PARAM_ALL_REG(table, emc_training_write_vref_ctrl, 0x00103200);
WRITE_PARAM_ALL_REG(table, emc_training_read_fine_ctrl, 0x1110FC00);
WRITE_PARAM_ALL_REG(table, emc_training_read_ctrl_misc, 0x0F085300);
WRITE_PARAM_ALL_REG(table, emc_training_read_vref_ctrl, 0x00105800);
WRITE_PARAM_ALL_REG(table, emc_training_ca_fine_ctrl, 0x0513801F);
WRITE_PARAM_ALL_REG(table, emc_training_ca_ctrl_misc, 0x1F101100);
WRITE_PARAM_ALL_REG(table, emc_training_ca_ctrl_misc1, 0x00000014);
WRITE_PARAM_ALL_REG(table, emc_training_ca_vref_ctrl, 0x00103200);
WRITE_PARAM_ALL_REG(table, emc_training_settle, 0x07070404);
// WRITE_PARAM_ALL_REG(table, emc_training_mpc, 0x00000000);
const u32 mc_tRCD = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
const u32 mc_tRPpb = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
const u32 mc_tRC = (uint) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
const u32 mc_tR2W = (uint) (((double) ((uint)tR2W >> 2) - 1.0) + 2.0);
const u32 mc_tW2R = (uint) (((double) (tW2R >> 2) - 1.0) + 2.0);
const u32 mc_tRAS = MIN(GET_CYCLE(tRAS), (u32) 0x7F);
const u32 mc_tRRD = MIN(GET_CYCLE(tRRD), (u32) 31);
table->burst_mc_regs.mc_emem_arb_timing_ras = (int) ((double) (mc_tRAS >> 2) - 2.0);
table->burst_mc_regs.mc_emem_arb_timing_rcd = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
table->burst_mc_regs.mc_emem_arb_timing_rp = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_timing_rc = (int) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
table->burst_mc_regs.mc_emem_arb_timing_faw = (int) ((double) (GET_CYCLE(tFAW) >> 2) - 1.0);
table->burst_mc_regs.mc_emem_arb_timing_rrd = (int) ((double) (mc_tRRD >> 2) - 1.0);
table->burst_mc_regs.mc_emem_arb_timing_r2w = (uint) (((double) ((uint) tR2W >> 2) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_timing_w2r = (uint) (((double) (tW2R >> 2) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_da_turns = (table->burst_mc_regs.mc_emem_arb_da_turns & 0x0000FFFF) | (mc_tW2R << 24) | (mc_tR2W << 16);
table->burst_mc_regs.mc_emem_arb_da_covers = (((uint) (mc_tRCD + 3 + mc_tRPpb) >> 1 & 0xff) << 8) | (((uint) (mc_tRCD + 11 + mc_tRPpb) >> 1 & 0xff) << 0x10) | ((mc_tRC >> 1) & 0xff);
table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xffe08000U) | ((mc_tRC + 1) & 0xff); /* Missing in l4t dump? TODO */
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
table->burst_mc_regs.mc_emem_arb_cfg = 0x0000000c;
// table->burst_mc_regs.mc_emem_arb_timing_rcd = 0x00000006;
// table->burst_mc_regs.mc_emem_arb_timing_rp = 0x00000007;
// table->burst_mc_regs.mc_emem_arb_timing_rc = 0x00000018;
// table->burst_mc_regs.mc_emem_arb_timing_ras = 0x0000000f;
// table->burst_mc_regs.mc_emem_arb_timing_faw = 0x0000000f;
// table->burst_mc_regs.mc_emem_arb_timing_rrd = 0x00000003;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 0x00000003;
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 0x0000000d;
table->burst_mc_regs.mc_emem_arb_timing_r2r = 0x00000007;
table->burst_mc_regs.mc_emem_arb_timing_w2w = 0x00000007;
// table->burst_mc_regs.mc_emem_arb_timing_r2w = 0x0000000c;
// table->burst_mc_regs.mc_emem_arb_timing_w2r = 0x0000000a;
// table->burst_mc_regs.mc_emem_arb_da_turns = 0x05060303;
// table->burst_mc_regs.mc_emem_arb_da_covers = 0x000d080c;
table->burst_mc_regs.mc_emem_arb_ring1_throttle = 0x001f0000;
// table->burst_mc_regs.mc_emem_arb_timing_rfcpb = 0x00000023;
table->burst_mc_regs.mc_emem_arb_timing_ccdmw = 0x00000008;
table->burst_mc_regs.mc_emem_arb_refpb_hp_ctrl = 0x000a1020;
table->burst_mc_regs.mc_emem_arb_refpb_bank_ctrl = 0x80001028;
// table->burst_mc_regs.mc_emem_arb_dhyst_ctrl = 0x00000002;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_0 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_1 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_2 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_3 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_4 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_5 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_6 = 0x0000001a;
table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_7 = 0x0000001a;
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x000000d0;
table->la_scale_regs.mc_ftop_ptsa_rate = 0x00000018;
table->la_scale_regs.mc_ptsa_grant_decrement = 0x00001203;
table->la_scale_regs.mc_latency_allowance_avpc_0 = 0x00800004;
table->la_scale_regs.mc_latency_allowance_xusb_1 = 0x00800038;
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = 0x00800005;
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = 0x00800014;
table->la_scale_regs.mc_latency_allowance_isp2_0 = 0x0000002c;
table->la_scale_regs.mc_latency_allowance_isp2_1 = 0x00800080;
table->la_scale_regs.mc_latency_allowance_vic_0 = 0x0080001d;
table->la_scale_regs.mc_latency_allowance_nvdec_0 = 0x00800095;
table->la_scale_regs.mc_latency_allowance_tsec_0 = 0x00800041;
table->la_scale_regs.mc_latency_allowance_ppcs_1 = 0x00800080;
table->la_scale_regs.mc_latency_allowance_xusb_0 = 0x0080003d;
table->la_scale_regs.mc_latency_allowance_ppcs_0 = 0x00340049;
table->la_scale_regs.mc_latency_allowance_gpu2_0 = 0x00800019;
table->la_scale_regs.mc_latency_allowance_hc_1 = 0x00000080;
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = 0x00800090;
table->la_scale_regs.mc_latency_allowance_mpcore_0 = 0x00800004;
table->la_scale_regs.mc_latency_allowance_vi2_0 = 0x00000080;
table->la_scale_regs.mc_latency_allowance_hc_0 = 0x00080016;
table->la_scale_regs.mc_latency_allowance_gpu_0 = 0x00800019;
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = 0x00800005;
table->la_scale_regs.mc_latency_allowance_nvenc_0 = 0x00800018;
table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab;
// WRITE_PARAM_ALL_REG(table, emc_rc, /*0x00000060*/ GET_CYCLE(tRC));
// WRITE_PARAM_ALL_REG(table, emc_rfc, /*0x00000120*/ GET_CYCLE(tRFCab));
// WRITE_PARAM_ALL_REG(table, emc_ras, /*0x00000044*/ GET_CYCLE(tRAS));
// WRITE_PARAM_ALL_REG(table, emc_rp, /*0x0000001D*/ GET_CYCLE(tRPpb));
// WRITE_PARAM_ALL_REG(table, emc_r2w, /*0x0000002A*/ tR2W);
// WRITE_PARAM_ALL_REG(table, emc_w2r, /*0x00000021*/ tW2R);
// WRITE_PARAM_ALL_REG(table, emc_r2p, 0x0000000C);
// WRITE_PARAM_ALL_REG(table, emc_w2p, 0x0000002D);
// WRITE_PARAM_ALL_REG(table, emc_rd_rcd, /*0x0000001D*/ GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_wr_rcd, /*0x0000001D*/ GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_rrd, /*0x00000010*/ GET_CYCLE(tRRD));
// WRITE_PARAM_ALL_REG(table, emc_rext, 0x00000017);
// WRITE_PARAM_ALL_REG(table, emc_wdv, 0x0000000E);
// WRITE_PARAM_ALL_REG(table, emc_quse, 0x00000024);
// WRITE_PARAM_ALL_REG(table, emc_qrst, 0x0006000C);
// WRITE_PARAM_ALL_REG(table, emc_qsafe, 0x00000034);
// WRITE_PARAM_ALL_REG(table, emc_rdv, 0x0000003C);
// WRITE_PARAM_ALL_REG(table, emc_refresh, /*0x00001820*/ refresh_raw);
// WRITE_PARAM_ALL_REG(table, emc_burst_refresh_num, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pdex2wr, 0x00000010);
// WRITE_PARAM_ALL_REG(table, emc_pdex2rd, 0x00000010);
// WRITE_PARAM_ALL_REG(table, emc_pchg2pden, 0x00000003);
// WRITE_PARAM_ALL_REG(table, emc_act2pden, 0x00000003);
// WRITE_PARAM_ALL_REG(table, emc_ar2pden, 0x00000003);
// WRITE_PARAM_ALL_REG(table, emc_rw2pden, /*0x00000038*/ GET_CYCLE(tRW2PDEN));
// WRITE_PARAM_ALL_REG(table, emc_txsr, /*0x0000012C*/ MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_tcke, 0x0000000D);
// WRITE_PARAM_ALL_REG(table, emc_tfaw, /*0x00000040*/ GET_CYCLE(tFAW));
// WRITE_PARAM_ALL_REG(table, emc_trpab, /*0x00000022*/ GET_CYCLE(tRPab));
// WRITE_PARAM_ALL_REG(table, emc_tclkstable, 0x00000004);
// WRITE_PARAM_ALL_REG(table, emc_tclkstop, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_trefbw, /* 0x00001860*/ trefbw);
// WRITE_PARAM_ALL_REG(table, emc_tppd, 0x00000004);
// WRITE_PARAM_ALL_REG(table, emc_odt_write, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, /*0x0000002E*/ GET_CYCLE(pdex2mrr));
// WRITE_PARAM_ALL_REG(table, emc_wext, 0x00000016);
// WRITE_PARAM_ALL_REG(table, emc_rfc_slr, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt2, 0x01900017);
// WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt, 0x0640002F);
// // table->emc_mrs = 0x00000000;
// // table->emc_emrs = 0x00000000;
// // table->emc_mrw = 0x00170040;
// WRITE_PARAM_ALL_REG(table, emc_fbio_spare, 0x00000012);
// WRITE_PARAM_ALL_REG(table, emc_fbio_cfg5, 0x9960A00D);
// WRITE_PARAM_ALL_REG(table, emc_pdex2cke, 0x00000002);
// WRITE_PARAM_ALL_REG(table, emc_cke2pden, 0x0000000E);
// // table->emc_emrs2 = 0x00000000;
// // table->emc_mrw2 = 0x0802002D;
// // table->emc_mrw3 = 0x0C0D00C0;
// // table->emc_mrw4 = 0xC0000000;
// WRITE_PARAM_ALL_REG(table, emc_r2r, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_einput, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_einput_duration, 0x0000001D);
// WRITE_PARAM_ALL_REG(table, emc_puterm_extra, 0x0000001F);
// WRITE_PARAM_ALL_REG(table, emc_tckesr, 0x00000018);
// WRITE_PARAM_ALL_REG(table, emc_tpd, 0x0000000C);
// table->emc_auto_cal_config = 0x201A51D8;
// table->emc_cfg_2 = 0x00110835;
// WRITE_PARAM_ALL_REG(table, emc_cfg_dig_dll, 0x002C03A9);
// WRITE_PARAM_ALL_REG(table, emc_cfg_dig_dll_period, 0x00008000);
// WRITE_PARAM_ALL_REG(table, emc_rdv_mask, 0x0000003E);
// WRITE_PARAM_ALL_REG(table, emc_wdv_mask, 0x0000000E);
// WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, 0x0000003C);
// WRITE_PARAM_ALL_REG(table, emc_rdv_early, 0x0000003A);
// table->emc_auto_cal_config8 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_zcal_interval, 0x00064000);
// WRITE_PARAM_ALL_REG(table, emc_zcal_wait_cnt, 0x00310640);
// WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_dq, 0x8020221F);
// WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_cmd, 0x0220F40F);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_brick_ctrl_fdpd, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_brick_ctrl_fdpd, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_brick_ctrl_rfu1, 0x1FFF1FFF);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_brick_ctrl_rfu2, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_tr_timing_0, 0x01186190);
// // WRITE_PARAM_ALL_REG(table, emc_tr_ctrl_1, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv, 0x0000003C);
// table->emc_sel_dpd_ctrl = 0x00040000;
// WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, /*0x00000608*/ (u32) (refresh_raw / 4));
// WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, 0x8000308C);
// WRITE_PARAM_ALL_REG(table, emc_txsrdll, /*0x0000012C*/ MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_tr_qpop, 0x0000002C);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv_mask, 0x0000003E);
// WRITE_PARAM_ALL_REG(table, emc_tr_qsafe, 0x00000034);
// WRITE_PARAM_ALL_REG(table, emc_tr_qrst, 0x0006000C);
// table->emc_auto_cal_config2 = 0x05500000;
// table->emc_auto_cal_config3 = 0x00770000;
// // WRITE_PARAM_ALL_REG(table, emc_tr_dvfs, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_auto_cal_channel, 0xC1E0030A);
// WRITE_PARAM_ALL_REG(table, emc_ibdly, 0x1000001C);
// WRITE_PARAM_ALL_REG(table, emc_obdly, 0x10000002);
// WRITE_PARAM_ALL_REG(table, emc_txdsrvttgen, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_we_duration, 0x0000000D);
// WRITE_PARAM_ALL_REG(table, emc_ws_duration, 0x00000008);
// WRITE_PARAM_ALL_REG(table, emc_wev, 0x0000000A);
// WRITE_PARAM_ALL_REG(table, emc_wsv, 0x0000000C);
// WRITE_PARAM_ALL_REG(table, emc_cfg_3, 0x00000040);
// // WRITE_PARAM_ALL_REG(table, emc_mrw6, 0x08037171);
// // WRITE_PARAM_ALL_REG(table, emc_mrw7, 0x48037171);
// // WRITE_PARAM_ALL_REG(table, emc_mrw8, 0x080B6666);
// // table->emc_mrw9 = 0x0C0E7272;
// // table->emc_mrw10 = 0x880C4848;
// // table->emc_mrw11 = 0x480C4848; /* Check them maybe */
// // table->emc_mrw12 = 0x880E1718;
// // table->emc_mrw13 = 0x480E1814;
// // WRITE_PARAM_ALL_REG(table, emc_mrw14, 0x08161414);
// // WRITE_PARAM_ALL_REG(table, emc_mrw15, 0x48161414);
// // table->emc_fdpd_ctrl_cmd_no_ramp = 0x00000001;
// WRITE_PARAM_ALL_REG(table, emc_wdv_chk, 0x00000006);
// // WRITE_PARAM_ALL_REG(table, emc_cfg_pipe_2, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_cfg_pipe_1, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_cfg_pipe, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_qpop, 0x0000002C);
// WRITE_PARAM_ALL_REG(table, emc_quse_width, 0x00000009);
// WRITE_PARAM_ALL_REG(table, emc_puterm_width, 0x0000000E);
// table->emc_auto_cal_config7 = 0x00770000;
// // WRITE_PARAM_ALL_REG(table, emc_refctrl2, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_fbio_cfg7, 0x00003BFF);
// WRITE_PARAM_ALL_REG(table, emc_rfcpb, /*0x00000090*/ GET_CYCLE(tRFCpb));
// // WRITE_PARAM_ALL_REG(table, emc_dqs_brlshft_0, 0x00000000); /* brlshft may or may not be important, I don't think it matters but who knows. */
// // WRITE_PARAM_ALL_REG(table, emc_dqs_brlshft_1, 0x00000000);
// table->emc_auto_cal_config4 = 0x00770000;
// table->emc_auto_cal_config5 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_ccdmw, 0x00000020);
// table->emc_auto_cal_config6 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_dll_cfg_0, 0x1F13612F);
// WRITE_PARAM_ALL_REG(table, emc_dll_cfg_1, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_config_sample_delay, 0x00000020);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_0, 0x10000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_1, 0x08000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_2, 0x08000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_3, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_4, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_5, 0x00001000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_bypass, 0xEFFF2210);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_0, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_1, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_2, 0xDCDCDCDC);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_0, 0x0A0A0A0A);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_1, 0x0A0A0A0A);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_2, 0x000A0A0A);
// // table->trim_regs.emc_pmacro_ib_vref_dq_0 = 0x15171414;
// // table->trim_regs.emc_pmacro_ib_vref_dq_1 = 0x15131513;
// // table->trim_regs.emc_pmacro_ib_vref_dqs_0 = 0x11111111;
// // table->trim_regs.emc_pmacro_ib_vref_dqs_1 = 0x11111111;
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_0, 0x000C000C);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_1, 0x000B000B);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_2, 0x000A000A);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_3, 0x000C000C);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_4, 0x0000000C);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_0, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_1, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_2, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_0, 0x00030808);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_1, 0x00015C00);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_bg_bias_ctrl_0, 0x00000034);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_pad_cfg_ctrl, 0x00020000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_zctrl, 0x00000550);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_pad_rx_ctrl, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_pad_rx_ctrl, 0x00000033);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_rx_term_mode, 0x00003000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_rx_term_mode, 0x00000011);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_pad_tx_ctrl, 0x02000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_pad_tx_ctrl, 0x02000101);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_common_pad_tx_ctrl, 0x00000007);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_autocal_cfg_common, 0x0000080D);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_2, 0x00102020);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ib_rxrt, 0x00000055);
// WRITE_PARAM_ALL_REG(table, emc_training_ctrl, 0x00009080);
// WRITE_PARAM_ALL_REG(table, emc_training_quse_cors_ctrl, 0x01124000);
// WRITE_PARAM_ALL_REG(table, emc_training_quse_fine_ctrl, 0x01125B6A);
// WRITE_PARAM_ALL_REG(table, emc_training_quse_ctrl_misc, 0x0F081000);
// WRITE_PARAM_ALL_REG(table, emc_training_write_fine_ctrl, 0x1114FC00);
// WRITE_PARAM_ALL_REG(table, emc_training_write_ctrl_misc, 0x07004300);
// WRITE_PARAM_ALL_REG(table, emc_training_write_vref_ctrl, 0x00103200);
// WRITE_PARAM_ALL_REG(table, emc_training_read_fine_ctrl, 0x1110FC00);
// WRITE_PARAM_ALL_REG(table, emc_training_read_ctrl_misc, 0x0F085300);
// WRITE_PARAM_ALL_REG(table, emc_training_read_vref_ctrl, 0x00105800);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_fine_ctrl, 0x0513801F);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_ctrl_misc, 0x1F101100);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_ctrl_misc1, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_vref_ctrl, 0x00103200);
// WRITE_PARAM_ALL_REG(table, emc_training_settle, 0x07070404);
// // WRITE_PARAM_ALL_REG(table, emc_training_mpc, 0x00000000);
//
// const u32 mc_tRCD = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
// const u32 mc_tRPpb = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// const u32 mc_tRC = (uint) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
// const u32 mc_tR2W = (uint) (((double) ((uint)tR2W >> 2) - 1.0) + 2.0);
// const u32 mc_tW2R = (uint) (((double) (tW2R >> 2) - 1.0) + 2.0);
// const u32 mc_tRAS = MIN(GET_CYCLE(tRAS), (u32) 0x7F);
// const u32 mc_tRRD = MIN(GET_CYCLE(tRRD), (u32) 31);
//
// table->burst_mc_regs.mc_emem_arb_timing_ras = (int) ((double) (mc_tRAS >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rcd = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rp = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rc = (int) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_faw = (int) ((double) (GET_CYCLE(tFAW) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_rrd = (int) ((double) (mc_tRRD >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_r2w = (uint) (((double) ((uint) tR2W >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2r = (uint) (((double) (tW2R >> 2) - 1.0) + 2.0);
//
// table->burst_mc_regs.mc_emem_arb_da_turns = (table->burst_mc_regs.mc_emem_arb_da_turns & 0x0000FFFF) | (mc_tW2R << 24) | (mc_tR2W << 16);
// table->burst_mc_regs.mc_emem_arb_da_covers = (((uint) (mc_tRCD + 3 + mc_tRPpb) >> 1 & 0xff) << 8) | (((uint) (mc_tRCD + 11 + mc_tRPpb) >> 1 & 0xff) << 0x10) | ((mc_tRC >> 1) & 0xff);
// table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xffe08000U) | ((mc_tRC + 1) & 0xff); /* Missing in l4t dump? TODO */
// table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
//
// table->burst_mc_regs.mc_emem_arb_cfg = 0x0000000c;
// // table->burst_mc_regs.mc_emem_arb_timing_rcd = 0x00000006;
// // table->burst_mc_regs.mc_emem_arb_timing_rp = 0x00000007;
// // table->burst_mc_regs.mc_emem_arb_timing_rc = 0x00000018;
// // table->burst_mc_regs.mc_emem_arb_timing_ras = 0x0000000f;
// // table->burst_mc_regs.mc_emem_arb_timing_faw = 0x0000000f;
// // table->burst_mc_regs.mc_emem_arb_timing_rrd = 0x00000003;
// table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 0x00000003;
// table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 0x0000000d;
// table->burst_mc_regs.mc_emem_arb_timing_r2r = 0x00000007;
// table->burst_mc_regs.mc_emem_arb_timing_w2w = 0x00000007;
// // table->burst_mc_regs.mc_emem_arb_timing_r2w = 0x0000000c;
// // table->burst_mc_regs.mc_emem_arb_timing_w2r = 0x0000000a;
// // table->burst_mc_regs.mc_emem_arb_da_turns = 0x05060303;
// // table->burst_mc_regs.mc_emem_arb_da_covers = 0x000d080c;
// table->burst_mc_regs.mc_emem_arb_ring1_throttle = 0x001f0000;
// // table->burst_mc_regs.mc_emem_arb_timing_rfcpb = 0x00000023;
// table->burst_mc_regs.mc_emem_arb_timing_ccdmw = 0x00000008;
// table->burst_mc_regs.mc_emem_arb_refpb_hp_ctrl = 0x000a1020;
// table->burst_mc_regs.mc_emem_arb_refpb_bank_ctrl = 0x80001028;
// // table->burst_mc_regs.mc_emem_arb_dhyst_ctrl = 0x00000002;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_0 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_1 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_2 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_3 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_4 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_5 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_6 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_7 = 0x0000001a;
// table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x000000d0;
// table->la_scale_regs.mc_ftop_ptsa_rate = 0x00000018;
// table->la_scale_regs.mc_ptsa_grant_decrement = 0x00001203;
// table->la_scale_regs.mc_latency_allowance_avpc_0 = 0x00800004;
// table->la_scale_regs.mc_latency_allowance_xusb_1 = 0x00800038;
// table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = 0x00800005;
// table->la_scale_regs.mc_latency_allowance_sdmmca_0 = 0x00800014;
// table->la_scale_regs.mc_latency_allowance_isp2_0 = 0x0000002c;
// table->la_scale_regs.mc_latency_allowance_isp2_1 = 0x00800080;
// table->la_scale_regs.mc_latency_allowance_vic_0 = 0x0080001d;
// table->la_scale_regs.mc_latency_allowance_nvdec_0 = 0x00800095;
// table->la_scale_regs.mc_latency_allowance_tsec_0 = 0x00800041;
// table->la_scale_regs.mc_latency_allowance_ppcs_1 = 0x00800080;
// table->la_scale_regs.mc_latency_allowance_xusb_0 = 0x0080003d;
// table->la_scale_regs.mc_latency_allowance_ppcs_0 = 0x00340049;
// table->la_scale_regs.mc_latency_allowance_gpu2_0 = 0x00800019;
// table->la_scale_regs.mc_latency_allowance_hc_1 = 0x00000080;
// table->la_scale_regs.mc_latency_allowance_sdmmc_0 = 0x00800090;
// table->la_scale_regs.mc_latency_allowance_mpcore_0 = 0x00800004;
// table->la_scale_regs.mc_latency_allowance_vi2_0 = 0x00000080;
// table->la_scale_regs.mc_latency_allowance_hc_0 = 0x00080016;
// table->la_scale_regs.mc_latency_allowance_gpu_0 = 0x00800019;
// table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = 0x00800005;
// table->la_scale_regs.mc_latency_allowance_nvenc_0 = 0x00800018;
// table->dram_timings.t_rp = tRFCpb;
// table->dram_timings.t_rfc = tRFCab;
}
/* These timings are slightly off from eos, I am not sure why but I am going to figure it out at some point. */
@@ -470,203 +470,203 @@ namespace ams::ldr::oc::pcv::erista {
if (C.mtcConf != AUTO_ADJ) /* Return even needed? */
return;
using namespace pcv::erista;
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
TABLE->shadow_regs_quse_train.PARAM = VALUE; \
TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
#define GET_CYCLE(PARAM) ((u32)((double)(PARAM) / tCK_avg))
/* This condition is insane but it's done in eos. */
/* Need to clean up at some point. */
u32 rext;
u32 wext;
if (C.eristaEmcMaxClock < 3200001) {
if (C.eristaEmcMaxClock < 2133001) {
rext = 26;
wext = 22;
} else {
rext = 28;
wext = 22;
if (2400000 < C.eristaEmcMaxClock) {
wext = 25;
}
}
} else {
rext = 30;
wext = 25;
}
u32 refresh_raw = 0xFFFF;
u32 trefbw = 0;
if (C.t8_tREFI != 6) {
refresh_raw = static_cast<u32>(std::floor(static_cast<double>(tREFpb_values[C.t8_tREFI]) / tCK_avg)) - 0x40;
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
}
trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
/* Primary timings. */
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE(tRCD));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE(tRPpb));
/* Secondary timings. */
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, (u32) 0xC);
WRITE_PARAM_ALL_REG(table, emc_w2p, (u32) 0x2D);
WRITE_PARAM_ALL_REG(table, emc_rext, rext);
WRITE_PARAM_ALL_REG(table, emc_wext, wext);
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE(tRPab));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE(tFAW));
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE(tRC));
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE(tSR));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE(tXP) + 1);
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE(tXP));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE(tXP) + 8);
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE(tXSR), (u32) 1022));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE(tXSR), (u32) 1022));
const u32 dyn_self_ref_control = (((u32)(7605.0 / tCK_avg)) + 260U) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000U);
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tRW2PDEN);
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));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE(pdex2mrr));
WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, (u32) (refresh_raw / 4));
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
const u32 mc_tRCD = (int)((double)(GET_CYCLE(tRCD) >> 2) - 2.0);
const u32 mc_tRPpb = (int)(((double)(GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
const u32 mc_tRC = (uint)((double)(GET_CYCLE(tRC) >> 2) - 1.0);
const u32 mc_tR2W = (uint)(((double)((uint)tR2W >> 2) - 1.0) + 2.0);
const u32 mc_tW2R = (uint)(((double)(tW2R >> 2) - 1.0) + 2.0);
const u32 mc_tRAS = MIN(GET_CYCLE(tRAS), (u32) 0x7F);
const u32 mc_tRRD = MIN(GET_CYCLE(tRRD), (u32) 31);
table->burst_mc_regs.mc_emem_arb_cfg = (int)(((double) C.eristaEmcMaxClock / 33300.0) * 0.25);
table->burst_mc_regs.mc_emem_arb_timing_ras = (int) ((double) (mc_tRAS >> 2) - 2.0);
table->burst_mc_regs.mc_emem_arb_timing_rcd = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
table->burst_mc_regs.mc_emem_arb_timing_rp = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_timing_rc = (int) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
table->burst_mc_regs.mc_emem_arb_timing_faw = (int) ((double)(GET_CYCLE(tFAW) >> 2) - 1.0);
table->burst_mc_regs.mc_emem_arb_timing_rrd = (int)((double)(mc_tRRD >> 2) - 1.0);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 3;
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 11;
table->burst_mc_regs.mc_emem_arb_timing_r2w = (uint)(((double)((uint)tR2W >> 2) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_timing_w2r = (uint)(((double)(tW2R >> 2) - 1.0) + 2.0);
u32 mc_r2r = table->burst_mc_regs.mc_emem_arb_timing_r2r;
if (mc_r2r > 1) {
mc_r2r = (uint)(((double)(long)((double)rext * 0.25) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_timing_r2r = mc_r2r;
}
u32 mc_w2w = table->burst_mc_regs.mc_emem_arb_timing_w2w;
if (mc_w2w > 1) {
mc_w2w = (uint)(((double)(long)((double)wext / 4.0) - 1.0) + 2.0);
table->burst_mc_regs.mc_emem_arb_timing_w2w = mc_w2w;
}
table->burst_mc_regs.mc_emem_arb_da_turns = ((mc_tW2R >> 1) << 0x18) | ((mc_tR2W >> 1) << 0x10) | ((mc_r2r >> 1) << 8) | ((mc_w2w >> 1));
table->burst_mc_regs.mc_emem_arb_da_covers = (((uint)(mc_tRCD + 3 + mc_tRPpb) >> 1 & 0xff) << 8) | (((uint)(mc_tRCD + 11 + mc_tRPpb) >> 1 & 0xff) << 0x10) | ((mc_tRC >> 1) & 0xff);
table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xffe08000U) | ((mc_tRC + 1) & 0xff);
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0xd0U), (u32)0x115);
table->la_scale_regs.mc_ftop_ptsa_rate = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0x18U), (u32)0x1f);
table->la_scale_regs.mc_ptsa_grant_decrement = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0x1203U), (u32)0x17ff);
u32 mc_latency_allowance = 0;
if (C.eristaEmcMaxClock / 1000 != 0) {
mc_latency_allowance = 204800 / (C.eristaEmcMaxClock / 1000);
}
const u32 mc_latency_allowance2 = mc_latency_allowance & 0xFF;
const u32 mc_latency_allowance3 = (mc_latency_allowance & 0xFF) << 0x10;
table->la_scale_regs.mc_latency_allowance_xusb_0 = (table->la_scale_regs.mc_latency_allowance_xusb_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & 0xff00ffffU) | mc_latency_allowance3;
u32 mc_latency_allowance_hc_0 = 0;
if (C.eristaEmcMaxClock / 1000 != 0) {
mc_latency_allowance_hc_0 = 35200 / (C.eristaEmcMaxClock / 1000);
}
table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & 0xff00ffffU) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & 0xffffff00U) | mc_latency_allowance_hc_0;
table->la_scale_regs.mc_latency_allowance_isp2_1 = (table->la_scale_regs.mc_latency_allowance_isp2_1 & 0xff00ff00U) | mc_latency_allowance3 | mc_latency_allowance2;
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & 0xffffff00U) | mc_latency_allowance2;
u32 mc_latency_allowance_gpu_0 = 0;
if (C.eristaEmcMaxClock / 1000 != 0) {
mc_latency_allowance_gpu_0 = 40000 / (C.eristaEmcMaxClock / 1000);
}
table->la_scale_regs.mc_latency_allowance_gpu_0 = ((mc_latency_allowance_gpu_0 | table->la_scale_regs.mc_latency_allowance_gpu_0) & 0xff00ff00U) | mc_latency_allowance3;
u32 mc_latency_allowance_gpu2_0 = 0;
if (C.eristaEmcMaxClock / 1000 != 0) {
mc_latency_allowance_gpu2_0 = 40000 / (C.eristaEmcMaxClock / 1000);
}
table->la_scale_regs.mc_latency_allowance_gpu2_0 = ((mc_latency_allowance_gpu2_0 | table->la_scale_regs.mc_latency_allowance_gpu2_0) & 0xff00ff00U) | mc_latency_allowance3;
u32 mc_latency_allowance_nvenc_0 = 0;
if (C.eristaEmcMaxClock / 1000 != 0) {
mc_latency_allowance_nvenc_0 = 38400 / (C.eristaEmcMaxClock / 1000);
}
table->la_scale_regs.mc_latency_allowance_nvenc_0 = ((mc_latency_allowance_nvenc_0 | table->la_scale_regs.mc_latency_allowance_nvenc_0) & 0xff00ff00U) | mc_latency_allowance3;
u32 mc_latency_allowance_vic_0 = 0;
if (C.eristaEmcMaxClock / 1000 != 0) {
mc_latency_allowance_vic_0 = 0xb540 / (C.eristaEmcMaxClock / 1000);
}
table->la_scale_regs.mc_latency_allowance_vic_0 = ((mc_latency_allowance_vic_0 | table->la_scale_regs.mc_latency_allowance_vic_0) & 0xff00ff00U) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & 0xffffff00U) | mc_latency_allowance2;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
if (C.hpMode) {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
}
table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab;
table->emc_cfg_2 = 0x11083d;
#undef GET_CYCLE
// using namespace pcv::erista;
//
// #define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
// TABLE->burst_regs.PARAM = VALUE; \
// TABLE->shadow_regs_ca_train.PARAM = VALUE; \
// TABLE->shadow_regs_quse_train.PARAM = VALUE; \
// TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
//
#define GET_CYCLE(PARAM) ((u32)((double)(PARAM) / (1000000.0 / 1600000.0)))
//
// /* This condition is insane but it's done in eos. */
// /* Need to clean up at some point. */
// u32 rext;
// u32 wext;
// if (C.eristaEmcMaxClock < 3200001) {
// if (C.eristaEmcMaxClock < 2133001) {
// rext = 26;
// wext = 22;
// } else {
// rext = 28;
// wext = 22;
//
// if (2400000 < C.eristaEmcMaxClock) {
// wext = 25;
// }
// }
// } else {
// rext = 30;
// wext = 25;
// }
//
// u32 refresh_raw = 0xFFFF;
// u32 trefbw = 0;
//
// if (C.t8_tREFI != 6) {
// refresh_raw = static_cast<u32>(std::floor(static_cast<double>(tREFpb_values[C.t8_tREFI]) / tCK_avg)) - 0x40;
// refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
// }
//
// trefbw = refresh_raw + 0x40;
// trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
//
// /* Primary timings. */
// WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE(tRAS));
// WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE(tRPpb));
//
// /* Secondary timings. */
// WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE(tRRD));
// WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE(tRFCab));
// WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE(tRFCpb));
// WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
// WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
// WRITE_PARAM_ALL_REG(table, emc_r2p, (u32) 0xC);
// WRITE_PARAM_ALL_REG(table, emc_w2p, (u32) 0x2D);
//
// WRITE_PARAM_ALL_REG(table, emc_rext, rext);
// WRITE_PARAM_ALL_REG(table, emc_wext, wext);
//
// WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE(tRPab));
// WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE(tFAW));
// WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE(tRC));
//
// WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE(tSR));
// WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE(tXP) + 1);
// WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE(tXP));
// WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE(tXP) + 8);
//
// WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE(tXSR), (u32) 1022));
//
// const u32 dyn_self_ref_control = (((u32)(7605.0 / tCK_avg)) + 260U) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000U);
// WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
//
// WRITE_PARAM_ALL_REG(table, emc_rw2pden, tRW2PDEN);
// 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));
// WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE(pdex2mrr));
//
// WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
// WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, (u32) (refresh_raw / 4));
// WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
//
// const u32 mc_tRCD = (int)((double)(GET_CYCLE(tRCD) >> 2) - 2.0);
// const u32 mc_tRPpb = (int)(((double)(GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// const u32 mc_tRC = (uint)((double)(GET_CYCLE(tRC) >> 2) - 1.0);
// const u32 mc_tR2W = (uint)(((double)((uint)tR2W >> 2) - 1.0) + 2.0);
// const u32 mc_tW2R = (uint)(((double)(tW2R >> 2) - 1.0) + 2.0);
// const u32 mc_tRAS = MIN(GET_CYCLE(tRAS), (u32) 0x7F);
// const u32 mc_tRRD = MIN(GET_CYCLE(tRRD), (u32) 31);
//
// table->burst_mc_regs.mc_emem_arb_cfg = (int)(((double) C.eristaEmcMaxClock / 33300.0) * 0.25);
// table->burst_mc_regs.mc_emem_arb_timing_ras = (int) ((double) (mc_tRAS >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rcd = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rp = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rc = (int) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_faw = (int) ((double)(GET_CYCLE(tFAW) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_rrd = (int)((double)(mc_tRRD >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 3;
// table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 11;
// table->burst_mc_regs.mc_emem_arb_timing_r2w = (uint)(((double)((uint)tR2W >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2r = (uint)(((double)(tW2R >> 2) - 1.0) + 2.0);
//
// u32 mc_r2r = table->burst_mc_regs.mc_emem_arb_timing_r2r;
// if (mc_r2r > 1) {
// mc_r2r = (uint)(((double)(long)((double)rext * 0.25) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_r2r = mc_r2r;
// }
//
// u32 mc_w2w = table->burst_mc_regs.mc_emem_arb_timing_w2w;
// if (mc_w2w > 1) {
// mc_w2w = (uint)(((double)(long)((double)wext / 4.0) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2w = mc_w2w;
// }
//
// table->burst_mc_regs.mc_emem_arb_da_turns = ((mc_tW2R >> 1) << 0x18) | ((mc_tR2W >> 1) << 0x10) | ((mc_r2r >> 1) << 8) | ((mc_w2w >> 1));
// table->burst_mc_regs.mc_emem_arb_da_covers = (((uint)(mc_tRCD + 3 + mc_tRPpb) >> 1 & 0xff) << 8) | (((uint)(mc_tRCD + 11 + mc_tRPpb) >> 1 & 0xff) << 0x10) | ((mc_tRC >> 1) & 0xff);
// table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xffe08000U) | ((mc_tRC + 1) & 0xff);
// table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0xd0U), (u32)0x115);
// table->la_scale_regs.mc_ftop_ptsa_rate = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0x18U), (u32)0x1f);
// table->la_scale_regs.mc_ptsa_grant_decrement = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0x1203U), (u32)0x17ff);
//
// u32 mc_latency_allowance = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance = 204800 / (C.eristaEmcMaxClock / 1000);
// }
//
// const u32 mc_latency_allowance2 = mc_latency_allowance & 0xFF;
// const u32 mc_latency_allowance3 = (mc_latency_allowance & 0xFF) << 0x10;
// table->la_scale_regs.mc_latency_allowance_xusb_0 = (table->la_scale_regs.mc_latency_allowance_xusb_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & 0xff00ffffU) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_hc_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_hc_0 = 35200 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & 0xffffff00U) | mc_latency_allowance_hc_0;
//
// table->la_scale_regs.mc_latency_allowance_isp2_1 = (table->la_scale_regs.mc_latency_allowance_isp2_1 & 0xff00ff00U) | mc_latency_allowance3 | mc_latency_allowance2;
// table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & 0xffffff00U) | mc_latency_allowance2;
//
// u32 mc_latency_allowance_gpu_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_gpu_0 = 40000 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_gpu_0 = ((mc_latency_allowance_gpu_0 | table->la_scale_regs.mc_latency_allowance_gpu_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_gpu2_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_gpu2_0 = 40000 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_gpu2_0 = ((mc_latency_allowance_gpu2_0 | table->la_scale_regs.mc_latency_allowance_gpu2_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_nvenc_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_nvenc_0 = 38400 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_nvenc_0 = ((mc_latency_allowance_nvenc_0 | table->la_scale_regs.mc_latency_allowance_nvenc_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_vic_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_vic_0 = 0xb540 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_vic_0 = ((mc_latency_allowance_vic_0 | table->la_scale_regs.mc_latency_allowance_vic_0) & 0xff00ff00U) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & 0xffffff00U) | mc_latency_allowance2;
//
// table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
//
// if (C.hpMode) {
// WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
// }
//
// table->dram_timings.t_rp = tRFCpb;
// table->dram_timings.t_rfc = tRFCab;
// table->emc_cfg_2 = 0x11083d;
// #undef GET_CYCLE
}
Result MemFreqMtcTable(u32 *ptr) {

View File

@@ -20,6 +20,7 @@
#include "pcv.hpp"
#include "../mtc_timing_value.hpp"
#include "../mariko/calculate_timings.hpp"
namespace ams::ldr::oc::pcv::mariko {
@@ -76,59 +77,58 @@ namespace ams::ldr::oc::pcv::mariko {
}
R_THROW(ldr::ResultInvalidCpuMinVolt());
}
Result CpuVoltDfll(u32 *ptr)
{
Result CpuVoltDfll(u32 *ptr) {
cvb_cpu_dfll_data *entry = reinterpret_cast<cvb_cpu_dfll_data *>(ptr);
R_UNLESS(entry->tune0_low == 0x0000FFCF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune0_high == 0x00000000, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_low == 0x012207FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_high == 0x03FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry());
switch (C.marikoCpuUV)
{
switch (C.marikoCpuUV) {
case 0:
break;
case 1:
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); // process_id 0 // EOS UV1
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); // process_id 0 // EOS UV1
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
break;
case 2:
// PATCH_OFFSET(&(entry->tune0_low), 0x0000FF92); /// EOS Uv2
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFDF);
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF92); /// EOS Uv2
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x027207FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
break;
case 3:
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFDF); // EOS UV3
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFDF);
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF9A); // EOS UV3
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x27307ff);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
break;
case 4:
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS Uv4
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFDF);
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA2); // EOS Uv4
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x27407ff);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
break;
case 5:
// PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV5
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFDF);
PATCH_OFFSET(&(entry->tune1_low), 0x21607ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27707ff);
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV5
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x022217FF);
break;
case 6:
// PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFDF);
PATCH_OFFSET(&(entry->tune1_low), 0x21607ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27807ff);
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x024417FF);
break;
case 7:
/// PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x21607ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x026617FF);
break;
// case 8:
// PATCH_OFFSET(&(entry->tune0_low), 0x0000FFFF); // EOS UV6
@@ -142,7 +142,6 @@ Result CpuVoltDfll(u32 *ptr)
R_SUCCEED();
}
Result GpuFreqMaxAsm(u32 *ptr32) {
// Check if both two instructions match the pattern
u32 ins1 = *ptr32, ins2 = *(ptr32 + 1);
@@ -200,7 +199,7 @@ Result CpuVoltDfll(u32 *ptr)
R_SUCCEED();
}
void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
@@ -223,19 +222,12 @@ void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
/* TODO: Make this less uggly and actually work by finding real clocks */
if (C.marikoEmcMaxClock > 3'100'000) {
obdly -= 2;
}
if (C.marikoEmcMaxClock > 2'500'000) {
obdly -= 2;
}
CalculateTimings();
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_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB8)));
WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F)));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
@@ -243,12 +235,12 @@ void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
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_trpab, MIN(GET_CYCLE_CEIL(tRPab), static_cast<u32>(0x3F)));
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(tXP) + 1);
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tXP));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tXP) + 8);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tR2P));
WRITE_PARAM_ALL_REG(table, emc_r2p, tR2P);
WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
WRITE_PARAM_ALL_REG(table, emc_trtm, tRTM);
WRITE_PARAM_ALL_REG(table, emc_tratm, tRATM);
@@ -256,40 +248,41 @@ void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
WRITE_PARAM_ALL_REG(table, emc_twtm, tWTM);
WRITE_PARAM_ALL_REG(table, emc_twatm, tWATM);
WRITE_PARAM_ALL_REG(table, emc_rext, 26);
WRITE_PARAM_ALL_REG(table, emc_rext, rext);
WRITE_PARAM_ALL_REG(table, emc_wext, (C.marikoEmcMaxClock >= 2533000) ? 0x19 : 0x16);
WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
const u32 dyn_self_ref_control = (((u32)(7605.0 / tCK_avg)) + 260U) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000U);
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(10.0));
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(10.0));
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(14.0));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(5.0));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, cke2pden);
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(pdex2mrr));
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN);
WRITE_PARAM_ALL_REG(table, emc_einput, 0xF);
WRITE_PARAM_ALL_REG(table, emc_einput_duration, 0x31);
WRITE_PARAM_ALL_REG(table, emc_einput, einput);
WRITE_PARAM_ALL_REG(table, emc_einput_duration, einput_duration);
WRITE_PARAM_ALL_REG(table, emc_obdly, obdly);
WRITE_PARAM_ALL_REG(table, emc_ibdly, 0x1000001C);
WRITE_PARAM_ALL_REG(table, emc_ibdly, ibdly);
WRITE_PARAM_ALL_REG(table, emc_wdv_mask, wdv);
WRITE_PARAM_ALL_REG(table, emc_quse_width, 0xD);
WRITE_PARAM_ALL_REG(table, emc_quse, 0x2F);
WRITE_PARAM_ALL_REG(table, emc_quse_width, quse_width);
WRITE_PARAM_ALL_REG(table, emc_quse, quse);
WRITE_PARAM_ALL_REG(table, emc_wdv, wdv);
WRITE_PARAM_ALL_REG(table, emc_wsv, wsv);
WRITE_PARAM_ALL_REG(table, emc_wev, wev);
WRITE_PARAM_ALL_REG(table, emc_qrst, 0x00080005);
WRITE_PARAM_ALL_REG(table, emc_qsafe, 0x44);
WRITE_PARAM_ALL_REG(table, emc_tr_qpop, 0x3B);
WRITE_PARAM_ALL_REG(table, emc_rdv, 0x49);
WRITE_PARAM_ALL_REG(table, emc_qpop, 0x3B);
WRITE_PARAM_ALL_REG(table, emc_tr_rdv_mask, 0x4B);
WRITE_PARAM_ALL_REG(table, emc_rdv_early, 0x47);
WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, 0x49);
WRITE_PARAM_ALL_REG(table, emc_rdv_mask, 0x4B);
WRITE_PARAM_ALL_REG(table, emc_tr_rdv, 0x49);
WRITE_PARAM_ALL_REG(table, emc_qrst, qrst);
WRITE_PARAM_ALL_REG(table, emc_qsafe, qsafe);
WRITE_PARAM_ALL_REG(table, emc_tr_qpop, qpop);
WRITE_PARAM_ALL_REG(table, emc_rdv, rdv);
WRITE_PARAM_ALL_REG(table, emc_qpop, qpop);
WRITE_PARAM_ALL_REG(table, emc_tr_rdv_mask, rdv + 2);
WRITE_PARAM_ALL_REG(table, emc_rdv_early, rdv - 2);
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);
constexpr u32 MC_ARB_DIV = 4;
constexpr u32 MC_ARB_SFA = 2;
@@ -386,14 +379,14 @@ void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
table->la_scale_regs.mc_latency_allowance_vic_0 = ((mc_latency_allowance_vic_0 | table->la_scale_regs.mc_latency_allowance_vic_0) & 0xff00ff00U) | mc_latency_allowance3;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & 0xffffff00U) | mc_latency_allowance2;
// table->pllm_ss_ctrl1 = 0xb55fe01;
// table->pllm_ss_ctrl2 = 0x10170b55;
// table->pllmb_ss_ctrl1 = 0xb55fe01;
// table->pllmb_ss_ctrl2 = 0x10170b55;
// table->pllm_ss_ctrl1 = 0xb55fe01;
// table->pllm_ss_ctrl2 = 0x10170b55;
// table->pllmb_ss_ctrl1 = 0xb55fe01;
// table->pllmb_ss_ctrl2 = 0x10170b55;
table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab;
table->dram_timings.rl = RL - 10;
table->dram_timings.rl = RL_DBI;
table->emc_mrw2 = 0x8802003F;
table->emc_cfg_2 = 0x11083D;
}
@@ -416,66 +409,201 @@ void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
* you'd better calculate timings yourself rather than relying on following algorithm.
*/
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
#define GET_CYCLE(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
WRITE_PARAM_ALL_REG(table, emc_rc, 0x60);
// 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_ras, GET_CYCLE_CEIL(tRAS));
// WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
// WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
// 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));
// 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_r2w, R2W);
// WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
// WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
//
// /* May or may not have to be patched in Micron; let's skip for now. */
// if (!IsMicron())
// {
// 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_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_tckesr, GET_CYCLE_CEIL(tSR));
// 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_trefbw, REFBW);
//
///* Worth replacing with l4t dumps at some point. */
//// Burst MC Regs
//#define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE;
//
// constexpr u32 MC_ARB_DIV = 4;
// constexpr u32 MC_ARB_SFA = 2;
//
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_cfg, C.marikoEmcMaxClock / (33.3 * 1000) / MC_ARB_DIV); // CYCLES_PER_UPDATE: The number of mcclk cycles per deadline timer update
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rcd, CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rp, CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rc, CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_ras, CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_faw, CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rrd, CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rap2pre, CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV))
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_wap2pre, CEIL((WTP) / MC_ARB_DIV))
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_r2r, CEIL(table->burst_regs.emc_rext / MC_ARB_DIV) - 1 + MC_ARB_SFA)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_r2w, CEIL((R2W) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_w2r, CEIL((W2R) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
// WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rfcpb, CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV))
/* This condition is insane but it's done in eos. */
/* Need to clean up at some point. */
// u32 rext;
// u32 wext;
// if (C.marikoEmcMaxClock < 3200001) {
// if (C.marikoEmcMaxClock < 2133001) {
// rext = 26;
// wext = 22;
// } else {
// rext = 28;
// wext = 22;
//
// if (2400000 < C.marikoEmcMaxClock) {
// wext = 25;
// }
// }
// } else {
// rext = 30;
// wext = 25;
// }
//
// u32 refresh_raw = 0xFFFF;
// u32 trefbw = 0;
//
// if (C.t8_tREFI != 6) {
// refresh_raw = static_cast<u32>(std::floor(static_cast<double>(tREFpb_values[C.t8_tREFI]) / tCK_avg)) - 0x40;
// refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
// }
//
// trefbw = refresh_raw + 0x40;
// trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
//
// /* Primary timings. */
// WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE(tRAS));
// WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE(tRPpb));
//
// /* Secondary timings. */
// WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE(tRRD));
// WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE(tRFCab));
// WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE(tRFCpb));
// WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
// WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, (u32) 0xC);
// WRITE_PARAM_ALL_REG(table, emc_w2p, (u32) 0x2D);
//
// WRITE_PARAM_ALL_REG(table, emc_rext, rext);
// WRITE_PARAM_ALL_REG(table, emc_wext, wext);
//
// WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE(tRPab));
// WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE(tFAW));
// WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE(tRC));
//
// WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE(tSR));
// WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE(tXP) + 2);
// WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE(tXP));
// WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE(tXP) + 8);
//
// WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE(tXSR), (u32) 1022));
//
// const u32 dyn_self_ref_control = (((u32)(7605.0 / tCK_avg)) + 260U) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000U);
// WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
//
// WRITE_PARAM_ALL_REG(table, emc_rw2pden, ams::ldr::oc::pcv::erista::tRW2PDEN);
// 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));
// WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE(ams::ldr::oc::pcv::erista::pdex2mrr));
//
// WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
// WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, (u32) (refresh_raw / 4));
// WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
//
// const u32 mc_tRCD = (int)((double)(GET_CYCLE(tRCD) >> 2) - 2.0);
// const u32 mc_tRPpb = (int)(((double)(GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// const u32 mc_tRC = (uint)((double)(GET_CYCLE(tRC) >> 2) - 1.0);
// const u32 mc_tR2W = (uint)(((double)((uint)tR2W >> 2) - 1.0) + 2.0);
// const u32 mc_tW2R = (uint)(((double)(tW2R >> 2) - 1.0) + 2.0);
// const u32 mc_tRAS = MIN(GET_CYCLE(tRAS), (u32) 0x7F);
// const u32 mc_tRRD = MIN(GET_CYCLE(tRRD), (u32) 31);
//
// table->burst_mc_regs.mc_emem_arb_cfg = (int)(((double) C.marikoEmcMaxClock / 33300.0) * 0.25);
// table->burst_mc_regs.mc_emem_arb_timing_ras = (int) ((double) (mc_tRAS >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rcd = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rp = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rc = (int) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_faw = (int) ((double)(GET_CYCLE(tFAW) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_rrd = (int)((double)(mc_tRRD >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 3;
// table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 11;
// table->burst_mc_regs.mc_emem_arb_timing_r2w = (uint)(((double)((uint)tR2W >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2r = (uint)(((double)(tW2R >> 2) - 1.0) + 2.0);
//
// u32 mc_r2r = table->burst_mc_regs.mc_emem_arb_timing_r2r;
// if (mc_r2r > 1) {
// mc_r2r = (uint)(((double)(long)((double)rext * 0.25) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_r2r = mc_r2r;
// }
//
// u32 mc_w2w = table->burst_mc_regs.mc_emem_arb_timing_w2w;
// if (mc_w2w > 1) {
// mc_w2w = (uint)(((double)(long)((double)wext / 4.0) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2w = mc_w2w;
// }
//
// table->burst_mc_regs.mc_emem_arb_da_turns = ((mc_tW2R >> 1) << 0x18) | ((mc_tR2W >> 1) << 0x10) | ((mc_r2r >> 1) << 8) | ((mc_w2w >> 1));
// table->burst_mc_regs.mc_emem_arb_da_covers = (((uint)(mc_tRCD + 3 + mc_tRPpb) >> 1 & 0xff) << 8) | (((uint)(mc_tRCD + 11 + mc_tRPpb) >> 1 & 0xff) << 0x10) | ((mc_tRC >> 1) & 0xff);
// table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xffe08000U) | ((mc_tRC + 1) & 0xff);
// table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = MIN((u32)((C.marikoEmcMaxClock / 1600000) * 0xd0U), (u32)0x115);
// table->la_scale_regs.mc_ftop_ptsa_rate = MIN((u32)((C.marikoEmcMaxClock / 1600000) * 0x18U), (u32)0x1f);
// table->la_scale_regs.mc_ptsa_grant_decrement = MIN((u32)((C.marikoEmcMaxClock / 1600000) * 0x1203U), (u32)0x17ff);
//
// u32 mc_latency_allowance = 0;
// if (C.marikoEmcMaxClock / 1000 != 0) {
// mc_latency_allowance = 204800 / (C.marikoEmcMaxClock / 1000);
// }
//
// const u32 mc_latency_allowance2 = mc_latency_allowance & 0xFF;
// const u32 mc_latency_allowance3 = (mc_latency_allowance & 0xFF) << 0x10;
// table->la_scale_regs.mc_latency_allowance_xusb_0 = (table->la_scale_regs.mc_latency_allowance_xusb_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & 0xff00ffffU) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_hc_0 = 0;
// if (C.marikoEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_hc_0 = 35200 / (C.marikoEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & 0xffffff00U) | mc_latency_allowance_hc_0;
//
// table->la_scale_regs.mc_latency_allowance_isp2_1 = (table->la_scale_regs.mc_latency_allowance_isp2_1 & 0xff00ff00U) | mc_latency_allowance3 | mc_latency_allowance2;
// table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & 0xffffff00U) | mc_latency_allowance2;
//
// u32 mc_latency_allowance_gpu_0 = 0;
// if (C.marikoEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_gpu_0 = 40000 / (C.marikoEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_gpu_0 = ((mc_latency_allowance_gpu_0 | table->la_scale_regs.mc_latency_allowance_gpu_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_gpu2_0 = 0;
// if (C.marikoEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_gpu2_0 = 40000 / (C.marikoEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_gpu2_0 = ((mc_latency_allowance_gpu2_0 | table->la_scale_regs.mc_latency_allowance_gpu2_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_nvenc_0 = 0;
// if (C.marikoEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_nvenc_0 = 38400 / (C.marikoEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_nvenc_0 = ((mc_latency_allowance_nvenc_0 | table->la_scale_regs.mc_latency_allowance_nvenc_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_vic_0 = 0;
// if (C.marikoEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_vic_0 = 0xb540 / (C.marikoEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_vic_0 = ((mc_latency_allowance_vic_0 | table->la_scale_regs.mc_latency_allowance_vic_0) & 0xff00ff00U) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & 0xffffff00U) | mc_latency_allowance2;
//
// table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
//
// if (C.hpMode) {
// WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
// }
//
// table->dram_timings.t_rp = tRFCpb;
// table->dram_timings.t_rfc = tRFCab;
// table->emc_cfg_2 = 0x11083d;
}
/* NOTE: This is reverse engineered eos code, naming may be inaccurate. */
void MemMtcPllmbDivisor(MarikoMtcTable *table) {
constexpr u32 PllOscInKHz = 38400;
constexpr u32 PllOscHalfKHz = 19200;