diff --git a/Source/hoc-clk/sysmodule/src/board/board.cpp b/Source/hoc-clk/sysmodule/src/board/board.cpp index 8d611419..c08bea97 100644 --- a/Source/hoc-clk/sysmodule/src/board/board.cpp +++ b/Source/hoc-clk/sysmodule/src/board/board.cpp @@ -48,6 +48,7 @@ #include "../tsensor/aotag.hpp" #include "../hos/integrations.hpp" #include "../file/file_utils.hpp" +#include "../hos/rgltr.h" namespace board { u64 clkVirtAddr, dsiVirtAddr, apbVirtAddr, fuseVirtAddr; @@ -137,6 +138,9 @@ namespace board { rc = pmdmntInitialize(); ASSERT_RESULT_OK(rc, "pmdmntInitialize"); + rc = rgltrInitialize(); + ASSERT_RESULT_OK(rc, "rgltrInitialize"); + rc = QueryMemoryMapping(&clkVirtAddr, 0x60006000, 0x1000); ASSERT_RESULT_OK(rc, "QueryMemoryMapping (clk)"); @@ -201,7 +205,7 @@ namespace board { apmExtExit(); psmExit(); - + rgltrExit(); if (HOSSVC_HAS_TC) { tcExit(); } diff --git a/Source/hoc-clk/sysmodule/src/board/board_freq.cpp b/Source/hoc-clk/sysmodule/src/board/board_freq.cpp index 918a1f51..7e1c0d48 100644 --- a/Source/hoc-clk/sysmodule/src/board/board_freq.cpp +++ b/Source/hoc-clk/sysmodule/src/board/board_freq.cpp @@ -41,6 +41,7 @@ #include "../soc/pllmb.hpp" #include "../file/config.hpp" #include "../soc/gm20b.hpp" +#include "../file/config.hpp" namespace board { #define MIDDLE_FREQ_TABLE_START_POINT 1228800000 static u32 currentInjectedHz = 0; @@ -75,6 +76,14 @@ namespace board { ASSERT_RESULT_OK(pcvSetClockRate(moduleID, hz), "pcvSetClockRate"); } + void HandleCpuUv() + { + if (board::GetSocType() == HocClkSocType_Erista) + board::SetDfllTunings(config::GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000); // Erista tbreak is always 1581MHz + else + board::SetDfllTunings(config::GetConfigValue(KipConfigValue_marikoCpuUVLow), config::GetConfigValue(KipConfigValue_marikoCpuUVHigh), board::CalculateTbreak(config::GetConfigValue(KipConfigValue_tableConf))); + } + void SetHz(HocClkModule module, u32 hz) { Result rc = 0; bool usesGovenor = module > HocClkModule_MEM; @@ -116,7 +125,9 @@ namespace board { PcvSetHz(GetPcvModule(module), pcvHz); } } - + if(config::GetConfigValue(HocClkConfigValue_LiveCpuUv) && module == HocClkModule_CPU) { + HandleCpuUv(); + } if (useGm20b) { gm20b::setClock(hz / 1000); currentInjectedHz = hz; diff --git a/Source/hoc-clk/sysmodule/src/board/board_volt.cpp b/Source/hoc-clk/sysmodule/src/board/board_volt.cpp index c8d34166..8b1a556c 100644 --- a/Source/hoc-clk/sysmodule/src/board/board_volt.cpp +++ b/Source/hoc-clk/sysmodule/src/board/board_volt.cpp @@ -28,6 +28,7 @@ #include "board_volt.hpp" #include "../file/file_utils.hpp" #include "../i2c/i2cDrv.h" +#include "../hos/rgltr.h" namespace board { GpuVoltData voltData = {}; @@ -134,19 +135,16 @@ namespace board { return; } } else { - if (GetHz(HocClkModule_CPU) < tbreakPoint || (!levelLow)) { // account for tbreak - *tune0_ptr = cachedTune.tune0Low; // I think each erista has a different tune0/tune1? - *tune1_ptr = cachedTune.tune1Low; - return; - } else { - if (levelLow) { - *tune0_ptr = eristaCpuUvTable[levelLow-1].tune0; - *tune1_ptr = eristaCpuUvTable[levelLow-1].tune1; - } else { - *tune0_ptr = 0x0; - *tune1_ptr = 0x0; - } - } + // if (GetHz(HocClkModule_CPU) < tbreakPoint || (!levelLow)) { // account for tbreak + // *tune0_ptr = cachedTune.tune0Low; // I think each erista has a different tune0/tune1? + // *tune1_ptr = cachedTune.tune1Low; + // return; + // } else { + // if (levelLow) { + *tune0_ptr = eristaCpuUvTable[levelLow-1].tune0; + *tune1_ptr = eristaCpuUvTable[levelLow-1].tune1; + // } else { + // } } } @@ -213,10 +211,13 @@ namespace board { PcvPowerDomainId_Max77812_Dram = 0x3A000005, // vddq } PowerDomainId; */ + /* + Note: I think Nintendo's I2C driver (or my driver, but it looks correct to me) + */ u32 GetVoltage(HocClkVoltage voltage) { u32 out = 0; BatteryChargeInfo info; - + RgltrSession s; switch (voltage) { case HocClkVoltage_SOC: out = I2c_BuckConverter_GetUvOut(&I2c_SOC); @@ -228,14 +229,18 @@ namespace board { if(GetSocType() == HocClkSocType_Mariko) { out = I2c_BuckConverter_GetUvOut(&I2c_Mariko_CPU); } else { - out = I2c_BuckConverter_GetUvOut(&I2c_Erista_CPU); + rgltrOpenSession(&s, PcvPowerDomainId_Max77621_Cpu); + rgltrGetVoltage(&s, &out); + rgltrCloseSession(&s); } break; case HocClkVoltage_GPU: if(GetSocType() == HocClkSocType_Mariko) { out = I2c_BuckConverter_GetUvOut(&I2c_Mariko_GPU); } else { - out = I2c_BuckConverter_GetUvOut(&I2c_Erista_GPU); + rgltrOpenSession(&s, PcvPowerDomainId_Max77621_Gpu); + rgltrGetVoltage(&s, &out); + rgltrCloseSession(&s); } break; case HocClkVoltage_EMCVDDQ: @@ -453,5 +458,4 @@ namespace board { return baseVolt; } - } \ No newline at end of file diff --git a/Source/hoc-clk/sysmodule/src/hos/rgltr.h b/Source/hoc-clk/sysmodule/src/hos/rgltr.h new file mode 100644 index 00000000..33268b8a --- /dev/null +++ b/Source/hoc-clk/sysmodule/src/hos/rgltr.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) ppkantorski (bord2death) + * + * 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 . + * + */ + +#pragma once +#include +#include "pcv_types.h" + +typedef struct { + Service s; +} RgltrSession; + +Result rgltrInitialize(void); + +void rgltrExit(void); + +Service* rgltrGetServiceSession(void); + +Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id); +void rgltrCloseSession(RgltrSession* session); +Result rgltrGetVoltage(RgltrSession* session, u32 *out_volt); +Result rgltrGetPowerModuleNumLimit(u32 *out); +Result rgltrGetVoltageEnabled(RgltrSession* session, u32 *out); +Result rgltrRequestVoltage(RgltrSession* session, u32 microvolt); +Result rgltrCancelVoltageRequest(RgltrSession* session); \ No newline at end of file diff --git a/Source/hoc-clk/sysmodule/src/hos/rgltr_services.cpp b/Source/hoc-clk/sysmodule/src/hos/rgltr_services.cpp new file mode 100644 index 00000000..4904df88 --- /dev/null +++ b/Source/hoc-clk/sysmodule/src/hos/rgltr_services.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) ppkantorski (bord2death) + * + * 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 . + * + */ + +#include +#include "rgltr.h" +#include "rgltr_services.h" // for extern Service g_rgltrSrv, etc. + +// Global service handle +Service g_rgltrSrv; + +Result rgltrInitialize(void) { + if (hosversionBefore(8, 0, 0)) { + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + } + return smGetService(&g_rgltrSrv, "rgltr"); +} + +void rgltrExit(void) { + serviceClose(&g_rgltrSrv); +} + +Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id) { + const u32 in = (u32)module_id; + return serviceDispatchIn( + &g_rgltrSrv, + 0, + in, + .out_num_objects = 1, + .out_objects = &session_out->s + ); +} + +Result rgltrGetVoltage(RgltrSession* session, u32* out_volt) { + u32 temp = 0; + Result rc = serviceDispatchOut(&session->s, 4, temp); + if (R_SUCCEEDED(rc)) { + *out_volt = temp; + } + return rc; +} + +Result rgltrRequestVoltage(RgltrSession* session, u32 microvolt) { + return serviceDispatchIn(&session->s, 5, microvolt); +} + +Result rgltrCancelVoltageRequest(RgltrSession* session) { + return serviceDispatch(&session->s, 6); +} + +void rgltrCloseSession(RgltrSession* session) { + serviceClose(&session->s); +} \ No newline at end of file diff --git a/Source/hoc-clk/sysmodule/src/hos/rgltr_services.h b/Source/hoc-clk/sysmodule/src/hos/rgltr_services.h new file mode 100644 index 00000000..d8a886bf --- /dev/null +++ b/Source/hoc-clk/sysmodule/src/hos/rgltr_services.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) ppkantorski (bord2death) + * + * 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 . + * + */ + +#pragma once + +#include // for Service, Result, hosversionBefore(), smGetService(), serviceClose(), etc. +#include "rgltr.h" // for RgltrSession, PowerDomainId, etc. + +extern Service g_rgltrSrv; + +Result rgltrInitialize(void); +void rgltrExit(void); + +Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id); + +Result rgltrGetVoltage(RgltrSession* session, u32* out_volt); + +void rgltrCloseSession(RgltrSession* session); \ No newline at end of file diff --git a/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp b/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp index d74a9d97..6f9d4c15 100644 --- a/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp +++ b/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp @@ -299,13 +299,6 @@ namespace clockManager { } } - void HandleCpuUv() - { - if (board::GetSocType() == HocClkSocType_Erista) - board::SetDfllTunings(config::GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000); // Erista tbreak is always 1581MHz - else - board::SetDfllTunings(config::GetConfigValue(KipConfigValue_marikoCpuUVLow), config::GetConfigValue(KipConfigValue_marikoCpuUVHigh), board::CalculateTbreak(config::GetConfigValue(KipConfigValue_tableConf))); - } void DVFSReset() { @@ -452,10 +445,6 @@ namespace clockManager { gContext.stable.freqs[module] = nearestHz; } - if (module == HocClkModule_CPU && config::GetConfigValue(HocClkConfigValue_LiveCpuUv)) { - HandleCpuUv(); - } - if (module == HocClkModule_MEM && board::GetSocType() == HocClkSocType_Mariko && targetHz < oldHz && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) { ApplyGpuDvfs(targetHz); } diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 00000000..ff3e6be6 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,214 @@ + +
+ +logo + +--- + +![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://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) +![Downloads](https://img.shields.io/github/downloads/Horizon-OC/Horizon-OC/total.svg?style=for-the-badge) + +--- + +
+ +## ⚠️ Disclaimer + +> **THIS TOOL CAN BE DANGEROUS IF MISUSED. PROCEED WITH CAUTION.** +> Due to the design of Horizon OS, **overclocking RAM can cause NAND OR SD CORRUPTION.** +> Ensure you have a **full NAND, PROINFO, EMUMMC and SD backup** before proceeding. + +--- + +## About + +**Horizon OC** is an open-source overclocking tool for Nintendo Switch consoles running **Atmosphere custom firmware**. +It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration tools. + +--- + +## Default clocks + +* **CPU:** Up to 1963MHz (Mariko) / 1785MHz (Erista) +* **GPU:** Up to 1075MHz (Mariko) / 921MHz (Erista) +* **RAM:** Up to 1866/2133MHz (Mariko) / 1600MHz (Erista) +* Over/undervolting support +* Built-in configurator +* Compatible with most homebrew + +> It is recommended to read the [guide](https://rentry.co/howtoget60fps) before proceeding, as this can help you get a *significant* performance boost over the default settings, often times with less power draw and heat output + +--- + +## Installation + +1. Ensure you have the latest versions of + + * [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere) + * [Ultrahand Overlay](https://github.com/ppkantorski/Ultrahand-Overlay) +2. Download and extract the **Horizon OC Package** to the root of your SD card. +3. If using **Hekate**, edit `hekate_ipl.ini` to include: + + ``` + kip1=atmosphere/kips/hoc.kip + ``` + + *(No changes needed if using fusee.)* + +--- + +## Configuration + +1. Open the Horizon OC Overlay +2. Open the settings menu +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. + +--- + +## Building from Source + +Refer to COMPILATION.md + +--- +## Clock table + +### MEM clocks (mhz) + +* 3200 → max on mariko, JEDEC. +* 3166 +* 3133 +* 3100 +* 3066 +* 3033 +* 3000 +* 2966 +* 2933 → JEDEC. +* 2900 +* 2866 +* 2833 +* 2800 +* 2766 +* 2733 +* 2700 +* 2666 → JEDEC. +* 2633 +* 2600 +* 2566 +* 2533 +* 2500 +* 2466 +* 2433 +* 2400 → max on erista, JEDEC. +* 2366 +* 2333 +* 2300 +* 2266 +* 2233 +* 2200 +* 2166 +* 2133 → Mariko JEDEC standard max (4266 Modules) +* 2100 +* 2066 +* 2033 +* 2000 +* 1996 → JEDEC standard +* 1966 +* 1933 +* 1900 +* 1866 → Mariko JEDEC standard max (3733 Modules) +* 1833 +* 1800 +* 1766 +* 1733 +* 1700 +* 1666 +* 1633 +* 1600 → official docked, boost mode, Erista JEDEC standard max (3200 Modules), JEDEC. +* 1331 → official handheld, JEDEC. +* 1065 +* 800 +* 665 + +### CPU clocks (mhz) +* 2703 → mariko absolute max, dangerous +* 2601 → unsafe +* 2499 +* 2397 → mariko safe max with UV (low speedo) +* 2295 +* 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 (mhz) +* 1536 → absolute max clock on mariko. very dangerous +* 1459 +* 1382 +* 1305 +* 1267 → NVIDIA T214(mariko) rating +* 1228 → mariko High UV safe clock +* 1152 → mariko hiOpt-15mV max clock +* 1075 → mariko hiOpt max clock. absolute max clock on erista. very dangerous +* 998 → NVIDIA T210 (erista) rating +* 960 (erista only) → erista high uv/hiOpt-15mV 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. On Erista, CPU in handheld is capped to 1581MHz +2. GPU overclock is capped at 460MHz on erista in handheld +3. On Mariko, cap with hiOpt is 614MHz, with hiOpt-15mV it is 691MHz and with High UV it's 768MHz +4. Clocks higher than 768MHz on erista need the official charger is plugged in. + +--- + +## Credits +* **Lightos's Cat** - Cat +* **Souldbminer** - hoc-clk and loader development +* **Lightos** - Loader patches development, hoc-clk development, guides +* **TDRR** - HOC Logo Design +* **tetetete-ctrl** - Website design +* **SciresM** - Atmosphere CFW +* **CTCaer** - L4T, Hekate, proper RAM timings +* **KazushiMe** - Switch OC Suite +* **Hanai3bi (Meha)** - Switch OC Suite, EOS, sys-clk-eos +* **NaGaa95** - L4T-OC kernel, Status Monitor fork +* **B3711 (halop)** - EOS, contributions +* **sys-clk team (m4xw, p-sam, natinusala)** - sys-clk +* **Dominatorul** - Soctherm driver, guides, general help +* **ppkantorski** - Ultrahand sys-clk & Status Monitor fork +* **MasaGratoR and ZachyCatGames** - General help +* **MasaGratoR** - Status Monitor & Display Refresh Rate driver +* **Dominatorul, Samybigio, Arcdelta, Miki, Happy, Winnerboi77, Blaise, Alvise, agjeococh, frost, letum00, and Xenshen** - Testing +* **Samybigio2011, Miki** - Italian translations +* **angelblaster** - Korean translations +* **q1332348216-glitch** - Chinese translations +* **Nvidia** - [Tegra X1 Technical Reference Manual](https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual), soctherm driver, L4T diff --git a/dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp b/dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp index 22188966..c0482a40 100644 Binary files a/dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp and b/dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp differ diff --git a/dist/atmosphere/kips/hoc.kip b/dist/atmosphere/kips/hoc.kip index 3c84a553..006812e2 100644 Binary files a/dist/atmosphere/kips/hoc.kip and b/dist/atmosphere/kips/hoc.kip differ diff --git a/dist/switch/.overlays/horizon-oc-overlay.ovl b/dist/switch/.overlays/horizon-oc-overlay.ovl index a546ef38..7d5d01e8 100644 Binary files a/dist/switch/.overlays/horizon-oc-overlay.ovl and b/dist/switch/.overlays/horizon-oc-overlay.ovl differ