Configurable CPU Boost Freq

This commit is contained in:
KazushiM
2022-03-17 12:15:46 +08:00
parent 4d76b83b95
commit 6585abfcb8
8 changed files with 118 additions and 58 deletions

View File

@@ -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:

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -66,8 +66,10 @@ typedef enum
typedef struct
{
bool systemCoreBoostCPU;
bool gotBoostCPUFreq;
ReverseNXMode reverseNXMode;
uint32_t maxMEMFreq;
uint32_t boostCPUFreq;
} SysClkOcExtra;
typedef struct

View File

@@ -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

View File

@@ -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();