27 Commits
0.37 ... 0.39

Author SHA1 Message Date
Lightos1
3f9a5f61fb Add mrf for erista 2026-02-15 15:41:52 +01:00
souldbminersmwc
b9156d6861 sysclk: add sys-dock intergration 2026-02-14 21:16:14 -05:00
souldbminersmwc
5d59be7b77 sysclk: add experemental gpu sched override option 2026-02-14 20:55:44 -05:00
souldbminersmwc
dd4c5a8732 sysclk: make memmem proper 2026-02-14 20:27:43 -05:00
souldbminersmwc
837543fb0f Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-02-14 20:23:25 -05:00
souldbminersmwc
03ede8f171 sysclk: fix crashing on boot and raise minimum refresh rate on aula 2026-02-14 20:23:22 -05:00
Lightos1
078d8164fc Remove include 2026-02-15 01:29:11 +01:00
Lightos1
ceff8a083e Remove function in header 2026-02-15 01:28:49 +01:00
Lightos1
b32efcc177 Erista: dvb + more precise timings/timings from eos & formating 2026-02-15 01:27:50 +01:00
Lightos1
d57fccc463 Add cpu load, thanks masa for the help! 2026-02-14 21:47:25 +01:00
Souldbminer
26cf028f2d Update contact information for reporting vulnerabilities 2026-02-13 19:59:36 -05:00
souldbminersmwc
6e80c9a75f chore: depricate exosphere patch 2026-02-13 19:53:13 -05:00
souldbminersmwc
42bdfb55f2 remove charge current from overlay 2026-02-13 19:35:40 -05:00
souldbminersmwc
e0967a9fd6 sysclk: fix ui issues 2026-02-13 19:33:42 -05:00
souldbminersmwc
2406ce4f86 sysclk: fix real freq bug 2026-02-13 19:12:01 -05:00
souldbminersmwc
3b40a4a3e5 sysclk: turn on size compiler optimization 2026-02-13 16:36:04 -05:00
souldbminersmwc
38c408dde6 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-02-13 16:33:31 -05:00
souldbminersmwc
5e62eb3f5d sysclk: fix compile issue and remove 1152 no uv gpu 2026-02-13 16:33:29 -05:00
Lightos1
b4b5599ed2 sleep of 300'000 is enough 2026-02-13 12:15:46 +01:00
souldbminersmwc
b4917f3e1a sysclk: remove enforce board limit
this setting is bugged, so remove it
2026-02-12 19:55:15 -05:00
souldbminersmwc
e6b4cb6612 sysclk: add lineon's cpu volt bugfix
thanks, lineon!
2026-02-12 19:49:52 -05:00
souldbminersmwc
b1ca62ce61 sysclk: fix voltage display issue 2026-02-12 19:19:53 -05:00
souldbminersmwc
243f614887 Update clock_manager.cpp 2026-02-12 18:22:43 -05:00
souldbminersmwc
a8577378f6 Update misc_gui.cpp 2026-02-12 17:01:33 -05:00
souldbminersmwc
564703b7c5 sysclk: improve cpu volt bugfix 2026-02-12 17:00:31 -05:00
souldbminersmwc
5ef56bed25 sysclk: remove live timing update and fix profile change dvfs bug 2026-02-12 16:15:25 -05:00
Lightos1
afddb963a9 Remove dvfsOffset capping 2026-02-12 21:22:53 +01:00
43 changed files with 553 additions and 959 deletions

View File

@@ -8,4 +8,4 @@
## Reporting a Vulnerability
Contact me on discord (soul_9017) or email me (souldbminer@gmail.com)
Contact Souldbminer or Lightos_ on discord (souldbminer, lightos_)

View File

@@ -36,6 +36,8 @@ volatile CustomizeTable C = {
.commonEmcMemVolt = 1175000, /* LPDDR4X JEDEC Specification */
.eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */
.eristaEmcMaxClock1 = 1600000,
.eristaEmcMaxClock2 = 1600000,
.marikoEmcMaxClock = 1866000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */
.marikoEmcVddqVolt = 600000, /* Micron: 600mV, other manafacturers: 640mV */
@@ -463,7 +465,7 @@ volatile CustomizeTable C = {
{ 921600, { }, { 970060,-10108, -614,-179, 1508, -13 } },
{ 998400, { }, { 1065665,-16075, -497,-179, 3213, 9 } },
{ 1075200, { }, { 1132576,-16093, -648, 0, 1077, 40 } },
{ 1152000, { }, { 1180029,-14534, -830, 0, 1469, 110 } },
// { 1152000, { }, { 1180029,-14534, -830, 0, 1469, 110 } },
// { 1228800, { }, { 1248293,-16383, -859, 0, 3722, 313 } },
// { 1267200, { }, { 1286399,-17475, -867, 0, 3681, 559 } },
},

View File

@@ -80,6 +80,8 @@ typedef struct CustomizeTable {
u32 commonEmcMemVolt;
u32 eristaEmcMaxClock;
u32 eristaEmcMaxClock1;
u32 eristaEmcMaxClock2;
u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt;
u32 emcDvbShift;

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 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 "../oc_common.hpp"
#include "../mtc_timing_value.hpp"
namespace ams::ldr::hoc::pcv::erista {
void CalculateTimings(double tCK_avg) {
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL_DBI - (C.t6_tRTW * 3) + finetRTW;
tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL_DBI + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL_DBI)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));
tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;
const double tMMRI = tRCD + (tCK_avg * 3);
pdex2mrr = tMMRI + 10;
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 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/>.
*/
#pragma once
namespace ams::ldr::hoc::pcv::erista {
void CalculateTimings(double tCK_avg);
}

View File

@@ -21,3 +21,4 @@ namespace ams::ldr::hoc::pcv::mariko {
void CalculateTimings();
}

View File

@@ -30,14 +30,7 @@ namespace ams::ldr::hoc {
#define PACK_U32(high, low) ((static_cast<u32>(high) << 16) | (static_cast<u32>(low) & 0xFFFF))
#define PACK_U32_NIBBLE_HIGH_BYTE_LOW(high, low) ((static_cast<u32>(high & 0xF) << 28) | (static_cast<u32>(low) & 0xFF))
/* Primary timings. */
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
const std::array<double, 7> tRRD_values = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? 8gb uses 7.5 tRRD on >=1331. */
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
/* Burst latency, not to be confused with base latency (tWRL). */
const u32 BL = 16;
@@ -75,56 +68,55 @@ namespace ams::ldr::hoc {
/* Write recovery time. */
const u32 tWR = 18;
/* TOOD: Fix erista */
namespace pcv::erista {
const double tCK_avg = 1000'000.0 / C.eristaEmcMaxClock;
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
const std::array<double, 8> tRRD_values = { 10.0, 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 };
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
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 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 tRFCpb = tRFC_values[C.t5_tRFC];
const u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
const s32 finetRTW = C.fineTune_t6_tRTW;
const s32 finetWTR = C.fineTune_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 u32 tRC = tRAS + tRPpb;
const u32 tRFCab = tRFCpb * 2;
const double tXSR = static_cast<double>(tRFCab + 7.5);
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
const double tRPab = tRPpb + 3;
const u32 tR2P = 12;
const u32 tR2P = CEIL((RL_DBI * 0.426) - 2.0);
inline u32 tR2W;
inline u32 rext;
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
const u32 tW2R = CEIL(MAX(WL + (0.010322547033278747 * (C.eristaEmcMaxClock / 1000.0)), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg));
inline u32 tWTPDEN;
inline u32 tW2R;
const u32 wdv = WL;
const u32 wsv = WL - 2;
const u32 wev = 0xA + (WL - 14);
inline u32 pdex2rw;
const double freq_mhz = C.eristaEmcMaxClock / 1000.0;
inline u32 tCLKSTOP;
const u32 quse_width = CEIL(((3.7165006256863955 - freq_mhz) + (-0.002446584377651142 * freq_mhz)) - FLOOR(freq_mhz / -0.9952024303111688));
const u32 quse = CEIL(MIN(RL_DBI + (2.991255208275918 - (quse_width + (-0.00511180626826906 * freq_mhz))), freq_mhz * 0.021333773138874437));
const u32 ibdly = 0x10000000 + FLOOR(MAX(RL_DBI - 1.9999956603408224, quse - 5.9999987787411175) + (-0.0011929079761504341 * freq_mhz));
const u32 obdlyHigh = 3 / FLOOR(MIN(static_cast<double>(2), tCK_avg * (WL - 7)));
const u32 obdlyLow = WL - MIN(static_cast<double>(WL), 12 - (CEIL(-0.0003991 * freq_mhz) * 2));
const u32 obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow);
const u32 tCKE = CEIL(1.0795 * CEIL(0.0074472 * (C.eristaEmcMaxClock / 1000.0)));
const double tMMRI = tRCD + (tCK_avg * 3);
const double pdex2mrr = tMMRI + 10;
const u32 tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6;
const u32 tR2W = CEIL(RL_DBI + (tDQSCK_max / tCK_avg) + (BL / 2) - WL + tWPRE + FLOOR(tRPST) + 9.0) - (C.t6_tRTW * 3);
const double pdex_local = (0.011 * freq_mhz) - 1.443;
const u32 pdex2rw = static_cast<u32>(ROUND(pdex_local)) < 22 ? 22 : (static_cast<u32>(ROUND(pdex_local)) > 33 ? 33 : static_cast<u32>(ROUND(pdex_local)));
const double cke2pden = (static_cast<double>((C.eristaEmcMaxClock / 1000.0) * 0.00875) - 0.65);
inline double pdex2mrr;
}
namespace pcv::mariko {
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
const std::array<double, 7> tRRD_values = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? 8gb uses 7.5 tRRD on >=1331. */
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
const double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock;
const double ramFreqMhz = C.marikoEmcMaxClock / 1000.0;
const u32 tRCD = tRCD_values[C.t1_tRCD];
const u32 tRPpb = tRP_values[C.t2_tRP];
@@ -170,7 +162,6 @@ namespace ams::ldr::hoc {
const u32 obdlyHigh = 3 / FLOOR(MIN(static_cast<double>(2), tCK_avg * (WL - 7)));
const u32 obdlyLow = MAX(WL - FLOOR((126.0 / CEIL(tCK_avg + 8.601))), 0.0);
const u32 obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow);
const u32 pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));

View File

@@ -138,19 +138,20 @@ void SafetyCheck() {
break;
}
using namespace ams::ldr::hoc::pcv;
sValidator validators[] = {
{ C.eristaCpuBoostClock, 1020'000, 2295'000, true },
{ C.marikoCpuBoostClock, 1020'000, 2703'000, true },
{ C.commonEmcMemVolt, 912'500, 1350'000 }, // Official burst vmax for the RAMs is 1500mV
{ C.eristaCpuMaxVolt, 1000, 1257 },
{ C.eristaEmcMaxClock, 1600'000, 2600'000 },
{ C.marikoCpuMaxVolt, 1000, 1235 },
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
{ C.marikoEmcVddqVolt, 250'000, 700'000 },
{ eristaCpuDvfsMaxFreq, 1785'000, 2295'000 },
{ marikoCpuDvfsMaxFreq, 1785'000, 2703'000 },
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000 },
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000 },
{ C.commonEmcMemVolt, 912'500, 1350'000 }, // Official burst vmax for the RAMs is 1500mV
{ C.eristaCpuMaxVolt, 1000, 1257 },
{ GET_MAX_OF_ARR(erista::maxClocks), 1600'000, 2600'000 },
{ C.marikoCpuMaxVolt, 1000, 1235 },
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
{ C.marikoEmcVddqVolt, 250'000, 700'000 },
{ eristaCpuDvfsMaxFreq, 1785'000, 2295'000 },
{ marikoCpuDvfsMaxFreq, 1785'000, 2703'000 },
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000 },
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000 },
};
for (auto& i : validators) {

View File

@@ -178,6 +178,9 @@ namespace ams::ldr::hoc::pcv {
}
namespace erista {
const u32 maxClocks[] = { C.eristaEmcMaxClock2, C.eristaEmcMaxClock1, C.eristaEmcMaxClock, };
#define GET_MAX_OF_ARR(ARR) (*std::max_element(ARR, ARR + std::size(ARR)))
constexpr cvb_entry_t CpuCvbTableDefault[] = {
// CPU_PLL_CVB_TABLE_ODN
{ 204000, {721094}, { } },

View File

@@ -20,6 +20,7 @@
#include "pcv.hpp"
#include "../mtc_timing_value.hpp"
#include "../erista/calculate_timings_erista.hpp"
namespace ams::ldr::hoc::pcv::erista {
@@ -180,325 +181,19 @@ namespace ams::ldr::hoc::pcv::erista {
R_SUCCEED();
}
// void MemMtcTableAutoAdjustBaseLatency(EristaMtcTable *table) {
// using namespace pcv::erista;
/* #define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
TABLE->shadow_regs_quse_train.PARAM = VALUE; \
TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
*/
// #define GET_CYCLE(PARAM) ((u32)((double)(PARAM) / tCK_avg))
/* This condition is insane but it's done in eos. */
/* Need to clean up at some point. */
// u32 rext;
// u32 wext;
// if (C.eristaEmcMaxClock < 3200001) {
// if (C.eristaEmcMaxClock < 2133001) {
// rext = 26;
// wext = 22;
// } else {
// rext = 28;
// wext = 22;
//
// if (2400000 < C.eristaEmcMaxClock) {
// wext = 25;
// }
// }
// } else {
// rext = 30;
// wext = 25;
// }
// u32 refresh_raw = 0xFFFF;
// u32 trefbw = 0;
//
// if (C.t8_tREFI != 6) {
// refresh_raw = static_cast<u32>(std::floor(static_cast<double>(tREFpb_values[C.t8_tREFI]) / tCK_avg)) - 0x40;
// refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
// }
//
// trefbw = refresh_raw + 0x40;
// trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
//
// if (C.hpMode) {
// WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
// } else {
// WRITE_PARAM_ALL_REG(table, emc_cfg, 0xF3200000);
// }
// WRITE_PARAM_ALL_REG(table, emc_rc, /*0x00000060*/ GET_CYCLE(tRC));
// WRITE_PARAM_ALL_REG(table, emc_rfc, /*0x00000120*/ GET_CYCLE(tRFCab));
// WRITE_PARAM_ALL_REG(table, emc_ras, /*0x00000044*/ GET_CYCLE(tRAS));
// WRITE_PARAM_ALL_REG(table, emc_rp, /*0x0000001D*/ GET_CYCLE(tRPpb));
// WRITE_PARAM_ALL_REG(table, emc_r2w, /*0x0000002A*/ tR2W);
// WRITE_PARAM_ALL_REG(table, emc_w2r, /*0x00000021*/ tW2R);
// WRITE_PARAM_ALL_REG(table, emc_r2p, 0x0000000C);
// WRITE_PARAM_ALL_REG(table, emc_w2p, 0x0000002D);
// WRITE_PARAM_ALL_REG(table, emc_rd_rcd, /*0x0000001D*/ GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_wr_rcd, /*0x0000001D*/ GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_rrd, /*0x00000010*/ GET_CYCLE(tRRD));
// WRITE_PARAM_ALL_REG(table, emc_rext, 0x00000017);
// WRITE_PARAM_ALL_REG(table, emc_wdv, 0x0000000E);
// WRITE_PARAM_ALL_REG(table, emc_quse, 0x00000024);
// WRITE_PARAM_ALL_REG(table, emc_qrst, 0x0006000C);
// WRITE_PARAM_ALL_REG(table, emc_qsafe, 0x00000034);
// WRITE_PARAM_ALL_REG(table, emc_rdv, 0x0000003C);
// WRITE_PARAM_ALL_REG(table, emc_refresh, /*0x00001820*/ refresh_raw);
// WRITE_PARAM_ALL_REG(table, emc_burst_refresh_num, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pdex2wr, 0x00000010);
// WRITE_PARAM_ALL_REG(table, emc_pdex2rd, 0x00000010);
// WRITE_PARAM_ALL_REG(table, emc_pchg2pden, 0x00000003);
// WRITE_PARAM_ALL_REG(table, emc_act2pden, 0x00000003);
// WRITE_PARAM_ALL_REG(table, emc_ar2pden, 0x00000003);
// WRITE_PARAM_ALL_REG(table, emc_rw2pden, /*0x00000038*/ GET_CYCLE(tRW2PDEN));
// WRITE_PARAM_ALL_REG(table, emc_txsr, /*0x0000012C*/ MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_tcke, 0x0000000D);
// WRITE_PARAM_ALL_REG(table, emc_tfaw, /*0x00000040*/ GET_CYCLE(tFAW));
// WRITE_PARAM_ALL_REG(table, emc_trpab, /*0x00000022*/ GET_CYCLE(tRPab));
// WRITE_PARAM_ALL_REG(table, emc_tclkstable, 0x00000004);
// WRITE_PARAM_ALL_REG(table, emc_tclkstop, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_trefbw, /* 0x00001860*/ trefbw);
// WRITE_PARAM_ALL_REG(table, emc_tppd, 0x00000004);
// WRITE_PARAM_ALL_REG(table, emc_odt_write, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, /*0x0000002E*/ GET_CYCLE(pdex2mrr));
// WRITE_PARAM_ALL_REG(table, emc_wext, 0x00000016);
// WRITE_PARAM_ALL_REG(table, emc_rfc_slr, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt2, 0x01900017);
// WRITE_PARAM_ALL_REG(table, emc_mrs_wait_cnt, 0x0640002F);
// // table->emc_mrs = 0x00000000;
// // table->emc_emrs = 0x00000000;
// // table->emc_mrw = 0x00170040;
// WRITE_PARAM_ALL_REG(table, emc_fbio_spare, 0x00000012);
// WRITE_PARAM_ALL_REG(table, emc_fbio_cfg5, 0x9960A00D);
// WRITE_PARAM_ALL_REG(table, emc_pdex2cke, 0x00000002);
// WRITE_PARAM_ALL_REG(table, emc_cke2pden, 0x0000000E);
// // table->emc_emrs2 = 0x00000000;
// // table->emc_mrw2 = 0x0802002D;
// // table->emc_mrw3 = 0x0C0D00C0;
// // table->emc_mrw4 = 0xC0000000;
// WRITE_PARAM_ALL_REG(table, emc_r2r, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_einput, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_einput_duration, 0x0000001D);
// WRITE_PARAM_ALL_REG(table, emc_puterm_extra, 0x0000001F);
// WRITE_PARAM_ALL_REG(table, emc_tckesr, 0x00000018);
// WRITE_PARAM_ALL_REG(table, emc_tpd, 0x0000000C);
// table->emc_auto_cal_config = 0x201A51D8;
// table->emc_cfg_2 = 0x00110835;
// WRITE_PARAM_ALL_REG(table, emc_cfg_dig_dll, 0x002C03A9);
// WRITE_PARAM_ALL_REG(table, emc_cfg_dig_dll_period, 0x00008000);
// WRITE_PARAM_ALL_REG(table, emc_rdv_mask, 0x0000003E);
// WRITE_PARAM_ALL_REG(table, emc_wdv_mask, 0x0000000E);
// WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, 0x0000003C);
// WRITE_PARAM_ALL_REG(table, emc_rdv_early, 0x0000003A);
// table->emc_auto_cal_config8 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_zcal_interval, 0x00064000);
// WRITE_PARAM_ALL_REG(table, emc_zcal_wait_cnt, 0x00310640);
// WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_dq, 0x8020221F);
// WRITE_PARAM_ALL_REG(table, emc_fdpd_ctrl_cmd, 0x0220F40F);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_brick_ctrl_fdpd, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_brick_ctrl_fdpd, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_brick_ctrl_rfu1, 0x1FFF1FFF);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_brick_ctrl_rfu2, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_tr_timing_0, 0x01186190);
// // WRITE_PARAM_ALL_REG(table, emc_tr_ctrl_1, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv, 0x0000003C);
// table->emc_sel_dpd_ctrl = 0x00040000;
// WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, /*0x00000608*/ (u32) (refresh_raw / 4));
// WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, 0x8000308C);
// WRITE_PARAM_ALL_REG(table, emc_txsrdll, /*0x0000012C*/ MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_tr_qpop, 0x0000002C);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv_mask, 0x0000003E);
// WRITE_PARAM_ALL_REG(table, emc_tr_qsafe, 0x00000034);
// WRITE_PARAM_ALL_REG(table, emc_tr_qrst, 0x0006000C);
// table->emc_auto_cal_config2 = 0x05500000;
// table->emc_auto_cal_config3 = 0x00770000;
// // WRITE_PARAM_ALL_REG(table, emc_tr_dvfs, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_auto_cal_channel, 0xC1E0030A);
// WRITE_PARAM_ALL_REG(table, emc_ibdly, 0x1000001C);
// WRITE_PARAM_ALL_REG(table, emc_obdly, 0x10000002);
// WRITE_PARAM_ALL_REG(table, emc_txdsrvttgen, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_we_duration, 0x0000000D);
// WRITE_PARAM_ALL_REG(table, emc_ws_duration, 0x00000008);
// WRITE_PARAM_ALL_REG(table, emc_wev, 0x0000000A);
// WRITE_PARAM_ALL_REG(table, emc_wsv, 0x0000000C);
// WRITE_PARAM_ALL_REG(table, emc_cfg_3, 0x00000040);
// // WRITE_PARAM_ALL_REG(table, emc_mrw6, 0x08037171);
// // WRITE_PARAM_ALL_REG(table, emc_mrw7, 0x48037171);
// // WRITE_PARAM_ALL_REG(table, emc_mrw8, 0x080B6666);
// // table->emc_mrw9 = 0x0C0E7272;
// // table->emc_mrw10 = 0x880C4848;
// // table->emc_mrw11 = 0x480C4848; /* Check them maybe */
// // table->emc_mrw12 = 0x880E1718;
// // table->emc_mrw13 = 0x480E1814;
// // WRITE_PARAM_ALL_REG(table, emc_mrw14, 0x08161414);
// // WRITE_PARAM_ALL_REG(table, emc_mrw15, 0x48161414);
// // table->emc_fdpd_ctrl_cmd_no_ramp = 0x00000001;
// WRITE_PARAM_ALL_REG(table, emc_wdv_chk, 0x00000006);
// // WRITE_PARAM_ALL_REG(table, emc_cfg_pipe_2, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_cfg_pipe_1, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_cfg_pipe, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_qpop, 0x0000002C);
// WRITE_PARAM_ALL_REG(table, emc_quse_width, 0x00000009);
// WRITE_PARAM_ALL_REG(table, emc_puterm_width, 0x0000000E);
// table->emc_auto_cal_config7 = 0x00770000;
// // WRITE_PARAM_ALL_REG(table, emc_refctrl2, 0x00000000);
// WRITE_PARAM_ALL_REG(table, emc_fbio_cfg7, 0x00003BFF);
// WRITE_PARAM_ALL_REG(table, emc_rfcpb, /*0x00000090*/ GET_CYCLE(tRFCpb));
// // WRITE_PARAM_ALL_REG(table, emc_dqs_brlshft_0, 0x00000000); /* brlshft may or may not be important, I don't think it matters but who knows. */
// // WRITE_PARAM_ALL_REG(table, emc_dqs_brlshft_1, 0x00000000);
// table->emc_auto_cal_config4 = 0x00770000;
// table->emc_auto_cal_config5 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_ccdmw, 0x00000020);
// table->emc_auto_cal_config6 = 0x00770000;
// WRITE_PARAM_ALL_REG(table, emc_dll_cfg_0, 0x1F13612F);
// WRITE_PARAM_ALL_REG(table, emc_dll_cfg_1, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_config_sample_delay, 0x00000020);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_0, 0x10000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_1, 0x08000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_2, 0x08000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_3, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_4, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_tx_pwrd_5, 0x00001000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_bypass, 0xEFFF2210);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_0, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_1, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_pwrd_2, 0xDCDCDCDC);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_0, 0x0A0A0A0A);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_1, 0x0A0A0A0A);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_ctrl_2, 0x000A0A0A);
// // table->trim_regs.emc_pmacro_ib_vref_dq_0 = 0x15171414;
// // table->trim_regs.emc_pmacro_ib_vref_dq_1 = 0x15131513;
// // table->trim_regs.emc_pmacro_ib_vref_dqs_0 = 0x11111111;
// // table->trim_regs.emc_pmacro_ib_vref_dqs_1 = 0x11111111;
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_0, 0x000C000C);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_1, 0x000B000B);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_2, 0x000A000A);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_3, 0x000C000C);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_long_cmd_4, 0x0000000C);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_0, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_1, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ddll_short_cmd_2, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_0, 0x00030808);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_1, 0x00015C00);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_bg_bias_ctrl_0, 0x00000034);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_pad_cfg_ctrl, 0x00020000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_zctrl, 0x00000550);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_pad_rx_ctrl, 0x00000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_pad_rx_ctrl, 0x00000033);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_rx_term_mode, 0x00003000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_rx_term_mode, 0x00000011);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_cmd_pad_tx_ctrl, 0x02000000);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_data_pad_tx_ctrl, 0x02000101);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_common_pad_tx_ctrl, 0x00000007);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_autocal_cfg_common, 0x0000080D);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_vttgen_ctrl_2, 0x00102020);
// // WRITE_PARAM_ALL_REG(table, emc_pmacro_ib_rxrt, 0x00000055);
// WRITE_PARAM_ALL_REG(table, emc_training_ctrl, 0x00009080);
// WRITE_PARAM_ALL_REG(table, emc_training_quse_cors_ctrl, 0x01124000);
// WRITE_PARAM_ALL_REG(table, emc_training_quse_fine_ctrl, 0x01125B6A);
// WRITE_PARAM_ALL_REG(table, emc_training_quse_ctrl_misc, 0x0F081000);
// WRITE_PARAM_ALL_REG(table, emc_training_write_fine_ctrl, 0x1114FC00);
// WRITE_PARAM_ALL_REG(table, emc_training_write_ctrl_misc, 0x07004300);
// WRITE_PARAM_ALL_REG(table, emc_training_write_vref_ctrl, 0x00103200);
// WRITE_PARAM_ALL_REG(table, emc_training_read_fine_ctrl, 0x1110FC00);
// WRITE_PARAM_ALL_REG(table, emc_training_read_ctrl_misc, 0x0F085300);
// WRITE_PARAM_ALL_REG(table, emc_training_read_vref_ctrl, 0x00105800);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_fine_ctrl, 0x0513801F);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_ctrl_misc, 0x1F101100);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_ctrl_misc1, 0x00000014);
// WRITE_PARAM_ALL_REG(table, emc_training_ca_vref_ctrl, 0x00103200);
// WRITE_PARAM_ALL_REG(table, emc_training_settle, 0x07070404);
// // WRITE_PARAM_ALL_REG(table, emc_training_mpc, 0x00000000);
//
// const u32 mc_tRCD = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
// const u32 mc_tRPpb = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// const u32 mc_tRC = (uint) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
// const u32 mc_tR2W = (uint) (((double) ((uint)tR2W >> 2) - 1.0) + 2.0);
// const u32 mc_tW2R = (uint) (((double) (tW2R >> 2) - 1.0) + 2.0);
// const u32 mc_tRAS = MIN(GET_CYCLE(tRAS), (u32) 0x7F);
// const u32 mc_tRRD = MIN(GET_CYCLE(tRRD), (u32) 31);
//
// table->burst_mc_regs.mc_emem_arb_timing_ras = (int) ((double) (mc_tRAS >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rcd = (int) ((double) (GET_CYCLE(tRCD) >> 2) - 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rp = (int) (((double) (GET_CYCLE(tRPpb) >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_rc = (int) ((double) (GET_CYCLE(tRC) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_faw = (int) ((double) (GET_CYCLE(tFAW) >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_rrd = (int) ((double) (mc_tRRD >> 2) - 1.0);
// table->burst_mc_regs.mc_emem_arb_timing_r2w = (uint) (((double) ((uint) tR2W >> 2) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2r = (uint) (((double) (tW2R >> 2) - 1.0) + 2.0);
//
// table->burst_mc_regs.mc_emem_arb_da_turns = (table->burst_mc_regs.mc_emem_arb_da_turns & 0x0000FFFF) | (mc_tW2R << 24) | (mc_tR2W << 16);
// table->burst_mc_regs.mc_emem_arb_da_covers = (((uint) (mc_tRCD + 3 + mc_tRPpb) >> 1 & 0xff) << 8) | (((uint) (mc_tRCD + 11 + mc_tRPpb) >> 1 & 0xff) << 0x10) | ((mc_tRC >> 1) & 0xff);
// table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xffe08000U) | ((mc_tRC + 1) & 0xff); /* Missing in l4t dump? TODO */
// table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
//
// table->burst_mc_regs.mc_emem_arb_cfg = 0x0000000c;
// // table->burst_mc_regs.mc_emem_arb_timing_rcd = 0x00000006;
// // table->burst_mc_regs.mc_emem_arb_timing_rp = 0x00000007;
// // table->burst_mc_regs.mc_emem_arb_timing_rc = 0x00000018;
// // table->burst_mc_regs.mc_emem_arb_timing_ras = 0x0000000f;
// // table->burst_mc_regs.mc_emem_arb_timing_faw = 0x0000000f;
// // table->burst_mc_regs.mc_emem_arb_timing_rrd = 0x00000003;
// table->burst_mc_regs.mc_emem_arb_timing_rap2pre = 0x00000003;
// table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 0x0000000d;
// table->burst_mc_regs.mc_emem_arb_timing_r2r = 0x00000007;
// table->burst_mc_regs.mc_emem_arb_timing_w2w = 0x00000007;
// // table->burst_mc_regs.mc_emem_arb_timing_r2w = 0x0000000c;
// // table->burst_mc_regs.mc_emem_arb_timing_w2r = 0x0000000a;
// // table->burst_mc_regs.mc_emem_arb_da_turns = 0x05060303;
// // table->burst_mc_regs.mc_emem_arb_da_covers = 0x000d080c;
// table->burst_mc_regs.mc_emem_arb_ring1_throttle = 0x001f0000;
// // table->burst_mc_regs.mc_emem_arb_timing_rfcpb = 0x00000023;
// table->burst_mc_regs.mc_emem_arb_timing_ccdmw = 0x00000008;
// table->burst_mc_regs.mc_emem_arb_refpb_hp_ctrl = 0x000a1020;
// table->burst_mc_regs.mc_emem_arb_refpb_bank_ctrl = 0x80001028;
// // table->burst_mc_regs.mc_emem_arb_dhyst_ctrl = 0x00000002;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_0 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_1 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_2 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_3 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_4 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_5 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_6 = 0x0000001a;
// table->burst_mc_regs.mc_emem_arb_dhyst_timeout_util_7 = 0x0000001a;
// table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x000000d0;
// table->la_scale_regs.mc_ftop_ptsa_rate = 0x00000018;
// table->la_scale_regs.mc_ptsa_grant_decrement = 0x00001203;
// table->la_scale_regs.mc_latency_allowance_avpc_0 = 0x00800004;
// table->la_scale_regs.mc_latency_allowance_xusb_1 = 0x00800038;
// table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = 0x00800005;
// table->la_scale_regs.mc_latency_allowance_sdmmca_0 = 0x00800014;
// table->la_scale_regs.mc_latency_allowance_isp2_0 = 0x0000002c;
// table->la_scale_regs.mc_latency_allowance_isp2_1 = 0x00800080;
// table->la_scale_regs.mc_latency_allowance_vic_0 = 0x0080001d;
// table->la_scale_regs.mc_latency_allowance_nvdec_0 = 0x00800095;
// table->la_scale_regs.mc_latency_allowance_tsec_0 = 0x00800041;
// table->la_scale_regs.mc_latency_allowance_ppcs_1 = 0x00800080;
// table->la_scale_regs.mc_latency_allowance_xusb_0 = 0x0080003d;
// table->la_scale_regs.mc_latency_allowance_ppcs_0 = 0x00340049;
// table->la_scale_regs.mc_latency_allowance_gpu2_0 = 0x00800019;
// table->la_scale_regs.mc_latency_allowance_hc_1 = 0x00000080;
// table->la_scale_regs.mc_latency_allowance_sdmmc_0 = 0x00800090;
// table->la_scale_regs.mc_latency_allowance_mpcore_0 = 0x00800004;
// table->la_scale_regs.mc_latency_allowance_vi2_0 = 0x00000080;
// table->la_scale_regs.mc_latency_allowance_hc_0 = 0x00080016;
// table->la_scale_regs.mc_latency_allowance_gpu_0 = 0x00800019;
// table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = 0x00800005;
// table->la_scale_regs.mc_latency_allowance_nvenc_0 = 0x00800018;
// table->dram_timings.t_rp = tRFCpb;
// table->dram_timings.t_rfc = tRFCab;
// }
/* These timings are slightly off from eos, I am not sure why but I am going to figure it out at some point. */
/* Note: This does not have proper timings, so base latency adjustment will not work. */
/* However, it may still achieve a slightly higher frequency, but not as much as it could be. */
/* I'm certainly not insane enough to attempt this pain again, so this will have to do *for now*. */
void MemMtcTableAutoAdjust(EristaMtcTable *table) {
const double tCK_avg = 1000'000.0 / table->rate_khz;
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
/* Ram power down */
/* B31: DRAM_CLKSTOP_PD */
/* B30: DRAM_CLKSTOP_SR */
@@ -515,9 +210,19 @@ namespace ams::ldr::hoc::pcv::erista {
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
}
if (table->rate_khz > 3200000) {
rext = 30;
} else if (table->rate_khz >= 2133001) {
rext = 28;
} else {
rext = 26;
}
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
CalculateTimings(tCK_avg);
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_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB8)));
@@ -531,15 +236,15 @@ namespace ams::ldr::hoc::pcv::erista {
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_trpab, MIN(GET_CYCLE_CEIL(tRPab), static_cast<u32>(0x3F)));
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR));
WRITE_PARAM_ALL_REG(table, emc_tcke, tCKE);
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(7.425) + 2);
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tXP));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tXP) + 8);
WRITE_PARAM_ALL_REG(table, emc_tclkstop, tCLKSTOP);
WRITE_PARAM_ALL_REG(table, emc_r2p, tR2P);
WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
WRITE_PARAM_ALL_REG(table, emc_w2p, tW2P);
WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
WRITE_PARAM_ALL_REG(table, emc_rext, C.eristaEmcMaxClock < 2133001 ? 26 : 28); // rext shouldn't be causing issues?
WRITE_PARAM_ALL_REG(table, emc_wext, (C.eristaEmcMaxClock >= 2533000) ? 0x19 : 0x16);
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_refresh, refresh_raw);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
@@ -547,20 +252,46 @@ namespace ams::ldr::hoc::pcv::erista {
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.763));
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(1.75));
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(1.05));
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(14.0));
WRITE_PARAM_ALL_REG(table, emc_cke2pden, /* cke2pden */ GET_CYCLE_CEIL(8.5));
(void) cke2pden;
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(8.499));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(pdex2mrr));
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN);
/* Accept imperfection or prepare for suffering. */
// WRITE_PARAM_ALL_REG(table, emc_einput, einput);
// WRITE_PARAM_ALL_REG(table, emc_einput_duration, einput_duration);
// WRITE_PARAM_ALL_REG(table, emc_obdly, obdly);
// WRITE_PARAM_ALL_REG(table, emc_ibdly, ibdly);
// WRITE_PARAM_ALL_REG(table, emc_wdv_mask, wdv);
// WRITE_PARAM_ALL_REG(table, emc_quse_width, quse_width);
// WRITE_PARAM_ALL_REG(table, emc_quse, quse);
// WRITE_PARAM_ALL_REG(table, emc_wdv, wdv);
// WRITE_PARAM_ALL_REG(table, emc_wsv, wsv);
// WRITE_PARAM_ALL_REG(table, emc_wev, wev);
// WRITE_PARAM_ALL_REG(table, emc_qrst, qrst);
// WRITE_PARAM_ALL_REG(table, emc_tr_qrst, qrst);
// WRITE_PARAM_ALL_REG(table, emc_qsafe, qsafe);
// WRITE_PARAM_ALL_REG(table, emc_tr_qsafe, qsafe);
// WRITE_PARAM_ALL_REG(table, emc_tr_qpop, qpop);
// WRITE_PARAM_ALL_REG(table, emc_qpop, qpop);
// WRITE_PARAM_ALL_REG(table, emc_rdv, rdv);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv_mask, rdv + 2);
// WRITE_PARAM_ALL_REG(table, emc_rdv_early, rdv - 2);
// WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv);
// WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv);
// ams::ldr::hoc::pcv::mariko::CalculateMrw2();
// table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast<u32>(mrw2);
// table->dram_timings.rl = RL_DBI;
/* This needs some clean up. */
constexpr double MC_ARB_DIV = 4.0;
constexpr u32 MC_ARB_SFA = 2;
table->burst_mc_regs.mc_emem_arb_cfg = C.eristaEmcMaxClock / (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_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;
@@ -593,54 +324,50 @@ namespace ams::ldr::hoc::pcv::erista {
table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xFFE08000) | (table->burst_mc_regs.mc_emem_arb_timing_rc + 1);
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = 0x115;
u32 mpcorer_ptsa_rate = MAX(static_cast<u32>(227), (table->rate_khz / 1600000) * 208);
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = mpcorer_ptsa_rate;
if (C.eristaEmcMaxClock >= 2133000) {
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1F;
} else {
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1B;
}
u32 ftop_ptsa_rate = MAX(static_cast<u32>(31), (table->rate_khz / 1600000) * 24);
table->la_scale_regs.mc_ftop_ptsa_rate = ftop_ptsa_rate;
table->la_scale_regs.mc_ptsa_grant_decrement = 0x17ff;
u32 grant_decrement = MAX(static_cast<u32>(6143), (table->rate_khz / 1600000) * 4611);
table->la_scale_regs.mc_ptsa_grant_decrement = grant_decrement;
constexpr u32 MaskHigh = 0xFF00FFFF;
constexpr u32 Mask2 = 0xFFFFFF00;
constexpr u32 Mask3 = 0xFF00FF00;
const u32 allowance1 = static_cast<u32>(0x32000 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
const u32 allowance2 = static_cast<u32>(0x9C40 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
const u32 allowance3 = static_cast<u32>(0xB540 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
const u32 allowance4 = static_cast<u32>(0x9600 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
const u32 allowance5 = static_cast<u32>(0x8980 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
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;
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_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_vic_0 = allowance3 | (table->la_scale_regs.mc_latency_allowance_vic_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_isp2_1 = (table->la_scale_regs.mc_latency_allowance_isp2_1 & Mask3) | (allowance1 << 16) | allowance1;
table->la_scale_regs.mc_latency_allowance_nvenc_0 = allowance4 | (table->la_scale_regs.mc_latency_allowance_nvenc_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & Mask2) | allowance5;
table->la_scale_regs.mc_latency_allowance_gpu_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_gpu2_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu2_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1;
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_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_isp2_1 = allowance1 | (table->la_scale_regs.mc_latency_allowance_isp2_1 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_gpu_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_gpu2_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu2_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_vic_0 = allowance3 | (table->la_scale_regs.mc_latency_allowance_vic_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_nvenc_0 = allowance4 | (table->la_scale_regs.mc_latency_allowance_nvenc_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & Mask2) | allowance5;
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1;
table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab;
table->dram_timings.rl = RL_DBI;
// WRITE_PARAM_ALL_REG(table, emc_obdly, obdly);
// WRITE_PARAM_ALL_REG(table, emc_ibdly, ibdly);
table->emc_cfg_2 = 0x11083D;
}
table->min_volt = std::min(static_cast<u32>(1050), 900 + C.emcDvbShift * 25);
}
Result MemFreqMtcTable(u32 *ptr) {
u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800};
@@ -655,25 +382,32 @@ namespace ams::ldr::hoc::pcv::erista {
R_UNLESS(table_list[i]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
}
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
if (GET_MAX_OF_ARR(maxClocks) <= EmcClkOSLimit) {
R_SKIP();
}
// Make room for new mtc table, discarding useless 40.8 MHz table
// 40800 overwritten by 68000, ..., 1331200 overwritten by 1600000, leaving table_list[0] not overwritten
for (u32 i = khz_list_size - 1; i > 0; i--)
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - 1]), sizeof(EristaMtcTable));
// Make room for new mtc table, discarding useless 40.8, 68000 and 102000 MHz table
// 40800 overwritten by 68000, ..., 1331200 overwritten by 1600000, leaving table_list[0], table_list[1] and table_list[2] not overwritten
for (u32 i = khz_list_size - 1; i > 2; --i) {
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - 3]), sizeof(EristaMtcTable));
}
MemMtcTableAutoAdjust(table_list[0]);
for (u32 i = 0; i < std::size(maxClocks); ++i) {
if (maxClocks[i] > EmcClkOSLimit) {
table_list[i]->rate_khz = maxClocks[i];
MemMtcTableAutoAdjust(table_list[i]);
}
}
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
R_SUCCEED();
}
Result MemFreqMax(u32 *ptr) {
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
if (GET_MAX_OF_ARR(maxClocks) <= EmcClkOSLimit) {
R_SKIP();
}
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxClocks));
R_SUCCEED();
}

View File

@@ -547,25 +547,25 @@ namespace ams::ldr::hoc::pcv::mariko {
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);
table->la_scale_regs.mc_latency_allowance_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_vic_0 = allowance3 | (table->la_scale_regs.mc_latency_allowance_vic_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_isp2_1 = (table->la_scale_regs.mc_latency_allowance_isp2_1 & Mask3) | (allowance1 << 16) | allowance1;
table->la_scale_regs.mc_latency_allowance_nvenc_0 = allowance4 | (table->la_scale_regs.mc_latency_allowance_nvenc_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & Mask2) | allowance5;
table->la_scale_regs.mc_latency_allowance_gpu_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_gpu2_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu2_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1;
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_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & MaskHigh) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_isp2_1 = allowance1 | (table->la_scale_regs.mc_latency_allowance_isp2_1 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_gpu_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_gpu2_0 = allowance2 | (table->la_scale_regs.mc_latency_allowance_gpu2_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_vic_0 = allowance3 | (table->la_scale_regs.mc_latency_allowance_vic_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_nvenc_0 = allowance4 | (table->la_scale_regs.mc_latency_allowance_nvenc_0 & Mask3) | (allowance1 << 16);
table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & Mask2) | allowance5;
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1;
table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab;

View File

@@ -169,15 +169,4 @@ Result hocClkIpcGetKipData()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_GetKipData, temp);
}
Result hocClkIpcUpdateEmcRegs()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_UpdateEmcRegs, temp);
}
Result hocClkIpcCalculateGpuVmin()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_CalculateGpuVmin, temp);
}

View File

@@ -31,7 +31,7 @@
extern "C" {
#endif
void *memmem_impl(void *haystack, size_t haystacklen,
void *memmem_impl(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#ifdef __cplusplus

View File

@@ -12,9 +12,9 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
/* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -102,7 +102,7 @@ typedef enum
SysClkPartLoad_EMC = 0,
SysClkPartLoad_EMCCpu,
HocClkPartLoad_GPU,
HocClkPartLoad_CPUAvg,
HocClkPartLoad_CPUMax,
HocClkPartLoad_BAT,
HocClkPartLoad_FAN,
SysClkPartLoad_EnumMax
@@ -140,6 +140,13 @@ enum {
DVFSMode_EnumMax,
};
typedef enum {
GpuSchedulingMode_DoNotOverride = 0,
GpuSchedulingMode_Enabled,
GpuSchedulingMode_Disabled,
GpuSchedulingMode_EnumMax,
} GpuSchedulingMode;
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)

View File

@@ -43,10 +43,12 @@ typedef struct
uint32_t voltages[HocClkVoltage_EnumMax];
u16 speedos[HorizonOCSpeedo_EnumMax];
u16 iddq[HorizonOCSpeedo_EnumMax];
GpuSchedulingMode gpuSchedulingMode;
bool isSysDockInstalled;
u8 maxDisplayFreq;
u8 fps;
u8 dramID;
bool isDram8GB;
u8 fps;
} SysClkContext;
typedef struct

View File

@@ -51,8 +51,6 @@ typedef enum {
HocClkConfigValue_LiteTDPLimit,
HocClkConfigValue_EnforceBoardLimit,
HorizonOCConfigValue_BatteryChargeCurrent,
HorizonOCConfigValue_OverwriteRefreshRate,
@@ -61,7 +59,7 @@ typedef enum {
HorizonOCConfigValue_DVFSMode,
HorizonOCConfigValue_DVFSOffset,
HocClkConfigValue_FixCpuVoltBug,
HorizonOCConfigValue_GPUScheduling,
KipConfigValue_custRev,
// KipConfigValue_mtcConf,
@@ -69,6 +67,8 @@ typedef enum {
KipConfigValue_commonEmcMemVolt,
KipConfigValue_eristaEmcMaxClock,
KipConfigValue_eristaEmcMaxClock1,
KipConfigValue_eristaEmcMaxClock2,
KipConfigValue_marikoEmcMaxClock,
KipConfigValue_marikoEmcVddqVolt,
KipConfigValue_emcDvbShift,
@@ -215,18 +215,12 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case HocClkConfigValue_LiteTDPLimit:
return pretty ? "Handheld TDP Limit" : "tdp_limit_l";
case HocClkConfigValue_EnforceBoardLimit:
return pretty ? "Enforce Board Limit" : "enforce_board_limit";
case HorizonOCConfigValue_BatteryChargeCurrent:
return pretty ? "Battery Charge Current" : "bat_charge_current";
case HorizonOCConfigValue_OverwriteRefreshRate:
return pretty ? "Display Refresh Rate Changing" : "drr_changing";
case HocClkConfigValue_FixCpuVoltBug:
return pretty ? "Fix CPU Volt Bug" : "cpu_volt_bugfix";
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
return pretty ? "Enable Unsafe Display Frequencies" : "drr_unsafe";
@@ -236,6 +230,8 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case HorizonOCConfigValue_DVFSOffset:
return pretty ? "DVFS Offset" : "dvfs_offset";
case HorizonOCConfigValue_GPUScheduling:
return pretty ? "GPU Scheduling" : "gpu_scheduling";
// KIP config values
case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev";
@@ -248,7 +244,11 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case KipConfigValue_commonEmcMemVolt:
return pretty ? "Common EMC/MEM Voltage" : "common_emc_mem_volt";
case KipConfigValue_eristaEmcMaxClock:
return pretty ? "Erista EMC Max Clock" : "erista_emc_max_clock";
return pretty ? "Erista EMC Max Clock 1" : "erista_emc_max_clock";
case KipConfigValue_eristaEmcMaxClock1:
return pretty ? "Erista EMC Max Clock 2" : "erista_emc_max_clock1";
case KipConfigValue_eristaEmcMaxClock2:
return pretty ? "Erista EMC Max Clock 3" : "erista_emc_max_clock2";
case KipConfigValue_marikoEmcMaxClock:
return pretty ? "Mariko EMC Max Clock" : "mariko_emc_max_clock";
case KipConfigValue_marikoEmcVddqVolt:
@@ -409,6 +409,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
case HorizonOCConfigValue_BatteryChargeCurrent:
case HorizonOCConfigValue_OverwriteRefreshRate:
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
case HorizonOCConfigValue_GPUScheduling:
return 0ULL;
case HocClkConfigValue_EristaMaxCpuClock:
return 1785ULL;
@@ -418,8 +419,6 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_EnforceBoardLimit:
case HocClkConfigValue_FixCpuVoltBug:
case HocClkConfigValue_IsFirstLoad:
case HorizonOCConfigValue_DVFSMode:
return 1ULL;
@@ -454,9 +453,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case HocClkConfigValue_OverwriteBoostMode:
case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_EnforceBoardLimit:
case HorizonOCConfigValue_OverwriteRefreshRate:
case HocClkConfigValue_FixCpuVoltBug:
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
case HocClkConfigValue_IsFirstLoad:
return (input & 0x1) == input;
@@ -466,6 +463,8 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case KipConfigValue_hpMode:
case KipConfigValue_commonEmcMemVolt:
case KipConfigValue_eristaEmcMaxClock:
case KipConfigValue_eristaEmcMaxClock1:
case KipConfigValue_eristaEmcMaxClock2:
case KipConfigValue_marikoEmcMaxClock:
case KipConfigValue_marikoEmcVddqVolt:
case KipConfigValue_emcDvbShift:
@@ -555,6 +554,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case KipCrc32:
case HorizonOCConfigValue_DVFSMode:
case HorizonOCConfigValue_DVFSOffset:
case HorizonOCConfigValue_GPUScheduling:
return true;
case HorizonOCConfigValue_BatteryChargeCurrent:
return ((input >= 1024) && (input <= 3072)) || !input;

View File

@@ -51,8 +51,6 @@ enum SysClkIpcCmd
SysClkIpcCmd_SetReverseNXRTMode = 12,
HocClkIpcCmd_SetKipData = 13,
HocClkIpcCmd_GetKipData = 14,
HocClkIpcCmd_UpdateEmcRegs = 15,
HocClkIpcCmd_CalculateGpuVmin = 16,
};

View File

@@ -169,15 +169,4 @@ Result hocClkIpcGetKipData()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_GetKipData, temp);
}
Result hocClkIpcUpdateEmcRegs()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_UpdateEmcRegs, temp);
}
Result hocClkIpcCalculateGpuVmin()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_CalculateGpuVmin, temp);
}

View File

@@ -42,9 +42,9 @@ static bool g_canChangeRefreshRateDocked = false;
static uint8_t g_lastVActiveSet = 0;
// Refresh rate tables
static const uint8_t g_dockedRefreshRates[] = {40, 45, 50, 55, 60, 70, 72, 75, 80, 90, 95, 100, 110, 120};
static bool g_dockedAllowed[14] = {0};
static bool g_dockedAllowed720p[14] = {0};
static const uint8_t g_dockedRefreshRates[] = {40, 45, 50, 55, 60, 70, 72, 75, 80, 90, 95, 100, 110, 120, 130, 144, 150, 160, 165, 170, 180, 190, 200, 210, 220, 230, 240};
static bool g_dockedAllowed[sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0])] = {0};
static bool g_dockedAllowed720p[sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0])] = {0};
static const DockedTimings g_dockedTimings1080p[] = {
{8, 32, 40, 7, 8, 6, 0, 88080}, // 40Hz

View File

@@ -24,7 +24,7 @@
#include "memmem.h"
void *memmem_impl(void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
void *memmem_impl(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
{
const unsigned char *cmpp;
const unsigned char *p;
@@ -39,7 +39,7 @@ void *memmem_impl(void *haystack, size_t haystacklen, const void *needle, size_t
}
if(needle == NULL)
{
return haystack;
return (void*)haystack;
}
if(haystacklen == 0)
{
@@ -47,7 +47,7 @@ void *memmem_impl(void *haystack, size_t haystacklen, const void *needle, size_t
}
if(needlelen == 0)
{
return haystack;
return (void*)haystack;
}
if(needlelen > haystacklen)

View File

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

View File

@@ -24,6 +24,7 @@
tsl::elm::ListItem* SpeedoItem = NULL;
tsl::elm::ListItem* IddqItem = NULL;
tsl::elm::ListItem* sysdockStatusItem = NULL;
ImageElement* CatImage = NULL;
HideableCategoryHeader* CatHeader = NULL;
HideableCustomDrawer* CatSpacer = NULL;
@@ -41,17 +42,21 @@ AboutGui::~AboutGui()
void AboutGui::listUI()
{
this->listElement->addItem(
new tsl::elm::CategoryHeader("Speedo/IDDQ")
new tsl::elm::CategoryHeader("Information")
);
SpeedoItem =
new tsl::elm::ListItem("Speedos:");
new tsl::elm::ListItem("Speedo:");
this->listElement->addItem(SpeedoItem);
IddqItem =
new tsl::elm::ListItem("IDDQ:");
this->listElement->addItem(IddqItem);
sysdockStatusItem =
new tsl::elm::ListItem("sys-dock status:");
this->listElement->addItem(sysdockStatusItem);
this->listElement->addItem(
new tsl::elm::CategoryHeader("Credits")
);
@@ -221,4 +226,5 @@ void AboutGui::refresh()
sprintf(strings[1], "%u/%u/%u", this->context->iddq[HorizonOCSpeedo_CPU], this->context->iddq[HorizonOCSpeedo_GPU], this->context->iddq[HorizonOCSpeedo_SOC]);
SpeedoItem->setValue(strings[0]);
IddqItem->setValue(strings[1]);
sysdockStatusItem->setValue(this->context->isSysDockInstalled ? "Installed" : "Not Installed");
}

View File

@@ -275,13 +275,16 @@ void AppProfileGui::addModuleListItemValue(
}
void AppProfileGui::addProfileUI(SysClkProfile profile)
{
{
BaseMenuGui::refresh();
if(!this->context)
return;
Result rc = sysclkIpcGetConfigValues(&configList); // idk why this is needed, probably some refreshing issue
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true) + std::string(" ") + ult::DIVIDER_SYMBOL + " Reset"));
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true) + std::string(" ") + ult::DIVIDER_SYMBOL + " \ue0e3 Reset"));
this->addModuleListItem(profile, SysClkModule_CPU);
this->addModuleListItem(profile, SysClkModule_GPU);
this->addModuleListItem(profile, SysClkModule_MEM);
@@ -289,9 +292,9 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
ValueThresholds lcdThresholds(60, 65);
if(!IsHoag() && configList.values[HorizonOCConfigValue_OverwriteRefreshRate]) {
if(profile != SysClkProfile_Docked)
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
else
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 5, " Hz", 1, 0);
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, IsAula() ? this->context->isSysDockInstalled ? 120 : 75 : 120, 5, " Hz", 1, 0);
}
#endif
this->addModuleListItemToggle(profile, HorizonOCModule_Governor);

View File

@@ -12,9 +12,9 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
/* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -36,13 +36,13 @@ BaseMenuGui::BaseMenuGui() : tempColors{ tsl::Color(0), tsl::Color(0), tsl::Colo
this->context = nullptr;
this->lastContextUpdate = 0;
this->listElement = nullptr;
// Pre-cache hardware model during initialization
IsAula();
IsMariko();
IsHoag();
// Initialize display strings
memset(displayStrings, 0, sizeof(displayStrings));
}
@@ -55,14 +55,14 @@ BaseMenuGui::~BaseMenuGui() {
void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
BaseGui::preDraw(renderer);
if(!this->context) [[unlikely]] return;
// All constants pre-calculated and cached
static constexpr const char* const labels[] = {
"App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "BAT", "PMIC", "FAN", "DISP"
};
static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1};
static u32 labelWidths[10];
static bool positionsInitialized = false;
@@ -77,29 +77,29 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
static u32 maxProfileValueWidth = renderer->getTextDimensions("PD Charger", false, SMALL_TEXT_SIZE).first; // longest word
u32 y = 91;
// === TOP SECTION ===
renderer->drawRoundedRect(14, 70-1, 420, 30+2, 15.0f, renderer->aWithOpacity(tsl::tableBGColor));
// App ID - use pre-formatted string
renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[0], false, positions[0] + labelWidths[0] + 9, y, SMALL_TEXT_SIZE, tsl::infoTextColor);
// Profile - use pre-formatted string
renderer->drawString(labels[1], false, 423 - maxProfileValueWidth - labelWidths[1] - 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[1], false, 423 - maxProfileValueWidth, y, SMALL_TEXT_SIZE, tsl::infoTextColor);
y = 129; // Direct assignment instead of += 38
// === MAIN DATA SECTION ===
renderer->drawRoundedRect(14, 106, 420, 156, 10.0f, renderer->aWithOpacity(tsl::tableBGColor));
// === FREQUENCY SECTION ===
// Labels first (better cache locality)
renderer->drawString(labels[2], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[3], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[4], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
// Current frequencies - use pre-formatted strings
renderer->drawString(displayStrings[2], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU
renderer->drawString(displayStrings[3], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU
@@ -107,7 +107,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
y = 149; // Direct assignment (129 + 20)
// renderer->drawString(displayStrings[19], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU Usage
renderer->drawString(displayStrings[19], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU Usage
renderer->drawString(displayStrings[17], false, positions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU Usage
renderer->drawString(displayStrings[18], false, positions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RAM Usage
@@ -115,39 +115,39 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
renderer->drawString(displayStrings[5], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU real
renderer->drawString(displayStrings[6], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU real
renderer->drawString(displayStrings[7], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM real
y = 169; // Direct assignment (149 + 20)
// === VOLTAGES ===
renderer->drawString(displayStrings[8], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU voltage
renderer->drawString(displayStrings[9], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage
renderer->drawStringWithColoredSections(displayStrings[10], false, {""}, dataPositions[5]-16, y, SMALL_TEXT_SIZE, tsl::infoTextColor, tsl::separatorColor);
y = 191; // Direct assignment (169 + 22)
// === TEMPERATURE SECTION ===
// Labels
renderer->drawString(labels[5], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[6], false, positions[6]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[7], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
// Temperatures with color - use pre-computed colors
renderer->drawString(displayStrings[11], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_SOC]); // SOC
renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_PCB]); // PCB
renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_Skin]); // Skin
y = 211; // Direct assignment (191 + 20)
renderer->drawString(displayStrings[14], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor);
// Power labels and values
renderer->drawString(labels[8], false, positions[8]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[9], false, positions[9], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[15], false, dataPositions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power now
renderer->drawString(displayStrings[16], false, dataPositions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power avg
y+=20;
renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
@@ -181,9 +181,9 @@ void BaseMenuGui::refresh()
if (armTicksToNs(ticks - this->lastContextUpdate) <= 1000000000UL) [[likely]] {
return; // Early exit for most calls
}
this->lastContextUpdate = ticks;
// Lazy context allocation
if (!this->context) [[unlikely]] {
this->context = new SysClkContext;
@@ -206,30 +206,30 @@ void BaseMenuGui::refresh()
// === FORMAT ALL DISPLAY STRINGS (once per second) ===
// App ID (hex conversion)
sprintf(displayStrings[0], "%016lX", context->applicationId);
// Profile
strcpy(displayStrings[1], sysclkFormatProfile(context->profile, true));
// Current frequencies
u32 hz = context->freqs[SysClkModule_CPU]; // CPU
sprintf(displayStrings[2], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[SysClkModule_GPU]; // GPU
sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[SysClkModule_MEM]; // MEM
sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
// Real frequencies
hz = context->realFreqs[SysClkModule_CPU]; // CPU
sprintf(displayStrings[5], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[SysClkModule_GPU]; // GPU
sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[SysClkModule_MEM]; // MEM
sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
// Voltages
sprintf(displayStrings[8], "%.1f mV", context->voltages[HocClkVoltage_CPU] / 1000.0);
sprintf(displayStrings[9], "%.1f mV", context->voltages[HocClkVoltage_GPU] / 1000.0);
@@ -243,31 +243,30 @@ void BaseMenuGui::refresh()
//sprintf(displayStrings[10], "%u mV", vddVoltageUv / 1000U);
sprintf(displayStrings[10], "%u.%u%u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U, (context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U, context->voltages[HocClkVoltage_EMCVDD2] / 1000U);
}
// Temperatures and pre-compute colors
u32 millis = context->temps[SysClkThermalSensor_SOC]; // SOC
sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[SysClkThermalSensor_SOC] = tsl::GradientColor(millis * 0.001f);
millis = context->temps[SysClkThermalSensor_PCB]; // PCB
sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[SysClkThermalSensor_PCB] = tsl::GradientColor(millis * 0.001f);
millis = context->temps[SysClkThermalSensor_Skin]; // Skin
sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[SysClkThermalSensor_Skin] = tsl::GradientColor(millis * 0.001f);
// SOC voltage (if available)
sprintf(displayStrings[14], "%u mV", context->voltages[HocClkVoltage_SOC] / 1000U);
// Power
sprintf(displayStrings[15], "%d mW", context->power[0]); // Now
sprintf(displayStrings[16], "%d mW", context->power[1]); // Avg
sprintf(displayStrings[17], "%u%%", context->partLoad[HocClkPartLoad_GPU] / 10);
sprintf(displayStrings[18], "%u%%", context->partLoad[SysClkPartLoad_EMC] / 10);
// sprintf(displayStrings[19], "%u", context->partLoad[HocClkPartLoad_CPUAvg]);
sprintf(displayStrings[19], "%u%%", context->partLoad[HocClkPartLoad_CPUMax] / 10);
millis = context->temps[HorizonOCThermalSensor_Battery]; // Battery
sprintf(displayStrings[20], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);

View File

@@ -285,14 +285,14 @@ void GlobalOverrideGui::listUI()
}
this->listElement->addItem(new tsl::elm::CategoryHeader(
"Temporary Overrides " + ult::DIVIDER_SYMBOL + " Reset"));
"Temporary Overrides " + ult::DIVIDER_SYMBOL + " \ue0e3 Reset"));
this->addModuleListItem(SysClkModule_CPU);
this->addModuleListItem(SysClkModule_GPU);
this->addModuleListItem(SysClkModule_MEM);
#if IS_MINIMAL == 0
ValueThresholds lcdThresholds(60, 65);
if(!IsHoag() && configList.values[HorizonOCConfigValue_OverwriteRefreshRate])
this->addModuleListItemValue(HorizonOCModule_Display, "Display", 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
this->addModuleListItemValue(HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
#endif
this->addModuleToggleItem(HorizonOCModule_Governor);
}

View File

@@ -242,18 +242,13 @@ void MiscGui::listUI()
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> noNamedValues = {};
this->listElement->addItem(new tsl::elm::CategoryHeader("Settings"));
addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr);
addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr);
#if IS_MINIMAL == 0
addConfigToggle(HocClkConfigValue_FixCpuVoltBug, nullptr);
#endif
addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr);
addConfigToggle(HocClkConfigValue_HandheldTDP, nullptr);
addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr);
// addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr);
#if IS_MINIMAL == 0
std::map<uint32_t, std::string> labels_pwr_l = {
@@ -281,7 +276,6 @@ void MiscGui::listUI()
);
}
ValueThresholds throttleThresholds(70, 80);
addConfigButton(
HocClkConfigValue_ThermalThrottleThreshold,
@@ -318,19 +312,19 @@ void MiscGui::listUI()
);
std::vector<NamedValue> dvfsOffset = {
NamedValue("-50", 0xFFFFFFCE),
NamedValue("-45", 0xFFFFFFD3),
NamedValue("-40", 0xFFFFFFD8),
NamedValue("-30", 0xFFFFFFE2),
NamedValue("-25", 0xFFFFFFE7),
NamedValue("-20", 0xFFFFFFEC),
NamedValue("-10", 0xFFFFFFF6),
NamedValue(" -5", 0xFFFFFFFB),
NamedValue(" 0", 0),
NamedValue(" +5", 5),
NamedValue("+10", 10),
NamedValue("+15", 15),
NamedValue("+20", 20),
NamedValue("-50 mV", 0xFFFFFFCE),
NamedValue("-45 mV", 0xFFFFFFD3),
NamedValue("-40 mV", 0xFFFFFFD8),
NamedValue("-30 mV", 0xFFFFFFE2),
NamedValue("-25 mV", 0xFFFFFFE7),
NamedValue("-20 mV", 0xFFFFFFEC),
NamedValue("-10 mV", 0xFFFFFFF6),
NamedValue(" -5 mV", 0xFFFFFFFB),
NamedValue("Disabled", 0),
NamedValue(" +5 mV", 5),
NamedValue("+10 mV", 10),
NamedValue("+15 mV", 15),
NamedValue("+20 mV", 20),
};
addConfigButton(HorizonOCConfigValue_DVFSOffset, "GPU DVFS Offset", ValueRange(0, 12, 1, "", 0), "GPU DVFS Offset", &thresholdsDisabled, {}, dvfsOffset, false);
@@ -383,47 +377,69 @@ void MiscGui::listUI()
});
this->listElement->addItem(gpuSubmenu);
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
#if IS_MINIMAL == 0
std::vector<NamedValue> chargerCurrents = {
NamedValue("Disabled", 0),
NamedValue("1024mA", 1024),
NamedValue("1280mA", 1280),
NamedValue("1536mA", 1536),
NamedValue("1792mA", 1792),
NamedValue("2048mA", 2048),
NamedValue("2304mA", 2304),
NamedValue("2560mA", 2560),
NamedValue("2816mA", 2816),
NamedValue("3072mA", 3072),
// std::vector<NamedValue> chargerCurrents = {
// NamedValue("Disabled", 0),
// NamedValue("1024mA", 1024),
// NamedValue("1280mA", 1280),
// NamedValue("1536mA", 1536),
// NamedValue("1792mA", 1792),
// NamedValue("2048mA", 2048),
// NamedValue("2304mA", 2304),
// NamedValue("2560mA", 2560),
// NamedValue("2816mA", 2816),
// NamedValue("3072mA", 3072),
// };
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
std::vector<NamedValue> gpuSchedValues = {
NamedValue("Do not override", GpuSchedulingMode_DoNotOverride),
NamedValue("Enabled", GpuSchedulingMode_Enabled, "96.5% limit"),
NamedValue("Disabled", GpuSchedulingMode_Disabled, "99.7% limit"),
};
tsl::elm::CustomDrawer* gpuSchedInfoText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 This option requires a reboot", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("to take effect", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
});
gpuSchedInfoText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70);
this->listElement->addItem(gpuSchedInfoText);
addConfigButton(
HorizonOCConfigValue_GPUScheduling,
"GPU Scheduling Override",
ValueRange(0, 0, 1, "", 0),
"GPU Scheduling Override",
&thresholdsDisabled,
{},
gpuSchedValues,
false
);
if(!IsHoag()) {
std::vector<NamedValue> chargerCurrents = {
NamedValue("Disabled", 0),
NamedValue("1024mA", 1024),
NamedValue("1280mA", 1280),
NamedValue("1536mA", 1536),
NamedValue("1792mA", 1792),
NamedValue("2048mA", 2048),
NamedValue("2304mA", 2304),
NamedValue("2560mA", 2560),
NamedValue("2816mA", 2816),
NamedValue("3072mA", 3072),
};
// std::vector<NamedValue> chargerCurrents = {
// NamedValue("Disabled", 0),
// NamedValue("1024mA", 1024),
// NamedValue("1280mA", 1280),
// NamedValue("1536mA", 1536),
// NamedValue("1792mA", 1792),
// NamedValue("2048mA", 2048),
// NamedValue("2304mA", 2304),
// NamedValue("2560mA", 2560),
// NamedValue("2816mA", 2816),
// NamedValue("3072mA", 3072),
// };
ValueThresholds chargerThresholds(2048, 2560);
// ValueThresholds chargerThresholds(2048, 2560);
addConfigButton(
HorizonOCConfigValue_BatteryChargeCurrent,
"Charge Current Override",
ValueRange(0, 0, 1, "", 0),
"Charge Current Override",
&chargerThresholds,
{},
chargerCurrents,
false
);
// addConfigButton(
// HorizonOCConfigValue_BatteryChargeCurrent,
// "Charge Current Override",
// ValueRange(0, 0, 1, "", 0),
// "Charge Current Override",
// &chargerThresholds,
// {},
// chargerCurrents,
// false
// );
addConfigToggle(HorizonOCConfigValue_OverwriteRefreshRate, nullptr);
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Enabling unsafe display", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
@@ -434,32 +450,33 @@ void MiscGui::listUI()
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 110);
this->listElement->addItem(warningText);
addConfigToggle(HorizonOCConfigValue_EnableUnsafeDisplayFreqs, nullptr);
} else {
std::vector<NamedValue> chargerCurrents = {
NamedValue("Disabled", 0),
NamedValue("1024mA", 1024),
NamedValue("1280mA", 1280),
NamedValue("1536mA", 1536),
NamedValue("1792mA", 1792),
NamedValue("2048mA", 2048),
NamedValue("2304mA", 2304),
NamedValue("2560mA", 2560),
};
ValueThresholds chargerThresholds(1792, 2048);
addConfigButton(
HorizonOCConfigValue_BatteryChargeCurrent,
"Charge Current Override",
ValueRange(0, 0, 1, "", 0),
"Charge Current Override",
&chargerThresholds,
{},
chargerCurrents,
false
);
}
// else {
// std::vector<NamedValue> chargerCurrents = {
// NamedValue("Disabled", 0),
// NamedValue("1024mA", 1024),
// NamedValue("1280mA", 1280),
// NamedValue("1536mA", 1536),
// NamedValue("1792mA", 1792),
// NamedValue("2048mA", 2048),
// NamedValue("2304mA", 2304),
// NamedValue("2560mA", 2560),
// };
// ValueThresholds chargerThresholds(1792, 2048);
// addConfigButton(
// HorizonOCConfigValue_BatteryChargeCurrent,
// "Charge Current Override",
// ValueRange(0, 0, 1, "", 0),
// "Charge Current Override",
// &chargerThresholds,
// {},
// chargerCurrents,
// false
// );
// }
#endif
}
@@ -583,16 +600,9 @@ protected:
};
if(IsErista()) {
addConfigButton(
KipConfigValue_eristaEmcMaxClock,
"RAM Max Clock",
ValueRange(0, 1, 1, "", 1),
"RAM Max Clock",
&eristaRamThresholds,
{},
eristaMaxEmcClock,
false
);
addConfigButton(KipConfigValue_eristaEmcMaxClock, "RAM Max Clock", ValueRange(0, 1, 1, "", 1), "RAM Max Clock", &eristaRamThresholds, {}, eristaMaxEmcClock, false);
addConfigButton(KipConfigValue_eristaEmcMaxClock1, "RAM Max Clock", ValueRange(0, 1, 1, "", 1), "RAM Max Clock", &eristaRamThresholds, {}, eristaMaxEmcClock, false);
addConfigButton(KipConfigValue_eristaEmcMaxClock2, "RAM Max Clock", ValueRange(0, 1, 1, "", 1), "RAM Max Clock", &eristaRamThresholds, {}, eristaMaxEmcClock, false);
} else {
addConfigButton(
KipConfigValue_marikoEmcMaxClock,
@@ -631,7 +641,7 @@ protected:
addConfigButton(
KipConfigValue_marikoEmcVddqVolt,
"RAM VDDQ Voltage",
ValueRange(550000, 700000, 5000, "mV", 1000),
ValueRange(400000, 700000, 5000, "mV", 1000),
"RAM VDDQ Voltage",
&thresholdsDisabled,
{},
@@ -713,37 +723,6 @@ protected:
this->listElement->addItem(new tsl::elm::CategoryHeader("Advanced"));
addConfigButton(KipConfigValue_t6_tRTW_fine_tune, "t6 tRTW Fine Tune", ValueRange(0, 4, 1, "", 0), "tRTW Fine Tune", &thresholdsDisabled, {}, t6_tRTW_fine_tune, false);
addConfigButton(KipConfigValue_t7_tWTR_fine_tune, "t7 tWTR Fine Tune", ValueRange(0, 6, 1, "", 0), "tWTR Fine Tune", &thresholdsDisabled, {}, t7_tWTR_fine_tune, false);
#if IS_MINIMAL == 0
if(IsMariko()) {
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
tsl::elm::ListItem* emcUpdBtn = new tsl::elm::ListItem("Update RAM Timings");
emcUpdBtn->setClickListener([this](u64 keys) {
if (keys & HidNpadButton_A) {
if(this->context->freqs[SysClkModule_MEM] > 1600000000) {
Result rc = hocClkIpcUpdateEmcRegs();
if (R_FAILED(rc)) {
FatalGui::openWithResultCode("hocClkIpcUpdateEmcRegs", rc);
return false;
}
return true;
} else {
writeNotification("Horizon OC\nSet your ram frequency to max\nbefore applying timings!");
}
}
return false;
});
this->listElement->addItem(emcUpdBtn);
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 This feature is EXPERIMENTAL", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("and should only be used for testing!", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
});
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70);
this->listElement->addItem(warningText);
}
#endif
}
};

View File

@@ -39,7 +39,7 @@ DEFINES := -DDISABLE_IPC -DTARGET="\"$(TARGET)\"" -DTARGET_VERSION="\"$(TARGET_V
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -O2 -ffunction-sections \
CFLAGS := -g -Wall -Os -ffunction-sections \
$(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -D__SWITCH__

View File

@@ -1,6 +1,7 @@
/*
* Copyright (c) 2020-2023 CTCaer
* Copyright (c) 2023 p-sam
* Copyright (c) 2026 Souldbminer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -47,7 +48,7 @@
#define PTO_CLK_CNT_BUSY BIT(31)
#define PTO_CLK_CNT 0xFFFFFF
#define CLK_PTO_CCLK_G 0x12
#define CLK_PTO_CCLK_G_DIV2 0x13
#define CLK_PTO_EMC 0x24
#define CLOCK(x) (*(volatile u32 *)(g_clk_base + (x)))
@@ -117,7 +118,7 @@ static u32 g_mem_freq = 0;
static u32 g_emc_lall = 0;
static u32 g_emc_lcpu = 0;
static u32 _clock_get_dev_freq(u32 id)
static u32 _clock_get_dev_freq(u32 id, u32 multiplier)
{
const u32 pto_win = 16;
const u32 pto_osc = 32768;
@@ -148,7 +149,7 @@ static u32 _clock_get_dev_freq(u32 id)
(void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL);
usleep(2);
u32 freq_khz = (u64)cnt * pto_osc / pto_win / 1000;
u32 freq_khz = (u64)cnt * multiplier * pto_osc / pto_win;
return freq_khz;
}
@@ -203,8 +204,8 @@ static void _clock_update_freqs(void)
return;
}
g_mem_freq = _clock_get_dev_freq(CLK_PTO_EMC) * 1000;
g_cpu_freq = _clock_get_dev_freq(CLK_PTO_CCLK_G) * 1000;
g_mem_freq = _clock_get_dev_freq(CLK_PTO_EMC, 1);
g_cpu_freq = _clock_get_dev_freq(CLK_PTO_CCLK_G_DIV2, 2);
if (!g_gpu_base)
{

View File

@@ -3,8 +3,8 @@
"title_id": "0x00FF0000636C6BFF",
"title_id_range_min": "0x00FF0000636C6BFF",
"title_id_range_max": "0x00FF0000636C6BFF",
"main_thread_stack_size": "0x00008000",
"main_thread_priority": 63,
"main_thread_stack_size": "0x0000C000",
"main_thread_priority": 16,
"default_cpu_id": 3,
"process_category": 0,
"is_retail": true,
@@ -25,7 +25,7 @@
"type": "kernel_flags",
"value": {
"highest_thread_priority": 63,
"lowest_thread_priority": 41,
"lowest_thread_priority": 16,
"lowest_cpu_id": 0,
"highest_cpu_id": 3
}

View File

@@ -65,12 +65,16 @@
#define HOSSVC_HAS_CLKRST (hosversionAtLeast(8,0,0))
#define HOSSVC_HAS_TC (hosversionAtLeast(5,0,0))
#define NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD 0x80044715
#define NVSCHED_CTRL_ENABLE 0x00000601
#define NVSCHED_CTRL_DISABLE 0x00000602
#define systemtickfrequency 19200000
#define systemtickfrequencyF 19200000.0f
#define CPU_TICK_WAIT (1'000'000'000 / 60)
constexpr u64 CpuTimeOutNs = 500'000'000;
constexpr double Systemtickfrequency = 19200000.0 * (static_cast<double>(CpuTimeOutNs) / 1'000'000'000.0);
Result nvInitialize_rc;
Result nvCheck = 1;
Result nvCheck_sched = 1;
LEvent threadexit;
Thread gpuLThread;
Thread cpuCore0Thread;
Thread cpuCore1Thread;
@@ -85,16 +89,17 @@ Result pwmDutyCycleCheck = 1;
double Rotation_Duty = 0;
u8 fanLevel;
uint32_t GPU_Load_u = 0, fd = 0;
uint32_t GPU_Load_u = 0, fd = 0, fd2 = 0;
BatteryChargeInfo info;
static SysClkSocType g_socType = SysClkSocType_Erista;
static HorizonOCConsoleType g_consoleType = HorizonOCConsoleType_Iowa;
std::atomic<uint64_t> idletick0{systemtickfrequency};
std::atomic<uint64_t> idletick1{systemtickfrequency};
std::atomic<uint64_t> idletick2{systemtickfrequency};
std::atomic<uint64_t> idletick3{systemtickfrequency};
u64 idletick0 = 0;
u64 idletick1 = 0;
u64 idletick2 = 0;
// u64 idletick3 = 0;
u32 cpu0, cpu1, cpu2, cpu3, cpuAvg;
u16 cpuSpeedo0, cpuSpeedo2, socSpeedo0; // CPU, GPU, SOC
u32 speedoBracket;
@@ -164,16 +169,16 @@ PcvModuleId Board::GetPcvModuleId(SysClkModule sysclkModule)
return pcvModuleId;
}
void CheckCore(void* idletick_ptr) {
std::atomic<uint64_t>* idletick = (std::atomic<uint64_t>*)idletick_ptr;
while (true) {
uint64_t idletick_a;
uint64_t idletick_b;
svcGetInfo(&idletick_b, InfoType_IdleTickCount, INVALID_HANDLE, -1);
svcSleepThread(CPU_TICK_WAIT);
svcGetInfo(&idletick_a, InfoType_IdleTickCount, INVALID_HANDLE, -1);
idletick->store(idletick_a - idletick_b, std::memory_order_release);
}
void CheckCore(void *idletickPtr) {
u64* idletick = static_cast<u64 *>(idletickPtr);
while(true) {
u64 idletickA;
u64 idletickB;
svcGetInfo(&idletickB, InfoType_IdleTickCount, INVALID_HANDLE, -1);
svcWaitForAddress(&threadexit, ArbitrationType_WaitIfEqual, 0, CpuTimeOutNs);
svcGetInfo(&idletickA, InfoType_IdleTickCount, INVALID_HANDLE, -1);
*idletick = idletickA - idletickB;
}
}
void gpuLoadThread(void*) {
@@ -205,7 +210,6 @@ void miscThreadFunc(void*) {
}
}
void Board::Initialize()
{
Result rc = 0;
@@ -237,8 +241,11 @@ void Board::Initialize()
rc = tmp451Initialize();
ASSERT_RESULT_OK(rc, "tmp451Initialize");
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
nvInitialize_rc = nvInitialize();
if (R_SUCCEEDED(nvInitialize_rc)) {
nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
nvCheck_sched = nvOpen(&fd2, "/dev/nvsched-ctrl");
}
rc = rgltrInitialize();
ASSERT_RESULT_OK(rc, "rgltrInitialize");
@@ -253,17 +260,17 @@ void Board::Initialize()
threadCreate(&gpuLThread, gpuLoadThread, NULL, NULL, 0x1000, 0x3F, -2);
threadStart(&gpuLThread);
threadCreate(&cpuCore0Thread, CheckCore, &idletick0, NULL, 0x500, 0x10, 0);
threadCreate(&cpuCore1Thread, CheckCore, &idletick1, NULL, 0x500, 0x10, 1);
threadCreate(&cpuCore2Thread, CheckCore, &idletick2, NULL, 0x500, 0x10, 2);
threadCreate(&cpuCore3Thread, CheckCore, &idletick3, NULL, 0x500, 0x10, 3);
threadCreate(&miscThread, miscThreadFunc, NULL, NULL, 0x1000, 0x3F, 3);
leventClear(&threadexit);
threadCreate(&cpuCore0Thread, CheckCore, &idletick0, NULL, 0x1000, 0x10, 0);
threadCreate(&cpuCore1Thread, CheckCore, &idletick1, NULL, 0x1000, 0x10, 1);
threadCreate(&cpuCore2Thread, CheckCore, &idletick2, NULL, 0x1000, 0x10, 2);
// threadCreate(&cpuCore3Thread, CheckCore, &idletick3, NULL, 0x1000, 0x10, 3);
threadCreate(&miscThread, miscThreadFunc, NULL, NULL, 0x1000, 0x10, 3);
threadStart(&cpuCore0Thread);
threadStart(&cpuCore1Thread);
threadStart(&cpuCore2Thread);
threadStart(&cpuCore3Thread);
// threadStart(&cpuCore3Thread);
threadStart(&miscThread);
batteryInfoInitialize();
@@ -393,7 +400,7 @@ void Board::Exit()
threadClose(&cpuCore0Thread);
threadClose(&cpuCore1Thread);
threadClose(&cpuCore2Thread);
threadClose(&cpuCore3Thread);
// threadClose(&cpuCore3Thread);
threadClose(&miscThread);
pwmChannelSessionClose(&g_ICon);
@@ -401,6 +408,7 @@ void Board::Exit()
rgltrExit();
batteryInfoExit();
pmdmntExit();
nvExit();
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag)
DisplayRefresh_Shutdown();
}
@@ -451,13 +459,22 @@ void Board::SetHz(SysClkModule module, std::uint32_t hz)
ASSERT_RESULT_OK(rc, "clkrstOpenSession");
rc = clkrstSetClockRate(&session, hz);
ASSERT_RESULT_OK(rc, "clkrstSetClockRate");
if (module == SysClkModule_CPU) {
svcSleepThread(300'000);
rc = clkrstSetClockRate(&session, hz);
ASSERT_RESULT_OK(rc, "clkrstSetClockRate");
}
clkrstCloseSession(&session);
}
else
{
rc = pcvSetClockRate(Board::GetPcvModule(module), hz);
ASSERT_RESULT_OK(rc, "pcvSetClockRate");
if (module == SysClkModule_CPU) {
svcSleepThread(300'000);
rc = pcvSetClockRate(Board::GetPcvModule(module), hz);
ASSERT_RESULT_OK(rc, "pcvSetClockRate");
}
}
}
@@ -767,6 +784,15 @@ std::int32_t Board::GetPowerMw(SysClkPowerSensor sensor)
return 0;
}
u32 GetMaxCpuLoad() {
float cpuUsage0 = std::clamp(((Systemtickfrequency - idletick0) / static_cast<double>(Systemtickfrequency)) * 1000.0, 0.0, 1000.0);
float cpuUsage1 = std::clamp(((Systemtickfrequency - idletick1) / static_cast<double>(Systemtickfrequency)) * 1000.0, 0.0, 1000.0);
float cpuUsage2 = std::clamp(((Systemtickfrequency - idletick2) / static_cast<double>(Systemtickfrequency)) * 1000.0, 0.0, 1000.0);
// float cpuUsage3 = std::clamp(((Systemtickfrequency - idletick3) / static_cast<double>(Systemtickfrequency)) * 1000.0, 0.0, 1000.0);
return std::round(std::max({cpuUsage0, cpuUsage1, cpuUsage2}));
}
std::uint32_t Board::GetPartLoad(SysClkPartLoad loadSource)
{
switch(loadSource)
@@ -777,8 +803,8 @@ std::uint32_t Board::GetPartLoad(SysClkPartLoad loadSource)
return t210EmcLoadCpu();
case HocClkPartLoad_GPU:
return GPU_Load_u;
case HocClkPartLoad_CPUAvg:
return idletick0;
case HocClkPartLoad_CPUMax:
return GetMaxCpuLoad();
case HocClkPartLoad_BAT:
batteryInfoGetChargeInfo(&info);
return info.RawBatteryCharge;
@@ -1111,162 +1137,6 @@ void Board::PcvHijackDvfs(u32 vmin) {
#define MC_REGISTER_BASE 0x70019000
#define MC_REGISTER_REGION_SIZE 0x1000
#define EMC_REGISTER_BASE 0x7001b000
#define EMC_REGISTER_REGION_SIZE 0x1000
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
#define WRITE_REGISTER_EMC(TIMING_OFFSET, VALUE) \
do { \
args = {}; \
args.X[0] = 0xF0000002; \
args.X[1] = EMC_REGISTER_BASE + (TIMING_OFFSET); \
args.X[2] = 0xFFFFFFFF; \
args.X[3] = (VALUE); \
svcCallSecureMonitor(&args); \
} while (false)
#define WRITE_REGISTER_MC(TIMING_OFFSET, VALUE) \
do { \
args = {}; \
args.X[0] = 0xF0000002; \
args.X[1] = MC_REGISTER_BASE + (TIMING_OFFSET); \
args.X[2] = 0xFFFFFFFF; \
args.X[3] = (VALUE); \
svcCallSecureMonitor(&args); \
} while (false)
// NOTE: needs patch to exosphere to expose emc region to secmon. MC does NOT need this patch
u32 tRCD_values[] = { 18, 17, 16, 15, 14, 13, 12, 11 };
u32 tRP_values[] = { 18, 17, 16, 15, 14, 13, 12, 11 };
u32 tRAS_values[] = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
double tRRD_values[] = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? */
u32 tRFC_values[] = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
u32 tWTR_values[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
u32 tREFpb_values[] = { 3900, 5850, 7800, 11700, 15600, 99999 };
// Credit to Lightos for these timings!
void Board::UpdateShadowRegs(u32 tRCD_i, u32 tRP_i, u32 tRAS_i, u32 tRRD_i, u32 tRFC_i, u32 tRTW_i, u32 tWTR_i, u32 tREFpb_i, u32 ramFreq, u32 rlAdd, u32 wlAdd, bool hpMode) {
// timing stuff
SecmonArgs args = {};
constexpr double MC_ARB_DIV = 4.0;
constexpr u32 MC_ARB_SFA = 2;
double tCK_avg = 1000'000.0 / ramFreq;
u32 BL = 16;
u32 RL = 28 + rlAdd;
u32 WL = 14 + wlAdd;
u32 RL_DBI = RL + 4;
u32 tRCD = tRCD_values[tRCD_i];
u32 tRPpb = tRP_values[tRP_i];
u32 tRAS = tRAS_values[tRAS_i];
double tRRD = tRRD_values[tRRD_i];
u32 tRFCpb = tRFC_values[tRFC_i];
u32 tWTR = 10 - tWTR_values[tWTR_i];
u32 tFAW = static_cast<u32>(tRRD * 4.0);
double tDQSCK_max = 3.5;
u32 tWPRE = 2;
double tRPST = 0.5;
u32 tR2W = CEIL(RL_DBI + (tDQSCK_max / tCK_avg) + (BL / 2) - WL + tWPRE + FLOOR(tRPST) + 9.0) - (tRTW_i * 3);
u32 tRC = tRAS + tRPpb;
u32 tRFCab = tRFCpb * 2;
u32 tRPab = tRPpb + 3;
u32 tW2R = CEIL(MAX(WL + (0.010322547033278747 * (ramFreq / 1000.0)), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg));
double tMMRI = tRCD + (tCK_avg * 3);
double pdex2mrr = tMMRI + 10;
u32 emc_cfg = hpMode ? 0x13200000 : 0xF3200000;
u32 refresh_raw = 0xFFFF;
if (tREFpb_i != 6) {
refresh_raw = CEIL(tREFpb_values[tREFpb_i] / tCK_avg) - 0x40;
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
}
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
u32 tR2P = 12 + (rlAdd / 2);
u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
double tXSR = (double) (tRFCab + 7.5);
args = {};
args.X[0] = 0xF0000002;
args.X[1] = EMC_REGISTER_BASE + EMC_INTSTATUS_0;
svcCallSecureMonitor(&args);
if(args.X[1] == (EMC_REGISTER_BASE + EMC_INTSTATUS_0)) { // if param 1 is identical read failed, exosphere needs patch!
writeNotification("Horizon OC\nExosphere not patched\nfor EMC r/w");
return;
}
// actually write the timings
WRITE_REGISTER_EMC(EMC_CFG_0, emc_cfg);
WRITE_REGISTER_EMC(EMC_RD_RCD_0, GET_CYCLE_CEIL(tRCD));
WRITE_REGISTER_EMC(EMC_WR_RCD_0, GET_CYCLE_CEIL(tRCD));
WRITE_REGISTER_EMC(EMC_RC_0, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB8)));
WRITE_REGISTER_EMC(EMC_RAS_0, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F)));
WRITE_REGISTER_EMC(EMC_RRD_0, GET_CYCLE_CEIL(tRRD));
WRITE_REGISTER_EMC(EMC_RFCPB_0, GET_CYCLE_CEIL(tRFCpb));
WRITE_REGISTER_EMC(EMC_RFC_0, GET_CYCLE_CEIL(tRFCab));
WRITE_REGISTER_EMC(EMC_RP_0, GET_CYCLE_CEIL(tRPpb));
WRITE_REGISTER_EMC(EMC_TRPAB_0, MIN(GET_CYCLE_CEIL(tRPab), static_cast<u32>(0x3F)));
WRITE_REGISTER_EMC(EMC_R2W_0, tR2W);
WRITE_REGISTER_EMC(EMC_W2R_0, tW2R);
WRITE_REGISTER_EMC(EMC_REFRESH_0, refresh_raw);
WRITE_REGISTER_EMC(EMC_PRE_REFRESH_REQ_CNT_0, refresh_raw / 4);
WRITE_REGISTER_EMC(EMC_TREFBW_0, trefbw);
WRITE_REGISTER_EMC(EMC_PDEX2MRR_0, GET_CYCLE_CEIL(pdex2mrr));
WRITE_REGISTER_EMC(EMC_TXSR_0, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
WRITE_REGISTER_EMC(EMC_TXSRDLL_0, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RCD_0, CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RP_0, CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RC_0, CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RAS_0, CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_FAW_0, CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RRD_0, CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RFCPB_0, CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_R2W_0, CEIL(tR2W / MC_ARB_DIV) - 1 + MC_ARB_SFA);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_W2R_0, CEIL(tW2R / MC_ARB_DIV) - 1 + MC_ARB_SFA);
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RAP2PRE_0, CEIL(tR2P / MC_ARB_DIV));
WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_WAP2PRE_0, CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA);
u32 da_turns = 0;
da_turns |= u8((CEIL(tR2W / MC_ARB_DIV) - 1 + MC_ARB_SFA) / 2) << 16;
da_turns |= u8((CEIL(tW2R / MC_ARB_DIV) - 1 + MC_ARB_SFA) / 2) << 24;
WRITE_REGISTER_MC(MC_EMEM_ARB_DA_TURNS_0, da_turns);
u32 da_covers = 0;
u8 r_cover = ((CEIL(tR2P / MC_ARB_DIV)) + (CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1) + (CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2)) / 2;
u8 w_cover = ((CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA) + (CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1) + (CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2)) / 2;
da_covers |= ((u32)(CEIL(GET_CYCLE_CEIL(tRC) / (u32)MC_ARB_DIV) - 1) / 2);
da_covers |= (r_cover << 8);
da_covers |= (w_cover << 16);
WRITE_REGISTER_MC(MC_EMEM_ARB_DA_COVERS_0, da_covers);
// TODO: modify mc_emem_arb_misc0
WRITE_REGISTER_MC(MC_TIMING_CONTROL_0, 0x1); // update timing regs as they are shadowed
WRITE_REGISTER_EMC(EMC_TIMING_CONTROL_0, 0x1);
}
bool Board::IsDram8GB() {
SecmonArgs args = {};
args.X[0] = 0xF0000002;
@@ -1279,3 +1149,22 @@ bool Board::IsDram8GB() {
} else
return args.X[1] == 0x00002000 ? true : false;
}
void Board::SetGpuSchedulingMode(GpuSchedulingMode mode) {
if (nvCheck_sched == 1) {
return;
}
u32 temp;
switch(mode) {
case GpuSchedulingMode_DoNotOverride:
return;
case GpuSchedulingMode_Disabled:
nvIoctl(fd2, NVSCHED_CTRL_DISABLE, &temp);
break;
case GpuSchedulingMode_Enabled:
nvIoctl(fd2, NVSCHED_CTRL_ENABLE, &temp);
break;
default:
ASSERT_ENUM_VALID(GpuSchedulingMode, mode);
}
}

View File

@@ -63,8 +63,8 @@ class Board
static std::uint32_t GetVoltage(HocClkVoltage voltage);
static u8 GetFanRotationLevel();
static u8 GetDramID();
static void UpdateShadowRegs(u32 tRCD_i, u32 tRP_i, u32 tRAS_i, u32 tRRD_i, u32 tRFC_i, u32 tRTW_i, u32 tWTR_i, u32 tREFpb_i, u32 ramFreq, u32 rlAdd, u32 wlAdd, bool hpMode);
static bool IsDram8GB();
static void SetGpuSchedulingMode(GpuSchedulingMode mode);
protected:
static void FetchHardwareInfos();
static PcvModule GetPcvModule(SysClkModule sysclkModule);

View File

@@ -39,6 +39,7 @@
#include <cstring>
#include <cstdio>
#include <crc32.h>
#include <sys/stat.h>
#define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0))
bool isGovernorEnabled = false; // to avoid thread messes
@@ -112,36 +113,14 @@ ClockManager::ClockManager()
this->context->dramID = Board::GetDramID();
this->context->isDram8GB = Board::IsDram8GB();
previousRamHz = Board::GetHz(SysClkModule_MEM);
}
Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling));
this->context->gpuSchedulingMode = (GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling);
void ClockManager::FixCpuBug() {
if(this->config->Refresh() && this->RefreshContext()) {
u32 targetHz = 0;
u32 maxHz = 0;
u32 nearestHz = 0;
// ResetToStockClocks();
targetHz = this->context->overrideFreqs[SysClkModule_CPU];
if (!targetHz) {
targetHz = this->config->GetAutoClockHz(this->context->applicationId, SysClkModule_CPU, this->context->profile, false);
if(!targetHz)
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, SysClkModule_CPU, this->context->profile, false);
}
if (targetHz) {
maxHz = this->GetMaxAllowedHz(SysClkModule_CPU, this->context->profile);
nearestHz = this->GetNearestHz(SysClkModule_CPU, targetHz, maxHz);
while ((nearestHz = this->GetNearestHz(SysClkModule_CPU, targetHz, maxHz)) != targetHz) {
Board::SetHz(SysClkModule_CPU, 1020000000);
svcSleepThread(1'000'000);
Board::SetHz(SysClkModule_CPU, maxHz);
this->context->freqs[SysClkModule_CPU] = maxHz;
}
Board::SetHz(SysClkModule_CPU, targetHz);
}
struct stat st = {0};
if (stat("sdmc:/atmosphere/contents/42000000000000A0", &st) == 0 && S_ISDIR(st.st_mode)) {
this->context->isSysDockInstalled = true;
} else {
this->context->isSysDockInstalled = false;
}
}
@@ -465,12 +444,12 @@ void ClockManager::Tick()
}
}
if(this->config->GetConfigValue(HocClkConfigValue_EnforceBoardLimit) && opMode == AppletOperationMode_Console ) {
if(Board::GetPowerMw(SysClkPowerSensor_Now) < 0) {
ResetToStockClocks();
return;
}
}
// if(this->config->GetConfigValue(HocClkConfigValue_EnforceBoardLimit) && opMode == AppletOperationMode_Console ) {
// if(Board::GetPowerMw(SysClkPowerSensor_Now) < 0) {
// ResetToStockClocks();
// return;
// }
// }
if(((tmp451TempSoc() / 1000) > (int)this->config->GetConfigValue(HocClkConfigValue_ThermalThrottleThreshold)) && this->config->GetConfigValue(HocClkConfigValue_ThermalThrottle)) {
ResetToStockClocks();
@@ -567,7 +546,6 @@ void ClockManager::Tick()
if(module == SysClkModule_MEM && Board::GetSocType() == SysClkSocType_Mariko && targetHz > oldHz && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) {
s32 dvfsOffset = this->config->GetConfigValue(HorizonOCConfigValue_DVFSOffset);
dvfsOffset = std::max(dvfsOffset, -50);
u32 vmin = Board::GetMinimumGpuVoltage(targetHz / 1000000) + dvfsOffset;
Board::PcvHijackDvfs(vmin);
@@ -577,7 +555,7 @@ void ClockManager::Tick()
I2c_BuckConverter_SetMvOut(&I2c_Mariko_GPU, vmin);
}
this->context->voltages[HocClkVoltage_GPU] = vmin;
this->context->voltages[HocClkVoltage_GPU] = vmin * 1000;
}
Board::SetHz((SysClkModule)module, nearestHz);
@@ -605,10 +583,6 @@ void ClockManager::Tick()
Board::ResetToStockGpu();
}
}
if(module == SysClkModule_CPU && this->config->GetConfigValue(HocClkConfigValue_FixCpuVoltBug)) {
FixCpuBug();
}
}
}
}
@@ -657,6 +631,11 @@ bool ClockManager::RefreshContext()
{
// this->rnxSync->ToggleSync(this->GetConfig()->GetConfigValue(HocClkConfigValue_SyncReverseNXMode));
Board::ResetToStock();
if (Board::GetSocType() == SysClkSocType_Mariko && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) {
Board::PcvHijackDvfs(0);
Board::SetHz(SysClkModule_GPU, ~0);
Board::ResetToStockGpu();
}
this->WaitForNextTick();
}
@@ -832,6 +811,8 @@ void ClockManager::SetKipData() {
CUST_WRITE_FIELD_BATCH(&table, commonEmcMemVolt, this->config->GetConfigValue(KipConfigValue_commonEmcMemVolt));
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock, this->config->GetConfigValue(KipConfigValue_eristaEmcMaxClock));
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock1, this->config->GetConfigValue(KipConfigValue_eristaEmcMaxClock1));
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock2, this->config->GetConfigValue(KipConfigValue_eristaEmcMaxClock2));
CUST_WRITE_FIELD_BATCH(&table, marikoEmcMaxClock, this->config->GetConfigValue(KipConfigValue_marikoEmcMaxClock));
CUST_WRITE_FIELD_BATCH(&table, marikoEmcVddqVolt, this->config->GetConfigValue(KipConfigValue_marikoEmcVddqVolt));
CUST_WRITE_FIELD_BATCH(&table, emcDvbShift, this->config->GetConfigValue(KipConfigValue_emcDvbShift));
@@ -955,6 +936,8 @@ void ClockManager::GetKipData() {
initialConfigValues[KipConfigValue_commonEmcMemVolt] = cust_get_common_emc_volt(&table);
initialConfigValues[KipConfigValue_eristaEmcMaxClock] = cust_get_erista_emc_max(&table);
initialConfigValues[KipConfigValue_eristaEmcMaxClock1] = cust_get_erista_emc_max1(&table);
initialConfigValues[KipConfigValue_eristaEmcMaxClock2] = cust_get_erista_emc_max2(&table);
initialConfigValues[KipConfigValue_marikoEmcMaxClock] = cust_get_mariko_emc_max(&table);
initialConfigValues[KipConfigValue_marikoEmcVddqVolt] = cust_get_mariko_emc_vddq(&table);
initialConfigValues[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table);
@@ -1001,6 +984,8 @@ void ClockManager::GetKipData() {
configValues.values[KipConfigValue_commonEmcMemVolt] = cust_get_common_emc_volt(&table);
configValues.values[KipConfigValue_eristaEmcMaxClock] = cust_get_erista_emc_max(&table);
configValues.values[KipConfigValue_eristaEmcMaxClock1] = cust_get_erista_emc_max1(&table);
configValues.values[KipConfigValue_eristaEmcMaxClock2] = cust_get_erista_emc_max2(&table);
configValues.values[KipConfigValue_marikoEmcMaxClock] = cust_get_mariko_emc_max(&table);
configValues.values[KipConfigValue_marikoEmcVddqVolt] = cust_get_mariko_emc_vddq(&table);
configValues.values[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table);
@@ -1072,22 +1057,3 @@ void ClockManager::GetKipData() {
writeNotification("Horizon OC\nConfig refresh failed");
}
}
void ClockManager::UpdateRamTimings() {
u32 t1_tRCD = this->config->GetConfigValue(KipConfigValue_t1_tRCD);
u32 t2_tRP = this->config->GetConfigValue(KipConfigValue_t2_tRP);
u32 t3_tRAS = this->config->GetConfigValue(KipConfigValue_t3_tRAS);
u32 t4_tRRD = this->config->GetConfigValue(KipConfigValue_t4_tRRD);
u32 t5_tRFC = this->config->GetConfigValue(KipConfigValue_t5_tRFC);
u32 t6_tRTW = this->config->GetConfigValue(KipConfigValue_t6_tRTW);
u32 t7_tWTR = this->config->GetConfigValue(KipConfigValue_t7_tWTR);
u32 t8_tREFI = this->config->GetConfigValue(KipConfigValue_t8_tREFI);
bool hpMode = (bool)this->config->GetConfigValue(KipConfigValue_hpMode);
u64 ramFreq = initialConfigValues[KipConfigValue_marikoEmcMaxClock];
u32 rlAdd = initialConfigValues[KipConfigValue_mem_burst_read_latency];
u32 wlAdd = initialConfigValues[KipConfigValue_mem_burst_write_latency];
Board::UpdateShadowRegs(t1_tRCD, t2_tRP, t3_tRAS, t4_tRRD, t5_tRFC, t6_tRTW, t7_tWTR, t8_tREFI, ramFreq, rlAdd, wlAdd, hpMode);
}

View File

@@ -49,7 +49,6 @@ class ClockManager
ClockManager();
virtual ~ClockManager();
void FixCpuBug();
SysClkContext GetCurrentContext();
Config* GetConfig();
@@ -63,7 +62,6 @@ class ClockManager
void SetKipData();
void GetKipData();
static void GovernorThread(void* arg);
void UpdateRamTimings();
struct {
std::uint32_t count;
std::uint32_t list[SYSCLK_FREQ_LIST_MAX];

View File

@@ -209,11 +209,6 @@ Result IpcService::ServiceHandlerFunc(void* arg, const IpcServerRequest* r, u8*
return ipcSrv->SetKipData();
}
break;
case HocClkIpcCmd_UpdateEmcRegs:
if (r->data.size >= 0) {
return ipcSrv->UpdateEmcRegs();
}
break;
}
return SYSCLK_ERROR(Generic);
@@ -380,10 +375,4 @@ Result IpcService::GetKipData() {
this->clockMgr->GetKipData();
return 0;
}
Result IpcService::UpdateEmcRegs() {
this->clockMgr->UpdateRamTimings();
return 0;
}
}

View File

@@ -57,8 +57,6 @@ class IpcService
Result SetReverseNXRTMode(ReverseNXMode mode);
Result SetKipData();
Result GetKipData();
Result UpdateEmcRegs();
Result CalculateGPUVmin();
bool running;
Thread thread;
LockableMutex threadMutex;

View File

@@ -32,6 +32,8 @@ typedef struct {
u32 hpMode;
u32 commonEmcMemVolt;
u32 eristaEmcMaxClock;
u32 eristaEmcMaxClock1;
u32 eristaEmcMaxClock2;
u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt;
u32 emcDvbShift;
@@ -192,6 +194,8 @@ static inline bool cust_set_hp_mode(const char* p, u32 v) { CUST_WRITE_FIELD(p,
static inline bool cust_set_common_emc_volt(const char* p, u32 v) { CUST_WRITE_FIELD(p, commonEmcMemVolt, v); }
static inline bool cust_set_erista_emc_max(const char* p, u32 v) { CUST_WRITE_FIELD(p, eristaEmcMaxClock, v); }
static inline bool cust_set_erista_emc_max1(const char* p, u32 v) { CUST_WRITE_FIELD(p, eristaEmcMaxClock1, v); }
static inline bool cust_set_erista_emc_max2(const char* p, u32 v) { CUST_WRITE_FIELD(p, eristaEmcMaxClock2, v); }
static inline bool cust_set_mariko_emc_max(const char* p, u32 v) { CUST_WRITE_FIELD(p, marikoEmcMaxClock, v); }
static inline bool cust_set_mariko_emc_vddq(const char* p, u32 v) { CUST_WRITE_FIELD(p, marikoEmcVddqVolt, v); }
static inline bool cust_set_emc_dvb_shift(const char* p, u32 v) { CUST_WRITE_FIELD(p, emcDvbShift, v); }
@@ -261,6 +265,8 @@ static inline u32 cust_get_hp_mode(const CustomizeTable* t) { return CUST_GET_FI
static inline u32 cust_get_common_emc_volt(const CustomizeTable* t) { return CUST_GET_FIELD(t, commonEmcMemVolt); }
static inline u32 cust_get_erista_emc_max(const CustomizeTable* t) { return CUST_GET_FIELD(t, eristaEmcMaxClock); }
static inline u32 cust_get_erista_emc_max1(const CustomizeTable* t) { return CUST_GET_FIELD(t, eristaEmcMaxClock1); }
static inline u32 cust_get_erista_emc_max2(const CustomizeTable* t) { return CUST_GET_FIELD(t, eristaEmcMaxClock2); }
static inline u32 cust_get_mariko_emc_max(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoEmcMaxClock); }
static inline u32 cust_get_mariko_emc_vddq(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoEmcVddqVolt); }
static inline u32 cust_get_emc_dvb_shift(const CustomizeTable* t) { return CUST_GET_FIELD(t, emcDvbShift); }

View File

@@ -12,9 +12,9 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
/* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -36,7 +36,7 @@
#include "process_management.h"
#include "clock_manager.h"
#include "ipc_service.h"
#define INNER_HEAP_SIZE 0x30000
#define INNER_HEAP_SIZE 0x40000
extern "C"
{
@@ -80,11 +80,11 @@ extern "C"
hosversionSet(MAKEHOSVERSION(fw.major, fw.minor, fw.micro));
setsysExit();
}
// rc = fanInitialize();
// if (R_FAILED(rc))
// diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen));
rc = i2cInitialize();
if (R_FAILED(rc))
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen));
@@ -96,7 +96,7 @@ extern "C"
// fanExit();
i2cExit();
fsExit();
fsdevUnmountAll();
fsdevUnmountAll();
}
}
@@ -154,6 +154,6 @@ int main(int argc, char** argv)
FileUtils::LogLine("Exit");
svcSleepThread(1000000ULL);
FileUtils::Exit();
return 0;
}

View File

@@ -21,20 +21,4 @@ cd ../../
cd Source/Horizon-OC-Monitor/
make -j"$(nproc)"
cp Horizon-OC-Monitor.ovl ../../dist/switch/.overlays/Horizon-OC-Monitor.ovl
cd ../../
ROOT="build"
PATCHES="Source/Atmosphere-Patches"
cp "$PATCHES/secmon_memory_layout.hpp" "$ROOT/libraries/libexosphere/include/exosphere/secmon/"
cp "$PATCHES/secmon_emc_access_table_data.inc" "$ROOT/exosphere/program/source/smc/"
cp "$PATCHES/secmon_define_emc_access_table.inc" "$ROOT/exosphere/program/source/smc/"
cp "$PATCHES/secmon_smc_register_access.cpp" "$ROOT/exosphere/program/source/smc/"
cd build/exosphere
make -j"$(nproc)"
cd out/nintendo_nx_arm64_armv8a/release
cp "exosphere.bin" "../../../../../dist/"
cp Horizon-OC-Monitor.ovl ../../dist/switch/.overlays/Horizon-OC-Monitor.ovl

Binary file not shown.

BIN
dist/exosphere.bin vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.