Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc4b3b8352 | ||
|
|
5123f7b1de | ||
|
|
3251d104c4 | ||
|
|
ea2d604c20 | ||
|
|
ae71cd447d | ||
|
|
4261dd83f0 | ||
|
|
4dc01c024a | ||
|
|
9e26329173 | ||
|
|
36441e6dea | ||
|
|
cdf28607c9 | ||
|
|
b383fa7ec2 | ||
|
|
d7178ddd2c | ||
|
|
9d149f0939 | ||
|
|
170dd79347 | ||
|
|
d97d359ec2 | ||
|
|
9ff9e315a0 | ||
|
|
cde560c4bd | ||
|
|
a15860ba8d | ||
|
|
76e6f1bd27 | ||
|
|
2c1ad1b755 | ||
|
|
2f2e5e9fb8 | ||
|
|
65b77a2d0b | ||
|
|
5d4812bde5 | ||
|
|
addd2de4d9 | ||
|
|
0df8ce745f | ||
|
|
62d055f163 | ||
|
|
fa1510a40d | ||
|
|
e6942f95e7 | ||
|
|
94b63003ab | ||
|
|
8aa20dc0cf | ||
|
|
db92c60cd2 | ||
|
|
c8c7b233f5 | ||
|
|
5a9afcbb74 | ||
|
|
8127a0c3b7 | ||
|
|
7c5e746594 | ||
|
|
7d30c4d384 | ||
|
|
883b4fc3f4 |
17
README.md
17
README.md
@@ -78,21 +78,21 @@ Refer to COMPILATION.md
|
||||
---
|
||||
## Clock table
|
||||
|
||||
### MEM clocks
|
||||
### MEM clocks (mhz)
|
||||
* 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.
|
||||
* 2133 → Mariko JEDEC standard max (4266 Modules)
|
||||
* 1996 → JEDEC standard
|
||||
* 1866 → Mariko JEDEC standard max (3733 Modules)
|
||||
* 1600 → official docked, boost mode, erista safe max, JEDEC.
|
||||
* 1331 → official handheld, JEDEC.
|
||||
* 1065
|
||||
* 800
|
||||
* 665
|
||||
|
||||
### CPU clocks
|
||||
### CPU clocks (mhz)
|
||||
* 2703 → mariko absolute max, dangerous
|
||||
* 2601 → unsafe
|
||||
* 2499
|
||||
@@ -115,16 +115,16 @@ Refer to COMPILATION.md
|
||||
* 714
|
||||
* 612 → sleep mode
|
||||
|
||||
### GPU clocks
|
||||
### GPU clocks (mhz)
|
||||
* 1536 → absolute max clock on mariko. very dangerous
|
||||
* 1459
|
||||
* 1382
|
||||
* 1305
|
||||
* 1267 → NVIDIA T214 rating
|
||||
* 1267 → NVIDIA T214(mariko) 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
|
||||
* 998 → NVIDIA T210 (erista) rating
|
||||
* 960 (erista only) → erista slt/hiopt safe max clock
|
||||
* 921 → erista no UV max clock
|
||||
* 844
|
||||
@@ -154,6 +154,7 @@ Refer to COMPILATION.md
|
||||
|
||||
* **Souldbminer** - hoc-clk and loader development
|
||||
* **Lightos** - Loader patches development, hoc-clk development, guides
|
||||
* **TDRR** - HOC Logo Design
|
||||
* **SciresM** - Atmosphere CFW
|
||||
* **CTCaer** - L4T, Hekate, proper RAM timings
|
||||
* **KazushiMe** - Switch OC Suite
|
||||
|
||||
88
Source/Atmosphere/stratosphere/loader/loader.json
Normal file
88
Source/Atmosphere/stratosphere/loader/loader.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "Loader",
|
||||
"title_id": "0x0100000000000001",
|
||||
"main_thread_stack_size": "0x4000",
|
||||
"main_thread_priority": 49,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"use_secure_memory": true,
|
||||
"immortal": true,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 128
|
||||
},
|
||||
{
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcSetHeapSize" : "0x01",
|
||||
"svcSetMemoryPermission" : "0x02",
|
||||
"svcSetMemoryAttribute" : "0x03",
|
||||
"svcMapMemory" : "0x04",
|
||||
"svcUnmapMemory" : "0x05",
|
||||
"svcQueryMemory" : "0x06",
|
||||
"svcExitProcess" : "0x07",
|
||||
"svcCreateThread" : "0x08",
|
||||
"svcStartThread" : "0x09",
|
||||
"svcExitThread" : "0x0A",
|
||||
"svcSleepThread" : "0x0B",
|
||||
"svcGetThreadPriority" : "0x0C",
|
||||
"svcSetThreadPriority" : "0x0D",
|
||||
"svcGetThreadCoreMask" : "0x0E",
|
||||
"svcSetThreadCoreMask" : "0x0F",
|
||||
"svcGetCurrentProcessorNumber" : "0x10",
|
||||
"svcSignalEvent" : "0x11",
|
||||
"svcClearEvent" : "0x12",
|
||||
"svcMapSharedMemory" : "0x13",
|
||||
"svcUnmapSharedMemory" : "0x14",
|
||||
"svcCreateTransferMemory" : "0x15",
|
||||
"svcCloseHandle" : "0x16",
|
||||
"svcResetSignal" : "0x17",
|
||||
"svcWaitSynchronization" : "0x18",
|
||||
"svcCancelSynchronization" : "0x19",
|
||||
"svcArbitrateLock" : "0x1A",
|
||||
"svcArbitrateUnlock" : "0x1B",
|
||||
"svcWaitProcessWideKeyAtomic" : "0x1C",
|
||||
"svcSignalProcessWideKey" : "0x1D",
|
||||
"svcGetSystemTick" : "0x1E",
|
||||
"svcConnectToNamedPort" : "0x1F",
|
||||
"svcSendSyncRequestLight" : "0x20",
|
||||
"svcSendSyncRequest" : "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer" : "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer" : "0x23",
|
||||
"svcGetProcessId" : "0x24",
|
||||
"svcGetThreadId" : "0x25",
|
||||
"svcBreak" : "0x26",
|
||||
"svcOutputDebugString" : "0x27",
|
||||
"svcReturnFromException" : "0x28",
|
||||
"svcGetInfo" : "0x29",
|
||||
"svcWaitForAddress" : "0x34",
|
||||
"svcSignalToAddress" : "0x35",
|
||||
"svcSynchronizePreemptionState" : "0x36",
|
||||
"svcCreateSession" : "0x40",
|
||||
"svcAcceptSession" : "0x41",
|
||||
"svcReplyAndReceiveLight" : "0x42",
|
||||
"svcReplyAndReceive" : "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer" : "0x44",
|
||||
"svcCreateEvent" : "0x45",
|
||||
"svcReadWriteRegister" : "0x4E",
|
||||
"svcQueryIoMapping" : "0x55",
|
||||
"svcSetProcessMemoryPermission" : "0x73",
|
||||
"svcMapProcessMemory" : "0x74",
|
||||
"svcUnmapProcessMemory" : "0x75",
|
||||
"svcMapProcessCodeMemory" : "0x77",
|
||||
"svcUnmapProcessCodeMemory" : "0x78",
|
||||
"svcCreateProcess" : "0x79",
|
||||
"svcCallSecureMonitor" : "0x7F"
|
||||
}
|
||||
}, {
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x7000F000",
|
||||
"is_ro": false,
|
||||
"size": "0x00001000",
|
||||
"is_io": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -40,13 +40,15 @@ volatile CustomizeTable C = {
|
||||
.eristaEmcMaxClock1 = 1600000,
|
||||
.eristaEmcMaxClock2 = 1600000,
|
||||
|
||||
/* Available: 66MHz step rate, 100MHz step rate and jedec. */
|
||||
/* Available: 66MHz step rate, 100MHz step rate, 133MHz step rate and jedec. */
|
||||
/* Jedec freqs are 1333MHz, 1600MHz, 1866MHz, 2133MHz, 2400MHz, 2666MHz, 2933MHz, 3200MHz. */
|
||||
.stepMode = StepMode_66MHz,
|
||||
|
||||
.marikoEmcMaxClock = 2133000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */
|
||||
.marikoEmcVddqVolt = 600000,
|
||||
|
||||
.emcDvbShift = 0,
|
||||
.marikoSocVmax = 0, /* 0 = stock limits (1450 - 1597 is 1050mV, 1598-1708 is 1025mV, 1709+ is 1000mV). */
|
||||
|
||||
// Primary
|
||||
.t1_tRCD = 0,
|
||||
@@ -65,21 +67,21 @@ volatile CustomizeTable C = {
|
||||
|
||||
/* Frequency where non low timings gets used. */
|
||||
.timingEmcTbreak = DISABLED,
|
||||
.low_t6_tRTW = DISABLED,
|
||||
.low_t7_tWTR = DISABLED,
|
||||
.low_t6_tRTW = 0,
|
||||
.low_t7_tWTR = 0,
|
||||
|
||||
.readLatency = {
|
||||
DISABLED,
|
||||
DISABLED,
|
||||
DISABLED,
|
||||
DISABLED,
|
||||
/* 1333 */ 0,
|
||||
/* 1600 */ 0,
|
||||
/* 1866 */ 0,
|
||||
/* 2133 */ 0,
|
||||
},
|
||||
|
||||
.writeLatency = {
|
||||
DISABLED,
|
||||
DISABLED,
|
||||
DISABLED,
|
||||
DISABLED,
|
||||
/* 1333 */ 0,
|
||||
/* 1600 */ 0,
|
||||
/* 1866 */ 0,
|
||||
/* 2133 */ 0,
|
||||
},
|
||||
|
||||
/* You can mix and match different latencies if needed */
|
||||
|
||||
@@ -40,6 +40,7 @@ enum StepMode: u32 {
|
||||
StepMode_66MHz = 0,
|
||||
StepMode_100MHz = 1,
|
||||
StepMode_Jedec = 2,
|
||||
StepMode_133MHz = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -93,6 +94,7 @@ typedef struct CustomizeTable {
|
||||
u32 marikoEmcMaxClock;
|
||||
u32 marikoEmcVddqVolt;
|
||||
u32 emcDvbShift;
|
||||
u32 marikoSocVmax;
|
||||
// advanced config
|
||||
u32 t1_tRCD;
|
||||
u32 t2_tRP;
|
||||
|
||||
@@ -52,6 +52,8 @@ namespace ams::ldr {
|
||||
R_DEFINE_ERROR_RESULT(UnsuccessfulPatcher, 1014);
|
||||
R_DEFINE_ERROR_RESULT(SafetyCheckFailure, 1015);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMtcTablePattern, 1016);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSocVoltPattern, 1017);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSocVoltLimit, 1018);
|
||||
}
|
||||
|
||||
namespace ams::ldr::hoc {
|
||||
|
||||
@@ -154,6 +154,7 @@ namespace ams::ldr::hoc::pcv {
|
||||
{ GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000, false, panic::Emc },
|
||||
{ C.marikoEmcMaxClock, 1600'000, 3500'000, false, panic::Emc },
|
||||
{ C.marikoEmcVddqVolt, 250'000, 700'000, false, panic::Emc },
|
||||
{ C.marikoSocVmax, 1000, 1200, false, panic::Emc },
|
||||
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000, false, panic::Gpu },
|
||||
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000, false, panic::Gpu },
|
||||
{ C.marikoGpuVmax, 800, 960, false, panic::Gpu },
|
||||
|
||||
@@ -26,6 +26,16 @@ namespace ams::ldr::hoc::pcv {
|
||||
|
||||
constexpr u32 NopIns = 0x1f2003d5;
|
||||
|
||||
template <typename Compare>
|
||||
u32 *ScanAssembly(u32 *ptr, u32 scanLimit, u32 pattern, Compare comp) {
|
||||
for (u32 i = 0; i < scanLimit; ++i) {
|
||||
if (comp(pattern, ptr[i])) {
|
||||
return ptr + i;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) {
|
||||
return ((ins1 ^ ins2) >> 5) == 0;
|
||||
};
|
||||
@@ -61,4 +71,75 @@ namespace ams::ldr::hoc::pcv {
|
||||
return ((ins1 & ImmMask) ^ (ins2 & ImmMask)) == 0;
|
||||
};
|
||||
|
||||
/* Csel (Conditional Select) */
|
||||
/*
|
||||
SF | Op | S | | RM | Cond | 0 | 0 | Rn | Rd
|
||||
31 | 30 | 29 | 28 27 26 25 24 23 | 20 19 18 17 16 | 15 14 13 12 | 11 | 10 | 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
inline auto AsmCompareCselNoReg = [](u32 ins1, u32 ins2) {
|
||||
constexpr u32 ClearReg = ~(((1 << 10) - 1) | (((1 << 5) - 1) << 16));
|
||||
return ((ins1 & ClearReg) ^ (ins2 & ClearReg)) == 0;
|
||||
};
|
||||
|
||||
/* Mul */
|
||||
/*
|
||||
SF | Op54 | Op31 | RM | o0 | RA | RN | RD
|
||||
31 | 30 29 28 27 26 25 24 | 23 22 21 | 20 19 18 17 16 | 15 | 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
inline auto AsmCompareMullNoReg = [](u32 ins1, u32 ins2) {
|
||||
constexpr u32 ClearReg = ~(((1 << 10) - 1) | (((1 << 5) - 1) << 16));
|
||||
return ((ins1 & ClearReg) ^ (ins2 & ClearReg)) == 0;
|
||||
};
|
||||
|
||||
/* Mul */
|
||||
/* MUL W11, W24, W26 */
|
||||
/* multiplies by 1000, mV -> uV */
|
||||
/*
|
||||
SF | Op54 | Op31 | RM | o0 | RA | RN | RD
|
||||
31 | 30 29 28 27 26 25 24 | 23 22 21 | 20 19 18 17 16 | 15 | 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
inline auto AsmGetMullRn = [](u32 ins) {
|
||||
constexpr u32 Mask = ((1 << 5) - 1) << 5;
|
||||
return (ins & Mask) >> 5;
|
||||
};
|
||||
|
||||
inline auto AsmGetMullRm = [](u32 ins) {
|
||||
constexpr u32 Mask = ((1 << 5) - 1) << 16;
|
||||
return (ins & Mask) >> 16;
|
||||
};
|
||||
|
||||
/* Subs (Shifted register) */
|
||||
/*
|
||||
SF | Op | S | | Shift | 0 | RM | Imm6 | Rn | Rd
|
||||
31 | 30 | 29 | 28 27 26 25 24 | 23 22 | 21 | 20 19 18 17 16 | 15 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
inline auto AsmSubsSetRn = [](u32 ins, u8 rn) {
|
||||
constexpr u32 RnMaskClear = ~(((1u << 5) - 1u) << 5);
|
||||
constexpr u32 RnMaskSet = (1u << 5) - 1u;
|
||||
|
||||
return (ins & RnMaskClear) | ((static_cast<u32>(rn) & RnMaskSet) << 5);
|
||||
};
|
||||
|
||||
/* Subs (Immediate) */
|
||||
|
||||
/*
|
||||
SF | Op | S | | Sh | Imm12 | Rn | Rd
|
||||
31 | 30 | 29 | 28 27 26 25 24 23 | 22 | 21 20 19 18 17 16 15 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
inline auto AsmSubsSetImm12 = [](u32 ins, u16 imm12) {
|
||||
constexpr u32 ClearMask = ~(((1u << 12) - 1) << 10);
|
||||
constexpr u32 SetImm12Mask = ( 1u << 12) - 1;
|
||||
|
||||
return (ins & ClearMask) | ((imm12 & SetImm12Mask) << 10);
|
||||
};
|
||||
|
||||
inline auto AsmSubsCompareNoReg = [](u32 ins1, u32 ins2) {
|
||||
return ((ins1 ^ ins2) >> 10) == 0;
|
||||
};
|
||||
|
||||
inline auto AsmCompareBrConNoImm19 = [](u32 ins1, u32 ins2) {
|
||||
constexpr u32 ClearImm19 = ~(((1 << 19) - 1) << 5);
|
||||
return (ins1 & ClearImm19) == (ins2 & ClearImm19);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -279,12 +279,6 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
|
||||
}
|
||||
|
||||
/* Verify the limit. */
|
||||
/* TODO: Make this a little bit cleaner at some point. */
|
||||
if (AsmGetImm16(ins1) != (GpuClkOsLimit & 0xFFFF) || AsmGetImm16(ins2) != (GpuClkOsLimit >> 16)) {
|
||||
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
|
||||
}
|
||||
|
||||
u32 max_clock;
|
||||
switch (C.marikoGpuUV) {
|
||||
case 0:
|
||||
@@ -615,6 +609,25 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit));
|
||||
}
|
||||
|
||||
void MtcGenerate133StepTable() {
|
||||
const u32 StepFreqs133[] = { 1733000, 1866000, 2000000, 2133000, 2266000, 2400000, 2533000, 2666000, 2800000, 2933000, 3066000, 3200000, 3333000, 3466000, }; // Avoid rounding issues
|
||||
constexpr u32 StepFreqs133Size = std::size(StepFreqs133);
|
||||
|
||||
for (u32 i = 0; i < StepFreqs133Size; ++i) {
|
||||
if (StepFreqs133[i] <= C.marikoEmcMaxClock) {
|
||||
newEmcList.push_back(StepFreqs133[i]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newEmcList.back() != C.marikoEmcMaxClock) {
|
||||
newEmcList.push_back(static_cast<u32>(C.marikoEmcMaxClock));
|
||||
}
|
||||
|
||||
newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit));
|
||||
}
|
||||
|
||||
void MtcGenerateFreqTables() {
|
||||
if (C.marikoEmcMaxClock <= EmcClkOSLimit) {
|
||||
return;
|
||||
@@ -635,6 +648,9 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
case StepMode_Jedec:
|
||||
MtcGenerateJedecTable();
|
||||
return;
|
||||
case StepMode_133MHz:
|
||||
MtcGenerate133StepTable();
|
||||
return;
|
||||
default:
|
||||
stepRate = 66667;
|
||||
break;
|
||||
@@ -782,21 +798,43 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
u32 max0 = 1050;
|
||||
u32 max1 = 1025;
|
||||
u32 max2 = 1000;
|
||||
s32 voltAdd = 25 * C.emcDvbShift;
|
||||
#define DVB_VOLT(zero, one, two) std::min(zero + voltAdd, 1050), std::min(one + voltAdd, 1025), std::min(two + voltAdd, 1000),
|
||||
DvbEntry emcDvbTableNew[] = {
|
||||
{ 204000, { 637, 637, 637, } },
|
||||
{ 1331200, { 650, 637, 637, } },
|
||||
{ 1600000, { 675, 650, 637, } },
|
||||
{ 1866000, { DVB_VOLT(700, 675, 650) } },
|
||||
{ 2133000, { DVB_VOLT(725, 700, 675) } },
|
||||
{ 2400000, { DVB_VOLT(750, 725, 700) } },
|
||||
{ 2666000, { DVB_VOLT(775, 750, 725) } },
|
||||
{ 2933000, { DVB_VOLT(800, 775, 750) } },
|
||||
{ 3200000, { DVB_VOLT(800, 800, 775) } },
|
||||
{ 0xFFFFFFFF, { } },
|
||||
|
||||
if (C.marikoSocVmax && C.marikoSocVmax > 1000) {
|
||||
max0 = C.marikoSocVmax;
|
||||
max1 = C.marikoSocVmax;
|
||||
max2 = C.marikoSocVmax;
|
||||
}
|
||||
|
||||
auto DvbVolt = [&](u32 zero, u32 one, u32 two) {
|
||||
return std::array<u32, 3>{
|
||||
std::min(zero + voltAdd, max0),
|
||||
std::min(one + voltAdd, max1),
|
||||
std::min(two + voltAdd, max2)
|
||||
};
|
||||
};
|
||||
|
||||
#define DVB(v) \
|
||||
static_cast<u32>((v)[0]), \
|
||||
static_cast<u32>((v)[1]), \
|
||||
static_cast<u32>((v)[2])
|
||||
DvbEntry emcDvbTableNew[] = {
|
||||
{ 204000, { 637, 637, 637, } },
|
||||
{ 1331200, { 650, 637, 637, } },
|
||||
{ 1600000, { 675, 650, 637, } },
|
||||
{ 1866000, { DVB(DvbVolt(700, 675, 650)) } },
|
||||
{ 2133000, { DVB(DvbVolt(725, 700, 675)) } },
|
||||
{ 2400000, { DVB(DvbVolt(750, 725, 700)) } },
|
||||
{ 2666000, { DVB(DvbVolt(775, 750, 725)) } },
|
||||
{ 2933000, { DVB(DvbVolt(800, 775, 750)) } },
|
||||
{ 3200000, { DVB(DvbVolt(800, 800, 775)) } },
|
||||
{ 0xFFFFFFFF, { } },
|
||||
};
|
||||
#undef DVB
|
||||
|
||||
u32 j = MtcTableCountDefault;
|
||||
for (u32 i = MtcTableCountDefault; i < newEmcList.size(); ++i) {
|
||||
if (newEmcList[i] >= emcDvbTableNew[j].freq && newEmcList[i] < emcDvbTableNew[j + 1].freq) {
|
||||
@@ -849,7 +887,7 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
regulator *entry = reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_2_3.default_uv));
|
||||
|
||||
constexpr u32 uv_step = 5'000;
|
||||
constexpr u32 uv_min = 250'000;
|
||||
constexpr u32 uv_min = 250'000;
|
||||
|
||||
auto validator = [entry]() {
|
||||
R_UNLESS(entry->id == 2, ldr::ResultInvalidRegulatorEntry());
|
||||
@@ -914,6 +952,124 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetSocSpeedo(u32 &socSpeedo) {
|
||||
constexpr u64 FusePhysicalAddress = 0x7000F000;
|
||||
u64 virtualAddress = 0;
|
||||
constexpr u64 Size = 0x1000;
|
||||
|
||||
u64 outSize;
|
||||
/* TODO: use svc::QueryMemoryMapping instead. */
|
||||
R_TRY(svcQueryMemoryMapping(&virtualAddress, &outSize, FusePhysicalAddress, Size));
|
||||
|
||||
constexpr u32 FuseOffset = 2048;
|
||||
constexpr u32 SocSpeedoOffset = 308;
|
||||
socSpeedo = *reinterpret_cast<u32 *>(virtualAddress + FuseOffset + SocSpeedoOffset);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
u32 GetSocProcessId(u32 socSpeedo) {
|
||||
if (socSpeedo <= 1597) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (socSpeedo <= 1708) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* >= 1709. */
|
||||
return 2;
|
||||
}
|
||||
|
||||
Result SocVoltAsm(u32 *compareSpeedos) {
|
||||
constexpr u32 VoltageScanLimit = 10;
|
||||
/* Might actually be speedo id. */
|
||||
u32 *writeProcessId = ScanAssembly(compareSpeedos, VoltageScanLimit, SocVoltWriteProcessIdAsm, asm_compare_no_rd);
|
||||
R_UNLESS(writeProcessId != nullptr, ldr::ResultInvalidSocVoltPattern());
|
||||
u8 writeProcessIdRd = asm_get_rd(*writeProcessId);
|
||||
|
||||
/* This writes 1050mV. */
|
||||
u32 *writeVoltage = ScanAssembly(writeProcessId, VoltageScanLimit, SocVoltWriteVoltageAsm, asm_compare_no_rd);
|
||||
R_UNLESS(writeVoltage != nullptr, ldr::ResultInvalidSocVoltPattern());
|
||||
u8 writeVoltageRd = asm_get_rd(*writeVoltage);
|
||||
|
||||
/* A csel instruction is used to select the soc voltage limit register. */
|
||||
/* We care about its destination register since that is used for verification. */
|
||||
constexpr u32 VoltageSelectScanLimit = 24;
|
||||
u32 *selectVoltage = ScanAssembly(writeVoltage, VoltageSelectScanLimit, SocVoltSelectRegisterAsm, AsmCompareCselNoReg);
|
||||
R_UNLESS(selectVoltage != nullptr, ldr::ResultInvalidSocVoltPattern());
|
||||
/* Todo: check rm and rn? */
|
||||
u8 selectVoltageRd = asm_get_rd(*selectVoltage);
|
||||
|
||||
/* rdCsel is then multiplied by 1000 to convert to uV. */
|
||||
/* This is pretty far down the function. */
|
||||
constexpr u32 MultiplierScanLimit = 200;
|
||||
u32 *multiplier = ScanAssembly(selectVoltage, MultiplierScanLimit, SocVoltMultiplyVoltsAsm, AsmCompareMullNoReg);
|
||||
R_UNLESS(multiplier != nullptr, ldr::ResultInvalidSocVoltPattern());
|
||||
u8 multiplierRn = AsmGetMullRn(*multiplier);
|
||||
u8 multiplierRm = AsmGetMullRm(*multiplier);
|
||||
/* One of the two registers has to be rdCsel. */
|
||||
R_UNLESS((multiplierRn == selectVoltageRd) || (multiplierRm == selectVoltageRd), ldr::ResultInvalidSocVoltPattern());
|
||||
u8 multiplierRd = asm_get_rd(*multiplier);
|
||||
|
||||
/* Subs instruction is then used to verify against absolute limit. */
|
||||
u32 limitValidationPattern = AsmSubsSetRn(SocVoltValidateLimitAsm, multiplierRd);
|
||||
u32 *limitValidation = ScanAssembly(multiplier, VoltageScanLimit, limitValidationPattern, AsmSubsCompareNoReg);
|
||||
R_UNLESS(limitValidation != nullptr, ldr::ResultInvalidSocVoltPattern());
|
||||
|
||||
/* There is a b.gt instruction right after (checks for socVoltageCap < socVoltageMax). */
|
||||
u32 *branchToAbort = limitValidation + 1;
|
||||
R_UNLESS(AsmCompareBrConNoImm19(*branchToAbort, SocVoltBranchToAbortAsm), ldr::ResultInvalidSocVoltPattern());
|
||||
|
||||
if (!C.marikoSocVmax || C.marikoSocVmax <= 1000) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
/* Adjust 1598 speedo minimum to ensure it always goes down process id 0 branch. */
|
||||
/* 2200 should be high enough :D */
|
||||
u32 compareSpeedosPatch = AsmSubsSetImm12(*compareSpeedos, 2200);
|
||||
PATCH_OFFSET(compareSpeedos, compareSpeedosPatch);
|
||||
|
||||
u32 socSpeedo = 0;
|
||||
R_TRY(GetSocSpeedo(socSpeedo));
|
||||
|
||||
/* Adjust processId from 0 to [process id of switch booting this]. */
|
||||
/* We're overwriting the orr instruction entirly. */
|
||||
u32 processId = GetSocProcessId(socSpeedo);
|
||||
u32 writeProcessIdPatch = asm_set_rd(asm_set_imm16(SocVoltWriteVoltageAsm, processId), writeProcessIdRd);
|
||||
PATCH_OFFSET(writeProcessId, writeProcessIdPatch);
|
||||
|
||||
/* Adjust voltage limit. */
|
||||
u32 voltageLimitPatch = asm_set_rd(asm_set_imm16(SocVoltWriteVoltageAsm, C.marikoSocVmax), writeVoltageRd);
|
||||
PATCH_OFFSET(writeVoltage, voltageLimitPatch);
|
||||
|
||||
/* Branches to an abort if limits are invalid -- we patch the branch instruction with NOP. */
|
||||
PATCH_OFFSET(branchToAbort, NopIns);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result SocVoltLimit(u32 *ptr) {
|
||||
R_UNLESS(!std::memcmp(ptr - SocVoltLimitMaxDefaultIndex, socVoltLimitArray, sizeof(socVoltLimitArray)), ldr::ResultInvalidSocVoltLimit());
|
||||
if (!C.marikoSocVmax || C.marikoSocVmax <= SocVoltLimitOfficial) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
constexpr u32 Step = 25;
|
||||
u32 maxVolt = C.marikoSocVmax;
|
||||
if (maxVolt % Step) {
|
||||
maxVolt = maxVolt / Step * Step; /* Round. */
|
||||
}
|
||||
|
||||
u32 volt = SocVoltLimitOfficial;
|
||||
for (u32 i = 1; i < DvfsTableEntryCount - SocVoltLimitMaxDefaultIndex && volt < maxVolt; ++i) {
|
||||
volt += Step;
|
||||
PATCH_OFFSET(ptr + i, volt);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Patch(uintptr_t mapped_nso, size_t nso_size) {
|
||||
nsoStart = reinterpret_cast<u32 *>(mapped_nso);
|
||||
MtcGenerateFreqTables();
|
||||
@@ -932,13 +1088,15 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
{ "GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn },
|
||||
{ "GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax },
|
||||
{ "GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit },
|
||||
{ "MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit },
|
||||
{ "MEM Freq Mtc", &MemFreqMtcTable, 1, nullptr, EmcClkOSLimit },
|
||||
{ "MEM Freq Dvb", &MemFreqDvbTable, 1, nullptr, EmcClkOSLimit },
|
||||
{ "MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
|
||||
{ "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
|
||||
{ "MEM Vddq", &EmcVddqVolt, 2, nullptr, EmcVddqDefault },
|
||||
{ "MEM Vdd2", &MemVoltHandler, 2, nullptr, MemVdd2Default },
|
||||
{ "Mem Table Asm", &MemMtcTableAsm, 0, &MemMtcGetGetTablePatternFn },
|
||||
{ "MEM Table Asm", &MemMtcTableAsm, 1, &MemMtcGetGetTablePatternFn },
|
||||
{ "SOC Volt Asm", &SocVoltAsm, 1, &SocVoltPatternFn },
|
||||
{ "SOC Volt Limit", &SocVoltLimit, 1, nullptr, SocVoltLimitOfficial },
|
||||
};
|
||||
|
||||
for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(MarikoMtcTable); ptr += sizeof(u32)) {
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
struct DvbEntry {
|
||||
u64 freq;
|
||||
s32 volt[4] = {};
|
||||
u32 volt[4] = {};
|
||||
};
|
||||
|
||||
constexpr DvbEntry EmcDvbTableDefault[] = {
|
||||
@@ -124,16 +124,37 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
{ 1600000, { 675, 650, 637, } },
|
||||
};
|
||||
|
||||
/* Movz */
|
||||
/*
|
||||
SF | OPC | HW | Imm16 | RD
|
||||
31 | 30 29 28 27 26 25 24 23 | 22 21 | 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
constexpr u32 SocVoltCompareSpeedoAsm = 0x7118FAFF; /* subs imm, compares to >=1598 max speedo and then goes down process id 1 route. */
|
||||
constexpr u32 SocVoltWriteProcessIdAsm = 0x2A1F03F4; /* orr, writes id 0. */
|
||||
constexpr u32 SocVoltWriteVoltageAsm = 0x52808358; /* Movz imm, writes 1050mV. */
|
||||
constexpr u32 SocVoltSelectRegisterAsm = 0x1A9A3118; /* Csel, selects the voltage -- we need the register of this. */
|
||||
constexpr u32 SocVoltMultiplyVoltsAsm = 0x1B1A7F0B; /* Mul, converts from mV -> uV */
|
||||
constexpr u32 SocVoltValidateLimitAsm = 0x6B0A017F; /* Subs, checks limits */
|
||||
constexpr u32 SocVoltBranchToAbortAsm = 0x540020AC; /* B.ge Branches to abort if limits are invalid. */
|
||||
|
||||
ALWAYS_INLINE bool SocVoltPatternFn(u32 *ptr) {
|
||||
return asm_compare_no_rd(*ptr, SocVoltCompareSpeedoAsm);
|
||||
}
|
||||
|
||||
constexpr u32 SocVoltLimitOfficial = 1050;
|
||||
constexpr u32 SocVoltLimitMaxDefaultIndex = 17;
|
||||
static const u32 socVoltLimitArray[DvfsTableEntryCount] = { 637, 650, 675, 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, };
|
||||
|
||||
constexpr u32 EmcListDefault[] = { 204000, 1331200, 1600000, };
|
||||
constexpr u32 EmcListSizeDefault = std::size(EmcListDefault);
|
||||
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
|
||||
constexpr u32 EmcRateStep = 33'000;
|
||||
constexpr u32 EmcRateStepScale = 33'200;
|
||||
|
||||
constexpr u32 EmcClkOSAlt = 1331'200;
|
||||
constexpr u32 EmcClkOSAlt = 1331'200;
|
||||
constexpr u32 EmcClkPllmLimit = 2133'000'000;
|
||||
constexpr u32 EmcVddqDefault = 600'000;
|
||||
constexpr u32 MemVdd2Default = 1100'000;
|
||||
constexpr u32 EmcVddqDefault = 600'000;
|
||||
constexpr u32 MemVdd2Default = 1100'000;
|
||||
|
||||
constexpr u32 MTC_TABLE_REV = 3;
|
||||
constexpr u32 MtcTableCountDefault = 3;
|
||||
@@ -260,8 +281,8 @@ namespace ams::ldr::hoc::pcv::mariko {
|
||||
|
||||
/* Adrp */
|
||||
/*
|
||||
OP | ImmLow | ImmHigh | RD
|
||||
31 | 30 29 28 27 26 25 24 | 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 | 4 3 2 1 0
|
||||
OP | ImmLow | | ImmHigh | RD
|
||||
31 | 30 29 | 28 27 26 25 24 | 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 | 4 3 2 1 0
|
||||
*/
|
||||
|
||||
/* ADD (immediate) */
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
});
|
||||
|
||||
// tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release);
|
||||
tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor Pro", APP_VERSION, true);
|
||||
tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true);
|
||||
rootFrame->setContent(Status);
|
||||
|
||||
return rootFrame;
|
||||
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
});
|
||||
|
||||
// tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release);
|
||||
tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor Pro", APP_VERSION, true);
|
||||
tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true);
|
||||
rootFrame->setContent(Status);
|
||||
|
||||
return rootFrame;
|
||||
|
||||
@@ -92,6 +92,7 @@ typedef enum
|
||||
HocClkThermalSensor_GPU,
|
||||
HocClkThermalSensor_MEM, // Returns the PLLX sensor value on Mariko
|
||||
HocClkThermalSensor_PLLX,
|
||||
HocClkThermalSensor_BQ24193,
|
||||
HocClkThermalSensor_EnumMax
|
||||
} HocClkThermalSensor;
|
||||
|
||||
@@ -125,9 +126,9 @@ typedef enum {
|
||||
} HocClkSpeedo;
|
||||
|
||||
typedef enum {
|
||||
GPUUVLevel_NoUV = 0,
|
||||
GPUUVLevel_SLT,
|
||||
GPUUVLevel_HiOPT,
|
||||
GPUUVLevel_HiOPT = 0,
|
||||
GPUUVLevel_HiOPT15,
|
||||
GPUUVLevel_HighUV,
|
||||
GPUUVLevel_EnumMax,
|
||||
} GPUUndervoltLevel;
|
||||
|
||||
@@ -164,8 +165,8 @@ typedef enum {
|
||||
} RamDisplayMode;
|
||||
|
||||
typedef enum {
|
||||
MemoryFrequencyMeasurementMode_Actmon = 0,
|
||||
MemoryFrequencyMeasurementMode_PLL,
|
||||
MemoryFrequencyMeasurementMode_PLL = 0,
|
||||
MemoryFrequencyMeasurementMode_Actmon,
|
||||
MemoryFrequencyMeasurementMode_EnumMax,
|
||||
} MemoryFrequencyMeasurementMode;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ typedef struct
|
||||
u16 resolutionHeight;
|
||||
|
||||
// Reserved for future use
|
||||
u8 reserved[0x428];
|
||||
u8 reserved[0x424];
|
||||
} HocClkContext;
|
||||
|
||||
typedef struct
|
||||
@@ -73,6 +73,6 @@ typedef struct
|
||||
|
||||
#define HOCCLK_FREQ_LIST_MAX 32
|
||||
|
||||
#define GLOBAL_PROFILE_ID 0xA111111111111111
|
||||
#define HOCCLK_GLOBAL_PROFILE_TID 0xA111111111111111
|
||||
|
||||
static_assert(sizeof(HocClkContext) == 0x500);
|
||||
@@ -85,6 +85,7 @@ typedef enum {
|
||||
KipConfigValue_marikoEmcMaxClock,
|
||||
KipConfigValue_marikoEmcVddqVolt,
|
||||
KipConfigValue_emcDvbShift,
|
||||
KipConfigValue_marikoSocVmax,
|
||||
|
||||
KipConfigValue_t1_tRCD,
|
||||
KipConfigValue_t2_tRP,
|
||||
@@ -310,7 +311,8 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
|
||||
return pretty ? "Mariko EMC VDDQ Voltage" : "mariko_emc_vddq_volt";
|
||||
case KipConfigValue_emcDvbShift:
|
||||
return pretty ? "EMC DVB Shift" : "emc_dvb_shift";
|
||||
|
||||
case KipConfigValue_marikoSocVmax:
|
||||
return pretty ? "SOC Vmax" : "soc_vmax";
|
||||
// Memory timings
|
||||
case KipConfigValue_t1_tRCD:
|
||||
return pretty ? "t1 - tRCD" : "t1_trcd";
|
||||
@@ -566,6 +568,7 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
|
||||
case KipConfigValue_marikoEmcMaxClock:
|
||||
case KipConfigValue_marikoEmcVddqVolt:
|
||||
case KipConfigValue_emcDvbShift:
|
||||
case KipConfigValue_marikoSocVmax:
|
||||
case KipConfigValue_t1_tRCD:
|
||||
case KipConfigValue_t2_tRP:
|
||||
case KipConfigValue_t3_tRAS:
|
||||
|
||||
@@ -39,7 +39,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk
|
||||
# version control constants
|
||||
#---------------------------------------------------------------------------------
|
||||
#TARGET_VERSION := $(shell git describe --dirty --always --tags)
|
||||
APP_VERSION := 2.0.1
|
||||
APP_VERSION := 2.1.0
|
||||
TARGET_VERSION := $(APP_VERSION)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
@@ -36,6 +36,7 @@ tsl::elm::ListItem* ramBWItemAll = NULL;
|
||||
tsl::elm::ListItem* ramBWItemCpu = NULL;
|
||||
tsl::elm::ListItem* ramBWItemGpu = NULL;
|
||||
tsl::elm::ListItem* ramBWItemMax = NULL;
|
||||
tsl::elm::ListItem* bqtempitem = NULL;
|
||||
|
||||
ImageElement* CatImage = NULL;
|
||||
HideableCategoryHeader* CatHeader = NULL;
|
||||
@@ -73,6 +74,10 @@ void AboutGui::listUI()
|
||||
this->listElement->addItem(eristaPLLXItem);
|
||||
}
|
||||
|
||||
bqtempitem =
|
||||
new tsl::elm::ListItem("BQ24193 Temp:");
|
||||
this->listElement->addItem(bqtempitem);
|
||||
|
||||
this->listElement->addItem(
|
||||
new tsl::elm::CategoryHeader("RAM Bandwidth")
|
||||
);
|
||||
@@ -382,4 +387,23 @@ void AboutGui::refresh()
|
||||
sprintf(strings[9], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWPeak]);
|
||||
ramBWItemMax->setValue(strings[9]);
|
||||
|
||||
switch(context->temps[HocClkThermalSensor_BQ24193]) {
|
||||
case 0:
|
||||
strcpy(strings[10], "Normal");
|
||||
break;
|
||||
case 1:
|
||||
strcpy(strings[10], "Warm");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(strings[10], "Hot");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(strings[10], "Overheat");
|
||||
break;
|
||||
default:
|
||||
strcpy(strings[10], "Unknown");
|
||||
}
|
||||
|
||||
bqtempitem->setValue(strings[10]);
|
||||
|
||||
}
|
||||
|
||||
@@ -290,6 +290,9 @@ public:
|
||||
: applicationId(appId), profileList(pList), profile(prof) {}
|
||||
|
||||
void listUI() override {
|
||||
BaseMenuGui::refresh(); // get latest context
|
||||
if(!this->context)
|
||||
return;
|
||||
Result rc = hocclkIpcGetConfigValues(&configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] {
|
||||
FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc);
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "base_menu_gui.h"
|
||||
#include "freq_choice_gui.h"
|
||||
#include "value_choice_gui.h"
|
||||
#define HOCCLK_GLOBAL_PROFILE_TID 0xA111111111111111
|
||||
class AppProfileGui : public BaseMenuGui
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -301,6 +301,9 @@ public:
|
||||
GovernorOverrideSubMenuGui(u32 initialPacked) : packed(initialPacked) {}
|
||||
|
||||
void listUI() override {
|
||||
BaseMenuGui::refresh(); // get latest context
|
||||
if(!this->context)
|
||||
return;
|
||||
Result rc = hocclkIpcGetConfigValues(&configList); // idk why this is needed, probably some refreshing issue
|
||||
if (R_FAILED(rc)) [[unlikely]] {
|
||||
FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc);
|
||||
|
||||
@@ -71,6 +71,10 @@ MiscGui::MiscGui()
|
||||
|
||||
MiscGui::~MiscGui()
|
||||
{
|
||||
if (shouldSaveKip) {
|
||||
sendKipData();
|
||||
shouldSaveKip = false;
|
||||
}
|
||||
if (s_kipThreadPending) {
|
||||
threadWaitForExit(&s_kipThread);
|
||||
threadClose(&s_kipThread);
|
||||
@@ -94,7 +98,7 @@ void MiscGui::addConfigToggle(HocClkConfigValue configVal, const char* altName,
|
||||
if (R_FAILED(rc)) {
|
||||
FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||
} else if (kip) {
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
}
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
});
|
||||
@@ -102,6 +106,59 @@ void MiscGui::addConfigToggle(HocClkConfigValue configVal, const char* altName,
|
||||
this->configToggles[configVal] = toggle;
|
||||
}
|
||||
|
||||
void MiscGui::addConfigTrackbar(HocClkConfigValue configVal, const char* altName, const ValueRange& range, bool kip) {
|
||||
struct IndexedBar : tsl::elm::NamedStepTrackBar {
|
||||
IndexedBar(const char* label, const ValueRange& r)
|
||||
: tsl::elm::NamedStepTrackBar("", {""}, true, label) {
|
||||
m_stepDescriptions.clear();
|
||||
u32 numSteps = (r.max - r.min) / r.step + 1;
|
||||
for (u32 i = 0; i < numSteps; i++) {
|
||||
u32 disp = (r.min + i * r.step) / r.divisor;
|
||||
std::string s = std::to_string(disp);
|
||||
if (!r.suffix.empty()) s += " " + r.suffix;
|
||||
m_stepDescriptions.push_back(s);
|
||||
}
|
||||
m_numSteps = (u8)m_stepDescriptions.size();
|
||||
m_selection = m_stepDescriptions[0];
|
||||
}
|
||||
};
|
||||
const char* name = altName ? altName : hocclkFormatConfigValue(configVal, true);
|
||||
auto* bar = new IndexedBar(name, range);
|
||||
u32 cur = (u32)this->configList->values[configVal];
|
||||
u16 curStep = 0;
|
||||
if (cur >= range.min && cur <= range.max && range.step > 0 && (cur - range.min) % range.step == 0)
|
||||
curStep = (u16)((cur - range.min) / range.step);
|
||||
bar->setProgress(curStep);
|
||||
bar->setValueChangedListener([this, configVal, kip, range](u16 v) {
|
||||
this->configList->values[configVal] = range.min + (u32)v * range.step;
|
||||
Result rc = hocclkIpcSetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||
if (kip) shouldSaveKip = true;
|
||||
});
|
||||
this->listElement->addItem(bar);
|
||||
}
|
||||
|
||||
void MiscGui::addMappedConfigTrackbar(HocClkConfigValue configVal, const char* altName,
|
||||
std::vector<u32> vals,
|
||||
std::initializer_list<std::string> names, bool kip) {
|
||||
const char* name = altName ? altName : hocclkFormatConfigValue(configVal, true);
|
||||
auto* bar = new tsl::elm::NamedStepTrackBar("", names, true, name);
|
||||
u32 cur = (u32)this->configList->values[configVal];
|
||||
u16 curIdx = 0;
|
||||
for (u16 i = 0; i < (u16)vals.size(); i++) {
|
||||
if (vals[i] == cur) { curIdx = i; break; }
|
||||
}
|
||||
bar->setProgress(curIdx);
|
||||
bar->setValueChangedListener([this, configVal, kip, vals](u16 idx) {
|
||||
if (idx < (u16)vals.size())
|
||||
this->configList->values[configVal] = vals[idx];
|
||||
Result rc = hocclkIpcSetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||
if (kip) shouldSaveKip = true;
|
||||
});
|
||||
this->listElement->addItem(bar);
|
||||
}
|
||||
|
||||
|
||||
void MiscGui::addConfigButton(HocClkConfigValue configVal,
|
||||
const char* altName,
|
||||
@@ -173,7 +230,7 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
|
||||
return false;
|
||||
}
|
||||
if (kip) {
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
}
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
return true;
|
||||
@@ -198,7 +255,7 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
|
||||
return false;
|
||||
}
|
||||
if (kip) {
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
}
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
return true;
|
||||
@@ -291,7 +348,7 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
|
||||
return false;
|
||||
}
|
||||
if (kip) {
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
}
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
return true;
|
||||
@@ -316,7 +373,7 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
|
||||
return false;
|
||||
}
|
||||
if (kip) {
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
}
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
return true;
|
||||
@@ -529,6 +586,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("General Settings"));
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
std::vector<NamedValue> ramVoltDispModes = {
|
||||
@@ -556,6 +615,7 @@ protected:
|
||||
false
|
||||
|
||||
);
|
||||
|
||||
addConfigButton(
|
||||
HocClkConfigValue_PollingIntervalMs,
|
||||
"Polling Interval",
|
||||
@@ -569,9 +629,10 @@ protected:
|
||||
|
||||
tsl::elm::CustomDrawer* exSetWarning = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
|
||||
renderer->drawString("\uE150 Experimental Settings are incomplete ", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("and may not work correctly! Here be dragons!", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("and may not work correctly or at all!", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("Here be dragons!", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
});
|
||||
exSetWarning->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70);
|
||||
exSetWarning->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 90);
|
||||
this->listElement->addItem(exSetWarning);
|
||||
|
||||
addConfigToggle(HocClkConfigValue_EnableExperimentalSettings, nullptr);
|
||||
@@ -584,6 +645,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental Settings"));
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
|
||||
@@ -605,8 +668,8 @@ protected:
|
||||
|
||||
|
||||
std::vector<NamedValue> ramRFMeasurementMethods = {
|
||||
NamedValue("Actmon", MemoryFrequencyMeasurementMode_Actmon),
|
||||
NamedValue("PLL", MemoryFrequencyMeasurementMode_PLL),
|
||||
NamedValue("Actmon", MemoryFrequencyMeasurementMode_Actmon),
|
||||
};
|
||||
addConfigButton(
|
||||
HocClkConfigValue_MemoryFrequencyMeasurementMode,
|
||||
@@ -659,13 +722,14 @@ protected:
|
||||
NamedValue("1024mA", 1024),
|
||||
NamedValue("1280mA", 1280),
|
||||
NamedValue("1536mA", 1536),
|
||||
NamedValue("1664mA", 1664), // Why Nintendo?
|
||||
NamedValue("1792mA", 1792),
|
||||
NamedValue("2048mA", 2048),
|
||||
NamedValue("2304mA", 2304),
|
||||
NamedValue("2560mA", 2560),
|
||||
};
|
||||
|
||||
ValueThresholds chargerThresholds(1792, 1793);
|
||||
ValueThresholds chargerThresholds(1664, 1793);
|
||||
|
||||
addConfigButton(
|
||||
HocClkConfigValue_BatteryChargeCurrent,
|
||||
@@ -689,6 +753,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Governor Settings"));
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
|
||||
@@ -722,6 +788,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
|
||||
BaseMenuGui::refresh(); // get latest context
|
||||
@@ -773,6 +841,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Safety Settings"));
|
||||
addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr);
|
||||
addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr);
|
||||
@@ -822,11 +892,58 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
BaseMenuGui::refresh();
|
||||
if(!this->context)
|
||||
return;
|
||||
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
std::vector<NamedValue> noNamedValues = {};
|
||||
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("RAM Settings"));
|
||||
|
||||
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("RAM Settings"));
|
||||
|
||||
addConfigTrackbar(KipConfigValue_emcDvbShift, "SoC DVB Shift", ValueRange(0, 16, 1)); // yes, DVB 16 is nessesary
|
||||
if(IsMariko()) {
|
||||
u32 socSpeedo = this->context->speedos[HocClkSpeedo_SOC];
|
||||
std::string autoText = "1000 mV";
|
||||
if (socSpeedo <= 1597) {
|
||||
autoText = "1050 mV";
|
||||
} else if (socSpeedo <= 1708) {
|
||||
autoText = "1025 mV";
|
||||
} else if(socSpeedo >= 1709) {
|
||||
autoText = "1000 mV";
|
||||
}
|
||||
|
||||
std::vector<NamedValue> marikovmaxconf = {
|
||||
NamedValue("Do not override", 0, autoText),
|
||||
NamedValue("1000 mV", 1000),
|
||||
NamedValue("1025 mV", 1025),
|
||||
NamedValue("1050 mV", 1050),
|
||||
NamedValue("1075 mV", 1075),
|
||||
NamedValue("1100 mV", 1100),
|
||||
NamedValue("1125 mV", 1125),
|
||||
NamedValue("1150 mV", 1150),
|
||||
NamedValue("1175 mV", 1175),
|
||||
NamedValue("1200 mV", 1200),
|
||||
};
|
||||
ValueThresholds marikovmaxT(1075, 1150);
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoSocVmax,
|
||||
"SoC Max Volt",
|
||||
ValueRange(0, 12, 1, "", 0),
|
||||
"SoC Max Volt",
|
||||
&marikovmaxT,
|
||||
{},
|
||||
marikovmaxconf,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
addConfigToggle(KipConfigValue_hpMode, "HP Mode", true);
|
||||
|
||||
std::map<uint32_t, std::string> emc_voltage_label = {
|
||||
@@ -838,7 +955,7 @@ protected:
|
||||
{1250000, "Unsafe Max"},
|
||||
};
|
||||
|
||||
ValueThresholds vdd2Thresholds(1212500, 1250000);
|
||||
ValueThresholds vdd2Thresholds(IsMariko() ? 1212500 : 1237500, 1250000);
|
||||
addConfigButton(
|
||||
KipConfigValue_commonEmcMemVolt,
|
||||
"RAM VDD2 Voltage",
|
||||
@@ -865,25 +982,16 @@ protected:
|
||||
);
|
||||
}
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_emcDvbShift,
|
||||
"SoC DVB Shift",
|
||||
ValueRange(0, 10, 1, "", 1),
|
||||
"SoC DVB Shift",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
if (IsMariko()) {
|
||||
std::vector<NamedValue> stepMode = {
|
||||
NamedValue("66MHz", 0),
|
||||
NamedValue("100MHz", 1),
|
||||
NamedValue("133MHz", 3), // Mantain compatability
|
||||
NamedValue("JEDEC.", 2),
|
||||
};
|
||||
|
||||
std::vector<NamedValue> stepMode = {
|
||||
NamedValue("66MHz", 0),
|
||||
NamedValue("100MHz", 1),
|
||||
NamedValue("Jedec", 2),
|
||||
};
|
||||
|
||||
addConfigButton(KipConfigValue_stepMode, "Step Mode", ValueRange(0, 0, 2, "", 0), "Step Mode", &thresholdsDisabled, {}, stepMode, false, true);
|
||||
addConfigButton(KipConfigValue_stepMode, "Step Mode", ValueRange(0, 0, 2, "", 0), "Step Mode", &thresholdsDisabled, {}, stepMode, false, true);
|
||||
}
|
||||
|
||||
if (IsErista()) {
|
||||
tsl::elm::ListItem* freqSubmenu = new tsl::elm::ListItem("RAM Frequency Editor");
|
||||
@@ -997,40 +1105,18 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Memory Timings"));
|
||||
|
||||
addConfigButton(KipConfigValue_t1_tRCD, "t1 tRCD", ValueRange(0, 7, 1, "", 1), "tRCD", &thresholdsDisabled, {}, {}, false, true);
|
||||
addConfigButton(KipConfigValue_t2_tRP, "t2 tRP", ValueRange(0, 7, 1, "", 1), "tRP", &thresholdsDisabled, {}, {}, false, true);
|
||||
addConfigButton(KipConfigValue_t3_tRAS, "t3 tRAS", ValueRange(0, 9, 1, "", 1), "tRAS", &thresholdsDisabled, {}, {}, false, true);
|
||||
addConfigButton(KipConfigValue_t4_tRRD, "t4 tRRD", ValueRange(0, 6, 1, "", 1), "tRRD", &thresholdsDisabled, {}, {}, false, true);
|
||||
u32 tRFCCount = 10;
|
||||
if (IsErista()) {
|
||||
tRFCCount = 5;
|
||||
}
|
||||
addConfigButton(KipConfigValue_t5_tRFC, "t5 tRFC", ValueRange(0, tRFCCount, 1, "", 1), "tRFC", &thresholdsDisabled, {}, {}, false, true);
|
||||
addConfigButton(KipConfigValue_t6_tRTW, "t6 tRTW", ValueRange(0, 9, 1, "", 1), "tRTW", &thresholdsDisabled, {}, {}, false, true);
|
||||
addConfigButton(KipConfigValue_t7_tWTR, "t7 tWTR", ValueRange(0, 9, 1, "", 1), "tWTR", &thresholdsDisabled, {}, {}, false, true);
|
||||
addConfigButton(KipConfigValue_t8_tREFI, "t8 tREFI", ValueRange(0, 6, 1, "", 1), "tREFI", &thresholdsDisabled, {}, {}, false, true);
|
||||
|
||||
std::vector<NamedValue> t6_tRTW_fine_tune = {
|
||||
NamedValue("-2", 0xFFFFFFFE),
|
||||
NamedValue("-1", 0xFFFFFFFF),
|
||||
NamedValue(" 0", 0),
|
||||
NamedValue("+1", 1),
|
||||
NamedValue("+2", 2),
|
||||
};
|
||||
|
||||
std::vector<NamedValue> t7_tWTR_fine_tune = {
|
||||
NamedValue("-3", 0xFFFFFFFD),
|
||||
NamedValue("-2", 0xFFFFFFFE),
|
||||
NamedValue("-1", 0xFFFFFFFF),
|
||||
NamedValue(" 0", 0),
|
||||
NamedValue("+1", 1),
|
||||
NamedValue("+2", 2),
|
||||
NamedValue("+3", 3),
|
||||
};
|
||||
addConfigTrackbar(KipConfigValue_t1_tRCD, "t1 tRCD", ValueRange(0, 7, 1));
|
||||
addConfigTrackbar(KipConfigValue_t2_tRP, "t2 tRP", ValueRange(0, 7, 1));
|
||||
addConfigTrackbar(KipConfigValue_t3_tRAS, "t3 tRAS", ValueRange(0, 9, 1));
|
||||
addConfigTrackbar(KipConfigValue_t4_tRRD, "t4 tRRD", ValueRange(0, 6, 1));
|
||||
addConfigTrackbar(KipConfigValue_t5_tRFC, "t5 tRFC", ValueRange(0, IsErista() ? 5u : 10u, 1));
|
||||
addConfigTrackbar(KipConfigValue_t6_tRTW, "t6 tRTW", ValueRange(0, 9, 1));
|
||||
addConfigTrackbar(KipConfigValue_t7_tWTR, "t7 tWTR", ValueRange(0, 9, 1));
|
||||
addConfigTrackbar(KipConfigValue_t8_tREFI, "t8 tREFI", ValueRange(0, 6, 1));
|
||||
|
||||
/* Yes this is duplicated code, yes I don't care. */
|
||||
std::vector<NamedValue> timingTbreakFreqs = {
|
||||
@@ -1101,13 +1187,18 @@ protected:
|
||||
nv.name = formatMemClockKhzLabel(nv.value, unit);
|
||||
}
|
||||
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Advanced"));
|
||||
addConfigButton(KipConfigValue_timingEmcTbreak, "RAM-Timing tBreak", ValueRange(0, 1, 1, "", 1), "tBreak", &thresholdsDisabled, {}, timingTbreakFreqs, false, true);
|
||||
addConfigButton(KipConfigValue_low_t6_tRTW, "Low t6 tRTW", ValueRange(0, 10, 1, "", 1), "low tRTW", &thresholdsDisabled, {}, {}, false, true );
|
||||
addConfigButton(KipConfigValue_low_t7_tWTR, "Low t7 tWTR", ValueRange(0, 10, 1, "", 1), "low tWTR", &thresholdsDisabled, {}, {}, false, true );
|
||||
addConfigButton(KipConfigValue_t2_tRP_cap, "1333WL t2 RP Cap", ValueRange(0, 8, 1, "", 1), "tRP Cap", &thresholdsDisabled, {}, {}, false, true );
|
||||
addConfigButton(KipConfigValue_t6_tRTW_fine_tune, "t6 tRTW Fine Tune", ValueRange(0, 4, 1, "", 0), "tRTW Fine Tune", &thresholdsDisabled, {}, t6_tRTW_fine_tune, false, true);
|
||||
addConfigButton(KipConfigValue_t7_tWTR_fine_tune, "t7 tWTR Fine Tune", ValueRange(0, 6, 1, "", 0), "tWTR Fine Tune", &thresholdsDisabled, {}, t7_tWTR_fine_tune, false, true);
|
||||
addConfigTrackbar(KipConfigValue_low_t6_tRTW, "Low t6 tRTW", ValueRange(0, 9, 1));
|
||||
addConfigTrackbar(KipConfigValue_low_t7_tWTR, "Low t7 tWTR", ValueRange(0, 9, 1));
|
||||
addConfigTrackbar(KipConfigValue_t2_tRP_cap, "1333WL t2 RP Cap", ValueRange(0, 8, 1));
|
||||
addMappedConfigTrackbar(KipConfigValue_t6_tRTW_fine_tune, "t6 tRTW Fine Tune",
|
||||
{0xFFFFFFFEu, 0xFFFFFFFFu, 0u, 1u, 2u},
|
||||
{"-2", "-1", " 0", "+1", "+2"});
|
||||
addMappedConfigTrackbar(KipConfigValue_t7_tWTR_fine_tune, "t7 tWTR Fine Tune",
|
||||
{0xFFFFFFFDu, 0xFFFFFFFEu, 0xFFFFFFFFu, 0u, 1u, 2u, 3u},
|
||||
{"-3", "-2", "-1", " 0", "+1", "+2", "+3"});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1275,7 +1366,7 @@ protected:
|
||||
FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||
return false;
|
||||
}
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
return true;
|
||||
},
|
||||
@@ -1335,7 +1426,7 @@ protected:
|
||||
FatalGui::openWithResultCode("hocclkIpcSetConfigValues", rc);
|
||||
return false;
|
||||
}
|
||||
sendKipData();
|
||||
shouldSaveKip = true;
|
||||
this->lastContextUpdate = armGetSystemTick();
|
||||
return true;
|
||||
},
|
||||
@@ -1384,6 +1475,90 @@ protected:
|
||||
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("CPU Settings"));
|
||||
if(IsMariko()) {
|
||||
addConfigTrackbar(KipConfigValue_marikoCpuUVLow, "CPU Low UV", ValueRange(0, 8, 1));
|
||||
addConfigTrackbar(KipConfigValue_marikoCpuUVHigh, "CPU High UV", ValueRange(0, 12, 1));
|
||||
|
||||
std::vector<NamedValue> marikoTableConf = {
|
||||
// NamedValue("Auto", 0),
|
||||
NamedValue("Default", 1),
|
||||
NamedValue("1581MHz Tbreak", 2),
|
||||
NamedValue("1683MHz Tbreak", 3),
|
||||
NamedValue("Extreme UV Table", 4)
|
||||
};
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_tableConf,
|
||||
"CPU UV Table",
|
||||
ValueRange(0, 12, 1, "", 0),
|
||||
"CPU UV Table",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
marikoTableConf,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuLowVmin,
|
||||
"CPU Low VMIN",
|
||||
ValueRange(550, 750, 5, "mV", 1),
|
||||
"CPU VMIN",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuHighVmin,
|
||||
"CPU High VMIN",
|
||||
ValueRange(650, 900, 5, "mV", 1),
|
||||
"CPU VMIN",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
ValueThresholds mCpuVoltThresholds(1160, 1180);
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuMaxVolt,
|
||||
"CPU Max Voltage",
|
||||
ValueRange(1000, 1200, 5, "mV", 1),
|
||||
"CPU Max Voltage",
|
||||
&mCpuVoltThresholds,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
std::vector<NamedValue> maxClkOptions = {
|
||||
NamedValue("1963 MHz", 1963500),
|
||||
NamedValue("2091 MHz", 2091000),
|
||||
NamedValue("2193 MHz", 2193000),
|
||||
NamedValue("2295 MHz", 2295000),
|
||||
NamedValue("2397 MHz", 2397000),
|
||||
NamedValue("2499 MHz", 2499000),
|
||||
NamedValue("2601 MHz", 2601000),
|
||||
NamedValue("2703 MHz", 2703000),
|
||||
};
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuMaxClock,
|
||||
"CPU Max Clock",
|
||||
ValueRange(0, 0, 1, "", 1),
|
||||
"CPU Max Clock",
|
||||
this->configList->values[KipConfigValue_marikoCpuUVHigh] ? &mCpuClockThresholdsUV : &mCpuClockThresholds,
|
||||
{},
|
||||
maxClkOptions,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
std::vector<NamedValue> ClkOptions = {
|
||||
NamedValue("1963 MHz", 1963500),
|
||||
NamedValue("2091 MHz", 2091000),
|
||||
@@ -1407,41 +1582,10 @@ protected:
|
||||
true
|
||||
);
|
||||
} else {
|
||||
std::vector<NamedValue> ClkOptionsE = {
|
||||
NamedValue("1785 MHz", 1785000),
|
||||
NamedValue("1887 MHz", 1887000),
|
||||
NamedValue("1989 MHz", 1989000),
|
||||
NamedValue("2091 MHz", 2091000),
|
||||
NamedValue("2193 MHz", 2193000),
|
||||
NamedValue("2295 MHz", 2295000),
|
||||
NamedValue("2397 MHz", 2397000),
|
||||
};
|
||||
addConfigButton(
|
||||
KipConfigValue_eristaCpuBoostClock,
|
||||
"CPU Boost Clock",
|
||||
ValueRange(0, 0, 1, "", 1),
|
||||
"CPU Boost Clock",
|
||||
this->configList->values[KipConfigValue_eristaCpuUV] ? &eCpuClockThresholdsUV : &eCpuClockThresholds,
|
||||
{},
|
||||
ClkOptionsE,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
if(IsErista()) {
|
||||
addConfigButton(
|
||||
KipConfigValue_eristaCpuUV,
|
||||
"CPU UV",
|
||||
ValueRange(0, 5, 1, "", 1),
|
||||
"CPU UV",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
addConfigTrackbar(KipConfigValue_eristaCpuUV, "CPU UV", ValueRange(0, 5, 1));
|
||||
|
||||
addConfigToggle(KipConfigValue_eristaCpuUnlock, "CPU Unlock", true);
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_eristaCpuVmin,
|
||||
"CPU VMIN",
|
||||
@@ -1487,112 +1631,29 @@ protected:
|
||||
maxClkOptions,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
std::vector<NamedValue> marikoTableConf = {
|
||||
// NamedValue("Auto", 0),
|
||||
NamedValue("Default", 1),
|
||||
NamedValue("1581MHz Tbreak", 2),
|
||||
NamedValue("1683MHz Tbreak", 3),
|
||||
NamedValue("Extreme UV Table", 4)
|
||||
};
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_tableConf,
|
||||
"CPU UV Table",
|
||||
ValueRange(0, 12, 1, "", 0),
|
||||
"CPU UV Table",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
marikoTableConf,
|
||||
false,
|
||||
true
|
||||
);
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuUVLow,
|
||||
"CPU Low UV",
|
||||
ValueRange(0, 8, 1, "", 1),
|
||||
"CPU Low UV",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuUVHigh,
|
||||
"CPU High UV",
|
||||
ValueRange(0, 12, 1, "", 1),
|
||||
"CPU High UV",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
std::vector<NamedValue> maxClkOptions = {
|
||||
NamedValue("1963 MHz", 1963500),
|
||||
std::vector<NamedValue> ClkOptionsE = {
|
||||
NamedValue("1785 MHz", 1785000),
|
||||
NamedValue("1887 MHz", 1887000),
|
||||
NamedValue("1989 MHz", 1989000),
|
||||
NamedValue("2091 MHz", 2091000),
|
||||
NamedValue("2193 MHz", 2193000),
|
||||
NamedValue("2295 MHz", 2295000),
|
||||
NamedValue("2397 MHz", 2397000),
|
||||
NamedValue("2499 MHz", 2499000),
|
||||
NamedValue("2601 MHz", 2601000),
|
||||
NamedValue("2703 MHz", 2703000),
|
||||
};
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuMaxClock,
|
||||
"CPU Max Clock",
|
||||
KipConfigValue_eristaCpuBoostClock,
|
||||
"CPU Boost Clock",
|
||||
ValueRange(0, 0, 1, "", 1),
|
||||
"CPU Max Clock",
|
||||
this->configList->values[KipConfigValue_marikoCpuUVHigh] ? &mCpuClockThresholdsUV : &mCpuClockThresholds,
|
||||
"CPU Boost Clock",
|
||||
this->configList->values[KipConfigValue_eristaCpuUV] ? &eCpuClockThresholdsUV : &eCpuClockThresholds,
|
||||
{},
|
||||
maxClkOptions,
|
||||
ClkOptionsE,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuLowVmin,
|
||||
"CPU Low VMIN",
|
||||
ValueRange(550, 750, 5, "mV", 1),
|
||||
"CPU VMIN",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuHighVmin,
|
||||
"CPU High VMIN",
|
||||
ValueRange(650, 900, 5, "mV", 1),
|
||||
"CPU VMIN",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
ValueThresholds mCpuVoltThresholds(1160, 1180);
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoCpuMaxVolt,
|
||||
"CPU Max Voltage",
|
||||
ValueRange(1000, 1200, 5, "mV", 1),
|
||||
"CPU Max Voltage",
|
||||
&mCpuVoltThresholds,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr);
|
||||
|
||||
}
|
||||
addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1602,6 +1663,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("RAM Frequency Editor"));
|
||||
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
@@ -1672,6 +1735,8 @@ public:
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
Result rc = hocclkIpcGetConfigValues(this->configList);
|
||||
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
std::vector<NamedValue> noNamedValues = {};
|
||||
|
||||
@@ -1825,6 +1890,7 @@ protected:
|
||||
NamedValue("-50 mV", 0xFFFFFFCE),
|
||||
NamedValue("-45 mV", 0xFFFFFFD3),
|
||||
NamedValue("-40 mV", 0xFFFFFFD8),
|
||||
NamedValue("-35 mV", 0xFFFFFFDD),
|
||||
NamedValue("-30 mV", 0xFFFFFFE2),
|
||||
NamedValue("-25 mV", 0xFFFFFFE7),
|
||||
NamedValue("-20 mV", 0xFFFFFFEC),
|
||||
@@ -2019,9 +2085,9 @@ protected:
|
||||
|
||||
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
|
||||
renderer->drawString("\uE150 Setting GPU Clocks past", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("1075MHz without UV, 1152MHz on SLT", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("or 1228MHz on HiOPT can cause ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("permanent damage to your Switch!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("1228MHz without a proper undervolt", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("can cause degradation or damage", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("to your console!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 110, 18, tsl::style::color::ColorText);
|
||||
});
|
||||
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 130);
|
||||
@@ -2041,9 +2107,9 @@ protected:
|
||||
addConfigButton(KipConfigValue_g_volt_921600, "921.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
if(this->configList->values[KipConfigValue_marikoGpuUV] >= GPUUVLevel_SLT)
|
||||
if(this->configList->values[KipConfigValue_marikoGpuUV] >= GPUUVLevel_HiOPT15)
|
||||
addConfigButton(KipConfigValue_g_volt_1152000, "1152.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
if(this->configList->values[KipConfigValue_marikoGpuUV] >= GPUUVLevel_HiOPT) {
|
||||
if(this->configList->values[KipConfigValue_marikoGpuUV] >= GPUUVLevel_HighUV) {
|
||||
addConfigButton(KipConfigValue_g_volt_1228800, "1228.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_1267200, "1267.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_1305600, "1305.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &MgpuVmaxThresholds, {}, mGpuVolts, false, true);
|
||||
@@ -2059,9 +2125,9 @@ protected:
|
||||
|
||||
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
|
||||
renderer->drawString("\uE150 Setting GPU Clocks past", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("921MHz without UV and 960MHz on", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("SLT or HiOPT can cause ", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("permanent damage to your Switch!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("921MHz without a proper undervolt", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("can cause degradation or damage", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("to your console!", false, x + 20, y + 90, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("Proceed at your own risk!", false, x + 20, y + 110, 18, tsl::style::color::ColorText);
|
||||
});
|
||||
warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 130);
|
||||
@@ -2090,9 +2156,9 @@ protected:
|
||||
addConfigButton(KipConfigValue_g_volt_e_844800, "844.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_e_883200, "883.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_e_921600, "921.6MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false, true);
|
||||
if(this->configList->values[KipConfigValue_eristaGpuUV] >= GPUUVLevel_SLT)
|
||||
if(this->configList->values[KipConfigValue_eristaGpuUV] >= GPUUVLevel_HiOPT15)
|
||||
addConfigButton(KipConfigValue_g_volt_e_960000, "960.0MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false, true);
|
||||
if(this->configList->values[KipConfigValue_eristaGpuUV] >= GPUUVLevel_HiOPT) {
|
||||
if(this->configList->values[KipConfigValue_eristaGpuUV] >= GPUUVLevel_HighUV) {
|
||||
addConfigButton(KipConfigValue_g_volt_e_998400, "998.4MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_e_1036800, "1036.8MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false, true);
|
||||
addConfigButton(KipConfigValue_g_volt_e_1075200, "1075.2MHz", ValueRange(0, 0, 0, "0", 1), "Voltage", &EgpuVmaxThresholds, {}, eGpuVolts_noAuto, false, true);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
#include "../../ipc.h"
|
||||
#include "base_menu_gui.h"
|
||||
#include <initializer_list>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
@@ -44,6 +45,10 @@ protected:
|
||||
std::set<HocClkConfigValue> emcClockConfigs;
|
||||
|
||||
void addConfigToggle(HocClkConfigValue configVal, const char* altName, bool kip = false);
|
||||
void addConfigTrackbar(HocClkConfigValue configVal, const char* altName, const ValueRange& range, bool kip = true);
|
||||
void addMappedConfigTrackbar(HocClkConfigValue configVal, const char* altName,
|
||||
std::vector<u32> vals,
|
||||
std::initializer_list<std::string> names, bool kip = true);
|
||||
void addConfigButton(HocClkConfigValue configVal,
|
||||
const char* altName,
|
||||
const ValueRange& range,
|
||||
@@ -72,4 +77,5 @@ protected:
|
||||
|
||||
tsl::elm::ToggleListItem* enabledToggle;
|
||||
u8 frameCounter = 60;
|
||||
bool shouldSaveKip = false;
|
||||
};
|
||||
@@ -31,6 +31,14 @@
|
||||
"highest_cpu_id": 3
|
||||
}
|
||||
}, {
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x70000000",
|
||||
"is_ro": false,
|
||||
"size": "0x00001000",
|
||||
"is_io": true
|
||||
}
|
||||
}, {
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x60006000",
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include "../file_utils.hpp"
|
||||
namespace board {
|
||||
|
||||
u64 clkVirtAddr, dsiVirtAddr;
|
||||
u64 clkVirtAddr, dsiVirtAddr, apbVirtAddr;
|
||||
|
||||
HocClkSocType gSocType;
|
||||
u8 gDramID;
|
||||
@@ -153,6 +153,9 @@ namespace board {
|
||||
rc = QueryMemoryMapping(&dsiVirtAddr, 0x54300000, 0x40000);
|
||||
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (dsi)");
|
||||
|
||||
rc = QueryMemoryMapping(&apbVirtAddr, 0x70000000, 0x1000);
|
||||
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (apb)");
|
||||
|
||||
display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = (GetConsoleType() == HocClkConsoleType_Hoag), .isRetroSUPER = integrations::GetRETROSuperStatus()};
|
||||
display::Initialize(&cfg);
|
||||
|
||||
@@ -175,6 +178,7 @@ namespace board {
|
||||
|
||||
max17050Exit();
|
||||
tmp451Exit();
|
||||
display::Shutdown();
|
||||
|
||||
ExitLoad();
|
||||
|
||||
@@ -185,7 +189,6 @@ namespace board {
|
||||
rgltrExit();
|
||||
batteryInfoExit();
|
||||
pmdmntExit();
|
||||
display::Shutdown();
|
||||
nvExit();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <pwm.h>
|
||||
#include "board.hpp"
|
||||
#include "../soctherm.hpp"
|
||||
|
||||
#include "bq24193.hpp"
|
||||
namespace board {
|
||||
|
||||
s32 GetTemperatureMilli(HocClkThermalSensor sensor) {
|
||||
@@ -82,6 +82,11 @@ namespace board {
|
||||
}
|
||||
case HocClkThermalSensor_PLLX: {
|
||||
millis = temps.pllx;
|
||||
break;
|
||||
}
|
||||
case HocClkThermalSensor_BQ24193: {
|
||||
millis = bq24193::getBQTemp();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ASSERT_ENUM_VALID(HocClkThermalSensor, sensor);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
|
||||
*
|
||||
*
|
||||
* Copyright (c) B3711
|
||||
*
|
||||
* 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.
|
||||
@@ -30,6 +32,7 @@
|
||||
namespace board {
|
||||
|
||||
GpuVoltData voltData = {};
|
||||
u32 cpuVoltTable[32] = {}; // 32LUT
|
||||
u64 cldvfs;
|
||||
CpuDfllData cachedTune;
|
||||
|
||||
@@ -371,14 +374,25 @@ namespace board {
|
||||
|
||||
/* Assuming mariko. */
|
||||
const u32 vmax = 800;
|
||||
constexpr u32 VoltageTableOffset = 312;
|
||||
if (!std::memcmp(&buffer[index + VoltageTableOffset], &vmax, sizeof(vmax))) {
|
||||
std::memcpy(voltData.voltTable, &buffer[index + VoltageTableOffset], sizeof(voltData.voltTable));
|
||||
voltData.voltTableAddress = base + memoryInfo.addr + VoltageTableOffset + index;
|
||||
constexpr u32 GpuVoltageTableOffset = 312;
|
||||
if (!std::memcmp(&buffer[index + GpuVoltageTableOffset], &vmax, sizeof(vmax))) {
|
||||
std::memcpy(voltData.voltTable, &buffer[index + GpuVoltageTableOffset], sizeof(voltData.voltTable));
|
||||
voltData.voltTableAddress = base + memoryInfo.addr + GpuVoltageTableOffset + index;
|
||||
}
|
||||
|
||||
constexpr u32 CpuVoltageTableOffset = 0xB8;
|
||||
std::memcpy(cpuVoltTable, &buffer[index + CpuVoltageTableOffset], sizeof(cpuVoltTable)); // TODO: verify the CPU table
|
||||
|
||||
svcCloseHandle(handle);
|
||||
handle = INVALID_HANDLE;
|
||||
|
||||
for(int i = 0; i < (int)std::size(cpuVoltTable); ++i) {
|
||||
fileUtils::LogLine("[dvfs] cpu volt %d: %u mV", i, cpuVoltTable[i]);
|
||||
}
|
||||
|
||||
for(int i = 0; i < (int)std::size(voltData.voltTable); ++i) {
|
||||
fileUtils::LogLine("[dvfs] gpu volt %d: %u mV", i, voltData.voltTable[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -429,17 +443,34 @@ namespace board {
|
||||
|
||||
static const u32 gpuVoltArray[] = { 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800, };
|
||||
|
||||
if (freqMhz <= 1600) {
|
||||
return 0;
|
||||
if (freqMhz <= 1600) return 0;
|
||||
if (bracket >= std::size(ramTable)) bracket = 0;
|
||||
|
||||
u32 bracketStart = ramTable[bracket][0];
|
||||
|
||||
|
||||
u32 rampStartVolt = (bracket == 0) ? 535 : 525;
|
||||
u32 rampSpan = 590 - rampStartVolt;
|
||||
|
||||
|
||||
if (freqMhz >= 1633 && freqMhz < bracketStart) {
|
||||
u32 raw = rampStartVolt + ((freqMhz - 1633) * rampSpan) / (bracketStart - 1633);
|
||||
u32 volt = ((raw + 2) / 5) * 5;
|
||||
if (volt < rampStartVolt) volt = rampStartVolt;
|
||||
if (volt > 590) volt = 590;
|
||||
return volt;
|
||||
}
|
||||
|
||||
|
||||
u32 baseVolt = gpuVoltArray[std::size(gpuVoltArray) - 1];
|
||||
for (u32 i = 0; i < std::size(gpuVoltArray); ++i) {
|
||||
if (freqMhz <= ramTable[bracket][i]) {
|
||||
return gpuVoltArray[i];
|
||||
baseVolt = gpuVoltArray[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return gpuVoltArray[std::size(gpuVoltArray) - 1];
|
||||
return baseVolt;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,6 @@ namespace board {
|
||||
u64 voltTableAddress;
|
||||
u32 ramVmin;
|
||||
};
|
||||
|
||||
/* TODO: Find out what component this actually targets. */
|
||||
struct UnkRegulator {
|
||||
u32 voltageMin;
|
||||
u32 voltageStep;
|
||||
|
||||
33
Source/hoc-clk/sysmodule/src/board/bq24193.cpp
Normal file
33
Source/hoc-clk/sysmodule/src/board/bq24193.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
|
||||
*
|
||||
* Copyright (c) CtCaer
|
||||
*
|
||||
* 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 "bq24193.hpp"
|
||||
|
||||
namespace bq24193 {
|
||||
static u8 bq24193_get_reg(u8 reg)
|
||||
{
|
||||
u8 out;
|
||||
I2cRead_OutU8(I2cDevice_Bq24193, reg, &out);
|
||||
return out;
|
||||
}
|
||||
u8 getBQTemp() {
|
||||
u8 regVal = bq24193_get_reg(BQ24193_FaultReg);
|
||||
return regVal & BQ24193_FAULT_THERM_MASK;
|
||||
}
|
||||
}
|
||||
128
Source/hoc-clk/sysmodule/src/board/bq24193.hpp
Normal file
128
Source/hoc-clk/sysmodule/src/board/bq24193.hpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
|
||||
*
|
||||
* Copyright (c) CtCaer
|
||||
*
|
||||
* 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 "board.hpp"
|
||||
#include <i2c.h>
|
||||
|
||||
namespace bq24193 {
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
// REG 0 masks.
|
||||
#define BQ24193_INCONFIG_INLIMIT_MASK (7<<0)
|
||||
#define BQ24193_INCONFIG_VINDPM_MASK 0x78
|
||||
#define BQ24193_INCONFIG_HIZ_EN_MASK (1<<7)
|
||||
|
||||
// REG 1 masks.
|
||||
#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
|
||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1) // 3000uV HOS default.
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN (1<<4)
|
||||
#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
|
||||
#define BQ24193_PORCONFIG_RESET_MASK (1<<7)
|
||||
|
||||
// REG 2 masks.
|
||||
#define BQ24193_CHRGCURR_20PCT_MASK (1<<0)
|
||||
#define BQ24193_CHRGCURR_ICHG_MASK 0xFC
|
||||
|
||||
// REG 3 masks.
|
||||
#define BQ24193_PRECHRG_ITERM 0x0F
|
||||
#define BQ24193_PRECHRG_IPRECHG 0xF0
|
||||
|
||||
// REG 4 masks.
|
||||
#define BQ24193_CHRGVOLT_VTHRES (1<<0)
|
||||
#define BQ24193_CHRGVOLT_BATTLOW (1<<1)
|
||||
#define BQ24193_CHRGVOLT_VREG 0xFC
|
||||
|
||||
// REG 5 masks.
|
||||
#define BQ24193_CHRGTERM_ISET_MASK (1<<0)
|
||||
#define BQ24193_CHRGTERM_CHGTIMER_MASK (3<<1)
|
||||
#define BQ24193_CHRGTERM_ENTIMER_MASK (1<<3)
|
||||
#define BQ24193_CHRGTERM_WATCHDOG_MASK (3<<4)
|
||||
#define BQ24193_CHRGTERM_TERM_ST_MASK (1<<6)
|
||||
#define BQ24193_CHRGTERM_TERM_EN_MASK (1<<7)
|
||||
|
||||
// REG 6 masks.
|
||||
#define BQ24193_IRTHERMAL_THERM_MASK (3<<0)
|
||||
#define BQ24193_IRTHERMAL_VCLAMP_MASK (7<<2)
|
||||
#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7<<5)
|
||||
|
||||
// REG 7 masks.
|
||||
#define BQ24193_MISC_INT_MASK (3<<0)
|
||||
#define BQ24193_MISC_VSET_MASK (1<<4)
|
||||
#define BQ24193_MISC_BATFET_DI_MASK (1<<5)
|
||||
#define BQ24193_MISC_TMR2X_EN_MASK (1<<6)
|
||||
#define BQ24193_MISC_DPDM_EN_MASK (1<<7)
|
||||
|
||||
// REG 8 masks.
|
||||
#define BQ24193_STATUS_VSYS_MASK (1<<0)
|
||||
#define BQ24193_STATUS_THERM_MASK (1<<1)
|
||||
#define BQ24193_STATUS_PG_MASK (1<<2)
|
||||
#define BQ24193_STATUS_DPM_MASK (1<<3)
|
||||
#define BQ24193_STATUS_CHRG_MASK (3<<4)
|
||||
#define BQ24193_STATUS_VBUS_MASK (3<<6)
|
||||
|
||||
// REG 9 masks.
|
||||
#define BQ24193_FAULT_THERM_MASK (7<<0)
|
||||
#define BQ24193_FAULT_BATT_OVP_MASK (1<<3)
|
||||
#define BQ24193_FAULT_CHARGE_MASK (3<<4)
|
||||
#define BQ24193_FAULT_BOOST_MASK (1<<6)
|
||||
#define BQ24193_FAULT_WATCHDOG_MASK (1<<7)
|
||||
|
||||
// REG A masks.
|
||||
#define BQ24193_VENDORPART_DEV_MASK (3<<0)
|
||||
#define BQ24193_VENDORPART_PN_MASK (7<<3)
|
||||
|
||||
enum BQ24193_reg {
|
||||
BQ24193_InputSource = 0x00,
|
||||
BQ24193_PORConfig = 0x01,
|
||||
BQ24193_ChrgCurr = 0x02,
|
||||
BQ24193_PreChrgTerm = 0x03,
|
||||
BQ24193_ChrgVolt = 0x04,
|
||||
BQ24193_ChrgTermTimer = 0x05,
|
||||
BQ24193_IRCompThermal = 0x06,
|
||||
BQ24193_Misc = 0x07,
|
||||
BQ24193_Status = 0x08,
|
||||
BQ24193_FaultReg = 0x09,
|
||||
BQ24193_VendorPart = 0x0A,
|
||||
};
|
||||
|
||||
enum BQ24193_reg_prop {
|
||||
BQ24193_InputVoltageLimit, // REG 0.
|
||||
BQ24193_InputCurrentLimit, // REG 0.
|
||||
BQ24193_SystemMinimumVoltage, // REG 1.
|
||||
BQ24193_FastChargeCurrentLimit, // REG 2.
|
||||
BQ24193_ChargeVoltageLimit, // REG 4.
|
||||
BQ24193_RechargeThreshold, // REG 4.
|
||||
BQ24193_ThermalRegulation, // REG 6.
|
||||
BQ24193_ChargeStatus, // REG 8.
|
||||
BQ24193_TempStatus, // REG 9.
|
||||
BQ24193_DevID, // REG A.
|
||||
BQ24193_ProductNumber, // REG A.
|
||||
};
|
||||
// 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
||||
enum BQ24193_Temp {
|
||||
BQ24193_Temp_Normal = 0,
|
||||
BQ24193_Temp_Warm = 2,
|
||||
BQ24193_Temp_Cool = 3,
|
||||
BQ24193_Temp_Cold = 5,
|
||||
BQ24193_Temp_Hot = 6,
|
||||
};
|
||||
u8 getBQTemp();
|
||||
}
|
||||
|
||||
@@ -1,132 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) Souldbminer
|
||||
*
|
||||
* Copyright (c) KazushiMe
|
||||
*
|
||||
* 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 "pllmb.hpp"
|
||||
|
||||
namespace pllmb {
|
||||
static const u8 qlin_hw_to_pdiv[17] = {
|
||||
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 30, 32
|
||||
};
|
||||
#define GET_BITS(VAL, HIGH, LOW) ((VAL & ((1UL << (HIGH + 1UL)) - 1UL)) >> LOW)
|
||||
#define GET_BIT(VAL, BIT) GET_BITS(VAL, BIT, BIT)
|
||||
|
||||
enum pdiv_type {
|
||||
PDIV_QLIN,
|
||||
PDIV_POW2
|
||||
};
|
||||
|
||||
struct pll_desc_t {
|
||||
u32 base_offset;
|
||||
u8 divm_shift;
|
||||
u8 divm_width;
|
||||
u8 divn_shift;
|
||||
u8 divn_width;
|
||||
u8 divp_shift;
|
||||
u8 divp_width;
|
||||
pdiv_type ptype;
|
||||
};
|
||||
|
||||
static const pll_desc_t pll_table[] = {
|
||||
{ PLLM_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLMB_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLP_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ PLLA_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ PLLU_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ _PLLD_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ PLLX_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLA1_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLDP_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLD2_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLC4_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLRE_BASE, 0, 8, 8, 8, 16, 4, PDIV_QLIN },
|
||||
{ PLLC_BASE, 0, 8, 10, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLC2_BASE, 0, 8, 10, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLC3_BASE, 0, 8, 10, 8, 20, 5, PDIV_QLIN },
|
||||
};
|
||||
|
||||
static inline u32 clk_read32(u32 offset)
|
||||
{
|
||||
return *(volatile u32 *)(uintptr_t)(board::clkVirtAddr + offset);
|
||||
static inline volatile u32& REG(uintptr_t addr) {
|
||||
return *reinterpret_cast<volatile u32*>(addr);
|
||||
}
|
||||
|
||||
static inline u32 extract(u32 val, u8 shift, u8 width)
|
||||
{
|
||||
return (val >> shift) & ((1u << width) - 1u);
|
||||
}
|
||||
// From jetson nano kernel
|
||||
typedef enum {
|
||||
/* divider = 2 */
|
||||
CLK_PLLX = 5,
|
||||
CLK_PLLM = 2,
|
||||
CLK_PLLMB = 37,
|
||||
/* PLLX & PLLG are backup PLLs for CPU & GPU */
|
||||
/* divider = 1 */
|
||||
CLK_CCLK_G = 18, // A57 CPU cluster
|
||||
CLK_EMC = 36,
|
||||
} PTO_ID; // PLL Test Output Register ID
|
||||
|
||||
static u64 pll_rate_from_desc(const pll_desc_t &pll, u64 osc_hz,
|
||||
bool undivided)
|
||||
{
|
||||
u32 base = clk_read32(pll.base_offset);
|
||||
u32 divm = extract(base, pll.divm_shift, pll.divm_width);
|
||||
u32 divn = extract(base, pll.divn_shift, pll.divn_width);
|
||||
/* See if GM20B clock GPC PLL regs are accessible. */
|
||||
|
||||
if (divm == 0 || divn == 0)
|
||||
return 0;
|
||||
#define PLLX_MISC0 0xE4
|
||||
#define PLLM_MISC2 0x9C
|
||||
|
||||
u64 vco = osc_hz * divn / divm;
|
||||
double ptoGetMHz(PTO_ID pto_id, u32 divider = 1, u32 presel_reg = 0, u32 presel_mask = 0) {
|
||||
u32 pre_val, val, presel_val;
|
||||
|
||||
if (undivided)
|
||||
return vco;
|
||||
|
||||
u32 hw_p = extract(base, pll.divp_shift, pll.divp_width);
|
||||
u32 pdiv;
|
||||
|
||||
if (pll.ptype == PDIV_QLIN)
|
||||
pdiv = (hw_p < 17) ? qlin_hw_to_pdiv[hw_p] : 1;
|
||||
else
|
||||
pdiv = 1u << hw_p;
|
||||
|
||||
return vco / pdiv;
|
||||
}
|
||||
|
||||
static u64 pll_rate_by_offset(u32 base_offset, u64 osc_hz,
|
||||
bool undivided)
|
||||
{
|
||||
for (const auto &pll : pll_table) {
|
||||
if (pll.base_offset == base_offset)
|
||||
return pll_rate_from_desc(pll, osc_hz, undivided);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 getRamClockRatePLLMB()
|
||||
{
|
||||
u32 clk_src = clk_read32(CLK_SOURCE_EMC);
|
||||
u32 src = (clk_src >> 29) & 0x7;
|
||||
u32 div = (clk_src >> 0) & 0xff;
|
||||
|
||||
u32 pll_off;
|
||||
bool undivided = false;
|
||||
|
||||
switch (src) {
|
||||
case EMC_SRC_PLLM:
|
||||
pll_off = PLLM_BASE;
|
||||
break;
|
||||
case EMC_SRC_PLLM_UD:
|
||||
pll_off = PLLM_BASE;
|
||||
undivided = true;
|
||||
break;
|
||||
case EMC_SRC_PLLMB:
|
||||
pll_off = PLLMB_BASE;
|
||||
break;
|
||||
case EMC_SRC_PLLMB_UD:
|
||||
pll_off = PLLMB_BASE;
|
||||
undivided = true;
|
||||
break;
|
||||
case EMC_SRC_PLLP:
|
||||
pll_off = PLLP_BASE;
|
||||
break;
|
||||
case EMC_SRC_PLLP_UD:
|
||||
pll_off = PLLP_BASE;
|
||||
undivided = true;
|
||||
break;
|
||||
case EMC_SRC_PLLC:
|
||||
pll_off = PLLC_BASE;
|
||||
break;
|
||||
case EMC_SRC_CLK_M:
|
||||
return OSC_HZ;
|
||||
default:
|
||||
return 0;
|
||||
if (presel_reg) {
|
||||
val = REG(board::clkVirtAddr + presel_reg);
|
||||
usleep(10);
|
||||
presel_val = val & presel_mask;
|
||||
val &= ~presel_mask;
|
||||
val |= presel_mask;
|
||||
REG(board::clkVirtAddr + presel_reg) = val;
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
u64 pll_hz = pll_rate_by_offset(pll_off, OSC_HZ, undivided);
|
||||
return pll_hz / (div + 2) * 2;
|
||||
constexpr u32 cycle_count = 16;
|
||||
pre_val = REG(board::clkVirtAddr + 0x60);
|
||||
val = BIT(23) | BIT(13) | (cycle_count - 1);
|
||||
val |= pto_id << 14;
|
||||
|
||||
REG(board::clkVirtAddr + 0x60) = val;
|
||||
usleep(10);
|
||||
REG(board::clkVirtAddr + 0x60) = val | BIT(10);
|
||||
usleep(10);
|
||||
REG(board::clkVirtAddr + 0x60) = val;
|
||||
usleep(10);
|
||||
REG(board::clkVirtAddr + 0x60) = val | BIT(9);
|
||||
usleep(500);
|
||||
|
||||
while(REG(board::clkVirtAddr + 0x64) & BIT(31))
|
||||
;
|
||||
|
||||
val = REG(board::clkVirtAddr + 0x64);
|
||||
val &= 0xFFFFFF;
|
||||
val *= divider;
|
||||
|
||||
double rate_hz = (u64)val * 32768. / cycle_count;
|
||||
usleep(10);
|
||||
REG(board::clkVirtAddr + 0x60) = pre_val;
|
||||
usleep(10);
|
||||
|
||||
if (presel_reg) {
|
||||
val = REG(board::clkVirtAddr + presel_reg);
|
||||
usleep(10);
|
||||
val &= ~presel_mask;
|
||||
val |= presel_val;
|
||||
REG(board::clkVirtAddr + presel_reg) = val;
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
return rate_hz;
|
||||
}
|
||||
|
||||
u64 getRamClockRatePLLMB() {
|
||||
// printf("\n"
|
||||
// "EMC: %6.1f MHz\n"
|
||||
// "CCLK_G: %6.1f MHz\n"
|
||||
// "PLLX: %6.1f MHz\n"
|
||||
// "PLLM: %6.1f MHz\n"
|
||||
// "PLLMB: %6.1f MHz\n",
|
||||
// ptoGetMHz(CLK_EMC),
|
||||
// ptoGetMHz(CLK_CCLK_G),
|
||||
// ptoGetMHz(CLK_PLLX, 2, PLLX_MISC0, BIT(22)),
|
||||
// ptoGetMHz(CLK_PLLM, 2, PLLM_MISC2, BIT(8)),
|
||||
// ptoGetMHz(CLK_PLLMB, 2, PLLM_MISC2, BIT(9))
|
||||
// );
|
||||
|
||||
u32 pllmb = ptoGetMHz(CLK_PLLMB, 2, PLLM_MISC2, BIT(9));
|
||||
u32 pllm = ptoGetMHz(CLK_PLLM, 2, PLLM_MISC2, BIT(8));
|
||||
return pllmb == 0 ? pllm : pllmb; // pllmb is zeroed out at times, fallback to pllm
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Souldbminer
|
||||
*
|
||||
* Copyright (c) KazushiMe
|
||||
*
|
||||
* 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 <cstdint>
|
||||
#include <switch.h>
|
||||
@@ -6,16 +25,5 @@
|
||||
#include <registers.h>
|
||||
namespace pllmb {
|
||||
|
||||
typedef enum PLLSource {
|
||||
EMC_SRC_PLLM = 0,
|
||||
EMC_SRC_PLLC = 1,
|
||||
EMC_SRC_PLLP = 2,
|
||||
EMC_SRC_CLK_M = 3,
|
||||
EMC_SRC_PLLM_UD = 4,
|
||||
EMC_SRC_PLLMB_UD = 5,
|
||||
EMC_SRC_PLLMB = 6,
|
||||
EMC_SRC_PLLP_UD = 7
|
||||
} PLLSource;
|
||||
|
||||
u64 getRamClockRatePLLMB();
|
||||
}
|
||||
@@ -286,7 +286,7 @@ namespace clockManager {
|
||||
if (!targetHz) {
|
||||
targetHz = config::GetAutoClockHz(gContext.applicationId, HocClkModule_GPU, gContext.profile, false);
|
||||
if (!targetHz) {
|
||||
targetHz = config::GetAutoClockHz(GLOBAL_PROFILE_ID, HocClkModule_GPU, gContext.profile, false);
|
||||
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_GPU, gContext.profile, false);
|
||||
}
|
||||
}
|
||||
u32 maxHz = GetMaxAllowedHz(HocClkModule_GPU, gContext.profile);
|
||||
@@ -357,7 +357,7 @@ namespace clockManager {
|
||||
if (!targetHz) {
|
||||
targetHz = config::GetAutoClockHz(gContext.applicationId, (HocClkModule)module, gContext.profile, returnRaw);
|
||||
if (!targetHz)
|
||||
targetHz = config::GetAutoClockHz(GLOBAL_PROFILE_ID, (HocClkModule)module, gContext.profile, returnRaw);
|
||||
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, (HocClkModule)module, gContext.profile, returnRaw);
|
||||
}
|
||||
|
||||
if (module == HocClkModule_Governor) {
|
||||
@@ -528,7 +528,7 @@ namespace clockManager {
|
||||
if (!targetHz) {
|
||||
targetHz = config::GetAutoClockHz(gContext.applicationId, HocClkModule_Display, gContext.profile, true);
|
||||
if (!targetHz)
|
||||
targetHz = config::GetAutoClockHz(GLOBAL_PROFILE_ID, HocClkModule_Display, gContext.profile, true);
|
||||
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_Display, gContext.profile, true);
|
||||
}
|
||||
|
||||
if (board::GetConsoleType() != HocClkConsoleType_Hoag)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "governor.hpp"
|
||||
#include "process_management.hpp"
|
||||
#include <hocclk/clock_manager.h>
|
||||
namespace governor {
|
||||
|
||||
#define POLL_NS 5'000'000 // 5 ms – governor poll rate
|
||||
@@ -43,7 +44,7 @@ namespace governor {
|
||||
if (!tempTargetHz) {
|
||||
tempTargetHz = config::GetAutoClockHz(clockManager::gContext.applicationId, HocClkModule_Governor, clockManager::gContext.profile, true);
|
||||
if (!tempTargetHz)
|
||||
tempTargetHz = config::GetAutoClockHz(GLOBAL_PROFILE_ID, HocClkModule_Governor, clockManager::gContext.profile, true);
|
||||
tempTargetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_Governor, clockManager::gContext.profile, true);
|
||||
}
|
||||
|
||||
auto resolve = [](u8 app, u8 temp) -> u8 {
|
||||
@@ -107,7 +108,7 @@ namespace governor {
|
||||
clockManager::gContext.profile, false);
|
||||
if (!hz)
|
||||
hz = config::GetAutoClockHz(
|
||||
GLOBAL_PROFILE_ID, module,
|
||||
HOCCLK_GLOBAL_PROFILE_TID, module,
|
||||
clockManager::gContext.profile, false);
|
||||
return hz;
|
||||
}
|
||||
@@ -295,7 +296,7 @@ namespace governor {
|
||||
if (!targetHz) {
|
||||
targetHz = config::GetAutoClockHz(clockManager::gContext.applicationId, HocClkModule_Display, clockManager::gContext.profile, false);
|
||||
if (!targetHz)
|
||||
targetHz = config::GetAutoClockHz(GLOBAL_PROFILE_ID, HocClkModule_Display, clockManager::gContext.profile, false);
|
||||
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_Display, clockManager::gContext.profile, false);
|
||||
}
|
||||
|
||||
u8 maxDisplay;
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace kip {
|
||||
CUST_WRITE_FIELD_BATCH(&table, marikoEmcMaxClock, config::GetConfigValue(KipConfigValue_marikoEmcMaxClock));
|
||||
CUST_WRITE_FIELD_BATCH(&table, marikoEmcVddqVolt, config::GetConfigValue(KipConfigValue_marikoEmcVddqVolt));
|
||||
CUST_WRITE_FIELD_BATCH(&table, emcDvbShift, config::GetConfigValue(KipConfigValue_emcDvbShift));
|
||||
CUST_WRITE_FIELD_BATCH(&table, marikoSocVmax, config::GetConfigValue(KipConfigValue_marikoSocVmax));
|
||||
|
||||
CUST_WRITE_FIELD_BATCH(&table, t1_tRCD, config::GetConfigValue(KipConfigValue_t1_tRCD));
|
||||
CUST_WRITE_FIELD_BATCH(&table, t2_tRP, config::GetConfigValue(KipConfigValue_t2_tRP));
|
||||
@@ -208,6 +209,7 @@ namespace kip {
|
||||
configValues.values[KipConfigValue_marikoEmcMaxClock] = cust_get_mariko_emc_max(&table);
|
||||
configValues.values[KipConfigValue_marikoEmcVddqVolt] = cust_get_mariko_emc_vddq(&table);
|
||||
configValues.values[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table);
|
||||
configValues.values[KipConfigValue_marikoSocVmax] = cust_get_marikoSocVmax(&table);
|
||||
|
||||
configValues.values[KipConfigValue_t1_tRCD] = cust_get_tRCD(&table);
|
||||
configValues.values[KipConfigValue_t2_tRP] = cust_get_tRP(&table);
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace kip {
|
||||
u32 marikoEmcMaxClock;
|
||||
u32 marikoEmcVddqVolt;
|
||||
u32 emcDvbShift;
|
||||
u32 marikoSocVmax;
|
||||
|
||||
// advanced config
|
||||
u32 t1_tRCD;
|
||||
u32 t2_tRP;
|
||||
@@ -266,6 +268,7 @@ namespace kip {
|
||||
static inline bool cust_set_common_gpu_offset(const char* p, u32 v) { CUST_WRITE_FIELD(p, commonGpuVoltOffset, v); }
|
||||
static inline bool cust_set_gpu_speedo(const char* p, u32 v) { CUST_WRITE_FIELD(p, gpuSpeedo, v); }
|
||||
static inline bool cust_set_marikoCpuMaxClock(const char* p, u32 v) { CUST_WRITE_FIELD(p, marikoCpuMaxClock, v); }
|
||||
static inline bool cust_set_marikoSocVmax(const char* p, u32 v) { CUST_WRITE_FIELD(p, marikoSocVmax, v); }
|
||||
|
||||
/* GPU VOLT ARRAY HELPERS */
|
||||
static inline bool cust_set_erista_gpu_volt(const char* p, int idx, u32 v) {
|
||||
@@ -354,6 +357,7 @@ namespace kip {
|
||||
static inline u32 cust_get_common_gpu_offset(const CustomizeTable* t) { return CUST_GET_FIELD(t, commonGpuVoltOffset); }
|
||||
static inline u32 cust_get_gpu_speedo(const CustomizeTable* t) { return CUST_GET_FIELD(t, gpuSpeedo); }
|
||||
static inline u32 cust_get_marikoCpuMaxClock(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoCpuMaxClock); }
|
||||
static inline u32 cust_get_marikoSocVmax(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoSocVmax); }
|
||||
|
||||
static inline u32 cust_get_erista_gpu_volt(const CustomizeTable* t, int idx) {
|
||||
if (!t || idx < 0 || idx >= 27) return 0;
|
||||
|
||||
4
build.sh
4
build.sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
SRC="Source/Atmosphere/stratosphere/loader/source/oc"
|
||||
DEST="build/stratosphere/loader/source/oc"
|
||||
SRC="Source/Atmosphere/stratosphere/loader/"
|
||||
DEST="build/stratosphere/loader/"
|
||||
mkdir -p "dist/atmosphere/kips/"
|
||||
mkdir -p "$DEST"
|
||||
|
||||
|
||||
16
dist/README.md
vendored
16
dist/README.md
vendored
@@ -78,21 +78,21 @@ Refer to COMPILATION.md
|
||||
---
|
||||
## Clock table
|
||||
|
||||
### MEM clocks
|
||||
### MEM clocks (mhz)
|
||||
* 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.
|
||||
* 2133 → Mariko JEDEC standard max (4266 Modules)
|
||||
* 1996 → JEDEC standard
|
||||
* 1866 → Mariko JEDEC standard max (3733 Modules)
|
||||
* 1600 → official docked, boost mode, erista safe max, JEDEC.
|
||||
* 1331 → official handheld, JEDEC.
|
||||
* 1065
|
||||
* 800
|
||||
* 665
|
||||
|
||||
### CPU clocks
|
||||
### CPU clocks (mhz)
|
||||
* 2703 → mariko absolute max, dangerous
|
||||
* 2601 → unsafe
|
||||
* 2499
|
||||
@@ -115,16 +115,16 @@ Refer to COMPILATION.md
|
||||
* 714
|
||||
* 612 → sleep mode
|
||||
|
||||
### GPU clocks
|
||||
### GPU clocks (mhz)
|
||||
* 1536 → absolute max clock on mariko. very dangerous
|
||||
* 1459
|
||||
* 1382
|
||||
* 1305
|
||||
* 1267 → NVIDIA T214 rating
|
||||
* 1267 → NVIDIA T214(mariko) 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
|
||||
* 998 → NVIDIA T210 (erista) rating
|
||||
* 960 (erista only) → erista slt/hiopt safe max clock
|
||||
* 921 → erista no UV max clock
|
||||
* 844
|
||||
|
||||
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.
198
dist/config/horizon-oc/lang/lang/es.json
vendored
198
dist/config/horizon-oc/lang/lang/es.json
vendored
@@ -2,140 +2,140 @@
|
||||
"Information": "Información",
|
||||
"IDDQ:": "IDDQ:",
|
||||
"Module: ": "Módulo:",
|
||||
"sys-dock status:": "estado del sys-dock:",
|
||||
"sys-dock status:": "Estado de sys-dock:",
|
||||
"SaltyNX status:": "Estado de SaltyNX:",
|
||||
"RR Display status:": "Estado de visualización RR:",
|
||||
"Wafer Position:": "Posición de la oblea:",
|
||||
"RR Display status:": "Estado de pantalla RR:",
|
||||
"Wafer Position:": "Posición del wafer:",
|
||||
"Credits": "Créditos",
|
||||
"Developers": "Desarrolladores",
|
||||
"Contributors": "Colaboradores",
|
||||
"Testers": "Probadores",
|
||||
"Special Thanks": "agradecimiento especial",
|
||||
"Testers": "Testers",
|
||||
"Special Thanks": "Agradecimientos especiales",
|
||||
"Unknown": "Desconocido",
|
||||
"Installed": "Instalado",
|
||||
"Not Installed": "No instalado",
|
||||
"X: %u Y: %u": "X: %u Y: %u",
|
||||
"THE BEER-WARE LICENSE": "LA LICENCIA DE CERVEZA",
|
||||
"THE BEER-WARE LICENSE": "LICENCIA BEER-WARE",
|
||||
"Default": "Predeterminado",
|
||||
"Do Not Override": "No anular",
|
||||
"Disabled": "Discapacitado",
|
||||
"Enabled": "Habilitado",
|
||||
"Do Not Override": "No sobrescribir",
|
||||
"Disabled": "Desactivado",
|
||||
"Enabled": "Activado",
|
||||
" \\ue0e3 Reset": "\\ue0e3 Restablecer",
|
||||
"Display": "Pantalla",
|
||||
"Application changed\\n\\n": "Aplicación modificada\\n\\n",
|
||||
"The running application changed\\n\\n": "La aplicación en ejecución cambió\\n\\n",
|
||||
"while editing was going on.": "mientras se realizaba la edición.",
|
||||
"Board": "tablero",
|
||||
"Application changed\\n\\n": "Aplicación cambiada\\n\\n",
|
||||
"The running application changed\\n\\n": "La aplicación en ejecución ha cambiado\\n\\n",
|
||||
"while editing was going on.": "mientras se estaba editando.",
|
||||
"Board": "Placa",
|
||||
"%u.%u%u mV": "%u.%u%u mV",
|
||||
"Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al módulo del sistema hoc-clk.\\n\\n",
|
||||
"Please make sure everything is\\n\\n": "Por favor asegúrese de que todo esté\\n\\n",
|
||||
"correctly installed and enabled.": "correctamente instalado y habilitado.",
|
||||
"Fatal error": "error fatal",
|
||||
"Temporary Overrides ": "Anulaciones temporales",
|
||||
"Sleep Mode": "Modo de suspensión",
|
||||
"Stock": "Valores",
|
||||
"Dev OC": "Desarrollador OC",
|
||||
"Boost Mode": "Modo de impulso",
|
||||
"Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al sysmodule hoc-clk.\\n\\n",
|
||||
"Please make sure everything is\\n\\n": "Asegúrate de que todo esté\\n\\n",
|
||||
"correctly installed and enabled.": "correctamente instalado y activado.",
|
||||
"Fatal error": "Error fatal",
|
||||
"Temporary Overrides ": "Ajustes temporales",
|
||||
"Sleep Mode": "Modo reposo",
|
||||
"Stock": "Valores de fábrica",
|
||||
"Dev OC": "OC de desarrollo",
|
||||
"Boost Mode": "Modo boost",
|
||||
"Safe Max": "Máximo seguro",
|
||||
"Unsafe Max": "Máximo inseguro",
|
||||
"Unsafe Max": "Máximo no seguro",
|
||||
"Absolute Max": "Máximo absoluto",
|
||||
"Handheld Safe Max": "Caja fuerte de mano máx.",
|
||||
"Enable": "Habilitar",
|
||||
"Handheld Safe Max": "Máximo seguro en portátil",
|
||||
"Enable": "Activar",
|
||||
"Edit App Profile": "Editar perfil de aplicación",
|
||||
"Edit Global Profile": "Editar perfil global",
|
||||
"Temporary Overrides": "Anulaciones temporales",
|
||||
"Temporary Overrides": "Ajustes temporales",
|
||||
"Settings": "Configuración",
|
||||
"About": "Acerca de",
|
||||
"Compiling with minimal features": "Compilando con características mínimas",
|
||||
"General Settings": "Configuraciones generales",
|
||||
"Governor Settings": "Configuración del gobernador",
|
||||
"Safety Settings": "Configuraciones de seguridad",
|
||||
"Save KIP Settings": "Guardar configuración de KIP",
|
||||
"Compiling with minimal features": "Compilado con funciones mínimas",
|
||||
"General Settings": "Configuración general",
|
||||
"Governor Settings": "Configuración del governor",
|
||||
"Safety Settings": "Configuración de seguridad",
|
||||
"Save KIP Settings": "Guardar configuración KIP",
|
||||
"RAM Settings": "Configuración de RAM",
|
||||
"CPU Settings": "Configuración de la CPU",
|
||||
"CPU Settings": "Configuración de CPU",
|
||||
"GPU Settings": "Configuración de GPU",
|
||||
"Display Settings": "Configuración de pantalla",
|
||||
"Experimental": "Experimental",
|
||||
"GPU Scheduling Override Method": "Método de anulación de programación de GPU",
|
||||
"can be dangerous and may cause": "puede ser peligroso y puede causar",
|
||||
"damage to your battery or charger!": "¡Daños a su batería o cargador!",
|
||||
"Charge Current Override": "Anulación de corriente de carga",
|
||||
"GPU Scheduling Override Method": "Método de sobrescritura del scheduling de GPU",
|
||||
"can be dangerous and may cause": "puede ser peligroso y causar",
|
||||
"damage to your battery or charger!": "daños a la batería o al cargador.",
|
||||
"Charge Current Override": "Sobrescritura de corriente de carga",
|
||||
"RAM Voltage Display Mode": "Modo de visualización de voltaje de RAM",
|
||||
"Polling Interval": "Intervalo de sondeo",
|
||||
"CPU Governor Minimum Frequency": "Frecuencia mínima del gobernador de CPU",
|
||||
"refresh rates may cause stress": "Las frecuencias de actualización pueden causar estrés.",
|
||||
"or damage to your display! ": "o daños a su pantalla!",
|
||||
"Proceed at your own risk!": "¡Continúe bajo su propio riesgo!",
|
||||
"Max Handheld Display": "Pantalla portátil máxima",
|
||||
"Display Clock": "Reloj de pantalla",
|
||||
"Official Rating": "Calificación oficial",
|
||||
"CPU Governor Minimum Frequency": "Frecuencia mínima del governor de CPU",
|
||||
"refresh rates may cause stress": "las tasas de refresco pueden causar estrés",
|
||||
"or damage to your display! ": "o dañar la pantalla.",
|
||||
"Proceed at your own risk!": "¡Úsalo bajo tu propio riesgo!",
|
||||
"Max Handheld Display": "Frecuencia máxima de pantalla en portátil",
|
||||
"Display Clock": "Frecuencia de pantalla",
|
||||
"Official Rating": "Valor oficial",
|
||||
"TDP Threshold": "Umbral de TDP",
|
||||
"Power": "poder",
|
||||
"Thermal Throttle Limit": "Límite del acelerador térmico",
|
||||
"HP Mode": "Modo HP",
|
||||
"Power": "Potencia",
|
||||
"Thermal Throttle Limit": "Límite de thermal throttling",
|
||||
"HP Mode": "Modo alto rendimiento",
|
||||
"Default (Mariko)": "Predeterminado (Mariko)",
|
||||
"Default (Erista)": "Predeterminado (Erista)",
|
||||
"Rating": "Calificación",
|
||||
"Safe Max (Mariko)": "Max seguro (Mariko)",
|
||||
"Safe Max (Erista)": "Safe Max (Erista)",
|
||||
"RAM VDD2 Voltage": "Voltaje RAM VDD2",
|
||||
"Voltage": "voltaje",
|
||||
"RAM VDDQ Voltage": "Voltaje RAM VDDQ",
|
||||
"RAM Frequency Editor": "Editor de frecuencia RAM",
|
||||
"JEDEC.": "JEDEC.",
|
||||
"High speedo needed!": "¡Se necesita alta velocidad!",
|
||||
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (Necesita Speedo/PLL extremo)",
|
||||
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (Necesita Speedo/PLL extremo)",
|
||||
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (Necesita Speedo/PLL extremo)",
|
||||
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (Necesita Speedo/PLL ridículo)",
|
||||
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (Necesita Speedo/PLL ridículo)",
|
||||
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (Necesita Speedo/PLL ridículo)",
|
||||
"Ram Max Clock": "Ram Max Reloj",
|
||||
"RAM Latency Editor": "Editor de latencia de RAM",
|
||||
"RAM Timing Reductions": "Reducciones de tiempo de RAM",
|
||||
"Memory Timings": "Tiempos de memoria",
|
||||
"Rating": "Valor",
|
||||
"Safe Max (Mariko)": "Máximo seguro (Mariko)",
|
||||
"Safe Max (Erista)": "Máximo seguro (Erista)",
|
||||
"RAM VDD2 Voltage": "Voltaje VDD2 de RAM",
|
||||
"Voltage": "Voltaje",
|
||||
"RAM VDDQ Voltage": "Voltaje VDDQ de RAM",
|
||||
"RAM Frequency Editor": "Editor de frecuencia de RAM",
|
||||
"JEDEC.": "JEDEC",
|
||||
"High speedo needed!": "¡Se necesita alto speedo!",
|
||||
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (requiere Speedo/PLL extremo)",
|
||||
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (requiere Speedo/PLL extremo)",
|
||||
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (requiere Speedo/PLL extremo)",
|
||||
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (requiere Speedo/PLL muy alto)",
|
||||
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (requiere Speedo/PLL muy alto)",
|
||||
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (requiere Speedo/PLL muy alto)",
|
||||
"Ram Max Clock": "Frecuencia máxima de RAM",
|
||||
"RAM Latency Editor": "Editor de latencias de RAM",
|
||||
"RAM Timing Reductions": "Reducción de timings de RAM",
|
||||
"Memory Timings": "Timings de memoria",
|
||||
"Advanced": "Avanzado",
|
||||
"t6 tRTW Fine Tune": "t6 tRTW Ajuste fino",
|
||||
"t6 tRTW Fine Tune": "Ajuste fino t6 tRTW",
|
||||
"tRTW Fine Tune": "Ajuste fino tRTW",
|
||||
"t7 tWTR Fine Tune": "t7 tWTR Ajuste fino",
|
||||
"tWTR Fine Tune": "Ajuste fino de tWTR",
|
||||
"Memory Latencies": "Latencias de la memoria",
|
||||
"Read Latency": "Leer latencia",
|
||||
"t7 tWTR Fine Tune": "Ajuste fino t7 tWTR",
|
||||
"tWTR Fine Tune": "Ajuste fino tWTR",
|
||||
"Memory Latencies": "Latencias de memoria",
|
||||
"Read Latency": "Latencia de lectura",
|
||||
"Write Latency": "Latencia de escritura",
|
||||
"CPU Boost Clock": "Reloj de aumento de CPU",
|
||||
"CPU UV": "procesador ultravioleta",
|
||||
"CPU Boost Clock": "Frecuencia boost de CPU",
|
||||
"CPU UV": "Undervolt de CPU",
|
||||
"CPU Unlock": "Desbloqueo de CPU",
|
||||
"CPU VMIN": "CPU VMIN",
|
||||
"CPU Max Voltage": "Voltaje máximo de la CPU",
|
||||
"CPU Max Clock": "Reloj máximo de CPU",
|
||||
"Extreme UV Table": "Mesa UV extrema",
|
||||
"CPU UV Table": "Tabla UV de CPU",
|
||||
"CPU Low UV": "CPU baja radiación ultravioleta",
|
||||
"CPU High UV": "CPU alta UV",
|
||||
"CPU VMIN": "VMIN de CPU",
|
||||
"CPU Max Voltage": "Voltaje máximo de CPU",
|
||||
"CPU Max Clock": "Frecuencia máxima de CPU",
|
||||
"Extreme UV Table": "Tabla de undervolt extrema",
|
||||
"CPU UV Table": "Tabla de undervolt de CPU",
|
||||
"CPU Low UV": "Undervolt bajo de CPU",
|
||||
"CPU High UV": "Undervolt alto de CPU",
|
||||
"CPU Low VMIN": "VMIN bajo de CPU",
|
||||
"CPU High VMIN": "VMIN alto de CPU",
|
||||
"No Undervolt": "Sin subvoltaje",
|
||||
"SLT Table": "Mesa TR",
|
||||
"No Undervolt": "Sin undervolt",
|
||||
"SLT Table": "Tabla SLT",
|
||||
"HiOPT Table": "Tabla HiOPT",
|
||||
"GPU Undervolt Table": "Tabla de subvoltaje de GPU",
|
||||
"GPU Undervolt Table": "Tabla de undervolt de GPU",
|
||||
"GPU Minimum Voltage": "Voltaje mínimo de GPU",
|
||||
"Calculate GPU Vmin": "Calcular GPU Vmin",
|
||||
"GPU VMIN": "GPU VMIN",
|
||||
"Calculate GPU Vmin": "Calcular Vmin de GPU",
|
||||
"GPU VMIN": "VMIN de GPU",
|
||||
"GPU Maximum Voltage": "Voltaje máximo de GPU",
|
||||
"GPU Voltage Offset": "Compensación de voltaje de GPU",
|
||||
"Do not override": "no anular",
|
||||
"Enabled (Default)": "Habilitado (predeterminado)",
|
||||
"96.6% limit": "límite del 96,6%",
|
||||
"99.7% limit": "límite del 99,7%",
|
||||
"GPU Scheduling Override": "Anulación de programación de GPU",
|
||||
"Official Service": "Servicio Oficial",
|
||||
"GPU DVFS Mode": "Modo GPU DVFS",
|
||||
"GPU DVFS Offset": "Compensación DVFS de GPU",
|
||||
"GPU Voltage Offset": "Offset de voltaje de GPU",
|
||||
"Do not override": "No sobrescribir",
|
||||
"Enabled (Default)": "Activado (predeterminado)",
|
||||
"96.6% limit": "Límite 96,6%",
|
||||
"99.7% limit": "Límite 99,7%",
|
||||
"GPU Scheduling Override": "Sobrescritura de scheduling de GPU",
|
||||
"Official Service": "Servicio oficial",
|
||||
"GPU DVFS Mode": "Modo DVFS de GPU",
|
||||
"GPU DVFS Offset": "Offset DVFS de GPU",
|
||||
"GPU Voltage Table": "Tabla de voltaje de GPU",
|
||||
"GPU Custom Table (mV)": "Tabla personalizada de GPU (mV)",
|
||||
"1075MHz without UV, 1152MHz on SLT": "1075MHz sin UV, 1152MHz en SLT",
|
||||
"or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar",
|
||||
"permanent damage to your Switch!": "¡Daño permanente a tu Switch!",
|
||||
"921MHz without UV and 960MHz on": "921MHz sin UV y 960MHz encendido",
|
||||
"SLT or HiOPT can cause ": "SLT o HiOPT pueden causar"
|
||||
}
|
||||
"1075MHz without UV, 1152MHz on SLT": "1075MHz sin undervolt, 1152MHz en SLT",
|
||||
"or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar ",
|
||||
"permanent damage to your Switch!": "¡daño permanente a tu Switch!",
|
||||
"921MHz without UV and 960MHz on": "921MHz sin undervolt y 960MHz en",
|
||||
"SLT or HiOPT can cause ": "SLT o HiOPT pueden causar "
|
||||
}
|
||||
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