Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7f14b88e5 | ||
|
|
35a269e4a7 | ||
|
|
ff95ca527f | ||
|
|
550e4e5204 | ||
|
|
a088c4795a | ||
|
|
e8a264fa11 | ||
|
|
de681c20a0 | ||
|
|
22aef264ab | ||
|
|
309717c468 | ||
|
|
9b91d7487c | ||
|
|
c0b458243c | ||
|
|
7d9c60cdfe | ||
|
|
12c9effec2 | ||
|
|
6eeab63075 | ||
|
|
2d81c5e127 | ||
|
|
b1739cea74 | ||
|
|
aa607ab1a7 | ||
|
|
d1242a17d4 | ||
|
|
80701c2891 | ||
|
|
cfd0d84ac8 | ||
|
|
c33aabdc84 | ||
|
|
c70fd82e60 | ||
|
|
574c248d68 | ||
|
|
0ae65c8740 | ||
|
|
39fbe25afc |
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Minimal devkitA64 container, apparently dkp-toolchain isn't needed?
|
||||
# Minimal devkitA64 container
|
||||
container:
|
||||
image: devkitpro/devkita64:20251231
|
||||
|
||||
@@ -47,9 +47,12 @@ jobs:
|
||||
# -------------------------------------------------
|
||||
# Get short commit SHA
|
||||
# -------------------------------------------------
|
||||
- name: Set commit SHA
|
||||
- name: Set commit SHA & dist
|
||||
id: vars
|
||||
run: echo "SHORT_SHA=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV
|
||||
run: |
|
||||
echo "SHORT_SHA=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV
|
||||
echo $SHORT_SHA > dist/.commit
|
||||
echo $GITHUB_SHA >> dist/.commit
|
||||
|
||||
- name: Clone Atmosphere
|
||||
run: git clone --depth=1 --single-branch https://github.com/Atmosphere-NX/Atmosphere.git atmosphere -b $(cat ams_ver.txt)
|
||||
@@ -149,23 +152,12 @@ jobs:
|
||||
- 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 }}
|
||||
name: horizon-oc-zeus-dist
|
||||
path: dist/
|
||||
compression-level: 3
|
||||
|
||||
13
README.md
13
README.md
@@ -41,10 +41,8 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
|
||||
* Built-in configurator
|
||||
* Compatible with most homebrew
|
||||
|
||||
> *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*
|
||||
> It is reccomended 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
|
||||
@@ -91,15 +89,15 @@ Refer to COMPILATION.md
|
||||
* 1866 → mariko safe max (3733 Modules), JEDEC.
|
||||
* 1600 → official docked, boost mode, erista safe max, JEDEC.
|
||||
* 1331 → official handheld, JEDEC.
|
||||
* 1065
|
||||
* 1065
|
||||
* 800
|
||||
* 665
|
||||
|
||||
### CPU clocks
|
||||
* 2601 → mariko absolute max, very dangerous
|
||||
* 2499
|
||||
* 2397
|
||||
* 2295 → mariko safe max with UV (low speedo)
|
||||
* 2397 → mariko safe max with UV (low speedo)
|
||||
* 2295
|
||||
* 2193
|
||||
* 2091
|
||||
* 1963 → mariko no UV max clock
|
||||
@@ -153,6 +151,7 @@ Refer to COMPILATION.md
|
||||
* **Souldbminer** – hoc-clk and loader development
|
||||
* **Lightos** – loader patches development
|
||||
* **SciresM** - Atmosphere CFW
|
||||
* **CTCaer** - L4T, Hekate, perfect ram timings
|
||||
* **KazushiMe** – Switch OC Suite
|
||||
* **hanai3bi (meha)** – Switch OC Suite, EOS, sys-clk-eos
|
||||
* **NaGaa95** – L4T-OC-kernel
|
||||
|
||||
@@ -694,11 +694,11 @@ namespace ams::ldr {
|
||||
|
||||
/* Apply PCV and PTM patches */
|
||||
if (g_is_pcv) {
|
||||
oc::pcv::Patch(map_address, nso_size);
|
||||
hoc::pcv::Patch(map_address, nso_size);
|
||||
}
|
||||
|
||||
if (g_is_ptm) {
|
||||
oc::ptm::Patch(map_address, nso_size);
|
||||
hoc::ptm::Patch(map_address, nso_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,23 +22,24 @@
|
||||
|
||||
/* Never edit these. */
|
||||
#define AUTO 0
|
||||
#define AUTO_RAM 0
|
||||
#define ENABLED 1
|
||||
#define DISABLED 0
|
||||
#define DEACTIVATED_GPU_FREQ 2000
|
||||
#define GPU_MIN_MIN_VOLT 480000
|
||||
#define CPU_MAX_MAX_VOLT 1235000
|
||||
|
||||
namespace ams::ldr::oc {
|
||||
namespace ams::ldr::hoc {
|
||||
|
||||
volatile CustomizeTable C = {
|
||||
|
||||
/* Disables RAM powerdown */
|
||||
.hpMode = DISABLED,
|
||||
|
||||
.commonEmcMemVolt = 1175000, // LPDDR4X JEDEC Specification
|
||||
.eristaEmcMaxClock = 1600000, // Maximum HB-MGCH ram rating
|
||||
.commonEmcMemVolt = 1175000, /* LPDDR4X JEDEC Specification */
|
||||
.eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */
|
||||
|
||||
.marikoEmcMaxClock = 1866000, // 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units
|
||||
.marikoEmcVddqVolt = 600000,
|
||||
.marikoEmcMaxClock = 1866000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */
|
||||
.marikoEmcVddqVolt = 600000, /* Micron: 600mV, other manafacturers: 640mV */
|
||||
.emcDvbShift = 0,
|
||||
|
||||
// Primary
|
||||
@@ -52,9 +53,7 @@ volatile CustomizeTable C = {
|
||||
.t7_tWTR = 0,
|
||||
.t8_tREFI = 0,
|
||||
|
||||
/* Set to 4 read and 2 write for 1866b tWRL. */
|
||||
/* For 2133 tWRL: 8 read and 4 write. */
|
||||
|
||||
/* You can mix and match different latencies if needed */
|
||||
/*
|
||||
* Read:
|
||||
* 2133RL = 40
|
||||
@@ -67,8 +66,9 @@ volatile CustomizeTable C = {
|
||||
* 1600WL = 14
|
||||
* 1331WL = 12
|
||||
*/
|
||||
.mem_burst_read_latency = 36,
|
||||
.mem_burst_write_latency = 16,
|
||||
|
||||
.mem_burst_read_latency = RL_1866,
|
||||
.mem_burst_write_latency = WL_1866,
|
||||
|
||||
.eristaCpuUV = 0,
|
||||
.eristaCpuVmin = 800,
|
||||
@@ -78,9 +78,11 @@ volatile CustomizeTable C = {
|
||||
|
||||
.marikoCpuUVLow = 0, // No undervolt
|
||||
.marikoCpuUVHigh = 0, // No undervolt
|
||||
|
||||
.tableConf = DEFAULT_TABLE,
|
||||
.marikoCpuLowVmin = 620,
|
||||
.marikoCpuHighVmin = 750,
|
||||
/* 1120mV is NVIDIA rating */
|
||||
.marikoCpuMaxVolt = 1120,
|
||||
|
||||
/* Supported values: 1963000, 2091000, 2193000, 2295000, 2397000, 2499000, 2601000, 2703000. */
|
||||
@@ -99,19 +101,22 @@ volatile CustomizeTable C = {
|
||||
.eristaGpuVmin = 810,
|
||||
|
||||
.marikoGpuUV = 0,
|
||||
|
||||
/* For automatic vmin detection, set this to AUTO. */
|
||||
.marikoGpuVmin = AUTO,
|
||||
/* vmin past 795mV won't work due to HOS limitation */
|
||||
/* Vmin is automatically set to 800mV when SoC temperature is below 20C */
|
||||
.marikoGpuVmin = AUTO,
|
||||
|
||||
.marikoGpuVmax = 800,
|
||||
|
||||
.commonGpuVoltOffset = 0,
|
||||
|
||||
/* Speedo is automatically set by hoc-clk on first boot */
|
||||
.gpuSpeedo = 1450,
|
||||
|
||||
/* This table is used with a gpu uv mode of 2. */
|
||||
/* Setting DEACTIVATED_GPU_FREQ on any freq will disable it and all freqs greater than it. (the latter is a bug :/) */
|
||||
/* AUTO: Voltage is optimally chosen; with commonGpuVoltOffset applied. */
|
||||
/* AUTO only works up to 1305 GPU on Mariko and 921 GPU on Erista */
|
||||
/* AUTO only works up to 1305 GPU on Mariko and 998 GPU on Erista (it is reccomended to manually set your 998MHz voltage though) */
|
||||
/* You can overwrite auto with any voltage (in mv) of your choice - offset will not be applied. */
|
||||
|
||||
.eristaGpuVoltArray = {
|
||||
@@ -159,8 +164,8 @@ volatile CustomizeTable C = {
|
||||
AUTO /* 921 */,
|
||||
AUTO /* 998 */,
|
||||
AUTO /* 1075 */,
|
||||
DEACTIVATED_GPU_FREQ /* 1152 */,
|
||||
DEACTIVATED_GPU_FREQ /* 1228 */,
|
||||
AUTO /* 1152 (SLT / HiOPT Only!) */,
|
||||
AUTO /* 1228 (HiOPT Only!) */,
|
||||
DEACTIVATED_GPU_FREQ /* 1267 (Disabled by default) */,
|
||||
DEACTIVATED_GPU_FREQ /* 1305 (Disabled by default) */,
|
||||
DEACTIVATED_GPU_FREQ /* 1344 (Disabled by default) */,
|
||||
|
||||
@@ -20,20 +20,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CUST_REV 11
|
||||
#define CUST_REV 1
|
||||
|
||||
#include "oc_common.hpp"
|
||||
#include "pcv/pcv_common.hpp"
|
||||
|
||||
namespace ams::ldr::oc {
|
||||
namespace ams::ldr::hoc {
|
||||
|
||||
#include "mtc_timing_table.hpp"
|
||||
|
||||
enum MtcConfig: u32 {
|
||||
AUTO_ADJ = 0,
|
||||
AUTO_ADJ_BL = 1,
|
||||
};
|
||||
|
||||
enum TableConfig: u32 {
|
||||
DEFAULT_TABLE = 1,
|
||||
TBREAK_1581 = 2,
|
||||
@@ -41,6 +36,33 @@ enum TableConfig: u32 {
|
||||
EXTREME_TABLE = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Read:
|
||||
* 2133RL = 40
|
||||
* 1866RL = 36
|
||||
* 1600RL = 32
|
||||
* 1331RL = 28
|
||||
* Write:
|
||||
* 2133WL = 18
|
||||
* 1866WL = 16
|
||||
* 1600WL = 14
|
||||
* 1331WL = 12
|
||||
*/
|
||||
|
||||
enum ReadLatency: u32 {
|
||||
RL_2133 = 40,
|
||||
RL_1866 = 36,
|
||||
RL_1600 = 32,
|
||||
RL_1331 = 28,
|
||||
};
|
||||
|
||||
enum WriteLatency: u32 {
|
||||
WL_2133 = 18,
|
||||
WL_1866 = 16,
|
||||
WL_1600 = 14,
|
||||
WL_1331 = 12,
|
||||
};
|
||||
|
||||
using CustomizeCpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit];
|
||||
using CustomizeGpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit];
|
||||
static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(CustomizeGpuDvfsTable));
|
||||
@@ -53,7 +75,7 @@ typedef struct CustomizeTable {
|
||||
u8 cust[4] = {'C', 'U', 'S', 'T'};
|
||||
u32 custRev = CUST_REV;
|
||||
|
||||
u32 mtcConf;
|
||||
u32 placeholder;
|
||||
u32 hpMode;
|
||||
|
||||
u32 commonEmcMemVolt;
|
||||
|
||||
@@ -18,49 +18,16 @@
|
||||
#include "../mtc_timing_value.hpp"
|
||||
#include "timing_tables.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
u32 GetRext() {
|
||||
void GetRext() {
|
||||
if (auto r = FindRext()) {
|
||||
return r->correct;
|
||||
rext = r->rext;
|
||||
return;
|
||||
}
|
||||
return 0x1A;
|
||||
}
|
||||
|
||||
void CalculateTWTPDEN() {
|
||||
tWTPDEN = tW2P + 1 + CEIL(tDQSS_max / tCK_avg) + CEIL(tDQS2DQ_max / tCK_avg) + 6;
|
||||
if (C.marikoEmcMaxClock >= 2'233'000 && C.marikoEmcMaxClock < 2'533'000) tWTPDEN++;
|
||||
if (C.marikoEmcMaxClock >= 2'433'000 && C.marikoEmcMaxClock < 2'800'000) tWTPDEN--;
|
||||
}
|
||||
|
||||
void CalculateTR2W() {
|
||||
tR2W = CEIL(RL_DBI + (tDQSCK_max / tCK_avg) + (BL / 2) - WL + tWPRE + FLOOR(tRPST) + 9.0) - (C.t6_tRTW * 3);
|
||||
|
||||
if (auto patch = FindTR2WPatch()) {
|
||||
tR2W += patch->adjust;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatePdex2rw() {
|
||||
double freq_mhz = C.marikoEmcMaxClock / 1000.0;
|
||||
|
||||
double pdex_local = (0.011 * freq_mhz) - 1.443;
|
||||
pdex2rw = static_cast<u32>(ROUND(pdex_local));
|
||||
|
||||
if (pdex2rw < 22) pdex2rw = 22;
|
||||
if (pdex2rw > 33) pdex2rw = 33;
|
||||
|
||||
if (auto patch = FindPdex2rwPatch()) {
|
||||
pdex2rw += patch->adjust;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateCke2pden() {
|
||||
cke2pden = (static_cast<double>((C.marikoEmcMaxClock / 1000.0) * 0.00875) - 0.65);
|
||||
|
||||
if (auto patch = FindCke2pdenPatch()) {
|
||||
cke2pden += patch->adjust;
|
||||
}
|
||||
/* Fallback. */
|
||||
rext = 0x1A;
|
||||
}
|
||||
|
||||
void CalculateMrw2() {
|
||||
@@ -93,11 +60,7 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
}
|
||||
|
||||
void CalculateTimings() {
|
||||
rext = GetRext();
|
||||
CalculateTWTPDEN();
|
||||
CalculateTR2W();
|
||||
CalculatePdex2rw();
|
||||
CalculateCke2pden();
|
||||
GetRext();
|
||||
CalculateMrw2();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
void CalculateTimings();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "../mtc_timing_value.hpp"
|
||||
#include "timing_tables.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
const ReplacePatch g_rext_table[] = {
|
||||
{2'133'000, 0x1A}, {2'166'000, 0x19}, {2'200'000, 0x19},
|
||||
@@ -36,78 +36,11 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
const u32 g_rext_table_size = sizeof(g_rext_table) / sizeof(g_rext_table[0]);
|
||||
|
||||
const ReplacePatch *FindRext() {
|
||||
for (u32 i = 0; i < g_rext_table_size; i++)
|
||||
if (g_rext_table[i].freq == C.marikoEmcMaxClock)
|
||||
for (u32 i = 0; i < g_rext_table_size; i++) {
|
||||
if (g_rext_table[i].freq >= C.marikoEmcMaxClock) {
|
||||
return &g_rext_table[i];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const AdjustPatch g_tr2w_patches[] = {
|
||||
{2'500'000, 1},
|
||||
{2'533'000, 1},
|
||||
{2'566'000, 1},
|
||||
{2'866'000, -1},
|
||||
{3'100'000, 1},
|
||||
{3'133'000, 1},
|
||||
};
|
||||
|
||||
const u32 g_tr2w_table_size = sizeof(g_tr2w_patches) / sizeof(g_tr2w_patches[0]);
|
||||
|
||||
const AdjustPatch *FindTR2WPatch() {
|
||||
for (u32 i = 0; i < g_tr2w_table_size; i++)
|
||||
if (g_tr2w_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_tr2w_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const AdjustPatch g_pdex2rw_patches[] = {
|
||||
{2'166'000, 1},
|
||||
{2'300'000, 1},
|
||||
{2'333'000, 1},
|
||||
{2'433'000, 1},
|
||||
{2'533'000, 0},
|
||||
{2'633'000, -1},
|
||||
{2'666'000, -1},
|
||||
{2'733'000, -1},
|
||||
{2'766'000, -1},
|
||||
{2'800'000, -1},
|
||||
{2'833'000, -1},
|
||||
{2'933'000, -1},
|
||||
{3'066'000, 1},
|
||||
};
|
||||
|
||||
const u32 g_pdex2rw_table_size = sizeof(g_pdex2rw_patches) / sizeof(g_pdex2rw_patches[0]);
|
||||
|
||||
const AdjustPatch *FindPdex2rwPatch() {
|
||||
for (u32 i = 0; i < g_pdex2rw_table_size; i++)
|
||||
if (g_pdex2rw_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_pdex2rw_patches[i];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const AdjustPatch g_cke2pden_patches[] = {
|
||||
{2'133'000, 1},
|
||||
{2'166'000, 1},
|
||||
{2'266'000, 1},
|
||||
{2'300'000, 1},
|
||||
{2'366'000, 1},
|
||||
{2'400'000, 1},
|
||||
{2'500'000, 1},
|
||||
{2'633'000, 1},
|
||||
{2'733'000, 1},
|
||||
{2'833'000, 1},
|
||||
{2'866'000, 1},
|
||||
{2'966'000, 1},
|
||||
{3'066'000, 1},
|
||||
{3'100'000, 1},
|
||||
};
|
||||
|
||||
const u32 g_cke2pden_table_size = sizeof(g_cke2pden_patches) / sizeof(g_cke2pden_patches[0]);
|
||||
|
||||
const AdjustPatch *FindCke2pdenPatch() {
|
||||
for (u32 i = 0; i < g_cke2pden_table_size; i++)
|
||||
if (g_cke2pden_patches[i].freq == C.marikoEmcMaxClock)
|
||||
return &g_cke2pden_patches[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,32 +17,15 @@
|
||||
#pragma once
|
||||
#include "../mtc_timing_value.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
struct ReplacePatch {
|
||||
u32 freq;
|
||||
u32 correct;
|
||||
u32 rext;
|
||||
};
|
||||
|
||||
extern const ReplacePatch g_rext_table[];
|
||||
extern const u32 g_rext_table_size;
|
||||
const ReplacePatch *FindRext();
|
||||
|
||||
struct AdjustPatch {
|
||||
u32 freq;
|
||||
s32 adjust;
|
||||
};
|
||||
|
||||
extern const AdjustPatch g_tr2w_patches[];
|
||||
extern const u32 g_tr2w_table_size;
|
||||
const AdjustPatch *FindTR2WPatch();
|
||||
|
||||
extern const AdjustPatch g_pdex2rw_patches[];
|
||||
extern const u32 g_pdex2rw_table_size;
|
||||
const AdjustPatch *FindPdex2rwPatch();
|
||||
|
||||
extern const AdjustPatch g_cke2pden_patches[];
|
||||
extern const u32 g_cke2pden_table_size;
|
||||
const AdjustPatch *FindCke2pdenPatch();
|
||||
|
||||
}
|
||||
|
||||
@@ -20,20 +20,20 @@
|
||||
|
||||
#include "oc_common.hpp"
|
||||
|
||||
namespace ams::ldr::oc {
|
||||
#define MAX(A, B) std::max(A, B)
|
||||
#define MIN(A, B) std::min(A, B)
|
||||
#define CEIL(A) std::ceil(A)
|
||||
#define FLOOR(A) std::floor(A)
|
||||
#define ROUND(A) std::lround(A)
|
||||
namespace ams::ldr::hoc {
|
||||
#define MAX(A, B) std::max(A, B)
|
||||
#define MIN(A, B) std::min(A, B)
|
||||
#define CEIL(A) std::ceil(A)
|
||||
#define FLOOR(A) std::floor(A)
|
||||
#define ROUND(A) std::lround(A)
|
||||
|
||||
#define PACK_U32(high, low) ((static_cast<u32>(high) << 16) | (static_cast<u32>(low) & 0xFFFF))
|
||||
#define PACK_U32_NIBBLE_HIGH_BYTE_LOW(high, low) ((static_cast<u32>(high & 0xF) << 28) | (static_cast<u32>(low) & 0xFF))
|
||||
|
||||
/* Primary timings. */
|
||||
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
|
||||
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
|
||||
const std::array<double, 7> tRRD_values = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? 8gb uses 7.5 tRRD on >=1331. */
|
||||
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
|
||||
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
@@ -96,7 +96,7 @@ namespace ams::ldr::oc {
|
||||
|
||||
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);
|
||||
@@ -139,43 +139,41 @@ namespace ams::ldr::oc {
|
||||
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
|
||||
const double tRPab = tRPpb + 3;
|
||||
|
||||
const u32 tR2P = 12 + ((RL_DBI - 32) / 2);
|
||||
inline u32 tR2W;
|
||||
const u32 tRTM = RL + 9 + (tDQSCK_max / tCK_avg) + FLOOR(tRPST) + CEIL(10 / tCK_avg); // Fix?
|
||||
const u32 tRATM = tRTM + CEIL(10 / tCK_avg) - 12; // Fix?
|
||||
const u32 tR2P = CEIL((RL_DBI * 0.426) - 2.0);
|
||||
const u32 tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL_DBI - (C.t6_tRTW * 3);
|
||||
const u32 tRTM = FLOOR((10.0 + RL_DBI) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg);
|
||||
const u32 tRATM = CEIL((tRTM - 10.0) + (RL_DBI * 0.426));
|
||||
inline u32 rext;
|
||||
|
||||
const u32 rdv = FLOOR(17.02046755653219 + (RL_DBI + (ramFreqMhz * 0.00510056573299173)));
|
||||
const u32 qpop = rdv - 14;
|
||||
const u32 quse_width = CEIL(((3.7165006256863955 - ramFreqMhz) + (-0.002446584377651142 * ramFreqMhz)) - FLOOR(ramFreqMhz / -0.9952024303111688));
|
||||
const u32 quse = CEIL(MIN(RL_DBI + (2.991255208275918 - (quse_width + (-0.00511180626826906 * ramFreqMhz))), ramFreqMhz * 0.021333773138874437));
|
||||
const u32 einput_duration = CEIL(quse_width + (ramFreqMhz * 0.01) + 4);
|
||||
const u32 einput = 5 + qpop - einput_duration;
|
||||
const u32 ibdly = 0x10000000 + FLOOR(MAX(RL_DBI - 1.9999956603408224, quse - 5.9999987787411175) + (-0.0011929079761504341 * ramFreqMhz));
|
||||
const u32 qrst_duration = FLOOR((ramFreqMhz * 0.001477125119082522) + 4.272302254983803);
|
||||
const u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0));
|
||||
const u32 qrst = PACK_U32(qrst_duration, qrstLow);
|
||||
const u32 qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
|
||||
|
||||
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
inline u32 tWTPDEN;
|
||||
const u32 tW2R = CEIL(MAX(WL + (0.010322547033278747 * ramFreqMhz), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg));
|
||||
const u32 tWTM = WL + (BL / 2) + 1 + CEIL(7.5 / tCK_avg);
|
||||
const u32 tWATM = tWTM + CEIL(tWR / tCK_avg);
|
||||
const u32 rdv = RL_DBI + FLOOR((5.105 / tCK_avg) + 17.017);
|
||||
const u32 qpop = rdv - 14;
|
||||
const u32 quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782);
|
||||
const u32 quse = FLOOR(RL_DBI + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg);
|
||||
const u32 einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width;
|
||||
const u32 einput = quse - CEIL(9.928 / tCK_avg);
|
||||
const u32 qrst_duration = FLOOR(8.399 - tCK_avg);
|
||||
const u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0));
|
||||
const u32 qrst = PACK_U32(qrst_duration, qrstLow);
|
||||
const u32 ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
|
||||
const u32 qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
|
||||
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
const u32 tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL_DBI + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
|
||||
const u32 tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL_DBI)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg);
|
||||
const u32 tWTM = CEIL(WL + ((7.570 / tCK_avg) + 8.753));
|
||||
const u32 tWATM = (tWTM + (FLOOR(WL / 0.816) * 2.0)) - 4.0;
|
||||
|
||||
const u32 wdv = WL;
|
||||
const u32 wsv = WL - 2;
|
||||
const u32 wev = 0xA + (WL - 14);
|
||||
|
||||
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 * ramFreqMhz) * 2));
|
||||
const u32 obdlyLow = MAX(WL - FLOOR((126.0 / CEIL(tCK_avg + 8.601))), 0.0);
|
||||
|
||||
const u32 obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow);
|
||||
|
||||
inline u32 pdex2rw;
|
||||
inline u32 cke2pden;
|
||||
const u32 pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));
|
||||
|
||||
const u32 tCKE = CEIL(1.0795 * CEIL(0.0074472 * ramFreqMhz));
|
||||
const u32 tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;
|
||||
|
||||
const double tMMRI = tRCD + (tCK_avg * 3);
|
||||
const double pdex2mrr = tMMRI + 10; /* Do this properly? */
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace ams::ldr {
|
||||
R_DEFINE_ERROR_RESULT(SafetyCheckFailure, 1015);
|
||||
}
|
||||
|
||||
namespace ams::ldr::oc {
|
||||
namespace ams::ldr::hoc {
|
||||
template<typename Pointer>
|
||||
struct PatcherEntry {
|
||||
using patternFn = bool(*)(Pointer* ptr);
|
||||
|
||||
@@ -65,7 +65,7 @@ void saveExec(const char* file_loc, const void* buf, size_t size) {
|
||||
}
|
||||
|
||||
Result Test_PcvDvfsTable() {
|
||||
using namespace ams::ldr::oc::pcv;
|
||||
using namespace ams::ldr::hoc::pcv;
|
||||
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&mariko::CpuCvbTableDefault)) == 18);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&erista::CpuCvbTableDefault)) == 16);
|
||||
@@ -76,19 +76,19 @@ Result Test_PcvDvfsTable() {
|
||||
cvb_entry_t last_mariko_cpu_cvb_entry_default = { 1963500, { 1675751, -38635, 27 }, { 1120000 } };
|
||||
assert(memcmp(GetDvfsTableLastEntry((cvb_entry_t *)(&mariko::CpuCvbTableDefault)), (void *)&last_mariko_cpu_cvb_entry_default, sizeof(last_mariko_cpu_cvb_entry_default)) == 0);
|
||||
assert(GetDvfsTableLastEntry((cvb_entry_t *)(&erista::GpuCvbTableDefault))->freq == 921600);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTableSLT)) == 25);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoCpuDvfsTableSLT)) == 25);
|
||||
|
||||
// Customized table default
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaCpuDvfsTable)) == 19);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTable)) == 21);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTableSLT)) == 22);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.eristaCpuDvfsTable)) == 19);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoCpuDvfsTable)) == 21);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoCpuDvfsTableSLT)) == 22);
|
||||
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaGpuDvfsTable)) == 12);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTable)) == 17);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableSLT)) == 17);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableHiOPT)) == 17);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.eristaGpuDvfsTable)) == 12);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoGpuDvfsTable)) == 17);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoGpuDvfsTableSLT)) == 17);
|
||||
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoGpuDvfsTableHiOPT)) == 17);
|
||||
|
||||
constexpr size_t limit = ams::ldr::oc::pcv::DvfsTableEntryLimit;
|
||||
constexpr size_t limit = ams::ldr::hoc::pcv::DvfsTableEntryLimit;
|
||||
cvb_entry_t customized_table[limit] = {};
|
||||
for (size_t i = 0; i < limit; i++) {
|
||||
assert(GetDvfsTableEntryCount(customized_table) == i);
|
||||
@@ -156,14 +156,14 @@ int main(int argc, char** argv) {
|
||||
size_t exec_path_patched_len = exec_path_len + std::max(strlen(mariko_ext), strlen(erista_ext)) + 1;
|
||||
|
||||
if (exe_opt == EXE_PCV) {
|
||||
ams::ldr::oc::pcv::SafetyCheck();
|
||||
ams::ldr::hoc::pcv::SafetyCheck();
|
||||
|
||||
{
|
||||
void* erista_buf = malloc(file_size);
|
||||
std::memcpy(erista_buf, file_buffer, file_size);
|
||||
|
||||
printf("Patching %s for Erista...\n", pcv_opt);
|
||||
ams::ldr::oc::pcv::erista::Patch(reinterpret_cast<uintptr_t>(erista_buf), file_size);
|
||||
ams::ldr::hoc::pcv::erista::Patch(reinterpret_cast<uintptr_t>(erista_buf), file_size);
|
||||
if (save_patched) {
|
||||
char* exec_path_erista = reinterpret_cast<char *>(malloc(exec_path_patched_len));
|
||||
strncpy(exec_path_erista, exec_path, exec_path_patched_len);
|
||||
@@ -179,7 +179,7 @@ int main(int argc, char** argv) {
|
||||
std::memcpy(mariko_buf, file_buffer, file_size);
|
||||
|
||||
printf("Patching %s for Mariko...\n", pcv_opt);
|
||||
ams::ldr::oc::pcv::mariko::Patch(reinterpret_cast<uintptr_t>(mariko_buf), file_size);
|
||||
ams::ldr::hoc::pcv::mariko::Patch(reinterpret_cast<uintptr_t>(mariko_buf), file_size);
|
||||
if (save_patched) {
|
||||
char* exec_path_mariko = reinterpret_cast<char *>(malloc(exec_path_patched_len));
|
||||
strncpy(exec_path_mariko, exec_path, exec_path_patched_len);
|
||||
@@ -196,7 +196,7 @@ int main(int argc, char** argv) {
|
||||
std::memcpy(mariko_buf, file_buffer, file_size);
|
||||
|
||||
printf("Patching %s (Mariko Only)...\n", ptm_opt);
|
||||
ams::ldr::oc::ptm::Patch(reinterpret_cast<uintptr_t>(mariko_buf), file_size);
|
||||
ams::ldr::hoc::ptm::Patch(reinterpret_cast<uintptr_t>(mariko_buf), file_size);
|
||||
if (save_patched) {
|
||||
char* exec_path_mariko = reinterpret_cast<char *>(malloc(exec_path_patched_len));
|
||||
strncpy(exec_path_mariko, exec_path, exec_path_patched_len);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "pcv.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv {
|
||||
namespace ams::ldr::hoc::pcv {
|
||||
|
||||
Result MemFreqPllmLimit(u32* ptr) {
|
||||
clk_pll_param* entry = reinterpret_cast<clk_pll_param *>(ptr);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "../oc_common.hpp"
|
||||
#include "pcv_common.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv {
|
||||
namespace ams::ldr::hoc::pcv {
|
||||
|
||||
namespace mariko {
|
||||
constexpr cvb_entry_t CpuCvbTableDefault[] = {
|
||||
@@ -122,6 +122,16 @@ namespace ams::ldr::oc::pcv {
|
||||
{0xFFFFFFFF, 35},
|
||||
};
|
||||
|
||||
static const u32 ramBrackets[][22] = {
|
||||
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, },
|
||||
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, },
|
||||
{ 2433, 2466, 2533, 2600, 2666, 2733, 2766, 2800, 2833, 2866, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3300, 3333, 3366, },
|
||||
{ 2500, 2533, 2600, 2633, 2666, 2733, 2800, 2866, 2900, 2966, 3033, 3100, 3166, 3200, 3233, 3266, 3300, 3333, 3366, 3400, 3400, 3400, },
|
||||
};
|
||||
|
||||
static const u32 gpuBudgetDvfsArray[] = { 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800};
|
||||
|
||||
|
||||
/* GPU Max Clock asm Pattern:
|
||||
*
|
||||
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ams::ldr::oc::pcv {
|
||||
namespace ams::ldr::hoc::pcv {
|
||||
|
||||
typedef struct cvb_coefficients {
|
||||
s32 c0 = 0;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "pcv.hpp"
|
||||
#include "../mtc_timing_value.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::erista {
|
||||
namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
Result CpuVoltDvfs(u32 *ptr) {
|
||||
if (MatchesPattern(ptr, cpuVoltDvfsPattern, cpuVoltDvfsOffsets)) {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "../mtc_timing_value.hpp"
|
||||
#include "../mariko/calculate_timings.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv::mariko {
|
||||
namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
u32 GetGpuVminVoltage() {
|
||||
for (auto e : vminTable) {
|
||||
@@ -50,6 +50,30 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
return ramScale;
|
||||
}
|
||||
|
||||
u32 GetSpeedoBracket() {
|
||||
u32 speedoBracket = 3;
|
||||
if ((C.gpuSpeedo < 1754) && (speedoBracket = 2, C.gpuSpeedo < 1690)) {
|
||||
speedoBracket = !!(1625 < C.gpuSpeedo);
|
||||
}
|
||||
|
||||
return speedoBracket;
|
||||
}
|
||||
|
||||
u32 GetGpuBudgetDvfsVoltage() {
|
||||
u32 bracket = GetSpeedoBracket();
|
||||
|
||||
if (ramFreqMhz <= 1600)
|
||||
return 0;
|
||||
|
||||
for (u32 voltageIndex = 0; voltageIndex < 22; voltageIndex++) {
|
||||
if (ramFreqMhz <= ramBrackets[bracket][voltageIndex]) {
|
||||
return gpuBudgetDvfsArray[voltageIndex];
|
||||
}
|
||||
}
|
||||
|
||||
return 800;
|
||||
}
|
||||
|
||||
/* Note: EOS (probably?) has a bug in this function that always results in high vmin, this is fixed here. */
|
||||
u32 GetAutoVoltage() {
|
||||
u32 voltage = GetGpuVminVoltage();
|
||||
@@ -78,38 +102,38 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
}
|
||||
|
||||
/* C.marikoGpuVmin is non zero, user sets manual voltage. */
|
||||
if (C.marikoGpuVmin) {
|
||||
if (C.marikoGpuVmin != 0 && C.marikoGpuVmin != 1) {
|
||||
PATCH_OFFSET(ptr, C.marikoGpuVmin);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* C.marikoGpuVmin is zero, auto voltage is applied. */
|
||||
/* C.marikoGpuVmin is zero OR one, auto voltage is applied. */
|
||||
/* Get vmin depending on speedo and ram clock. */
|
||||
u32 autoVmin = GetAutoVoltage();
|
||||
u32 autoVmin = C.marikoGpuVmin == 0 ? GetAutoVoltage() : GetGpuBudgetDvfsVoltage();
|
||||
PATCH_OFFSET(ptr, autoVmin);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GpuVoltThermals(u32 *ptr) {
|
||||
u32 vmin = std::memcmp(ptr - 3, gpuVoltThermalPattern, sizeof(gpuVoltThermalPattern));
|
||||
if (vmin) {
|
||||
if (std::memcmp(ptr - 3, gpuVoltThermalPattern, sizeof(gpuVoltThermalPattern))) {
|
||||
R_THROW(ldr::ResultInvalidGpuDvfs());
|
||||
}
|
||||
|
||||
u32 vmin = C.marikoGpuVmin;
|
||||
|
||||
/* Automatic voltage. */
|
||||
if (!C.marikoGpuVmin) {
|
||||
vmin = GetAutoVoltage();
|
||||
if (!C.marikoGpuVmin || C.marikoGpuVmin == 1) {
|
||||
vmin = C.marikoGpuVmin == 0 ? GetAutoVoltage() : GetGpuBudgetDvfsVoltage();
|
||||
PATCH_OFFSET(ptr, vmin);
|
||||
PATCH_OFFSET(ptr + 3, vmin);
|
||||
PATCH_OFFSET(ptr + 6, vmin);
|
||||
PATCH_OFFSET(ptr + 9, vmin);
|
||||
} else {
|
||||
/* Manual voltage. */
|
||||
PATCH_OFFSET(ptr, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 3, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 6, C.marikoGpuVmin);
|
||||
PATCH_OFFSET(ptr + 9, C.marikoGpuVmin);
|
||||
vmin = C.marikoGpuVmin;
|
||||
PATCH_OFFSET(ptr, vmin);
|
||||
PATCH_OFFSET(ptr + 3, vmin);
|
||||
PATCH_OFFSET(ptr + 6, vmin);
|
||||
PATCH_OFFSET(ptr + 9, vmin);
|
||||
}
|
||||
|
||||
PATCH_OFFSET(ptr + 12, vmin);
|
||||
@@ -432,9 +456,9 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
|
||||
WRITE_PARAM_ALL_REG(table, emc_trpab, MIN(GET_CYCLE_CEIL(tRPab), static_cast<u32>(0x3F)));
|
||||
WRITE_PARAM_ALL_REG(table, emc_tckesr, GET_CYCLE_CEIL(tSR));
|
||||
WRITE_PARAM_ALL_REG(table, emc_tcke, tCKE);
|
||||
WRITE_PARAM_ALL_REG(table, emc_tcke, GET_CYCLE_CEIL(7.425) + 2);
|
||||
WRITE_PARAM_ALL_REG(table, emc_tpd, GET_CYCLE_CEIL(tXP));
|
||||
WRITE_PARAM_ALL_REG(table, emc_tclkstop, GET_CYCLE_CEIL(tXP) + 8); // TODO analyse
|
||||
WRITE_PARAM_ALL_REG(table, emc_tclkstop, tCLKSTOP);
|
||||
WRITE_PARAM_ALL_REG(table, emc_r2p, tR2P);
|
||||
WRITE_PARAM_ALL_REG(table, emc_r2w, tR2W);
|
||||
WRITE_PARAM_ALL_REG(table, emc_trtm, tRTM);
|
||||
@@ -452,12 +476,11 @@ namespace ams::ldr::oc::pcv::mariko {
|
||||
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
|
||||
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw);
|
||||
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw);
|
||||
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.75));
|
||||
WRITE_PARAM_ALL_REG(table, emc_pchg2pden, GET_CYCLE_CEIL(1.763));
|
||||
WRITE_PARAM_ALL_REG(table, emc_ar2pden, GET_CYCLE_CEIL(1.75));
|
||||
WRITE_PARAM_ALL_REG(table, emc_pdex2cke, GET_CYCLE_CEIL(1.05));
|
||||
WRITE_PARAM_ALL_REG(table, emc_act2pden, GET_CYCLE_CEIL(14.0));
|
||||
WRITE_PARAM_ALL_REG(table, emc_cke2pden, /* cke2pden */ GET_CYCLE_CEIL(8.5));
|
||||
(void) cke2pden;
|
||||
WRITE_PARAM_ALL_REG(table, emc_cke2pden, GET_CYCLE_CEIL(8.499));
|
||||
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(pdex2mrr));
|
||||
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN);
|
||||
WRITE_PARAM_ALL_REG(table, emc_einput, einput);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "ptm.hpp"
|
||||
|
||||
namespace ams::ldr::oc::ptm {
|
||||
namespace ams::ldr::hoc::ptm {
|
||||
|
||||
Result CpuPtmBoost(perf_conf_entry* entry) {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "../oc_common.hpp"
|
||||
|
||||
namespace ams::ldr::oc::ptm {
|
||||
namespace ams::ldr::hoc::ptm {
|
||||
|
||||
typedef struct {
|
||||
u32 conf_id;
|
||||
|
||||
@@ -12,7 +12,7 @@ def image_to_rgba8888_array(image_path, output_path):
|
||||
|
||||
# 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('// This is a 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')
|
||||
@@ -32,7 +32,7 @@ def image_to_rgba8888_array(image_path, output_path):
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='PNG -> RGB8888 script'
|
||||
description='PNG to RGB8888 script'
|
||||
)
|
||||
parser.add_argument('input', help='Input image file (e.g. cat.png)')
|
||||
parser.add_argument(
|
||||
|
||||
@@ -60,7 +60,7 @@ typedef enum {
|
||||
HocClkConfigValue_FixCpuVoltBug,
|
||||
|
||||
KipConfigValue_custRev,
|
||||
KipConfigValue_mtcConf,
|
||||
// KipConfigValue_mtcConf,
|
||||
KipConfigValue_hpMode,
|
||||
|
||||
KipConfigValue_commonEmcMemVolt,
|
||||
@@ -226,8 +226,8 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
|
||||
// KIP config values
|
||||
case KipConfigValue_custRev:
|
||||
return pretty ? "Custom Revision" : "kip_cust_rev";
|
||||
case KipConfigValue_mtcConf:
|
||||
return pretty ? "MTC Config" : "kip_mtc_conf";
|
||||
// case KipConfigValue_mtcConf:
|
||||
// return pretty ? "MTC Config" : "kip_mtc_conf";
|
||||
case KipConfigValue_hpMode:
|
||||
return pretty ? "HP Mode" : "kip_hp_mode";
|
||||
|
||||
@@ -446,7 +446,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
|
||||
return (input & 0x1) == input;
|
||||
|
||||
case KipConfigValue_custRev:
|
||||
case KipConfigValue_mtcConf:
|
||||
// case KipConfigValue_mtcConf:
|
||||
case KipConfigValue_hpMode:
|
||||
case KipConfigValue_commonEmcMemVolt:
|
||||
case KipConfigValue_eristaEmcMaxClock:
|
||||
|
||||
@@ -39,7 +39,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk
|
||||
# version control constants
|
||||
#---------------------------------------------------------------------------------
|
||||
#TARGET_VERSION := $(shell git describe --dirty --always --tags)
|
||||
APP_VERSION := 0.34
|
||||
APP_VERSION := 0.35
|
||||
TARGET_VERSION := $(APP_VERSION)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
@@ -59,7 +59,6 @@ tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool sel
|
||||
if (selected)
|
||||
text += " \uE14B";
|
||||
|
||||
// NEW: Right-side label
|
||||
std::string rightText = "";
|
||||
auto it = labels.find(hz);
|
||||
if (it != labels.end())
|
||||
@@ -156,16 +155,26 @@ void FreqChoiceGui::listUI()
|
||||
|
||||
if (IsMariko())
|
||||
{
|
||||
unsafe_cpu = 1964;
|
||||
unsafe_gpu = 1076;
|
||||
danger_cpu = 2398;
|
||||
unsafe_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2296 : 1963;
|
||||
if(this->configList->values[KipConfigValue_marikoGpuUV] == 0) {
|
||||
unsafe_gpu = 1076;
|
||||
} else if (this->configList->values[KipConfigValue_marikoGpuUV] == 1) {
|
||||
unsafe_gpu = 1153;
|
||||
} else {
|
||||
unsafe_gpu = 1229;
|
||||
}
|
||||
danger_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2500 : 2398;
|
||||
danger_gpu = 1306;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsafe_cpu = 1786;
|
||||
unsafe_gpu = 922;
|
||||
danger_cpu = 2092;
|
||||
unsafe_cpu = this->configList->values[KipConfigValue_eristaCpuUV] ? 1964 : 1786;
|
||||
if(this->configList->values[KipConfigValue_eristaGpuUV] == 0) {
|
||||
unsafe_gpu = 922;
|
||||
} else {
|
||||
unsafe_gpu = 961;
|
||||
}
|
||||
danger_cpu = this->configList->values[KipConfigValue_eristaCpuUV] ? 2194 : 1964;
|
||||
danger_gpu = 999;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -255,9 +255,6 @@ void MiscGui::listUI()
|
||||
addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr);
|
||||
|
||||
#if IS_MINIMAL == 0
|
||||
std::map<uint32_t, std::string> labels_pwr_r = {
|
||||
{8600, "Official Rating"}
|
||||
};
|
||||
std::map<uint32_t, std::string> labels_pwr_l = {
|
||||
{6400, "Official Rating"}
|
||||
};
|
||||
@@ -273,14 +270,13 @@ void MiscGui::listUI()
|
||||
labels_pwr_l
|
||||
);
|
||||
} else {
|
||||
ValueThresholds tdpThresholds(8600, 9500);
|
||||
ValueThresholds tdpThresholds(9600, 11000);
|
||||
addConfigButton(
|
||||
HocClkConfigValue_HandheldTDPLimit,
|
||||
"TDP Threshold",
|
||||
ValueRange(5000, 10000, 100, "mW", 1),
|
||||
ValueRange(8000, 12000, 100, "mW", 1),
|
||||
"Power",
|
||||
&tdpThresholds,
|
||||
labels_pwr_r
|
||||
&tdpThresholds
|
||||
);
|
||||
}
|
||||
|
||||
@@ -461,7 +457,7 @@ protected:
|
||||
NamedValue("2033MHz", 2033000),
|
||||
NamedValue("2066MHz", 2066000),
|
||||
NamedValue("2100MHz", 2100000),
|
||||
NamedValue("2133MHz", 2133000),
|
||||
NamedValue("2133MHz", 2133000, "JEDEC."),
|
||||
NamedValue("2166MHz", 2166000),
|
||||
NamedValue("2200MHz", 2200000),
|
||||
NamedValue("2233MHz", 2233000),
|
||||
@@ -941,7 +937,7 @@ protected:
|
||||
};
|
||||
|
||||
std::vector<NamedValue> mGpuVoltsVmin = {
|
||||
NamedValue("Auto", 0),
|
||||
NamedValue("Auto", 0), NamedValue("Auto (RAM)", 1),
|
||||
NamedValue("480mV", 480), NamedValue("485mV", 485), NamedValue("490mV", 490),
|
||||
NamedValue("495mV", 495), NamedValue("500mV", 500), NamedValue("505mV", 505),
|
||||
NamedValue("510mV", 510), NamedValue("515mV", 515), NamedValue("520mV", 520),
|
||||
|
||||
@@ -208,9 +208,18 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
|
||||
case SysClkSocType_Erista:
|
||||
return 460800000;
|
||||
case SysClkSocType_Mariko:
|
||||
return 614400000;
|
||||
switch(this->config->GetConfigValue(KipConfigValue_marikoGpuUV)) {
|
||||
case 0:
|
||||
return 614400000;
|
||||
case 1:
|
||||
return 691200000;
|
||||
case 2:
|
||||
return 768000000;
|
||||
default:
|
||||
return 614400000;
|
||||
}
|
||||
default:
|
||||
return 4294967294;
|
||||
return 460800000;
|
||||
}
|
||||
}
|
||||
else if (profile <= SysClkProfile_HandheldChargingUSB)
|
||||
@@ -219,11 +228,26 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
|
||||
case SysClkSocType_Erista:
|
||||
return 768000000;
|
||||
case SysClkSocType_Mariko:
|
||||
return 921600000;
|
||||
switch(this->config->GetConfigValue(KipConfigValue_marikoGpuUV)) {
|
||||
case 0:
|
||||
return 844800000;
|
||||
case 1:
|
||||
return 921600000;
|
||||
case 2:
|
||||
return 998400000;
|
||||
default:
|
||||
return 844800000;
|
||||
}
|
||||
default:
|
||||
return 4294967294;
|
||||
return 768000000;
|
||||
}
|
||||
}
|
||||
} else if(module == SysClkModule_CPU) {
|
||||
if(profile < SysClkProfile_HandheldCharging && Board::GetSocType() == SysClkSocType_Erista) {
|
||||
return 1581000000;
|
||||
} else {
|
||||
return 4294967294;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -739,7 +763,7 @@ void ClockManager::SetKipData() {
|
||||
}
|
||||
|
||||
CUST_WRITE_FIELD_BATCH(&table, custRev, this->config->GetConfigValue(KipConfigValue_custRev));
|
||||
CUST_WRITE_FIELD_BATCH(&table, mtcConf, this->config->GetConfigValue(KipConfigValue_mtcConf));
|
||||
// CUST_WRITE_FIELD_BATCH(&table, mtcConf, this->config->GetConfigValue(KipConfigValue_mtcConf));
|
||||
CUST_WRITE_FIELD_BATCH(&table, hpMode, this->config->GetConfigValue(KipConfigValue_hpMode));
|
||||
|
||||
CUST_WRITE_FIELD_BATCH(&table, commonEmcMemVolt, this->config->GetConfigValue(KipConfigValue_commonEmcMemVolt));
|
||||
@@ -859,7 +883,7 @@ void ClockManager::GetKipData() {
|
||||
if(writeBootConfigValues) {
|
||||
writeBootConfigValues = false;
|
||||
|
||||
initialConfigValues[KipConfigValue_mtcConf] = cust_get_mtc_conf(&table);
|
||||
// initialConfigValues[KipConfigValue_mtcConf] = cust_get_mtc_conf(&table);
|
||||
initialConfigValues[KipConfigValue_hpMode] = cust_get_hp_mode(&table);
|
||||
|
||||
initialConfigValues[KipConfigValue_commonEmcMemVolt] = cust_get_common_emc_volt(&table);
|
||||
@@ -904,7 +928,7 @@ void ClockManager::GetKipData() {
|
||||
initialConfigValues[KipConfigValue_gpuSpeedo] = cust_get_gpu_speedo(&table);
|
||||
}
|
||||
|
||||
configValues.values[KipConfigValue_mtcConf] = cust_get_mtc_conf(&table);
|
||||
// configValues.values[KipConfigValue_mtcConf] = cust_get_mtc_conf(&table);
|
||||
configValues.values[KipConfigValue_hpMode] = cust_get_hp_mode(&table);
|
||||
|
||||
configValues.values[KipConfigValue_commonEmcMemVolt] = cust_get_common_emc_volt(&table);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
typedef struct {
|
||||
u8 cust[4];
|
||||
u32 custRev;
|
||||
u32 mtcConf;
|
||||
u32 placeholder;
|
||||
u32 hpMode;
|
||||
u32 commonEmcMemVolt;
|
||||
u32 eristaEmcMaxClock;
|
||||
@@ -183,7 +183,7 @@ static inline bool cust_read_and_cache(const char* path, CustomizeTable* out) {
|
||||
} while (0)
|
||||
|
||||
static inline bool cust_set_cust_rev(const char* p, u32 v) { CUST_WRITE_FIELD(p, custRev, v); }
|
||||
static inline bool cust_set_mtc_conf(const char* p, u32 v) { CUST_WRITE_FIELD(p, mtcConf, v); }
|
||||
// static inline bool cust_set_mtc_conf(const char* p, u32 v) { CUST_WRITE_FIELD(p, mtcConf, v); }
|
||||
static inline bool cust_set_hp_mode(const char* p, u32 v) { CUST_WRITE_FIELD(p, hpMode, v); }
|
||||
|
||||
static inline bool cust_set_common_emc_volt(const char* p, u32 v) { CUST_WRITE_FIELD(p, commonEmcMemVolt, v); }
|
||||
@@ -250,7 +250,7 @@ static inline u32 cust_get_field(const CustomizeTable* t, u32 offset) {
|
||||
#define CUST_GET_FIELD(table, field) ((table) ? (table)->field : 0)
|
||||
|
||||
static inline u32 cust_get_cust_rev(const CustomizeTable* t) { return CUST_GET_FIELD(t, custRev); }
|
||||
static inline u32 cust_get_mtc_conf(const CustomizeTable* t) { return CUST_GET_FIELD(t, mtcConf); }
|
||||
// static inline u32 cust_get_mtc_conf(const CustomizeTable* t) { return CUST_GET_FIELD(t, mtcConf); }
|
||||
static inline u32 cust_get_hp_mode(const CustomizeTable* t) { return CUST_GET_FIELD(t, hpMode); }
|
||||
|
||||
static inline u32 cust_get_common_emc_volt(const CustomizeTable* t) { return CUST_GET_FIELD(t, commonEmcMemVolt); }
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "process_management.h"
|
||||
#include "file_utils.h"
|
||||
#include "errors.h"
|
||||
#define IS_QLAUNCH 0x20f
|
||||
|
||||
void ProcessManagement::Initialize()
|
||||
{
|
||||
@@ -47,7 +48,7 @@ void ProcessManagement::WaitForQLaunch()
|
||||
do
|
||||
{
|
||||
rc = pmdmntGetProcessId(&pid, PROCESS_MANAGEMENT_QLAUNCH_TID);
|
||||
svcSleepThread(500000000ULL);
|
||||
svcSleepThread(50 * 1000000ULL); // 50ms
|
||||
} while (R_FAILED(rc));
|
||||
}
|
||||
|
||||
@@ -58,7 +59,7 @@ std::uint64_t ProcessManagement::GetCurrentApplicationId()
|
||||
std::uint64_t tid = 0;
|
||||
rc = pmdmntGetApplicationProcessId(&pid);
|
||||
|
||||
if (rc == 0x20f)
|
||||
if (rc == IS_QLAUNCH)
|
||||
{
|
||||
return PROCESS_MANAGEMENT_QLAUNCH_TID;
|
||||
}
|
||||
@@ -67,7 +68,7 @@ std::uint64_t ProcessManagement::GetCurrentApplicationId()
|
||||
|
||||
rc = pminfoGetProgramId(&tid, pid);
|
||||
|
||||
if (rc == 0x20f)
|
||||
if (rc == IS_QLAUNCH)
|
||||
{
|
||||
return PROCESS_MANAGEMENT_QLAUNCH_TID;
|
||||
}
|
||||
|
||||
13
dist/README.md
vendored
13
dist/README.md
vendored
@@ -41,10 +41,8 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
|
||||
* Built-in configurator
|
||||
* Compatible with most homebrew
|
||||
|
||||
> *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*
|
||||
> It is reccomended 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
|
||||
@@ -91,15 +89,15 @@ Refer to COMPILATION.md
|
||||
* 1866 → mariko safe max (3733 Modules), JEDEC.
|
||||
* 1600 → official docked, boost mode, erista safe max, JEDEC.
|
||||
* 1331 → official handheld, JEDEC.
|
||||
* 1065
|
||||
* 1065
|
||||
* 800
|
||||
* 665
|
||||
|
||||
### CPU clocks
|
||||
* 2601 → mariko absolute max, very dangerous
|
||||
* 2499
|
||||
* 2397
|
||||
* 2295 → mariko safe max with UV (low speedo)
|
||||
* 2397 → mariko safe max with UV (low speedo)
|
||||
* 2295
|
||||
* 2193
|
||||
* 2091
|
||||
* 1963 → mariko no UV max clock
|
||||
@@ -153,6 +151,7 @@ Refer to COMPILATION.md
|
||||
* **Souldbminer** – hoc-clk and loader development
|
||||
* **Lightos** – loader patches development
|
||||
* **SciresM** - Atmosphere CFW
|
||||
* **CTCaer** - L4T, Hekate, perfect ram timings
|
||||
* **KazushiMe** – Switch OC Suite
|
||||
* **hanai3bi (meha)** – Switch OC Suite, EOS, sys-clk-eos
|
||||
* **NaGaa95** – L4T-OC-kernel
|
||||
|
||||
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
Binary file not shown.
BIN
dist/atmosphere/kips/hoc.kip
vendored
BIN
dist/atmosphere/kips/hoc.kip
vendored
Binary file not shown.
BIN
dist/switch/.overlays/Horizon-OC-Monitor.ovl
vendored
BIN
dist/switch/.overlays/Horizon-OC-Monitor.ovl
vendored
Binary file not shown.
BIN
dist/switch/.overlays/horizon-oc-overlay.ovl
vendored
BIN
dist/switch/.overlays/horizon-oc-overlay.ovl
vendored
Binary file not shown.
Reference in New Issue
Block a user