loader: refactor ram frequency calculation logic

This commit is contained in:
souldbminersmwc
2026-01-01 16:51:11 -05:00
parent ce97087baa
commit ea20003df0
14 changed files with 192 additions and 116 deletions

View File

@@ -19,7 +19,7 @@
#include "timing_tables.hpp" #include "timing_tables.hpp"
namespace ams::ldr::oc::pcv::mariko { namespace ams::ldr::oc::pcv::mariko {
u32 calcClock;
u32 GetRext() { u32 GetRext() {
if (auto r = FindRext()) { if (auto r = FindRext()) {
return r->correct; return r->correct;
@@ -35,7 +35,7 @@ namespace ams::ldr::oc::pcv::mariko {
for (u32 i = 0; i < g_misc_table_size; i++) { for (u32 i = 0; i < g_misc_table_size; i++) {
const auto& e = g_misc_table[i]; const auto& e = g_misc_table[i];
if (C.marikoEmcMaxClock >= e.min_freq) { if (calcClock >= e.min_freq) {
rdv += e.rdv_inc; rdv += e.rdv_inc;
if (e.einput) einput_duration = e.einput; if (e.einput) einput_duration = e.einput;
if (e.quse_width) quse_width = e.quse_width; if (e.quse_width) quse_width = e.quse_width;
@@ -64,8 +64,8 @@ namespace ams::ldr::oc::pcv::mariko {
void CalculateTWTPDEN() { void CalculateTWTPDEN() {
tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6; tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6;
if (C.marikoEmcMaxClock >= 2'233'000 && C.marikoEmcMaxClock < 2'533'000) tWTPDEN++; if (calcClock >= 2'233'000 && calcClock < 2'533'000) tWTPDEN++;
if (C.marikoEmcMaxClock >= 2'433'000 && C.marikoEmcMaxClock < 2'800'000) tWTPDEN--; if (calcClock >= 2'433'000 && calcClock < 2'800'000) tWTPDEN--;
} }
void CalculateTR2W() { void CalculateTR2W() {
@@ -78,12 +78,12 @@ namespace ams::ldr::oc::pcv::mariko {
void CalculateQrst() { void CalculateQrst() {
qrst = 0x00070000; qrst = 0x00070000;
u32 qrst_calc = ROUND(22.1 - (C.marikoEmcMaxClock / 1000000.0) * 8.0) + C.mem_burst_read_latency; u32 qrst_calc = ROUND(22.1 - (calcClock / 1000000.0) * 8.0) + C.mem_burst_read_latency;
u32 qrst_low = MAX(static_cast<u32>(0), qrst_calc); u32 qrst_low = MAX(static_cast<u32>(0), qrst_calc);
if (C.marikoEmcMaxClock >= 2'533'000) { if (calcClock >= 2'533'000) {
qrst = INCREMENT_HIGH_BYTES_BY(qrst, 1); qrst = INCREMENT_HIGH_BYTES_BY(qrst, 1);
} else if (C.marikoEmcMaxClock == 2'800'000) { } else if (calcClock == 2'800'000) {
qrst = SET_HIGH_BYTES(qrst, 6); qrst = SET_HIGH_BYTES(qrst, 6);
} }
@@ -95,20 +95,20 @@ namespace ams::ldr::oc::pcv::mariko {
} }
void CalculateQsafe() { void CalculateQsafe() {
qsafe = ROUND((C.marikoEmcMaxClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency; qsafe = ROUND((calcClock / 1000.0) / 138.0 + 37.4) + C.mem_burst_read_latency;
if (auto patch = FindQsafePatch()) { if (auto patch = FindQsafePatch()) {
qsafe += patch->adjust; qsafe += patch->adjust;
} }
} }
void CalculateQpop() { void CalculateQpop() {
qpop = FLOOR(((C.marikoEmcMaxClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency; qpop = FLOOR(((calcClock / 1000.0) - 2133 + 167) / 200.0) + 0x2D + C.mem_burst_read_latency;
if (C.marikoEmcMaxClock >= 3'133'000) qpop++; if (calcClock >= 3'133'000) qpop++;
} }
void CalculatePdex2rw() { void CalculatePdex2rw() {
double freq_mhz = C.marikoEmcMaxClock / 1000.0; double freq_mhz = calcClock / 1000.0;
double pdex_local = (0.011 * freq_mhz) - 1.443; double pdex_local = (0.011 * freq_mhz) - 1.443;
pdex2rw = static_cast<u32>(ROUND(pdex_local)); pdex2rw = static_cast<u32>(ROUND(pdex_local));
@@ -122,14 +122,16 @@ namespace ams::ldr::oc::pcv::mariko {
} }
void CalculateCke2pden() { void CalculateCke2pden() {
cke2pden = (static_cast<double>((C.marikoEmcMaxClock / 1000.0) * 0.00875) - 0.65); cke2pden = (static_cast<double>((calcClock / 1000.0) * 0.00875) - 0.65);
if (auto patch = FindCke2pdenPatch()) { if (auto patch = FindCke2pdenPatch()) {
cke2pden += patch->adjust; cke2pden += patch->adjust;
} }
} }
void CalculateTimings() { void CalculateTimings(u32 rate_khz) {
calcClock = rate_khz;
SetTableMaxClock(rate_khz);
CalculateMiscTimings(); CalculateMiscTimings();
CalculateIbdly(); CalculateIbdly();
CalculateObdly(); CalculateObdly();

View File

@@ -17,7 +17,5 @@
#pragma once #pragma once
namespace ams::ldr::oc::pcv::mariko { namespace ams::ldr::oc::pcv::mariko {
void CalculateTimings(u32 rate_khz);
void CalculateTimings();
} }

View File

@@ -18,7 +18,11 @@
#include "timing_tables.hpp" #include "timing_tables.hpp"
namespace ams::ldr::oc::pcv::mariko { namespace ams::ldr::oc::pcv::mariko {
u32 clkMax;
void SetTableMaxClock(u32 maxClock) {
clkMax = maxClock;
}
const MiscTimings g_misc_table[] = { const MiscTimings g_misc_table[] = {
{1'866'000, 1, 0x20, 0x9, }, {1'866'000, 1, 0x20, 0x9, },
{2'133'000, 1, 0x24, 0xA, }, {2'133'000, 1, 0x24, 0xA, },
@@ -65,7 +69,7 @@ namespace ams::ldr::oc::pcv::mariko {
const ReplacePatch *FindRext() { const ReplacePatch *FindRext() {
for (u32 i = 0; i < g_rext_table_size; i++) for (u32 i = 0; i < g_rext_table_size; i++)
if (g_rext_table[i].freq == C.marikoEmcMaxClock) if (g_rext_table[i].freq == clkMax)
return &g_rext_table[i]; return &g_rext_table[i];
return nullptr; return nullptr;
} }
@@ -92,7 +96,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindIbdlyPatch() { const AdjustPatch *FindIbdlyPatch() {
for (u32 i = 0; i < g_ibdly_table_size; i++) for (u32 i = 0; i < g_ibdly_table_size; i++)
if (g_ibdly_patches[i].freq == C.marikoEmcMaxClock) if (g_ibdly_patches[i].freq == clkMax)
return &g_ibdly_patches[i]; return &g_ibdly_patches[i];
return nullptr; return nullptr;
} }
@@ -125,7 +129,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindObdlyPatch() { const AdjustPatch *FindObdlyPatch() {
for (u32 i = 0; i < g_obdly_table_size; i++) for (u32 i = 0; i < g_obdly_table_size; i++)
if (g_obdly_patches[i].freq == C.marikoEmcMaxClock) if (g_obdly_patches[i].freq == clkMax)
return &g_obdly_patches[i]; return &g_obdly_patches[i];
return nullptr; return nullptr;
} }
@@ -143,7 +147,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindTR2WPatch() { const AdjustPatch *FindTR2WPatch() {
for (u32 i = 0; i < g_tr2w_table_size; i++) for (u32 i = 0; i < g_tr2w_table_size; i++)
if (g_tr2w_patches[i].freq == C.marikoEmcMaxClock) if (g_tr2w_patches[i].freq == clkMax)
return &g_tr2w_patches[i]; return &g_tr2w_patches[i];
return nullptr; return nullptr;
} }
@@ -178,7 +182,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindQrstPatch() { const AdjustPatch *FindQrstPatch() {
for (u32 i = 0; i < g_qrst_table_size; i++) for (u32 i = 0; i < g_qrst_table_size; i++)
if (g_qrst_patches[i].freq == C.marikoEmcMaxClock) if (g_qrst_patches[i].freq == clkMax)
return &g_qrst_patches[i]; return &g_qrst_patches[i];
return nullptr; return nullptr;
} }
@@ -209,7 +213,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindQsafePatch() { const AdjustPatch *FindQsafePatch() {
for (u32 i = 0; i < g_qsafe_table_size; i++) for (u32 i = 0; i < g_qsafe_table_size; i++)
if (g_qsafe_patches[i].freq == C.marikoEmcMaxClock) if (g_qsafe_patches[i].freq == clkMax)
return &g_qsafe_patches[i]; return &g_qsafe_patches[i];
return nullptr; return nullptr;
} }
@@ -234,7 +238,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindPdex2rwPatch() { const AdjustPatch *FindPdex2rwPatch() {
for (u32 i = 0; i < g_pdex2rw_table_size; i++) for (u32 i = 0; i < g_pdex2rw_table_size; i++)
if (g_pdex2rw_patches[i].freq == C.marikoEmcMaxClock) if (g_pdex2rw_patches[i].freq == clkMax)
return &g_pdex2rw_patches[i]; return &g_pdex2rw_patches[i];
return nullptr; return nullptr;
} }
@@ -260,7 +264,7 @@ namespace ams::ldr::oc::pcv::mariko {
const AdjustPatch *FindCke2pdenPatch() { const AdjustPatch *FindCke2pdenPatch() {
for (u32 i = 0; i < g_cke2pden_table_size; i++) for (u32 i = 0; i < g_cke2pden_table_size; i++)
if (g_cke2pden_patches[i].freq == C.marikoEmcMaxClock) if (g_cke2pden_patches[i].freq == clkMax)
return &g_cke2pden_patches[i]; return &g_cke2pden_patches[i];
return nullptr; return nullptr;
} }

View File

@@ -18,7 +18,7 @@
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
namespace ams::ldr::oc::pcv::mariko { namespace ams::ldr::oc::pcv::mariko {
void SetTableMaxClock(u32 maxClock);
struct ReplacePatch { struct ReplacePatch {
u32 freq; u32 freq;
u32 correct; u32 correct;

View File

@@ -0,0 +1,61 @@
/*
*
* 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;
}

View File

@@ -111,54 +111,46 @@ namespace ams::ldr::oc {
} }
namespace pcv::mariko { namespace pcv::mariko {
const double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock; extern double tCK_avg;
extern u32 tRCD;
const u32 tRCD = tRCD_values[C.t1_tRCD]; extern u32 tRPpb;
const u32 tRPpb = tRP_values[C.t2_tRP]; extern u32 tRAS;
const u32 tRAS = tRAS_values[C.t3_tRAS]; extern double tRRD;
const double tRRD = tRRD_values[C.t4_tRRD]; extern u32 tRFCpb;
const u32 tRFCpb = tRFC_values[C.t5_tRFC]; extern u32 tWTR;
const u32 tWTR = 10 - tWTR_values[C.t7_tWTR]; extern u32 tRC;
extern u32 tRFCab;
const u32 tRC = tRAS + tRPpb; extern double tXSR;
const u32 tRFCab = tRFCpb * 2; extern u32 tFAW;
const double tXSR = (double) (tRFCab + 7.5); extern double tRPab;
const u32 tFAW = static_cast<u32>(tRRD * 4.0); extern u32 tR2P;
const double tRPab = tRPpb + 3; extern u32 tR2W;
extern u32 tRTM;
const u32 tR2P = 12 + (C.mem_burst_read_latency / 2); extern u32 tRATM;
inline u32 tR2W; extern u32 rdv;
const u32 tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(10 / tCK_avg); // Fix? extern u32 quse;
const u32 tRATM = tRTM + CEIL(10 / tCK_avg) - 12; // Fix? extern u32 einput;
inline u32 rdv; extern u32 einput_duration;
const u32 quse = FLOOR((-0.0048159 * (C.marikoEmcMaxClock / 1000.0)) + RL_DBI) + (FLOOR((C.marikoEmcMaxClock / 1000.0) * 0.0050997) * 1.5134); extern u32 ibdly;
const u32 einput = quse - ((C.marikoEmcMaxClock / 1000.0) * 0.01); extern u32 obdly;
inline u32 einput_duration; extern u32 quse_width;
inline u32 ibdly; extern u32 rext;
inline u32 obdly; extern u32 qrst;
inline u32 quse_width; extern u32 qsafe;
inline u32 rext; extern u32 qpop;
inline u32 qrst; extern u32 tW2P;
inline u32 qsafe; extern u32 tWTPDEN;
inline u32 qpop; extern u32 tW2R;
extern u32 tWTM;
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5; extern u32 tWATM;
inline u32 tWTPDEN; extern u32 wdv;
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)); extern u32 wsv;
const u32 tWTM = WL + (BL / 2) + 1 + CEIL(7.5 / tCK_avg); extern u32 wev;
const u32 tWATM = tWTM + CEIL(tWR / tCK_avg); extern u32 pdex2rw;
extern u32 cke2pden;
const u32 wdv = WL; extern u32 tCKE;
const u32 wsv = WL - 2; extern double tMMRI;
const u32 wev = 0xA + C.mem_burst_write_latency; extern double pdex2mrr;
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? */
} }
} }

View File

@@ -413,6 +413,34 @@ namespace ams::ldr::oc::pcv::mariko {
} }
void MemMtcTableAutoAdjust(MarikoMtcTable *table) { 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) \ #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; \
@@ -435,7 +463,7 @@ namespace ams::ldr::oc::pcv::mariko {
u32 trefbw = refresh_raw + 0x40; u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF)); trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
CalculateTimings(); CalculateTimings(table->rate_khz);
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));
@@ -462,7 +490,7 @@ namespace ams::ldr::oc::pcv::mariko {
WRITE_PARAM_ALL_REG(table, emc_twtm, tWTM); WRITE_PARAM_ALL_REG(table, emc_twtm, tWTM);
WRITE_PARAM_ALL_REG(table, emc_twatm, tWATM); WRITE_PARAM_ALL_REG(table, emc_twatm, tWATM);
WRITE_PARAM_ALL_REG(table, emc_rext, rext); WRITE_PARAM_ALL_REG(table, emc_rext, rext);
WRITE_PARAM_ALL_REG(table, emc_wext, (C.marikoEmcMaxClock >= 2533000) ? 0x19 : 0x16); WRITE_PARAM_ALL_REG(table, emc_wext, (table->rate_khz >= 2533000) ? 0x19 : 0x16);
WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw); 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_pre_refresh_req_cnt, refresh_raw / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw); WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
@@ -509,7 +537,7 @@ namespace ams::ldr::oc::pcv::mariko {
constexpr double MC_ARB_DIV = 4.0; constexpr double MC_ARB_DIV = 4.0;
constexpr u32 MC_ARB_SFA = 2; constexpr u32 MC_ARB_SFA = 2;
table->burst_mc_regs.mc_emem_arb_cfg = C.marikoEmcMaxClock / (33.3 * 1000) / MC_ARB_DIV; table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (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_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_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; table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
@@ -544,7 +572,7 @@ namespace ams::ldr::oc::pcv::mariko {
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x115; table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x115;
if (C.marikoEmcMaxClock >= 2133000) { if (table->rate_khz >= 2133000) {
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1F; table->la_scale_regs.mc_ftop_ptsa_rate = 0x1F;
} else { } else {
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1B; table->la_scale_regs.mc_ftop_ptsa_rate = 0x1B;
@@ -556,11 +584,11 @@ namespace ams::ldr::oc::pcv::mariko {
constexpr u32 Mask2 = 0xFFFFFF00; constexpr u32 Mask2 = 0xFFFFFF00;
constexpr u32 Mask3 = 0xFF00FF00; constexpr u32 Mask3 = 0xFF00FF00;
const u32 allowance1 = static_cast<u32>(0x32000 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF; const u32 allowance1 = static_cast<u32>(0x32000 / (table->rate_khz / 0x3E8)) & 0xFF;
const u32 allowance2 = static_cast<u32>(0x9C40 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF; const u32 allowance2 = static_cast<u32>(0x9C40 / (table->rate_khz / 0x3E8)) & 0xFF;
const u32 allowance3 = static_cast<u32>(0xB540 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF; const u32 allowance3 = static_cast<u32>(0xB540 / (table->rate_khz / 0x3E8)) & 0xFF;
const u32 allowance4 = static_cast<u32>(0x9600 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF; const u32 allowance4 = static_cast<u32>(0x9600 / (table->rate_khz / 0x3E8)) & 0xFF;
const u32 allowance5 = static_cast<u32>(0x8980 / (C.marikoEmcMaxClock / 0x3E8)) & 0xFF; const u32 allowance5 = static_cast<u32>(0x8980 / (table->rate_khz / 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_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); table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & MaskHigh) | (allowance1 << 16);
@@ -808,24 +836,24 @@ namespace ams::ldr::oc::pcv::mariko {
constexpr u32 PllOscInKHz = 38400; constexpr u32 PllOscInKHz = 38400;
constexpr u32 PllOscHalfKHz = 19200; constexpr u32 PllOscHalfKHz = 19200;
double target_freq_d = static_cast<double>(C.marikoEmcMaxClock); double target_freq_d = static_cast<double>(table->rate_khz);
s32 divm_candidate_half = static_cast<u8>(C.marikoEmcMaxClock / PllOscHalfKHz); s32 divm_candidate_half = static_cast<u8>(table->rate_khz / PllOscHalfKHz);
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; 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;
u32 divm_final = remainder_check + 1; u32 divm_final = remainder_check + 1;
table->pllmb_divm = divm_final; table->pllmb_divm = divm_final;
double div_step_d = static_cast<double>(PllOscInKHz) / divm_final; double div_step_d = static_cast<double>(PllOscInKHz) / divm_final;
s32 divn_integer = static_cast<u8>(C.marikoEmcMaxClock / div_step_d); s32 divn_integer = static_cast<u8>(table->rate_khz / div_step_d);
table->pllmb_divn = divn_integer; table->pllmb_divn = divn_integer;
u32 divn_fraction = static_cast<s32>((target_freq_d / div_step_d - divn_integer - 0.5) * 8192.0); 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); u32 actual_freq_khz = static_cast<u32>((divn_integer + 0.5 + divn_fraction * 0.000122070312) * div_step_d);
if (C.marikoEmcMaxClock - 2366001 < 133999) { if (table->rate_khz - 2366001 < 133999) {
s32 divn_fraction_ssc = static_cast<s32>((actual_freq_khz * 0.997 / div_step_d - divn_integer - 0.5) * 8192.0); 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); double delta_scaled = (0.3 / div_step_d + 0.3 / div_step_d) * (divn_fraction - divn_fraction_ssc);
@@ -853,7 +881,7 @@ namespace ams::ldr::oc::pcv::mariko {
table->pllm_ss_cfg &= 0xBFFFFFFF; table->pllm_ss_cfg &= 0xBFFFFFFF;
table->pllmb_ss_cfg &= 0xBFFFFFFF; table->pllmb_ss_cfg &= 0xBFFFFFFF;
u64 pair = (static_cast<u64>(divn_fraction) << 32) | static_cast<u64>(C.marikoEmcMaxClock); u64 pair = (static_cast<u64>(divn_fraction) << 32) | static_cast<u64>(table->rate_khz);
u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast<u32>((pair - actual_freq_khz) >> 32); u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast<u32>((pair - actual_freq_khz) >> 32);
table->pllm_ss_ctrl2 = pll_misc; table->pllm_ss_ctrl2 = pll_misc;
@@ -882,12 +910,12 @@ namespace ams::ldr::oc::pcv::mariko {
// Copy unmodified 1600000 table to tmp // Copy unmodified 1600000 table to tmp
std::memcpy(reinterpret_cast<void *>(tmp), reinterpret_cast<void *>(table_max), sizeof(MarikoMtcTable)); std::memcpy(reinterpret_cast<void *>(tmp), reinterpret_cast<void *>(table_max), sizeof(MarikoMtcTable));
// Adjust max freq mtc timing parameters with reference to 1331200 table // Adjust max freq mtc timing parameters with reference to 1331200 table
/* TODO: Implement mariko */ /* TODO: Implement mariko */
MemMtcTableAutoAdjust(table_max); MemMtcTableAutoAdjust(table_max);
MemMtcPllmbDivisor(table_max); MemMtcPllmbDivisor(table_max);
// Overwrite 13312000 table with unmodified 1600000 table copied back // Overwrite 13312000 table with unmodified 1600000 table copied back
std::memcpy(reinterpret_cast<void *>(table_alt), reinterpret_cast<void *>(tmp), sizeof(MarikoMtcTable)); std::memcpy(reinterpret_cast<void *>(table_alt), reinterpret_cast<void *>(tmp), sizeof(MarikoMtcTable));

View File

@@ -37,7 +37,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk
# version control constants # version control constants
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
#TARGET_VERSION := $(shell git describe --dirty --always --tags) #TARGET_VERSION := $(shell git describe --dirty --always --tags)
APP_VERSION := 0.22 APP_VERSION := 0.23
TARGET_VERSION := $(APP_VERSION) TARGET_VERSION := $(APP_VERSION)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@@ -43,7 +43,7 @@ std::string getVersionString() {
char buf[0x100] = ""; char buf[0x100] = "";
Result rc = sysclkIpcGetVersionString(buf, sizeof(buf)); Result rc = sysclkIpcGetVersionString(buf, sizeof(buf));
if (R_FAILED(rc) || buf[0] == '\0') { if (R_FAILED(rc) || buf[0] == '\0') {
return "HorizonOC-Misc"; return "Unknown";
} }
return std::string(buf); return std::string(buf);
} }

View File

@@ -41,7 +41,7 @@ class BaseGui : public tsl::Gui
public: public:
BaseGui() {} BaseGui() {}
~BaseGui() {} ~BaseGui() {}
virtual void preDraw(tsl::gfx::Renderer* renderer); virtual void preDraw(tsl::gfx::Renderer* renderer);
void update() override; void update() override;
tsl::elm::Element* createUI() override; tsl::elm::Element* createUI() override;
virtual tsl::elm::Element* baseUI() = 0; virtual tsl::elm::Element* baseUI() = 0;

View File

@@ -148,28 +148,27 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
y+=20; y+=20;
renderer->drawString(labels[10], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[11], false, positions[6], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_Battery]); // Battery renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_Battery]); // Battery
renderer->drawString(displayStrings[22], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_PMIC]); // PMIC
renderer->drawString(labels[13], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label renderer->drawString(labels[13], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq
renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label
renderer->drawString(displayStrings[24], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
y+=20; y+=20;
renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage
renderer->drawString(displayStrings[23], false, positions[2] - 2, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat Age renderer->drawString(displayStrings[23], false, positions[2] - 2, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat Age
renderer->drawString(labels[12], false, positions[6], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label
renderer->drawString(displayStrings[24], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
renderer->drawString(displayStrings[26], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp volt renderer->drawString(displayStrings[26], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp volt
y+=20;
} }
// Optimized refresh - now does all the string formatting once per second // Optimized refresh - now does all the string formatting once per second
@@ -268,17 +267,12 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[21], "%d mV", context->voltages[HocClkVoltage_Battery]); // BAT AVG sprintf(displayStrings[21], "%d mV", context->voltages[HocClkVoltage_Battery]); // BAT AVG
millis = context->temps[HorizonOCThermalSensor_PMIC]; // Battery
sprintf(displayStrings[22], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HorizonOCThermalSensor_PMIC] = tsl::GradientColor(millis * 0.001f);
sprintf(displayStrings[23], "%u%%", context->PartLoad[HocClkPartLoad_BAT] / 1000); sprintf(displayStrings[23], "%u%%", context->PartLoad[HocClkPartLoad_BAT] / 1000);
sprintf(displayStrings[24], "%u%%", context->PartLoad[HocClkPartLoad_FAN]); sprintf(displayStrings[24], "%u%%", context->PartLoad[HocClkPartLoad_FAN]);
sprintf(displayStrings[25], "%u Hz", context->realFreqs[HorizonOCModule_Display]); sprintf(displayStrings[25], "%u Hz", context->realFreqs[HorizonOCModule_Display]);
sprintf(displayStrings[26], "%u.%u mV", context->voltages[HocClkVoltage_Display] / 1000U, context->voltages[HocClkVoltage_Display] % 1000U);
//sprintf(displayStrings[26], "%u", context->speedos[HorizonOCSpeedo_CPU]); //sprintf(displayStrings[26], "%u", context->speedos[HorizonOCSpeedo_CPU]);
} }

View File

@@ -45,7 +45,7 @@ void MainGui::listUI()
// this->lastContextUpdate = armGetSystemTick(); // this->lastContextUpdate = armGetSystemTick();
// this->context->enabled = state; // this->context->enabled = state;
// }); // });
// this->listElement->addItem(this->enabledToggle); // this->listElement->addItem(this->enabledToggle);
tsl::elm::ListItem* appProfileItem = new tsl::elm::ListItem("Edit App Profile"); tsl::elm::ListItem* appProfileItem = new tsl::elm::ListItem("Edit App Profile");
appProfileItem->setClickListener([this](u64 keys) { appProfileItem->setClickListener([this](u64 keys) {

View File

@@ -31,9 +31,6 @@
class MainGui : public BaseMenuGui class MainGui : public BaseMenuGui
{ {
protected:
tsl::elm::ToggleListItem* enabledToggle;
public: public:
MainGui() {} MainGui() {}
~MainGui() {} ~MainGui() {}