diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 8ebe48c8..684740e1 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -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 } }, }, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp index 4a29151e..4436111f 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -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((static_cast(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; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp index 22d67f06..40cf502f 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -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; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp index a5567bb3..9977f916 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -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(tmp), reinterpret_cast(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(table_alt), reinterpret_cast(tmp), sizeof(MarikoMtcTable));