48 Commits
0.33 ... 0.34

Author SHA1 Message Date
souldbminersmwc
ebcf07dab8 update files 2026-02-07 17:51:38 -05:00
souldbminersmwc
d170ca92ad ldr: rework reserved entries 2026-02-07 17:51:18 -05:00
souldbminersmwc
cab8a14b99 Merge branch 'develop' of https://github.com/Horizon-OC/Horizon-OC into develop 2026-02-06 19:43:48 -05:00
souldbminersmwc
b623dabce5 sysclk: fix 1963mhz bug 2026-02-06 19:42:58 -05:00
Dominator
e5eb49f2e5 Merge pull request #33 from Blaise-25/develop 2026-02-06 01:47:22 +02:00
Blaise-25
9f0a609735 Update README.md 2026-02-05 15:20:12 -08:00
Souldbminer
19a2e562bc Update README.md 2026-02-05 16:12:30 -05:00
souldbminersmwc
73c3311251 Merge branch 'develop' of https://github.com/Horizon-OC/Horizon-OC into develop 2026-02-04 19:33:30 -05:00
souldbminersmwc
eb7fca1c1a erista ram overclock support + reserved entried
if you use hoc-clk 0.33 and want to update follow these steps

go to config/horizon-oc/config.ini
remove these two entries:

crc32=xxxxxxxxxxx
is_first_load=0
2026-02-04 19:33:10 -05:00
Dominator
ad1f070a6b Update README.md 2026-02-05 01:17:10 +02:00
souldbminersmwc
3bad144280 sysclk: add cat script 2026-02-03 19:01:49 -05:00
souldbminersmwc
123d4b6080 Merge branch 'develop' of https://github.com/Horizon-OC/Horizon-OC into develop 2026-02-03 18:57:02 -05:00
souldbminersmwc
2f6ed69b92 sysclk: refine misc gui 2026-02-03 18:56:48 -05:00
Souldbminer
337f7e6ac0 Merge pull request #32 from OEMunlag/develop
proper github actions build
2026-02-03 15:57:29 -05:00
2fort sink
a5efa7ae72 Add files via upload 2026-02-03 16:55:48 -03:00
2fort sink
a8ee389681 Revert to last working
Updated the Docker image for the build container and removed unnecessary steps for creating compiler shims. Added packaging of the dist folder as a ZIP file with the commit SHA.
2026-02-03 16:40:38 -03:00
2fort sink
54554bacea Change Docker image and install switch-dev
Updated the Docker image for the build container and added a step to install switch-dev.
2026-02-03 16:28:09 -03:00
2fort sink
3da2fc4b6d Merge branch 'Horizon-OC:develop' into develop 2026-02-03 15:05:11 -03:00
2fort sink
83287b1f5c Update build.yml 2026-02-02 21:53:24 -03:00
2fort sink
4f6756c609 Update build.yml 2026-02-02 21:29:05 -03:00
souldbminersmwc
ef2434c457 try to fix status monitor issues 2026-02-02 19:13:08 -05:00
2fort sink
b0237a2042 Update build.yml 2026-02-02 21:07:54 -03:00
2fort sink
c6275eb977 Update build.yml 2026-02-02 20:51:49 -03:00
2fort sink
72961aa2f1 Update build.yml 2026-02-02 20:46:58 -03:00
2fort sink
9c60697344 Merge branch 'Horizon-OC:develop' into develop 2026-02-02 20:45:15 -03:00
2fort sink
f786d97de1 Update build.yml 2026-02-02 20:44:06 -03:00
2fort sink
20389043ac Enhance build.yml with ccache shims for compilers
very hacky I know but we also fix exosphere hopefully with this
2026-02-02 20:37:56 -03:00
souldbminersmwc
00b9d8550e ldr: fix erista cpu validator
this DOES NOT fix erista cpu uv, but is probably part of the issue
2026-02-02 18:18:22 -05:00
2fort sink
0c0a4b3d6b Merge branch 'Horizon-OC:develop' into develop 2026-02-01 19:14:07 -03:00
2fort sink
61fd9d74d3 Update build.yml 2026-02-01 19:14:00 -03:00
2fort sink
f36383d0e7 Update build.yml 2026-02-01 18:58:52 -03:00
2fort sink
cff4267a68 Fix ROOT variable assignment in build workflow 2026-02-01 18:32:01 -03:00
2fort sink
65e7d83972 Update build.yml 2026-02-01 18:26:30 -03:00
2fort sink
e2533e2bb0 Patch exosphere and build, fix comment and zip making redundancy 2026-02-01 18:19:23 -03:00
2fort sink
6c94f5754c Update build.yml 2026-02-01 17:58:52 -03:00
2fort sink
aaf77997e1 Update build.yml 2026-02-01 17:52:44 -03:00
2fort sink
c933e02aed Merge branch 'Horizon-OC:develop' into develop 2026-02-01 17:46:47 -03:00
2fort sink
770c25dbcb build hoc-clk and shallow clone ams
Updated the build process to use shallow clones and added a new build step for the hoc-clk sysmodule and overlay.
2026-02-01 17:44:20 -03:00
2fort sink
dbb4d698a0 Increase make parallel jobs and update file paths 2026-02-01 16:12:26 -03:00
2fort sink
6ae084433f Update build.yml 2026-02-01 15:58:29 -03:00
2fort sink
32f19c4f0e Update build.yml 2026-02-01 15:48:47 -03:00
2fort sink
05cf2ab4dd Clone Atmosphere with specific branch from file 2026-02-01 14:28:37 -03:00
2fort sink
13a4ea4ca0 create ams_ver.txt
Should be self-explanatory, we use this for the actions build system
2026-02-01 14:27:02 -03:00
2fort sink
e2ef52e095 Update build.yml 2026-02-01 14:25:15 -03:00
2fort sink
bbd3b1a0fc Refactor build.yml for environment setup and ccache
Updated the build workflow to set environment variables using GitHub Actions environment files and improved the ccache installation step.
2026-02-01 14:22:31 -03:00
2fort sink
8dcfb55646 retry
cache and actions cache
2026-02-01 14:15:59 -03:00
2fort sink
ae0f4c7963 Delete .github/workflows/build.yml 2026-02-01 13:54:21 -03:00
2fort sink
222db76200 refactor this test testing woo waa waewewe waowowoewewahaaswadisadasud
Updated comments and modified build steps in the GitHub Actions workflow.
2026-02-01 13:52:55 -03:00
27 changed files with 895 additions and 498 deletions

171
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,171 @@
name: Build Horizon OC Zeus
on:
push:
branches: [ develop, main, master ]
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
# Minimal devkitA64 container, apparently dkp-toolchain isn't needed?
container:
image: devkitpro/devkita64:20251231
steps:
- name: Checkout repository and submodules # needed for hoc-clk
uses: actions/checkout@v6.0.2
with:
submodules: recursive
# -------------------------------------------------
# Fix PATH for devkitA64 and devkitARM
# -------------------------------------------------
- name: Set devkitPro PATH
run: |
echo "DEVKITPRO=/opt/devkitpro" >> $GITHUB_ENV
echo "DEVKITA64=/opt/devkitpro/devkitA64" >> $GITHUB_ENV
echo "DEVKITARM=/opt/devkitpro/devkitARM" >> $GITHUB_ENV
echo "PATH=/opt/devkitpro/devkitA64/bin:/opt/devkitpro/devkitARM/bin:$PATH" >> $GITHUB_ENV
shell: bash
- name: Check devkitPro gcc and g++ versions
run: |
aarch64-none-elf-gcc --version
aarch64-none-elf-g++ --version
shell: bash # is this even needed? but for consistency let's keep using it
- name: Install ccache
run: |
apt-get update
apt-get install -y ccache
shell: bash
# -------------------------------------------------
# Get short commit SHA
# -------------------------------------------------
- name: Set commit SHA
id: vars
run: echo "SHORT_SHA=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV
- name: Clone Atmosphere
run: git clone --depth=1 --single-branch https://github.com/Atmosphere-NX/Atmosphere.git atmosphere -b $(cat ams_ver.txt)
- name: Prepare build folder
run: |
mkdir -p build
cp -r atmosphere/* build/
- name: Override ldr_process_creation.cpp
run: |
cp -rf Source/Atmosphere/stratosphere/loader/source/* build/stratosphere/loader/source/
- name: Cache ccache
uses: actions/cache@v5.0.3
with:
path: /root/.cache/ccache
key: ccache-${{ runner.os }}-devkitpro-ams-${{ hashFiles('ams_ver.txt') }} # last key was utter garbage, stick to ams versions,
restore-keys: |
ccache-${{ runner.os }}-devkitpro-
- name: Configure ccache
run: |
export CCACHE_DIR=/root/.cache/ccache
echo "CCACHE_DIR=/root/.cache/ccache" >> $GITHUB_ENV
ccache --set-config=max_size=10G
ccache --set-config=compiler_check=content
ccache --zero-stats
- name: Build hoc-clk sysmodule and overlay
shell: bash
run: |
export CC="ccache aarch64-none-elf-gcc"
export CXX="ccache aarch64-none-elf-g++"
ROOT_DIR="$GITHUB_WORKSPACE/Source/sys-clk"
DIST_DIR="$ROOT_DIR/dist"
mkdir -p "$DIST_DIR"
echo "*** sysmodule ***"
TITLE_ID="$(grep -oP '"title_id":\s*"0x\K(\w+)' \
"$ROOT_DIR/sysmodule/perms.json")"
echo "TITLE_ID: $TITLE_ID"
pushd "$ROOT_DIR/sysmodule"
make -j$(($(nproc) * 2)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
popd
mkdir -p "$DIST_DIR/atmosphere/contents/$TITLE_ID/flags"
cp -vf \
"$ROOT_DIR/sysmodule/out/horizon-oc.nsp" \
"$DIST_DIR/atmosphere/contents/$TITLE_ID/exefs.nsp"
: >"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag"
cp -vf \
"$ROOT_DIR/sysmodule/toolbox.json" \
"$DIST_DIR/atmosphere/contents/$TITLE_ID/toolbox.json"
echo "*** overlay ***"
pushd "$ROOT_DIR/overlay"
make -j$(($(nproc) * 2)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
popd
mkdir -p "$DIST_DIR/switch/.overlays"
cp -vf \
"$ROOT_DIR/overlay/out/horizon-oc-overlay.ovl" \
"$DIST_DIR/switch/.overlays/horizon-oc-overlay.ovl"
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"
- name: Build kip
working-directory: build/stratosphere/loader
run: |
export CC="ccache aarch64-none-elf-gcc"
export CXX="ccache aarch64-none-elf-g++"
make -j$(($(nproc) * 4)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
hactool -t kip1 out/nintendo_nx_arm64_armv8a/release/loader.kip --uncompress=hoc.kip
cp hoc.kip ../../../dist/atmosphere/kips/hoc.kip
- name: ccache stats
run: ccache --show-stats
# -------------------------------------------------
# Package dist folder as ZIP with commit SHA
# -------------------------------------------------
- name: Package dist
# working-directory: horizon-oc
run: |
ZIP_NAME="horizon-oc-zeus-dist-${SHORT_SHA}.zip"
zip -r "$ZIP_NAME" dist
echo "ZIP_NAME=$ZIP_NAME" >> $GITHUB_ENV
# -------------------------------------------------
# Upload ZIP artifact
# -------------------------------------------------
- name: Upload build artifact
uses: actions/upload-artifact@v6
with:
name: horizon-oc-zeus-dist-${{ env.SHORT_SHA }}
path: dist/
compression-level: 3

View File

@@ -7,7 +7,7 @@
![License: GPL-2.0](https://img.shields.io/badge/GPL--2.0-red?style=for-the-badge)
![Nintendo Switch](https://img.shields.io/badge/Nintendo_Switch-E60012?style=for-the-badge\&logo=nintendo-switch\&logoColor=white)
[![Discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge\&logo=discord\&logoColor=white)](https://discord.com/invite/S3eX47dHsB)
[![Discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge\&logo=discord\&logoColor=white)](https://dsc.gg/horizonoc)
![VSCode](https://img.shields.io/badge/VSCode-0078D4?style=for-the-badge\&logo=visual%20studio%20code\&logoColor=white)
![Made with Notepad++](assets/np++.png?raw=true)
![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=for-the-badge\&logo=c%2B%2B\&logoColor=white)
@@ -44,7 +44,7 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
> *Higher (potentially dangerous) frequencies are unlockable via configuration.*
> *Erista and Mariko units can usually push a bit further fully safely with a bit of undervolting, however this may not work on all units.*
> *The exact maximum overclock possible varies per console, although most consoles should be able to do this safely.*
> *You may refer to the Clock Table to see clocks in more detail*
---
## Installation
@@ -69,7 +69,7 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
1. Open the Horizon OC Overlay
2. Open the settings menu
3. Adjust your overclocking settings as desired.
3. Adjust your overclocking settings as desired. A helpful guide can be found [here.](https://rentry.co/mariko#oc-settings-for-horizon-oc)
4. Click **Save KIP Settings** to apply your configuration.
---
@@ -78,6 +78,73 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
Refer to COMPILATION.md
---
## Clock table
### MEM clocks
* 3200 → max on mariko, JEDEC.
* 2933 → JEDEC.
* 2666 → JEDEC.
* 2400 → max on erista, JEDEC.
* 2133 → mariko safe max (4266 Modules), JEDEC.
* 1996 → JEDEC.
* 1866 → mariko safe max (3733 Modules), JEDEC.
* 1600 → official docked, boost mode, erista safe max, JEDEC.
* 1331 → official handheld, JEDEC.
* 1065
* 800
* 665
### CPU clocks
* 2601 → mariko absolute max, very dangerous
* 2499
* 2397
* 2295 → mariko safe max with UV (low speedo)
* 2193
* 2091
* 1963 → mariko no UV max clock
* 1887
* 1785 → erista no UV max clock, boost mode
* 1683
* 1581
* 1428
* 1326
* 1224 → sdev oc
* 1122
* 1020 → official docked & handheld
* 918
* 816
* 714
* 612 → sleep mode
### GPU clocks
* 1536 → absolute max clock on mariko. very dangerous
* 1459
* 1382
* 1305
* 1267 → NVIDIA T214 rating
* 1228 → mariko HiOPT safe clock
* 1152 → mariko SLT max clock
* 1075 → mariko no UV max clock. absolute max clock on erista. very dangerous
* 998 → NVIDIA T210 rating
* 960 (erista only) → erista slt/hiopt safe max clock
* 921 → erista no UV max clock
* 844
* 768 → official docked
* 691
* 614
* 537
* 460 → max handheld
* 384 → official handheld
* 307 → official handheld
* 230
* 153
* 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.
---
## Credits
@@ -95,4 +162,4 @@ Refer to COMPILATION.md
* **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
* **Samybigio2011** - Italian translations
* **Samybigio2011** - Italian translations

View File

@@ -58,11 +58,9 @@ typedef struct CustomizeTable {
u32 commonEmcMemVolt;
u32 eristaEmcMaxClock;
u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt;
u32 emcDvbShift;
// advanced config
u32 t1_tRCD;
u32 t2_tRP;
@@ -106,7 +104,7 @@ typedef struct CustomizeTable {
u32 eristaGpuVoltArray[27];
u32 marikoGpuVoltArray[24];
u32 reserved[64];
CustomizeCpuDvfsTable eristaCpuDvfsTable;
CustomizeCpuDvfsTable eristaCpuDvfsTableSLT;

View File

@@ -77,7 +77,49 @@ namespace ams::ldr::oc {
/* 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 {

View File

@@ -66,10 +66,10 @@ namespace ams::ldr::oc::pcv::erista {
Result CpuVoltDfll(u32* ptr) {
cvb_cpu_dfll_data *entry = reinterpret_cast<cvb_cpu_dfll_data *>(ptr);
R_UNLESS(entry->tune0_low == 0x0000FFCF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune0_high == 0x00000000, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_low == 0x012207FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_high == 0x03FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune0_low == 0xFFEAD0FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_low == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
if( !C.eristaCpuUV) {
R_SKIP();
@@ -493,206 +493,154 @@ namespace ams::ldr::oc::pcv::erista {
/* These timings are slightly off from eos, I am not sure why but I am going to figure it out at some point. */
void MemMtcTableAutoAdjust(EristaMtcTable *table) {
(void) table;
// using namespace pcv::erista;
//
/* #define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) // note: add backslashes to make the macro definition work
TABLE->burst_regs.PARAM = VALUE; \
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
TABLE->shadow_regs_quse_train.PARAM = VALUE; \
#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(PARAM) ((u32)((double)(PARAM) / (1000000.0 / 1600000.0)))
//
// /* 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));
//
// /* Primary timings. */
// WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE(tRCD));
// WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE(tRAS));
// WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE(tRPpb));
//
// /* Secondary timings. */
// WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE(tRRD));
// WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE(tRFCab));
// WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE(tRFCpb));
// WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
// WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
// WRITE_PARAM_ALL_REG(table, emc_r2p, (u32) 0xC);
// WRITE_PARAM_ALL_REG(table, emc_w2p, (u32) 0x2D);
//
// WRITE_PARAM_ALL_REG(table, emc_rext, rext);
// WRITE_PARAM_ALL_REG(table, emc_wext, wext);
//
// WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE(tRPab));
// WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE(tFAW));
// WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE(tRC));
//
// WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE(tSR));
// WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE(tXP) + 1);
// WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE(tXP));
// WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE(tXP) + 8);
//
// WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE(tXSR), (u32) 1022));
// WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE(tXSR), (u32) 1022));
//
// const u32 dyn_self_ref_control = (((u32)(7605.0 / tCK_avg)) + 260U) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000U);
// WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
//
// WRITE_PARAM_ALL_REG(table, emc_rw2pden, tRW2PDEN);
// 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));
// WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE(pdex2mrr));
//
// WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
// WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, (u32) (refresh_raw / 4));
// WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
//
// 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_cfg = (int)(((double) C.eristaEmcMaxClock / 33300.0) * 0.25);
// 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_rap2pre = 3;
// table->burst_mc_regs.mc_emem_arb_timing_wap2pre = 11;
// 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);
//
// u32 mc_r2r = table->burst_mc_regs.mc_emem_arb_timing_r2r;
// if (mc_r2r > 1) {
// mc_r2r = (uint)(((double)(long)((double)rext * 0.25) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_r2r = mc_r2r;
// }
//
// u32 mc_w2w = table->burst_mc_regs.mc_emem_arb_timing_w2w;
// if (mc_w2w > 1) {
// mc_w2w = (uint)(((double)(long)((double)wext / 4.0) - 1.0) + 2.0);
// table->burst_mc_regs.mc_emem_arb_timing_w2w = mc_w2w;
// }
//
// table->burst_mc_regs.mc_emem_arb_da_turns = ((mc_tW2R >> 1) << 0x18) | ((mc_tR2W >> 1) << 0x10) | ((mc_r2r >> 1) << 8) | ((mc_w2w >> 1));
// 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);
// table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0xd0U), (u32)0x115);
// table->la_scale_regs.mc_ftop_ptsa_rate = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0x18U), (u32)0x1f);
// table->la_scale_regs.mc_ptsa_grant_decrement = MIN((u32)((C.eristaEmcMaxClock / 1600000) * 0x1203U), (u32)0x17ff);
//
// u32 mc_latency_allowance = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance = 204800 / (C.eristaEmcMaxClock / 1000);
// }
//
// const u32 mc_latency_allowance2 = mc_latency_allowance & 0xFF;
// const u32 mc_latency_allowance3 = (mc_latency_allowance & 0xFF) << 0x10;
// table->la_scale_regs.mc_latency_allowance_xusb_0 = (table->la_scale_regs.mc_latency_allowance_xusb_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmc_0 = (table->la_scale_regs.mc_latency_allowance_sdmmc_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_tsec_0 = (table->la_scale_regs.mc_latency_allowance_tsec_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmca_0 = (table->la_scale_regs.mc_latency_allowance_sdmmca_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcaa_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_sdmmcab_0 = (table->la_scale_regs.mc_latency_allowance_sdmmcab_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_ppcs_1 = (table->la_scale_regs.mc_latency_allowance_ppcs_1 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_mpcore_0 = (table->la_scale_regs.mc_latency_allowance_mpcore_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_avpc_0 = (table->la_scale_regs.mc_latency_allowance_avpc_0 & 0xff00ffffU) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_hc_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_hc_0 = 35200 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_nvdec_0 = (table->la_scale_regs.mc_latency_allowance_nvdec_0 & 0xff00ffffU) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_hc_0 = (table->la_scale_regs.mc_latency_allowance_hc_0 & 0xffffff00U) | mc_latency_allowance_hc_0;
//
// table->la_scale_regs.mc_latency_allowance_isp2_1 = (table->la_scale_regs.mc_latency_allowance_isp2_1 & 0xff00ff00U) | mc_latency_allowance3 | mc_latency_allowance2;
// table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & 0xffffff00U) | mc_latency_allowance2;
//
// u32 mc_latency_allowance_gpu_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_gpu_0 = 40000 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_gpu_0 = ((mc_latency_allowance_gpu_0 | table->la_scale_regs.mc_latency_allowance_gpu_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_gpu2_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_gpu2_0 = 40000 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_gpu2_0 = ((mc_latency_allowance_gpu2_0 | table->la_scale_regs.mc_latency_allowance_gpu2_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_nvenc_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_nvenc_0 = 38400 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_nvenc_0 = ((mc_latency_allowance_nvenc_0 | table->la_scale_regs.mc_latency_allowance_nvenc_0) & 0xff00ff00U) | mc_latency_allowance3;
//
// u32 mc_latency_allowance_vic_0 = 0;
// if (C.eristaEmcMaxClock / 1000 != 0) {
// mc_latency_allowance_vic_0 = 0xb540 / (C.eristaEmcMaxClock / 1000);
// }
//
// table->la_scale_regs.mc_latency_allowance_vic_0 = ((mc_latency_allowance_vic_0 | table->la_scale_regs.mc_latency_allowance_vic_0) & 0xff00ff00U) | mc_latency_allowance3;
// table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & 0xffffff00U) | mc_latency_allowance2;
//
// table->burst_mc_regs.mc_emem_arb_timing_rfcpb = GET_CYCLE(tRFCpb) >> 2;
//
// if (C.hpMode) {
// WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
// }
//
// table->dram_timings.t_rp = tRFCpb;
// table->dram_timings.t_rfc = tRFCab;
// table->emc_cfg_2 = 0x11083d;
// #undef GET_CYCLE
}
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
/* Ram power down */
/* B31: DRAM_CLKSTOP_PD */
/* B30: DRAM_CLKSTOP_SR */
/* B29: DRAM_ACPD */
if (C.hpMode) {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0x13200000);
} else {
WRITE_PARAM_ALL_REG(table, emc_cfg, 0xF3200000);
}
u32 refresh_raw = 0xFFFF;
if (C.t8_tREFI != 6) {
refresh_raw = CEIL(tREFpb_values[C.t8_tREFI] / tCK_avg) - 0x40;
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
}
u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
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)));
WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F)));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), static_cast<u32>(0x3fe)));
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_tpd, GET_CYCLE_CEIL(tXP));
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tXP) + 8);
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_refresh, refresh_raw);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000);
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_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_pdex2mrr, GET_CYCLE_CEIL(pdex2mrr));
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN);
/* 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_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;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA;
if (table->burst_mc_regs.mc_emem_arb_timing_r2r > 1) {
table->burst_mc_regs.mc_emem_arb_timing_r2r = CEIL(table->burst_regs.emc_rext / 4) - 1 + MC_ARB_SFA;
}
table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(tR2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(tW2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
u32 da_turns = 0;
da_turns |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16;
da_turns |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24;
table->burst_mc_regs.mc_emem_arb_da_turns = da_turns;
u32 da_covers = 0;
u8 r_cover = (table->burst_mc_regs.mc_emem_arb_timing_rap2pre + table->burst_mc_regs.mc_emem_arb_timing_rp + table->burst_mc_regs.mc_emem_arb_timing_rcd) / 2;
u8 w_cover = (table->burst_mc_regs.mc_emem_arb_timing_wap2pre + table->burst_mc_regs.mc_emem_arb_timing_rp + table->burst_mc_regs.mc_emem_arb_timing_rcd) / 2;
da_covers |= (table->burst_mc_regs.mc_emem_arb_timing_rc / 2);
da_covers |= (r_cover << 8);
da_covers |= (w_cover << 16);
table->burst_mc_regs.mc_emem_arb_da_covers = da_covers;
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;
if (C.eristaEmcMaxClock >= 2133000) {
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1F;
} else {
table->la_scale_regs.mc_ftop_ptsa_rate = 0x1B;
}
table->la_scale_regs.mc_ptsa_grant_decrement = 0x17ff;
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;
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->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;
}
Result MemFreqMtcTable(u32 *ptr) {
u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800};
@@ -735,7 +683,7 @@ namespace ams::ldr::oc::pcv::erista {
{"CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, static_cast<u32>(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq)},
{"CPU Volt DVFS", &CpuVoltDvfs, 1, nullptr, 825},
{"CPU Volt Thermals", &CpuVoltThermals, 1, nullptr, 825},
{"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFD0EAFF},
{"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)},

View File

@@ -83,7 +83,7 @@ Result nvdecCheck = 1;
Result nvencCheck = 1;
Result nvjpgCheck = 1;
Result nifmCheck = 1;
Result sysclkCheck = 1;
Result sysclkCheck = 0;
Result pwmDutyCycleCheck = 1;
//Wi-Fi
@@ -572,21 +572,19 @@ void Misc(void*) {
}
// Get sys-clk data
if (R_SUCCEEDED(sysclkCheck)) {
SysClkContext sysclkCTX;
if (R_SUCCEEDED(sysclkIpcGetCurrentContext(&sysclkCTX))) {
realCPU_Hz = sysclkCTX.realFreqs[SysClkModule_CPU];
realGPU_Hz = sysclkCTX.realFreqs[SysClkModule_GPU];
realRAM_Hz = sysclkCTX.realFreqs[SysClkModule_MEM];
partLoad[SysClkPartLoad_EMC] = sysclkCTX.partLoad[SysClkPartLoad_EMC];
partLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.partLoad[SysClkPartLoad_EMCCpu];
realCPU_mV = sysclkCTX.voltages[HocClkVoltage_CPU];
realGPU_mV = sysclkCTX.voltages[HocClkVoltage_GPU];
realVDD2_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDD2];
realVDDQ_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly];
realSOC_mV = sysclkCTX.voltages[HocClkVoltage_SOC];
}
SysClkContext sysclkCTX;
if (R_SUCCEEDED(sysclkIpcGetCurrentContext(&sysclkCTX))) {
realCPU_Hz = sysclkCTX.realFreqs[SysClkModule_CPU];
realGPU_Hz = sysclkCTX.realFreqs[SysClkModule_GPU];
realRAM_Hz = sysclkCTX.realFreqs[SysClkModule_MEM];
partLoad[SysClkPartLoad_EMC] = sysclkCTX.partLoad[SysClkPartLoad_EMC];
partLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.partLoad[SysClkPartLoad_EMCCpu];
realCPU_mV = sysclkCTX.voltages[HocClkVoltage_CPU];
realGPU_mV = sysclkCTX.voltages[HocClkVoltage_GPU];
realVDD2_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDD2];
realVDDQ_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly];
realSOC_mV = sysclkCTX.voltages[HocClkVoltage_SOC];
}
// Temperatures
@@ -699,21 +697,7 @@ void Misc3(void*) {
do {
mutexLock(&mutex_Misc);
// Get sys-clk data
if (R_SUCCEEDED(sysclkCheck)) {
SysClkContext sysclkCTX;
if (R_SUCCEEDED(sysclkIpcGetCurrentContext(&sysclkCTX))) {
partLoad[SysClkPartLoad_EMC] = sysclkCTX.partLoad[SysClkPartLoad_EMC];
partLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.partLoad[SysClkPartLoad_EMCCpu];
realCPU_mV = sysclkCTX.voltages[HocClkVoltage_CPU];
realGPU_mV = sysclkCTX.voltages[HocClkVoltage_GPU];
realSOC_mV = sysclkCTX.voltages[HocClkVoltage_SOC];
realVDD2_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDD2];
realVDDQ_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly];
}
}
// Temperatures
if (R_SUCCEEDED(i2cCheck)) {
Tmp451GetSocTemp(&SOC_temperatureF);

View File

@@ -446,14 +446,6 @@ public:
if (SaltySD) {
LoadSharedMemoryAndRefreshRate();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
}
if (R_SUCCEEDED(splInitialize())) {
u64 sku = 0;
splGetConfig(SplConfigItem_HardwareType, &sku);
@@ -466,16 +458,14 @@ public:
}
}
splExit();
sysclkIpcInitialize();
});
Hinted = envIsSyscallHinted(0x6F);
}
virtual void exitServices() override {
CloseThreads();
if (R_SUCCEEDED(sysclkCheck)) {
sysclkIpcExit();
}
sysclkIpcExit();
shmemClose(&_sharedmemory);
//Exit services
clkrstExit();
@@ -530,14 +520,6 @@ public:
if (SaltySD) {
LoadSharedMemory();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
}
if (R_SUCCEEDED(splInitialize())) {
u64 sku = 0;
splGetConfig(SplConfigItem_HardwareType, &sku);
@@ -550,6 +532,7 @@ public:
}
}
splExit();
sysclkIpcInitialize();
});
Hinted = envIsSyscallHinted(0x6F);
}
@@ -557,9 +540,7 @@ public:
virtual void exitServices() override {
CloseThreads();
shmemClose(&_sharedmemory);
if (R_SUCCEEDED(sysclkCheck)) {
sysclkIpcExit();
}
sysclkIpcExit();
//Exit services
clkrstExit();
pcvExit();
@@ -617,14 +598,6 @@ public:
if (SaltySD) {
LoadSharedMemory();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
}
if (R_SUCCEEDED(splInitialize())) {
u64 sku = 0;
splGetConfig(SplConfigItem_HardwareType, &sku);
@@ -637,6 +610,7 @@ public:
}
}
splExit();
sysclkIpcInitialize();
});
Hinted = envIsSyscallHinted(0x6F);
@@ -645,9 +619,7 @@ public:
virtual void exitServices() override {
CloseThreads();
shmemClose(&_sharedmemory);
if (R_SUCCEEDED(sysclkCheck)) {
sysclkIpcExit();
}
sysclkIpcExit();
// Exit services
clkrstExit();
pcvExit();
@@ -707,14 +679,6 @@ public:
if (SaltySD) {
LoadSharedMemoryAndRefreshRate();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
}
if (R_SUCCEEDED(splInitialize())) {
u64 sku = 0;
splGetConfig(SplConfigItem_HardwareType, &sku);
@@ -727,6 +691,7 @@ public:
}
}
splExit();
sysclkIpcInitialize();
});
Hinted = envIsSyscallHinted(0x6F);
}
@@ -734,9 +699,7 @@ public:
virtual void exitServices() override {
CloseThreads();
shmemClose(&_sharedmemory);
if (R_SUCCEEDED(sysclkCheck)) {
sysclkIpcExit();
}
sysclkIpcExit();
clkrstExit();
pcvExit();
tsExit();
@@ -790,14 +753,6 @@ public:
if (SaltySD) {
LoadSharedMemoryAndRefreshRate();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
}
if (R_SUCCEEDED(splInitialize())) {
u64 sku = 0;
splGetConfig(SplConfigItem_HardwareType, &sku);
@@ -810,6 +765,7 @@ public:
}
}
splExit();
sysclkIpcInitialize();
});
Hinted = envIsSyscallHinted(0x6F);
}
@@ -817,9 +773,7 @@ public:
virtual void exitServices() override {
CloseThreads();
shmemClose(&_sharedmemory);
if (R_SUCCEEDED(sysclkCheck)) {
sysclkIpcExit();
}
sysclkIpcExit();
clkrstExit();
pcvExit();
tsExit();
@@ -873,14 +827,6 @@ public:
if (SaltySD) {
LoadSharedMemoryAndRefreshRate();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
}
if (R_SUCCEEDED(splInitialize())) {
u64 sku = 0;
splGetConfig(SplConfigItem_HardwareType, &sku);
@@ -893,6 +839,7 @@ public:
}
}
splExit();
sysclkIpcInitialize();
});
Hinted = envIsSyscallHinted(0x6F);
}
@@ -900,9 +847,7 @@ public:
virtual void exitServices() override {
CloseThreads();
shmemClose(&_sharedmemory);
if (R_SUCCEEDED(sysclkCheck)) {
sysclkIpcExit();
}
sysclkIpcExit();
clkrstExit();
pcvExit();
tsExit();

View File

@@ -233,12 +233,10 @@ public:
else if (realRAM_Hz && settings.showDeltas && (settings.showRealFreqs || settings.showTargetFreqs)) {
renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor));
}
if (R_SUCCEEDED(sysclkCheck)) {
static std::vector<std::string> PartLoadColoredChars = {"CPU", "GPU"};
//static auto loadLabelWidth = renderer->getTextDimensions("Load: ", false, 15).first;
renderer->drawString("Load", false, COMMON_MARGIN, height_offset+15, 15, (settings.catColor2));
renderer->drawStringWithColoredSections(RAM_load_c, false, PartLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2);
}
static std::vector<std::string> PartLoadColoredChars = {"CPU", "GPU"};
//static auto loadLabelWidth = renderer->getTextDimensions("Load: ", false, 15).first;
renderer->drawString("Load", false, COMMON_MARGIN, height_offset+15, 15, (settings.catColor2));
renderer->drawStringWithColoredSections(RAM_load_c, false, PartLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2);
}
if (R_SUCCEEDED(Hinted)) {
//static auto textWidth = renderer->getTextDimensions("Total \nApplication \nApplet \nSystem \nSystem Unsafe ", false, 15).first;

View File

@@ -354,7 +354,7 @@ public:
else
width = renderer->getTextDimensions("100%@4444.4444 mV", false, fontsize).first;
}
} else if (key == "GPU" || (key == "RAM" && settings.showRAMLoad && R_SUCCEEDED(sysclkCheck))) {
} else if (key == "GPU" || (key == "RAM" && settings.showRAMLoad)) {
//dimensions = renderer->drawString("100.0%@4444.4", false, 0, 0, fontsize, renderer->a(0x0000));
if (!settings.showRAMLoadCPUGPU) {
@@ -370,7 +370,7 @@ public:
width = renderer->getTextDimensions("100%[100%,100%]@4444.4444 mV", false, fontsize).first;
}
}
} else if (key == "RAM" && (!settings.showRAMLoad || R_FAILED(sysclkCheck))) {
} else if (key == "RAM" && (!settings.showRAMLoad)) {
//dimensions = renderer->drawString("44444444MB@4444.4", false, 0, 0, fontsize, renderer->a(0x0000));
if (!settings.realVolts) {
width = renderer->getTextDimensions("100%@4444.4", false, fontsize).first;
@@ -993,51 +993,33 @@ public:
} else {
unsigned PartLoadInt;
if (R_SUCCEEDED(sysclkCheck)) {
PartLoadInt = partLoad[SysClkPartLoad_EMC] / 10;
if (settings.showRAMLoadCPUGPU) {
unsigned ramCpuLoadInt = partLoad[SysClkPartLoad_EMCCpu] / 10;
int RAM_GPU_Load = partLoad[SysClkPartLoad_EMC] - partLoad[SysClkPartLoad_EMCCpu];
unsigned ramGpuLoadInt = RAM_GPU_Load / 10;
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%[%u%%,%u%%]@%hu.%hhu",
PartLoadInt, ramCpuLoadInt, ramGpuLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%[%u%%,%u%%]@%hu.%hhu",
PartLoadInt, ramCpuLoadInt, ramGpuLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
} else {
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", PartLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", PartLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
}
} else {
const uint64_t RAM_Total_all = RAM_Total_application_u + RAM_Total_applet_u +
RAM_Total_system_u + RAM_Total_systemunsafe_u;
const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u +
RAM_Used_system_u + RAM_Used_systemunsafe_u;
PartLoadInt = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0;
PartLoadInt = partLoad[SysClkPartLoad_EMC] / 10;
if (settings.showRAMLoadCPUGPU) {
unsigned ramCpuLoadInt = partLoad[SysClkPartLoad_EMCCpu] / 10;
int RAM_GPU_Load = partLoad[SysClkPartLoad_EMC] - partLoad[SysClkPartLoad_EMCCpu];
unsigned ramGpuLoadInt = RAM_GPU_Load / 10;
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", PartLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
"%u%%[%u%%,%u%%]@%hu.%hhu",
PartLoadInt, ramCpuLoadInt, ramGpuLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", PartLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
"%u%%[%u%%,%u%%]@%hu.%hhu",
PartLoadInt, ramCpuLoadInt, ramGpuLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
} else {
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", PartLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", PartLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
}
}

View File

@@ -1,5 +1,21 @@
/*
* --------------------------------------------------------------------------
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* 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/>.
*
*/
/* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
* wrote this file. As long as you retain this notice you can do whatever you
@@ -8,11 +24,12 @@
* --------------------------------------------------------------------------
*/
#define NX_SERVICE_ASSUME_NON_DOMAIN
#include <sysclk/client/ipc.h>
#include <switch.h>
#include <string.h>
#include <stdatomic.h>
#include <sysclk/client/ipc.h>
static Service g_sysclkSrv;
static atomic_size_t g_refCnt;
@@ -20,7 +37,7 @@ static atomic_size_t g_refCnt;
bool sysclkIpcRunning()
{
Handle handle;
const bool running = R_FAILED(smRegisterService(&handle, smEncodeName(SYSCLK_IPC_SERVICE_NAME), false, 1));
bool running = R_FAILED(smRegisterService(&handle, smEncodeName(SYSCLK_IPC_SERVICE_NAME), false, 1));
if (!running)
{
@@ -94,7 +111,10 @@ Result sysclkIpcSetOverride(SysClkModule module, u32 hz)
Result sysclkIpcGetProfiles(u64 tid, SysClkTitleProfileList* out_profiles)
{
return serviceDispatchInOut(&g_sysclkSrv, SysClkIpcCmd_GetProfiles, tid, *out_profiles);
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_GetProfiles, tid,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = {{out_profiles, sizeof(SysClkTitleProfileList)}},
);
}
Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles)
@@ -107,12 +127,18 @@ Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles)
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues)
{
return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetConfigValues, *out_configValues);
return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_GetConfigValues,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = {{out_configValues, sizeof(SysClkConfigValueList)}},
);
}
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetConfigValues, *configValues);
return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_SetConfigValues,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = {{configValues, sizeof(SysClkConfigValueList)}},
);
}
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount)
@@ -125,4 +151,33 @@ Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* o
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = {{list, maxCount * sizeof(u32)}},
);
}
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetReverseNXRTMode, mode);
}
Result hocClkIpcSetKipData()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_SetKipData, temp);
}
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);
}

53
Source/sys-clk/bitmap.py Normal file
View File

@@ -0,0 +1,53 @@
from PIL import Image
import argparse
import os
def image_to_rgba8888_array(image_path, output_path):
# Open and convert to RGBA
img = Image.open(image_path).convert('RGBA')
width, height = img.size
# Get pixel data
pixels = img.tobytes()
# Write as C header file
with open(output_path, 'w') as f:
f.write('// This is a generated automatically generated file, do not edit manually.\n')
f.write(f'// {os.path.basename(image_path)} - {width}x{height}\n')
f.write(f'const unsigned int IMG_WIDTH = {width};\n')
f.write(f'const unsigned int IMG_HEIGHT = {height};\n')
f.write('const unsigned char IMG_DATA[] = {\n ')
for i, byte in enumerate(pixels):
f.write(f'0x{byte:02X}')
if i < len(pixels) - 1:
f.write(', ')
if (i + 1) % 12 == 0:
f.write('\n ')
f.write('\n};\n')
print(f'Converted: {width}x{height} -> {len(pixels)} bytes')
print(f'Output: {output_path}')
def main():
parser = argparse.ArgumentParser(
description='PNG -> RGB8888 script'
)
parser.add_argument('input', help='Input image file (e.g. cat.png)')
parser.add_argument(
'-o', '--output',
help='Output header file (default: <input>.h)'
)
args = parser.parse_args()
output_path = args.output
if not output_path:
base, _ = os.path.splitext(args.input)
output_path = base + '.h'
image_to_rgba8888_array(args.input, output_path)
if __name__ == '__main__':
main()

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.33
APP_VERSION := 0.34
TARGET_VERSION := $(APP_VERSION)
#---------------------------------------------------------------------------------

View File

@@ -29,6 +29,7 @@
#include "../format.h"
#include "fatal_gui.h"
#include "labels.h"
AppProfileGui::AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList)
{
this->applicationId = applicationId;
@@ -50,7 +51,13 @@ void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfil
FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc);
return;
}
std::map<uint32_t, std::string> labels = {};
if (module == SysClkModule_CPU) {
labels = IsMariko() ? cpu_freq_label_m : cpu_freq_label_e;
} else if (module == SysClkModule_GPU) {
labels = IsMariko() ? gpu_freq_label_m : gpu_freq_label_e;
}
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module](std::uint32_t hz) {
this->profileList->mhzMap[profile][module] = hz / 1000000;
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
@@ -62,7 +69,7 @@ void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfil
}
return true;
}, true
}, true, labels
);
}
@@ -282,7 +289,7 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
ValueThresholds lcdThresholds(60, 65);
if(!IsHoag() && configList.values[HorizonOCConfigValue_OverwriteRefreshRate]) {
if(profile != SysClkProfile_Docked)
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
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);
}

View File

@@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// this is a generated file, do not edit manually.
// cat.png - 96x128
static const unsigned int CAT_WIDTH = 96;
static const unsigned int CAT_HEIGHT = 128;

View File

@@ -19,7 +19,7 @@
#include "fatal_gui.h"
#include "global_override_gui.h"
#include "value_choice_gui.h"
#include "labels.h"
GlobalOverrideGui::GlobalOverrideGui()
{
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) {
@@ -38,6 +38,14 @@ void GlobalOverrideGui::openFreqChoiceGui(SysClkModule module)
FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc);
return;
}
std::map<uint32_t, std::string> labels = {};
if (module == SysClkModule_CPU) {
labels = IsMariko() ? cpu_freq_label_m : cpu_freq_label_e;
} else if (module == SysClkModule_GPU) {
labels = IsMariko() ? gpu_freq_label_m : gpu_freq_label_e;
}
tsl::changeTo<FreqChoiceGui>(
this->context->overrideFreqs[module], hzList, hzCount, module,
[this, module](std::uint32_t hz) {
@@ -52,7 +60,8 @@ void GlobalOverrideGui::openFreqChoiceGui(SysClkModule module)
return true;
},
true);
true, labels
);
}
void GlobalOverrideGui::openValueChoiceGui(
@@ -283,7 +292,7 @@ void GlobalOverrideGui::listUI()
#if IS_MINIMAL == 0
ValueThresholds lcdThresholds(60, 65);
if(!IsHoag() && configList.values[HorizonOCConfigValue_OverwriteRefreshRate])
this->addModuleListItemValue(HorizonOCModule_Display, "Display", 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
this->addModuleListItemValue(HorizonOCModule_Display, "Display", 40, configList.values[HorizonOCConfigValue_EnableUnsafeDisplayFreqs] ? IsAula() ? 65 : 72 : 60, 1, " Hz", 1, 0, lcdThresholds);
#endif
this->addModuleToggleItem(HorizonOCModule_Governor);
}

View File

@@ -0,0 +1,46 @@
#include <map>
#include <cstdint>
#include <string>
std::map<uint32_t, std::string> cpu_freq_label_m = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{1963000000, "Safe Max"},
{2397000000, "Unsafe Max"},
{2703000000, "Absolute Max"},
};
std::map<uint32_t, std::string> cpu_freq_label_e = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Boost Mode & Safe Max"},
{2091000000, "Unsafe Max"},
{2295000000, "Absolute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_e = {
{76800000, "Boost Mode"},
{307200000, "Handheld"},
{345600000, "Handheld"},
{384000000, "Handheld"},
{422400000, "Handheld"},
{460800000, "Handheld Safe Max"},
{768000000, "Docked"},
{921600000, "Safe Max"},
{960000000, "Unsafe Max"},
{1075200000, "Aboslute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_m = {
{76800000, "Boost Mode"},
{307200000, "Handheld"},
{384000000, "Handheld"},
{460800000, "Handheld"},
{614400000, "Handheld Safe Max"},
{768000000, "Docked"},
{1075200000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Aboslute Max"},
};

View File

@@ -0,0 +1,9 @@
#pragma once
#include <map>
#include <cstdint>
#include <string>
extern std::map<uint32_t, std::string> cpu_freq_label_m;
extern std::map<uint32_t, std::string> cpu_freq_label_e;
extern std::map<uint32_t, std::string> gpu_freq_label_m;
extern std::map<uint32_t, std::string> gpu_freq_label_e;

View File

@@ -23,6 +23,7 @@
#include <cstring>
#include <vector>
#include <notification.h>
#include "labels.h"
#if IS_MINIMAL == 1
#pragma message("Compiling with minimal features")
#endif
@@ -33,25 +34,6 @@ class CpuSubmenuGui;
class GpuSubmenuGui;
class GpuCustomTableSubmenuGui;
std::map<uint32_t, std::string> cpu_freq_label_m = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{1963000000, "Safe Max"},
{2397000000, "Unsafe Max"},
{2805000000, "Absolute Max"},
};
std::map<uint32_t, std::string> cpu_freq_label_e = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Boost Mode & Safe Max"},
{2091000000, "Unsafe Max"},
{2295000000, "Absolute Max"},
};
MiscGui::MiscGui()
{
this->configList = new SysClkConfigValueList {};
@@ -459,8 +441,10 @@ protected:
addConfigToggle(KipConfigValue_hpMode, "HP Mode");
ValueThresholds eristaRamThresholds(2208000, 2304000);
std::vector<NamedValue> marikoMaxEmcClock = {
NamedValue("1600MHz (JEDEC.)", 1600000),
NamedValue("1600MHz", 1600000, "JEDEC."),
NamedValue("1633MHz", 1633000),
NamedValue("1666MHz", 1666000),
NamedValue("1700MHz", 1700000),
@@ -468,16 +452,16 @@ protected:
NamedValue("1766MHz", 1766000),
NamedValue("1800MHz", 1800000),
NamedValue("1833MHz", 1833000),
NamedValue("1866MHz (JEDEC.)", 1866000),
NamedValue("1866MHz", 1866000, "JEDEC."),
NamedValue("1900MHz", 1900000),
NamedValue("1933MHz", 1933000),
NamedValue("1966MHz", 1966000),
NamedValue("1996MHz (JEDEC.)", 1996800),
NamedValue("1996MHz", 1996800, "JEDEC."),
NamedValue("2000MHz", 2000000),
NamedValue("2033MHz", 2033000),
NamedValue("2066MHz", 2066000),
NamedValue("2100MHz", 2100000),
NamedValue("2133MHz (JEDEC.)", 2133000),
NamedValue("2133MHz", 2133000),
NamedValue("2166MHz", 2166000),
NamedValue("2200MHz", 2200000),
NamedValue("2233MHz", 2233000),
@@ -485,7 +469,7 @@ protected:
NamedValue("2300MHz", 2300000),
NamedValue("2333MHz", 2333000),
NamedValue("2366MHz", 2366000),
NamedValue("2400MHz (JEDEC.)", 2400000),
NamedValue("2400MHz", 2400000, "JEDEC."),
NamedValue("2433MHz", 2433000),
NamedValue("2466MHz", 2466000),
NamedValue("2500MHz", 2500000),
@@ -493,7 +477,7 @@ protected:
NamedValue("2566MHz", 2566000),
NamedValue("2600MHz", 2600000),
NamedValue("2633MHz", 2633000),
NamedValue("2666MHz", 2666000),
NamedValue("2666MHz", 2666000, "JEDEC."),
NamedValue("2700MHz", 2700000),
NamedValue("2733MHz", 2733000),
NamedValue("2766MHz", 2766000),
@@ -501,7 +485,7 @@ protected:
NamedValue("2833MHz", 2833000),
NamedValue("2866MHz", 2866000),
NamedValue("2900MHz", 2900000),
NamedValue("2933MHz (JEDEC.)", 2933000),
NamedValue("2933MHz", 2933000, "JEDEC."),
NamedValue("2966MHz", 2966000),
NamedValue("3000MHz", 3000000),
NamedValue("3033MHz", 3033000),
@@ -509,10 +493,10 @@ protected:
NamedValue("3100MHz", 3100000),
NamedValue("3133MHz", 3133000),
NamedValue("3166MHz", 3166000),
NamedValue("3200MHz (JEDEC.)", 3200000),
// NamedValue("3233MHz (Needs high Speedo/PLL)", 3233000),
// NamedValue("3266MHz (Needs high Speedo/PLL)", 3266000),
// NamedValue("3300MHz (Needs high Speedo/PLL)", 3300000),
NamedValue("3200MHz", 3200000, "JEDEC."),
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),
@@ -522,7 +506,7 @@ protected:
};
std::vector<NamedValue> eristaMaxEmcClock = {
NamedValue("1600MHz (JEDEC.)", 1600000),
NamedValue("1600MHz", 1600000, "JEDEC."),
NamedValue("1633MHz", 1633000),
NamedValue("1666MHz", 1666000),
NamedValue("1700MHz", 1700000),
@@ -530,32 +514,44 @@ protected:
NamedValue("1766MHz", 1766000),
NamedValue("1800MHz", 1800000),
NamedValue("1833MHz", 1833000),
NamedValue("1866MHz (JEDEC.)", 1866000),
NamedValue("1900MHz", 1900000),
NamedValue("1933MHz", 1933000),
NamedValue("1966MHz", 1966000),
NamedValue("2000MHz", 2000000),
NamedValue("2033MHz", 2033000),
NamedValue("2066MHz", 2066000),
NamedValue("2100MHz", 2100000),
NamedValue("2133MHz (JEDEC.)", 2133000),
NamedValue("2166MHz", 2166000),
NamedValue("2200MHz (high power draw!)", 2200000),
NamedValue("2233MHz (high power draw!)", 2233000),
NamedValue("2266MHz (high power draw!)", 2266000),
NamedValue("2300MHz (high power draw!)", 2300000),
NamedValue("2333MHz (high power draw!)", 2333000),
NamedValue("2366MHz (high power draw!)", 2366000),
NamedValue("2400MHz (high power draw & JEDEC.)", 2400000),
NamedValue("1862MHz", 1862400, "JEDEC."),
NamedValue("1881MHz", 1881600),
NamedValue("1900MHz", 1900800),
NamedValue("1920MHz", 1920000),
NamedValue("1939MHz", 1939200),
NamedValue("1958MHz", 1958400),
NamedValue("1977MHz", 1977600),
NamedValue("1996MHz", 1996800, "JEDEC."),
NamedValue("2016MHz", 2016000),
NamedValue("2035MHz", 2035200),
NamedValue("2054MHz", 2054400),
NamedValue("2073MHz", 2073600),
NamedValue("2092MHz", 2092800),
NamedValue("2112MHz", 2112000),
NamedValue("2131MHz", 2131200, "JEDEC."),
NamedValue("2150MHz", 2150400),
NamedValue("2169MHz", 2169600),
NamedValue("2188MHz", 2188800),
NamedValue("2208MHz", 2208000),
NamedValue("2227MHz", 2227200),
NamedValue("2246MHz", 2246400),
NamedValue("2265MHz", 2265600),
NamedValue("2284MHz", 2284800),
NamedValue("2304MHz", 2304000),
NamedValue("2323MHz", 2323200),
NamedValue("2342MHz", 2342400),
NamedValue("2361MHz", 2361600),
NamedValue("2380MHz", 2380800),
NamedValue("2400MHz", 2400000, "JEDEC."),
};
if(IsErista()) {
addConfigButton(
KipConfigValue_eristaEmcMaxClock,
"EMC Max Clock",
"RAM Max Clock",
ValueRange(0, 1, 1, "", 1),
"EMC Max Clock",
&thresholdsDisabled,
"RAM Max Clock",
&eristaRamThresholds,
{},
eristaMaxEmcClock,
false
@@ -563,9 +559,9 @@ protected:
} else {
addConfigButton(
KipConfigValue_marikoEmcMaxClock,
"EMC Max Clock",
"RAM Max Clock",
ValueRange(0, 1, 1, "", 1),
"EMC Max Clock",
"RAM Max Clock",
&thresholdsDisabled,
{},
marikoMaxEmcClock,
@@ -585,7 +581,7 @@ protected:
ValueThresholds vdd2Thresholds(1212500, 1250000);
addConfigButton(
KipConfigValue_commonEmcMemVolt,
"EMC VDD2 Voltage",
"RAM VDD2 Voltage",
ValueRange(912500, 1350000, 12500, "mV", 1000, 1),
"Voltage",
&vdd2Thresholds,
@@ -597,9 +593,9 @@ protected:
if(IsMariko()) {
addConfigButton(
KipConfigValue_marikoEmcVddqVolt,
"EMC VDDQ Voltage",
"RAM VDDQ Voltage",
ValueRange(550000, 700000, 5000, "mV", 1000),
"EMC VDDQ Voltage",
"RAM VDDQ Voltage",
&thresholdsDisabled,
{},
{},
@@ -609,16 +605,16 @@ protected:
addConfigButton(
KipConfigValue_emcDvbShift,
"DVB Shift",
"SoC DVB Shift",
ValueRange(0, 10, 1, "", 1),
"DVB Shift",
"SoC DVB Shift",
&thresholdsDisabled,
{},
{},
false
);
tsl::elm::ListItem* timingsSubmenu = new tsl::elm::ListItem("Memory Timings");
tsl::elm::ListItem* timingsSubmenu = new tsl::elm::ListItem("RAM Timing Reductions");
timingsSubmenu->setClickListener([](u64 keys) {
if (keys & HidNpadButton_A) {
tsl::changeTo<RamTimingsSubmenuGui>();
@@ -628,7 +624,7 @@ protected:
});
this->listElement->addItem(timingsSubmenu);
tsl::elm::ListItem* latenciesSubmenu = new tsl::elm::ListItem("Memory Latencies");
tsl::elm::ListItem* latenciesSubmenu = new tsl::elm::ListItem("RAM Latencies");
latenciesSubmenu->setClickListener([](u64 keys) {
if (keys & HidNpadButton_A) {
tsl::changeTo<RamLatenciesSubmenuGui>();
@@ -659,32 +655,34 @@ 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);
#if IS_MINIMAL == 0
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;
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 true;
} else {
writeNotification("Horizon OC\nSet your ram frequency to max\nbefore applying timings!");
}
}
return false;
});
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);
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
}
};
@@ -700,17 +698,17 @@ protected:
this->listElement->addItem(new tsl::elm::CategoryHeader("Memory Latencies"));
std::vector<NamedValue> rlLabels = {
NamedValue("1333RL", 28),
NamedValue("1600RL", 32),
NamedValue("1866RL", 36),
NamedValue("2133RL", 40)
NamedValue("1333 RL", 28),
NamedValue("1600 RL", 32),
NamedValue("1866 RL", 36),
NamedValue("2133 RL", 40)
};
std::vector<NamedValue> wlLabels = {
NamedValue("1333WL", 12),
NamedValue("1600WL", 14),
NamedValue("1866WL", 16),
NamedValue("2133WL", 18)
NamedValue("1333 WL", 12),
NamedValue("1600 WL", 14),
NamedValue("1866 WL", 16),
NamedValue("2133 WL", 18)
};
addConfigButton(
@@ -748,6 +746,8 @@ 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),
@@ -863,6 +863,8 @@ protected:
);
std::vector<NamedValue> maxClkOptions = {
NamedValue("1785 MHz", 1785000),
NamedValue("1887 MHz", 1887000),
NamedValue("1963 MHz", 1963000),
NamedValue("2091 MHz", 2091000),
NamedValue("2193 MHz", 2193000),
@@ -933,7 +935,7 @@ protected:
this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Settings"));
std::vector<NamedValue> gpuUvConf = {
NamedValue("No UV", 0),
NamedValue("No Undervolt", 0),
NamedValue("SLT Table", 1),
NamedValue("HiOPT Table", 2),
};
@@ -977,9 +979,9 @@ protected:
);
addConfigButton(
KipConfigValue_eristaGpuVmin,
"GPU VMIN",
"GPU Minimum Voltage",
ValueRange(700, 875, 5, "mV", 1),
"GPU VMIN",
"GPU Minimum Voltage",
&thresholdsDisabled,
{},
{},
@@ -1014,9 +1016,9 @@ protected:
ValueThresholds MgpuVmaxThresholds(800, 850);
addConfigButton(
KipConfigValue_marikoGpuVmax,
"GPU VMAX",
"GPU Maximum Voltage",
ValueRange(750, 960, 5, "mV", 1),
"GPU VMAX",
"GPU Maximum Voltage",
&MgpuVmaxThresholds,
{},
{},
@@ -1026,9 +1028,9 @@ protected:
addConfigButton(
KipConfigValue_commonGpuVoltOffset,
"GPU Volt Offset",
"GPU Voltage Offset",
ValueRange(0, 50, 5, "mV", 1),
"GPU Volt Offset",
"GPU Voltage Offset",
&thresholdsDisabled,
{},
{},
@@ -1224,7 +1226,7 @@ protected:
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_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);
}

View File

@@ -114,38 +114,40 @@ ClockManager::ClockManager()
void ClockManager::FixCpuBug() {
u32 targetHz = 0;
u32 maxHz = 0;
u32 nearestHz = 0;
if(this->config->Refresh() && this->RefreshContext()) {
u32 targetHz = 0;
u32 maxHz = 0;
u32 nearestHz = 0;
// ResetToStockClocks();
// 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;
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::SetHz(SysClkModule_CPU, targetHz);
}
}
ClockManager::~ClockManager()
{
threadClose(&governorTHREAD);
delete this->config;
delete this->context;
threadClose(&governorTHREAD);
}
SysClkContext ClockManager::GetCurrentContext()
@@ -323,7 +325,6 @@ void ClockManager::GovernorThread(void* arg)
continue;
}
std::scoped_lock lock{mgr->contextMutex};
if (!isGovernorEnabled)
{
@@ -337,6 +338,8 @@ void ClockManager::GovernorThread(void* arg)
svcSleepThread(50'000'000);
continue;
}
std::scoped_lock lock{mgr->contextMutex};
u32 currentHz = Board::GetHz(SysClkModule_GPU);
@@ -755,7 +758,6 @@ void ClockManager::SetKipData() {
CUST_WRITE_FIELD_BATCH(&table, t8_tREFI, this->config->GetConfigValue(KipConfigValue_t8_tREFI));
CUST_WRITE_FIELD_BATCH(&table, mem_burst_read_latency, this->config->GetConfigValue(KipConfigValue_mem_burst_read_latency));
CUST_WRITE_FIELD_BATCH(&table, mem_burst_write_latency, this->config->GetConfigValue(KipConfigValue_mem_burst_write_latency));
CUST_WRITE_FIELD_BATCH(&table, eristaCpuUV, this->config->GetConfigValue(KipConfigValue_eristaCpuUV));
CUST_WRITE_FIELD_BATCH(&table, eristaCpuVmin, this->config->GetConfigValue(KipConfigValue_eristaCpuVmin));
CUST_WRITE_FIELD_BATCH(&table, eristaCpuMaxVolt, this->config->GetConfigValue(KipConfigValue_eristaCpuMaxVolt));
@@ -851,6 +853,8 @@ void ClockManager::GetKipData() {
}
static bool writeBootConfigValues = true;
configValues.values[KipCrc32] = (u64)checksum_file("sdmc:/atmosphere/kips/hoc.kip"); // write checksum
if(writeBootConfigValues) {
writeBootConfigValues = false;

View File

@@ -35,6 +35,7 @@ typedef struct {
u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt;
u32 emcDvbShift;
// advanced config
u32 t1_tRCD;
u32 t2_tRP;
u32 t3_tRAS;
@@ -43,6 +44,7 @@ typedef struct {
u32 t6_tRTW;
u32 t7_tWTR;
u32 t8_tREFI;
u32 mem_burst_read_latency;
u32 mem_burst_write_latency;
@@ -58,17 +60,24 @@ typedef struct {
u32 marikoCpuHighVmin;
u32 marikoCpuMaxVolt;
u32 marikoCpuMaxClock;
u32 eristaCpuBoostClock;
u32 marikoCpuBoostClock;
u32 eristaGpuUV;
u32 eristaGpuVmin;
u32 marikoGpuUV;
u32 marikoGpuVmin;
u32 marikoGpuVmax;
u32 commonGpuVoltOffset;
u32 gpuSpeedo;
u32 eristaGpuVoltArray[27];
u32 marikoGpuVoltArray[24];
u32 reserved[64];
} CustomizeTable;
#pragma pack(pop)

1
ams_ver.txt Normal file
View File

@@ -0,0 +1 @@
1.10.2

View File

@@ -26,7 +26,7 @@ cp Horizon-OC-Monitor.ovl ../../dist/switch/.overlays/Horizon-OC-Monitor.ovl
cd ../../
ROOT="build"
PATCHES="Atmosphere-Patches"
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/"

75
dist/README.md vendored
View File

@@ -7,7 +7,7 @@
![License: GPL-2.0](https://img.shields.io/badge/GPL--2.0-red?style=for-the-badge)
![Nintendo Switch](https://img.shields.io/badge/Nintendo_Switch-E60012?style=for-the-badge\&logo=nintendo-switch\&logoColor=white)
[![Discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge\&logo=discord\&logoColor=white)](https://discord.com/invite/S3eX47dHsB)
[![Discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge\&logo=discord\&logoColor=white)](https://dsc.gg/horizonoc)
![VSCode](https://img.shields.io/badge/VSCode-0078D4?style=for-the-badge\&logo=visual%20studio%20code\&logoColor=white)
![Made with Notepad++](assets/np++.png?raw=true)
![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=for-the-badge\&logo=c%2B%2B\&logoColor=white)
@@ -44,7 +44,7 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
> *Higher (potentially dangerous) frequencies are unlockable via configuration.*
> *Erista and Mariko units can usually push a bit further fully safely with a bit of undervolting, however this may not work on all units.*
> *The exact maximum overclock possible varies per console, although most consoles should be able to do this safely.*
> *You may refer to the Clock Table to see clocks in more detail*
---
## Installation
@@ -69,7 +69,7 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
1. Open the Horizon OC Overlay
2. Open the settings menu
3. Adjust your overclocking settings as desired.
3. Adjust your overclocking settings as desired. A helpful guide can be found [here.](https://rentry.co/mariko#oc-settings-for-horizon-oc)
4. Click **Save KIP Settings** to apply your configuration.
---
@@ -78,6 +78,73 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
Refer to COMPILATION.md
---
## Clock table
### MEM clocks
* 3200 → max on mariko, JEDEC.
* 2933 → JEDEC.
* 2666 → JEDEC.
* 2400 → max on erista, JEDEC.
* 2133 → mariko safe max (4266 Modules), JEDEC.
* 1996 → JEDEC.
* 1866 → mariko safe max (3733 Modules), JEDEC.
* 1600 → official docked, boost mode, erista safe max, JEDEC.
* 1331 → official handheld, JEDEC.
* 1065
* 800
* 665
### CPU clocks
* 2601 → mariko absolute max, very dangerous
* 2499
* 2397
* 2295 → mariko safe max with UV (low speedo)
* 2193
* 2091
* 1963 → mariko no UV max clock
* 1887
* 1785 → erista no UV max clock, boost mode
* 1683
* 1581
* 1428
* 1326
* 1224 → sdev oc
* 1122
* 1020 → official docked & handheld
* 918
* 816
* 714
* 612 → sleep mode
### GPU clocks
* 1536 → absolute max clock on mariko. very dangerous
* 1459
* 1382
* 1305
* 1267 → NVIDIA T214 rating
* 1228 → mariko HiOPT safe clock
* 1152 → mariko SLT max clock
* 1075 → mariko no UV max clock. absolute max clock on erista. very dangerous
* 998 → NVIDIA T210 rating
* 960 (erista only) → erista slt/hiopt safe max clock
* 921 → erista no UV max clock
* 844
* 768 → official docked
* 691
* 614
* 537
* 460 → max handheld
* 384 → official handheld
* 307 → official handheld
* 230
* 153
* 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.
---
## Credits
@@ -95,4 +162,4 @@ Refer to COMPILATION.md
* **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
* **Samybigio2011** - Italian translations
* **Samybigio2011** - Italian translations

Binary file not shown.

Binary file not shown.

Binary file not shown.