high ram oc

This commit is contained in:
souldbminersmwc
2025-09-09 16:39:28 -04:00
parent 06faabdddf
commit 962b8bc0a0
17 changed files with 333 additions and 449 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -103,22 +103,103 @@ volatile CustomizeTable C = {
.gpuVmax = 800, .gpuVmax = 800,
.gpuVmin = 600,
.marikoEmcDvbShift = 0, .marikoEmcDvbShift = 0,
.ramTimingPresetOne = 0, // T1-3 EOS .latency = 0, // Ram latency values. Goes from 0-6. Affects tWL and tRL
.ramTimingPresetTwo = 0, // T4 .BL = 16, // Keep at 16
.ramTimingPresetThree = 0, // Try all values from 0-6 // tRFCpb (refresh cycle time per bank) in ns for 8Gb density
.tRFCpb = 140,
.ramTimingPresetFour = 0, // EOS T5 // tRFCab (refresh cycle time all banks) in ns for 8Gb density
.tRFCab = 280, // tRFCpb * 2
.ramTimingPresetFive = 0, // EOS T7 // tRAS (row active time) in ns
.tRAS = 42,
.ramTimingPresetSix = 0, // EOS T8 // tRPpb (row precharge time per bank) in ns
.tRPpb = 18,
// tRPab (row precharge time all banks) in ns
.tRPab = 21, // tRPab + 3
// tRC (ACTIVATE-ACTIVATE command period same bank) in ns
.tRC = 60, // tRPpb + tRAS
// DQS output access time from CK_t/CK_c
.tDQSCK_min = 1.5,
// DQS output access time from CK_t/CK_c
.tDQSCK_max = 3.5,
// Write preamble (tCK)
.tWPRE = 1.8,
// Read postamble (tCK)
.tRPST = 0.4,
// WRITE command to first DQS transition(max) (tCK)
.tDQSS_max = 1.25,
// DQ-to-DQS offset(max) (ns)
.tDQS2DQ_max = 0.8,
// DQS_t, DQS_c to DQ skew total, per group, per access (DBI Disabled)
.tDQSQ = 0.18,
z
// Write-to-Read delay
.tWTR = 10,
// Internal READ-to-PRE-CHARGE command delay in ns
.tRTP = 7.5,
// write recovery time
.tWR = 18,
// Read to refresh delay
.tR2REF = 26, // Round down tRTP + tRPpb
// tRCD (RAS-CAS delay) in ns
.tRCD = 18,
// tRRD (Active bank-A to Active bank-B) in ns
.tRRD = 10.0,
// tREFpb (average refresh interval per bank) in ns for 8Gb density
.tREFpb = 488,
// tREFab (average refresh interval all 8 banks) in ns for 8Gb density
// const u32 tREFab = tREFpb * 8;
// tPDEX2WR, tPDEX2RD (timing delay from exiting powerdown mode to a write/read command) in ns
// const u32 tPDEX2 = 10;
// Exit power-down to next valid command delay
.tXP = 10,
// Delay from valid command to CKE input LOW in ns
.tCMDCKE = 1.75,
// tACT2PDEN (timing delay from an activate, MRS or EMRS command to power-down entry) in ns
// Valid clock and CS requirement after CKE input LOW after MRW command
.tMRWCKEL = 14,
// Valid CS requirement after CKE input LOW
.tCKELCS = 5,
// Valid CS requirement before CKE input HIGH
.tCSCKEH = 1.75,
// tXSR (SELF REFRESH exit to next valid command delay) in ns
.tXSR = 287.5, // tRFCab + 7.5
// tCKE (minimum pulse width(HIGH and LOW pulse width)) in ns
.tCKE = 7.5,
// Minimum self refresh time (entry to exit)
.tSR = 15,
// tFAW (Four-bank Activate Window) in ns
.tFAW = 40,
// Valid Clock requirement before CKE Input HIGH in ns
.tCKCKEH = 1.75,
.ramTimingPresetSeven = 0,
//
.marikoGpuVoltArray = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, .marikoGpuVoltArray = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -61,15 +61,42 @@ typedef struct CustomizeTable {
u32 cpuMaxFreq; u32 cpuMaxFreq;
u32 gpuMaxFreq; u32 gpuMaxFreq;
u32 gpuVmax; u32 gpuVmax;
// advanced config u32 gpuVmin;
u32 marikoEmcDvbShift; u32 marikoEmcDvbShift;
u32 ramTimingPresetOne; // ram timings
u32 ramTimingPresetTwo; u32 latency;
u32 ramTimingPresetThree; u32 BL;
u32 ramTimingPresetFour; u32 tRFCpb;
u32 ramTimingPresetFive; u32 tRFCab;
u32 ramTimingPresetSix; u32 tRAS;
u32 ramTimingPresetSeven; u32 tRPpb;
u32 tRPab;
u32 tRC;
double tDQSCK_min;
double tDQSCK_max;
double tWPRE;
double tRPST;
double tDQSS_max;
double tDQS2DQ_max;
double tDQSQ;
u32 tWTR;
double tRTP;
u32 tWR;
u32 tR2REF;
u32 tRCD;
double tRRD;
u32 tREFpb;
double tXP;
double tCMDCKE;
u32 tMRWCKEL;
double tCKELCS;
double tCSCKEH;
double tXSR;
double tCKE;
u32 tSR;
u32 tFAW;
double tCKCKEH;
// //
u32 marikoGpuVoltArray[24]; u32 marikoGpuVoltArray[24];

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -24,210 +24,88 @@ namespace ams::ldr::oc {
#define CEIL(A) std::ceil(A) #define CEIL(A) std::ceil(A)
#define FLOOR(A) std::floor(A) #define FLOOR(A) std::floor(A)
//Preset One
const std::array<u32, 6> tRCD_values = {18, 17, 16, 15, 14, 13};
const std::array<u32, 6> tRP_values = {18, 17, 16, 15, 14, 13};
const std::array<u32, 6> tRAS_values = {42, 39, 36, 34, 32, 30};
// Preset Two
const std::array<double, 5> tRRD_values = {10, 7.5, 6, 4, 3};
const std::array<double, 5> tFAW_values = {40, 30, 24, 16, 12};
// Preset Three
const std::array<u32, 6> tWR_values = {18, 15, 15, 12, 12, 8};
const std::array<double, 6> tRTP_values = {7.5, 7.5, 6, 6, 4, 4};
// Preset Four
const std::array<u32, 6> tRFC_values = {140, 120, 100, 80, 70, 60};
// Preset Five
const std::array<u32, 6> tWTR_values = {10, 8, 6, 4, 2, 1};
// Preset Six
const std::array<u32, 5> tREFpb_values = {488, 976, 1952, 3256, 9999};
const u32 TIMING_PRESET_ONE = C.ramTimingPresetOne;
const u32 TIMING_PRESET_TWO = C.ramTimingPresetTwo;
const u32 TIMING_PRESET_THREE = C.ramTimingPresetThree;
const u32 TIMING_PRESET_FOUR = C.ramTimingPresetFour;
const u32 TIMING_PRESET_FIVE = C.ramTimingPresetFive;
const u32 TIMING_PRESET_SIX = C.ramTimingPresetSix;
const u32 TIMING_PRESET_SEVEN = C.ramTimingPresetSeven;
// Burst Length
const u32 BL = 16;
// tRFCpb (refresh cycle time per bank) in ns for 8Gb density
const u32 tRFCpb = !TIMING_PRESET_FOUR ? 140 : tRFC_values[TIMING_PRESET_FOUR-1];
// tRFCab (refresh cycle time all banks) in ns for 8Gb density
const u32 tRFCab = !TIMING_PRESET_FOUR ? 280 : 2*tRFCpb;
// tRAS (row active time) in ns
const u32 tRAS = !TIMING_PRESET_ONE ? 42 : tRAS_values[TIMING_PRESET_ONE-1];
// tRPpb (row precharge time per bank) in ns
const u32 tRPpb = !TIMING_PRESET_ONE ? 18 : tRP_values[TIMING_PRESET_ONE-1];
// tRPab (row precharge time all banks) in ns
const u32 tRPab = !TIMING_PRESET_ONE ? 21 : tRPpb + 3;
// tRC (ACTIVATE-ACTIVATE command period same bank) in ns
const u32 tRC = tRPpb + tRAS;
// DQS output access time from CK_t/CK_c
const double tDQSCK_min = 1.5;
// DQS output access time from CK_t/CK_c
const double tDQSCK_max = 3.5;
// Write preamble (tCK)
const double tWPRE = 1.8;
// Read postamble (tCK)
const double tRPST = 0.4;
// WRITE command to first DQS transition(max) (tCK)
const double tDQSS_max = 1.25;
// DQ-to-DQS offset(max) (ns)
const double tDQS2DQ_max = 0.8;
// DQS_t, DQS_c to DQ skew total, per group, per access (DBI Disabled)
const double tDQSQ = 0.18;
// Write-to-Read delay
const u32 tWTR = !TIMING_PRESET_FIVE ? 10 : tWTR_values[TIMING_PRESET_FIVE-1];
// Internal READ-to-PRE-CHARGE command delay in ns
const double tRTP = !TIMING_PRESET_THREE ? 7.5 : tRTP_values[TIMING_PRESET_THREE-1];
// write recovery time
const u32 tWR = !TIMING_PRESET_THREE ? 18 : tWR_values[TIMING_PRESET_THREE-1];
// Read to refresh delay
const u32 tR2REF = tRTP + tRPpb;
// tRCD (RAS-CAS delay) in ns
const u32 tRCD = !TIMING_PRESET_ONE ? 18 : tRCD_values[TIMING_PRESET_ONE-1];
// tRRD (Active bank-A to Active bank-B) in ns
const double tRRD = !TIMING_PRESET_TWO ? 10. : tRRD_values[TIMING_PRESET_TWO-1];
// tREFpb (average refresh interval per bank) in ns for 8Gb density
const u32 tREFpb = !TIMING_PRESET_SIX ? 488 : tREFpb_values[TIMING_PRESET_SIX-1];
// tREFab (average refresh interval all 8 banks) in ns for 8Gb density
// const u32 tREFab = tREFpb * 8;
// tPDEX2WR, tPDEX2RD (timing delay from exiting powerdown mode to a write/read command) in ns
// const u32 tPDEX2 = 10;
// Exit power-down to next valid command delay
const double tXP = 10;
// Delay from valid command to CKE input LOW in ns
const double tCMDCKE = 1.75;
// tACT2PDEN (timing delay from an activate, MRS or EMRS command to power-down entry) in ns
// Valid clock and CS requirement after CKE input LOW after MRW command
const u32 tMRWCKEL = 14;
// Valid CS requirement after CKE input LOW
const double tCKELCS = 5;
// Valid CS requirement before CKE input HIGH
const double tCSCKEH = 1.75;
// tXSR (SELF REFRESH exit to next valid command delay) in ns
const double tXSR = tRFCab + 7.5;
// tCKE (minimum pulse width(HIGH and LOW pulse width)) in ns
const double tCKE = 7.5;
// Minimum self refresh time (entry to exit)
const u32 tSR = 15;
// tFAW (Four-bank Activate Window) in ns
const u32 tFAW = !TIMING_PRESET_TWO ? 40 : tFAW_values[TIMING_PRESET_TWO-1];
// Valid Clock requirement before CKE Input HIGH in ns
const double tCKCKEH = 1.75;
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ // p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
//const u32 QUSE = RL + CEIL(tDQSCK_min/tCK_avg + tDQSQ); //const u32 QUSE = RL + CEIL(C.tDQSCK_min/tCK_avg + C.tDQSQ);
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;
// Write Latency // Write Latency
const u32 WL = 14 - 2*TIMING_PRESET_SEVEN; const u32 WL = 14 - 2*C.latency;
// Read Latency // Read Latency
const u32 RL = 32 - 4*TIMING_PRESET_SEVEN; const u32 RL = 32 - 4*C.latency;
// minimum number of cycles from any read command to any write command, irrespective of bank // 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; const u32 R2W = CEIL (RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - WL + C.tWPRE + FLOOR(C.tRPST)) + 6;
// Delay Time From WRITE-to-READ // Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg) - 6; const u32 W2R = WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg) - 6;
// write-to-precharge time for commands to the same bank in cycles // write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8; const u32 WTP = WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg) - 8;
// #_of_rows per die for 8Gb density // #_of_rows per die for 8Gb density
const u32 numOfRows = 65536; const u32 numOfRows = 65536;
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%] // {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
// emc_clk_period = dram_clk / 2; // emc_clk_period = dram_clk / 2;
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin) // 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4); const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
const u32 REFBW = MIN((u32)65536, REFRESH+64); const u32 REFBW = MIN((u32)65536, REFRESH+64);
// Write With Auto Precharge to to Power-Down Entry // Write With Auto Precharge to to Power-Down Entry
const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6; const u32 WTPDEN = WTP + 1 + CEIL(C.tDQSS_max/tCK_avg) + CEIL(C.tDQS2DQ_max/tCK_avg) + 6;
// Additional time after t XP hasexpired until the MRR commandmay be issued // Additional time after t XP hasexpired until the MRR commandmay be issued
const double tMRRI = tRCD + 3 * tCK_avg; const double tMRRI = C.tRCD + 3 * tCK_avg;
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns // tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
const double tPDEX2MRR = tXP + tMRRI; const double tPDEX2MRR = C.tXP + tMRRI;
} }
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;
// Write Latency // Write Latency
const u32 WL = 14 - 2*TIMING_PRESET_SEVEN; const u32 WL = 14 - 2*C.latency;
// Read Latency // Read Latency
const u32 RL = 32 - 4*TIMING_PRESET_SEVEN; const u32 RL = 32 - 4*C.latency;
// minimum number of cycles from any read command to any write command, irrespective of bank // 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)); const u32 R2W = CEIL (RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - WL + C.tWPRE + FLOOR(C.tRPST));
// Delay Time From WRITE-to-READ // Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg); const u32 W2R = WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg);
// write-to-precharge time for commands to the same bank in cycles // write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg); const u32 WTP = WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg);
// Read-To-MRW delay // Read-To-MRW delay
const u32 RTM = RL + BL/2 + CEIL(tDQSCK_max/tCK_avg) + FLOOR(tRPST) + CEIL(7.5/tCK_avg); const u32 RTM = RL + C.BL/2 + CEIL(C.tDQSCK_max/tCK_avg) + FLOOR(C.tRPST) + CEIL(7.5/tCK_avg);
// Write-To-MRW/MRR delay // Write-To-MRW/MRR delay
const u32 WTM = WL + 1 + BL/2 + CEIL(7.5/tCK_avg); const u32 WTM = WL + 1 + C.BL/2 + CEIL(7.5/tCK_avg);
// Read With AP-To-MRW/MRR delay // Read With AP-To-MRW/MRR delay
const u32 RATM = RTM + CEIL(tRTP/tCK_avg) - 8; const u32 RATM = RTM + CEIL(C.tRTP/ 1000/tCK_avg) - 8;
// Write With AP-To-MRW/MRR delay // Write With AP-To-MRW/MRR delay
const u32 WATM = WTM + CEIL(tWR/tCK_avg); const u32 WATM = WTM + CEIL(C.tWR/tCK_avg);
// #_of_rows per die for 8Gb density // #_of_rows per die for 8Gb density
const u32 numOfRows = 65536; const u32 numOfRows = 65536;
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%] // {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
// emc_clk_period = dram_clk / 2; // emc_clk_period = dram_clk / 2;
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin) // 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
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(C.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);
// Write With Auto Precharge to to Power-Down Entry // Write With Auto Precharge to to Power-Down Entry
const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6; const u32 WTPDEN = WTP + 1 + CEIL(C.tDQSS_max/tCK_avg) + CEIL(C.tDQS2DQ_max/tCK_avg) + 6;
// Additional time after t XP hasexpired until the MRR commandmay be issued // Additional time after t XP hasexpired until the MRR commandmay be issued
const double tMRRI = tRCD + 3 * tCK_avg; const double tMRRI = C.tRCD + 3 * tCK_avg;
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns // tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
const double tPDEX2MRR = tXP + tMRRI; const double tPDEX2MRR = C.tXP + tMRRI;
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -350,12 +350,14 @@ namespace ams::ldr::oc::pcv
cvb_entry_t *entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head); cvb_entry_t *entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head);
for (size_t i = 0; i < customize_entry_count; i++) for (size_t i = 0; i < customize_entry_count; i++)
{ {
if (C.marikoGpuVoltArray[i] != 0) if (!(C.marikoGpuVoltArray[i] < C.gpuVmin))
{ {
u32 patched_voltage = C.marikoGpuVoltArray[i]; u32 patched_voltage = C.marikoGpuVoltArray[i];
if(!C.gpuVmax) {
if(patched_voltage > C.gpuVmax) { if(patched_voltage > C.gpuVmax) {
patched_voltage = C.gpuVmax; patched_voltage = C.gpuVmax;
} }
}
PATCH_OFFSET(&(entry->cvb_pll_param.c0), patched_voltage * 1000); PATCH_OFFSET(&(entry->cvb_pll_param.c0), patched_voltage * 1000);
PATCH_OFFSET(&(entry->cvb_pll_param.c1), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c1), 0);
PATCH_OFFSET(&(entry->cvb_pll_param.c2), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c2), 0);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -83,57 +83,57 @@ void MemMtcTableAutoAdjust(EristaMtcTable* table) {
#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(C.tRC));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab)); WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(C.tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb)); WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W); WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(C.tRTP/ 1000));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); 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(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
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);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(tXP)); WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(C.tXP));
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(tXP)); WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(C.tXP));
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(tCMDCKE)); WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(C.tCMDCKE));
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(tMRWCKEL)); WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(C.tMRWCKEL));
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(tCMDCKE)); WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(C.tCMDCKE));
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN); WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(tCKELCS)); WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(C.tCKELCS));
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(tCSCKEH)); WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(C.tCSCKEH));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR)); WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
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(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe)); WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(tCKE)); WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(C.tCKE));
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR)); WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(C.tSR));
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tCKE)); WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(C.tCKE));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW)); WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(C.tFAW));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(C.tRPab));
WRITE_PARAM_ALL_REG(table, emc_tclkstable, GET_CYCLE_CEIL(tCKCKEH)); WRITE_PARAM_ALL_REG(table, emc_tclkstable, GET_CYCLE_CEIL(C.tCKCKEH));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tCKE)+8); WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(C.tCKE)+8);
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;
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA; table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(C.tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(C.tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(C.tRTP/ 1000) / 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_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(C.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;
} }
@@ -144,69 +144,55 @@ void MemMtcTableCustomAdjust(EristaMtcTable* table) {
constexpr u32 MC_ARB_DIV = 4; constexpr u32 MC_ARB_DIV = 4;
constexpr u32 MC_ARB_SFA = 2; constexpr u32 MC_ARB_SFA = 2;
if (TIMING_PRESET_ONE) { WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(C.tRC));
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC)); WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(C.tRPab));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV - 2); table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV - 2);
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV - 1); table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(C.tRC) / MC_ARB_DIV - 1);
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA); table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA);
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV - 2); table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV - 2);
}
if (TIMING_PRESET_TWO) { WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(C.tFAW));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(C.tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
}
if (TIMING_PRESET_THREE) { WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(C.tRTP/ 1000));
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(C.tRTP/ 1000) / 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_wap2pre = CEIL(WTP / MC_ARB_DIV);
}
if (TIMING_PRESET_FOUR) { WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(C.tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
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(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
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(C.tRFCpb) / MC_ARB_DIV);
}
if (TIMING_PRESET_FIVE) { WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
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;
}
if (TIMING_PRESET_SIX) { 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); WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
}
if (TIMING_PRESET_SEVEN) { WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W); WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
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_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;
}
u32 DA_TURNS = 0; u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -187,44 +187,44 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
#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(C.tRC));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab)); WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(C.tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb)); WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W); WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(C.tRTP/ 1000));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_trtm, RTM); WRITE_PARAM_ALL_REG(table, emc_trtm, RTM);
WRITE_PARAM_ALL_REG(table, emc_twtm, WTM); WRITE_PARAM_ALL_REG(table, emc_twtm, WTM);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM); WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM); WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
//WRITE_PARAM_ALL_REG(table, emc_tr2ref, GET_CYCLE_CEIL(tR2REF)); //WRITE_PARAM_ALL_REG(table, emc_tr2ref, GET_CYCLE_CEIL(C.tR2REF));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
WRITE_PARAM_ALL_REG(table, emc_rext, 26); WRITE_PARAM_ALL_REG(table, emc_rext, 26);
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);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(tXP)); WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(C.tXP));
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(tXP)); WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE_CEIL(C.tXP));
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(tCMDCKE)); WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(C.tCMDCKE));
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(tMRWCKEL)); WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(C.tMRWCKEL));
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(tCMDCKE)); WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(C.tCMDCKE));
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN); WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(tCKELCS)); WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(C.tCKELCS));
//WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(tCSCKEH)); //WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(C.tCSCKEH));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR)); WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
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(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe)); WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(tCKE) + 1); WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(C.tCKE) + 1);
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR)); WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(C.tSR));
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tCKE)); WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(C.tCKE));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW)); WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(C.tFAW));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(C.tRPab));
//WRITE_PARAM_ALL_REG(table, emc_tclkstable, GET_CYCLE_CEIL(tCKCKEH)); //WRITE_PARAM_ALL_REG(table, emc_tclkstable, GET_CYCLE_CEIL(C.tCKCKEH));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tCKE) + 8); WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(C.tCKE) + 8);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW); WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
ADJUST_PARAM_ALL_REG(table, emc_dyn_self_ref_control, ref); ADJUST_PARAM_ALL_REG(table, emc_dyn_self_ref_control, ref);
@@ -234,7 +234,7 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
BITS = BITS & ~( ((1u << HIGH) << 1u) - (1u << LOW) ); BITS = BITS & ~( ((1u << HIGH) << 1u) - (1u << LOW) );
#define ADJUST(TARGET) (u32)CEIL(TARGET * (C.marikoEmcMaxClock / EmcClkOSLimit)) #define ADJUST(TARGET) (u32)CEIL(TARGET * (C.marikoEmcMaxClock / EmcClkOSLimit))
#define ADJUST_INVERSE(TARGET) (u32)(TARGET * (EmcClkOSLimit / 1000) / (C.marikoEmcMaxClock / 1000)) #define ADJUST_INVERSE(TARGET) (u32)(TARGET * (EmcClkOSLimit / 1000) / (C.marikoEmcMaxClock))
// 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;
@@ -243,18 +243,18 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
constexpr u32 MC_ARB_SFA = 2; 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_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_rcd, CEIL(GET_CYCLE_CEIL(C.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_rp, CEIL(GET_CYCLE_CEIL(C.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_rc, CEIL(GET_CYCLE_CEIL(C.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_ras, CEIL(GET_CYCLE_CEIL(C.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_faw, CEIL(GET_CYCLE_CEIL(C.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_rrd, CEIL(GET_CYCLE_CEIL(C.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_rap2pre, CEIL(GET_CYCLE_CEIL(C.tRTP/ 1000) / 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_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_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_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_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_BURST_MC_REG(table, mc_emem_arb_timing_rfcpb, CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV))
u32 DA_TURNS = 0; u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN
@@ -323,8 +323,8 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
table->pllmb_ss_ctrl1 = 0x0b55fe01; table->pllmb_ss_ctrl1 = 0x0b55fe01;
table->pllmb_ss_ctrl2 = 0x10170b55; table->pllmb_ss_ctrl2 = 0x10170b55;
table->dram_timings.t_rp = tRPpb; table->dram_timings.t_rp = C.tRPpb;
table->dram_timings.t_rfc = tRFCab; table->dram_timings.t_rfc = C.tRFCab;
//table->dram_timings.rl = 32; //table->dram_timings.rl = 32;
table->emc_cfg_2 = 0x0011083d; table->emc_cfg_2 = 0x0011083d;
@@ -337,76 +337,62 @@ void MemMtcTableCustomAdjust(MarikoMtcTable* table) {
constexpr u32 MC_ARB_DIV = 4; constexpr u32 MC_ARB_DIV = 4;
constexpr u32 MC_ARB_SFA = 2; constexpr u32 MC_ARB_SFA = 2;
if (TIMING_PRESET_ONE) { WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(C.tRC));
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC)); WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS)); WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb)); WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(C.tRPab));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab)); WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_pdex2mrr,GET_CYCLE_CEIL(tPDEX2MRR));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr,GET_CYCLE_CEIL(tPDEX2MRR));
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(C.tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA; table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2;
}
if (TIMING_PRESET_TWO) { WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(C.tFAW));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(C.tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
}
if (TIMING_PRESET_THREE) { WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(C.tRTP/ 1000));
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP)); WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM); WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM); WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(C.tRTP/ 1000) / 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_wap2pre = CEIL(WTP / MC_ARB_DIV);
}
if (TIMING_PRESET_FOUR) { WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(C.tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
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(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
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(C.tRFCpb) / MC_ARB_DIV);
}
if (TIMING_PRESET_FIVE) { WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
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;
}
if (TIMING_PRESET_SIX) { 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); WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
}
if (TIMING_PRESET_SEVEN) { WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W); WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R); WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP); WRITE_PARAM_ALL_REG(table, emc_trtm, RTM);
WRITE_PARAM_ALL_REG(table, emc_trtm, RTM); WRITE_PARAM_ALL_REG(table, emc_twtm, WTM);
WRITE_PARAM_ALL_REG(table, emc_twtm, WTM); WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM); WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM); WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
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_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;
}
u32 DA_TURNS = 0; u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) hanai3bi (meha) and Souldbminer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -13,7 +13,7 @@
* *
*/ */
#define __version__ "4.5.1-multithread" #define __version__ "4.5.1-multithread-ocs2"
// Include the most common headers from the C standard library // Include the most common headers from the C standard library
#include <stddef.h> #include <stddef.h>
@@ -241,9 +241,10 @@ int main(int argc, char* argv[])
bool isDevKit8GB = false; bool isDevKit8GB = false;
printf("MemTesterNX version " __version__ " (%d-bit)\n"\ printf("MemTesterNX version " __version__ " (%d-bit)\n"\
"Based on memtester. Copyright (C) 2001-2020 Charles Cazabon, 2021 KazushiMe.\n"\ "Based on memtester. Copyright (C) 2001-2020 Charles Cazabon, 2021 KazushiMe, 2025 Souldbminer.\n"\
"Licensed under the GNU General Public License version 2 (only).\n\n"\ "Licensed under the GNU General Public License version 2 (only).\n\n"\
"Support full RAM test (up to 8GB) with 3-4 threads.\n"\ "Support full RAM test (up to 8GB) with 3-4 threads.\n"\
"Ensure to set your CPU and GPU freq to maximum to get the best result.\n"\
"It will be looping forever until error occurs or user exits to HOME screen.\n\n"\ "It will be looping forever until error occurs or user exits to HOME screen.\n\n"\
"Press A: long test\n"\ "Press A: long test\n"\
"Press X: fast test\n"\ "Press X: fast test\n"\

View File

@@ -99,7 +99,7 @@ double ptoGetMHz(PTO_ID pto_id, u32 divider = 1, u32 presel_reg = 0, u32 presel_
val &= 0xFFFFFF; val &= 0xFFFFFF;
val *= divider; val *= divider;
double rate_mhz = (u64)val * 32768. / cycle_count / 1000. / 1000.; double rate_mhz = (u64)val * 32768. / cycle_count / 1000..;
usleep(10); usleep(10);
REG(clkrst_base + 0x60) = pre_val; REG(clkrst_base + 0x60) = pre_val;
usleep(10); usleep(10);

View File

@@ -93,8 +93,11 @@ class AdvEntry extends CustEntry {
e.value = String(this.value) e.value = String(this.value)
} }
} }
class GpuEntry extends CustEntry { class GpuEntry extends CustEntry {
constructor(e, t, i = CustPlatform.Mariko, n = 4, a = ["range: 480 ≤ x ≤ 960 (Zero is disabled)"], r = 480, s = [0, 960], l = 5, o = !1) { constructor(e, t, i = CustPlatform.Mariko, n = 4, a = ["range: vMin ≤ x ≤ 960 (Zero is disabled)"], r = 480, s = [0, 960], l = 5, o = !1) {
super(e, t, i, n, a, r, s, l, o), this.id = e, this.name = t, this.platform = i, this.size = n, this.desc = a, this.defval = r, this.step = l, this.zeroable = o super(e, t, i, n, a, r, s, l, o), this.id = e, this.name = t, this.platform = i, this.size = n, this.desc = a, this.defval = r, this.step = l, this.zeroable = o
} }
createElement() { createElement() {
@@ -214,6 +217,13 @@ var CustTable = [
"Anything above 800MV is considered UNSAFE (although it depends per frequency)" "Anything above 800MV is considered UNSAFE (although it depends per frequency)"
], 800, [480, 1000], 1, !1), ], 800, [480, 1000], 1, !1),
new CustEntry("gpuVmin", "Mariko Minimum allowed GPU Voltage (mV)", CustPlatform.Mariko, 4, [
"Default: 600",
"This is the minimum voltage you can use in GPU UV3.",
"A higher Vmin is required for a higher max ram clock"
], 600, [480, 1000], 1, !1),
]; ];
var AdvTable = [ var AdvTable = [
@@ -224,94 +234,7 @@ var AdvTable = [
"Acceptable range : 0~9" "Acceptable range : 0~9"
], 0, [0, 9], 1), ], 0, [0, 9], 1),
new AdvEntry("ramTimingPresetOne", "Primary RAM Timing Preset", CustPlatform.All, 4, [
"<b>WARNING</b>: Unstable timings can corrupt your nand",
"Select Timing Preset for both AUTO_ADJ and CUSTOM_ADJ",
"Values are : tRCD - tRP - tRAS (tRC = tRP + tRAS)",
"<b>0</b> : Do Not Adjust (2400Mhz: 12 - 12 - 28) (CUST_ADJ only)",
"<b>1</b> : 18 - 18 - 42 (Default timing)",
"<b>2</b> : 17 - 17 - 39",
"<b>3</b> : 16 - 16 - 36",
"<b>4</b> : 15 - 15 - 34",
"<b>5</b> : 14 - 14 - 32",
"<b>6</b> : 13 - 13 - 30"
], 1, [0, 6], 1),
new AdvEntry("ramTimingPresetTwo", "Secondary RAM Timing Preset", CustPlatform.All, 4, [
"WARNING: Unstable timings can corrupt your nand",
"Secondary Timing Preset for both AUTO_ADJ and CUSTOM_ADJ",
"Values are : tRRD - tFAW",
"<b>0</b> : Do Not Adjust (2400Mhz: 6.6 - 26.6) (CUST_ADJ only)",
"<b>1</b> : 10 - 40 (Default timing) (3733 specs)",
"<b>2</b> : 7.5 - 30 (4266 specs)",
"<b>3</b> : 6 - 24",
"<b>4</b> : 4 - 16",
"<b>5</b> : 3 - 12"
], 1, [0, 5], 1),
new AdvEntry("ramTimingPresetThree", "Secondary RAM Timing Preset", CustPlatform.All, 4, [
"WARNING: Unstable timings can corrupt your nand",
"Secondary Timing Preset for both AUTO_ADJ and CUSTOM_ADJ",
"Values are : tWR - tRTP",
"<b>0</b> : Do Not Adjust (2400Mhz: ?? - 5) (CUST_ADJ only)",
"<b>1</b> : 18 - 7.5 (Default timing)",
"<b>2</b> : 15 - 7.5",
"<b>3</b> : 15 - 6",
"<b>4</b> : 12 - 6",
"<b>5</b> : 12 - 4",
"<b>6</b> : 8 - 4"
], 1, [0, 6], 1),
new AdvEntry("ramTimingPresetFour", "Secondary RAM Timing Preset", CustPlatform.All, 4, [
"WARNING: Unstable timings can corrupt your nand",
"Secondary Timing Preset for both AUTO_ADJ and CUSTOM_ADJ",
"Values are : tRFC",
"<b>0</b> : Do Not Adjust (2400Mhz: 93.3) (CUST_ADJ only)",
"<b>1</b> : 140 (Default timing)",
"<b>2</b> : 120",
"<b>3</b> : 100",
"<b>4</b> : 80",
"<b>5</b> : 70",
"<b>6</b> : 60"
], 1, [0, 6], 1),
new AdvEntry("ramTimingPresetFive", "Secondary RAM Timing Preset", CustPlatform.All, 4, [
"WARNING: Unstable timings can corrupt your nand",
"Secondary Timing Preset for both AUTO_ADJ and CUSTOM_ADJ",
"Values are : tWTR",
"<b>0</b> : Do Not Adjust (2400Mhz: ??) (CUST_ADJ only)",
"<b>1</b> : 10 (Default timing)",
"<b>2</b> : 8",
"<b>3</b> : 6",
"<b>4</b> : 4",
"<b>5</b> : 2",
"<b>6</b> : 1"
], 1, [0, 6], 1),
new AdvEntry("ramTimingPresetSix", "Tertiary RAM Timing Preset", CustPlatform.All, 4, [
"WARNING: Unstable timings can corrupt your nand",
"Tertiary Timing Preset for both AUTO_ADJ and CUSTOM_ADJ",
"Values are : tREFpb",
"<b>0</b> : Do Not Adjust (2400Mhz: 325) (CUST_ADJ only)",
"<b>1</b> : 488 (Default timing)",
"<b>2</b> : 976",
"<b>3</b> : 1952",
"<b>4</b> : 3256",
"<b>5</b> : MAX"
], 1, [0, 5], 1),
new AdvEntry("ramTimingPresetSeven", "Latency Decrement", CustPlatform.All, 4, [
"WARNING: Unstable timings can corrupt your nand",
"Latency decrement for both AUTO_ADJ and CUSTOM_ADJ",
"This preset decreases Write/Read related delays. Values are Write - Read",
"<b>0</b> : 0 - 0, Do Not Adjust for CUST_ADJ",
"<b>1</b> : '-2' - '-4'",
"<b>2</b> : '-4' - '-8'",
"<b>3</b> : '-6' - '-12'",
"<b>4</b> : '-8' - '-16'",
"<b>5</b> : '-10' - '-20'",
"<b>6</b> : '-12' - '-24'"
], 0, [0, 6], 1)
]; ];
var GpuTable = [ var GpuTable = [