Merge branch 'develop' of https://github.com/Horizon-OC/Horizon-OC into develop
This commit is contained in:
@@ -35,7 +35,7 @@ enum MtcConfig: u32 {
|
||||
};
|
||||
|
||||
enum TableConfig: u32 {
|
||||
AUTO = 0, /* Auto is not supported yet. */
|
||||
AUTO_DEPRECATED = 0,
|
||||
DEFAULT_TABLE = 1,
|
||||
TBREAK_1581 = 2,
|
||||
TBREAK_1683 = 3,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "timing_tables.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
u32 calcClock;
|
||||
|
||||
u32 GetRext() {
|
||||
if (auto r = FindRext()) {
|
||||
return r->correct;
|
||||
@@ -35,7 +35,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
for (u32 i = 0; i < g_misc_table_size; i++) {
|
||||
const auto& e = g_misc_table[i];
|
||||
if (calcClock >= e.min_freq) {
|
||||
if (C.marikoEmcMaxClock >= e.min_freq) {
|
||||
rdv += e.rdv_inc;
|
||||
if (e.einput) einput_duration = e.einput;
|
||||
if (e.quse_width) quse_width = e.quse_width;
|
||||
@@ -64,8 +64,8 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
void CalculateTWTPDEN() {
|
||||
tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6;
|
||||
if (calcClock >= 2'233'000 && calcClock < 2'533'000) tWTPDEN++;
|
||||
if (calcClock >= 2'433'000 && calcClock < 2'800'000) tWTPDEN--;
|
||||
if (C.marikoEmcMaxClock >= 2'233'000 && C.marikoEmcMaxClock < 2'533'000) tWTPDEN++;
|
||||
if (C.marikoEmcMaxClock >= 2'433'000 && C.marikoEmcMaxClock < 2'800'000) tWTPDEN--;
|
||||
}
|
||||
|
||||
void CalculateTR2W() {
|
||||
@@ -78,12 +78,12 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
void CalculateQrst() {
|
||||
qrst = 0x00070000;
|
||||
u32 qrst_calc = ROUND(22.1 - (calcClock / 1000000.0) * 8.0) + C.mem_burst_read_latency;
|
||||
u32 qrst_calc = ROUND(22.1 - (C.marikoEmcMaxClock / 1000000.0) * 8.0) + C.mem_burst_read_latency;
|
||||
u32 qrst_low = MAX(static_cast<u32>(0), qrst_calc);
|
||||
|
||||
if (calcClock >= 2'533'000) {
|
||||
if (C.marikoEmcMaxClock >= 2'533'000) {
|
||||
qrst = INCREMENT_HIGH_BYTES_BY(qrst, 1);
|
||||
} else if (calcClock == 2'800'000) {
|
||||
} else if (C.marikoEmcMaxClock == 2'800'000) {
|
||||
qrst = SET_HIGH_BYTES(qrst, 6);
|
||||
}
|
||||
|
||||
@@ -95,20 +95,20 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
}
|
||||
|
||||
void CalculateQsafe() {
|
||||
qsafe = ROUND((calcClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency;
|
||||
qsafe = ROUND((C.marikoEmcMaxClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency;
|
||||
if (auto patch = FindQsafePatch()) {
|
||||
qsafe += patch->adjust;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateQpop() {
|
||||
qpop = FLOOR(((calcClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency;
|
||||
qpop = FLOOR(((C.marikoEmcMaxClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency;
|
||||
|
||||
if (calcClock >= 3'133'000) qpop++;
|
||||
if (C.marikoEmcMaxClock >= 3'133'000) qpop++;
|
||||
}
|
||||
|
||||
void CalculatePdex2rw() {
|
||||
double freq_mhz = calcClock / 1000.0;
|
||||
double freq_mhz = C.marikoEmcMaxClock / 1000.0;
|
||||
|
||||
double pdex_local = (0.011 * freq_mhz) - 1.443;
|
||||
pdex2rw = static_cast<u32>(ROUND(pdex_local));
|
||||
@@ -122,16 +122,14 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
}
|
||||
|
||||
void CalculateCke2pden() {
|
||||
cke2pden = (static_cast<double>((calcClock / 1000.0) * 0.00875) - 0.65);
|
||||
cke2pden = (static_cast<double>((C.marikoEmcMaxClock / 1000.0) * 0.00875) - 0.65);
|
||||
|
||||
if (auto patch = FindCke2pdenPatch()) {
|
||||
cke2pden += patch->adjust;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateTimings(u32 rate_khz) {
|
||||
calcClock = rate_khz;
|
||||
SetTableMaxClock(rate_khz);
|
||||
void CalculateTimings() {
|
||||
CalculateMiscTimings();
|
||||
CalculateIbdly();
|
||||
CalculateObdly();
|
||||
@@ -144,4 +142,4 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
CalculateCke2pden();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
void CalculateTimings(u32 rate_khz);
|
||||
}
|
||||
|
||||
void CalculateTimings();
|
||||
|
||||
}
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
#include "timing_tables.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
u32 clkMax;
|
||||
|
||||
void SetTableMaxClock(u32 maxClock) {
|
||||
clkMax = maxClock;
|
||||
}
|
||||
const MiscTimings g_misc_table[] = {
|
||||
{1'866'000, 1, 0x20, 0x9, },
|
||||
{2'133'000, 1, 0x24, 0xA, },
|
||||
@@ -69,7 +65,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const ReplacePatch *FindRext() {
|
||||
for (u32 i = 0; i < g_rext_table_size; i++)
|
||||
if (g_rext_table[i].freq == clkMax)
|
||||
if (g_rext_table[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_rext_table[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -96,7 +92,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindIbdlyPatch() {
|
||||
for (u32 i = 0; i < g_ibdly_table_size; i++)
|
||||
if (g_ibdly_patches[i].freq == clkMax)
|
||||
if (g_ibdly_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_ibdly_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -129,7 +125,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindObdlyPatch() {
|
||||
for (u32 i = 0; i < g_obdly_table_size; i++)
|
||||
if (g_obdly_patches[i].freq == clkMax)
|
||||
if (g_obdly_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_obdly_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -147,7 +143,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindTR2WPatch() {
|
||||
for (u32 i = 0; i < g_tr2w_table_size; i++)
|
||||
if (g_tr2w_patches[i].freq == clkMax)
|
||||
if (g_tr2w_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_tr2w_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -182,7 +178,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindQrstPatch() {
|
||||
for (u32 i = 0; i < g_qrst_table_size; i++)
|
||||
if (g_qrst_patches[i].freq == clkMax)
|
||||
if (g_qrst_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_qrst_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -213,7 +209,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindQsafePatch() {
|
||||
for (u32 i = 0; i < g_qsafe_table_size; i++)
|
||||
if (g_qsafe_patches[i].freq == clkMax)
|
||||
if (g_qsafe_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_qsafe_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -238,7 +234,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindPdex2rwPatch() {
|
||||
for (u32 i = 0; i < g_pdex2rw_table_size; i++)
|
||||
if (g_pdex2rw_patches[i].freq == clkMax)
|
||||
if (g_pdex2rw_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_pdex2rw_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
@@ -264,9 +260,9 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
const AdjustPatch *FindCke2pdenPatch() {
|
||||
for (u32 i = 0; i < g_cke2pden_table_size; i++)
|
||||
if (g_cke2pden_patches[i].freq == clkMax)
|
||||
if (g_cke2pden_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_cke2pden_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "../mtc_timing_value.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
void SetTableMaxClock(u32 maxClock);
|
||||
|
||||
struct ReplacePatch {
|
||||
u32 freq;
|
||||
u32 correct;
|
||||
@@ -71,4 +71,4 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
extern const MiscTimings g_misc_table[];
|
||||
extern const u32 g_misc_table_size;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2025 Lightos_
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mtc_timing_value.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock;
|
||||
u32 tRCD = tRCD_values[C.t1_tRCD];
|
||||
u32 tRPpb = tRP_values[C.t2_tRP];
|
||||
u32 tRAS = tRAS_values[C.t3_tRAS];
|
||||
double tRRD = tRRD_values[C.t4_tRRD];
|
||||
u32 tRFCpb = tRFC_values[C.t5_tRFC];
|
||||
u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
|
||||
u32 tRC = tRAS + tRPpb;
|
||||
u32 tRFCab = tRFCpb * 2;
|
||||
double tXSR = (double) (tRFCab + 7.5);
|
||||
u32 tFAW = static_cast<u32>(tRRD * 4.0);
|
||||
double tRPab = tRPpb + 3;
|
||||
u32 tR2P = 12 + (C.mem_burst_read_latency / 2);
|
||||
u32 tR2W = 0;
|
||||
u32 tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(10 / tCK_avg);
|
||||
u32 tRATM = tRTM + CEIL(10 / tCK_avg) - 12;
|
||||
u32 rdv = 0;
|
||||
u32 quse = FLOOR((-0.0048159 * (C.marikoEmcMaxClock / 1000.0)) + RL_DBI) + (FLOOR((C.marikoEmcMaxClock / 1000.0) * 0.0050997) * 1.5134);
|
||||
u32 einput = quse - ((C.marikoEmcMaxClock / 1000.0) * 0.01);
|
||||
u32 einput_duration = 0;
|
||||
u32 ibdly = 0;
|
||||
u32 obdly = 0;
|
||||
u32 quse_width = 0;
|
||||
u32 rext = 0;
|
||||
u32 qrst = 0;
|
||||
u32 qsafe = 0;
|
||||
u32 qpop = 0;
|
||||
u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
u32 tWTPDEN = 0;
|
||||
u32 tW2R = CEIL(MAX(WL + (0.010322547033278747 * (C.marikoEmcMaxClock / 1000.0)), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg));
|
||||
u32 tWTM = WL + (BL / 2) + 1 + CEIL(7.5 / tCK_avg);
|
||||
u32 tWATM = tWTM + CEIL(tWR / tCK_avg);
|
||||
u32 wdv = WL;
|
||||
u32 wsv = WL - 2;
|
||||
u32 wev = 0xA + C.mem_burst_write_latency;
|
||||
u32 pdex2rw = 0;
|
||||
u32 cke2pden = 0;
|
||||
u32 tCKE = CEIL(1.0795 * CEIL(0.0074472 * (C.marikoEmcMaxClock / 1000.0)));
|
||||
double tMMRI = tRCD + (tCK_avg * 3);
|
||||
double pdex2mrr = tMMRI + 10;
|
||||
}
|
||||
@@ -111,46 +111,54 @@ namespace ams::ldr::oc {
|
||||
}
|
||||
|
||||
namespace pcv::mariko {
|
||||
extern double tCK_avg;
|
||||
extern u32 tRCD;
|
||||
extern u32 tRPpb;
|
||||
extern u32 tRAS;
|
||||
extern double tRRD;
|
||||
extern u32 tRFCpb;
|
||||
extern u32 tWTR;
|
||||
extern u32 tRC;
|
||||
extern u32 tRFCab;
|
||||
extern double tXSR;
|
||||
extern u32 tFAW;
|
||||
extern double tRPab;
|
||||
extern u32 tR2P;
|
||||
extern u32 tR2W;
|
||||
extern u32 tRTM;
|
||||
extern u32 tRATM;
|
||||
extern u32 rdv;
|
||||
extern u32 quse;
|
||||
extern u32 einput;
|
||||
extern u32 einput_duration;
|
||||
extern u32 ibdly;
|
||||
extern u32 obdly;
|
||||
extern u32 quse_width;
|
||||
extern u32 rext;
|
||||
extern u32 qrst;
|
||||
extern u32 qsafe;
|
||||
extern u32 qpop;
|
||||
extern u32 tW2P;
|
||||
extern u32 tWTPDEN;
|
||||
extern u32 tW2R;
|
||||
extern u32 tWTM;
|
||||
extern u32 tWATM;
|
||||
extern u32 wdv;
|
||||
extern u32 wsv;
|
||||
extern u32 wev;
|
||||
extern u32 pdex2rw;
|
||||
extern u32 cke2pden;
|
||||
extern u32 tCKE;
|
||||
extern double tMMRI;
|
||||
extern double pdex2mrr;
|
||||
const double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock;
|
||||
|
||||
const u32 tRCD = tRCD_values[C.t1_tRCD];
|
||||
const u32 tRPpb = tRP_values[C.t2_tRP];
|
||||
const u32 tRAS = tRAS_values[C.t3_tRAS];
|
||||
const double tRRD = tRRD_values[C.t4_tRRD];
|
||||
const u32 tRFCpb = tRFC_values[C.t5_tRFC];
|
||||
const u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
|
||||
|
||||
const u32 tRC = tRAS + tRPpb;
|
||||
const u32 tRFCab = tRFCpb * 2;
|
||||
const double tXSR = (double) (tRFCab + 7.5);
|
||||
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
|
||||
const double tRPab = tRPpb + 3;
|
||||
|
||||
const u32 tR2P = 12 + (C.mem_burst_read_latency / 2);
|
||||
inline u32 tR2W;
|
||||
const u32 tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(10 / tCK_avg); // Fix?
|
||||
const u32 tRATM = tRTM + CEIL(10 / tCK_avg) - 12; // Fix?
|
||||
inline u32 rdv;
|
||||
const u32 quse = FLOOR((-0.0048159 * (C.marikoEmcMaxClock / 1000.0)) + RL_DBI) + (FLOOR((C.marikoEmcMaxClock / 1000.0) * 0.0050997) * 1.5134);
|
||||
const u32 einput = quse - ((C.marikoEmcMaxClock / 1000.0) * 0.01);
|
||||
inline u32 einput_duration;
|
||||
inline u32 ibdly;
|
||||
inline u32 obdly;
|
||||
inline u32 quse_width;
|
||||
inline u32 rext;
|
||||
inline u32 qrst;
|
||||
inline u32 qsafe;
|
||||
inline u32 qpop;
|
||||
|
||||
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
inline u32 tWTPDEN;
|
||||
const u32 tW2R = CEIL(MAX(WL + (0.010322547033278747 * (C.marikoEmcMaxClock / 1000.0)), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg));
|
||||
const u32 tWTM = WL + (BL / 2) + 1 + CEIL(7.5 / tCK_avg);
|
||||
const u32 tWATM = tWTM + CEIL(tWR / tCK_avg);
|
||||
|
||||
const u32 wdv = WL;
|
||||
const u32 wsv = WL - 2;
|
||||
const u32 wev = 0xA + C.mem_burst_write_latency;
|
||||
|
||||
inline u32 pdex2rw;
|
||||
inline u32 cke2pden;
|
||||
|
||||
const u32 tCKE = CEIL(1.0795 * CEIL(0.0074472 * (C.marikoEmcMaxClock / 1000.0)));
|
||||
|
||||
const double tMMRI = tRCD + (tCK_avg * 3);
|
||||
const double pdex2mrr = tMMRI + 10; /* Do this properly? */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Copyright (c) Souldbminer and Horizon OC Contributors
|
||||
*
|
||||
* Copyright (c) 2025 Lightos_
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
@@ -302,7 +304,7 @@ namespace ams::ldr::oc::pcv {
|
||||
|
||||
if (isMariko) {
|
||||
switch (C.tableConf) {
|
||||
case AUTO:
|
||||
case AUTO_DEPRECATED:
|
||||
case TBREAK_1683: {
|
||||
customize_table = const_cast<cvb_entry_t *>(C.marikoCpuDvfsTable1683Tbreak);
|
||||
break;
|
||||
|
||||
@@ -413,34 +413,6 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
}
|
||||
|
||||
void MemMtcTableAutoAdjust(MarikoMtcTable *table) {
|
||||
tCK_avg = 1000'000.0 / table->rate_khz;
|
||||
tRCD = tRCD_values[C.t1_tRCD];
|
||||
tRPpb = tRP_values[C.t2_tRP];
|
||||
tRAS = tRAS_values[C.t3_tRAS];
|
||||
tRRD = tRRD_values[C.t4_tRRD];
|
||||
tRFCpb = tRFC_values[C.t5_tRFC];
|
||||
tWTR = 10 - tWTR_values[C.t7_tWTR];
|
||||
tRC = tRAS + tRPpb;
|
||||
tRFCab = tRFCpb * 2;
|
||||
tXSR = (double) (tRFCab + 7.5);
|
||||
tFAW = static_cast<u32>(tRRD * 4.0);
|
||||
tRPab = tRPpb + 3;
|
||||
tR2P = 12 + (C.mem_burst_read_latency / 2);
|
||||
tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(10 / tCK_avg); // Fix?
|
||||
tRATM = tRTM + CEIL(10 / tCK_avg) - 12; // Fix?
|
||||
quse = FLOOR((-0.0048159 * (table->rate_khz / 1000.0)) + RL_DBI) + (FLOOR((table->rate_khz / 1000.0) * 0.0050997) * 1.5134);
|
||||
einput = quse - ((table->rate_khz / 1000.0) * 0.01);
|
||||
tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
tW2R = CEIL(MAX(WL + (0.010322547033278747 * (table->rate_khz / 1000.0)), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg));
|
||||
tWTM = WL + (BL / 2) + 1 + CEIL(7.5 / tCK_avg);
|
||||
tWATM = tWTM + CEIL(tWR / tCK_avg);
|
||||
wdv = WL;
|
||||
wsv = WL - 2;
|
||||
wev = 0xA + C.mem_burst_write_latency;
|
||||
tCKE = CEIL(1.0795 * CEIL(0.0074472 * (table->rate_khz / 1000.0)));
|
||||
tMMRI = tRCD + (tCK_avg * 3);
|
||||
pdex2mrr = tMMRI + 10; /* Do this properly? */
|
||||
|
||||
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
|
||||
TABLE->burst_regs.PARAM = VALUE; \
|
||||
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
|
||||
@@ -463,7 +435,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
u32 trefbw = refresh_raw + 0x40;
|
||||
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
|
||||
|
||||
CalculateTimings(table->rate_khz);
|
||||
CalculateTimings();
|
||||
|
||||
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
|
||||
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
|
||||
@@ -490,7 +462,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
WRITE_PARAM_ALL_REG(table, emc_twtm, tWTM);
|
||||
WRITE_PARAM_ALL_REG(table, emc_twatm, tWATM);
|
||||
WRITE_PARAM_ALL_REG(table, emc_rext, rext);
|
||||
WRITE_PARAM_ALL_REG(table, emc_wext, (table->rate_khz >= 2533000) ? 0x19 : 0x16);
|
||||
WRITE_PARAM_ALL_REG(table, emc_wext, (C.marikoEmcMaxClock >= 2533000) ? 0x19 : 0x16);
|
||||
WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
|
||||
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4);
|
||||
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
|
||||
@@ -537,7 +509,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
constexpr double MC_ARB_DIV = 4.0;
|
||||
constexpr u32 MC_ARB_SFA = 2;
|
||||
|
||||
table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV;
|
||||
table->burst_mc_regs.mc_emem_arb_cfg = C.marikoEmcMaxClock / (33.3 * 1000) / MC_ARB_DIV;
|
||||
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_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1;
|
||||
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
|
||||
@@ -572,7 +544,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x115;
|
||||
|
||||
if (table->rate_khz >= 2133000) {
|
||||
if (C.marikoEmcMaxClock >= 2133000) {
|
||||
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1F;
|
||||
} else {
|
||||
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1B;
|
||||
@@ -584,11 +556,11 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
constexpr u32 Mask2 = 0xFFFFFF00;
|
||||
constexpr u32 Mask3 = 0xFF00FF00;
|
||||
|
||||
const u32 allowance1 = static_cast<u32>(0x32000 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance2 = static_cast<u32>(0x9C40 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance3 = static_cast<u32>(0xB540 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance4 = static_cast<u32>(0x9600 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance5 = static_cast<u32>(0x8980 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance1 = static_cast<u32>(0x32000 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance2 = static_cast<u32>(0x9C40 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance3 = static_cast<u32>(0xB540 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance4 = static_cast<u32>(0x9600 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance5 = static_cast<u32>(0x8980 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
|
||||
table->la_scale_regs.mc_latency_allowance_xusb_0 = (table->la_scale_regs.mc_latency_allowance_xusb_0 & MaskHigh) | (allowance1 << 16);
|
||||
table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & MaskHigh) | (allowance1 << 16);
|
||||
@@ -616,7 +588,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
table->emc_mrw2 = 0x8802003F;
|
||||
table->emc_cfg_2 = 0x11083D;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
@@ -836,24 +808,24 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
constexpr u32 PllOscInKHz = 38400;
|
||||
constexpr u32 PllOscHalfKHz = 19200;
|
||||
|
||||
double target_freq_d = static_cast<double>(table->rate_khz);
|
||||
double target_freq_d = static_cast<double>(C.marikoEmcMaxClock);
|
||||
|
||||
s32 divm_candidate_half = static_cast<u8>(table->rate_khz / PllOscHalfKHz);
|
||||
s32 divm_candidate_half = static_cast<u8>(C.marikoEmcMaxClock / PllOscHalfKHz);
|
||||
|
||||
bool remainder_check = (table->rate_khz - PllOscInKHz * (table->rate_khz / PllOscInKHz)) > (table->rate_khz - PllOscHalfKHz * divm_candidate_half) && static_cast<int>(((target_freq_d / PllOscHalfKHz - divm_candidate_half - 0.5) * 8192.0)) != 0;
|
||||
bool remainder_check = (C.marikoEmcMaxClock - PllOscInKHz * (C.marikoEmcMaxClock / PllOscInKHz)) > (C.marikoEmcMaxClock - PllOscHalfKHz * divm_candidate_half) && static_cast<int>(((target_freq_d / PllOscHalfKHz - divm_candidate_half - 0.5) * 8192.0)) != 0;
|
||||
|
||||
u32 divm_final = remainder_check + 1;
|
||||
table->pllmb_divm = divm_final;
|
||||
|
||||
double div_step_d = static_cast<double>(PllOscInKHz) / divm_final;
|
||||
s32 divn_integer = static_cast<u8>(table->rate_khz / div_step_d);
|
||||
s32 divn_integer = static_cast<u8>(C.marikoEmcMaxClock / div_step_d);
|
||||
table->pllmb_divn = divn_integer;
|
||||
|
||||
u32 divn_fraction = static_cast<s32>((target_freq_d / div_step_d - divn_integer - 0.5) * 8192.0);
|
||||
|
||||
u32 actual_freq_khz = static_cast<u32>((divn_integer + 0.5 + divn_fraction * 0.000122070312) * div_step_d);
|
||||
|
||||
if (table->rate_khz - 2366001 < 133999) {
|
||||
if (C.marikoEmcMaxClock - 2366001 < 133999) {
|
||||
s32 divn_fraction_ssc = static_cast<s32>((actual_freq_khz * 0.997 / div_step_d - divn_integer - 0.5) * 8192.0);
|
||||
|
||||
double delta_scaled = (0.3 / div_step_d + 0.3 / div_step_d) * (divn_fraction - divn_fraction_ssc);
|
||||
@@ -881,7 +853,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
table->pllm_ss_cfg &= 0xBFFFFFFF;
|
||||
table->pllmb_ss_cfg &= 0xBFFFFFFF;
|
||||
|
||||
u64 pair = (static_cast<u64>(divn_fraction) << 32) | static_cast<u64>(table->rate_khz);
|
||||
u64 pair = (static_cast<u64>(divn_fraction) << 32) | static_cast<u64>(C.marikoEmcMaxClock);
|
||||
u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast<u32>((pair - actual_freq_khz) >> 32);
|
||||
|
||||
table->pllm_ss_ctrl2 = pll_misc;
|
||||
@@ -910,12 +882,12 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
|
||||
// Copy unmodified 1600000 table to tmp
|
||||
std::memcpy(reinterpret_cast<void *>(tmp), reinterpret_cast<void *>(table_max), sizeof(MarikoMtcTable));
|
||||
|
||||
// Adjust max freq mtc timing parameters with reference to 1331200 table
|
||||
/* TODO: Implement mariko */
|
||||
MemMtcTableAutoAdjust(table_max);
|
||||
MemMtcPllmbDivisor(table_max);
|
||||
|
||||
MemMtcTableAutoAdjust(table_max);
|
||||
|
||||
MemMtcPllmbDivisor(table_max);
|
||||
// Overwrite 13312000 table with unmodified 1600000 table copied back
|
||||
std::memcpy(reinterpret_cast<void *>(table_alt), reinterpret_cast<void *>(tmp), sizeof(MarikoMtcTable));
|
||||
|
||||
|
||||
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
Binary file not shown.
Reference in New Issue
Block a user