BL fixing I think done correctly? idk

This commit is contained in:
Lightos1
2025-10-01 22:26:21 +02:00
parent 4809e97da9
commit f8c738e5e8
3 changed files with 309 additions and 277 deletions

View File

@@ -58,15 +58,14 @@
// const u32 TIMING_PRESET_SIX = C.ramTimingPresetSix; // const u32 TIMING_PRESET_SIX = C.ramTimingPresetSix;
// const u32 TIMING_PRESET_SEVEN = C.ramTimingPresetSeven; // const u32 TIMING_PRESET_SEVEN = C.ramTimingPresetSeven;
// Burst Length
const u32 BL = 16;
// Write Latency // Write Latency
const u32 WL = 14 + C.mem_burst_latency; const u32 WL = 14 + C.mem_burst_latency;
// Read Latency // Read Latency
const u32 RL = 32 - C.mem_burst_latency; const u32 RL = 32 - C.mem_burst_latency;
// Burst Length
const u32 BL = 16;
// tRFCpb (refresh cycle time per bank) in ns for 8Gb density // tRFCpb (refresh cycle time per bank) in ns for 8Gb density
const u32 tRFCpb = !C.t5_tRFC ? 140 : tRFC_values[C.t5_tRFC-1]; const u32 tRFCpb = !C.t5_tRFC ? 140 : tRFC_values[C.t5_tRFC-1];
@@ -128,13 +127,38 @@
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4); const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
const u32 REFBW = MIN((u32)65536, REFRESH+64); const u32 REFBW = MIN((u32)65536, REFRESH+64);
// DQS output access time from CK_t/CK_c
const double tDQSCK_min = 1.5;
const double tDQSCK_max = 3.5;
// Write preamble (tCK)
const double tWPRE = 1.8;
// Read postamble (tCK)
const double tRPST = 0.4;
namespace pcv::erista { namespace pcv::erista {
// tCK_avg (average clock period) in ns // tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.eristaEmcMaxClock; const double tCK_avg = 1000'000. / C.eristaEmcMaxClock;
// minimum number of cycles from any read command to any write command, irrespective of bank
const u32 R2W = CEIL (RL + CEIL(tDQSCK_max/tCK_avg) + BL/2 - WL + tWPRE + FLOOR(tRPST)) + 6;
// Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg) - 6;
// write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8;
} }
namespace pcv::mariko { namespace pcv::mariko {
// tCK_avg (average clock period) in ns // tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.marikoEmcMaxClock; const double tCK_avg = 1000'000. / C.marikoEmcMaxClock;
const u32 R2W = CEIL (RL + CEIL(tDQSCK_max/tCK_avg) + BL/2 - WL + tWPRE + FLOOR(tRPST)) + 6;
// Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg) - 6;
// write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8;
} }
} }

View File

@@ -21,8 +21,8 @@
#include "pcv.hpp" #include "pcv.hpp"
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
namespace ams::ldr::oc::pcv::erista { namespace ams::ldr::oc::pcv::erista {
Result CpuFreqVdd(u32* ptr) { Result CpuFreqVdd(u32* ptr) {
dvfs_rail* entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq)); dvfs_rail* entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq));
R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry()); R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry());
@@ -41,13 +41,13 @@
} }
R_SUCCEED(); R_SUCCEED();
} }
Result GpuVmin(u32 *ptr) { Result GpuVmin(u32 *ptr) {
if (!C.eristaGpuVmin) if (!C.eristaGpuVmin)
R_SKIP(); R_SKIP();
PATCH_OFFSET(ptr, (int)C.eristaGpuVmin); PATCH_OFFSET(ptr, (int)C.eristaGpuVmin);
R_SUCCEED(); R_SUCCEED();
} }
Result CpuVoltRange(u32 *ptr) { Result CpuVoltRange(u32 *ptr) {
u32 min_volt_got = *(ptr - 1); u32 min_volt_got = *(ptr - 1);
for (const auto &mv : CpuMinVolts) { for (const auto &mv : CpuMinVolts) {
@@ -101,7 +101,7 @@
break; break;
} }
R_SUCCEED(); R_SUCCEED();
} }
Result GpuFreqMaxAsm(u32 *ptr32) { Result GpuFreqMaxAsm(u32 *ptr32) {
// Check if both two instructions match the pattern // Check if both two instructions match the pattern
@@ -163,13 +163,13 @@
if (C.mtcConf != AUTO_ADJ) if (C.mtcConf != AUTO_ADJ)
return; return;
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \ #define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
TABLE->burst_regs.PARAM = VALUE; \ TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \ TABLE->shadow_regs_ca_train.PARAM = VALUE; \
TABLE->shadow_regs_quse_train.PARAM = VALUE; \ TABLE->shadow_regs_quse_train.PARAM = VALUE; \
TABLE->shadow_regs_rdwr_train.PARAM = VALUE; TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg)) #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_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab)); WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
@@ -177,6 +177,9 @@
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); 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_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); 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_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
@@ -191,7 +194,7 @@
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab));
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW); WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
#define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE; #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_DIV = 4;
constexpr u32 MC_ARB_SFA = 2; constexpr u32 MC_ARB_SFA = 2;
@@ -205,8 +208,8 @@
//table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV); //table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
// table->burst_mc_regs.mc_emem_arb_timing_r2r = CEIL(table->burst_regs.emc_rext / MC_ARB_DIV) - 1 + MC_ARB_SFA; // table->burst_mc_regs.mc_emem_arb_timing_r2r = CEIL(table->burst_regs.emc_rext / MC_ARB_DIV) - 1 + MC_ARB_SFA;
// table->burst_mc_regs.mc_emem_arb_timing_w2w = CEIL(table->burst_regs.emc_wext / MC_ARB_DIV) - 1 + MC_ARB_SFA; // table->burst_mc_regs.mc_emem_arb_timing_w2w = CEIL(table->burst_regs.emc_wext / MC_ARB_DIV) - 1 + MC_ARB_SFA;
// table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA; // table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
// table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA; // table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV);
// table->burst_mc_regs.mc_emem_arb_timing_ccdmw = CEIL(tCCDMW / MC_ARB_DIV) -1 + MC_ARB_SFA; // table->burst_mc_regs.mc_emem_arb_timing_ccdmw = CEIL(tCCDMW / MC_ARB_DIV) -1 + MC_ARB_SFA;
} }
@@ -288,4 +291,4 @@
} }
} }
} }

View File

@@ -272,10 +272,14 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table) {
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH); 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_pre_refresh_req_cnt, REFRESH / 4);
/* Do not patch on micron. */ 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()) { if (!IsMicron()) {
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(tXP)); // NOT on micron WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(tXP));
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(tXP)); // NOT on micron 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_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
@@ -285,6 +289,7 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table) {
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab));
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW); WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
/* Worth replacing with l4t dumps at some point. */
// Burst MC Regs // Burst MC Regs
#define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE; #define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE;