Configurable CPU Boost Freq
This commit is contained in:
@@ -13,12 +13,16 @@ static const volatile CustomizeTable C = {
|
||||
* - Max Clock in kHz:
|
||||
* Default: 1785000
|
||||
* >= 2193000 will enable overvolting (> 1120 mV)
|
||||
* - Boost Clock in kHz:
|
||||
* Default: 1785000
|
||||
* Boost clock will be applied when applications request higher CPU frequency for quicker loading.
|
||||
* - Max Voltage in mV:
|
||||
* Default voltage: 1120
|
||||
* Haven't tested anything higher than 1220.
|
||||
*/
|
||||
.marikoCpuMaxClock = 2397000,
|
||||
.marikoCpuMaxVolt = 1220,
|
||||
.marikoCpuMaxClock = 2397000,
|
||||
.marikoCpuBoostClock = 1785000,
|
||||
.marikoCpuMaxVolt = 1220,
|
||||
|
||||
/* Mariko GPU:
|
||||
* - Max Clock in kHz:
|
||||
|
||||
@@ -1150,22 +1150,31 @@ namespace ams::ldr::oc {
|
||||
return;
|
||||
#endif
|
||||
|
||||
perf_conf_entry* confTable = 0;
|
||||
constexpr u32 entryCnt = 16;
|
||||
constexpr u32 memPtmLimit = 1600'000'000;
|
||||
constexpr u32 memPtmAlt = 1331'200'000;
|
||||
constexpr u32 memPtmClamp = 1065'600'000;
|
||||
const u32 memPtmMax = C.marikoEmcMaxClock * 1000;
|
||||
perf_conf_entry* confTable = 0;
|
||||
constexpr u32 entryCnt = 16;
|
||||
constexpr u32 cpuPtmDefault = 1020'000'000;
|
||||
constexpr u32 cpuPtmDevOC = 1224'000'000;
|
||||
constexpr u32 cpuPtmBoost = 1785'000'000;
|
||||
const u32 cpuPtmBoostNew = C.marikoCpuBoostClock * 1000;
|
||||
constexpr u32 memPtmLimit = 1600'000'000;
|
||||
constexpr u32 memPtmAlt = 1331'200'000;
|
||||
constexpr u32 memPtmClamp = 1065'600'000;
|
||||
const u32 memPtmMax = C.marikoEmcMaxClock * 1000;
|
||||
|
||||
for (uintptr_t ptr = mapped_nso;
|
||||
ptr <= mapped_nso + nso_size - sizeof(perf_conf_entry) * entryCnt;
|
||||
ptr += sizeof(u32))
|
||||
{
|
||||
u32 value = *(reinterpret_cast<u32 *>(ptr));
|
||||
u32* ptr32 = reinterpret_cast<u32 *>(ptr);
|
||||
u32 value = *(ptr32);
|
||||
|
||||
if (value == memPtmLimit)
|
||||
if (value == cpuPtmDefault)
|
||||
{
|
||||
confTable = reinterpret_cast<perf_conf_entry *>(ptr - offsetof(perf_conf_entry, emc_freq_1));
|
||||
u32 value_next = *(ptr32 + 1);
|
||||
if (value_next != cpuPtmDefault)
|
||||
continue;
|
||||
|
||||
confTable = reinterpret_cast<perf_conf_entry *>(ptr - offsetof(perf_conf_entry, cpu_freq_1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1179,24 +1188,44 @@ namespace ams::ldr::oc {
|
||||
{
|
||||
perf_conf_entry* entry_current = confTable + i;
|
||||
|
||||
if (entry_current->emc_freq_1 != entry_current->emc_freq_2) {
|
||||
LOGGING("@%p: emc_freq_1(%u) != emc_freq_2(%u)", &(entry_current->emc_freq_1), entry_current->emc_freq_1, entry_current->emc_freq_2);
|
||||
if (entry_current->cpu_freq_1 != entry_current->cpu_freq_2 ||
|
||||
entry_current->gpu_freq_1 != entry_current->gpu_freq_2 ||
|
||||
entry_current->emc_freq_1 != entry_current->emc_freq_2)
|
||||
{
|
||||
LOGGING("@%p: Invalid confTable entry", &entry_current);
|
||||
CRASH();
|
||||
}
|
||||
|
||||
switch (entry_current->cpu_freq_1)
|
||||
{
|
||||
case cpuPtmBoost:
|
||||
PatchOffset(&(entry_current->cpu_freq_1), cpuPtmBoostNew);
|
||||
PatchOffset(&(entry_current->cpu_freq_2), cpuPtmBoostNew);
|
||||
LOGGING("0x%x: CPU: Boost Freq", entry_current->conf_id);
|
||||
break;
|
||||
case cpuPtmDefault:
|
||||
case cpuPtmDevOC:
|
||||
break;
|
||||
default:
|
||||
LOGGING("Unknown CPU Freq: %u @%p!", entry_current->cpu_freq_1, &(entry_current->cpu_freq_1));
|
||||
CRASH();
|
||||
}
|
||||
|
||||
switch (entry_current->emc_freq_1)
|
||||
{
|
||||
case memPtmLimit:
|
||||
PatchOffset(&(entry_current->emc_freq_1), memPtmMax);
|
||||
PatchOffset(&(entry_current->emc_freq_2), memPtmMax);
|
||||
LOGGING("0x%x: MEM: Max Freq", entry_current->conf_id);
|
||||
break;
|
||||
case memPtmAlt:
|
||||
case memPtmClamp:
|
||||
PatchOffset(&(entry_current->emc_freq_1), memPtmLimit);
|
||||
PatchOffset(&(entry_current->emc_freq_2), memPtmLimit);
|
||||
LOGGING("0x%x: MEM: Alt Freq", entry_current->conf_id);
|
||||
break;
|
||||
default:
|
||||
LOGGING("Wrong mem freq: %u @%p!", entry_current->emc_freq_1, &(entry_current->emc_freq_1));
|
||||
LOGGING("Unknown MEM Freq: %u @%p!", entry_current->emc_freq_1, &(entry_current->emc_freq_1));
|
||||
CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define CUST_REV 1
|
||||
#define CUST_REV 2
|
||||
#include "mtc_timing_table.hpp"
|
||||
|
||||
namespace ams::ldr::oc {
|
||||
@@ -31,6 +31,7 @@ namespace ams::ldr::oc {
|
||||
u16 custRev = CUST_REV;
|
||||
u16 mtcConf = AUTO_ADJ_MARIKO_SAFE;
|
||||
u32 marikoCpuMaxClock;
|
||||
u32 marikoCpuBoostClock;
|
||||
u32 marikoCpuMaxVolt;
|
||||
u32 marikoGpuMaxClock;
|
||||
u32 marikoEmcMaxClock;
|
||||
|
||||
@@ -66,8 +66,10 @@ typedef enum
|
||||
typedef struct
|
||||
{
|
||||
bool systemCoreBoostCPU;
|
||||
bool gotBoostCPUFreq;
|
||||
ReverseNXMode reverseNXMode;
|
||||
uint32_t maxMEMFreq;
|
||||
uint32_t boostCPUFreq;
|
||||
} SysClkOcExtra;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -59,8 +59,10 @@ ClockManager::ClockManager()
|
||||
|
||||
this->oc = new SysClkOcExtra;
|
||||
this->oc->systemCoreBoostCPU = false;
|
||||
this->oc->gotBoostCPUFreq = false;
|
||||
this->oc->reverseNXMode = ReverseNX_NotFound;
|
||||
this->oc->maxMEMFreq = 0;
|
||||
this->oc->boostCPUFreq = 1785'000'000;
|
||||
}
|
||||
|
||||
ClockManager::~ClockManager()
|
||||
@@ -73,7 +75,13 @@ ClockManager::~ClockManager()
|
||||
bool ClockManager::IsCpuBoostMode()
|
||||
{
|
||||
std::uint32_t confId = this->context->perfConfId;
|
||||
return (confId == 0x92220009 || confId == 0x9222000A);
|
||||
bool isCpuBoostMode = (confId == 0x92220009 || confId == 0x9222000A);
|
||||
if (isCpuBoostMode && !this->oc->gotBoostCPUFreq)
|
||||
{
|
||||
this->oc->gotBoostCPUFreq = true;
|
||||
this->oc->boostCPUFreq = std::max(this->context->freqs[SysClkModule_CPU], this->oc->boostCPUFreq);
|
||||
}
|
||||
return isCpuBoostMode;
|
||||
}
|
||||
|
||||
bool ClockManager::IsReverseNXModeValid()
|
||||
@@ -158,8 +166,8 @@ uint32_t ClockManager::GetHz(SysClkModule module)
|
||||
|
||||
if (module == SysClkModule_CPU)
|
||||
{
|
||||
if (this->oc->systemCoreBoostCPU && hz < CPU_BOOST_FREQ)
|
||||
return CPU_BOOST_FREQ;
|
||||
if (this->oc->systemCoreBoostCPU && hz < this->oc->boostCPUFreq)
|
||||
return this->oc->boostCPUFreq;
|
||||
else if (!hz)
|
||||
/* Prevent crash when hz = 0 in SetHz(0), trigger RefreshContext() and Tick() */
|
||||
return 1020'000'000;
|
||||
@@ -180,8 +188,8 @@ void ClockManager::Tick()
|
||||
|
||||
if (hz && hz != this->context->freqs[module])
|
||||
{
|
||||
// Skip setting CPU or GPU clocks in CpuBoostMode if CPU <= 1963.5MHz or GPU >= 76.8MHz
|
||||
if (IsCpuBoostMode() && ((module == SysClkModule_CPU && hz <= CPU_BOOST_FREQ) || module == SysClkModule_GPU))
|
||||
// Skip setting CPU or GPU clocks in CpuBoostMode if CPU <= boostCPUFreq or GPU >= 76.8MHz
|
||||
if (IsCpuBoostMode() && ((module == SysClkModule_CPU && hz <= this->oc->boostCPUFreq) || module == SysClkModule_GPU))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -204,7 +212,7 @@ void ClockManager::WaitForNextTick()
|
||||
if ( isAutoBoostEnabled
|
||||
&& this->context->realProfile != SysClkProfile_Handheld
|
||||
&& this->context->enabled
|
||||
&& this->context->freqs[SysClkModule_CPU] <= CPU_BOOST_FREQ)
|
||||
&& this->context->freqs[SysClkModule_CPU] <= this->oc->boostCPUFreq)
|
||||
{
|
||||
uint64_t systemCoreIdleTickPrev = 0, systemCoreIdleTickNext = 0;
|
||||
svcGetInfo(&systemCoreIdleTickPrev, InfoType_IdleTickCount, INVALID_HANDLE, 3);
|
||||
@@ -237,7 +245,7 @@ void ClockManager::WaitForNextTick()
|
||||
}
|
||||
else if (!systemCoreBoostCPUPrevState && this->oc->systemCoreBoostCPU)
|
||||
{
|
||||
Clocks::SetHz(SysClkModule_CPU, CPU_BOOST_FREQ);
|
||||
Clocks::SetHz(SysClkModule_CPU, this->oc->boostCPUFreq);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -47,7 +47,6 @@ class ClockManager
|
||||
std::uint64_t lastCsvWriteNs;
|
||||
|
||||
SysClkOcExtra *oc;
|
||||
const uint32_t CPU_BOOST_FREQ = 1785'000'000;
|
||||
|
||||
bool IsCpuBoostMode();
|
||||
bool IsReverseNXModeValid();
|
||||
|
||||
Reference in New Issue
Block a user