82 Commits

Author SHA1 Message Date
souldbminersmwc
4dd9bc0449 fix staring bug 2026-02-23 18:12:51 -05:00
souldbminersmwc
ced04a3060 fix ldr stuff 2026-02-23 16:42:24 -05:00
souldbminersmwc
605f87b078 fix stuff 2026-02-23 16:33:16 -05:00
souldbminersmwc
2e083b59a6 samy mode: reduce safety 2026-02-23 16:28:11 -05:00
souldbminersmwc
00f70e7c5e samymode2 2026-02-23 16:25:27 -05:00
souldbminersmwc
55e84d0051 sysclk: fix compile error 2026-02-23 15:08:06 -05:00
souldbminersmwc
8cd9727429 sysclk: fix clock capping bypass bug 2026-02-23 10:39:29 -05:00
Lightos1
660e839bed Extend emc unlock 2026-02-21 19:36:52 +01:00
Lightos1
afb16d2045 Remove lazy rl_dbi stuff 2026-02-21 15:34:38 +01:00
souldbminersmwc
f4b025f33c sysclk: remove display option on hoag and mark cpu governor as experemental 2026-02-20 19:27:04 -05:00
Souldbminer
e03c3b7be0 Update README.md 2026-02-20 17:04:40 -05:00
Lightos1
5a2ba5f785 Board: Fix no sched override 2026-02-20 19:12:51 +01:00
Lightos1
e1463dca05 Bump version 2026-02-20 16:55:34 +01:00
Lightos1
82972127a1 Boost mode: Cpu voltage bug workaround 2026-02-20 16:53:30 +01:00
Lightos1
272eaed351 UI reordering and text removal for smoother scrolling 2026-02-20 16:30:55 +01:00
Lightos1
989e67daac Overlay: Remove unsupported cpu max freq 2026-02-20 15:40:30 +01:00
Lightos1
dcec618ae9 Fix freqs not being set 2026-02-20 15:15:21 +01:00
Lightos1
bc12388b6d formating 2026-02-20 07:34:17 +01:00
Lightos1
6625488180 Formating 2026-02-20 07:33:51 +01:00
Lightos1
1209337af6 Erista: MRf and timing fixes 2026-02-20 07:32:10 +01:00
Souldbminer
0f608b1702 Revise GPU overclocking notes in README
Updated GPU overclocking notes for Erista and Mariko.
2026-02-19 19:59:57 -05:00
Souldbminer
cf547d517b Update testing contributors in README.md 2026-02-19 19:57:54 -05:00
Souldbminer
8c75c68dca Update LICENSE 2026-02-19 19:56:22 -05:00
souldbminersmwc
ab020c0a90 sysclk: code cleanup 2026-02-19 19:41:17 -05:00
souldbminersmwc
44dc402b54 sysclk: revise governor and change override logic 2026-02-19 18:54:21 -05:00
souldbminersmwc
a1d047f48d sysclk: remove atmosphere-libs 2026-02-19 16:36:20 -05:00
souldbminersmwc
cbed5e11ab sysclk: remove unnessesary code 2026-02-19 16:35:12 -05:00
souldbminersmwc
1ad3f6c441 sysclk: add GPU sched ini method 2026-02-19 16:33:55 -05:00
souldbminersmwc
820a26ba2a sysclk: add atmosphere-libs as submodule 2026-02-19 16:11:21 -05:00
souldbminersmwc
f0952119b6 sysclk: add CPU governor and more governor settings 2026-02-18 19:32:33 -05:00
souldbminersmwc
ca5ddbd779 sysclk: fix translation 2026-02-17 10:59:49 -05:00
souldbminersmwc
be49a27118 Update clock_manager.cpp 2026-02-16 18:41:59 -05:00
souldbminersmwc
190353dc11 sysclk: add on-the-fly CPU undervolt 2026-02-16 18:27:26 -05:00
souldbminersmwc
4a1772df77 sysclk: remove unused variable 2026-02-16 14:06:54 -05:00
souldbminersmwc
460d1b8471 sysclk: fix up refresh rate driver 2026-02-16 14:06:35 -05:00
souldbminersmwc
2493c798bc Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-02-15 17:44:48 -05:00
souldbminersmwc
7525baf567 sysclk: remove reversenx mode, some code cleanup, display upto 240hz, experemental settings config option, remove max display clock , bump version 2026-02-15 17:43:41 -05:00
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
Lightos1
aa72176196 Remove budget dvfs 2026-02-12 17:15:26 +01:00
Lightos1
7af0721847 DVFS: Safety check fix 2026-02-12 17:02:52 +01:00
Lightos1
2a6320e646 Bracket fix 2026-02-12 16:49:12 +01:00
Lightos1
fc212bb419 Bump version 2026-02-12 16:46:49 +01:00
Lightos1
14e0053335 DVFS: Add offset 2026-02-12 16:44:04 +01:00
Lightos1
8f28daceef DVFS: Add safety check 2026-02-12 16:12:36 +01:00
souldbminersmwc
f1044673d0 sysclk: modify dvfs logic 2026-02-11 19:28:43 -05:00
souldbminersmwc
61a0ebffee sysclk: fully fix dvfs 2026-02-11 19:22:25 -05:00
souldbminersmwc
8de8f4013e sysclk: fix dvfs config option 2026-02-11 19:11:02 -05:00
souldbminersmwc
dd447553d4 sysclk: make dvfs work 2026-02-11 19:09:55 -05:00
Lightos1
11c456e00c Fix random } 2026-02-11 17:42:10 +01:00
Lightos1
5efb4bdd6b Add hijack dvfs from sys-clk-eos 2026-02-11 16:57:26 +01:00
Lightos1
e331f1249b Why did this not commit? 2026-02-11 11:08:29 +01:00
Lightos1
786467d7ea add r2w fine tuning 2026-02-11 11:05:45 +01:00
Lightos1
496e77301b bump version 2026-02-11 01:06:52 +01:00
Lightos1
d657f1d156 Fix typo 2 2026-02-10 15:33:47 +01:00
Lightos1
7ab5c2f540 Fix typo 2026-02-10 15:33:03 +01:00
Lightos1
71900721cf Make AUTO_RAM default (for now) 2026-02-10 15:26:12 +01:00
74 changed files with 3562 additions and 2028 deletions

2
.gitmodules vendored
View File

@@ -6,4 +6,4 @@
url = https://github.com/ppkantorski/libultrahand
[submodule "Source/sys-clk/overlay/lib/libultrahand"]
path = Source/sys-clk/overlay/lib/libultrahand
url = https://github.com/ppkantorski/libultrahand
url = https://github.com/ppkantorski/libultrahand

View File

@@ -6,6 +6,8 @@
- Although "sys-clk" uses permissive license, all modifications towards it in this repo ("hoc-clk") are licensed under GPL v2.
- Status-Monitor is licensed under the GPLv2
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991

View File

@@ -56,7 +56,6 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
```
kip1=atmosphere/kips/hoc.kip
secmon=exosphere.bin
```
*(No changes needed if using fusee.)*
@@ -114,6 +113,9 @@ Refer to COMPILATION.md
* 816
* 714
* 612 → sleep mode
**Notes:**
1. On Erista, CPU in handheld is capped to 1581MHz
### GPU clocks
* 1536 → absolute max clock on mariko. very dangerous
@@ -140,8 +142,10 @@ Refer to COMPILATION.md
* 76 → boost mode
**Notes:**
1. GPU overclock is capped at 460MHz in handheld and capped at 768MHz if charging, unless you're using the official charger.
2. Clocks higher than 768MHz need the official charger is plugged in.
1. GPU overclock is capped at 460MHz on erista in handheld
2. On Mariko, cap with No uv is 614MHz, with SLT it is 691MHz and with HiOPT it's 768MHz
3. Clocks higher than 768MHz on erista need the official charger is plugged in.
4. On Mariko, cap with No uv is 844MHz, with SLT it is 921MHz and with HiOPT it's 998MHz
---
@@ -160,5 +164,5 @@ Refer to COMPILATION.md
* **b0rd2death** Ultrahand sys-clk & Status Monitor fork
* **MasaGratoR and ZachyCatGames** - General help
* **MasaGratoR** - Status Monitor & Display Refresh Rate Driver
* **Dom, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh and Xenshen** - Testing
* **Dom, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh, frost, letum00 and Xenshen** - Testing
* **Samybigio2011** - Italian translations

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

@@ -0,0 +1,25 @@
/*
* Copyright (c) Atmosphère-NX
*
* 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/>.
*/
#define __ACCESS_TABLE_NAME__ EmcAccessTable1
#define __ACCESS_TABLE_ADDRESS__ MemoryRegionPhysicalDeviceExternalMemoryController1.GetAddress()
#define __ACCESS_TABLE_INC__ "secmon_emc_access_table_data.inc"
#include "secmon_define_access_table.inc"
#undef __ACCESS_TABLE_INC__
#undef __ACCESS_TABLE_ADDRESS__
#undef __ACCESS_TABLE_NAME__

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) Atmosphère-NX
*
* 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/>.
*/
#define __ACCESS_TABLE_NAME__ EmcAccessTable2
#define __ACCESS_TABLE_ADDRESS__ MemoryRegionPhysicalDeviceExternalMemoryController2.GetAddress()
#define __ACCESS_TABLE_INC__ "secmon_emc_access_table_data.inc"
#include "secmon_define_access_table.inc"
#undef __ACCESS_TABLE_INC__
#undef __ACCESS_TABLE_ADDRESS__
#undef __ACCESS_TABLE_NAME__

View File

@@ -965,3 +965,76 @@ SetRegisterAllowed(0xECC);
SetRegisterAllowed(0xED0);
SetRegisterAllowed(0xED4);
SetRegisterAllowed(0xED8);
SetRegisterAllowed(0xEDC);
SetRegisterAllowed(0xEE0);
SetRegisterAllowed(0xEE4);
SetRegisterAllowed(0xEE8);
SetRegisterAllowed(0xEEC);
SetRegisterAllowed(0xEF0);
SetRegisterAllowed(0xEF4);
SetRegisterAllowed(0xEF8);
SetRegisterAllowed(0xEFC);
SetRegisterAllowed(0xF00);
SetRegisterAllowed(0xF04);
SetRegisterAllowed(0xF08);
SetRegisterAllowed(0xF0C);
SetRegisterAllowed(0xF10);
SetRegisterAllowed(0xF14);
SetRegisterAllowed(0xF18);
SetRegisterAllowed(0xF1C);
SetRegisterAllowed(0xF20);
SetRegisterAllowed(0xF24);
SetRegisterAllowed(0xF28);
SetRegisterAllowed(0xF2C);
SetRegisterAllowed(0xF30);
SetRegisterAllowed(0xF34);
SetRegisterAllowed(0xF38);
SetRegisterAllowed(0xF3C);
SetRegisterAllowed(0xF40);
SetRegisterAllowed(0xF44);
SetRegisterAllowed(0xF48);
SetRegisterAllowed(0xF4C);
SetRegisterAllowed(0xF50);
SetRegisterAllowed(0xF54);
SetRegisterAllowed(0xF58);
SetRegisterAllowed(0xF5C);
SetRegisterAllowed(0xF60);
SetRegisterAllowed(0xF64);
SetRegisterAllowed(0xF68);
SetRegisterAllowed(0xF6C);
SetRegisterAllowed(0xF70);
SetRegisterAllowed(0xF74);
SetRegisterAllowed(0xF78);
SetRegisterAllowed(0xF7C);
SetRegisterAllowed(0xF80);
SetRegisterAllowed(0xF84);
SetRegisterAllowed(0xF88);
SetRegisterAllowed(0xF8C);
SetRegisterAllowed(0xF90);
SetRegisterAllowed(0xF94);
SetRegisterAllowed(0xF98);
SetRegisterAllowed(0xF9C);
SetRegisterAllowed(0xFA0);
SetRegisterAllowed(0xFA4);
SetRegisterAllowed(0xFA8);
SetRegisterAllowed(0xFAC);
SetRegisterAllowed(0xFB0);
SetRegisterAllowed(0xFB4);
SetRegisterAllowed(0xFB8);
SetRegisterAllowed(0xFBC);
SetRegisterAllowed(0xFC0);
SetRegisterAllowed(0xFC4);
SetRegisterAllowed(0xFC8);
SetRegisterAllowed(0xFCC);
SetRegisterAllowed(0xFD0);
SetRegisterAllowed(0xFD4);
SetRegisterAllowed(0xFD8);
SetRegisterAllowed(0xFDC);
SetRegisterAllowed(0xFE0);
SetRegisterAllowed(0xFE4);
SetRegisterAllowed(0xFE8);
SetRegisterAllowed(0xFEC);
SetRegisterAllowed(0xFF0);
SetRegisterAllowed(0xFF4);
SetRegisterAllowed(0xFF8);
SetRegisterAllowed(0xFFC);

View File

@@ -123,39 +123,41 @@ namespace ams::secmon {
constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCode = MemoryRegion(UINT64_C(0x40020000), 0x20000);
static_assert(MemoryRegionPhysicalIram.Contains(MemoryRegionPhysicalIramBootCode));
constexpr inline const MemoryRegion MemoryRegionVirtualDevice = MemoryRegion(UINT64_C(0x1F0040000), UINT64_C(0x40000));
constexpr inline const MemoryRegion MemoryRegionVirtualDevice = MemoryRegion(UINT64_C(0x1F0040000), UINT64_C(0x40000 + 0x2000));
static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualDevice));
constexpr inline const MemoryRegion MemoryRegionVirtualDeviceEmpty = MemoryRegion(MemoryRegionVirtualDevice.GetStartAddress(), 0);
#define AMS_SECMON_FOREACH_DEVICE_REGION(HANDLER, ...) \
HANDLER(GicDistributor, Empty, UINT64_C(0x50041000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(GicCpuInterface, GicDistributor, UINT64_C(0x50042000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
HANDLER(Uart, GicCpuInterface, UINT64_C(0x70006000), UINT64_C(0x1000), false, ## __VA_ARGS__) \
HANDLER(ClkRst, Uart, UINT64_C(0x60006000), UINT64_C(0x1000), false, ## __VA_ARGS__) \
HANDLER(RtcPmc, ClkRst, UINT64_C(0x7000E000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Timer, RtcPmc, UINT64_C(0x60005000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(System, Timer, UINT64_C(0x6000C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(SecurityEngine, System, UINT64_C(0x70012000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
HANDLER(SecurityEngine2, SecurityEngine, UINT64_C(0x70412000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
HANDLER(SysCtr0, SecurityEngine2, UINT64_C(0x700F0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MemoryController, SysCtr0, UINT64_C(0x70019000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ExternalMemoryController, MemoryController, UINT64_C(0x7001b000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(FuseKFuse, ExternalMemoryController, UINT64_C(0x7000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ApbMisc, FuseKFuse, UINT64_C(0x70000000), UINT64_C(0x4000), true, ## __VA_ARGS__) \
HANDLER(FlowController, ApbMisc, UINT64_C(0x60007000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(BootloaderParams, FlowController, UINT64_C(0x40000000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(I2c5, BootloaderParams, UINT64_C(0x7000D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Gpio, I2c5, UINT64_C(0x6000D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(I2c1, Gpio, UINT64_C(0x7000C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ExceptionVectors, I2c1, UINT64_C(0x6000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MemoryController0, ExceptionVectors, UINT64_C(0x7001C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MemoryController1, MemoryController0, UINT64_C(0x7001D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Sdmmc, MemoryController1, UINT64_C(0x700B0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Disp1, Sdmmc, UINT64_C(0x54200000), UINT64_C(0x3000), true, ## __VA_ARGS__) \
HANDLER(Dsi, Disp1, UINT64_C(0x54300000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MipiCal, Dsi, UINT64_C(0x700E3000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Soctherm, MipiCal, UINT64_C(0x700E2000), UINT64_C(0x1000), true, ## __VA_ARGS__)
HANDLER(GicDistributor, Empty, UINT64_C(0x50041000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(GicCpuInterface, GicDistributor, UINT64_C(0x50042000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
HANDLER(Uart, GicCpuInterface, UINT64_C(0x70006000), UINT64_C(0x1000), false, ## __VA_ARGS__) \
HANDLER(ClkRst, Uart, UINT64_C(0x60006000), UINT64_C(0x1000), false, ## __VA_ARGS__) \
HANDLER(RtcPmc, ClkRst, UINT64_C(0x7000E000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Timer, RtcPmc, UINT64_C(0x60005000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(System, Timer, UINT64_C(0x6000C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(SecurityEngine, System, UINT64_C(0x70012000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
HANDLER(SecurityEngine2, SecurityEngine, UINT64_C(0x70412000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
HANDLER(SysCtr0, SecurityEngine2, UINT64_C(0x700F0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MemoryController, SysCtr0, UINT64_C(0x70019000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ExternalMemoryController, MemoryController, UINT64_C(0x7001b000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(FuseKFuse, ExternalMemoryController, UINT64_C(0x7000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ApbMisc, FuseKFuse, UINT64_C(0x70000000), UINT64_C(0x4000), true, ## __VA_ARGS__) \
HANDLER(FlowController, ApbMisc, UINT64_C(0x60007000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(BootloaderParams, FlowController, UINT64_C(0x40000000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(I2c5, BootloaderParams, UINT64_C(0x7000D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Gpio, I2c5, UINT64_C(0x6000D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(I2c1, Gpio, UINT64_C(0x7000C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ExceptionVectors, I2c1, UINT64_C(0x6000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MemoryController0, ExceptionVectors, UINT64_C(0x7001C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MemoryController1, MemoryController0, UINT64_C(0x7001D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Sdmmc, MemoryController1, UINT64_C(0x700B0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Disp1, Sdmmc, UINT64_C(0x54200000), UINT64_C(0x3000), true, ## __VA_ARGS__) \
HANDLER(Dsi, Disp1, UINT64_C(0x54300000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(MipiCal, Dsi, UINT64_C(0x700E3000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(Soctherm, MipiCal, UINT64_C(0x700E2000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ExternalMemoryController1, Soctherm, UINT64_C(0x7001e000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
HANDLER(ExternalMemoryController2, ExternalMemoryController1, UINT64_C(0x7001f000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
#define DEFINE_DEVICE_REGION(_NAME_, _PREV_, _ADDRESS_, _SIZE_, _SECURE_) \
constexpr inline const MemoryRegion MemoryRegionVirtualDevice##_NAME_ = MemoryRegion(MemoryRegionVirtualDevice##_PREV_.GetEndAddress() + 0x1000, _SIZE_); \

View File

@@ -99,6 +99,8 @@ namespace ams::secmon::smc {
#include "secmon_define_pmc_access_table.inc"
#include "secmon_define_mc_access_table.inc"
#include "secmon_define_emc_access_table.inc"
#include "secmon_define_emc1_access_table.inc"
#include "secmon_define_emc2_access_table.inc"
#include "secmon_define_soctherm_access_table.inc"
#include "secmon_define_mc01_access_table.inc"
@@ -106,6 +108,8 @@ namespace ams::secmon::smc {
{ PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, },
{ McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, },
{ EmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController.GetAddress(), EmcAccessTable::Address, EmcAccessTable::Size, },
{ EmcAccessTable1::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController1.GetAddress(), EmcAccessTable1::Address, EmcAccessTable1::Size, },
{ EmcAccessTable2::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController2.GetAddress(), EmcAccessTable2::Address, EmcAccessTable2::Size, },
{ SocthermAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceSoctherm.GetAddress(), SocthermAccessTable::Address, SocthermAccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },

View File

@@ -22,12 +22,11 @@
/* Never edit these. */
#define AUTO 0
#define AUTO_RAM 0
#define ENABLED 1
#define DISABLED 0
#define DEACTIVATED_GPU_FREQ 2000
#define GPU_MIN_MIN_VOLT 480000
#define CPU_MAX_MAX_VOLT 1235000
#define CPU_MAX_MAX_VOLT 1395000
namespace ams::ldr::hoc {
@@ -37,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 */
@@ -121,32 +122,28 @@ volatile CustomizeTable C = {
.eristaGpuVoltArray = {
AUTO /* 76 */,
AUTO /* 115 */,
AUTO /* 153 */,
AUTO /* 192 */,
AUTO /* 230 */,
AUTO /* 269 */,
AUTO /* 307 */,
AUTO /* 346 */,
AUTO /* 384 */,
AUTO /* 422 */,
AUTO /* 460 */,
AUTO /* 499 */,
AUTO /* 537 */,
AUTO /* 576 */,
AUTO /* 614 */,
AUTO /* 652 */,
AUTO /* 691 */,
AUTO /* 729 */,
AUTO /* 768 */,
AUTO /* 806 */,
AUTO /* 844 */,
AUTO /* 883 */,
AUTO /* 921 */,
DEACTIVATED_GPU_FREQ /* 960 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 998 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1036 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1075 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1152 (SLT / HiOPT Only!) */,
DEACTIVATED_GPU_FREQ /* 1228 (HiOPT Only!) */,
DEACTIVATED_GPU_FREQ /* 1305 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1344 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1382 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1420 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1459 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1497 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1536 (Disabled by default) */,
},
.marikoGpuVoltArray = {
@@ -166,7 +163,6 @@ volatile CustomizeTable C = {
AUTO /* 1075 */,
AUTO /* 1152 (SLT / HiOPT Only!) */,
AUTO /* 1228 (HiOPT Only!) */,
DEACTIVATED_GPU_FREQ /* 1267 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1305 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1344 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1382 (Disabled by default) */,
@@ -174,8 +170,18 @@ volatile CustomizeTable C = {
DEACTIVATED_GPU_FREQ /* 1459 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1497 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1536 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1574 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1612 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1651 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1689 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1728 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1766 (Disabled by default) */,
DEACTIVATED_GPU_FREQ /* 1804 (Disabled by default) */,
},
/* Advanced. */
.fineTune_t6_tRTW = 0,
.fineTune_t7_tWTR = 0,
/* You shouldn't have to anything past here. */
@@ -196,9 +202,9 @@ volatile CustomizeTable C = {
{ 1581000, { 1130000, }, { 2889664, -122173, 1834, } },
{ 1683000, { 1168000, }, { 5100873, -279186, 4747, } },
{ 1785000, { 1225000, }, { 5100873, -279186, 4747, } },
// { 1887000, { 1225000, }, { 5100873, -279186, 4747, } },
// { 1989000, { 1227500, }, { 5100873, -279186, 4747, } },
// { 2091000, { 1256250, }, { 5100873, -279186, 4747, } },
{ 1887000, { 1225000, }, { 5100873, -279186, 4747, } },
{ 1989000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2091000, { 1256250, }, { 5100873, -279186, 4747, } },
},
.eristaCpuDvfsTableSLT = {
@@ -220,9 +226,13 @@ volatile CustomizeTable C = {
{ 1785000, { 1225000, }, { 5100873, -279186, 4747, } },
{ 1887000, { 1225000, }, { 5100873, -279186, 4747, } },
{ 1989000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2091000, { 1256250, }, { 5100873, -279186, 4747, } },
{ 2193000, { 1256250, }, { 5100873, -279186, 4747, } },
{ 2295000, { 1256250, }, { 5100873, -279186, 4747, } },
{ 2091000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2193000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2295000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2397000, { 1395000, }, { 5100873, -279186, 4747, } },
{ 2499000, { 1395000, }, { 6000000, -179186, 4747, } },
{ 2601000, { 1395000, }, { 6000000, -179186, 4747, } },
{ 2703000, { 1395000, }, { 6000000, -179186, 4747, } },
},
.marikoCpuDvfsTable = {
@@ -244,17 +254,13 @@ volatile CustomizeTable C = {
{ 1785000, { 1527196, -36015, 27, }, { 1120000, } },
{ 1887000, { 1609246, -37515, 27, }, { 1120000, } },
{ 1963500, { 1675751, -38635, 27, }, { 1120000, } },
// { 2091000, { 1716501, -39395, 27, }, { CPU_MAX_MAX_VOLT, } },
// { 2193000, { 1775132, -40505, 27, }, { CPU_MAX_MAX_VOLT, } },
// { 2295000, { 1866287, -42005, 27, }, { CPU_MAX_MAX_VOLT, } },
// { 2397000, { 1961107, -43506, 27, }, { CPU_MAX_MAX_VOLT, } },
{ 2091000, { 1716501, -39395, 27, }, { CPU_MAX_MAX_VOLT, } },
{ 2193000, { 1775132, -40505, 27, }, { CPU_MAX_MAX_VOLT, } },
{ 2295000, { 1866287, -42005, 27, }, { CPU_MAX_MAX_VOLT, } },
{ 2397000, { 1961107, -43506, 27, }, { CPU_MAX_MAX_VOLT, } },
},
.marikoCpuDvfsTableSLT = {
{ 204000, { 732856, -17335, 113, }, { } },
{ 306000, { 760024, -18195, 113, }, { } },
{ 408000, { 789258, -19055, 113, }, { } },
{ 510000, { 789258, -19055, 113, }, { } },
{ 612000, { 789258, -19055, 113, }, { } },
{ 714000, { 789258, -19055, 113, }, { } },
{ 816000, { 789258, -19055, 113, }, { } },
@@ -276,13 +282,12 @@ volatile CustomizeTable C = {
{ 2499000, { 1580725, -35815, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2601000, { 1702903, -36675, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2703000, { 1770375, -37515, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2805000, { 1908891, -37707, 113 }, { CPU_MAX_MAX_VOLT, } },
{ 2907000, { 1960388, -38395, 113 }, { CPU_MAX_MAX_VOLT ,} },
{ 3009000, { 2011885, -39083, 113 }, { CPU_MAX_MAX_VOLT ,} },
},
.marikoCpuDvfsTable1581Tbreak {
{ 204000, { 732856, -17335, 113, }, { } },
{ 306000, { 760024, -18195, 113, }, { } },
{ 408000, { 789258, -19055, 113, }, { } },
{ 510000, { 789258, -19055, 113, }, { } },
{ 612000, { 853926, -20775, 113, }, { } },
{ 714000, { 889361, -21625, 113, }, { } },
{ 816000, { 926862, -22485, 113, }, { } },
@@ -304,13 +309,12 @@ volatile CustomizeTable C = {
{ 2499000, { 1736856, -35286, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2601000, { 1787838, -35967, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2703000, { 1838820, -36648, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2805000, { 1908891, -37707, 113 }, { CPU_MAX_MAX_VOLT, } },
{ 2907000, { 1960388, -38395, 113 }, { CPU_MAX_MAX_VOLT ,} },
{ 3009000, { 2011885, -39083, 113 }, { CPU_MAX_MAX_VOLT ,} },
},
.marikoCpuDvfsTable1683Tbreak {
{ 204000, { 732856, -17335, 113, }, { } },
{ 306000, { 760024, -18195, 113, }, { } },
{ 408000, { 789258, -19055, 113, }, { } },
{ 510000, { 789258, -19055, 113, }, { } },
{ 612000, { 853926, -20775, 113, }, { } },
{ 714000, { 889361, -21625, 113, }, { } },
{ 816000, { 926862, -22485, 113, }, { } },
@@ -332,13 +336,12 @@ volatile CustomizeTable C = {
{ 2499000, { 1736856, -35286, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2601000, { 1787838, -35967, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2703000, { 1838820, -36648, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2805000, { 1908891, -37707, 113 }, { CPU_MAX_MAX_VOLT, } },
{ 2907000, { 1960388, -38395, 113 }, { CPU_MAX_MAX_VOLT ,} },
{ 3009000, { 2011885, -39083, 113 }, { CPU_MAX_MAX_VOLT ,} },
},
.marikoCpuDvfsTableExtreme {
{ 204000, { 732856, -17335, 113, }, { } },
{ 306000, { 760024, -18195, 113, }, { } },
{ 408000, { 789258, -19055, 113, }, { } },
{ 510000, { 789258, -19915, 113, }, { } },
{ 612000, { 789258, -19055, 113, }, { } },
{ 714000, { 820558, -19915, 113, }, { } },
{ 816000, { 853926, -20775, 113, }, { } },
@@ -360,91 +363,66 @@ volatile CustomizeTable C = {
{ 2499000, { 1580725, -35815, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2601000, { 1702903, -36675, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2703000, { 1775375, -37515, 113, }, { CPU_MAX_MAX_VOLT, } },
{ 2805000, { 1908891, -37707, 113 }, { CPU_MAX_MAX_VOLT, } },
{ 2907000, { 1960388, -38395, 113 }, { CPU_MAX_MAX_VOLT ,} },
{ 3009000, { 2011885, -39083, 113 }, { CPU_MAX_MAX_VOLT ,} },
},
.eristaGpuDvfsTable = {
{ 76800, { }, { 814294, 8144, -940, 808, -21583, 226, } },
{ 115200, { }, { 856185, 8144, -940, 808, -21583, 226, } },
{ 153600, { }, { 856185, 8144, -940, 808, -21583, 226, } },
{ 192000, { }, { 898077, 8144, -940, 808, -21583, 226, } },
{ 230400, { }, { 898077, 8144, -940, 808, -21583, 226, } },
{ 268800, { }, { 939968, 8144, -940, 808, -21583, 226, } },
{ 307200, { }, { 939968, 8144, -940, 808, -21583, 226, } },
{ 345600, { }, { 981860, 8144, -940, 808, -21583, 226, } },
{ 384000, { }, { 981860, 8144, -940, 808, -21583, 226, } },
{ 422400, { }, { 1023751, 8144, -940, 808, -21583, 226, } },
{ 460800, { }, { 1023751, 8144, -940, 808, -21583, 226, } },
{ 499200, { }, { 1065642, 8144, -940, 808, -21583, 226, } },
{ 537600, { }, { 1065642, 8144, -940, 808, -21583, 226, } },
{ 576000, { }, { 1107534, 8144, -940, 808, -21583, 226, } },
{ 614400, { }, { 1107534, 8144, -940, 808, -21583, 226, } },
{ 652800, { }, { 1149425, 8144, -940, 808, -21583, 226, } },
{ 691200, { }, { 1149425, 8144, -940, 808, -21583, 226, } },
{ 729600, { }, { 1191317, 8144, -940, 808, -21583, 226, } },
{ 768000, { }, { 1191317, 8144, -940, 808, -21583, 226, } },
{ 806400, { }, { 1233208, 8144, -940, 808, -21583, 226, } },
{ 844800, { }, { 1233208, 8144, -940, 808, -21583, 226, } },
{ 883200, { }, { 1275100, 8144, -940, 808, -21583, 226, } },
{ 921600, { }, { 1275100, 8144, -940, 808, -21583, 226, } },
// { 998400, { }, { 1316991, 8144, -940, 808, -21583, 226, } },
},
.eristaGpuDvfsTableSLT = {
{ 76800, { }, { 814294, 8144, -940, 0, 0, 226, } },
{ 115200, { }, { 856185, 8144, -940, 0, 0, 226, } },
{ 153600, { }, { 856185, 8144, -940, 0, 0, 226, } },
{ 192000, { }, { 908077, 8144, -940, 0, 0, 226, } },
{ 230400, { }, { 908077, 8144, -940, 0, 0, 226, } },
{ 268800, { }, { 934968, 8144, -940, 0, 0, 226, } },
{ 307200, { }, { 934968, 8144, -940, 0, 0, 226, } },
{ 345600, { }, { 952860, 8144, -940, 0, 0, 226, } },
{ 384000, { }, { 952860, 8144, -940, 0, 0, 226, } },
{ 422400, { }, { 978751, 8144, -940, 0, 0, 226, } },
{ 460800, { }, { 978751, 8144, -940, 0, 0, 226, } },
{ 499200, { }, { 990642, 8144, -940, 0, 0, 226, } },
{ 537600, { }, { 990642, 8144, -940, 0, 0, 226, } },
{ 576000, { }, { 1017534, 8144, -940, 0, 0, 226, } },
{ 614400, { }, { 1017534, 8144, -940, 0, 0, 226, } },
{ 652800, { }, { 1042425, 8144, -940, 0, 0, 226, } },
{ 691200, { }, { 1042425, 8144, -940, 0, 0, 226, } },
{ 729600, { }, { 1066317, 8144, -940, 0, 0, 226, } },
{ 768000, { }, { 1066317, 8144, -940, 0, 0, 226, } },
{ 806400, { }, { 1093208, 8144, -940, 0, 0, 226, } },
{ 844800, { }, { 1093208, 8144, -940, 0, 0, 226, } },
{ 883200, { }, { 1118100, 8144, -940, 0, 0, 226, } },
{ 921600, { }, { 1118100, 8144, -940, 0, 0, 226, } },
{ 960000, { }, { 1156991, 8144, -940, 0, 0, 226, } },
},
.eristaGpuDvfsTableHiOPT = {
{ 76800, { }, { 814294, 8144, -940, 0, 0, 226, } },
{ 115200, { }, { 856185, 8144, -940, 0, 0, 226, } },
{ 153600, { }, { 856185, 8144, -940, 0, 0, 226, } },
{ 192000, { }, { 908077, 8144, -940, 0, 0, 226, } },
{ 230400, { }, { 908077, 8144, -940, 0, 0, 226, } },
{ 268800, { }, { 934968, 8144, -940, 0, 0, 226, } },
{ 307200, { }, { 934968, 8144, -940, 0, 0, 226, } },
{ 345600, { }, { 952860, 8144, -940, 0, 0, 226, } },
{ 384000, { }, { 952860, 8144, -940, 0, 0, 226, } },
{ 422400, { }, { 978751, 8144, -940, 0, 0, 226, } },
{ 460800, { }, { 978751, 8144, -940, 0, 0, 226, } },
{ 499200, { }, { 990642, 8144, -940, 0, 0, 226, } },
{ 537600, { }, { 990642, 8144, -940, 0, 0, 226, } },
{ 576000, { }, { 1017534, 8144, -940, 0, 0, 226, } },
{ 614400, { }, { 1017534, 8144, -940, 0, 0, 226, } },
{ 652800, { }, { 1042425, 8144, -940, 0, 0, 226, } },
{ 691200, { }, { 1042425, 8144, -940, 0, 0, 226, } },
{ 729600, { }, { 1066317, 8144, -940, 0, 0, 226, } },
{ 768000, { }, { 1066317, 8144, -940, 0, 0, 226, } },
{ 806400, { }, { 1093208, 8144, -940, 0, 0, 226, } },
{ 844800, { }, { 1093208, 8144, -940, 0, 0, 226, } },
{ 883200, { }, { 1118100, 8144, -940, 0, 0, 226, } },
{ 921600, { }, { 1118100, 8144, -940, 0, 0, 226, } },
{ 960000, { }, { 1156991, 8144, -940, 0, 0, 226, } },
{ 998400, { }, { 1156991, 8144, -940, 0, 0, 226, } },
{ 1036800, { }, { } },
{ 1075200, { }, { } },
// { 1152000, { }, { } },
{ 1152000, { }, { } },
{ 1228800, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1267200, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1344000, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1382400, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1420800, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1459200, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1497600, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1536000, { }, { 0, 0, 0, 0, 0, 0 } },
},
.marikoGpuDvfsTable = {
@@ -463,8 +441,8 @@ volatile CustomizeTable C = {
{ 998400, { }, { 1065665,-16075, -497,-179, 3213, 9 } },
{ 1075200, { }, { 1132576,-16093, -648, 0, 1077, 40 } },
{ 1152000, { }, { 1180029,-14534, -830, 0, 1469, 110 } },
// { 1228800, { }, { 1248293,-16383, -859, 0, 3722, 313 } },
// { 1267200, { }, { 1286399,-17475, -867, 0, 3681, 559 } },
{ 1228800, { }, { 1248293,-16383, -859, 0, 3722, 313 } },
{ 1267200, { }, { 1286399,-17475, -867, 0, 3681, 559 } },
},
.marikoGpuDvfsTableSLT = {
@@ -484,7 +462,7 @@ volatile CustomizeTable C = {
{ 1075200, { }, { 1132576, -16093, -648, 0, 1077, 40 } },
{ 1152000, { }, { 1180029, -14534, -830, 0, 1469, 110 } },
{ 1228800, { }, { 1238293, -16383, -859, 0, 3722, 313 } },
// { 1267200, { }, { 1276399, -17475, -867, 0, 3681, 559 } },
{ 1267200, { }, { 1276399, -17475, -867, 0, 3681, 559 } },
},
.marikoGpuDvfsTableHiOPT = {
@@ -512,6 +490,13 @@ volatile CustomizeTable C = {
{ 1459200, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1497600, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1536000, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1574400, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1612800, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1651200, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1689600, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1728000, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1766400, { }, { 0, 0, 0, 0, 0, 0 } },
{ 1804800, { }, { 0, 0, 0, 0, 0, 0 } },
},
};

View File

@@ -80,6 +80,8 @@ typedef struct CustomizeTable {
u32 commonEmcMemVolt;
u32 eristaEmcMaxClock;
u32 eristaEmcMaxClock1;
u32 eristaEmcMaxClock2;
u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt;
u32 emcDvbShift;
@@ -123,9 +125,10 @@ typedef struct CustomizeTable {
u32 gpuSpeedo;
u32 eristaGpuVoltArray[27];
u32 marikoGpuVoltArray[24];
u32 eristaGpuVoltArray[24];
u32 marikoGpuVoltArray[31];
u32 fineTune_t6_tRTW;
u32 fineTune_t7_tWTR;
u32 reserved[60];

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 - (C.t6_tRTW * 3) + finetRTW;
tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (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)), 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

@@ -43,7 +43,7 @@ namespace ams::ldr::hoc::pcv::mariko {
u32 wlIndex = 0;
for (u32 i = 0; i < std::size(rlMapDBI); ++i) {
if (rlMapDBI[i] == RL_DBI) {
if (rlMapDBI[i] == RL) {
rlIndex = i;
break;
}

View File

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

View File

@@ -30,25 +30,13 @@ 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;
/* Base latency for read and write (tWRL). */
const u32 RL = C.mem_burst_read_latency - 4; /* (This is a lazy fix for now) */
const u32 RL = C.mem_burst_read_latency;
const u32 WL = C.mem_burst_write_latency;
/* Switch uses RL_DBI, todo: get rid of non DBI_RL. */
const u32 RL_DBI = RL + 4;
/* Precharge to Precharge Delay. (tCK) */
const u32 tPPD = 4;
@@ -75,56 +63,14 @@ 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 u32 tRCD = tRCD_values[C.t1_tRCD];
const u32 tRPpb = tRP_values[C.t2_tRP];
const u32 tRAS = tRAS_values[C.t3_tRAS];
const double tRRD = tRRD_values[C.t4_tRRD];
const u32 tRFCpb = tRFC_values[C.t5_tRFC];
const u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
const u32 tRC = tRAS + tRPpb;
const u32 tRFCab = tRFCpb * 2;
const double tXSR = (double) (tRFCab + 7.5);
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
const double tRPab = tRPpb + 3;
const u32 tR2P = 12;
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));
const u32 wdv = WL;
const u32 wsv = WL - 2;
const u32 wev = 0xA + (WL - 14);
const double freq_mhz = C.eristaEmcMaxClock / 1000.0;
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);
}
namespace pcv::mariko {
const double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock;
const double ramFreqMhz = C.marikoEmcMaxClock / 1000.0;
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, 6> tRFC_values = { 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];
@@ -132,6 +78,7 @@ namespace ams::ldr::hoc {
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 s32 finetRTW = C.fineTune_t6_tRTW;
const s32 finetWTR = C.fineTune_t7_tWTR;
const u32 tRC = tRAS + tRPpb;
@@ -140,16 +87,57 @@ namespace ams::ldr::hoc {
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
const double tRPab = tRPpb + 3;
const u32 tR2P = CEIL((RL_DBI * 0.426) - 2.0);
const u32 tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL_DBI - (C.t6_tRTW * 3);
const u32 tRTM = FLOOR((10.0 + RL_DBI) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg);
const u32 tRATM = CEIL((tRTM - 10.0) + (RL_DBI * 0.426));
const u32 tR2P = CEIL((RL * 0.426) - 2.0);
inline u32 tR2W;
inline u32 rext;
const u32 rdv = RL_DBI + FLOOR((5.105 / tCK_avg) + 17.017);
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
inline u32 tWTPDEN;
inline u32 tW2R;
inline u32 pdex2rw;
inline u32 tCLKSTOP;
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 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 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 = static_cast<double>(tRFCab + 7.5);
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
const double tRPab = tRPpb + 3;
const u32 tR2P = CEIL((RL * 0.426) - 2.0);
const u32 tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW;
const u32 tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg);
const u32 tRATM = CEIL((tRTM - 10.0) + (RL * 0.426));
inline u32 rext;
const u32 rdv = RL + FLOOR((5.105 / tCK_avg) + 17.017);
const u32 qpop = rdv - 14;
const u32 quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782);
const u32 quse = FLOOR(RL_DBI + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg);
const u32 quse = FLOOR(RL + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg);
const u32 einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width;
const u32 einput = quse - CEIL(9.928 / tCK_avg);
const u32 qrst_duration = FLOOR(8.399 - tCK_avg);
@@ -158,8 +146,8 @@ namespace ams::ldr::hoc {
const u32 ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
const u32 qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
const u32 tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL_DBI + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
const u32 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;
const u32 tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
const u32 tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
const u32 tWTM = CEIL(WL + ((7.570 / tCK_avg) + 8.753));
const u32 tWATM = (tWTM + (FLOOR(WL / 0.816) * 2.0)) - 4.0;
@@ -169,7 +157,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)));
@@ -184,3 +171,4 @@ namespace ams::ldr::hoc {
}

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.eristaCpuBoostClock, 1020'000, 3009'000, true },
{ C.marikoCpuBoostClock, 1020'000, 3009'000, true },
{ C.commonEmcMemVolt, 912'500, 1500'000 }, // Official burst vmax for the RAMs is 1500mV
{ C.eristaCpuMaxVolt, 1000, 1500 },
{ GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2700'000 },
{ C.marikoCpuMaxVolt, 1000, 1500 },
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
{ C.marikoEmcVddqVolt, 250'000, 1500'000 },
{ eristaCpuDvfsMaxFreq, 1785'000, 3009'000 },
{ marikoCpuDvfsMaxFreq, 1785'000, 3009'000 },
{ eristaGpuDvfsMaxFreq, 768'000, 1536'000 },
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000 },
};
for (auto& i : validators) {

View File

@@ -58,7 +58,7 @@ namespace ams::ldr::hoc::pcv {
static const u32 cpuVoltThermalData[] = { 620, 1120, 20000, 620, 1120, 70000, 950, 1132, 0, 950, 1227, 0 };
static const u32 allowedCpuMaxFrequencies[] = { 1'963'000, 2'091'000, 2'193'000, 2'295'000, 2'397'000, 2'499'000, 2'601'000, 2'703'000, };
static const u32 allowedCpuMaxFrequencies[] = { 1'963'000, 2'091'000, 2'193'000, 2'295'000, 2'397'000, 2'499'000, 2'601'000, 2'703'000, 2'805'000, 2'907'000, 3'009'000, };
constexpr cvb_entry_t GpuCvbTableDefault[] = {
// GPUB01_NA_CVB_TABLE
@@ -122,16 +122,6 @@ namespace ams::ldr::hoc::pcv {
{0xFFFFFFFF, 35},
};
static const u32 ramBrackets[][22] = {
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, },
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, },
{ 2433, 2466, 2533, 2600, 2666, 2733, 2766, 2800, 2833, 2866, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3300, 3333, 3366, },
{ 2500, 2533, 2600, 2633, 2666, 2733, 2800, 2866, 2900, 2966, 3033, 3100, 3166, 3200, 3233, 3266, 3300, 3333, 3366, 3400, 3400, 3400, },
};
static const u32 gpuBudgetDvfsArray[] = { 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800};
/* GPU Max Clock asm Pattern:
*
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
@@ -188,6 +178,9 @@ namespace ams::ldr::hoc::pcv {
}
namespace erista {
static u32 maxEmcClocks[] = { 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}, { } },
@@ -209,21 +202,25 @@ namespace ams::ldr::hoc::pcv {
{ },
};
constexpr u32 CpuVoltOfficial = 1235;
constexpr u32 CpuVminOfficial = 825;
constexpr u32 CpuVoltL4T = 1235'000;
constexpr u16 CpuMinVolts[] = { 950, 850, 825, 810 };
inline bool CpuMaxVoltPatternFn(u32* ptr32) {
u32 val = *ptr32;
return (val == 1132 || val == 1170 || val == 1227);
}
static const u32 cpuVoltDvfsPattern[] = { 1227, 1000, 100, 1000, 0 };
static const u32 cpuVoltDvfsOffsets[] = { 5, 6, 7, 8, 9 };
static_assert(sizeof(cpuVoltDvfsPattern) == sizeof(cpuVoltDvfsOffsets), "Invalid cpuVoltDvfsPattern");
static const u32 cpuVoltageThermalPattern[] = { 950, 1132, 0, 950, 1227, 0, 825, 1227, 15000, 825, 1170, 60000, 825, 1132, 80000 };
static_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "invalid cpuVoltageThermalPattern size");
constexpr u32 GpuClkPllLimit = 921'600'000;
constexpr u32 GpuClkPllLimit = 2'600'000;
constexpr u32 GpuClkPllMax = 921'600'000;
constexpr u32 GpuVminOfficial = 810;
static const u32 gpuVoltDvfsPattern[] = { 810, 1150, 1000, 100, 1000, 10, };

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 {
@@ -166,339 +167,19 @@ namespace ams::ldr::hoc::pcv::erista {
R_SUCCEED();
}
Result GpuFreqPllLimit(u32 *ptr) {
clk_pll_param *entry = reinterpret_cast<clk_pll_param *>(ptr);
// All zero except for freq
for (size_t i = 1; i < sizeof(clk_pll_param) / sizeof(u32); i++) {
R_UNLESS(*(ptr + i) == 0, ldr::ResultInvalidGpuPllEntry());
}
// Double the max clk simply
u32 max_clk = entry->freq * 2;
entry->freq = max_clk;
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 +196,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 +222,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 +238,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;
/* 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,57 +310,58 @@ 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 = MIN(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 = MIN(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 = MIN(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) {
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) {
R_SKIP();
}
u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800};
std::sort(maxEmcClocks, maxEmcClocks + std::size(maxEmcClocks), std::greater<>());
u32 khz_list_size = sizeof(khz_list) / sizeof(u32);
// Generate list for mtc table pointers
@@ -655,25 +373,77 @@ namespace ams::ldr::hoc::pcv::erista {
R_UNLESS(table_list[i]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
}
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
R_SKIP();
u32 additionalFreqs = 0;
for (u32 i = 0; i < std::size(maxEmcClocks); ++i) {
if (maxEmcClocks[i] > EmcClkOSLimit) {
++additionalFreqs;
} else {
break;
}
}
// 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 204000, ..., 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 > additionalFreqs - 1; --i) {
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - additionalFreqs]), sizeof(EristaMtcTable));
}
MemMtcTableAutoAdjust(table_list[0]);
for (u32 i = 0; i < additionalFreqs; ++i) {
/* Since we're not scaling latency timings properly, copy over the 1600Mhz table to get the closest timings. */
std::memcpy(table_list[i], table_list[additionalFreqs], sizeof(EristaMtcTable));
table_list[i]->rate_khz = maxEmcClocks[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(maxEmcClocks) <= EmcClkOSLimit) {
R_SKIP();
}
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxEmcClocks));
R_SUCCEED();
}
Result CpuVoltRange(u32* ptr) {
u32 min_volt_got = *(ptr - 1);
for (const auto& mv : CpuMinVolts) {
if (min_volt_got != mv)
continue;
if (!C.eristaCpuMaxVolt)
R_SKIP();
PATCH_OFFSET(ptr, C.eristaCpuMaxVolt);
R_SUCCEED();
}
R_THROW(ldr::ResultInvalidCpuMinVolt());
}
Result GpuFreqPllMax(u32 *ptr) {
clk_pll_param *entry = reinterpret_cast<clk_pll_param *>(ptr);
// All zero except for freq
for (size_t i = 1; i < sizeof(clk_pll_param) / sizeof(u32); i++) {
R_UNLESS(*(ptr + i) == 0, ldr::ResultInvalidGpuPllEntry());
}
// Double the max clk simply
u32 max_clk = entry->freq * 2;
entry->freq = max_clk;
R_SUCCEED();
}
Result GpuFreqPllLimit(u32 *ptr) {
u32 prev_freq = *(ptr - 1);
if (prev_freq != 128000 && prev_freq != 1300000 && prev_freq != 76800) {
R_THROW(ldr::ResultInvalidGpuPllEntry());
}
PATCH_OFFSET(ptr, 3600000);
R_SUCCEED();
}
@@ -682,13 +452,15 @@ namespace ams::ldr::hoc::pcv::erista {
PatcherEntry<u32> patches[] = {
{"CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, static_cast<u32>(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq)},
{"CPU Volt DVFS", &CpuVoltDvfs, 1, nullptr, 825},
{"CPU Volt Limit", &CpuVoltRange, 0, &CpuMaxVoltPatternFn},
{"CPU Volt Thermals", &CpuVoltThermals, 1, nullptr, 825},
{"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFEAD0FF},
{"GPU Volt DVFS", &GpuVoltDVFS, 1, nullptr, 810},
{"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, 810},
{"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq)},
{"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn},
{"GPU Freq PLL", &GpuFreqPllLimit, 1, nullptr, GpuClkPllLimit},
{"GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax},
{"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit},
{"MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit},
{"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit},
{"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit},
@@ -711,4 +483,5 @@ namespace ams::ldr::hoc::pcv::erista {
}
}
}
}

View File

@@ -50,30 +50,6 @@ namespace ams::ldr::hoc::pcv::mariko {
return ramScale;
}
u32 GetSpeedoBracket() {
u32 speedoBracket = 3;
if ((C.gpuSpeedo < 1754) && (speedoBracket = 2, C.gpuSpeedo < 1690)) {
speedoBracket = !!(1625 < C.gpuSpeedo);
}
return speedoBracket;
}
u32 GetGpuBudgetDvfsVoltage() {
u32 bracket = GetSpeedoBracket();
if (ramFreqMhz <= 1600)
return 0;
for (u32 voltageIndex = 0; voltageIndex < 22; voltageIndex++) {
if (ramFreqMhz <= ramBrackets[bracket][voltageIndex]) {
return gpuBudgetDvfsArray[voltageIndex];
}
}
return 800;
}
/* Note: EOS (probably?) has a bug in this function that always results in high vmin, this is fixed here. */
u32 GetAutoVoltage() {
u32 voltage = GetGpuVminVoltage();
@@ -102,14 +78,13 @@ namespace ams::ldr::hoc::pcv::mariko {
}
/* C.marikoGpuVmin is non zero, user sets manual voltage. */
if (C.marikoGpuVmin != 0 && C.marikoGpuVmin != 1) {
if (C.marikoGpuVmin) {
PATCH_OFFSET(ptr, C.marikoGpuVmin);
R_SUCCEED();
}
/* C.marikoGpuVmin is zero OR one, auto voltage is applied. */
/* Get vmin depending on speedo and ram clock. */
u32 autoVmin = C.marikoGpuVmin == 0 ? GetAutoVoltage() : GetGpuBudgetDvfsVoltage();
/* C.marikoGpuVmin is zero, auto voltage is applied. */
u32 autoVmin = GetAutoVoltage();
PATCH_OFFSET(ptr, autoVmin);
R_SUCCEED();
}
@@ -122,8 +97,8 @@ namespace ams::ldr::hoc::pcv::mariko {
u32 vmin = C.marikoGpuVmin;
/* Automatic voltage. */
if (!C.marikoGpuVmin || C.marikoGpuVmin == 1) {
vmin = C.marikoGpuVmin == 0 ? GetAutoVoltage() : GetGpuBudgetDvfsVoltage();
if (!C.marikoGpuVmin) {
vmin = GetAutoVoltage();
PATCH_OFFSET(ptr, vmin);
PATCH_OFFSET(ptr + 3, vmin);
PATCH_OFFSET(ptr + 6, vmin);
@@ -291,7 +266,6 @@ namespace ams::ldr::hoc::pcv::mariko {
break;
}
switch (C.marikoCpuUVHigh) {
case 1:
PATCH_OFFSET(&(entry->tune1_high), 0);
@@ -572,42 +546,34 @@ 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;
table->dram_timings.rl = RL_DBI;
table->dram_timings.rl = RL;
table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast<u32>(mrw2);
table->emc_cfg_2 = 0x11083D;
}
// WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE(10.0));
// WRITE_PARAM_ALL_REG(table, emc_pdex2rd, GET_CYCLE(10.0));
// WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE(1.75));
// WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE(1.75));
// WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE(1.75));
// WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE(14.0));
// WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE(5.0));
void MemMtcPllmbDivisor(MarikoMtcTable *table) {
constexpr u32 PllOscInKHz = 38400;
constexpr u32 PllOscHalfKHz = 19200;

View File

@@ -153,12 +153,6 @@ Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* o
);
}
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetReverseNXRTMode, mode);
}
Result hocClkIpcSetKipData()
{
u32 temp = 0;
@@ -169,15 +163,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

@@ -1,61 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM --- Root directory ---
set ROOT_DIR=%~dp0
set DIST_DIR=%ROOT_DIR%dist
REM --- Number of CPU cores ---
set CORES=%NUMBER_OF_PROCESSORS%
REM --- Optional first argument as DIST_DIR ---
if not "%~1"=="" set DIST_DIR=%~1
echo DIST_DIR: %DIST_DIR%
echo CORES: %CORES%
REM ========================
REM sysmodule
REM ========================
echo *** sysmodule ***
REM Extract TITLE_ID from perms.json using findstr (rough approximation)
for /f "tokens=2 delims=: " %%A in ('findstr /i "title_id" "%ROOT_DIR%sysmodule\perms.json"') do (
set TITLE_ID=%%A
)
REM Remove quotes and 0x prefix
set TITLE_ID=!TITLE_ID:"=!
set TITLE_ID=!TITLE_ID:0x=!
REM Build sysmodule
pushd "%ROOT_DIR%sysmodule"
make -j %CORES%
popd
REM Copy sysmodule files to dist
if not exist "%DIST_DIR%\atmosphere\contents\%TITLE_ID%\flags" mkdir "%DIST_DIR%\atmosphere\contents\%TITLE_ID%\flags"
copy /Y "%ROOT_DIR%sysmodule\out\horizon-oc.nsp" "%DIST_DIR%\atmosphere\contents\%TITLE_ID%\exefs.nsp"
type nul > "%DIST_DIR%\atmosphere\contents\%TITLE_ID%\flags\boot2.flag"
copy /Y "%ROOT_DIR%sysmodule\toolbox.json" "%DIST_DIR%\atmosphere\contents\%TITLE_ID%\toolbox.json"
REM ========================
REM overlay
REM ========================
echo *** overlay ***
pushd "%ROOT_DIR%overlay"
make -j %CORES%
popd
if not exist "%DIST_DIR%\switch\.overlays" mkdir "%DIST_DIR%\switch\.overlays"
copy /Y "%ROOT_DIR%overlay\out\horizon-oc-overlay.ovl" "%DIST_DIR%\switch\.overlays\horizon-oc-overlay.ovl"
REM ========================
REM assets
REM ========================
echo *** assets ***
if not exist "%DIST_DIR%\config\horizon-oc" mkdir "%DIST_DIR%\config\horizon-oc"
copy /Y "%ROOT_DIR%config.ini.template" "%DIST_DIR%\config\horizon-oc\config.ini.template"
copy /Y "%ROOT_DIR%..\..\README.md" "%DIST_DIR%\README.md"
endlocal

View File

@@ -36,3 +36,7 @@ echo "*** assets ***"
mkdir -p "$DIST_DIR/config/horizon-oc"
cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/horizon-oc/config.ini.template"
cp -vf "$ROOT_DIR/../../README.md" "$DIST_DIR/README.md"
echo "*** lang ***"
cp -r "$ROOT_DIR/overlay/lang/" "$DIST_DIR/config/horizon-oc/lang/"

View File

@@ -124,8 +124,8 @@ typedef struct {
bool displaySyncDocked;
bool displaySyncDockedOutOfFocus60;
} DisplayRefreshConfig;
bool DisplayRefresh_Initialize(const DisplayRefreshConfig* config);
void DisplayRefresh_SetDockedState(bool isDocked);
bool DisplayRefresh_SetRate(uint32_t new_refreshRate);
bool DisplayRefresh_GetRate(uint32_t* out_refreshRate, bool internal);
uint8_t DisplayRefresh_GetDockedHighestAllowed(void);

View File

@@ -0,0 +1,41 @@
/*
MIT License
Copyright (c) 2024 Roy Merkel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef MEMMEM_IMPL_H
#define MEMMEM_IMPL_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void *memmem_impl(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -12,9 +12,8 @@
*
* 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
@@ -310,6 +309,9 @@
#define EMC_PMACRO_CMD_CTRL_1_0 0x784
#define EMC_PMACRO_CMD_CTRL_2_0 0x788
#define MC_REGISTER_BASE 0x70019000
#define MC_REGISTER_REGION_SIZE 0x1000
#define MC_INTSTATUS_0 0x000
#define MC_INTMASK_0 0x004
#define MC_ERR_STATUS_0 0x008
@@ -489,4 +491,40 @@
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xBEC
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS_0 0xC00
#define MC_SECURITY_CARVEOUT2_BOM_0 0xC5C
#define MC_SECURITY_CARVEOUT3_BOM_0 0xCAC
#define MC_SECURITY_CARVEOUT3_BOM_0 0xCAC
#define CLDVFS_REGION_BASE 0x70110000
#define CLDVFS_REGION_SIZE 0x1000
#define CL_DVFS_CTRL_0 0x0
#define CL_DVFS_CONFIG_0 0x4
#define CL_DVFS_PARAMS_0 0x8
#define CL_DVFS_TUNE0_0 0xC
#define CL_DVFS_TUNE1_0 0x10
#define CL_DVFS_FREQ_REQ_0 0x14
#define CL_DVFS_SCALE_RAMP_0 0x18
#define CL_DVFS_DROOP_CTRL_0 0x1C
#define CL_DVFS_OUTPUT_CFG_0 0x20
#define CL_DVFS_OUTPUT_FORCE_0 0x24
#define CL_DVFS_MONITOR_CTRL_0 0x28
#define CL_DVFS_MONITOR_DATA_0 0x2C
#define CL_DVFS_I2C_CFG_0 0x40
#define CL_DVFS_I2C_VDD_REG_ADDR_0 0x44
#define CL_DVFS_I2C_STS_0 0x48
#define CL_DVFS_INTR_STS_0 0x5C
#define CL_DVFS_INTR_EN_0 0x60
#define DVFS_DFLL_THROTTLE_CTRL_0 0x64
#define DVFS_DFLL_THROTTLE_LIGHT_0 0x68
#define DVFS_DFLL_THROTTLE_MEDIUM_0 0x6C
#define DVFS_DFLL_THROTTLE_HEAVY_0 0x70
#define DVFS_CC4_HVC_0 0x74
#define CL_DVFS_MONITOR_DATA_0 0x2C
#define CL_DVFS_I2C_CFG_0 0x40
#define CL_DVFS_I2C_VDD_REG_ADDR_0 0x44
#define CL_DVFS_I2C_STS_0 0x48
#define CL_DVFS_INTR_STS_0 0x5C
#define CL_DVFS_INTR_EN_0 0x60
#define DVFS_DFLL_THROTTLE_CTRL_0 0x64
#define DVFS_DFLL_THROTTLE_LIGHT_0 0x68
#define DVFS_DFLL_THROTTLE_MEDIUM_0 0x6C
#define DVFS_DFLL_THROTTLE_HEAVY_0 0x70
#define CL_DVFS_I2C_CLK_DIVISOR_REGISTER_0 0x16C

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,22 +102,12 @@ typedef enum
SysClkPartLoad_EMC = 0,
SysClkPartLoad_EMCCpu,
HocClkPartLoad_GPU,
HocClkPartLoad_CPUAvg,
HocClkPartLoad_CPUMax,
HocClkPartLoad_BAT,
HocClkPartLoad_FAN,
SysClkPartLoad_EnumMax
} SysClkPartLoad;
typedef enum
{
ReverseNX_NotFound = 0,
ReverseNX_SystemDefault = 0,
ReverseNX_Handheld,
ReverseNX_Docked,
} ReverseNXMode;
typedef enum {
HorizonOCSpeedo_CPU = 0,
HorizonOCSpeedo_GPU,
@@ -132,6 +122,36 @@ typedef enum {
GPUUVLevel_EnumMax,
} GPUUndervoltLevel;
enum {
DVFSMode_Disabled = 0,
DVFSMode_Hijack,
// DVFSMode_OfficialService,
// DVFSMode_Hack,
DVFSMode_EnumMax,
};
typedef enum {
GpuSchedulingMode_DoNotOverride = 0,
GpuSchedulingMode_Enabled,
GpuSchedulingMode_Disabled,
GpuSchedulingMode_EnumMax,
} GpuSchedulingMode;
typedef enum {
GpuSchedulingOverrideMethod_Ini = 0,
GpuSchedulingOverrideMethod_NvService,
GpuSchedulingOverrideMethod_EnumMax,
} GpuSchedulingOverrideMethod;
typedef enum {
GovernorState_DoNotOverride = 0,
GovernorState_Disabled,
GovernorState_Enabled_CpuGpu,
GovernorState_Enabled_Cpu,
GovernorState_Enabled_Gpu,
GovernorState_EnumMax,
} GovernorState;
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)

View File

@@ -48,11 +48,8 @@ Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles);
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues);
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues);
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount);
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode);
Result hocClkIpcSetKipData();
Result hocClkIpcGetKipData();
Result hocClkIpcUpdateEmcRegs();
Result hocClkIpcCalculateGpuVmin();
static inline Result sysclkIpcRemoveOverride(SysClkModule module)
{

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,20 +51,26 @@ typedef enum {
HocClkConfigValue_LiteTDPLimit,
HocClkConfigValue_EnforceBoardLimit,
HorizonOCConfigValue_BatteryChargeCurrent,
HorizonOCConfigValue_OverwriteRefreshRate,
HorizonOCConfigValue_EnableUnsafeDisplayFreqs,
HocClkConfigValue_FixCpuVoltBug,
HorizonOCConfigValue_DVFSMode,
HorizonOCConfigValue_DVFSOffset,
HorizonOCConfigValue_LiveCpuUv,
HorizonOCConfigValue_EnableExperimentalSettings,
HorizonOCConfigValue_GPUScheduling,
HorizonOCConfigValue_GPUSchedulingMethod,
KipConfigValue_custRev,
// KipConfigValue_mtcConf,
KipConfigValue_hpMode,
KipConfigValue_commonEmcMemVolt,
KipConfigValue_eristaEmcMaxClock,
KipConfigValue_eristaEmcMaxClock1,
KipConfigValue_eristaEmcMaxClock2,
KipConfigValue_marikoEmcMaxClock,
KipConfigValue_marikoEmcVddqVolt,
KipConfigValue_emcDvbShift,
@@ -129,35 +135,40 @@ typedef enum {
KipConfigValue_g_volt_1459200,
KipConfigValue_g_volt_1497600,
KipConfigValue_g_volt_1536000,
KipConfigValue_g_volt_1574400,
KipConfigValue_g_volt_1612800,
KipConfigValue_g_volt_1651200,
KipConfigValue_g_volt_1689600,
KipConfigValue_g_volt_1728000,
KipConfigValue_g_volt_1766400,
KipConfigValue_g_volt_1804800,
KipConfigValue_g_volt_e_76800,
KipConfigValue_g_volt_e_115200,
KipConfigValue_g_volt_e_153600,
KipConfigValue_g_volt_e_192000,
KipConfigValue_g_volt_e_230400,
KipConfigValue_g_volt_e_268800,
KipConfigValue_g_volt_e_307200,
KipConfigValue_g_volt_e_345600,
KipConfigValue_g_volt_e_384000,
KipConfigValue_g_volt_e_422400,
KipConfigValue_g_volt_e_460800,
KipConfigValue_g_volt_e_499200,
KipConfigValue_g_volt_e_537600,
KipConfigValue_g_volt_e_576000,
KipConfigValue_g_volt_e_614400,
KipConfigValue_g_volt_e_652800,
KipConfigValue_g_volt_e_691200,
KipConfigValue_g_volt_e_729600,
KipConfigValue_g_volt_e_768000,
KipConfigValue_g_volt_e_806400,
KipConfigValue_g_volt_e_844800,
KipConfigValue_g_volt_e_883200,
KipConfigValue_g_volt_e_921600,
KipConfigValue_g_volt_e_960000,
KipConfigValue_g_volt_e_998400,
KipConfigValue_g_volt_e_1036800,
KipConfigValue_g_volt_e_1075200,
KipConfigValue_g_volt_e_1152000,
KipConfigValue_g_volt_e_1228800,
KipConfigValue_g_volt_e_1267200,
KipConfigValue_g_volt_e_1305600,
KipConfigValue_g_volt_e_1344000,
KipConfigValue_g_volt_e_1382400,
KipConfigValue_g_volt_e_1420800,
KipConfigValue_g_volt_e_1459200,
KipConfigValue_g_volt_e_1497600,
KipConfigValue_g_volt_e_1536000,
KipConfigValue_t6_tRTW_fine_tune,
KipConfigValue_t7_tWTR_fine_tune,
KipCrc32,
@@ -210,21 +221,33 @@ 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";
case HorizonOCConfigValue_DVFSMode:
return pretty ? "DVFS Mode" : "dvfs_mode";
case HorizonOCConfigValue_DVFSOffset:
return pretty ? "DVFS Offset" : "dvfs_offset";
case HorizonOCConfigValue_GPUScheduling:
return pretty ? "GPU Scheduling" : "gpu_scheduling";
case HorizonOCConfigValue_GPUSchedulingMethod:
return pretty ? "GPU Scheduling Method" : "gpu_sched_method";
case HorizonOCConfigValue_LiveCpuUv:
return pretty ? "Live CPU Undervolt" : "live_cpu_uv";
case HorizonOCConfigValue_EnableExperimentalSettings:
return pretty ? "Enable Experimental Settings" : "enable_experimental_settings";
// KIP config values
case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev";
@@ -237,7 +260,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:
@@ -343,35 +370,42 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case KipConfigValue_g_volt_1459200: return pretty ? "Mariko GPU Volt 1459 MHz" : "g_volt_1459200";
case KipConfigValue_g_volt_1497600: return pretty ? "Mariko GPU Volt 1497 MHz" : "g_volt_1497600";
case KipConfigValue_g_volt_1536000: return pretty ? "Mariko GPU Volt 1536 MHz" : "g_volt_1536000";
case KipConfigValue_g_volt_1574400: return pretty ? "Mariko GPU Volt 1574 MHz" : "g_volt_1574400";
case KipConfigValue_g_volt_1612800: return pretty ? "Mariko GPU Volt 1612 MHz" : "g_volt_1612800";
case KipConfigValue_g_volt_1651200: return pretty ? "Mariko GPU Volt 1651 MHz" : "g_volt_1651200";
case KipConfigValue_g_volt_1689600: return pretty ? "Mariko GPU Volt 1689 MHz" : "g_volt_1689600";
case KipConfigValue_g_volt_1728000: return pretty ? "Mariko GPU Volt 1728 MHz" : "g_volt_1728000";
case KipConfigValue_g_volt_1766400: return pretty ? "Mariko GPU Volt 1766 MHz" : "g_volt_1766400";
case KipConfigValue_g_volt_1804800: return pretty ? "Mariko GPU Volt 1804 MHz" : "g_volt_1804800";
// Erista GPU voltages (27)
case KipConfigValue_g_volt_e_76800: return pretty ? "Erista GPU Volt 76 MHz" : "g_volt_e_76800";
case KipConfigValue_g_volt_e_115200: return pretty ? "Erista GPU Volt 115 MHz" : "g_volt_e_115200";
case KipConfigValue_g_volt_e_153600: return pretty ? "Erista GPU Volt 153 MHz" : "g_volt_e_153600";
case KipConfigValue_g_volt_e_192000: return pretty ? "Erista GPU Volt 192 MHz" : "g_volt_e_192000";
case KipConfigValue_g_volt_e_230400: return pretty ? "Erista GPU Volt 230 MHz" : "g_volt_e_230400";
case KipConfigValue_g_volt_e_268800: return pretty ? "Erista GPU Volt 268 MHz" : "g_volt_e_268800";
case KipConfigValue_g_volt_e_307200: return pretty ? "Erista GPU Volt 307 MHz" : "g_volt_e_307200";
case KipConfigValue_g_volt_e_345600: return pretty ? "Erista GPU Volt 345 MHz" : "g_volt_e_345600";
case KipConfigValue_g_volt_e_384000: return pretty ? "Erista GPU Volt 384 MHz" : "g_volt_e_384000";
case KipConfigValue_g_volt_e_422400: return pretty ? "Erista GPU Volt 422 MHz" : "g_volt_e_422400";
case KipConfigValue_g_volt_e_460800: return pretty ? "Erista GPU Volt 460 MHz" : "g_volt_e_460800";
case KipConfigValue_g_volt_e_499200: return pretty ? "Erista GPU Volt 499 MHz" : "g_volt_e_499200";
case KipConfigValue_g_volt_e_537600: return pretty ? "Erista GPU Volt 537 MHz" : "g_volt_e_537600";
case KipConfigValue_g_volt_e_576000: return pretty ? "Erista GPU Volt 576 MHz" : "g_volt_e_576000";
case KipConfigValue_g_volt_e_614400: return pretty ? "Erista GPU Volt 614 MHz" : "g_volt_e_614400";
case KipConfigValue_g_volt_e_652800: return pretty ? "Erista GPU Volt 652 MHz" : "g_volt_e_652800";
case KipConfigValue_g_volt_e_691200: return pretty ? "Erista GPU Volt 691 MHz" : "g_volt_e_691200";
case KipConfigValue_g_volt_e_729600: return pretty ? "Erista GPU Volt 729 MHz" : "g_volt_e_729600";
case KipConfigValue_g_volt_e_768000: return pretty ? "Erista GPU Volt 768 MHz" : "g_volt_e_768000";
case KipConfigValue_g_volt_e_806400: return pretty ? "Erista GPU Volt 806 MHz" : "g_volt_e_806400";
case KipConfigValue_g_volt_e_844800: return pretty ? "Erista GPU Volt 844 MHz" : "g_volt_e_844800";
case KipConfigValue_g_volt_e_883200: return pretty ? "Erista GPU Volt 883 MHz" : "g_volt_e_883200";
case KipConfigValue_g_volt_e_921600: return pretty ? "Erista GPU Volt 921 MHz" : "g_volt_e_921600";
case KipConfigValue_g_volt_e_960000: return pretty ? "Erista GPU Volt 960 MHz" : "g_volt_e_960000";
case KipConfigValue_g_volt_e_998400: return pretty ? "Erista GPU Volt 998 MHz" : "g_volt_e_998400";
case KipConfigValue_g_volt_e_1036800: return pretty ? "Erista GPU Volt 1036 MHz" : "g_volt_e_1036800";
case KipConfigValue_g_volt_e_1075200: return pretty ? "Erista GPU Volt 1075 MHz" : "g_volt_e_1075200";
case KipConfigValue_g_volt_e_1152000: return pretty ? "Erista GPU Volt 1152 MHz" : "g_volt_e_1152000";
case KipConfigValue_g_volt_e_1228800: return pretty ? "Erista GPU Volt 1228 MHz" : "g_volt_e_1228800";
case KipConfigValue_g_volt_e_1267200: return pretty ? "Erista GPU Volt 1267 MHz" : "g_volt_e_1267200";
case KipConfigValue_g_volt_e_1305600: return pretty ? "Erista GPU Volt 1305 MHz" : "g_volt_e_1305600";
case KipConfigValue_g_volt_e_1344000: return pretty ? "Erista GPU Volt 1344 MHz" : "g_volt_e_1344000";
case KipConfigValue_g_volt_e_1382400: return pretty ? "Erista GPU Volt 1382 MHz" : "g_volt_e_1382400";
case KipConfigValue_g_volt_e_1420800: return pretty ? "Erista GPU Volt 1420 MHz" : "g_volt_e_1420800";
case KipConfigValue_g_volt_e_1459200: return pretty ? "Erista GPU Volt 1459 MHz" : "g_volt_e_1459200";
case KipConfigValue_g_volt_e_1497600: return pretty ? "Erista GPU Volt 1497 MHz" : "g_volt_e_1497600";
case KipConfigValue_g_volt_e_1536000: return pretty ? "Erista GPU Volt 1536 MHz" : "g_volt_e_1536000";
case KipConfigValue_t6_tRTW_fine_tune: return pretty ? "t6 - tRTW Fine Tune" : "t6_tRTW_fine_fune";
case KipConfigValue_t7_tWTR_fine_tune: return pretty ? "t7 - tWTR Fine Tune" : "t7_tWTR_fine_tune";
case KipCrc32:
return pretty ? "CRC32" : "crc32";
@@ -392,23 +426,23 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
case SysClkConfigValue_FreqLogIntervalMs:
case SysClkConfigValue_PowerLogIntervalMs:
case SysClkConfigValue_CsvWriteIntervalMs:
case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode:
case HorizonOCConfigValue_BatteryChargeCurrent:
case HorizonOCConfigValue_OverwriteRefreshRate:
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
case HorizonOCConfigValue_GPUScheduling:
case HorizonOCConfigValue_LiveCpuUv:
case HorizonOCConfigValue_GPUSchedulingMethod:
return 0ULL;
case HocClkConfigValue_EristaMaxCpuClock:
return 1785ULL;
case HocClkConfigValue_MarikoMaxCpuClock:
return 1963ULL;
case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_EnforceBoardLimit:
case HocClkConfigValue_FixCpuVoltBug:
case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode:
case HocClkConfigValue_IsFirstLoad:
case HorizonOCConfigValue_DVFSMode:
case HorizonOCConfigValue_EnableExperimentalSettings:
return 1ULL;
case HocClkConfigValue_ThermalThrottleThreshold:
return 70ULL;
@@ -441,11 +475,12 @@ 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:
case HorizonOCConfigValue_EnableExperimentalSettings:
case HorizonOCConfigValue_LiveCpuUv:
case HorizonOCConfigValue_GPUSchedulingMethod:
return (input & 0x1) == input;
case KipConfigValue_custRev:
@@ -453,6 +488,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:
@@ -484,65 +521,16 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case KipConfigValue_marikoGpuVmax:
case KipConfigValue_commonGpuVoltOffset:
case KipConfigValue_gpuSpeedo:
case KipConfigValue_g_volt_76800:
case KipConfigValue_g_volt_153600:
case KipConfigValue_g_volt_230400:
case KipConfigValue_g_volt_307200:
case KipConfigValue_g_volt_384000:
case KipConfigValue_g_volt_460800:
case KipConfigValue_g_volt_537600:
case KipConfigValue_g_volt_614400:
case KipConfigValue_g_volt_691200:
case KipConfigValue_g_volt_768000:
case KipConfigValue_g_volt_844800:
case KipConfigValue_g_volt_921600:
case KipConfigValue_g_volt_998400:
case KipConfigValue_g_volt_1075200:
case KipConfigValue_g_volt_1152000:
case KipConfigValue_g_volt_1228800:
case KipConfigValue_g_volt_1267200:
case KipConfigValue_g_volt_1305600:
case KipConfigValue_g_volt_1344000:
case KipConfigValue_g_volt_1382400:
case KipConfigValue_g_volt_1420800:
case KipConfigValue_g_volt_1459200:
case KipConfigValue_g_volt_1497600:
case KipConfigValue_g_volt_1536000:
case KipConfigValue_g_volt_e_76800:
case KipConfigValue_g_volt_e_115200:
case KipConfigValue_g_volt_e_153600:
case KipConfigValue_g_volt_e_192000:
case KipConfigValue_g_volt_e_230400:
case KipConfigValue_g_volt_e_268800:
case KipConfigValue_g_volt_e_307200:
case KipConfigValue_g_volt_e_345600:
case KipConfigValue_g_volt_e_384000:
case KipConfigValue_g_volt_e_422400:
case KipConfigValue_g_volt_e_460800:
case KipConfigValue_g_volt_e_499200:
case KipConfigValue_g_volt_e_537600:
case KipConfigValue_g_volt_e_576000:
case KipConfigValue_g_volt_e_614400:
case KipConfigValue_g_volt_e_652800:
case KipConfigValue_g_volt_e_691200:
case KipConfigValue_g_volt_e_729600:
case KipConfigValue_g_volt_e_768000:
case KipConfigValue_g_volt_e_806400:
case KipConfigValue_g_volt_e_844800:
case KipConfigValue_g_volt_e_883200:
case KipConfigValue_g_volt_e_921600:
case KipConfigValue_g_volt_e_960000:
case KipConfigValue_g_volt_e_998400:
case KipConfigValue_g_volt_e_1036800:
case KipConfigValue_g_volt_e_1075200:
case KipConfigValue_eristaCpuVmin:
case KipConfigValue_eristaCpuUnlock:
case KipConfigValue_t6_tRTW_fine_tune:
case KipConfigValue_t7_tWTR_fine_tune:
case KipCrc32:
case HorizonOCConfigValue_DVFSMode:
case HorizonOCConfigValue_DVFSOffset:
case HorizonOCConfigValue_GPUScheduling:
return true;
case HorizonOCConfigValue_BatteryChargeCurrent:
return ((input >= 1024) && (input <= 3072)) || !input;
default:
return false;
return true;
}
}

View File

@@ -48,11 +48,8 @@ enum SysClkIpcCmd
SysClkIpcCmd_GetConfigValues = 9,
SysClkIpcCmd_SetConfigValues = 10,
SysClkIpcCmd_GetFreqList = 11,
SysClkIpcCmd_SetReverseNXRTMode = 12,
HocClkIpcCmd_SetKipData = 13,
HocClkIpcCmd_GetKipData = 14,
HocClkIpcCmd_UpdateEmcRegs = 15,
HocClkIpcCmd_CalculateGpuVmin = 16,
HocClkIpcCmd_SetKipData = 12,
HocClkIpcCmd_GetKipData = 13,
};

View File

@@ -153,12 +153,6 @@ Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* o
);
}
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetReverseNXRTMode, mode);
}
Result hocClkIpcSetKipData()
{
u32 temp = 0;
@@ -169,15 +163,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,10 +42,23 @@ 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, 140, 144, 150, 160, 165, 170, 180, 190, 200, 210, 220, 230, 240};
// Calculate with this tool:
// https://tomverbeure.github.io/video_timings_calculator?horiz_pixels=1920&vert_pixels=1080&refresh_rate=240&margins=false&interlaced=false&bpc=8&color_fmt=rgb444&video_opt=false&custom_hblank=80&custom_vblank=6
/*
typedef struct {
uint16_t hFrontPorch;
uint8_t hSyncWidth;
uint8_t hBackPorch;
uint8_t vFrontPorch;
uint8_t vSyncWidth;
uint8_t vBackPorch;
uint8_t VIC;
uint32_t pixelClock_kHz;
} DockedTimings;
*/
static const DockedTimings g_dockedTimings1080p[] = {
{8, 32, 40, 7, 8, 6, 0, 88080}, // 40Hz
{8, 32, 40, 9, 8, 6, 0, 99270}, // 45Hz
@@ -60,7 +73,21 @@ static const DockedTimings g_dockedTimings1080p[] = {
{8, 32, 40, 36, 8, 6, 0, 214700}, // 95Hz
{528, 44, 148, 4, 5, 36, 64, 297000}, // 100Hz
{8, 32, 40, 44, 8, 6, 0, 250360}, // 110Hz
{88, 44, 148, 4, 5, 36, 63, 297000} // 120Hz
{88, 44, 148, 4, 5, 36, 63, 297000}, // 120Hz
{8, 32, 40, 55, 8, 6, 0, 298750}, //130Hz CVT-RBv2
{8, 32, 40, 61, 8, 6, 0, 323400}, //140Hz CVT-RBv2
{8, 32, 40, 63, 8, 6, 0, 333216}, //144Hz CVT-RBv2
{8, 32, 40, 67, 8, 6, 0, 348300}, //150Hz CVT-RBv2
{8, 32, 40, 72, 8, 6, 0, 373120}, //160Hz CVT-RBv2
{8, 32, 40, 75, 8, 6, 0, 385770}, //165Hz CVT-RBv2
{8, 32, 40, 78, 8, 6, 0, 398480}, //170Hz CVT-RBv2
{8, 32, 40, 84, 8, 6, 0, 424080}, //180Hz CVT-RBv2
{8, 32, 40, 90, 8, 6, 0, 449920}, //190Hz CVT-RBv2
{8, 32, 40, 96, 8, 6, 0, 476000}, //200Hz CVT-RBv2
{8, 32, 40, 102, 8, 6, 0, 502320}, //210Hz CVT-RBv2
{8, 32, 40, 108, 8, 6, 0, 528880}, //220Hz CVT-RBv2
{8, 32, 40, 114, 8, 6, 0, 555680}, //230Hz CVT-RBv2
{8, 32, 40, 121, 8, 6, 0, 583200}, //240Hz CVT-RBv2
};
static const HandheldTimings g_handheldTimingsRETRO[] = {
@@ -81,15 +108,6 @@ static uint8_t _getDockedRefreshRateIterator(uint32_t refreshRate) {
return 0xFF;
}
static void _setDefaultDockedSettings(void) {
memset(g_dockedAllowed, 0, sizeof(g_dockedAllowed));
g_dockedAllowed[_getDockedRefreshRateIterator(50)] = true;
g_dockedAllowed[_getDockedRefreshRateIterator(60)] = true;
memset(g_dockedAllowed720p, 0, sizeof(g_dockedAllowed720p));
g_dockedAllowed720p[_getDockedRefreshRateIterator(50)] = true;
g_dockedAllowed720p[_getDockedRefreshRateIterator(60)] = true;
}
static void _changeOledElvssSettings(const uint32_t* offsets, const uint32_t* value, uint32_t size, uint32_t start) {
if (!g_config.dsiVirtAddr || !value || !size) return;
@@ -126,13 +144,14 @@ static void _changeOledElvssSettings(const uint32_t* offsets, const uint32_t* va
dsi[DSI_VIDEO_MODE_CONTROL] = false;
svcSleepThread(20000000);
}
void DisplayRefresh_SetDockedState(bool isDocked) {
g_config.isDocked = isDocked;
}
bool DisplayRefresh_Initialize(const DisplayRefreshConfig* config) {
if (!config) return false;
g_config = *config;
_setDefaultDockedSettings();
g_initialized = true;
return true;
}
@@ -180,69 +199,20 @@ void DisplayRefresh_CorrectOledGamma(uint32_t refresh_rate) {
}
void DisplayRefresh_SetAllowedDockedRatesIPC(uint32_t refreshRates, bool is720p) {
struct {
unsigned int Hz_40: 1;
unsigned int Hz_45: 1;
unsigned int Hz_50: 1;
unsigned int Hz_55: 1;
unsigned int Hz_60: 1;
unsigned int Hz_70: 1;
unsigned int Hz_72: 1;
unsigned int Hz_75: 1;
unsigned int Hz_80: 1;
unsigned int Hz_90: 1;
unsigned int Hz_95: 1;
unsigned int Hz_100: 1;
unsigned int Hz_110: 1;
unsigned int Hz_120: 1;
unsigned int reserved: 18;
} rates;
memcpy(&rates, &refreshRates, 4);
bool* target = is720p ? g_dockedAllowed720p : g_dockedAllowed;
target[_getDockedRefreshRateIterator(40)] = rates.Hz_40;
target[_getDockedRefreshRateIterator(45)] = rates.Hz_45;
target[_getDockedRefreshRateIterator(50)] = rates.Hz_50;
target[_getDockedRefreshRateIterator(55)] = rates.Hz_55;
target[_getDockedRefreshRateIterator(60)] = true;
target[_getDockedRefreshRateIterator(70)] = rates.Hz_70;
target[_getDockedRefreshRateIterator(72)] = rates.Hz_72;
target[_getDockedRefreshRateIterator(75)] = rates.Hz_75;
target[_getDockedRefreshRateIterator(80)] = rates.Hz_80;
target[_getDockedRefreshRateIterator(90)] = rates.Hz_90;
target[_getDockedRefreshRateIterator(95)] = rates.Hz_95;
target[_getDockedRefreshRateIterator(100)] = rates.Hz_100;
target[_getDockedRefreshRateIterator(110)] = rates.Hz_110;
target[_getDockedRefreshRateIterator(120)] = rates.Hz_120;
// Function kept for API compatibility but does nothing
(void)refreshRates;
(void)is720p;
}
uint8_t DisplayRefresh_GetDockedHighestAllowed(void) {
const size_t numRates = sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0]);
if (g_lastVActive == 1080) {
for (int i = numRates - 1; g_dockedRefreshRates[i] > 60; i--) {
if (g_dockedAllowed[i])
return (g_dockedRefreshRates[i] > g_dockedHighestRefreshRate) ? g_dockedHighestRefreshRate : g_dockedRefreshRates[i];
}
} else if (g_lastVActive == 720) {
for (int i = numRates - 1; g_dockedRefreshRates[i] > 60; i--) {
if (g_dockedAllowed720p[i])
return (g_dockedRefreshRates[i] > g_dockedHighestRefreshRate) ? g_dockedHighestRefreshRate : g_dockedRefreshRates[i];
}
}
return 60;
return (g_dockedHighestRefreshRate > 60) ? g_dockedHighestRefreshRate : 60;
}
static void _getDockedHighestRefreshRate(uint32_t fd_in) {
uint8_t highestRefreshRate = 60;
uint32_t fd = fd_in;
if (!fd && nvOpen(&fd, "/dev/nvdisp-disp1")) {
g_dockedHighestRefreshRate = 60;
return;
}
if(!fd) nvOpen(&fd, "/dev/nvdisp-disp1");
NvdcModeDB2 db2 = {0};
int rc = nvIoctl(fd, NVDISP_GET_MODE_DB2, &db2);
@@ -288,8 +258,8 @@ static void _getDockedHighestRefreshRate(uint32_t fd_in) {
rc = nvIoctl(fd, NVDISP_GET_PANEL_DATA, &dpaux);
if (rc == 0) {
g_dockedLinkRate = dpaux.set.link_rate;
if (display_b.hActive == 1920 && display_b.vActive == 1080 && highestRefreshRate > 75 && dpaux.set.link_rate < 20)
highestRefreshRate = 75;
// if (display_b.hActive == 1920 && display_b.vActive == 1080 && highestRefreshRate > 75 && dpaux.set.link_rate < 20 && )
// highestRefreshRate = 75;
}
if (!fd_in) nvClose(fd);
@@ -403,10 +373,6 @@ static bool _setNvDispDockedRefreshRate(uint32_t new_refreshRate) {
if (display_b.vActive != g_lastVActiveSet) {
g_lastVActiveSet = display_b.vActive;
if (display_b.vActive != 720 && display_b.vActive != 1080) {
memset(g_dockedAllowed, 0, sizeof(g_dockedAllowed));
g_dockedAllowed[_getDockedRefreshRateIterator(60)] = true;
}
}
uint32_t h_total = display_b.hActive + display_b.hFrontPorch + display_b.hSyncWidth + display_b.hBackPorch;
@@ -416,15 +382,13 @@ static bool _setNvDispDockedRefreshRate(uint32_t new_refreshRate) {
int8_t itr = -1;
const size_t numRates = sizeof(g_dockedRefreshRates) / sizeof(g_dockedRefreshRates[0]);
// Find closest matching refresh rate
if ((new_refreshRate <= 60) && ((60 % new_refreshRate) == 0)) {
itr = _getDockedRefreshRateIterator(60);
}
if (itr == -1) {
for (size_t i = 0; i < numRates; i++) {
bool* allowed = (display_b.vActive == 720) ? g_dockedAllowed720p : g_dockedAllowed;
if (allowed[i] != true) continue;
uint8_t val = g_dockedRefreshRates[i];
if ((val % new_refreshRate) == 0) {
itr = i;
@@ -437,9 +401,8 @@ static bool _setNvDispDockedRefreshRate(uint32_t new_refreshRate) {
if (!g_config.matchLowestDocked) {
itr = _getDockedRefreshRateIterator(60);
} else {
bool* allowed = (display_b.vActive == 1080) ? g_dockedAllowed : g_dockedAllowed720p;
for (size_t i = 0; i < numRates; i++) {
if ((allowed[i] == true) && (new_refreshRate < g_dockedRefreshRates[i])) {
if (new_refreshRate < g_dockedRefreshRates[i]) {
itr = i;
break;
}
@@ -449,15 +412,13 @@ static bool _setNvDispDockedRefreshRate(uint32_t new_refreshRate) {
if (itr == -1) itr = _getDockedRefreshRateIterator(60);
bool increase = refreshRateNow < g_dockedRefreshRates[itr];
bool* allowed = (display_b.vActive == 720) ? g_dockedAllowed720p : g_dockedAllowed;
while(itr >= 0 && itr < (int8_t)numRates && allowed[itr] != true) {
if (!g_config.displaySyncDocked) {
if (increase) itr++;
else itr--;
} else {
itr++;
// Clamp to highest allowed refresh rate
if (g_dockedRefreshRates[itr] > g_dockedHighestRefreshRate) {
for (int8_t i = itr; i >= 0; i--) {
if (g_dockedRefreshRates[i] <= g_dockedHighestRefreshRate) {
itr = i;
break;
}
}
}
@@ -629,8 +590,7 @@ bool DisplayRefresh_SetRate(uint32_t new_refreshRate) {
bool DisplayRefresh_GetRate(uint32_t* out_refreshRate, bool internal) {
if (!out_refreshRate || !g_initialized || !g_config.clkVirtAddr) return false;
uint32_t value = 60;
static uint32_t value = 60;
if (g_config.isRetroSUPER && !g_config.isDocked) {
uint32_t fd = 0;
@@ -705,7 +665,10 @@ bool DisplayRefresh_GetRate(uint32_t* out_refreshRate, bool internal) {
return false;
}
}
if(internal) {
*out_refreshRate = value;
return true;
}
uint32_t fd = 0;
if (!nvOpen(&fd, "/dev/nvdisp-disp1")) {
NvdcMode2 display_b = {0};

View File

@@ -0,0 +1,83 @@
/*
MIT License
Copyright (c) 2024 Roy Merkel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "memmem.h"
void *memmem_impl(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
{
const unsigned char *cmpp;
const unsigned char *p;
const unsigned char *endp;
const unsigned char *q;
const unsigned char *endq;
unsigned char found;
if(haystack == NULL)
{
return NULL;
}
if(needle == NULL)
{
return (void*)haystack;
}
if(haystacklen == 0)
{
return NULL;
}
if(needlelen == 0)
{
return (void*)haystack;
}
if(needlelen > haystacklen)
{
return NULL;
}
endp = haystack + haystacklen - needlelen;
endq = needle + needlelen;
for(p = haystack; p <= endp; p++)
{
found = 1;
cmpp = p;
for(q = needle; q < endq; q++)
{
if(*cmpp != *q)
{
found = 0;
break;
}
else
{
cmpp++;
}
}
if(found)
{
return (void*)p;
}
}
return NULL;
}

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.35
APP_VERSION := 0.41
TARGET_VERSION := $(APP_VERSION)
#---------------------------------------------------------------------------------
@@ -55,7 +55,7 @@ CFLAGS := -Os -Wall -flto -fdata-sections -ffunction-sections -fno-rtti -fno-com
CFLAGS += $(INCLUDE) -D__SWITCH__
# Enable appearance overriding
UI_OVERRIDE_PATH := /config/sys-clk/
UI_OVERRIDE_PATH := /config/horizon-oc/
CFLAGS += -DUI_OVERRIDE_PATH="\"$(UI_OVERRIDE_PATH)\""
# Disable fstream

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

@@ -95,7 +95,8 @@ void AppProfileGui::openValueChoiceGui(
enableThresholds,
labels,
namedValues,
showDefaultValue
showDefaultValue,
true
);
}
@@ -148,6 +149,36 @@ void AppProfileGui::addModuleListItemToggle(SysClkProfile profile, SysClkModule
this->listElement->addItem(toggle);
}
std::string AppProfileGui::formatValueDisplay(
std::uint32_t value,
const std::vector<NamedValue>& namedValues,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces
)
{
if (value == 0) {
return FREQ_DEFAULT_TEXT;
}
if (!namedValues.empty()) {
for (const auto& namedValue : namedValues) {
if (namedValue.value == value) {
return namedValue.name;
}
}
}
char buf[32];
if (decimalPlaces > 0) {
double displayValue = (double)value / divisor;
snprintf(buf, sizeof(buf), "%.*f%s", decimalPlaces, displayValue, suffix.c_str());
} else {
snprintf(buf, sizeof(buf), "%u%s", value / divisor, suffix.c_str());
}
return std::string(buf);
}
void AppProfileGui::addModuleListItemValue(
SysClkProfile profile,
SysClkModule module,
@@ -158,26 +189,17 @@ void AppProfileGui::addModuleListItemValue(
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds
ValueThresholds thresholds,
std::vector<NamedValue> namedValues,
bool showDefaultValue
)
{
tsl::elm::ListItem* listItem =
new tsl::elm::ListItem(sysclkFormatModule(module, true));
std::uint32_t storedValue = this->profileList->mhzMap[profile][module];
if (storedValue == 0) {
listItem->setValue(FREQ_DEFAULT_TEXT);
} else {
char buf[32];
if (decimalPlaces > 0) {
double displayValue = (double)storedValue / divisor;
snprintf(buf, sizeof(buf), "%.*f%s", decimalPlaces, displayValue, suffix.c_str());
} else {
snprintf(buf, sizeof(buf), "%u%s", storedValue / divisor, suffix.c_str());
}
listItem->setValue(buf);
}
listItem->setValue(this->formatValueDisplay(storedValue, namedValues, suffix, divisor, decimalPlaces));
listItem->setClickListener(
[this,
listItem,
@@ -190,13 +212,14 @@ void AppProfileGui::addModuleListItemValue(
suffix,
divisor,
decimalPlaces,
thresholds](u64 keys)
thresholds,
namedValues,
showDefaultValue](u64 keys)
{
if ((keys & HidNpadButton_A) == HidNpadButton_A)
{
std::uint32_t currentValue =
this->profileList->mhzMap[profile][module] * divisor;
ValueRange range(
min,
max,
@@ -205,36 +228,19 @@ void AppProfileGui::addModuleListItemValue(
divisor,
decimalPlaces
);
this->openValueChoiceGui(
listItem,
currentValue,
range,
categoryName,
[this, listItem, profile, module, divisor, suffix, decimalPlaces, thresholds](std::uint32_t value) -> bool
[this, listItem, profile, module, divisor, suffix, decimalPlaces, thresholds, namedValues](std::uint32_t value) -> bool
{
this->profileList->mhzMap[profile][module] = value / divisor;
if (value == 0) {
listItem->setValue(FREQ_DEFAULT_TEXT);
} else {
char buf[32];
if (decimalPlaces > 0) {
double displayValue = (double)value / divisor;
snprintf(buf, sizeof(buf), "%.*f%s",
decimalPlaces, displayValue, suffix.c_str());
} else {
snprintf(buf, sizeof(buf), "%u%s",
value / divisor, suffix.c_str());
}
listItem->setValue(buf);
}
listItem->setValue(this->formatValueDisplay(value / divisor, namedValues, suffix, divisor, decimalPlaces));
Result rc =
sysclkIpcSetProfiles(this->applicationId,
this->profileList);
if (R_FAILED(rc))
{
FatalGui::openWithResultCode(
@@ -243,58 +249,137 @@ void AppProfileGui::addModuleListItemValue(
}
return true;
},
thresholds,
false
false,
{},
namedValues,
showDefaultValue
);
return true;
}
else if ((keys & HidNpadButton_Y) == HidNpadButton_Y)
{
this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(FREQ_DEFAULT_TEXT);
Result rc =
sysclkIpcSetProfiles(this->applicationId,
this->profileList);
if (R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
return false;
}
return true;
}
return false;
});
this->listElement->addItem(listItem);
}
void AppProfileGui::addProfileUI(SysClkProfile profile)
{
Result rc = sysclkIpcGetConfigValues(&configList); // idk why this is needed, probably some refreshing issue
{
BaseMenuGui::refresh();
if(!this->context)
return;
Result rc = sysclkIpcGetConfigValues(&configList);
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);
#if IS_MINIMAL == 0
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);
else
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 5, " Hz", 1, 0);
if(profile != SysClkProfile_Docked) {
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
} else {
if(IsAula() && this->context->isSysDockInstalled) {
std::vector<NamedValue> dockedFreqs = {
NamedValue("40 Hz", 40),
NamedValue("45 Hz", 45),
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75),
NamedValue("80 Hz", 80),
NamedValue("90 Hz", 90),
NamedValue("95 Hz", 95),
NamedValue("100 Hz", 100),
NamedValue("110 Hz", 110),
NamedValue("120 Hz", 120),
NamedValue("130 Hz", 130),
NamedValue("140 Hz", 140),
NamedValue("144 Hz", 144),
NamedValue("150 Hz", 150),
NamedValue("160 Hz", 160),
NamedValue("165 Hz", 165),
NamedValue("170 Hz", 170),
NamedValue("180 Hz", 180),
NamedValue("190 Hz", 190),
NamedValue("200 Hz", 200),
NamedValue("210 Hz", 210),
NamedValue("220 Hz", 220),
NamedValue("230 Hz", 230),
NamedValue("240 Hz", 240)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, 240, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqs);
} else if (IsAula() && !this->context->isSysDockInstalled) {
std::vector<NamedValue> dockedFreqsLimited = {
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("65 Hz", 65),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 75, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsLimited);
} else {
std::vector<NamedValue> dockedFreqsStandard = {
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("65 Hz", 65),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75),
NamedValue("80 Hz", 80),
NamedValue("85 Hz", 85),
NamedValue("90 Hz", 90),
NamedValue("95 Hz", 95),
NamedValue("100 Hz", 100),
NamedValue("105 Hz", 105),
NamedValue("110 Hz", 110),
NamedValue("115 Hz", 115),
NamedValue("120 Hz", 120)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsStandard);
}
}
}
#endif
this->addModuleListItemToggle(profile, HorizonOCModule_Governor);
std::vector<NamedValue> governorSettingsE = {
NamedValue("Do Not Override", GovernorState_DoNotOverride),
NamedValue("Disabled", GovernorState_Disabled),
NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu),
NamedValue("CPU", GovernorState_Enabled_Cpu),
NamedValue("GPU", GovernorState_Enabled_Gpu),
};
std::vector<NamedValue> governorSettings = {
NamedValue("Do Not Override", GovernorState_DoNotOverride),
NamedValue("Disabled", GovernorState_Disabled),
NamedValue("GPU", GovernorState_Enabled_Gpu),
};
this->addModuleListItemValue(profile, HorizonOCModule_Governor, "Governor", 0, 0, 1, "", 1, 0, ValueThresholds(), configList.values[HorizonOCConfigValue_EnableExperimentalSettings] ?governorSettingsE : governorSettings, false);
}
void AppProfileGui::listUI()
@@ -334,4 +419,4 @@ void AppProfileGui::update()
""
);
}
}
}

View File

@@ -23,22 +23,17 @@
* stuff is worth it, you can buy us a beer in return. - The sys-clk authors
* --------------------------------------------------------------------------
*/
#pragma once
#include "../../ipc.h"
#include "base_menu_gui.h"
#include "freq_choice_gui.h"
#include "value_choice_gui.h"
#define SYSCLK_GLOBAL_PROFILE_TID 0xA111111111111111
class AppProfileGui : public BaseMenuGui
{
protected:
std::uint64_t applicationId;
SysClkTitleProfileList* profileList;
void openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfile profile, SysClkModule module);
void addModuleListItem(SysClkProfile profile, SysClkModule module);
void addModuleListItemToggle(SysClkProfile profile, SysClkModule module);
@@ -54,6 +49,13 @@ class AppProfileGui : public BaseMenuGui
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true
);
std::string formatValueDisplay(
std::uint32_t value,
const std::vector<NamedValue>& namedValues,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces
);
void addModuleListItemValue(
SysClkProfile profile,
SysClkModule module,
@@ -64,14 +66,15 @@ class AppProfileGui : public BaseMenuGui
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds = {}
ValueThresholds thresholds,
std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true
);
void addProfileUI(SysClkProfile profile);
public:
AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList);
~AppProfileGui();
void listUI() override;
static void changeTo(std::uint64_t applicationId);
void update() override;
};
};

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

@@ -118,32 +118,32 @@ void FreqChoiceGui::listUI()
std::uint32_t hz = this->hzList[i];
uint32_t mhz = hz / 1000000;
if (checkMax && IsMariko()) {
if (moduleName == "cpu" &&
this->configList->values[HocClkConfigValue_MarikoMaxCpuClock] < mhz)
continue;
// if (checkMax && IsMariko()) {
// if (moduleName == "cpu" &&
// this->configList->values[HocClkConfigValue_MarikoMaxCpuClock] < mhz)
// continue;
// if (moduleName == "gpu" &&
// this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz)
// continue;
// // if (moduleName == "gpu" &&
// // this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz)
// // continue;
// if (moduleName == "mem" &&
// this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz)
// continue;
// // if (moduleName == "mem" &&
// // this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz)
// // continue;
} else if (checkMax && IsErista()) {
if (moduleName == "cpu" &&
this->configList->values[HocClkConfigValue_EristaMaxCpuClock] < mhz)
continue;
// } else if (checkMax && IsErista()) {
// if (moduleName == "cpu" &&
// this->configList->values[HocClkConfigValue_EristaMaxCpuClock] < mhz)
// continue;
// if (moduleName == "gpu" &&
// this->configList->values[HocClkConfigValue_EristaMaxGpuClock] < mhz)
// continue;
// // if (moduleName == "gpu" &&
// // this->configList->values[HocClkConfigValue_EristaMaxGpuClock] < mhz)
// // continue;
// if (moduleName == "mem" &&
// this->configList->values[HocClkConfigValue_EristaMaxMemClock] < mhz)
// continue;
}
// // if (moduleName == "mem" &&
// // this->configList->values[HocClkConfigValue_EristaMaxMemClock] < mhz)
// // continue;
// }
if (moduleName == "mem" && mhz <= 600)
continue;
@@ -155,7 +155,7 @@ void FreqChoiceGui::listUI()
if (IsMariko())
{
unsafe_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2296 : 1963;
unsafe_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2296 : 1964;
if(this->configList->values[KipConfigValue_marikoGpuUV] == 0) {
unsafe_gpu = 1076;
} else if (this->configList->values[KipConfigValue_marikoGpuUV] == 1) {

View File

@@ -99,11 +99,16 @@ void GlobalOverrideGui::addModuleListItemValue(
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds
ValueThresholds thresholds,
const std::vector<NamedValue>& namedValues,
bool showDefaultValue
)
{
bool hasNamedValues = !namedValues.empty();
this->customFormatModules[module] = std::make_tuple(suffix, divisor, decimalPlaces);
if (!hasNamedValues) {
this->customFormatModules[module] = std::make_tuple(suffix, divisor, decimalPlaces);
}
tsl::elm::ListItem* listItem =
new tsl::elm::ListItem(sysclkFormatModule(module, true));
@@ -121,7 +126,10 @@ void GlobalOverrideGui::addModuleListItemValue(
suffix,
divisor,
decimalPlaces,
thresholds](u64 keys)
thresholds,
namedValues,
hasNamedValues,
showDefaultValue](u64 keys)
{
if ((keys & HidNpadButton_A) == HidNpadButton_A)
{
@@ -147,7 +155,7 @@ void GlobalOverrideGui::addModuleListItemValue(
range,
categoryName,
[this, listItem, module, divisor, suffix, decimalPlaces, thresholds](std::uint32_t value) -> bool
[this, listItem, module, divisor, suffix, decimalPlaces, thresholds, namedValues, hasNamedValues, showDefaultValue](std::uint32_t value) -> bool
{
if (!this->context) {
return false;
@@ -158,6 +166,13 @@ void GlobalOverrideGui::addModuleListItemValue(
if (value == 0) {
listItem->setValue(FREQ_DEFAULT_TEXT);
} else if (hasNamedValues) {
for (const auto& namedValue : namedValues) {
if (namedValue.value == value / divisor) {
listItem->setValue(namedValue.name);
break;
}
}
} else {
char buf[32];
if (decimalPlaces > 0) {
@@ -188,8 +203,8 @@ void GlobalOverrideGui::addModuleListItemValue(
thresholds,
false,
std::map<std::uint32_t, std::string>(),
std::vector<NamedValue>(),
true
namedValues,
showDefaultValue
);
return true;
@@ -285,16 +300,30 @@ 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);
std::vector<NamedValue> governorSettingsE = {
NamedValue("Do Not Override", GovernorState_DoNotOverride),
NamedValue("Disabled", GovernorState_Disabled),
NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu),
NamedValue("CPU", GovernorState_Enabled_Cpu),
NamedValue("GPU", GovernorState_Enabled_Gpu),
};
std::vector<NamedValue> governorSettings = {
NamedValue("Do Not Override", GovernorState_DoNotOverride),
NamedValue("Disabled", GovernorState_Disabled),
NamedValue("GPU", GovernorState_Enabled_Gpu),
};
this->addModuleListItemValue(HorizonOCModule_Governor, "Governor", 0, 0, 1, "", 1, 0, ValueThresholds(), configList.values[HorizonOCConfigValue_EnableExperimentalSettings] ?governorSettingsE : governorSettings, false);
}
void GlobalOverrideGui::refresh()
@@ -306,17 +335,30 @@ void GlobalOverrideGui::refresh()
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) {
if (m == HorizonOCModule_Governor) {
auto *toggle =
static_cast<tsl::elm::ToggleListItem *>(this->listItems[m]);
if (!toggle)
continue;
bool newState = this->context->overrideFreqs[m] != 0;
if (toggle->getState() != newState) {
toggle->setState(newState);
if (this->listItems[m] != nullptr &&
this->listHz[m] != this->context->overrideFreqs[m]) {
std::string displayText = FREQ_DEFAULT_TEXT;
std::uint32_t currentValue = this->context->overrideFreqs[m];
std::vector<NamedValue> governorSettings = {
NamedValue("Do Not Override", GovernorState_DoNotOverride),
NamedValue("Disabled", GovernorState_Disabled),
NamedValue("CPU + GPU", GovernorState_Enabled_CpuGpu),
NamedValue("CPU", GovernorState_Enabled_Cpu),
NamedValue("GPU", GovernorState_Enabled_Gpu),
};
for (const auto& setting : governorSettings) {
if (setting.value == currentValue) {
displayText = setting.name;
break;
}
}
this->listItems[m]->setValue(displayText);
this->listHz[m] = currentValue;
}
continue;
}

View File

@@ -1,4 +1,5 @@
/*
*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
@@ -23,10 +24,7 @@
* stuff is worth it, you can buy us a beer in return. - The sys-clk authors
* --------------------------------------------------------------------------
*/
#pragma once
#include "../../ipc.h"
#include "base_menu_gui.h"
#include "freq_choice_gui.h"
@@ -63,7 +61,9 @@ class GlobalOverrideGui : public BaseMenuGui
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds = {}
ValueThresholds thresholds = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true
);
public:
GlobalOverrideGui();
@@ -71,4 +71,4 @@ class GlobalOverrideGui : public BaseMenuGui
void listUI() override;
void refresh() override;
void setModuleCustomFormat(SysClkModule module, const std::string& suffix, std::uint32_t divisor, int decimalPlaces);
};
};

View File

@@ -47,7 +47,7 @@ std::map<uint32_t, std::string> gpu_freq_label_e = {
{768000000, "Docked"},
{921600000, "Safe Max"},
{960000000, "Unsafe Max"},
{1075200000, "Aboslute Max"},
{1075200000, "Absolute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_m = {
@@ -59,5 +59,6 @@ std::map<uint32_t, std::string> gpu_freq_label_m = {
{768000000, "Docked"},
{1075200000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Aboslute Max"},
};
{1536000000, "Absolute Max"},
};

View File

@@ -239,21 +239,17 @@ void MiscGui::addFreqButton(SysClkConfigValue configVal,
void MiscGui::listUI()
{
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> noNamedValues = {};
this->listElement->addItem(new tsl::elm::CategoryHeader("Settings"));
Result rc = sysclkIpcGetConfigValues(configList);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader("Safety 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 +277,6 @@ void MiscGui::listUI()
);
}
ValueThresholds throttleThresholds(70, 80);
addConfigButton(
HocClkConfigValue_ThermalThrottleThreshold,
@@ -292,10 +287,65 @@ void MiscGui::listUI()
);
#endif
if(IsMariko()) {
addFreqButton(HocClkConfigValue_MarikoMaxCpuClock, nullptr, SysClkModule_CPU, cpu_freq_label_m);
} else {
addFreqButton(HocClkConfigValue_EristaMaxCpuClock, nullptr, SysClkModule_CPU, cpu_freq_label_e);
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> noNamedValues = {};
this->listElement->addItem(new tsl::elm::CategoryHeader("CPU Settings"));
addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr);
std::vector<NamedValue> gpuSchedValues = {
NamedValue("Do not override", GpuSchedulingMode_DoNotOverride),
NamedValue("Enabled (Default)", GpuSchedulingMode_Enabled, "96.6% limit"),
NamedValue("Disabled", GpuSchedulingMode_Disabled, "99.7% limit"),
};
this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Settings"));
addConfigButton(
HorizonOCConfigValue_GPUScheduling,
"GPU Scheduling Override",
ValueRange(0, 0, 1, "", 0),
"GPU Scheduling Override",
&thresholdsDisabled,
{},
gpuSchedValues,
false
);
if (IsMariko()) {
std::vector<NamedValue> dvfsValues = {
NamedValue("Disabled", DVFSMode_Disabled),
NamedValue("PCV Hijack", DVFSMode_Hijack),
// NamedValue("Official Service", DVFSMode_OfficialService),
// NamedValue("Hack", DVFSMode_Hack),
};
addConfigButton(
HorizonOCConfigValue_DVFSMode,
"GPU DVFS Mode",
ValueRange(0, 0, 1, "", 0),
"GPU DVFS Mode",
&thresholdsDisabled,
{},
dvfsValues,
false
);
std::vector<NamedValue> dvfsOffset = {
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);
}
this->listElement->addItem(new tsl::elm::CategoryHeader("KIP"));
@@ -343,22 +393,43 @@ void MiscGui::listUI()
return false;
});
this->listElement->addItem(gpuSubmenu);
if(!IsHoag()) {
this->listElement->addItem(new tsl::elm::CategoryHeader("Display"));
addConfigToggle(HorizonOCConfigValue_OverwriteRefreshRate, nullptr);
addConfigToggle(HorizonOCConfigValue_EnableUnsafeDisplayFreqs, nullptr);
}
#if IS_MINIMAL == 0
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
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),
};
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),
// };
if(this->configList->values[HorizonOCConfigValue_EnableExperimentalSettings]) {
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
addConfigToggle(HorizonOCConfigValue_LiveCpuUv, nullptr);
std::vector<NamedValue> gpuSchedMethodValues = {
NamedValue("INI", GpuSchedulingOverrideMethod_Ini),
NamedValue("NV Service", GpuSchedulingOverrideMethod_NvService),
};
addConfigButton(
HorizonOCConfigValue_GPUSchedulingMethod,
"GPU Scheduling Override Method",
ValueRange(0, 0, 1, "", 0),
"GPU Scheduling Override Method",
&thresholdsDisabled,
{},
gpuSchedMethodValues,
false
);
std::vector<NamedValue> chargerCurrents = {
NamedValue("Disabled", 0),
NamedValue("1024mA", 1024),
@@ -370,9 +441,14 @@ void MiscGui::listUI()
NamedValue("2560mA", 2560),
NamedValue("2816mA", 2816),
NamedValue("3072mA", 3072),
NamedValue("3328mA", 3328),
NamedValue("3840mA", 3840),
NamedValue("4096mA", 4096),
NamedValue("4352mA", 4352),
NamedValue("4608mA", 4608),
};
ValueThresholds chargerThresholds(2048, 2560);
ValueThresholds chargerThresholds(2048, 2049);
addConfigButton(
HorizonOCConfigValue_BatteryChargeCurrent,
@@ -384,44 +460,8 @@ void MiscGui::listUI()
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);
renderer->drawString("refresh rates may cause stress", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
renderer->drawString("or damage to your display! ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
});
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
);
}
#endif
}
@@ -494,12 +534,12 @@ protected:
NamedValue("3233MHz", 3233000, "High speedo needed!"),
NamedValue("3266MHz", 3266000, "High speedo needed!"),
NamedValue("3300MHz", 3300000, "High speedo needed!"),
// NamedValue("3333MHz (Needs extreme Speedo/PLL)", 3333000),
// NamedValue("3366MHz (Needs extreme Speedo/PLL)", 3366000),
// NamedValue("3400MHz (Needs extreme Speedo/PLL)", 3400000),
// NamedValue("3433MHz (Needs ridiculous Speedo/PLL)", 3433000),
// NamedValue("3466MHz (Needs ridiculous Speedo/PLL)", 3466000),
// NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000),
NamedValue("3333MHz", 3333000, "High speedo needed!"),
NamedValue("3366MHz", 3366000, "High speedo needed!"),
NamedValue("3400MHz", 3400000, "High speedo needed!"),
NamedValue("3433MHz", 3433000, "High speedo needed!"),
NamedValue("3466MHz", 3466000, "High speedo needed!"),
NamedValue("3500MHz", 3500000, "High speedo needed!"),
};
std::vector<NamedValue> eristaMaxEmcClock = {
@@ -540,19 +580,27 @@ protected:
NamedValue("2361MHz", 2361600),
NamedValue("2380MHz", 2380800),
NamedValue("2400MHz", 2400000, "JEDEC."),
NamedValue("2423MHz", 2423200),
NamedValue("2442MHz", 2442400),
NamedValue("2461MHz", 2461600),
NamedValue("2480MHz", 2480800),
NamedValue("2500MHz", 2500000),
NamedValue("2523MHz", 2523200),
NamedValue("2542MHz", 2542400),
NamedValue("2561MHz", 2561600),
NamedValue("2580MHz", 2580800),
NamedValue("2600MHz", 2600000),
NamedValue("2623MHz", 2623200),
NamedValue("2642MHz", 2642400),
NamedValue("2661MHz", 2661600),
NamedValue("2680MHz", 2680800),
NamedValue("2700MHz", 2700000),
};
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,
@@ -579,7 +627,7 @@ protected:
addConfigButton(
KipConfigValue_commonEmcMemVolt,
"RAM VDD2 Voltage",
ValueRange(912500, 1350000, 12500, "mV", 1000, 1),
ValueRange(912500, 1500000, 12500, "mV", 1000, 1),
"Voltage",
&vdd2Thresholds,
emc_voltage_label,
@@ -591,7 +639,7 @@ protected:
addConfigButton(
KipConfigValue_marikoEmcVddqVolt,
"RAM VDDQ Voltage",
ValueRange(550000, 700000, 5000, "mV", 1000),
ValueRange(400000, 1500000, 5000, "mV", 1000),
"RAM VDDQ Voltage",
&thresholdsDisabled,
{},
@@ -652,6 +700,14 @@ protected:
addConfigButton(KipConfigValue_t7_tWTR, "t7 tWTR", ValueRange(0, 10, 1, "", 1), "tWTR", &thresholdsDisabled, {}, {}, false);
addConfigButton(KipConfigValue_t8_tREFI, "t8 tREFI", ValueRange(0, 6, 1, "", 1), "tREFI", &thresholdsDisabled, {}, {}, false);
std::vector<NamedValue> t6_tRTW_fine_tune = {
NamedValue("-2", 0xFFFFFFFE),
NamedValue("-1", 0xFFFFFFFF),
NamedValue(" 0", 0),
NamedValue("+1", 1),
NamedValue("+2", 2),
};
std::vector<NamedValue> t7_tWTR_fine_tune = {
NamedValue("-3", 0xFFFFFFFD),
NamedValue("-2", 0xFFFFFFFE),
@@ -663,38 +719,8 @@ protected:
};
this->listElement->addItem(new tsl::elm::CategoryHeader("Advanced"));
addConfigButton(KipConfigValue_t7_tWTR_fine_tune, "t7 tWTR Fine Tune", ValueRange(0, 6, 1, "", 0), "t7 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
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);
}
};
@@ -757,8 +783,6 @@ protected:
this->listElement->addItem(new tsl::elm::CategoryHeader("CPU Settings"));
if(IsMariko()) {
std::vector<NamedValue> ClkOptions = {
NamedValue("1785 MHz", 1785000),
NamedValue("1887 MHz", 1887000),
NamedValue("1963 MHz", 1963000),
NamedValue("2091 MHz", 2091000),
NamedValue("2193 MHz", 2193000),
@@ -787,6 +811,10 @@ protected:
NamedValue("2091 MHz", 2091000),
NamedValue("2193 MHz", 2193000),
NamedValue("2295 MHz", 2295000),
NamedValue("2397 MHz", 2797000),
NamedValue("2499 MHz", 2499000),
NamedValue("2601 MHz", 2601000),
NamedValue("2703 MHz", 2703000),
};
ValueThresholds eCpuClockThresholds(1785000, 2091000);
addConfigButton(
@@ -826,7 +854,7 @@ protected:
addConfigButton(
KipConfigValue_eristaCpuMaxVolt,
"CPU Max Voltage",
ValueRange(1120, 1235, 5, "mV", 1),
ValueRange(1120, 1525, 5, "mV", 1),
"CPU Max Voltage",
&thresholdsDisabled,
{},
@@ -884,6 +912,9 @@ protected:
NamedValue("2499 MHz", 2499000),
NamedValue("2601 MHz", 2601000),
NamedValue("2703 MHz", 2703000),
NamedValue("2805 MHz", 2805000),
NamedValue("2907 MHz", 2907000),
NamedValue("3009 MHz", 3009000),
};
ValueThresholds mCpuMaxClockThresholds(1963000, 2397000);
addConfigButton(
@@ -923,7 +954,7 @@ protected:
addConfigButton(
KipConfigValue_marikoCpuMaxVolt,
"CPU Max Voltage",
ValueRange(1000, 1235, 5, "mV", 1),
ValueRange(1000, 1525, 5, "mV", 1),
"CPU Max Voltage",
&mCpuVoltThresholds,
{},
@@ -952,7 +983,7 @@ protected:
};
std::vector<NamedValue> mGpuVoltsVmin = {
NamedValue("Auto", 0), NamedValue("Auto (RAM)", 1),
NamedValue("Auto", 0),
NamedValue("480mV", 480), NamedValue("485mV", 485), NamedValue("490mV", 490),
NamedValue("495mV", 495), NamedValue("500mV", 500), NamedValue("505mV", 505),
NamedValue("510mV", 510), NamedValue("515mV", 515), NamedValue("520mV", 520),
@@ -1028,7 +1059,7 @@ protected:
addConfigButton(
KipConfigValue_marikoGpuVmax,
"GPU Maximum Voltage",
ValueRange(750, 960, 5, "mV", 1),
ValueRange(750, 1525, 5, "mV", 1),
"GPU Maximum Voltage",
&MgpuVmaxThresholds,
{},
@@ -1113,32 +1144,67 @@ protected:
NamedValue("915mV", 915), NamedValue("920mV", 920), NamedValue("925mV", 925),
NamedValue("930mV", 930), NamedValue("935mV", 935), NamedValue("940mV", 940),
NamedValue("945mV", 945), NamedValue("950mV", 950), NamedValue("955mV", 955),
NamedValue("960mV", 960),
NamedValue("960mV", 960), NamedValue("965mV", 965), NamedValue("970mV", 970),
NamedValue("975mV", 975), NamedValue("980mV", 980), NamedValue("985mV", 985),
NamedValue("990mV", 990), NamedValue("995mV", 995), NamedValue("1000mV", 1000),
NamedValue("1005mV", 1005), NamedValue("1010mV", 1010), NamedValue("1015mV", 1015),
NamedValue("1020mV", 1020), NamedValue("1025mV", 1025), NamedValue("1030mV", 1030),
NamedValue("1035mV", 1035), NamedValue("1040mV", 1040), NamedValue("1045mV", 1045),
NamedValue("1050mV", 1050), NamedValue("1055mV", 1055), NamedValue("1060mV", 1060),
NamedValue("1065mV", 1065), NamedValue("1070mV", 1070), NamedValue("1075mV", 1075),
NamedValue("1080mV", 1080), NamedValue("1085mV", 1085), NamedValue("1090mV", 1090),
NamedValue("1095mV", 1095), NamedValue("1100mV", 1100), NamedValue("1105mV", 1105),
NamedValue("1110mV", 1110), NamedValue("1115mV", 1115), NamedValue("1120mV", 1120),
NamedValue("1125mV", 1125), NamedValue("1130mV", 1130)
};
std::vector<NamedValue> eGpuVolts = {
NamedValue("Disabled", 2000),
NamedValue("Auto", 0),
NamedValue("700mV", 700), NamedValue("705mV", 705), NamedValue("710mV", 710),
NamedValue("715mV", 715), NamedValue("720mV", 720), NamedValue("725mV", 725),
NamedValue("730mV", 730), NamedValue("735mV", 735), NamedValue("740mV", 740),
NamedValue("745mV", 745), NamedValue("750mV", 750), NamedValue("755mV", 755),
NamedValue("760mV", 760), NamedValue("765mV", 765), NamedValue("770mV", 770),
NamedValue("775mV", 775), NamedValue("780mV", 780), NamedValue("785mV", 785),
NamedValue("790mV", 790), NamedValue("795mV", 795), NamedValue("800mV", 800),
NamedValue("805mV", 805), NamedValue("810mV", 810), NamedValue("815mV", 815),
NamedValue("820mV", 820), NamedValue("825mV", 825), NamedValue("830mV", 830),
NamedValue("835mV", 835), NamedValue("840mV", 840), NamedValue("845mV", 845),
NamedValue("850mV", 850), NamedValue("855mV", 855), NamedValue("860mV", 860),
NamedValue("865mV", 865), NamedValue("870mV", 870), NamedValue("875mV", 875),
NamedValue("880mV", 880), NamedValue("885mV", 885), NamedValue("890mV", 890),
NamedValue("895mV", 895), NamedValue("900mV", 900), NamedValue("905mV", 905),
NamedValue("910mV", 910), NamedValue("915mV", 915), NamedValue("920mV", 920),
NamedValue("925mV", 925), NamedValue("930mV", 930), NamedValue("935mV", 935),
NamedValue("940mV", 940), NamedValue("945mV", 945), NamedValue("950mV", 950),
NamedValue("955mV", 955), NamedValue("960mV", 960), NamedValue("965mV", 965),
NamedValue("970mV", 970), NamedValue("975mV", 975), NamedValue("980mV", 980),
NamedValue("985mV", 985), NamedValue("990mV", 990), NamedValue("995mV", 995),
NamedValue("480mV", 480), NamedValue("485mV", 485), NamedValue("490mV", 490),
NamedValue("495mV", 495), NamedValue("500mV", 500), NamedValue("505mV", 505),
NamedValue("510mV", 510), NamedValue("515mV", 515), NamedValue("520mV", 520),
NamedValue("525mV", 525), NamedValue("530mV", 530), NamedValue("535mV", 535),
NamedValue("540mV", 540), NamedValue("545mV", 545), NamedValue("550mV", 550),
NamedValue("555mV", 555), NamedValue("560mV", 560), NamedValue("565mV", 565),
NamedValue("570mV", 570), NamedValue("575mV", 575), NamedValue("580mV", 580),
NamedValue("585mV", 585), NamedValue("590mV", 590), NamedValue("595mV", 595),
NamedValue("600mV", 600), NamedValue("605mV", 605), NamedValue("610mV", 610),
NamedValue("615mV", 615), NamedValue("620mV", 620), NamedValue("625mV", 625),
NamedValue("630mV", 630), NamedValue("635mV", 635), NamedValue("640mV", 640),
NamedValue("645mV", 645), NamedValue("650mV", 650), NamedValue("655mV", 655),
NamedValue("660mV", 660), NamedValue("665mV", 665), NamedValue("670mV", 670),
NamedValue("675mV", 675), NamedValue("680mV", 680), NamedValue("685mV", 685),
NamedValue("690mV", 690), NamedValue("695mV", 695), NamedValue("700mV", 700),
NamedValue("705mV", 705), NamedValue("710mV", 710), NamedValue("715mV", 715),
NamedValue("720mV", 720), NamedValue("725mV", 725), NamedValue("730mV", 730),
NamedValue("735mV", 735), NamedValue("740mV", 740), NamedValue("745mV", 745),
NamedValue("750mV", 750), NamedValue("755mV", 755), NamedValue("760mV", 760),
NamedValue("765mV", 765), NamedValue("770mV", 770), NamedValue("775mV", 775),
NamedValue("780mV", 780), NamedValue("785mV", 785), NamedValue("790mV", 790),
NamedValue("795mV", 795), NamedValue("800mV", 800), NamedValue("805mV", 805),
NamedValue("810mV", 810), NamedValue("815mV", 815), NamedValue("820mV", 820),
NamedValue("825mV", 825), NamedValue("830mV", 830), NamedValue("835mV", 835),
NamedValue("840mV", 840), NamedValue("845mV", 845), NamedValue("850mV", 850),
NamedValue("855mV", 855), NamedValue("860mV", 860), NamedValue("865mV", 865),
NamedValue("870mV", 870), NamedValue("875mV", 875), NamedValue("880mV", 880),
NamedValue("885mV", 885), NamedValue("890mV", 890), NamedValue("895mV", 895),
NamedValue("900mV", 900), NamedValue("905mV", 905), NamedValue("910mV", 910),
NamedValue("915mV", 915), NamedValue("920mV", 920), NamedValue("925mV", 925),
NamedValue("930mV", 930), NamedValue("935mV", 935), NamedValue("940mV", 940),
NamedValue("945mV", 945), NamedValue("950mV", 950), NamedValue("955mV", 955),
NamedValue("960mV", 960), NamedValue("965mV", 965), NamedValue("970mV", 970),
NamedValue("975mV", 975), NamedValue("980mV", 980), NamedValue("985mV", 985),
NamedValue("990mV", 990), NamedValue("995mV", 995), NamedValue("1000mV", 1000),
NamedValue("1005mV", 1005), NamedValue("1010mV", 1010), NamedValue("1015mV", 1015),
NamedValue("1020mV", 1020), NamedValue("1025mV", 1025), NamedValue("1030mV", 1030),
NamedValue("1035mV", 1035), NamedValue("1040mV", 1040), NamedValue("1045mV", 1045),
NamedValue("1050mV", 1050), NamedValue("1055mV", 1055), NamedValue("1060mV", 1060),
NamedValue("1065mV", 1065), NamedValue("1070mV", 1070), NamedValue("1075mV", 1075),
NamedValue("1080mV", 1080), NamedValue("1085mV", 1085), NamedValue("1090mV", 1090),
NamedValue("1095mV", 1095), NamedValue("1100mV", 1100), NamedValue("1105mV", 1105),
NamedValue("1110mV", 1110), NamedValue("1115mV", 1115), NamedValue("1120mV", 1120),
NamedValue("1125mV", 1125), NamedValue("1130mV", 1130)
};
std::vector<NamedValue> mGpuVolts_noAuto = {
@@ -1175,45 +1241,69 @@ protected:
NamedValue("915mV", 915), NamedValue("920mV", 920), NamedValue("925mV", 925),
NamedValue("930mV", 930), NamedValue("935mV", 935), NamedValue("940mV", 940),
NamedValue("945mV", 945), NamedValue("950mV", 950), NamedValue("955mV", 955),
NamedValue("960mV", 960),
NamedValue("960mV", 960), NamedValue("965mV", 965), NamedValue("970mV", 970),
NamedValue("975mV", 975), NamedValue("980mV", 980), NamedValue("985mV", 985),
NamedValue("990mV", 990), NamedValue("995mV", 995), NamedValue("1000mV", 1000),
NamedValue("1005mV", 1005), NamedValue("1010mV", 1010), NamedValue("1015mV", 1015),
NamedValue("1020mV", 1020), NamedValue("1025mV", 1025), NamedValue("1030mV", 1030),
NamedValue("1035mV", 1035), NamedValue("1040mV", 1040), NamedValue("1045mV", 1045),
NamedValue("1050mV", 1050), NamedValue("1055mV", 1055), NamedValue("1060mV", 1060),
NamedValue("1065mV", 1065), NamedValue("1070mV", 1070), NamedValue("1075mV", 1075),
NamedValue("1080mV", 1080), NamedValue("1085mV", 1085), NamedValue("1090mV", 1090),
NamedValue("1095mV", 1095), NamedValue("1100mV", 1100), NamedValue("1105mV", 1105),
NamedValue("1110mV", 1110), NamedValue("1115mV", 1115), NamedValue("1120mV", 1120),
NamedValue("1125mV", 1125), NamedValue("1130mV", 1130)
};
std::vector<NamedValue> eGpuVolts_noAuto = {
NamedValue("Disabled", 2000),
NamedValue("700mV", 700), NamedValue("705mV", 705), NamedValue("710mV", 710),
NamedValue("715mV", 715), NamedValue("720mV", 720), NamedValue("725mV", 725),
NamedValue("730mV", 730), NamedValue("735mV", 735), NamedValue("740mV", 740),
NamedValue("745mV", 745), NamedValue("750mV", 750), NamedValue("755mV", 755),
NamedValue("760mV", 760), NamedValue("765mV", 765), NamedValue("770mV", 770),
NamedValue("775mV", 775), NamedValue("780mV", 780), NamedValue("785mV", 785),
NamedValue("790mV", 790), NamedValue("795mV", 795), NamedValue("800mV", 800),
NamedValue("805mV", 805), NamedValue("810mV", 810), NamedValue("815mV", 815),
NamedValue("820mV", 820), NamedValue("825mV", 825), NamedValue("830mV", 830),
NamedValue("835mV", 835), NamedValue("840mV", 840), NamedValue("845mV", 845),
NamedValue("850mV", 850), NamedValue("855mV", 855), NamedValue("860mV", 860),
NamedValue("865mV", 865), NamedValue("870mV", 870), NamedValue("875mV", 875),
NamedValue("880mV", 880), NamedValue("885mV", 885), NamedValue("890mV", 890),
NamedValue("895mV", 895), NamedValue("900mV", 900), NamedValue("905mV", 905),
NamedValue("910mV", 910), NamedValue("915mV", 915), NamedValue("920mV", 920),
NamedValue("925mV", 925), NamedValue("930mV", 930), NamedValue("935mV", 935),
NamedValue("940mV", 940), NamedValue("945mV", 945), NamedValue("950mV", 950),
NamedValue("955mV", 955), NamedValue("960mV", 960), NamedValue("965mV", 965),
NamedValue("970mV", 970), NamedValue("975mV", 975), NamedValue("980mV", 980),
NamedValue("985mV", 985), NamedValue("990mV", 990), NamedValue("995mV", 995),
NamedValue("480mV", 480), NamedValue("485mV", 485), NamedValue("490mV", 490),
NamedValue("495mV", 495), NamedValue("500mV", 500), NamedValue("505mV", 505),
NamedValue("510mV", 510), NamedValue("515mV", 515), NamedValue("520mV", 520),
NamedValue("525mV", 525), NamedValue("530mV", 530), NamedValue("535mV", 535),
NamedValue("540mV", 540), NamedValue("545mV", 545), NamedValue("550mV", 550),
NamedValue("555mV", 555), NamedValue("560mV", 560), NamedValue("565mV", 565),
NamedValue("570mV", 570), NamedValue("575mV", 575), NamedValue("580mV", 580),
NamedValue("585mV", 585), NamedValue("590mV", 590), NamedValue("595mV", 595),
NamedValue("600mV", 600), NamedValue("605mV", 605), NamedValue("610mV", 610),
NamedValue("615mV", 615), NamedValue("620mV", 620), NamedValue("625mV", 625),
NamedValue("630mV", 630), NamedValue("635mV", 635), NamedValue("640mV", 640),
NamedValue("645mV", 645), NamedValue("650mV", 650), NamedValue("655mV", 655),
NamedValue("660mV", 660), NamedValue("665mV", 665), NamedValue("670mV", 670),
NamedValue("675mV", 675), NamedValue("680mV", 680), NamedValue("685mV", 685),
NamedValue("690mV", 690), NamedValue("695mV", 695), NamedValue("700mV", 700),
NamedValue("705mV", 705), NamedValue("710mV", 710), NamedValue("715mV", 715),
NamedValue("720mV", 720), NamedValue("725mV", 725), NamedValue("730mV", 730),
NamedValue("735mV", 735), NamedValue("740mV", 740), NamedValue("745mV", 745),
NamedValue("750mV", 750), NamedValue("755mV", 755), NamedValue("760mV", 760),
NamedValue("765mV", 765), NamedValue("770mV", 770), NamedValue("775mV", 775),
NamedValue("780mV", 780), NamedValue("785mV", 785), NamedValue("790mV", 790),
NamedValue("795mV", 795), NamedValue("800mV", 800), NamedValue("805mV", 805),
NamedValue("810mV", 810), NamedValue("815mV", 815), NamedValue("820mV", 820),
NamedValue("825mV", 825), NamedValue("830mV", 830), NamedValue("835mV", 835),
NamedValue("840mV", 840), NamedValue("845mV", 845), NamedValue("850mV", 850),
NamedValue("855mV", 855), NamedValue("860mV", 860), NamedValue("865mV", 865),
NamedValue("870mV", 870), NamedValue("875mV", 875), NamedValue("880mV", 880),
NamedValue("885mV", 885), NamedValue("890mV", 890), NamedValue("895mV", 895),
NamedValue("900mV", 900), NamedValue("905mV", 905), NamedValue("910mV", 910),
NamedValue("915mV", 915), NamedValue("920mV", 920), NamedValue("925mV", 925),
NamedValue("930mV", 930), NamedValue("935mV", 935), NamedValue("940mV", 940),
NamedValue("945mV", 945), NamedValue("950mV", 950), NamedValue("955mV", 955),
NamedValue("960mV", 960), NamedValue("965mV", 965), NamedValue("970mV", 970),
NamedValue("975mV", 975), NamedValue("980mV", 980), NamedValue("985mV", 985),
NamedValue("990mV", 990), NamedValue("995mV", 995), NamedValue("1000mV", 1000),
NamedValue("1005mV", 1005), NamedValue("1010mV", 1010), NamedValue("1015mV", 1015),
NamedValue("1020mV", 1020), NamedValue("1025mV", 1025), NamedValue("1030mV", 1030),
NamedValue("1035mV", 1035), NamedValue("1040mV", 1040), NamedValue("1045mV", 1045),
NamedValue("1050mV", 1050), NamedValue("1055mV", 1055), NamedValue("1060mV", 1060),
NamedValue("1065mV", 1065), NamedValue("1070mV", 1070), NamedValue("1075mV", 1075),
NamedValue("1080mV", 1080), NamedValue("1085mV", 1085), NamedValue("1090mV", 1090),
NamedValue("1095mV", 1095), NamedValue("1100mV", 1100), NamedValue("1105mV", 1105),
NamedValue("1110mV", 1110), NamedValue("1115mV", 1115), NamedValue("1120mV", 1120),
NamedValue("1125mV", 1125), NamedValue("1130mV", 1130)
};
if (IsMariko()) {
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Setting GPU Clocks past", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("1075MHz without UV, 1152MHz on SLT", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
renderer->drawString("or 1228MHz on HiOPT can cause ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
renderer->drawString("permanent damage to your Switch!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 110, 18, tsl::style::color::ColorText);
});
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 130);
this->listElement->addItem(warningText);
addConfigButton(KipConfigValue_g_volt_76800, "76.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_153600, "153.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_230400, "230.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
@@ -1228,62 +1318,49 @@ protected:
addConfigButton(KipConfigValue_g_volt_921600, "921.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
if(this->configList->values[KipConfigValue_marikoGpuUV] >= GPUUVLevel_SLT)
addConfigButton(KipConfigValue_g_volt_1152000, "1152.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
if(this->configList->values[KipConfigValue_marikoGpuUV] >= GPUUVLevel_HiOPT) {
addConfigButton(KipConfigValue_g_volt_1228800, "1228.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1267200, "1267.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1305600, "1305.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1344000, "1344.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1382400, "1382.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1420800, "1420.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1459200, "1459.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1497600, "1497.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1536000, "1536.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
}
addConfigButton(KipConfigValue_g_volt_1152000, "1152.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1228800, "1228.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1267200, "1267.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1305600, "1305.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_1344000, "1344.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1382400, "1382.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1420800, "1420.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1459200, "1459.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1497600, "1497.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1536000, "1536.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1574400, "1574.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1612800, "1612.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1651200, "1651.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1689600, "1689.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1728000, "1728.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1766400, "1766.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_1804800, "1804.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
} else {
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Setting GPU Clocks past", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
renderer->drawString("921MHz without UV and 960MHz on", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
renderer->drawString("SLT or HiOPT can cause ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
renderer->drawString("permanent damage to your Switch!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 110, 18, tsl::style::color::ColorText);
});
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 130);
this->listElement->addItem(warningText);
addConfigButton(KipConfigValue_g_volt_e_76800, "76.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_115200, "115.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_153600, "153.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_192000, "192.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_230400, "230.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_268800, "268.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_307200, "307.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_345600, "345.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_384000, "384.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_422400, "422.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_460800, "460.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_499200, "499.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_537600, "537.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_576000, "576.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_614400, "614.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_652800, "652.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_691200, "691.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_729600, "729.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_768000, "768.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_806400, "806.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_844800, "844.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_883200, "883.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_921600, "921.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
if(this->configList->values[KipConfigValue_eristaGpuUV] >= GPUUVLevel_SLT)
addConfigButton(KipConfigValue_g_volt_e_960000, "960.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
if(this->configList->values[KipConfigValue_eristaGpuUV] >= GPUUVLevel_HiOPT) {
addConfigButton(KipConfigValue_g_volt_e_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_1036800, "1036.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
}
addConfigButton(KipConfigValue_g_volt_e_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false);
addConfigButton(KipConfigValue_g_volt_e_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1152000, "1152.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1228800, "1228.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1267200, "1267.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1305600, "1305.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1344000, "1344.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1382400, "1382.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1420800, "1420.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1459200, "1459.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1497600, "1497.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
addConfigButton(KipConfigValue_g_volt_e_1536000, "1536.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts_noAuto, false);
}
}
};

View File

@@ -30,7 +30,8 @@ ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
bool enableThresholds,
std::map<std::uint32_t, std::string> labels,
std::vector<NamedValue> namedValues,
bool showDefaultValue)
bool showDefaultValue,
bool showDNO)
: selectedValue(selectedValue),
range(range),
categoryName(categoryName),
@@ -39,7 +40,8 @@ ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
enableThresholds(enableThresholds),
labels(labels),
namedValues(namedValues),
showDefaultValue(showDefaultValue)
showDefaultValue(showDefaultValue),
showDNO(showDNO)
{
}
@@ -52,7 +54,7 @@ std::string ValueChoiceGui::formatValue(std::uint32_t value)
std::ostringstream oss;
if(showDefaultValue) {
if (value == 0) {
return VALUE_DEFAULT_TEXT;
return this->showDNO ? FREQ_DEFAULT_TEXT : VALUE_DEFAULT_TEXT;
}
}
double displayValue = static_cast<double>(value) / static_cast<double>(range.divisor);
@@ -164,17 +166,16 @@ void ValueChoiceGui::listUI()
if (!categoryName.empty()) {
this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName));
}
if (showDefaultValue) {
this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
}
for (const auto& namedValue : namedValues) {
int safety = enableThresholds ? getSafetyLevel(namedValue.value) : 0;
bool selected = (namedValue.value == this->selectedValue);
this->listElement->addItem(this->createNamedValueListItem(namedValue, selected, safety));
}
if (showDefaultValue) {
this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
}
if (namedValues.empty()) {
for (std::uint32_t value = range.min; value <= range.max; value += range.step)
{

View File

@@ -71,7 +71,7 @@ protected:
std::vector<NamedValue> namedValues;
bool showDefaultValue = true;
bool showDNO = false;
tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety);
tsl::elm::ListItem* createNamedValueListItem(const NamedValue& namedValue, bool selected, int safety);
std::string formatValue(std::uint32_t value);
@@ -86,7 +86,8 @@ public:
bool enableThresholds = false,
std::map<std::uint32_t, std::string> labels = {},
std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true);
bool showDefaultValue = true,
bool showDNO = false);
~ValueChoiceGui();
void addNamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "")

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
}
@@ -57,6 +57,15 @@
"is_io": true
}
},
{
"type": "map",
"value": {
"address": "0x70110000",
"size": "0x1000",
"is_ro": false,
"is_io": true
}
},
{
"type": "syscalls",
"value": {

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>
@@ -41,6 +41,8 @@
#include <cstring>
#include <registers.h>
#include <notification.h>
#include <memmem.h>
#include <minIni.h>
#define MAX(A, B) std::max(A, B)
#define MIN(A, B) std::min(A, B)
@@ -64,12 +66,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;
@@ -84,20 +90,37 @@ 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;
u16 cpuIDDQ, gpuIDDQ, socIDDQ;
u8 g_dramID = 0;
u64 cldvfs, cldvfs_temp;
u32 cachedEristaUvLowTune0 = 0, cachedEristaUvLowTune1 = 0, cachedMarikoUvHighTune0 = 0;
static const u32 ramBrackets[][22] = {
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, },
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, },
{ 2433, 2466, 2533, 2600, 2666, 2733, 2766, 2800, 2833, 2866, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3300, 3333, 3366, },
{ 2500, 2533, 2600, 2633, 2666, 2733, 2800, 2866, 2900, 2966, 3033, 3100, 3166, 3200, 3233, 3266, 3300, 3333, 3366, 3400, 3400, 3400, },
};
static const u32 gpuDvfsArray[] = { 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800};
u32 dvfsTable[6][32] = {};
u64 dvfsAddress;
u32 ramVmin;
const char* Board::GetModuleName(SysClkModule module, bool pretty)
{
@@ -149,16 +172,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*) {
@@ -190,7 +213,6 @@ void miscThreadFunc(void*) {
}
}
void Board::Initialize()
{
Result rc = 0;
@@ -222,8 +244,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");
@@ -238,17 +263,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();
@@ -268,6 +293,16 @@ void Board::Initialize()
}
FetchHardwareInfos();
rc = svcQueryMemoryMapping(&cldvfs, &cldvfs_temp, CLDVFS_REGION_BASE, CLDVFS_REGION_SIZE);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (cldvfs)");
if(Board::GetSocType() == SysClkSocType_Erista) {
cachedEristaUvLowTune0 = *(u32*)(cldvfs + CL_DVFS_TUNE0_0);
cachedEristaUvLowTune1 = *(u32*)(cldvfs + CL_DVFS_TUNE1_0);
} else {
Board::SetHz(SysClkModule_CPU, 1785000000);
cachedMarikoUvHighTune0 = *(u32*)(cldvfs + CL_DVFS_TUNE0_0);
Board::ResetToStockCpu();
}
}
void Board::fuseReadSpeedos() {
@@ -311,7 +346,7 @@ void Board::fuseReadSpeedos() {
cpuIDDQ = *reinterpret_cast<const u16*>(dump + FUSE_CPU_IDDQ_CALIB);
gpuIDDQ = *reinterpret_cast<const u16*>(dump + FUSE_SOC_IDDQ_CALIB);
socIDDQ = *reinterpret_cast<const u16*>(dump + FUSE_GPU_IDDQ_CALIB);
svcCloseHandle(debug);
return;
}
@@ -378,7 +413,7 @@ void Board::Exit()
threadClose(&cpuCore0Thread);
threadClose(&cpuCore1Thread);
threadClose(&cpuCore2Thread);
threadClose(&cpuCore3Thread);
// threadClose(&cpuCore3Thread);
threadClose(&miscThread);
pwmChannelSessionClose(&g_ICon);
@@ -386,6 +421,7 @@ void Board::Exit()
rgltrExit();
batteryInfoExit();
pmdmntExit();
nvExit();
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag)
DisplayRefresh_Shutdown();
}
@@ -421,7 +457,6 @@ SysClkProfile Board::GetProfile()
void Board::SetHz(SysClkModule module, std::uint32_t hz)
{
Result rc = 0;
if(module == HorizonOCModule_Display && Board::GetConsoleType() != HorizonOCConsoleType_Hoag) {
DisplayRefresh_SetRate(hz);
return;
@@ -436,13 +471,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(200'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(200'000);
rc = pcvSetClockRate(Board::GetPcvModule(module), hz);
ASSERT_RESULT_OK(rc, "pcvSetClockRate");
}
}
}
@@ -458,7 +502,7 @@ std::uint32_t Board::GetHz(SysClkModule module)
hz = 60;
return hz;
}
if(HOSSVC_HAS_CLKRST)
{
ClkrstSession session = {0};
@@ -690,14 +734,15 @@ void Board::ResetToStockGpu()
}
void Board::ResetToStockDisplay() {
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag)
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag) {
DisplayRefresh_SetRate(60);
}
}
u8 Board::GetHighestDockedDisplayRate() {
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag)
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag) {
return DisplayRefresh_GetDockedHighestAllowed();
else
} else
return 60;
}
@@ -752,8 +797,17 @@ 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)
{
case SysClkPartLoad_EMC:
@@ -762,8 +816,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;
@@ -792,6 +846,7 @@ u8 Board::GetDramID() {
void Board::FetchHardwareInfos()
{
fuseReadSpeedos();
SetSpeedoBracket();
u64 sku = 0, dramID = 0;
Result rc = splInitialize();
ASSERT_RESULT_OK(rc, "splInitialize");
@@ -801,7 +856,7 @@ void Board::FetchHardwareInfos()
rc = splGetConfig(SplConfigItem_DramId, &dramID);
ASSERT_RESULT_OK(rc, "splGetConfig");
splExit();
switch(sku)
@@ -816,9 +871,12 @@ void Board::FetchHardwareInfos()
g_socType = SysClkSocType_Erista;
}
if (g_socType == SysClkSocType_Mariko) {
CacheDvfsTable();
}
g_consoleType = (HorizonOCConsoleType)sku;
g_dramID = (u8)dramID;
}
/*
@@ -926,174 +984,338 @@ std::uint32_t Board::GetVoltage(HocClkVoltage voltage)
return out > 0 ? out : 0;
}
#define MC_REGISTER_BASE 0x70019000
#define MC_REGISTER_REGION_SIZE 0x1000
void Board::SetSpeedoBracket() {
if (cpuSpeedo2 >= 1754) {
speedoBracket = 3;
} else if (cpuSpeedo2 >= 1690) {
speedoBracket = 2;
} else if (cpuSpeedo2 > 1625) {
speedoBracket = 1;
} else {
speedoBracket = 0;
}
}
#define EMC_REGISTER_BASE 0x7001b000
#define EMC_REGISTER_REGION_SIZE 0x1000
u32 Board::GetMinimumGpuVoltage(u32 freqMhz) {
if (freqMhz <= 1600)
return 0;
#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));
for (u32 voltageIndex = 0; voltageIndex < 22; ++voltageIndex) {
if (freqMhz <= ramBrackets[speedoBracket][voltageIndex]) {
return gpuDvfsArray[voltageIndex];
}
}
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
return 800;
}
u32 tR2P = 12 + (rlAdd / 2);
u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
Handle Board::GetPcvHandle() {
constexpr u64 PcvID = 0x10000000000001a;
u64 processIDList[80]{};
s32 processCount = 0;
Handle handle = INVALID_HANDLE;
double tXSR = (double) (tRFCab + 7.5);
DebugEventInfo debugEvent{};
args = {};
args.X[0] = 0xF0000002;
args.X[1] = EMC_REGISTER_BASE + EMC_INTSTATUS_0;
svcCallSecureMonitor(&args);
/* Get all running processes. */
Result resultGetProcessList = svcGetProcessList(&processCount, processIDList, std::size(processIDList));
if (R_FAILED(resultGetProcessList)) {
return INVALID_HANDLE;
}
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");
/* Try to find pcv. */
for (int i = 0; i < processCount; ++i) {
if (handle != INVALID_HANDLE) {
svcCloseHandle(handle);
handle = INVALID_HANDLE;
}
/* Try to debug process, if it fails, try next process. */
Result resultSvcDebugProcess = svcDebugActiveProcess(&handle, processIDList[i]);
if (R_FAILED(resultSvcDebugProcess)) {
continue;
}
/* Try to get a debug event. */
Result resultDebugEvent = svcGetDebugEvent(&debugEvent, handle);
if (R_SUCCEEDED(resultDebugEvent)) {
if (debugEvent.info.create_process.program_id == PcvID) {
return handle;
}
}
}
/* Failed to get handle. */
return INVALID_HANDLE;
}
void Board::CacheDvfsTable() {
const u32 voltagePattern[] = { 600000, 12500, 1400000, };
Handle handle = GetPcvHandle();
if (handle == INVALID_HANDLE) {
FileUtils::LogLine("[Board] Invalid handle!");
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)));
MemoryInfo memoryInfo = {};
u64 address = 0;
u32 pageInfo = 0;
constexpr u32 PageSize = 0x1000;
u8 buffer[PageSize];
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);
/* Loop until failure. */
while (true) {
/* Find pcv heap. */
while (true) {
Result resultProcessMemory = svcQueryDebugProcessMemory(&memoryInfo, &pageInfo, handle, address);
address = memoryInfo.addr + memoryInfo.size;
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);
if (R_FAILED(resultProcessMemory) || !address) {
svcCloseHandle(handle);
FileUtils::LogLine("[Board] Failed to get process data. %u", R_DESCRIPTION(resultProcessMemory));
handle = INVALID_HANDLE;
return;
}
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);
if (memoryInfo.size && (memoryInfo.perm & 3) == 3 && static_cast<char>(memoryInfo.type) == 0x04) {
/* Found valid memory. */
break;
}
}
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);
for (u64 base = 0; base < memoryInfo.size; base += PageSize) {
u32 memorySize = std::min(memoryInfo.size, static_cast<u64>(PageSize));
if (R_FAILED(svcReadDebugProcessMemory(buffer, handle, base + memoryInfo.addr, memorySize))) {
break;
}
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);
u8 *resultPattern = static_cast<u8 *>(memmem_impl(buffer, sizeof(buffer), voltagePattern, sizeof(voltagePattern)));
u32 index = resultPattern - buffer;
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);
if (!resultPattern) {
continue;
}
/* Assuming mariko. */
const u32 vmax = 800;
constexpr u32 DvfsTableOffset = 312;
if (!std::memcmp(&buffer[index + DvfsTableOffset], &vmax, sizeof(vmax))) {
std::memcpy(dvfsTable, &buffer[index + DvfsTableOffset], sizeof(dvfsTable));
dvfsAddress = base + memoryInfo.addr + DvfsTableOffset + index;
}
svcCloseHandle(handle);
handle = INVALID_HANDLE;
return;
}
}
svcCloseHandle(handle);
handle = INVALID_HANDLE;
return;
}
void Board::PcvHijackDvfs(u32 vmin) {
u32 table[192];
static_assert(sizeof(table) == sizeof(dvfsTable));
std::memcpy(table, dvfsTable, sizeof(dvfsTable));
if (ramVmin == vmin) {
return;
}
for (u32 i = 0; i < std::size(table); ++i) {
if (table[i] && table[i] <= vmin) {
table[i] = vmin;
}
}
Handle handle = GetPcvHandle();
if (handle == INVALID_HANDLE) {
FileUtils::LogLine("Invalid handle!");
return;
}
Result rc = svcWriteDebugProcessMemory(handle, table, dvfsAddress, sizeof(table));
if (R_SUCCEEDED(rc)) {
ramVmin = vmin;
}
svcCloseHandle(handle);
FileUtils::LogLine("[dvfs] voltage set to %u mV", vmin);
}
bool Board::IsDram8GB() {
SecmonArgs args = {};
args.X[0] = 0xF0000002;
args.X[1] = MC_REGISTER_BASE + MC_EMEM_CFG_0;
svcCallSecureMonitor(&args);
SecmonArgs args = {};
args.X[0] = 0xF0000002;
args.X[1] = MC_REGISTER_BASE + MC_EMEM_CFG_0;
svcCallSecureMonitor(&args);
if(args.X[1] == (MC_REGISTER_BASE + MC_EMEM_CFG_0)) { // if param 1 is identical read failed
writeNotification("Horizon OC\nSecmon read failed!\n This may be a hardware issue!");
writeNotification("Horizon OC\nSecmon read failed!\n This may be a hardware issue!");
return false;
} else
return args.X[1] == 0x00002000 ? true : false;
}
void Board::SetGpuSchedulingMode(GpuSchedulingMode mode, GpuSchedulingOverrideMethod method) {
if (nvCheck_sched == 1 && method == GpuSchedulingOverrideMethod_NvService) {
return;
}
u32 temp;
bool enabled = false;
switch(mode) {
case GpuSchedulingMode_DoNotOverride: break;
case GpuSchedulingMode_Disabled:
if(method == GpuSchedulingOverrideMethod_NvService)
nvIoctl(fd2, NVSCHED_CTRL_DISABLE, &temp);
else
enabled = false;
break;
case GpuSchedulingMode_Enabled:
if(method == GpuSchedulingOverrideMethod_NvService)
nvIoctl(fd2, NVSCHED_CTRL_ENABLE, &temp);
else
enabled = true;
break;
default:
ASSERT_ENUM_VALID(GpuSchedulingMode, mode);
}
if(method == GpuSchedulingOverrideMethod_Ini) {
const char* ini_path = "sdmc:/atmosphere/config/system_settings.ini";
const char* section = "am.gpu";
const char* key = "gpu_scheduling_enabled";
const char* value = enabled ? "u8!0x1" : "u8!0x0";
ini_puts(section, key, value, ini_path);
}
}
void Board::SetDisplayRefreshDockedState(bool docked) {
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag) {
DisplayRefresh_SetDockedState(docked);
}
}
typedef struct EristaCpuUvEntry {
u32 tune0;
u32 tune1;
} EristaCpuUvEntry;
typedef struct MarikoCpuUvEntry {
u32 tune0_low;
u32 tune0_high;
u32 tune1_low;
u32 tune1_high;
} MarikoCpuUvEntry;
EristaCpuUvEntry eristaCpuUvTable[5] = {
{0xffff, 0x27007ff},
{0xefff, 0x27407ff},
{0xdfff, 0x27807ff},
{0xdfdf, 0x27a07ff},
{0xcfdf, 0x37007ff},
};
MarikoCpuUvEntry marikoCpuUvLow[12] = {
{0xffa0, 0xffff, 0x21107ff, 0},
{0x0, 0xffdf, 0x21107ff, 0x27207ff},
{0xffdf, 0xffdf, 0x21107ff, 0x27307ff},
{0xffff, 0xffdf, 0x21107ff, 0x27407ff},
{0x0, 0xffdf, 0x21607ff, 0x27707ff},
{0x0, 0xffdf, 0x21607ff, 0x27807ff},
{0x0, 0xdfff, 0x21607ff, 0x27b07ff},
{0xdfff, 0xdfff, 0x21707ff, 0x27b07ff},
{0xdfff, 0xdfff, 0x21707ff, 0x27c07ff},
{0xdfff, 0xdfff, 0x21707ff, 0x27d07ff},
{0xdfff, 0xdfff, 0x21707ff, 0x27e07ff},
{0xdfff, 0xdfff, 0x21707ff, 0x27f07ff},
};
MarikoCpuUvEntry marikoCpuUvHigh[12] = {
{0x0, 0xffff, 0, 0},
{0x0, 0xffdf, 0, 0x27207ff},
{0x0, 0xffdf, 0, 0x27307ff},
{0x0, 0xffdf, 0, 0x27407ff},
{0x0, 0xffdf, 0, 0x27707ff},
{0x0, 0xffdf, 0, 0x27807ff},
{0x0, 0xdfff, 0, 0x27b07ff},
{0x0, 0xdfff, 0, 0x27c07ff},
{0x0, 0xdfff, 0, 0x27d07ff},
{0x0, 0xdfff, 0, 0x27e07ff},
{0x0, 0xdfff, 0, 0x27f07ff},
{0x0, 0xdfff, 0, 0x27f07ff},
};
void Board::SetCpuUvLevel(u32 levelLow, u32 levelHigh, u32 tbreakPoint) {
u32* tune0_ptr = (u32*)(cldvfs + CL_DVFS_TUNE0_0);
u32* tune1_ptr = (u32*)(cldvfs + CL_DVFS_TUNE1_0);
if(Board::GetSocType() == SysClkSocType_Mariko) {
if(Board::GetHz(SysClkModule_CPU) < tbreakPoint && (levelLow || levelHigh)) {
if(levelLow) {
*tune0_ptr = marikoCpuUvLow[levelLow-1].tune0_low;
*tune1_ptr = marikoCpuUvLow[levelLow-1].tune1_low;
}
return;
} else {
if(levelLow) {
*tune0_ptr = marikoCpuUvLow[levelLow-1].tune0_low;
*tune1_ptr = marikoCpuUvLow[levelLow-1].tune1_low;
}
if(levelHigh) {
*tune0_ptr = marikoCpuUvHigh[levelHigh-1].tune0_high;
*tune1_ptr = marikoCpuUvHigh[levelHigh-1].tune1_high;
}
return;
}
if(Board::GetHz(SysClkModule_CPU) < tbreakPoint || (!levelLow)) { // account for tbreak
*tune0_ptr = 0xCFFF;
*tune1_ptr = 0xFF072201;
return;
} else if (Board::GetHz(SysClkModule_CPU) >= tbreakPoint || (!levelHigh)) {
*tune0_ptr = cachedMarikoUvHighTune0; // per console?
*tune1_ptr = 0xFFF7FF3F;
return;
}
} else {
if(Board::GetHz(SysClkModule_CPU) < tbreakPoint || (!levelLow)) { // account for tbreak
*tune0_ptr = cachedEristaUvLowTune0; // I think each erista has a different tune0/tune1?
*tune1_ptr = cachedEristaUvLowTune1;
return;
} else {
if(levelLow) {
*tune0_ptr = eristaCpuUvTable[levelLow-1].tune0;
*tune1_ptr = eristaCpuUvTable[levelLow-1].tune1;
} else {
*tune0_ptr = 0x0;
*tune1_ptr = 0x0;
}
}
}
}
/*
enum TableConfig: u32 {
DEFAULT_TABLE = 1,
TBREAK_1581 = 2,
TBREAK_1683 = 3,
EXTREME_TABLE = 4,
};
*/
u32 Board::CalculateTbreak(u32 table) {
if(Board::GetSocType() == SysClkSocType_Erista)
return 1581000000;
else {
switch(table) {
case 1 ... 2:
case 4:
return 1581000000;
case 3:
return 1683000000;
default:
return 1581000000;
}
}
}

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>
@@ -33,6 +33,8 @@
class Board
{
public:
static void PcvHijackDvfs(u32 vmin);
static u32 GetMinimumGpuVoltage(u32 freqMhz);
static void fuseReadSpeedos();
static u16 getSpeedo(HorizonOCSpeedo speedoType);
static u16 getIDDQ(HorizonOCSpeedo speedoType);
@@ -61,10 +63,17 @@ 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, GpuSchedulingOverrideMethod method);
static void SetDisplayRefreshDockedState(bool docked);
static void SetCpuUvLevel(u32 levelLow, u32 levelHigh, u32 tbreakPoint);
static u32 CalculateTbreak(u32 table);
protected:
static void FetchHardwareInfos();
static PcvModule GetPcvModule(SysClkModule sysclkModule);
static PcvModuleId GetPcvModuleId(SysClkModule sysclkModule);
private:
static void SetSpeedoBracket();
static void CacheDvfsTable();
static Handle GetPcvHandle();
};

View File

@@ -40,15 +40,20 @@
#include <cstdio>
#include <crc32.h>
#define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0))
bool isGovernorEnabled = false; // to avoid thread messes
bool lastGovernorState = false;
bool isGpuGovernorEnabled = false;
bool isCpuGovernorEnabled = false;
bool lastGpuGovernorState = false;
bool lastCpuGovernorState = false;
bool hasChanged = true;
ClockManager *ClockManager::instance = NULL;
Thread governorTHREAD;
Thread cpuGovernorTHREAD;
Thread gpuGovernorTHREAD;
u32 initialConfigValues[SysClkConfigValue_EnumMax]; // initial config. used for safety checks
bool kipAvailable = false;
bool isCpuGovernorInBoostMode = false;
ClockManager *ClockManager::GetInstance()
{
return instance;
@@ -88,11 +93,22 @@ ClockManager::ClockManager()
this->lastTempLogNs = 0;
this->lastCsvWriteNs = 0;
this->rnxSync = new ReverseNXSync;
this->sysDockIntegration = new SysDockIntegration;
memset(&initialConfigValues, 0, sizeof(initialConfigValues));
this->GetKipData();
threadCreate(
&governorTHREAD,
&cpuGovernorTHREAD,
ClockManager::CpuGovernorThread,
this,
NULL,
0x2000,
0x3F,
-2
);
threadCreate(
&gpuGovernorTHREAD,
ClockManager::GovernorThread,
this,
NULL,
@@ -101,7 +117,8 @@ ClockManager::ClockManager()
-2
);
threadStart(&governorTHREAD);
threadStart(&cpuGovernorTHREAD);
threadStart(&gpuGovernorTHREAD);
for(int i = 0; i < HorizonOCSpeedo_EnumMax; i++) {
this->context->speedos[i] = Board::getSpeedo((HorizonOCSpeedo)i);
@@ -110,42 +127,15 @@ ClockManager::ClockManager()
this->context->dramID = Board::GetDramID();
this->context->isDram8GB = Board::IsDram8GB();
}
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);
}
}
Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling), (GpuSchedulingOverrideMethod)this->config->GetConfigValue(HorizonOCConfigValue_GPUSchedulingMethod));
this->context->gpuSchedulingMode = (GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling);
this->context->isSysDockInstalled = this->sysDockIntegration->getCurrentSysDockState();
}
ClockManager::~ClockManager()
{
threadClose(&governorTHREAD);
threadClose(&cpuGovernorTHREAD);
threadClose(&gpuGovernorTHREAD);
delete this->config;
delete this->context;
}
@@ -196,7 +186,7 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
{
if (this->config->GetConfigValue(HocClkConfigValue_UncappedClocks))
{
return 4294967294; // Integer limit, uncapped clocks ON
return ~0; // Integer limit, uncapped clocks ON
}
else
{
@@ -246,7 +236,7 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
if(profile < SysClkProfile_HandheldCharging && Board::GetSocType() == SysClkSocType_Erista) {
return 1581000000;
} else {
return 4294967294;
return ~0;
}
}
}
@@ -337,6 +327,160 @@ u32 findIndexMHz(u32 arr[], u32 size, u32 value) {
return 0;
}
void ClockManager::CpuGovernorThread(void* arg)
{
ClockManager* mgr = static_cast<ClockManager*>(arg);
for (;;)
{
if (!mgr->running)
{
svcSleepThread(50'000'000);
continue;
}
if (!isCpuGovernorEnabled)
{
svcSleepThread(50'000'000);
continue;
}
std::uint32_t mode = 0;
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
bool isInBoostMode = R_SUCCEEDED(rc) && apmExtIsBoostMode(mode);
if (isInBoostMode)
{
isCpuGovernorInBoostMode = true;
svcSleepThread(50'000'000);
continue;
}
isCpuGovernorInBoostMode = false;
auto& table = mgr->freqTable[SysClkModule_CPU];
if (table.count == 0)
{
svcSleepThread(50'000'000);
continue;
}
std::scoped_lock lock{mgr->contextMutex};
u32 currentHz = Board::GetHz(SysClkModule_CPU);
u32 index = table.count - 1;
for (u32 i = 0; i < table.count; i++)
{
if (table.list[i] == currentHz)
{
index = i;
break;
}
}
if (table.list[index] != currentHz)
{
for (u32 i = 0; i < table.count; i++)
{
if (table.list[i] >= currentHz)
{
index = i;
break;
}
}
}
u32 targetHz = mgr->context->overrideFreqs[SysClkModule_CPU];
if (!targetHz)
{
targetHz = mgr->config->GetAutoClockHz(
mgr->context->applicationId,
SysClkModule_CPU,
mgr->context->profile,
false
);
if (!targetHz)
{
targetHz = mgr->config->GetAutoClockHz(
GLOBAL_PROFILE_ID,
SysClkModule_CPU,
mgr->context->profile,
false
);
}
}
int gpuLoad = Board::GetPartLoad(HocClkPartLoad_GPU);
int cpuLoad = Board::GetPartLoad(HocClkPartLoad_CPUMax);
if (isGpuGovernorEnabled && gpuLoad < 800)
{
if (cpuLoad < 600 && index > 0)
{
index--;
}
else if (cpuLoad > 800 && index + 1 < table.count)
{
index++;
}
}
else
{
if (cpuLoad < 600 && index > 0)
{
index--;
}
else if (cpuLoad > 800 && index + 1 < table.count)
{
index++;
}
}
u32 maxHz = mgr->GetMaxAllowedHz(SysClkModule_CPU, mgr->context->profile);
if (targetHz)
{
u32 targetIndex = table.count - 1;
for (u32 i = 0; i < table.count; i++)
{
if (table.list[i] >= targetHz)
{
targetIndex = i;
break;
}
}
if (index > targetIndex)
{
index = targetIndex;
}
}
if (maxHz > 0 && table.list[index] > maxHz)
{
for (u32 i = table.count; i > 0; i--)
{
if (table.list[i - 1] <= maxHz)
{
index = i - 1;
break;
}
}
}
u32 newHz = table.list[index];
if (mgr->IsAssignableHz(SysClkModule_CPU, newHz))
{
Board::SetHz(SysClkModule_CPU, newHz);
mgr->context->freqs[SysClkModule_CPU] = newHz;
}
svcSleepThread(50'000'000);
}
}
void ClockManager::GovernorThread(void* arg)
{
ClockManager* mgr = static_cast<ClockManager*>(arg);
@@ -349,8 +493,7 @@ void ClockManager::GovernorThread(void* arg)
continue;
}
if (!isGovernorEnabled)
if (!isGpuGovernorEnabled)
{
svcSleepThread(50'000'000);
continue;
@@ -367,7 +510,7 @@ void ClockManager::GovernorThread(void* arg)
u32 currentHz = Board::GetHz(SysClkModule_GPU);
u32 index = 0;
u32 index = table.count - 1;
for (u32 i = 0; i < table.count; i++)
{
if (table.list[i] == currentHz)
@@ -377,6 +520,18 @@ void ClockManager::GovernorThread(void* arg)
}
}
if (table.list[index] != currentHz)
{
for (u32 i = 0; i < table.count; i++)
{
if (table.list[i] >= currentHz)
{
index = i;
break;
}
}
}
u32 targetHz = mgr->context->overrideFreqs[SysClkModule_GPU];
if (!targetHz)
{
@@ -398,17 +553,34 @@ void ClockManager::GovernorThread(void* arg)
}
}
int load = Board::GetPartLoad(HocClkPartLoad_GPU);
int gpuLoad = Board::GetPartLoad(HocClkPartLoad_GPU);
int cpuLoad = Board::GetPartLoad(HocClkPartLoad_CPUMax);
if (load < 600 && index > 0)
if (isCpuGovernorEnabled && !isCpuGovernorInBoostMode && cpuLoad < 600)
{
index--;
if (gpuLoad < 600 && index > 0)
{
index--;
}
else if (gpuLoad > 750 && index + 1 < table.count)
{
index++;
}
}
else if (load > 800 && index + 1 < table.count)
else
{
index++;
if (gpuLoad < 600 && index > 0)
{
index--;
}
else if (gpuLoad > 800 && index + 1 < table.count)
{
index++;
}
}
u32 maxHz = mgr->GetMaxAllowedHz(SysClkModule_GPU, mgr->context->profile);
if (targetHz)
{
u32 targetIndex = table.count - 1;
@@ -427,6 +599,17 @@ void ClockManager::GovernorThread(void* arg)
}
}
if (maxHz > 0 && table.list[index] > maxHz)
{
for (u32 i = table.count; i > 0; i--)
{
if (table.list[i - 1] <= maxHz)
{
index = i - 1;
break;
}
}
}
u32 newHz = table.list[index];
if (mgr->IsAssignableHz(SysClkModule_GPU, newHz))
@@ -439,16 +622,21 @@ void ClockManager::GovernorThread(void* arg)
}
}
bool prevBoostMode = true;
void ClockManager::Tick()
GovernorState ClockManager::GetEffectiveGovernorState(GovernorState appState, GovernorState tempState)
{
std::scoped_lock lock{this->contextMutex};
std::uint32_t mode = 0;
AppletOperationMode opMode = appletGetOperationMode();
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration");
if (tempState == GovernorState_Disabled)
{
return GovernorState_Disabled;
}
if (tempState != GovernorState_DoNotOverride)
{
return tempState;
}
return appState;
}
void ClockManager::HandleSafetyFeatures() {
AppletOperationMode opMode = appletGetOperationMode();
if(this->config->GetConfigValue(HocClkConfigValue_HandheldTDP) && opMode == AppletOperationMode_Handheld) {
if(Board::GetConsoleType() == HorizonOCConsoleType_Hoag) {
if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_LiteTDPLimit)) {
@@ -463,115 +651,260 @@ void ClockManager::Tick()
}
}
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();
return;
}
bool isBoost = apmExtIsBoostMode(mode);
// if(isBoost) {
// Board::SetHz(SysClkModule_CPU, Board::GetSocType() == SysClkSocType_Mariko ? this->config->GetConfigValue(HocClkConfigValue_MarikoBoostCpuClock) * 1000'000 : this->config->GetConfigValue(HocClkConfigValue_EristaBoostCpuClock) * 1000'000);
// }
prevBoostMode = isBoost;
}
bool noGPU = false;
void ClockManager::HandleMiscFeatures() {
if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) {
I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent));
}
}
void ClockManager::HandleGovernor(uint32_t targetHz) {
GovernorState appGovernorState = (GovernorState)targetHz;
u32 tempTargetHz = this->context->overrideFreqs[HorizonOCModule_Governor];
if (!tempTargetHz)
{
tempTargetHz = this->config->GetAutoClockHz(this->context->applicationId, HorizonOCModule_Governor, this->context->profile, true);
if(!tempTargetHz)
tempTargetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, HorizonOCModule_Governor, this->context->profile, true);
}
GovernorState tempGovernorState = (GovernorState)tempTargetHz;
GovernorState effectiveState = this->GetEffectiveGovernorState(appGovernorState, tempGovernorState);
bool newCpuGovernorState = (effectiveState == GovernorState_Enabled_CpuGpu || effectiveState == GovernorState_Enabled_Cpu);
bool newGpuGovernorState = (effectiveState == GovernorState_Enabled_CpuGpu || effectiveState == GovernorState_Enabled_Gpu);
isCpuGovernorEnabled = newCpuGovernorState;
isGpuGovernorEnabled = newGpuGovernorState;
if(newCpuGovernorState == false && lastCpuGovernorState == true) {
svcSleepThread(150'000'000); // thread syncing. probably a cleaner way to do this but hey, it works!
Board::ResetToStockCpu();
}
if(newGpuGovernorState == false && lastGpuGovernorState == true) {
svcSleepThread(150'000'000);
Board::ResetToStockGpu();
}
if(newCpuGovernorState != lastCpuGovernorState || newGpuGovernorState != lastGpuGovernorState) {
FileUtils::LogLine("[mgr] Governor state changed: CPU %s, GPU %s", newCpuGovernorState ? "enabled" : "disabled", newGpuGovernorState ? "enabled" : "disabled");
lastCpuGovernorState = newCpuGovernorState;
lastGpuGovernorState = newGpuGovernorState;
}
}
void ClockManager::DVFSBeforeSet(u32 targetHz) {
s32 dvfsOffset = this->config->GetConfigValue(HorizonOCConfigValue_DVFSOffset);
u32 vmin = Board::GetMinimumGpuVoltage(targetHz / 1000000) + dvfsOffset;
Board::PcvHijackDvfs(vmin);
/* Update the voltage. */
if (I2c_BuckConverter_GetMvOut(&I2c_Mariko_GPU) < vmin) {
I2c_BuckConverter_SetMvOut(&I2c_Mariko_GPU, vmin);
}
this->context->voltages[HocClkVoltage_GPU] = vmin * 1000;
}
void ClockManager::DVFSAfterSet(u32 targetHz) {
s32 dvfsOffset = this->config->GetConfigValue(HorizonOCConfigValue_DVFSOffset);
dvfsOffset = std::max(dvfsOffset, -50);
u32 vmin = Board::GetMinimumGpuVoltage(targetHz / 1000000) + dvfsOffset;
Board::PcvHijackDvfs(vmin);
targetHz = this->context->overrideFreqs[SysClkModule_GPU];
if (!targetHz)
{
targetHz = this->config->GetAutoClockHz(this->context->applicationId, SysClkModule_GPU, this->context->profile, false);
if(!targetHz)
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, SysClkModule_GPU, this->context->profile, false);
}
if(targetHz) {
Board::SetHz(SysClkModule_GPU, ~0);
Board::SetHz(SysClkModule_GPU, targetHz);
}
}
void ClockManager::HandleCpuUv() {
if(Board::GetSocType() == SysClkSocType_Erista)
Board::SetCpuUvLevel(this->config->GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000);
else
Board::SetCpuUvLevel(this->config->GetConfigValue(KipConfigValue_marikoCpuUVLow), this->config->GetConfigValue(KipConfigValue_marikoCpuUVHigh), Board::CalculateTbreak(this->config->GetConfigValue(KipConfigValue_tableConf)));
}
void ClockManager::DVFSReset() {
if (Board::GetSocType() == SysClkSocType_Mariko && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) {
Board::PcvHijackDvfs(0);
u32 targetHz = this->context->overrideFreqs[SysClkModule_GPU];
if (!targetHz) {
targetHz = this->config->GetAutoClockHz(this->context->applicationId, SysClkModule_GPU, this->context->profile, false);
if(!targetHz) {
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, SysClkModule_GPU, this->context->profile, false);
}
}
u32 maxHz = this->GetMaxAllowedHz(SysClkModule_GPU, this->context->profile);
u32 nearestHz = this->GetNearestHz(SysClkModule_GPU, targetHz, maxHz);
Board::SetHz(SysClkModule_GPU, ~0);
if(targetHz) {
Board::SetHz(SysClkModule_GPU, nearestHz);
} else {
Board::ResetToStockGpu();
}
}
}
void ClockManager::HandleFreqReset(SysClkModule module, bool isBoost) {
switch (module)
{
case SysClkModule_CPU:
if(!(isBoost || (this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode) && isBoost)))
Board::ResetToStockCpu();
if(this->config->GetConfigValue(HorizonOCConfigValue_LiveCpuUv)) {
if(Board::GetSocType() == SysClkSocType_Erista)
Board::SetCpuUvLevel(this->config->GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000);
else
Board::SetCpuUvLevel(this->config->GetConfigValue(KipConfigValue_marikoCpuUVLow), this->config->GetConfigValue(KipConfigValue_marikoCpuUVHigh), Board::CalculateTbreak(this->config->GetConfigValue(KipConfigValue_tableConf)));
}
break;
case SysClkModule_GPU:
Board::ResetToStockGpu();
break;
case SysClkModule_MEM:
Board::ResetToStockMem();
DVFSReset();
default:
break;
}
}
void ClockManager::SetClocks(bool isBoost) {
std::uint32_t targetHz = 0;
std::uint32_t maxHz = 0;
std::uint32_t nearestHz = 0;
if(isBoost && !this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode)) {
u32 boostFreq = Board::GetHz(SysClkModule_CPU);
if (boostFreq / 1000000 > 1785) {
Board::SetHz(SysClkModule_CPU, boostFreq);
}
return; // Return if we are't overwriting boost mode
}
bool returnRaw = false; // Return a value scaled to MHz instead of raw value
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
{
u32 oldHz = Board::GetHz((SysClkModule)module); // Get Old RAM hz (used primarily for DVFS Logic)
if(module > SysClkModule_MEM)
returnRaw = true;
else
returnRaw = false;
targetHz = this->context->overrideFreqs[module];
if (!targetHz)
{
targetHz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile, returnRaw);
if(!targetHz)
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, (SysClkModule)module, this->context->profile, returnRaw);
}
if(module == HorizonOCModule_Governor) {
HandleGovernor(targetHz);
}
if(module == HorizonOCModule_Display && this->config->GetConfigValue(HorizonOCConfigValue_OverwriteRefreshRate) && Board::GetConsoleType() != HorizonOCConsoleType_Hoag) {
if(targetHz)
Board::SetHz(HorizonOCModule_Display, targetHz);
else
Board::ResetToStockDisplay();
}
// Skip GPU and CPU if governors handle them
if(module > SysClkModule_MEM) {
continue;
}
bool noCPU = isCpuGovernorEnabled;
bool noGPU = isGpuGovernorEnabled;
if(noCPU && module == SysClkModule_CPU)
continue;
if(noGPU && module == SysClkModule_GPU)
continue;
if (targetHz)
{
maxHz = this->GetMaxAllowedHz((SysClkModule)module, this->context->profile);
nearestHz = this->GetNearestHz((SysClkModule)module, targetHz, maxHz);
if (nearestHz != this->context->freqs[module]) {
FileUtils::LogLine(
"[mgr] %s clock set : %u.%u MHz (target = %u.%u MHz)",
Board::GetModuleName((SysClkModule)module, true),
nearestHz / 1000000, nearestHz / 100000 - nearestHz / 1000000 * 10,
targetHz / 1000000, targetHz / 100000 - targetHz / 1000000 * 10
);
if(module == SysClkModule_MEM && Board::GetSocType() == SysClkSocType_Mariko && targetHz > oldHz && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) {
DVFSBeforeSet(targetHz);
}
Board::SetHz((SysClkModule)module, nearestHz);
this->context->freqs[module] = nearestHz;
if(module == SysClkModule_CPU && this->config->GetConfigValue(HorizonOCConfigValue_LiveCpuUv))
{
HandleCpuUv();
}
if(module == SysClkModule_MEM && Board::GetSocType() == SysClkSocType_Mariko && targetHz < oldHz && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) {
DVFSAfterSet(targetHz);
}
}
} else {
HandleFreqReset((SysClkModule)module, isBoost);
}
}
}
void ClockManager::Tick()
{
std::scoped_lock lock{this->contextMutex};
std::uint32_t mode = 0;
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration");
bool isBoost = apmExtIsBoostMode(mode);
HandleSafetyFeatures();
if (this->RefreshContext() || this->config->Refresh())
{
if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) {
I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent));
}
std::uint32_t targetHz = 0;
std::uint32_t maxHz = 0;
std::uint32_t nearestHz = 0;
if(apmExtIsBoostMode(mode) && !this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode)) {
// ResetToStockClocks();
return;
}
bool returnRaw = false;
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
{
if(module > SysClkModule_MEM)
returnRaw = true;
else
returnRaw = false;
targetHz = this->context->overrideFreqs[module];
if (!targetHz)
{
targetHz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile, returnRaw);
if(!targetHz)
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, (SysClkModule)module, this->context->profile, returnRaw);
}
if(module == HorizonOCModule_Governor) {
bool newGovernorState = targetHz;
if(newGovernorState != lastGovernorState) {
FileUtils::LogLine("[mgr] Governor state changed: %s", newGovernorState ? "enabled" : "disabled");
lastGovernorState = newGovernorState;
hasChanged = true;
Board::ResetToStock();
}
isGovernorEnabled = newGovernorState;
}
if(module == HorizonOCModule_Display && this->config->GetConfigValue(HorizonOCConfigValue_OverwriteRefreshRate) && Board::GetConsoleType() != HorizonOCConsoleType_Hoag) {
if(targetHz)
Board::SetHz(HorizonOCModule_Display, targetHz);
else
Board::ResetToStockDisplay();
}
if(targetHz && this->context->realFreqs[HorizonOCModule_Display] != targetHz && module == HorizonOCModule_Display)
this->context->realFreqs[HorizonOCModule_Display] = targetHz;
// Skip GPU if governor handles it
if(module > SysClkModule_MEM) {
continue;
}
if(isGovernorEnabled) {
noGPU = true;
} else {
noGPU = false;
}
if(noGPU && module == SysClkModule_GPU)
continue;
if (targetHz)
{
maxHz = this->GetMaxAllowedHz((SysClkModule)module, this->context->profile);
nearestHz = this->GetNearestHz((SysClkModule)module, targetHz, maxHz);
if (nearestHz != this->context->freqs[module]) {
FileUtils::LogLine(
"[mgr] %s clock set : %u.%u MHz (target = %u.%u MHz)",
Board::GetModuleName((SysClkModule)module, true),
nearestHz / 1000000, nearestHz / 100000 - nearestHz / 1000000 * 10,
targetHz / 1000000, targetHz / 100000 - targetHz / 1000000 * 10
);
Board::SetHz((SysClkModule)module, nearestHz);
this->context->freqs[module] = nearestHz;
}
if(module == SysClkModule_CPU && this->config->GetConfigValue(HocClkConfigValue_FixCpuVoltBug)) {
FixCpuBug();
}
}
}
HandleMiscFeatures();
SetClocks(isBoost);
}
}
void ClockManager::ResetToStockClocks() {
Board::ResetToStockCpu();
if(this->config->GetConfigValue(HorizonOCConfigValue_LiveCpuUv))
{
if(Board::GetSocType() == SysClkSocType_Erista)
Board::SetCpuUvLevel(this->config->GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000);
else
Board::SetCpuUvLevel(this->config->GetConfigValue(KipConfigValue_marikoCpuUVLow), this->config->GetConfigValue(KipConfigValue_marikoCpuUVHigh), Board::CalculateTbreak(this->config->GetConfigValue(KipConfigValue_tableConf)));
}
Board::ResetToStockGpu();
}
@@ -597,7 +930,6 @@ bool ClockManager::RefreshContext()
FileUtils::LogLine("[mgr] TitleID change: %016lX", applicationId);
this->context->applicationId = applicationId;
hasChanged = true;
this->rnxSync->Reset(applicationId);
}
SysClkProfile profile = Board::GetProfile();
@@ -611,8 +943,12 @@ bool ClockManager::RefreshContext()
// restore clocks to stock values on app or profile change
if (hasChanged)
{
// 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();
}
@@ -634,23 +970,6 @@ bool ClockManager::RefreshContext()
{
FileUtils::LogLine("[mgr] %s override change: %u.%u MHz", Board::GetModuleName((SysClkModule)module, true), hz / 1000000, hz / 100000 - hz / 1000000 * 10);
}
else
{
FileUtils::LogLine("[mgr] %s override disabled", Board::GetModuleName((SysClkModule)module, true));
switch (module)
{
case SysClkModule_CPU:
if(!(apmExtIsBoostMode(mode) || (this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode) && apmExtIsBoostMode(mode))))
Board::ResetToStockCpu();
break;
case SysClkModule_GPU:
Board::ResetToStockGpu();
break;
case SysClkModule_MEM:
Board::ResetToStockMem();
break;
}
}
this->context->overrideFreqs[module] = hz;
hasChanged = true;
}
@@ -713,7 +1032,7 @@ bool ClockManager::RefreshContext()
FileUtils::WriteContextToCsv(this->context);
}
this->context->maxDisplayFreq = Board::GetHighestDockedDisplayRate();
// this->context->maxDisplayFreq = Board::GetHighestDockedDisplayRate();
u32 targetHz = this->context->overrideFreqs[HorizonOCModule_Display];
if (!targetHz)
@@ -723,18 +1042,15 @@ bool ClockManager::RefreshContext()
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, HorizonOCModule_Display, this->context->profile, true);
}
if(targetHz && this->context->realFreqs[HorizonOCModule_Display] > targetHz)
if(targetHz && this->context->realFreqs[HorizonOCModule_Display] > targetHz && this->context->profile != SysClkProfile_Docked)
this->context->realFreqs[HorizonOCModule_Display] = targetHz; // clean up display real freqs, should probably be moved to the real freqs loop?
if(Board::GetConsoleType() != HorizonOCConsoleType_Hoag)
Board::SetDisplayRefreshDockedState(this->context->profile == SysClkProfile_Docked);
return hasChanged;
}
void ClockManager::SetRNXRTMode(ReverseNXMode mode)
{
this->rnxSync->SetRTMode(mode);
}
void ClockManager::SetKipData() {
// TODO: figure out if this REALLY causes issues (i doubt it)
// if(Board::GetSocType() == SysClkSocType_Mariko) {
@@ -768,6 +1084,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));
@@ -808,14 +1126,15 @@ void ClockManager::SetKipData() {
CUST_WRITE_FIELD_BATCH(&table, commonGpuVoltOffset, this->config->GetConfigValue(KipConfigValue_commonGpuVoltOffset));
CUST_WRITE_FIELD_BATCH(&table, gpuSpeedo, this->config->GetConfigValue(KipConfigValue_gpuSpeedo));
for (int i = 0; i < 24; i++) {
for (int i = 0; i < 31; i++) {
table.marikoGpuVoltArray[i] = this->config->GetConfigValue((SysClkConfigValue)(KipConfigValue_g_volt_76800 + i));
}
for (int i = 0; i < 27; i++) {
for (int i = 0; i < 24; i++) {
table.eristaGpuVoltArray[i] = this->config->GetConfigValue((SysClkConfigValue)(KipConfigValue_g_volt_e_76800 + i));
}
CUST_WRITE_FIELD_BATCH(&table, t6_tRTW_fine_tune, this->config->GetConfigValue(KipConfigValue_t6_tRTW_fine_tune));
CUST_WRITE_FIELD_BATCH(&table, t7_tWTR_fine_tune, this->config->GetConfigValue(KipConfigValue_t7_tWTR_fine_tune));
if (!cust_write_table("sdmc:/atmosphere/kips/hoc.kip", &table)) {
@@ -890,6 +1209,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);
@@ -927,6 +1248,7 @@ void ClockManager::GetKipData() {
initialConfigValues[KipConfigValue_marikoGpuVmax] = cust_get_mariko_gpu_vmax(&table);
initialConfigValues[KipConfigValue_commonGpuVoltOffset] = cust_get_common_gpu_offset(&table);
initialConfigValues[KipConfigValue_gpuSpeedo] = cust_get_gpu_speedo(&table);
initialConfigValues[KipConfigValue_t6_tRTW_fine_tune] = cust_get_tRTW_fine_tune(&table);
initialConfigValues[KipConfigValue_t7_tWTR_fine_tune] = cust_get_tWTR_fine_tune(&table);
}
@@ -935,6 +1257,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);
@@ -974,17 +1298,18 @@ void ClockManager::GetKipData() {
configValues.values[KipConfigValue_commonGpuVoltOffset] = cust_get_common_gpu_offset(&table);
configValues.values[KipConfigValue_gpuSpeedo] = Board::getSpeedo(HorizonOCSpeedo_GPU); // cust_get_gpu_speedo(&table);
for (int i = 0; i < 24; i++) {
for (int i = 0; i < 31; i++) {
configValues.values[KipConfigValue_g_volt_76800 + i] = cust_get_mariko_gpu_volt(&table, i);
initialConfigValues[KipConfigValue_g_volt_76800 + i] = cust_get_mariko_gpu_volt(&table, i);
}
for (int i = 0; i < 27; i++) {
for (int i = 0; i < 24; i++) {
configValues.values[KipConfigValue_g_volt_e_76800 + i] = cust_get_erista_gpu_volt(&table, i);
initialConfigValues[KipConfigValue_g_volt_e_76800 + i] = cust_get_erista_gpu_volt(&table, i);
}
configValues.values[KipConfigValue_t7_tWTR_fine_tune] = cust_get_tWTR_fine_tune(&table);
configValues.values[KipConfigValue_t6_tRTW_fine_tune] = cust_get_tRTW_fine_tune(&table);
// if(cust_get_cust_rev(&table) == KIP_CUST_REV)
// return;
@@ -1004,75 +1329,4 @@ void ClockManager::GetKipData() {
FileUtils::LogLine("[clock_manager] Config refresh error in 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);
}
unsigned int ramBrackets[][22] =
{
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, },
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, },
{ 2433, 2466, 2533, 2600, 2666, 2733, 2766, 2800, 2833, 2866, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3300, 3333, 3366, },
{ 2500, 2533, 2600, 2633, 2666, 2733, 2800, 2866, 2900, 2966, 3033, 3100, 3166, 3200, 3233, 3266, 3300, 3333, 3366, 3400, 3400, 3400, }
};
unsigned int gpuDvfsArray[] = { 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800};
int ClockManager::GetSpeedoBracket (int speedo)
{
int speedoBracket = 3;
if ((speedo < 1754) && (speedoBracket = 2, speedo < 1690)) {
speedoBracket = !!(1625 < speedo);
}
return speedoBracket;
}
unsigned int ClockManager::GetGpuVoltage (unsigned int freq, int speedo)
{
long int loop;
int bracket = GetSpeedoBracket(speedo);
if (freq < 1601)
return 610;
loop = 0;
do
{
if (freq <= ramBrackets[bracket][loop])
return gpuDvfsArray[loop];
loop++;
} while (loop != 22);
return 800;
}
void ClockManager::calculateGpuVmin (void)
{
if(this->config->Refresh()) {
SysClkConfigValueList configValues;
this->config->GetConfigValues(&configValues);
int speedo = Board::getSpeedo(HorizonOCSpeedo_CPU), freq = this->config->GetConfigValue(KipConfigValue_marikoEmcMaxClock);
configValues.values[KipConfigValue_marikoGpuVmin] = GetGpuVoltage(freq, speedo);
this->config->SetConfigValues(&configValues, true);
}
}
}

View File

@@ -23,54 +23,166 @@
* stuff is worth it, you can buy us a beer in return. - The sys-clk authors
* --------------------------------------------------------------------------
*/
#pragma once
#include <atomic>
#include <sysclk.h>
#include <switch.h>
#include "config.h"
#include "board.h"
#include <nxExt/cpp/lockable_mutex.h>
#include "integrations.h"
void governorThread(void*);
class ReverseNXSync;
class SysDockIntegration;
class ClockManager
{
public:
static ClockManager* GetInstance();
static void Initialize();
static void Exit();
ClockManager();
virtual ~ClockManager();
void FixCpuBug();
SysClkContext GetCurrentContext();
Config* GetConfig();
void SetRunning(bool running);
bool Running();
void GetFreqList(SysClkModule module, std::uint32_t* list, std::uint32_t maxCount, std::uint32_t* outCount);
/**
* Handles safety features
*
*/
void HandleSafetyFeatures();
/**
* Handles misc features (currently only battery charge current).
*
*/
void HandleMiscFeatures();
/**
* Handles governor state resolution and applies CPU/GPU governor transitions.
*
* @param targetHz Governor override value for the current profile.
*/
void HandleGovernor(uint32_t targetHz);
/**
* Handles DVFS logic before the frequency set
*
* @param targetHz Governor override value for the current profile.
*/
void DVFSBeforeSet(u32 targetHz);
/**
* Handles DVFS logic after the frequency set
*
* @param targetHz Governor override value for the current profile.
*/
void DVFSAfterSet(u32 targetHz);
/**
* Reset the GPU vMin
*
*/
void DVFSReset();
/**
* Handles the Live CPU UV Feature
*
*/
void HandleCpuUv();
/**
* Handles frequency resets
*
* @param module The module to reset frequency for
* @param isBoost Is in boost mode
*/
void HandleFreqReset(SysClkModule module, bool isBoost);
/**
* Sets clocks
*
* @param isBoost Is in boost mode
*/
void SetClocks(bool isBoost);
/**
* Main function, runs every 5s in sleep mode, and a user specified amount when awake
*
*/
void Tick();
/**
* Reset CPU/GPU to stock values
*
*/
void ResetToStockClocks();
/**
* Wait for the next tick event
*
*/
void WaitForNextTick();
void SetRNXRTMode(ReverseNXMode mode);
/**
* Set the data in the KIP
*
*/
void SetKipData();
/**
* Get the data from the KIP
*
*/
void GetKipData();
/**
* Runs the CPU Governor
*
* @param arg Cast to ClockManager* for context
*/
static void CpuGovernorThread(void* arg);
/**
* Runs the GPU Governor
*
* @param arg Cast to ClockManager* for context
*/
static void GovernorThread(void* arg);
void UpdateRamTimings();
/**
* Gets the effective governor state from application/temporary override
*
* @param appState Governor state from app
* @param tempState Governor state from temporary override
*/
GovernorState GetEffectiveGovernorState(GovernorState appState, GovernorState tempState);
/**
* Frequency tables
*
*/
struct {
std::uint32_t count;
std::uint32_t list[SYSCLK_FREQ_LIST_MAX];
} freqTable[SysClkModule_EnumMax];
/**
* Gets the current GPU speedo bracket
*
* @param speedo GPU Speedo
*/
int GetSpeedoBracket (int speedo);
/**
* Gets the required vMin for a ram frequency for a speedo
*
* @param freq RAM Freq in MHz
* @param speedo GPU Speedo
*/
unsigned int GetGpuVoltage (unsigned int freq, int speedo);
void calculateGpuVmin(void);
protected:
bool IsAssignableHz(SysClkModule module, std::uint32_t hz);
inline std::uint32_t GetMaxAllowedHz(SysClkModule module, SysClkProfile profile);
@@ -78,9 +190,7 @@ class ClockManager
bool ConfigIntervalTimeout(SysClkConfigValue intervalMsConfigValue, std::uint64_t ns, std::uint64_t* lastLogNs);
void RefreshFreqTableRow(SysClkModule module);
bool RefreshContext();
static ClockManager *instance;
std::atomic_bool running;
LockableMutex contextMutex;
Config* config;
@@ -89,5 +199,5 @@ class ClockManager
std::uint64_t lastFreqLogNs;
std::uint64_t lastPowerLogNs;
std::uint64_t lastCsvWriteNs;
ReverseNXSync *rnxSync;
};
SysDockIntegration *sysDockIntegration;
};

View File

@@ -17,68 +17,16 @@
#include "integrations.h"
#include <sys/stat.h>
ReverseNXSync::ReverseNXSync()
: m_rt_mode(ReverseNX_NotFound), m_tool_mode(ReverseNX_NotFound) {
FILE *fp = fopen("/atmosphere/contents/0000000000534C56/flags/boot2.flag", "r");
m_tool_enabled = fp ? true : false;
if (fp)
fclose(fp);
SysDockIntegration::SysDockIntegration() {
}
SysClkProfile ReverseNXSync::GetProfile(SysClkProfile real) {
switch (this->GetMode()) {
case ReverseNX_Docked:
return SysClkProfile_Docked;
case ReverseNX_Handheld:
if (real == SysClkProfile_Docked)
return SysClkProfile_HandheldChargingOfficial;
default:
return real;
bool SysDockIntegration::getCurrentSysDockState() {
struct stat st = {0};
if (stat("sdmc:/atmosphere/contents/42000000000000A0", &st) == 0 && S_ISDIR(st.st_mode)) {
return true;
} else {
return false;
}
}
ReverseNXMode ReverseNXSync::GetMode() {
if (!this->m_sync_enabled)
return ReverseNX_NotFound;
if (this->m_rt_mode)
return this->m_rt_mode;
return this->m_tool_mode;
}
ReverseNXMode ReverseNXSync::GetToolModeFromPatch(const char* patch_path) {
constexpr uint32_t DOCKED_MAGIC = 0x320003E0;
constexpr uint32_t HANDHELD_MAGIC = 0x52A00000;
FILE *fp = fopen(patch_path, "rb");
if (fp) {
uint32_t buf = 0;
fread(&buf, sizeof(buf), 1, fp);
fclose(fp);
if (buf == DOCKED_MAGIC)
return ReverseNX_Docked;
if (buf == HANDHELD_MAGIC)
return ReverseNX_Handheld;
}
return ReverseNX_NotFound;
}
ReverseNXMode ReverseNXSync::RecheckToolMode() {
ReverseNXMode mode = ReverseNX_NotFound;
if (this->m_tool_enabled) {
const char* fileName = "_ZN2nn2oe18GetPerformanceModeEv.asm64"; // or _ZN2nn2oe18GetPerformanceModeEv.asm64
const char* filePath = new char[72];
SCOPE_EXIT { delete[] filePath; };
/* Check per-game patch */
snprintf((char*)filePath, 72, "/SaltySD/patches/%016lX/%s", this->m_app_id, fileName);
mode = this->GetToolModeFromPatch(filePath);
if (!mode) {
/* Check global patch */
snprintf((char*)filePath, 72, "/SaltySD/patches/%s", fileName);
mode = this->GetToolModeFromPatch(filePath);
}
}
return mode;
}

View File

@@ -29,25 +29,9 @@
#include "clock_manager.h"
class ReverseNXSync {
class SysDockIntegration {
public:
ReverseNXSync ();
SysDockIntegration();
void ToggleSync(bool enable) { m_sync_enabled = enable; };
void Reset(uint64_t app_id) { m_app_id = app_id; SetRTMode(ReverseNX_NotFound); GetToolMode(); }
ReverseNXMode GetRTMode() { return m_rt_mode; };
void SetRTMode(ReverseNXMode mode) { m_rt_mode = mode; };
ReverseNXMode GetToolMode() { return m_tool_mode = RecheckToolMode(); };
SysClkProfile GetProfile(SysClkProfile real);
ReverseNXMode GetMode();
protected:
std::atomic<ReverseNXMode> m_rt_mode;
ReverseNXMode m_tool_mode;
uint64_t m_app_id = 0;
bool m_tool_enabled;
bool m_sync_enabled;
ReverseNXMode GetToolModeFromPatch(const char* patch_path);
ReverseNXMode RecheckToolMode();
bool getCurrentSysDockState();
};

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>
@@ -43,7 +43,7 @@ IpcService::IpcService(ClockManager* clockMgr)
this->running = false;
this->clockMgr = clockMgr;
}
void IpcService::SetRunning(bool running)
@@ -198,27 +198,11 @@ Result IpcService::ServiceHandlerFunc(void* arg, const IpcServerRequest* r, u8*
);
}
break;
case SysClkIpcCmd_SetReverseNXRTMode:
if (r->data.size >= sizeof(ReverseNXMode)) {
ReverseNXMode mode = *((ReverseNXMode*)r->data.ptr);
return ipcSrv->SetReverseNXRTMode(mode);
}
break;
case HocClkIpcCmd_SetKipData:
if (r->data.size >= 0) {
return ipcSrv->SetKipData();
}
break;
case HocClkIpcCmd_UpdateEmcRegs:
if (r->data.size >= 0) {
return ipcSrv->UpdateEmcRegs();
}
break;
case HocClkIpcCmd_CalculateGpuVmin:
if (r->data.size >= 0) {
return ipcSrv->CalculateGPUVmin();
}
break;
}
return SYSCLK_ERROR(Generic);
@@ -371,29 +355,14 @@ Result IpcService::GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t*
return 0;
}
Result IpcService::SetReverseNXRTMode(ReverseNXMode mode) {
return 0;
}
Result IpcService::SetKipData() {
this->clockMgr->SetKipData();
return 0;
}
Result IpcService::GetKipData() {
this->clockMgr->GetKipData();
return 0;
}
Result IpcService::UpdateEmcRegs() {
this->clockMgr->UpdateRamTimings();
return 0;
}
Result IpcService::CalculateGPUVmin() {
this->clockMgr->calculateGpuVmin();
return 0;
}

View File

@@ -54,11 +54,8 @@ class IpcService
Result GetConfigValues(SysClkConfigValueList* out_configValues);
Result SetConfigValues(SysClkConfigValueList* configValues);
Result GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t* out_list, std::size_t size, std::uint32_t* out_count);
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;
@@ -75,9 +77,10 @@ typedef struct {
u32 gpuSpeedo;
u32 eristaGpuVoltArray[27];
u32 marikoGpuVoltArray[24];
u32 eristaGpuVoltArray[24];
u32 marikoGpuVoltArray[31];
u32 t6_tRTW_fine_tune;
u32 t7_tWTR_fine_tune;
u32 reserved[60];
@@ -191,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); }
@@ -203,6 +208,7 @@ static inline bool cust_set_tRFC(const char* p, u32 v) { CUST_WRITE_FIELD(p, t5_
static inline bool cust_set_tRTW(const char* p, u32 v) { CUST_WRITE_FIELD(p, t6_tRTW, v); }
static inline bool cust_set_tWTR(const char* p, u32 v) { CUST_WRITE_FIELD(p, t7_tWTR, v); }
static inline bool cust_set_tREFI(const char* p, u32 v) { CUST_WRITE_FIELD(p, t8_tREFI, v); }
static inline bool cust_set_tRTW_fine_tune(const char* p, u32 v) { CUST_WRITE_FIELD(p, t6_tRTW_fine_tune, v); }
static inline bool cust_set_tWTR_fine_tune(const char* p, u32 v) { CUST_WRITE_FIELD(p, t7_tWTR_fine_tune, v); }
static inline bool cust_set_burst_read_lat(const char* p, u32 v) { CUST_WRITE_FIELD(p, mem_burst_read_latency, v); }
static inline bool cust_set_burst_write_lat(const char* p, u32 v) { CUST_WRITE_FIELD(p, mem_burst_write_latency, v); }
@@ -259,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); }
@@ -271,6 +279,7 @@ static inline u32 cust_get_tRFC(const CustomizeTable* t) { return CUST_GET_FIELD
static inline u32 cust_get_tRTW(const CustomizeTable* t) { return CUST_GET_FIELD(t, t6_tRTW); }
static inline u32 cust_get_tWTR(const CustomizeTable* t) { return CUST_GET_FIELD(t, t7_tWTR); }
static inline u32 cust_get_tREFI(const CustomizeTable* t) { return CUST_GET_FIELD(t, t8_tREFI); }
static inline u32 cust_get_tRTW_fine_tune(const CustomizeTable* t) { return CUST_GET_FIELD(t, t6_tRTW_fine_tune); }
static inline u32 cust_get_tWTR_fine_tune(const CustomizeTable* t) { return CUST_GET_FIELD(t, t7_tWTR_fine_tune); }
static inline u32 cust_get_burst_read_lat(const CustomizeTable* t) { return CUST_GET_FIELD(t, mem_burst_read_latency); }
static inline u32 cust_get_burst_write_lat(const CustomizeTable* t) { return CUST_GET_FIELD(t, mem_burst_write_latency); }
@@ -299,12 +308,12 @@ static inline u32 cust_get_gpu_speedo(const CustomizeTable* t) { return CUST_GET
static inline u32 cust_get_marikoCpuMaxClock(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoCpuMaxClock); }
static inline u32 cust_get_erista_gpu_volt(const CustomizeTable* t, int idx) {
if (!t || idx < 0 || idx >= 27) return 0;
if (!t || idx < 0 || idx > 24) return 0;
return t->eristaGpuVoltArray[idx];
}
static inline u32 cust_get_mariko_gpu_volt(const CustomizeTable* t, int idx) {
if (!t || idx < 0 || idx >= 24) return 0;
if (!t || idx < 0 || idx > 31) return 0;
return t->marikoGpuVoltArray[idx];
}
@@ -321,32 +330,30 @@ static inline bool cust_set_mariko_gpu_volt_##freq( \
}
DECL_ERISTA_GPU_VOLT_HELPER(76800, 0)
DECL_ERISTA_GPU_VOLT_HELPER(115200, 1)
DECL_ERISTA_GPU_VOLT_HELPER(153600, 2)
DECL_ERISTA_GPU_VOLT_HELPER(192000, 3)
DECL_ERISTA_GPU_VOLT_HELPER(230400, 4)
DECL_ERISTA_GPU_VOLT_HELPER(268800, 5)
DECL_ERISTA_GPU_VOLT_HELPER(307200, 6)
DECL_ERISTA_GPU_VOLT_HELPER(345600, 7)
DECL_ERISTA_GPU_VOLT_HELPER(384000, 8)
DECL_ERISTA_GPU_VOLT_HELPER(422400, 9)
DECL_ERISTA_GPU_VOLT_HELPER(460800, 10)
DECL_ERISTA_GPU_VOLT_HELPER(499200, 11)
DECL_ERISTA_GPU_VOLT_HELPER(537600, 12)
DECL_ERISTA_GPU_VOLT_HELPER(576000, 13)
DECL_ERISTA_GPU_VOLT_HELPER(614400, 14)
DECL_ERISTA_GPU_VOLT_HELPER(652800, 15)
DECL_ERISTA_GPU_VOLT_HELPER(691200, 16)
DECL_ERISTA_GPU_VOLT_HELPER(729600, 17)
DECL_ERISTA_GPU_VOLT_HELPER(768000, 18)
DECL_ERISTA_GPU_VOLT_HELPER(806400, 19)
DECL_ERISTA_GPU_VOLT_HELPER(844800, 20)
DECL_ERISTA_GPU_VOLT_HELPER(883200, 21)
DECL_ERISTA_GPU_VOLT_HELPER(921600, 22)
DECL_ERISTA_GPU_VOLT_HELPER(960000, 23)
DECL_ERISTA_GPU_VOLT_HELPER(998400, 24)
DECL_ERISTA_GPU_VOLT_HELPER(1036800, 25)
DECL_ERISTA_GPU_VOLT_HELPER(1075200, 26)
DECL_ERISTA_GPU_VOLT_HELPER(153600, 1)
DECL_ERISTA_GPU_VOLT_HELPER(230400, 2)
DECL_ERISTA_GPU_VOLT_HELPER(307200, 3)
DECL_ERISTA_GPU_VOLT_HELPER(384000, 4)
DECL_ERISTA_GPU_VOLT_HELPER(460800, 5)
DECL_ERISTA_GPU_VOLT_HELPER(537600, 6)
DECL_ERISTA_GPU_VOLT_HELPER(614400, 7)
DECL_ERISTA_GPU_VOLT_HELPER(691200, 8)
DECL_ERISTA_GPU_VOLT_HELPER(768000, 9)
DECL_ERISTA_GPU_VOLT_HELPER(844800, 10)
DECL_ERISTA_GPU_VOLT_HELPER(921600, 11)
DECL_ERISTA_GPU_VOLT_HELPER(998400, 12)
DECL_ERISTA_GPU_VOLT_HELPER(1075200, 13)
DECL_ERISTA_GPU_VOLT_HELPER(1152000, 14)
DECL_ERISTA_GPU_VOLT_HELPER(1228800, 15)
DECL_ERISTA_GPU_VOLT_HELPER(1267200, 16)
DECL_ERISTA_GPU_VOLT_HELPER(1305600, 17)
DECL_ERISTA_GPU_VOLT_HELPER(1344000, 18)
DECL_ERISTA_GPU_VOLT_HELPER(1382400, 19)
DECL_ERISTA_GPU_VOLT_HELPER(1420800, 20)
DECL_ERISTA_GPU_VOLT_HELPER(1459200, 21)
DECL_ERISTA_GPU_VOLT_HELPER(1497600, 22)
DECL_ERISTA_GPU_VOLT_HELPER(1536000, 23)
DECL_MARIKO_GPU_VOLT_HELPER(76800, 0)
DECL_MARIKO_GPU_VOLT_HELPER(153600, 1)
@@ -372,6 +379,13 @@ DECL_MARIKO_GPU_VOLT_HELPER(1420800, 20)
DECL_MARIKO_GPU_VOLT_HELPER(1459200, 21)
DECL_MARIKO_GPU_VOLT_HELPER(1497600, 22)
DECL_MARIKO_GPU_VOLT_HELPER(1536000, 23)
DECL_MARIKO_GPU_VOLT_HELPER(1574400, 24)
DECL_MARIKO_GPU_VOLT_HELPER(1612800, 25)
DECL_MARIKO_GPU_VOLT_HELPER(1651200, 26)
DECL_MARIKO_GPU_VOLT_HELPER(1689600, 27)
DECL_MARIKO_GPU_VOLT_HELPER(1728000, 28)
DECL_MARIKO_GPU_VOLT_HELPER(1766400, 29)
DECL_MARIKO_GPU_VOLT_HELPER(1804800, 30)
#define DECL_ERISTA_GPU_VOLT_GET(freq, idx) \
@@ -387,33 +401,32 @@ static inline u32 cust_get_mariko_gpu_volt_##freq##_val(const char* p) { \
return cust_get_mariko_gpu_volt(&t, idx); \
}
DECL_ERISTA_GPU_VOLT_GET(76800, 0)
DECL_ERISTA_GPU_VOLT_GET(115200, 1)
DECL_ERISTA_GPU_VOLT_GET(153600, 2)
DECL_ERISTA_GPU_VOLT_GET(192000, 3)
DECL_ERISTA_GPU_VOLT_GET(230400, 4)
DECL_ERISTA_GPU_VOLT_GET(268800, 5)
DECL_ERISTA_GPU_VOLT_GET(307200, 6)
DECL_ERISTA_GPU_VOLT_GET(345600, 7)
DECL_ERISTA_GPU_VOLT_GET(384000, 8)
DECL_ERISTA_GPU_VOLT_GET(422400, 9)
DECL_ERISTA_GPU_VOLT_GET(460800, 10)
DECL_ERISTA_GPU_VOLT_GET(499200, 11)
DECL_ERISTA_GPU_VOLT_GET(537600, 12)
DECL_ERISTA_GPU_VOLT_GET(576000, 13)
DECL_ERISTA_GPU_VOLT_GET(614400, 14)
DECL_ERISTA_GPU_VOLT_GET(652800, 15)
DECL_ERISTA_GPU_VOLT_GET(691200, 16)
DECL_ERISTA_GPU_VOLT_GET(729600, 17)
DECL_ERISTA_GPU_VOLT_GET(768000, 18)
DECL_ERISTA_GPU_VOLT_GET(806400, 19)
DECL_ERISTA_GPU_VOLT_GET(844800, 20)
DECL_ERISTA_GPU_VOLT_GET(883200, 21)
DECL_ERISTA_GPU_VOLT_GET(921600, 22)
DECL_ERISTA_GPU_VOLT_GET(960000, 23)
DECL_ERISTA_GPU_VOLT_GET(998400, 24)
DECL_ERISTA_GPU_VOLT_GET(1036800, 25)
DECL_ERISTA_GPU_VOLT_GET(1075200, 26)
DECL_ERISTA_GPU_VOLT_GET(153600, 1)
DECL_ERISTA_GPU_VOLT_GET(230400, 2)
DECL_ERISTA_GPU_VOLT_GET(307200, 3)
DECL_ERISTA_GPU_VOLT_GET(384000, 4)
DECL_ERISTA_GPU_VOLT_GET(460800, 5)
DECL_ERISTA_GPU_VOLT_GET(537600, 6)
DECL_ERISTA_GPU_VOLT_GET(614400, 7)
DECL_ERISTA_GPU_VOLT_GET(691200, 8)
DECL_ERISTA_GPU_VOLT_GET(768000, 9)
DECL_ERISTA_GPU_VOLT_GET(844800, 10)
DECL_ERISTA_GPU_VOLT_GET(921600, 11)
DECL_ERISTA_GPU_VOLT_GET(998400, 12)
DECL_ERISTA_GPU_VOLT_GET(1075200, 13)
DECL_ERISTA_GPU_VOLT_GET(1152000, 14)
DECL_ERISTA_GPU_VOLT_GET(1228800, 15)
DECL_ERISTA_GPU_VOLT_GET(1267200, 16)
DECL_ERISTA_GPU_VOLT_GET(1305600, 17)
DECL_ERISTA_GPU_VOLT_GET(1344000, 18)
DECL_ERISTA_GPU_VOLT_GET(1382400, 19)
DECL_ERISTA_GPU_VOLT_GET(1420800, 20)
DECL_ERISTA_GPU_VOLT_GET(1459200, 21)
DECL_ERISTA_GPU_VOLT_GET(1497600, 22)
DECL_ERISTA_GPU_VOLT_GET(1536000, 23)
DECL_MARIKO_GPU_VOLT_GET(76800, 0)
DECL_MARIKO_GPU_VOLT_GET(153600, 1)
@@ -438,4 +451,11 @@ DECL_MARIKO_GPU_VOLT_GET(1382400, 19)
DECL_MARIKO_GPU_VOLT_GET(1420800, 20)
DECL_MARIKO_GPU_VOLT_GET(1459200, 21)
DECL_MARIKO_GPU_VOLT_GET(1497600, 22)
DECL_MARIKO_GPU_VOLT_GET(1536000, 23)
DECL_MARIKO_GPU_VOLT_GET(1536000, 23)
DECL_MARIKO_GPU_VOLT_GET(1574400, 24)
DECL_MARIKO_GPU_VOLT_GET(1612800, 25)
DECL_MARIKO_GPU_VOLT_GET(1651200, 26)
DECL_MARIKO_GPU_VOLT_GET(1689600, 27)
DECL_MARIKO_GPU_VOLT_GET(1728000, 28)
DECL_MARIKO_GPU_VOLT_GET(1766400, 29)
DECL_MARIKO_GPU_VOLT_GET(1804800, 30)

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

12
dist/README.md vendored
View File

@@ -56,7 +56,6 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
```
kip1=atmosphere/kips/hoc.kip
secmon=exosphere.bin
```
*(No changes needed if using fusee.)*
@@ -114,6 +113,9 @@ Refer to COMPILATION.md
* 816
* 714
* 612 → sleep mode
**Notes:**
1. On Erista, CPU in handheld is capped to 1581MHz
### GPU clocks
* 1536 → absolute max clock on mariko. very dangerous
@@ -140,8 +142,10 @@ Refer to COMPILATION.md
* 76 → boost mode
**Notes:**
1. GPU overclock is capped at 460MHz in handheld and capped at 768MHz if charging, unless you're using the official charger.
2. Clocks higher than 768MHz need the official charger is plugged in.
1. GPU overclock is capped at 460MHz on erista in handheld
2. On Mariko, cap with No uv is 614MHz, with SLT it is 691MHz and with HiOPT it's 768MHz
3. Clocks higher than 768MHz on erista need the official charger is plugged in.
4. On Mariko, cap with No uv is 844MHz, with SLT it is 921MHz and with HiOPT it's 998MHz
---
@@ -160,5 +164,5 @@ Refer to COMPILATION.md
* **b0rd2death** Ultrahand sys-clk & Status Monitor fork
* **MasaGratoR and ZachyCatGames** - General help
* **MasaGratoR** - Status Monitor & Display Refresh Rate Driver
* **Dom, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh and Xenshen** - Testing
* **Dom, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh, frost, letum00 and Xenshen** - Testing
* **Samybigio2011** - Italian translations

Binary file not shown.

132
dist/config/horizon-oc/lang/en.json vendored Normal file
View File

@@ -0,0 +1,132 @@
{
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "Edit App Profile",
"Advanced": "Advanced",
"Edit Global Profile": "Edit Global Profile",
"Temporary Overrides": "Temporary Overrides",
"Temporary Overrides Reset": "Temporary Overrides Reset",
"Settings": "Settings",
"Information": "Information",
"Enable": "Enable",
"Uncapped Clocks": "Uncapped Clocks",
"Override Boost Mode": "Override Boost Mode",
"CPU Max Display Clock": "CPU Max Display Clock",
"Thermal Throttle": "Thermal Throttle",
"Thermal Throttle Threshold": "Thermal Throttle Threshold",
"Handheld TDP": "Handheld TDP",
"Handheld TDP Limit": "Handheld TDP Limit",
"Lite TDP Limit": "Lite TDP Limit",
"Enforce Board Limit": "Enforce Board Limit",
"Battery Charge Current": "Battery Charge Current",
"Display Refresh Rate Changing": "Display Refresh Rate Changing",
"Fix CPU Volt Bug": "Fix CPU Volt Bug",
"[cfg] no enum format string": "[cfg] no enum format string",
"KIP": "KIP",
"Save KIP Settings": "Save KIP Settings",
"RAM Settings": "RAM Settings",
"CPU Settings": "CPU Settings",
"GPU Settings": "GPU Settings",
"Experimental": "Experimental",
"Charge Current Override": "Charge Current Override",
"Disabled": "Disabled",
"HP Mode": "HP Mode",
"EMC Max Clock": "EMC Max Clock",
"EMC VDD2 Voltage": "EMC VDD2 Voltage",
"EMC VDDQ Voltage": "EMC VDDQ Voltage",
"DVB Shift": "DVB Shift",
"Memory Timings": "Memory Timings",
"Memory Latencies": "Memory Latencies",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "Update RAM Timings",
"\uE150 This feature is EXPERIMENTAL": "\uE150 This feature is EXPERIMENTAL",
"and should only be used for testing!": "and should only be used for testing!",
"Read Latency": "Read Latency",
"Write Latency": "Write Latency",
"CPU UV": "CPU UV",
"CPU Unlock": "CPU Unlock",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "CPU Max Voltage",
"CPU UV Table": "CPU UV Table",
"CPU Low UV": "CPU Low UV",
"CPU High UV": "CPU High UV",
"CPU Max Clock": "CPU Max Clock",
"CPU Low VMIN": "CPU Low VMIN",
"CPU High VMIN": "CPU High VMIN",
"GPU Undervolt Table": "GPU Undervolt Table",
"Calculate GPU Vmin": "Calculate GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU VMAX": "GPU VMAX",
"GPU Volt Offset": "GPU Volt Offset",
"GPU Custom Table": "GPU Custom Table",
"GPU Custom Table (mV)": "GPU Custom Table (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 Setting GPU Clocks past",
"1075MHz without UV, 1152MHz on SLT or ": "1075MHz without UV, 1152MHz on SLT or ",
"1228MHz on HiOPT can cause ": "1228MHz on HiOPT can cause ",
"permanent damage to your Switch!": "permanent damage to your Switch!",
"Proceed at your own risk!": "Proceed at your own risk!",
"921MHz without UV and 960MHz on": "921MHz without UV and 960MHz on",
"SLT or HiOPT can cause ": "SLT or HiOPT can cause ",
"Auto": "Auto",
"Sleep Mode": "Sleep Mode",
"Stock": "Stock",
"Dev OC": "Dev OC",
"Boost Mode": "Boost Mode",
"Safe Max": "Safe Max",
"Unsafe Max": "Unsafe Max",
"Absolute Max": "Absolute Max",
"Boost Mode & Safe Max": "Boost Mode & Safe Max",
"Official Rating": "Official Rating",
"Default (Mariko)": "Default (Mariko)",
"Default (Erista)": "Default (Erista)",
"Rating": "Rating",
"Safe Max (Mariko)": "Safe Max (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"Default": "Default",
"1581MHz Tbreak": "1581MHz Tbreak",
"1683MHz Tbreak": "1683MHz Tbreak",
"Extreme UV Table": "Extreme UV Table",
"No UV": "No UV",
"SLT Table": "SLT Table",
"HiOPT Table": "HiOPT Table",
"Power": "Power",
"Temp": "Temp",
"Voltage": "Voltage",
"TDP Threshold": "TDP Threshold",
"Lite TDP Threshold": "Lite TDP Threshold",
"Thermal Throttle Limit": "Thermal Throttle Limit",
"1600BL": "1600BL",
"1866BL": "1866BL",
"2133BL": "2133BL",
"BAT": "BAT",
"FAN": "FAN",
"DISP": "DISP",
"Board": "Board",
"Skin": "Skin",
"Now": "Now",
"Avg": "Avg",
"App ID": "App ID",
"Profile": "Profile",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "Memory",
"Display": "Display",
"Governor": "Governor",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "Docked",
"Handheld": "Handheld",
"Charging": "Charging",
"USB Charger": "USB Charger",
"PD Charger": "PD Charger",
"VDD2": "VDD2",
"VDDQ": "VDDQ",
"GPU DVFS": "GPU DVFS"
}

35
dist/config/horizon-oc/lang/es.json vendored Normal file
View File

@@ -0,0 +1,35 @@
{
"Edit App Profile": "Editar perfil de la app",
"Advanced": "Avanzado",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Anulaciones temporales",
"Temporary Overrides   Reset": "Anulaciones temporales   Reiniciar",
"Settings": "Configuración",
"Enable": "Habilitar",
"Uncapped Clocks": "Relojes sin límite",
"Override Boost Mode": "Sobrescribir modo Boost",
"Auto CPU Boost": "Impulso automático de CPU",
"Sync ReverseNX": "Sincronizar con ReverseNX",
"GPU DVFS": "GPU DVFS",
"Off": "Apagado",
"Official Service Method": "Método de servicio oficial",
"Hijack Method": "Método de secuestro",
"App ID": "ID App",
"EOS mode": "Modo EOS",
"Skin": "Tema",
"Now": "Ahora",
"Avg": "Med",
"Docked": "Conectado al dock",
"Handheld": "Portátil",
"Charging": "Cargando",
"PD Charger": "Cargador oficial",
"USB Charger": "Cargador USB",
"Docked   Reset": "Conectado al dock   Reiniciar",
"Handheld   Reset": "Portátil   Reiniciar",
"Charging   Reset": "Cargando   Reiniciar",
"PD Charger   Reset": "Cargador oficial   Reiniciar",
"USB Charger   Reset": "Cargador USB   Reiniciar",
"Memory": "Memoria",
"Default": "No sobrescribir",
"Profile": "Perfil"
}

132
dist/config/horizon-oc/lang/it.json vendored Normal file
View File

@@ -0,0 +1,132 @@
{
"Information about Translation": "This is a translation made by Samybigio2011. If you find any errors, please report them on GitHub, or feel free to contribute!",
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "Profilo App",
"Advanced": "Avanzate",
"Edit Global Profile": "Profilo Globale",
"Temporary Overrides": "Override Temporaneo",
"Temporary Overrides Reset": "Temporary Overrides Reset",
"Settings": "Impostazioni",
"Information": "Informazioni",
"Enable": "Abilita",
"Uncapped Clocks": "Sblocca Clock",
"Override Boost Mode": "Sovrascrivi Boost Mode",
"CPU Max Display Clock": "Massimo Clock CPU mostrato",
"Thermal Throttle": "Rallentamento Termico",
"Thermal Throttle Threshold": "Soglia Rallentamento Termico",
"Handheld TDP": "TPD Handheld",
"Handheld TDP Limit": "Limite TDP Handheld",
"Lite TDP Limit": "Limite TDP Lite",
"Enforce Board Limit": "Forza Limite di Potenza",
"Battery Charge Current": "Corrente di Ricarica",
"Display Refresh Rate Changing": "Cambio di Frequenza Display",
"Fix CPU Volt Bug": "Risolvi Bug CPU",
"[cfg] no enum format string": "[cfg] no enum format string",
"KIP": "KIP",
"Save KIP Settings": "Salva Impotazioni KIP",
"RAM Settings": "Impostazioni RAM",
"CPU Settings": "Impostazioni CPU",
"GPU Settings": "Impostazioni GPU",
"Experimental": "Esperimentale",
"Charge Current Override": "Sovrascrivi Corrente di Ricarica",
"Disabled": "Disabilitato",
"HP Mode": "Modalità HP",
"EMC Max Clock": "Clock EMC Massimo",
"EMC VDD2 Voltage": "Voltaggio VDD2 EMC",
"EMC VDDQ Voltage": "Voltaggio VDDQ EMC",
"DVB Shift": "Shift DVB",
"Memory Timings": "Timing Memoria",
"Memory Latencies": "Latency Memoria",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "Aggiorna Timing RAM",
"\uE150 This feature is EXPERIMENTAL": "\uE150 Questa funzione è ESPERIMENRALE!",
"and should only be used for testing!": "e dovrebbe essere usata solo per testare!",
"Read Latency": "Latency Lettura",
"Write Latency": "Latency Scrittura",
"CPU UV": "UV CPU",
"CPU Unlock": "Sblocco CPU",
"CPU VMIN": "VMIN CPU",
"CPU Max Voltage": "Voltaggio Massimo CPU",
"CPU UV Table": "Tavola UV CPU",
"CPU Low UV": "UV Basso CPU",
"CPU High UV": "UV Alto CPU",
"CPU Max Clock": "Clock Massimo CPU",
"CPU Low VMIN": "VMIN Basso CPU",
"CPU High VMIN": "VMIN Alto CPU",
"GPU Undervolt Table": "Tavola Undervolt GPU",
"Calculate GPU Vmin": "Calcola VMIN GPU",
"GPU VMIN": "VMIN GPU",
"GPU VMAX": "VMAX GPU",
"GPU Volt Offset": "Offset Voltaggio GPU",
"GPU Custom Table": "Tavola GPU Custom",
"GPU Custom Table (mV)": "Tavola GPU Custom (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 Impostare Clock GPU oltre",
"1075MHz without UV, 1152MHz on SLT or ": "1075MHz senza UV, 1152MHz su SLT o ",
"1228MHz on HiOPT can cause ": "1228MHz su HiOPT può causare ",
"permanent damage to your Switch!": "danni permanenti alla tua console!",
"Proceed at your own risk!": "Procedi al tuo rischio!",
"921MHz without UV and 960MHz on": "921MHz senza UV e 960MHz su",
"SLT or HiOPT can cause ": "SLT o HiOPT può causare ",
"Auto": "Auto",
"Sleep Mode": "Modalità Sleep",
"Stock": "Stock",
"Dev OC": "OC Sviluppo",
"Boost Mode": "Modalità Boost",
"Safe Max": "Massimo Sicuro",
"Unsafe Max": "Massimo Insicuro",
"Absolute Max": "Massimo Assoluto",
"Boost Mode & Safe Max": "Modalità Boost e Massimo Sicuro",
"Official Rating": "Rating Ufficiale",
"Default (Mariko)": "Default (Mariko)",
"Default (Erista)": "Default (Erista)",
"Rating": "Rating",
"Safe Max (Mariko)": "Max Sicuro (Mariko)",
"Safe Max (Erista)": "Max Sicuro (Erista)",
"Default": "Default",
"1581MHz Tbreak": "Tbreak 1581MHz",
"1683MHz Tbreak": "Tbreak 1683MHz",
"Extreme UV Table": "Tavola UV Estremo",
"No UV": "No UV",
"SLT Table": "Tavola SLT",
"HiOPT Table": "Tavola HiOPT",
"Power": "Potenza",
"Temp": "Temperatura",
"Voltage": "Voltaggio",
"TDP Threshold": "Soglia TDP",
"Lite TDP Threshold": "Soglia TDP Lite",
"Thermal Throttle Limit": "Limite Rallentamento Termico",
"1600BL": "BL1600",
"1866BL": "BL1866",
"2133BL": "BL2133",
"BAT": "BAT",
"FAN": "FAN",
"DISP": "DISP",
"Board": "Scheda",
"Skin": "Skin",
"Now": "Ora",
"Avg": "Med",
"App ID": "ID App",
"Profile": "Profilo",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "Memoria",
"Display": "Display",
"Governor": "Governor",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "Dock",
"Handheld": "Handheld",
"Charging": "In Carica",
"USB Charger": "Caricatore USB",
"PD Charger": "Caricatore PD",
"VDD2": "VDD2",
"VDDQ": "VDDQ"
}

132
dist/config/horizon-oc/lang/lang/en.json vendored Normal file
View File

@@ -0,0 +1,132 @@
{
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "Edit App Profile",
"Advanced": "Advanced",
"Edit Global Profile": "Edit Global Profile",
"Temporary Overrides": "Temporary Overrides",
"Temporary Overrides Reset": "Temporary Overrides Reset",
"Settings": "Settings",
"Information": "Information",
"Enable": "Enable",
"Uncapped Clocks": "Uncapped Clocks",
"Override Boost Mode": "Override Boost Mode",
"CPU Max Display Clock": "CPU Max Display Clock",
"Thermal Throttle": "Thermal Throttle",
"Thermal Throttle Threshold": "Thermal Throttle Threshold",
"Handheld TDP": "Handheld TDP",
"Handheld TDP Limit": "Handheld TDP Limit",
"Lite TDP Limit": "Lite TDP Limit",
"Enforce Board Limit": "Enforce Board Limit",
"Battery Charge Current": "Battery Charge Current",
"Display Refresh Rate Changing": "Display Refresh Rate Changing",
"Fix CPU Volt Bug": "Fix CPU Volt Bug",
"[cfg] no enum format string": "[cfg] no enum format string",
"KIP": "KIP",
"Save KIP Settings": "Save KIP Settings",
"RAM Settings": "RAM Settings",
"CPU Settings": "CPU Settings",
"GPU Settings": "GPU Settings",
"Experimental": "Experimental",
"Charge Current Override": "Charge Current Override",
"Disabled": "Disabled",
"HP Mode": "HP Mode",
"EMC Max Clock": "EMC Max Clock",
"EMC VDD2 Voltage": "EMC VDD2 Voltage",
"EMC VDDQ Voltage": "EMC VDDQ Voltage",
"DVB Shift": "DVB Shift",
"Memory Timings": "Memory Timings",
"Memory Latencies": "Memory Latencies",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "Update RAM Timings",
"\uE150 This feature is EXPERIMENTAL": "\uE150 This feature is EXPERIMENTAL",
"and should only be used for testing!": "and should only be used for testing!",
"Read Latency": "Read Latency",
"Write Latency": "Write Latency",
"CPU UV": "CPU UV",
"CPU Unlock": "CPU Unlock",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "CPU Max Voltage",
"CPU UV Table": "CPU UV Table",
"CPU Low UV": "CPU Low UV",
"CPU High UV": "CPU High UV",
"CPU Max Clock": "CPU Max Clock",
"CPU Low VMIN": "CPU Low VMIN",
"CPU High VMIN": "CPU High VMIN",
"GPU Undervolt Table": "GPU Undervolt Table",
"Calculate GPU Vmin": "Calculate GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU VMAX": "GPU VMAX",
"GPU Volt Offset": "GPU Volt Offset",
"GPU Custom Table": "GPU Custom Table",
"GPU Custom Table (mV)": "GPU Custom Table (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 Setting GPU Clocks past",
"1075MHz without UV, 1152MHz on SLT or ": "1075MHz without UV, 1152MHz on SLT or ",
"1228MHz on HiOPT can cause ": "1228MHz on HiOPT can cause ",
"permanent damage to your Switch!": "permanent damage to your Switch!",
"Proceed at your own risk!": "Proceed at your own risk!",
"921MHz without UV and 960MHz on": "921MHz without UV and 960MHz on",
"SLT or HiOPT can cause ": "SLT or HiOPT can cause ",
"Auto": "Auto",
"Sleep Mode": "Sleep Mode",
"Stock": "Stock",
"Dev OC": "Dev OC",
"Boost Mode": "Boost Mode",
"Safe Max": "Safe Max",
"Unsafe Max": "Unsafe Max",
"Absolute Max": "Absolute Max",
"Boost Mode & Safe Max": "Boost Mode & Safe Max",
"Official Rating": "Official Rating",
"Default (Mariko)": "Default (Mariko)",
"Default (Erista)": "Default (Erista)",
"Rating": "Rating",
"Safe Max (Mariko)": "Safe Max (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"Default": "Default",
"1581MHz Tbreak": "1581MHz Tbreak",
"1683MHz Tbreak": "1683MHz Tbreak",
"Extreme UV Table": "Extreme UV Table",
"No UV": "No UV",
"SLT Table": "SLT Table",
"HiOPT Table": "HiOPT Table",
"Power": "Power",
"Temp": "Temp",
"Voltage": "Voltage",
"TDP Threshold": "TDP Threshold",
"Lite TDP Threshold": "Lite TDP Threshold",
"Thermal Throttle Limit": "Thermal Throttle Limit",
"1600BL": "1600BL",
"1866BL": "1866BL",
"2133BL": "2133BL",
"BAT": "BAT",
"FAN": "FAN",
"DISP": "DISP",
"Board": "Board",
"Skin": "Skin",
"Now": "Now",
"Avg": "Avg",
"App ID": "App ID",
"Profile": "Profile",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "Memory",
"Display": "Display",
"Governor": "Governor",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "Docked",
"Handheld": "Handheld",
"Charging": "Charging",
"USB Charger": "USB Charger",
"PD Charger": "PD Charger",
"VDD2": "VDD2",
"VDDQ": "VDDQ",
"GPU DVFS": "GPU DVFS"
}

View File

@@ -0,0 +1,35 @@
{
"Edit App Profile": "Editar perfil de la app",
"Advanced": "Avanzado",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Anulaciones temporales",
"Temporary Overrides   Reset": "Anulaciones temporales   Reiniciar",
"Settings": "Configuración",
"Enable": "Habilitar",
"Uncapped Clocks": "Relojes sin límite",
"Override Boost Mode": "Sobrescribir modo Boost",
"Auto CPU Boost": "Impulso automático de CPU",
"Sync ReverseNX": "Sincronizar con ReverseNX",
"GPU DVFS": "GPU DVFS",
"Off": "Apagado",
"Official Service Method": "Método de servicio oficial",
"Hijack Method": "Método de secuestro",
"App ID": "ID App",
"EOS mode": "Modo EOS",
"Skin": "Tema",
"Now": "Ahora",
"Avg": "Med",
"Docked": "Conectado al dock",
"Handheld": "Portátil",
"Charging": "Cargando",
"PD Charger": "Cargador oficial",
"USB Charger": "Cargador USB",
"Docked   Reset": "Conectado al dock   Reiniciar",
"Handheld   Reset": "Portátil   Reiniciar",
"Charging   Reset": "Cargando   Reiniciar",
"PD Charger   Reset": "Cargador oficial   Reiniciar",
"USB Charger   Reset": "Cargador USB   Reiniciar",
"Memory": "Memoria",
"Default": "No sobrescribir",
"Profile": "Perfil"
}

132
dist/config/horizon-oc/lang/lang/it.json vendored Normal file
View File

@@ -0,0 +1,132 @@
{
"Information about Translation": "This is a translation made by Samybigio2011. If you find any errors, please report them on GitHub, or feel free to contribute!",
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "Profilo App",
"Advanced": "Avanzate",
"Edit Global Profile": "Profilo Globale",
"Temporary Overrides": "Override Temporaneo",
"Temporary Overrides Reset": "Temporary Overrides Reset",
"Settings": "Impostazioni",
"Information": "Informazioni",
"Enable": "Abilita",
"Uncapped Clocks": "Sblocca Clock",
"Override Boost Mode": "Sovrascrivi Boost Mode",
"CPU Max Display Clock": "Massimo Clock CPU mostrato",
"Thermal Throttle": "Rallentamento Termico",
"Thermal Throttle Threshold": "Soglia Rallentamento Termico",
"Handheld TDP": "TPD Handheld",
"Handheld TDP Limit": "Limite TDP Handheld",
"Lite TDP Limit": "Limite TDP Lite",
"Enforce Board Limit": "Forza Limite di Potenza",
"Battery Charge Current": "Corrente di Ricarica",
"Display Refresh Rate Changing": "Cambio di Frequenza Display",
"Fix CPU Volt Bug": "Risolvi Bug CPU",
"[cfg] no enum format string": "[cfg] no enum format string",
"KIP": "KIP",
"Save KIP Settings": "Salva Impotazioni KIP",
"RAM Settings": "Impostazioni RAM",
"CPU Settings": "Impostazioni CPU",
"GPU Settings": "Impostazioni GPU",
"Experimental": "Esperimentale",
"Charge Current Override": "Sovrascrivi Corrente di Ricarica",
"Disabled": "Disabilitato",
"HP Mode": "Modalità HP",
"EMC Max Clock": "Clock EMC Massimo",
"EMC VDD2 Voltage": "Voltaggio VDD2 EMC",
"EMC VDDQ Voltage": "Voltaggio VDDQ EMC",
"DVB Shift": "Shift DVB",
"Memory Timings": "Timing Memoria",
"Memory Latencies": "Latency Memoria",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "Aggiorna Timing RAM",
"\uE150 This feature is EXPERIMENTAL": "\uE150 Questa funzione è ESPERIMENRALE!",
"and should only be used for testing!": "e dovrebbe essere usata solo per testare!",
"Read Latency": "Latency Lettura",
"Write Latency": "Latency Scrittura",
"CPU UV": "UV CPU",
"CPU Unlock": "Sblocco CPU",
"CPU VMIN": "VMIN CPU",
"CPU Max Voltage": "Voltaggio Massimo CPU",
"CPU UV Table": "Tavola UV CPU",
"CPU Low UV": "UV Basso CPU",
"CPU High UV": "UV Alto CPU",
"CPU Max Clock": "Clock Massimo CPU",
"CPU Low VMIN": "VMIN Basso CPU",
"CPU High VMIN": "VMIN Alto CPU",
"GPU Undervolt Table": "Tavola Undervolt GPU",
"Calculate GPU Vmin": "Calcola VMIN GPU",
"GPU VMIN": "VMIN GPU",
"GPU VMAX": "VMAX GPU",
"GPU Volt Offset": "Offset Voltaggio GPU",
"GPU Custom Table": "Tavola GPU Custom",
"GPU Custom Table (mV)": "Tavola GPU Custom (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 Impostare Clock GPU oltre",
"1075MHz without UV, 1152MHz on SLT or ": "1075MHz senza UV, 1152MHz su SLT o ",
"1228MHz on HiOPT can cause ": "1228MHz su HiOPT può causare ",
"permanent damage to your Switch!": "danni permanenti alla tua console!",
"Proceed at your own risk!": "Procedi al tuo rischio!",
"921MHz without UV and 960MHz on": "921MHz senza UV e 960MHz su",
"SLT or HiOPT can cause ": "SLT o HiOPT può causare ",
"Auto": "Auto",
"Sleep Mode": "Modalità Sleep",
"Stock": "Stock",
"Dev OC": "OC Sviluppo",
"Boost Mode": "Modalità Boost",
"Safe Max": "Massimo Sicuro",
"Unsafe Max": "Massimo Insicuro",
"Absolute Max": "Massimo Assoluto",
"Boost Mode & Safe Max": "Modalità Boost e Massimo Sicuro",
"Official Rating": "Rating Ufficiale",
"Default (Mariko)": "Default (Mariko)",
"Default (Erista)": "Default (Erista)",
"Rating": "Rating",
"Safe Max (Mariko)": "Max Sicuro (Mariko)",
"Safe Max (Erista)": "Max Sicuro (Erista)",
"Default": "Default",
"1581MHz Tbreak": "Tbreak 1581MHz",
"1683MHz Tbreak": "Tbreak 1683MHz",
"Extreme UV Table": "Tavola UV Estremo",
"No UV": "No UV",
"SLT Table": "Tavola SLT",
"HiOPT Table": "Tavola HiOPT",
"Power": "Potenza",
"Temp": "Temperatura",
"Voltage": "Voltaggio",
"TDP Threshold": "Soglia TDP",
"Lite TDP Threshold": "Soglia TDP Lite",
"Thermal Throttle Limit": "Limite Rallentamento Termico",
"1600BL": "BL1600",
"1866BL": "BL1866",
"2133BL": "BL2133",
"BAT": "BAT",
"FAN": "FAN",
"DISP": "DISP",
"Board": "Scheda",
"Skin": "Skin",
"Now": "Ora",
"Avg": "Med",
"App ID": "ID App",
"Profile": "Profilo",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "Memoria",
"Display": "Display",
"Governor": "Governor",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "Dock",
"Handheld": "Handheld",
"Charging": "In Carica",
"USB Charger": "Caricatore USB",
"PD Charger": "Caricatore PD",
"VDD2": "VDD2",
"VDDQ": "VDDQ"
}

View File

@@ -0,0 +1,133 @@
{
"Information about Translation": "This is a machine translation. If you find any errors, please report them on GitHub, or feel free to contribute!",
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "编辑应用配置",
"Advanced": "高级",
"Edit Global Profile": "编辑全局配置",
"Temporary Overrides": "临时覆盖",
"Temporary Overrides Reset": "临时覆盖 重置",
"Settings": "设置",
"Information": "信息",
"Enable": "启用",
"Uncapped Clocks": "解除频率上限",
"Override Boost Mode": "覆盖加速模式",
"CPU Max Display Clock": "CPU 最大显示频率",
"Thermal Throttle": "温度节流",
"Thermal Throttle Threshold": "温度节流阈值",
"Handheld TDP": "掌机模式 TDP",
"Handheld TDP Limit": "掌机模式 TDP 限制",
"Lite TDP Limit": "Lite TDP 限制",
"Enforce Board Limit": "强制主板限制",
"Battery Charge Current": "电池充电电流",
"Display Refresh Rate Changing": "显示刷新率变更",
"Fix CPU Volt Bug": "修复 CPU 电压错误",
"[cfg] no enum format string": "[cfg] 无枚举格式字符串",
"KIP": "KIP",
"Save KIP Settings": "保存 KIP 设置",
"RAM Settings": "内存设置",
"CPU Settings": "CPU 设置",
"GPU Settings": "GPU 设置",
"Experimental": "实验性功能",
"Charge Current Override": "充电电流覆盖",
"Disabled": "禁用",
"HP Mode": "高性能模式",
"EMC Max Clock": "EMC 最大频率",
"EMC VDD2 Voltage": "EMC VDD2 电压",
"EMC VDDQ Voltage": "EMC VDDQ 电压",
"DVB Shift": "DVB 偏移",
"Memory Timings": "内存时序",
"Memory Latencies": "内存延迟",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "更新内存时序",
"\uE150 This feature is EXPERIMENTAL": "\uE150 此功能为实验性功能",
"and should only be used for testing!": "仅应用于测试!",
"Read Latency": "读取延迟",
"Write Latency": "写入延迟",
"CPU UV": "CPU 降压",
"CPU Unlock": "CPU 解锁",
"CPU VMIN": "CPU 最低电压",
"CPU Max Voltage": "CPU 最大电压",
"CPU UV Table": "CPU 降压表",
"CPU Low UV": "CPU 低频降压",
"CPU High UV": "CPU 高频降压",
"CPU Max Clock": "CPU 最大频率",
"CPU Low VMIN": "CPU 低频最低电压",
"CPU High VMIN": "CPU 高频最低电压",
"GPU Undervolt Table": "GPU 降压表",
"Calculate GPU Vmin": "计算 GPU 最低电压",
"GPU VMIN": "GPU 最低电压",
"GPU VMAX": "GPU 最大电压",
"GPU Volt Offset": "GPU 电压偏移",
"GPU Custom Table": "GPU 自定义表",
"GPU Custom Table (mV)": "GPU 自定义表 (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 将 GPU 频率设置超过",
"1075MHz without UV, 1152MHz on SLT or ": "无降压时的 1075MHz、SLT 时的 1152MHz 或",
"1228MHz on HiOPT can cause ": "HiOPT 时的 1228MHz 可能会造成",
"permanent damage to your Switch!": "对您的 Switch 造成永久性损坏!",
"Proceed at your own risk!": "风险自负!",
"921MHz without UV and 960MHz on": "无降压时的 921MHz 和",
"SLT or HiOPT can cause ": "SLT 或 HiOPT 时的 960MHz 可能会造成",
"Auto": "自动",
"Sleep Mode": "休眠模式",
"Stock": "默认",
"Dev OC": "开发超频",
"Boost Mode": "加速模式",
"Safe Max": "安全最大值",
"Unsafe Max": "不安全最大值",
"Absolute Max": "绝对最大值",
"Boost Mode & Safe Max": "加速模式 & 安全最大值",
"Official Rating": "官方额定值",
"Default (Mariko)": "默认 (Mariko)",
"Default (Erista)": "默认 (Erista)",
"Rating": "额定值",
"Safe Max (Mariko)": "安全最大值 (Mariko)",
"Safe Max (Erista)": "安全最大值 (Erista)",
"Default": "默认",
"1581MHz Tbreak": "1581MHz Tbreak",
"1683MHz Tbreak": "1683MHz Tbreak",
"Extreme UV Table": "极限降压表",
"No UV": "不降压",
"SLT Table": "SLT 表",
"HiOPT Table": "HiOPT 表",
"Power": "功耗",
"Temp": "温度",
"Voltage": "电压",
"TDP Threshold": "TDP 阈值",
"Lite TDP Threshold": "Lite TDP 阈值",
"Thermal Throttle Limit": "温度节流限制",
"1600BL": "1600BL",
"1866BL": "1866BL",
"2133BL": "2133BL",
"BAT": "电池",
"FAN": "风扇",
"DISP": "显示",
"Board": "主板",
"Skin": "外壳",
"Now": "当前",
"Avg": "平均",
"App ID": "应用 ID",
"Profile": "配置",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "内存",
"Display": "显示",
"Governor": "调速器",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "底座模式",
"Handheld": "掌机模式",
"Charging": "充电中",
"USB Charger": "USB 充电器",
"PD Charger": "PD 充电器",
"VDD2": "VDD2",
"VDDQ": "VDDQ",
"GPU DVFS": "GPU DVFS"
}

133
dist/config/horizon-oc/lang/zh-cn.json vendored Normal file
View File

@@ -0,0 +1,133 @@
{
"Information about Translation": "This is a machine translation. If you find any errors, please report them on GitHub, or feel free to contribute!",
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "编辑应用配置",
"Advanced": "高级",
"Edit Global Profile": "编辑全局配置",
"Temporary Overrides": "临时覆盖",
"Temporary Overrides Reset": "临时覆盖 重置",
"Settings": "设置",
"Information": "信息",
"Enable": "启用",
"Uncapped Clocks": "解除频率上限",
"Override Boost Mode": "覆盖加速模式",
"CPU Max Display Clock": "CPU 最大显示频率",
"Thermal Throttle": "温度节流",
"Thermal Throttle Threshold": "温度节流阈值",
"Handheld TDP": "掌机模式 TDP",
"Handheld TDP Limit": "掌机模式 TDP 限制",
"Lite TDP Limit": "Lite TDP 限制",
"Enforce Board Limit": "强制主板限制",
"Battery Charge Current": "电池充电电流",
"Display Refresh Rate Changing": "显示刷新率变更",
"Fix CPU Volt Bug": "修复 CPU 电压错误",
"[cfg] no enum format string": "[cfg] 无枚举格式字符串",
"KIP": "KIP",
"Save KIP Settings": "保存 KIP 设置",
"RAM Settings": "内存设置",
"CPU Settings": "CPU 设置",
"GPU Settings": "GPU 设置",
"Experimental": "实验性功能",
"Charge Current Override": "充电电流覆盖",
"Disabled": "禁用",
"HP Mode": "高性能模式",
"EMC Max Clock": "EMC 最大频率",
"EMC VDD2 Voltage": "EMC VDD2 电压",
"EMC VDDQ Voltage": "EMC VDDQ 电压",
"DVB Shift": "DVB 偏移",
"Memory Timings": "内存时序",
"Memory Latencies": "内存延迟",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "更新内存时序",
"\uE150 This feature is EXPERIMENTAL": "\uE150 此功能为实验性功能",
"and should only be used for testing!": "仅应用于测试!",
"Read Latency": "读取延迟",
"Write Latency": "写入延迟",
"CPU UV": "CPU 降压",
"CPU Unlock": "CPU 解锁",
"CPU VMIN": "CPU 最低电压",
"CPU Max Voltage": "CPU 最大电压",
"CPU UV Table": "CPU 降压表",
"CPU Low UV": "CPU 低频降压",
"CPU High UV": "CPU 高频降压",
"CPU Max Clock": "CPU 最大频率",
"CPU Low VMIN": "CPU 低频最低电压",
"CPU High VMIN": "CPU 高频最低电压",
"GPU Undervolt Table": "GPU 降压表",
"Calculate GPU Vmin": "计算 GPU 最低电压",
"GPU VMIN": "GPU 最低电压",
"GPU VMAX": "GPU 最大电压",
"GPU Volt Offset": "GPU 电压偏移",
"GPU Custom Table": "GPU 自定义表",
"GPU Custom Table (mV)": "GPU 自定义表 (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 将 GPU 频率设置超过",
"1075MHz without UV, 1152MHz on SLT or ": "无降压时的 1075MHz、SLT 时的 1152MHz 或",
"1228MHz on HiOPT can cause ": "HiOPT 时的 1228MHz 可能会造成",
"permanent damage to your Switch!": "对您的 Switch 造成永久性损坏!",
"Proceed at your own risk!": "风险自负!",
"921MHz without UV and 960MHz on": "无降压时的 921MHz 和",
"SLT or HiOPT can cause ": "SLT 或 HiOPT 时的 960MHz 可能会造成",
"Auto": "自动",
"Sleep Mode": "休眠模式",
"Stock": "默认",
"Dev OC": "开发超频",
"Boost Mode": "加速模式",
"Safe Max": "安全最大值",
"Unsafe Max": "不安全最大值",
"Absolute Max": "绝对最大值",
"Boost Mode & Safe Max": "加速模式 & 安全最大值",
"Official Rating": "官方额定值",
"Default (Mariko)": "默认 (Mariko)",
"Default (Erista)": "默认 (Erista)",
"Rating": "额定值",
"Safe Max (Mariko)": "安全最大值 (Mariko)",
"Safe Max (Erista)": "安全最大值 (Erista)",
"Default": "默认",
"1581MHz Tbreak": "1581MHz Tbreak",
"1683MHz Tbreak": "1683MHz Tbreak",
"Extreme UV Table": "极限降压表",
"No UV": "不降压",
"SLT Table": "SLT 表",
"HiOPT Table": "HiOPT 表",
"Power": "功耗",
"Temp": "温度",
"Voltage": "电压",
"TDP Threshold": "TDP 阈值",
"Lite TDP Threshold": "Lite TDP 阈值",
"Thermal Throttle Limit": "温度节流限制",
"1600BL": "1600BL",
"1866BL": "1866BL",
"2133BL": "2133BL",
"BAT": "电池",
"FAN": "风扇",
"DISP": "显示",
"Board": "主板",
"Skin": "外壳",
"Now": "当前",
"Avg": "平均",
"App ID": "应用 ID",
"Profile": "配置",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "内存",
"Display": "显示",
"Governor": "调速器",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "底座模式",
"Handheld": "掌机模式",
"Charging": "充电中",
"USB Charger": "USB 充电器",
"PD Charger": "PD 充电器",
"VDD2": "VDD2",
"VDDQ": "VDDQ",
"GPU DVFS": "GPU DVFS"
}

BIN
dist/exosphere.bin vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.