BL fixing I think done correctly? idk
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user