(Unfinished): Mariko timing stuff

This commit is contained in:
Lightos1
2025-10-31 14:58:51 +01:00
parent 31ea468b49
commit e24661129d
4 changed files with 274 additions and 127 deletions

View File

@@ -30,56 +30,56 @@ namespace ams::ldr::oc {
volatile CustomizeTable C = {
.mtcConf = AUTO_ADJ,
.mtcConf = AUTO_ADJ_BL,
.hpMode = DISABLED,
.commonCpuBoostClock = 1785000, // Default boost clock
.commonEmcMemVolt = 1175000, // LPDDR4X JEDEC Specification
.commonEmcMemVolt = 1212500, // LPDDR4X JEDEC Specification
.eristaCpuMaxVolt = 1235,
.eristaEmcMaxClock = 1600000, // Maximum HB-MGCH ram rating
.eristaEmcMaxClock = 2300000, // Maximum HB-MGCH ram rating
.marikoCpuMaxVolt = 1120,
.marikoEmcMaxClock = 1862400, // Hynix NME and Samsung AM-MGCJ Rating (others are 4766MT, 2133MHz)
.marikoEmcMaxClock = 1866000, // Hynix NME and Samsung AM-MGCJ Rating (others are 4766MT, 2133MHz)
.marikoEmcVddqVolt = 600000,
.marikoEmcVddqVolt = 640000,
.marikoCpuUV = 0, // No undervolt
.marikoCpuUV = 5, // No undervolt
.marikoGpuUV = 0,
.marikoGpuUV = 3,
.eristaCpuUV = 0,
.eristaGpuUV = 0,
.eristaGpuUV = 3,
.enableMarikoGpuUnsafeFreqs = DISABLED,
.enableMarikoGpuUnsafeFreqs = ENABLED,
.enableEristaGpuUnsafeFreqs = DISABLED,
.enableEristaGpuUnsafeFreqs = ENABLED,
.enableMarikoCpuUnsafeFreqs = DISABLED,
.enableMarikoCpuUnsafeFreqs = ENABLED,
.enableEristaCpuUnsafeFreqs = DISABLED,
.enableEristaCpuUnsafeFreqs = ENABLED,
.commonGpuVoltOffset = 0,
.EmcDvbShift = 0,
.EmcDvbShift = 5,
// Defaults - (3-3-2) 0-1-4-3-6
// Primary
.t1_tRCD = 0,
.t2_tRP = 0,
.t3_tRAS = 0,
.t1_tRCD = 5,
.t2_tRP = 7,
.t3_tRAS = 8,
// Secondary
.t4_tRRD = 0,
.t5_tRFC = 0,
.t6_tRTW = 0,
.t7_tWTR = 0,
.t8_tREFI= 0,
.t4_tRRD = 1,
.t5_tRFC = 2,
.t6_tRTW = 5,
.t7_tWTR = 4,
.t8_tREFI= 6,
// .mem_burst_latency = 0, // 0 - 1600l, 1 = 1866bl, 2 = 2133bl /* TODO: Remove/fix. */
@@ -89,7 +89,7 @@ volatile CustomizeTable C = {
.marikoGpuVmin = 610,
.marikoGpuVmax = 800,
.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 sameot
@@ -110,11 +110,11 @@ volatile CustomizeTable C = {
710 /* 1075 */,
735 /* 1152 */,
785 /* 1228 */,
0 /* 1267 (Disabled by default) */,
0 /* 1305 (Disabled by default) */,
0 /* 1344 (Disabled by default) */,
0 /* 1382 (Disabled by default) */,
0 /* 1420 (Disabled by default) */,
780 /* 1267 (Disabled by default) */,
805 /* 1305 (Disabled by default) */,
870 /* 1344 (Disabled by default) */,
870 /* 1382 (Disabled by default) */,
870 /* 1420 (Disabled by default) */,
0 /* 1459 (Disabled by default) */,
0 /* 1497 (Disabled by default) */,
0 /* 1536 (Disabled by default) */,
@@ -133,9 +133,9 @@ volatile CustomizeTable C = {
875 /* 691 */,
900 /* 768 */,
950 /* 844 */,
975 /* 921 */,
0 /* 998 (Disabled by default) */,
0 /* 1075 (Disabled by default) */,
887 /* 921 */,
950 /* 998 (Disabled by default) */,
995 /* 1075 (Disabled by default) */,
},
@@ -225,7 +225,7 @@ volatile CustomizeTable C = {
{ 768000, { }, { 1191317, 8144, -940, 808, -21583, 226 } },
{ 844800, { }, { 1233208, 8144, -940, 808, -21583, 226 } },
{ 921600, { }, { 1275100, 8144, -940, 808, -21583, 226 } },
// { 998400, { }, { 1316991, 8144, -940, 808, -21583, 226 } },
{ 998400, { }, { 1316991, 8144, -940, 808, -21583, 226 } },
// { 1075200, { }, { 1358882, 8144, -940, 808, -21583, 226 } },
},
@@ -243,7 +243,7 @@ volatile CustomizeTable C = {
{ 768000, { }, { 1107534, 8144, -940, 808, -21583, 226 } },
{ 844800, { }, { 1149426, 8144, -940, 808, -21583, 226 } },
{ 921600, { }, { 1191317, 8144, -940, 808, -21583, 226 } },
// { 998400, { }, { 1275100, 8144, -940, 808, -21583, 226 } },
{ 998400, { }, { 1275100, 8144, -940, 808, -21583, 226 } },
// { 1075200, { }, { 1316991, 8144, -940, 808, -21583, 226 } },
},

View File

@@ -74,9 +74,9 @@ namespace ams::ldr::oc {
const u32 tFAW = (u32) (tRRD * 4.0);
/* Latency stuff. */
const u32 tR2W = (u32)(((((double)(long)(3.5 / tCK_avg) + 32.0 + (BL / 2)) - 14.0) + tWPRE + 12.0) - (double)(C.t6_tRTW * 3));
const u32 tW2R = static_cast<u32>((static_cast<long>(tWTR / tCK_avg) + 23.0) - (BL / 2.0));
const u32 tRW2PDEN = (u32) ((double) (u64)(1.25 / tCK_avg) + 46.0 + (double) (u64)(0.8 / tCK_avg) + 6.0);
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)((1.25 / tCK_avg) + 46 + (0.8 / tCK_avg) + 6);
/* Refresh Cycle time. (All Banks) */
const u32 tRFCab = tRFCpb * 2;
@@ -94,7 +94,7 @@ namespace ams::ldr::oc {
const double tXP = 7.5; // I assume this is correct.
/* u32ernal READ to PRECHARGE command delay. */
const u32 pdex2mrr = (u32) (tCK_avg * 3.0 + (double) tRCD_values[C.t1_tRCD] + 10.0);
const int pdex2mrr = (tCK_avg * 3.0) + tRCD_values[C.t1_tRCD] + 1;
/* Row Precharge Time. (all banks) */
const double tRPab = tRPpb + 3;

View File

@@ -178,24 +178,24 @@ namespace ams::ldr::oc::pcv::erista {
/* 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 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;
@@ -415,7 +415,7 @@ namespace ams::ldr::oc::pcv::erista {
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 = (val & 0x0000FFFF) | (tW2R << 24) | (tR2W << 16);
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;

View File

@@ -252,11 +252,162 @@ namespace ams::ldr::oc::pcv::mariko
}
}
/* Unholly commenting shit to make werror shut up. (No time to do it properly atm) */
/* TODO: Implement mariko.
void MemMtcTableAutoAdjust(MarikoMtcTable *table)
{
Official Tegra X1 TRM, sign up for nvidia developer program (free) to download:
void MemMtcTableAutoAdjustBaseLatency(MarikoMtcTable *table) {
#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;
WRITE_PARAM_ALL_REG(table, emc_cfg, 0xf3200000);
WRITE_PARAM_ALL_REG(table, emc_rc, 0x00000070);
WRITE_PARAM_ALL_REG(table, emc_rfc, 0x0000020b);
WRITE_PARAM_ALL_REG(table, emc_ras, 0x0000004f);
WRITE_PARAM_ALL_REG(table, emc_rp, 0x00000022);
WRITE_PARAM_ALL_REG(table, emc_r2w, 0x0000002e);
WRITE_PARAM_ALL_REG(table, emc_w2r, 0x00000025);
WRITE_PARAM_ALL_REG(table, emc_r2p, 0x0000000e);
WRITE_PARAM_ALL_REG(table, emc_w2p, 0x00000033);
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, 0x00000022);
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, 0x00000022);
WRITE_PARAM_ALL_REG(table, emc_rrd, 0x00000013);
WRITE_PARAM_ALL_REG(table, emc_rext, 0x0000001a);
WRITE_PARAM_ALL_REG(table, emc_qsafe, 0x00000038);
WRITE_PARAM_ALL_REG(table, emc_refresh, 0x00001c2d);
WRITE_PARAM_ALL_REG(table, emc_burst_refresh_num, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, 0x00000013);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, 0x00000013);
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, 0x00000004);
WRITE_PARAM_ALL_REG(table, emc_act2pden, 0x0000001b);
WRITE_PARAM_ALL_REG(table, emc_ar2pden, 0x00000004);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, 0x0000003f);
WRITE_PARAM_ALL_REG(table, emc_txsr, 0x00000219);
WRITE_PARAM_ALL_REG(table, emc_tcke, 0x00000010);
WRITE_PARAM_ALL_REG(table, emc_tfaw, 0x0000004b);
WRITE_PARAM_ALL_REG(table, emc_trpab, 0x00000028);
WRITE_PARAM_ALL_REG(table, emc_tclkstable, 0x00000004);
WRITE_PARAM_ALL_REG(table, emc_tclkstop, 0x00000017);
WRITE_PARAM_ALL_REG(table, emc_trefbw, 0x00001c6d);
WRITE_PARAM_ALL_REG(table, emc_tppd, 0x00000004);
WRITE_PARAM_ALL_REG(table, emc_odt_write, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, 0x00000037);
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, 0x01d3001b);
WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt, 0x074a0034);
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, 0x9160a00d);
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, 0x00000002);
WRITE_PARAM_ALL_REG(table, emc_cke2pden, 0x00000010);
WRITE_PARAM_ALL_REG(table, emc_r2r, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_einput, 0x00000015);
WRITE_PARAM_ALL_REG(table, emc_einput_duration, 0x00000020);
WRITE_PARAM_ALL_REG(table, emc_puterm_extra, 0x00000001);
WRITE_PARAM_ALL_REG(table, emc_tckesr, 0x0000001c);
WRITE_PARAM_ALL_REG(table, emc_tpd, 0x0000000e);
table->emc_cfg_2 = 0x0011083d;
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, 0x00000040);
WRITE_PARAM_ALL_REG(table, emc_wdv_mask, 0x00000010);
WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, 0x0000003e);
WRITE_PARAM_ALL_REG(table, emc_rdv_early, 0x0000003c);
WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_dq, 0x8020221f);
WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_cmd, 0x0220f40f);
table->emc_sel_dpd_ctrl = 0x0004000c;
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, 0x0000070b);
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, 0x80003873);
WRITE_PARAM_ALL_REG(table, emc_txsrdll, 0x00000219);
WRITE_PARAM_ALL_REG(table, emc_ibdly, 0x1000001f);
WRITE_PARAM_ALL_REG(table, emc_obdly, 0x10000004);
WRITE_PARAM_ALL_REG(table, emc_txdsrvttgen, 0x00000000);
WRITE_PARAM_ALL_REG(table, emc_we_duration, 0x0000000e);
WRITE_PARAM_ALL_REG(table, emc_ws_duration, 0x00000008);
WRITE_PARAM_ALL_REG(table, emc_wev, 0x0000000c);
WRITE_PARAM_ALL_REG(table, emc_cfg_3, 0x00000040);
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, 0x0fff0000);
WRITE_PARAM_ALL_REG(table, emc_cfg_pipe, 0x0fff0000);
WRITE_PARAM_ALL_REG(table, emc_quse_width, 0x00000009);
WRITE_PARAM_ALL_REG(table, emc_puterm_width, 0x80000000);
WRITE_PARAM_ALL_REG(table, emc_fbio_cfg7, 0x00003bff);
WRITE_PARAM_ALL_REG(table, emc_rfcpb, 0x00000106);
WRITE_PARAM_ALL_REG(table, emc_ccdmw, 0x00000020);
WRITE_PARAM_ALL_REG(table, emc_config_sample_delay, 0x00000020);
table->dram_timings.t_rp = 0x00000106;
table->dram_timings.t_rfc = 0x0000020b;
table->dram_timings.rl = 32; /* */
WRITE_PARAM_ALL_REG(table, emc_wdv, 0x00000010); /* */
WRITE_PARAM_ALL_REG(table, emc_quse, 0x00000028); /* */
WRITE_PARAM_ALL_REG(table, emc_qrst, 0x0007000c); /* These timings cause issues and I have no idea why. */
WRITE_PARAM_ALL_REG(table, emc_rdv, 0x0000003e); /* */
WRITE_PARAM_ALL_REG(table, emc_wsv, 0x0000000e); /* */
WRITE_PARAM_ALL_REG(table, emc_qpop, 0x00000030); /* */
table->burst_mc_regs.mc_emem_arb_cfg = 0x0000000E;
table->burst_mc_regs.mc_emem_arb_outstanding_req = 0x80000080;
table->burst_mc_regs.mc_emem_arb_timing_rcd = 0x00000007;
table->burst_mc_regs.mc_emem_arb_timing_rp = 0x00000008;
table->burst_mc_regs.mc_emem_arb_timing_rc = 0x0000001C;
table->burst_mc_regs.mc_emem_arb_timing_ras = 0x00000012;
table->burst_mc_regs.mc_emem_arb_timing_faw = 0x00000012;
table->burst_mc_regs.mc_emem_arb_timing_rrd = 0x00000004;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 0x00000004;
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 0x0000000F;
table->burst_mc_regs.mc_emem_arb_timing_r2r = 0x00000001;
table->burst_mc_regs.mc_emem_arb_timing_w2w = 0x00000001;
table->burst_mc_regs.mc_emem_arb_timing_r2w = 0x0000000D;
table->burst_mc_regs.mc_emem_arb_timing_w2r = 0x0000000B;
table->burst_mc_regs.mc_emem_arb_da_turns = 0x05060000;
table->burst_mc_regs.mc_emem_arb_da_covers = 0x000F0A0E;
table->burst_mc_regs.mc_emem_arb_misc0 = 0x726E2A1D;
table->burst_mc_regs.mc_emem_arb_misc1 = 0x70000F0F;
table->burst_mc_regs.mc_emem_arb_misc2 = 0x00000000;
table->burst_mc_regs.mc_emem_arb_ring1_throttle = 0x001F0000;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = 0x00000041;
table->burst_mc_regs.mc_emem_arb_timing_ccdmw = 0x00000008;
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 = 0x000000F2;
table->la_scale_regs.mc_ftop_ptsa_rate = 0x0000001B;
table->la_scale_regs.mc_ptsa_grant_decrement = 0x00001501;
table->la_scale_regs.mc_latency_allowance_avpc_0 = 0x006D0004;
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = 0x006D0005;
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = 0x006D0014;
table->la_scale_regs.mc_latency_allowance_isp2_0 = 0x0000002C;
table->la_scale_regs.mc_latency_allowance_isp2_1 = 0x006D006D;
table->la_scale_regs.mc_latency_allowance_vic_0 = 0x006D0019;
table->la_scale_regs.mc_latency_allowance_nvdec_0 = 0x006D0095;
table->la_scale_regs.mc_latency_allowance_tsec_0 = 0x006D0041;
table->la_scale_regs.mc_latency_allowance_ppcs_1 = 0x006D0080;
table->la_scale_regs.mc_latency_allowance_xusb_0 = 0x006D003D;
table->la_scale_regs.mc_latency_allowance_ppcs_0 = 0x00340049;
table->la_scale_regs.mc_latency_allowance_gpu2_0 = 0x006D0016;
table->la_scale_regs.mc_latency_allowance_hc_1 = 0x0000006D;
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = 0x006D0090;
table->la_scale_regs.mc_latency_allowance_mpcore_0 = 0x006D0004;
table->la_scale_regs.mc_latency_allowance_vi2_0 = 0x0000006D;
table->la_scale_regs.mc_latency_allowance_hc_0 = 0x00080013;
table->la_scale_regs.mc_latency_allowance_gpu_0 = 0x006D0016;
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = 0x006D0005;
table->la_scale_regs.mc_latency_allowance_nvenc_0 = 0x006D0018;
}
void MemMtcTableAutoAdjust(MarikoMtcTable *table) {
/* Official Tegra X1 TRM, sign up for nvidia developer program (free) to download:
* https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual
* Section 18.11: MC Registers
*
@@ -271,75 +422,66 @@ namespace ams::ldr::oc::pcv::mariko
*
* If you have access to LPDDR4(X) specs or datasheets (from manufacturers or Google),
* you'd better calculate timings yourself rather than relying on following algorithm.
/
*/
if (C.mtcConf != AUTO_ADJ)
{
return;
}
#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 WRITE_PARAM_BURST_REG(TABLE, PARAM, VALUE) TABLE->burst_regs.PARAM = VALUE;
#define WRITE_PARAM_CA_TRAIN_REG(TABLE, PARAM, VALUE) TABLE->shadow_regs_ca_train.PARAM = VALUE;
#define WRITE_PARAM_RDWR_TRAIN_REG(TABLE, PARAM, VALUE) TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
#define GET_CYCLE(PARAM) ((u32)((double)(PARAM) / tCK_avg))
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
WRITE_PARAM_BURST_REG(TABLE, PARAM, VALUE) \
WRITE_PARAM_CA_TRAIN_REG(TABLE, PARAM, VALUE) \
WRITE_PARAM_RDWR_TRAIN_REG(TABLE, PARAM, VALUE)
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
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))
}*/
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))
}
void MemMtcPllmbDivisor(MarikoMtcTable *table)
{
@@ -398,7 +540,12 @@ namespace ams::ldr::oc::pcv::mariko
std::memcpy(reinterpret_cast<void *>(tmp), reinterpret_cast<void *>(table_max), sizeof(MarikoMtcTable));
// Adjust max freq mtc timing parameters with reference to 1331200 table
/* TODO: Implement mariko */
// MemMtcTableAutoAdjust(table_max);
if (C.mtcConf == AUTO_ADJ) {
MemMtcTableAutoAdjust(table_max);
} else {
MemMtcTableAutoAdjustBaseLatency(table_max);
}
MemMtcPllmbDivisor(table_max);
// Overwrite 13312000 table with unmodified 1600000 table copied back
std::memcpy(reinterpret_cast<void *>(table_alt), reinterpret_cast<void *>(tmp), sizeof(MarikoMtcTable));