1.5.1
This commit is contained in:
@@ -62,7 +62,7 @@ ClockManager::ClockManager()
|
||||
this->oc->realProfile = SysClkProfile_Handheld;
|
||||
|
||||
this->rnxSync = new ReverseNXSync;
|
||||
this->governor = new Governor;
|
||||
this->governor = new Governor();
|
||||
}
|
||||
|
||||
ClockManager::~ClockManager()
|
||||
@@ -209,15 +209,25 @@ bool ClockManager::RefreshContext()
|
||||
{
|
||||
PsmExt::ChargingHandler(this->GetInstance());
|
||||
|
||||
bool hasChanged = this->config->Refresh();
|
||||
bool hasChanged = false;
|
||||
SysClkProfile realProfile = Clocks::GetCurrentProfile();
|
||||
if (realProfile != this->oc->realProfile)
|
||||
{
|
||||
FileUtils::LogLine("[mgr] Profile change: %s", Clocks::GetProfileName(realProfile, true));
|
||||
this->oc->realProfile = realProfile;
|
||||
// Signal that power state has been changed, reset the override
|
||||
this->SetBatteryChargingDisabledOverride(false);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
hasChanged = this->config->Refresh();
|
||||
if (hasChanged) {
|
||||
this->rnxSync->ToggleSync(this->GetConfig()->GetConfigValue(SysClkConfigValue_SyncReverseNXMode));
|
||||
bool allowUnsafe = this->GetConfig()->GetConfigValue(SysClkConfigValue_AllowUnsafeFrequencies);
|
||||
Clocks::SetAllowUnsafe(allowUnsafe);
|
||||
|
||||
this->governor->SetAutoCPUBoost(this->GetConfig()->GetConfigValue(SysClkConfigValue_AutoCPUBoost));
|
||||
if (Clocks::GetIsMariko())
|
||||
this->governor->SetCPUBoostHz(Clocks::GetNearestHz(SysClkModule_CPU, SysClkProfile_EnumMax, Clocks::boostCpuFreq));
|
||||
this->governor->SetCPUBoostHz(Clocks::GetNearestHz(SysClkModule_CPU, this->oc->realProfile, Clocks::boostCpuFreq));
|
||||
}
|
||||
|
||||
bool enabled = this->GetConfig()->Enabled();
|
||||
@@ -248,16 +258,6 @@ bool ClockManager::RefreshContext()
|
||||
}
|
||||
this->governor->SetConfig(governorConfig);
|
||||
|
||||
SysClkProfile realProfile = Clocks::GetCurrentProfile();
|
||||
if (realProfile != this->oc->realProfile)
|
||||
{
|
||||
FileUtils::LogLine("[mgr] Profile change: %s", Clocks::GetProfileName(realProfile, true));
|
||||
this->oc->realProfile = realProfile;
|
||||
// Signal that power state has been changed, reset the override
|
||||
this->SetBatteryChargingDisabledOverride(false);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
/* Update PerformanceConfigurationId */
|
||||
{
|
||||
uint32_t confId = 0;
|
||||
|
||||
@@ -45,6 +45,7 @@ class ClockManager
|
||||
virtual ~ClockManager();
|
||||
|
||||
bool RefreshContext();
|
||||
uint32_t GetHz(SysClkModule);
|
||||
|
||||
static ClockManager *instance;
|
||||
std::atomic_bool running;
|
||||
@@ -57,6 +58,4 @@ class ClockManager
|
||||
SysClkOcExtra *oc;
|
||||
ReverseNXSync *rnxSync;
|
||||
Governor *governor;
|
||||
|
||||
uint32_t GetHz(SysClkModule);
|
||||
};
|
||||
|
||||
@@ -14,66 +14,98 @@
|
||||
#include "errors.h"
|
||||
#include "file_utils.h"
|
||||
|
||||
void Clocks::GetRange(SysClkModule module, SysClkProfile profile, uint32_t** min, uint32_t** max)
|
||||
Result Clocks::GetRange(SysClkModule module, SysClkProfile profile, uint32_t** min, uint32_t** max)
|
||||
{
|
||||
if (module == SysClkModule_MEM) {
|
||||
*min = isMariko ? &g_freq_table_mem_hz[4] : &g_freq_table_mem_hz[0]; // 1600 / 665
|
||||
*max = &g_freq_table_mem_hz[5]; // 1862 - Max
|
||||
return;
|
||||
switch (module) {
|
||||
case SysClkModule_CPU:
|
||||
case SysClkModule_GPU:
|
||||
case SysClkModule_MEM:
|
||||
*min = freqRange[module].min;
|
||||
*max = freqRange[module].max[profile];
|
||||
break;
|
||||
default:
|
||||
ERROR_THROW("No such PcvModule: %u", module);
|
||||
}
|
||||
|
||||
if (module == SysClkModule_CPU) {
|
||||
*min = &g_freq_table_cpu_hz[0];
|
||||
if (isMariko)
|
||||
*max = !allowUnsafe ? &g_freq_table_cpu_hz[15] : &g_freq_table_cpu_hz[19]; // 1963 / 2397
|
||||
else
|
||||
*max = (!allowUnsafe || profile == SysClkProfile_Handheld) ?
|
||||
&g_freq_table_cpu_hz[13] : &g_freq_table_cpu_hz[16]; // 1785 / 2091
|
||||
if (!*min || !*max || *max < *min || size_t(*max - *min + 1) > sizeof(SysClkFrequencyTable))
|
||||
return SYSCLK_ERROR(InternalFrequencyTableError);
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Clocks::UpdateFreqRange() {
|
||||
freqRange[SysClkModule_MEM].InitDefault(SysClkModule_MEM);
|
||||
if (isMariko) {
|
||||
freqRange[SysClkModule_MEM].first = freqRange[SysClkModule_MEM].min = freqRange[SysClkModule_MEM].FindFreq(1600'000'000);
|
||||
}
|
||||
|
||||
if (module == SysClkModule_GPU) {
|
||||
*min = &g_freq_table_gpu_hz[0];
|
||||
if (isMariko) {
|
||||
*max = (!allowUnsafe || profile == SysClkProfile_Handheld) ?
|
||||
&g_freq_table_gpu_hz[12] : &g_freq_table_gpu_hz[17]; // 998 / 1305
|
||||
return;
|
||||
freqRange[SysClkModule_CPU].InitDefault(SysClkModule_CPU);
|
||||
uint32_t* cpu_max_freq = freqRange[SysClkModule_CPU].last;
|
||||
uint32_t CPU_SAFE_MAX = isMariko ? 1963'500'000 : 1785'000'000;
|
||||
uint32_t CPU_UNSAFE_MAX[SysClkProfile_EnumMax];
|
||||
for (auto &m : CPU_UNSAFE_MAX) {
|
||||
m = *cpu_max_freq;
|
||||
}
|
||||
if (!isMariko) {
|
||||
CPU_UNSAFE_MAX[SysClkProfile_Handheld] = 1785'000'000;
|
||||
}
|
||||
|
||||
freqRange[SysClkModule_GPU].InitDefault(SysClkModule_GPU);
|
||||
uint32_t* gpu_max_freq = freqRange[SysClkModule_GPU].last;
|
||||
uint32_t GPU_SAFE_MAX[SysClkProfile_EnumMax];
|
||||
if (isMariko) {
|
||||
for (auto &m : GPU_SAFE_MAX) {
|
||||
m = 998'400'000;
|
||||
}
|
||||
|
||||
switch (profile) {
|
||||
case SysClkProfile_Handheld:
|
||||
*max = &g_freq_table_gpu_hz[5]; // 460
|
||||
break;
|
||||
case SysClkProfile_HandheldChargingUSB:
|
||||
*max = &g_freq_table_gpu_hz[9]; // 768
|
||||
break;
|
||||
default:
|
||||
*max = &g_freq_table_gpu_hz[11]; // 921
|
||||
break;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
GPU_SAFE_MAX[SysClkProfile_Handheld] = \
|
||||
GPU_SAFE_MAX[SysClkProfile_HandheldCharging] = 460'800'000;
|
||||
GPU_SAFE_MAX[SysClkProfile_HandheldChargingUSB] = 768'000'000;
|
||||
GPU_SAFE_MAX[SysClkProfile_HandheldChargingOfficial] = \
|
||||
GPU_SAFE_MAX[SysClkProfile_Docked] = 921'600'000;
|
||||
};
|
||||
uint32_t GPU_UNSAFE_MAX[SysClkProfile_EnumMax];
|
||||
for (auto &m : GPU_UNSAFE_MAX) {
|
||||
m = *gpu_max_freq;
|
||||
}
|
||||
if (isMariko) {
|
||||
GPU_UNSAFE_MAX[SysClkProfile_Handheld] = 998'400'000;
|
||||
} else {
|
||||
memcpy(GPU_UNSAFE_MAX, GPU_SAFE_MAX, sizeof(GPU_UNSAFE_MAX));
|
||||
}
|
||||
|
||||
ERROR_THROW("No such PcvModule: %u", module);
|
||||
const bool use_unsafe = allowUnsafe;
|
||||
for (int i = 0; i < int(SysClkProfile_EnumMax); i++) {
|
||||
freqRange[SysClkModule_CPU].max[i] = std::min(cpu_max_freq,
|
||||
freqRange[SysClkModule_CPU].FindFreq(use_unsafe ? CPU_UNSAFE_MAX[i] : CPU_SAFE_MAX, SysClkProfile(i)));
|
||||
freqRange[SysClkModule_GPU].max[i] = std::min(gpu_max_freq,
|
||||
freqRange[SysClkModule_GPU].FindFreq(use_unsafe ? GPU_UNSAFE_MAX[i] : GPU_SAFE_MAX[i], SysClkProfile(i)));
|
||||
}
|
||||
}
|
||||
|
||||
Result Clocks::GetTable(SysClkModule module, SysClkProfile profile, SysClkFrequencyTable* out_table) {
|
||||
uint32_t* min = NULL;
|
||||
uint32_t* max = NULL;
|
||||
GetRange(module, profile, &min, &max);
|
||||
if (!min || !max || (max - min) / sizeof(uint32_t) >= sizeof(SysClkFrequencyTable) / sizeof(uint32_t))
|
||||
return 1;
|
||||
if (Result res = GetRange(module, profile, &min, &max)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
memset(out_table, 0, sizeof(SysClkFrequencyTable));
|
||||
uint32_t* p = min;
|
||||
size_t idx = 0;
|
||||
while(p <= max)
|
||||
out_table->values[idx++] = *p++;
|
||||
out_table->freq[idx++] = *p++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Clocks::SetAllowUnsafe(bool allow) {
|
||||
if (allowUnsafe != allow) {
|
||||
allowUnsafe = allow;
|
||||
UpdateFreqRange();
|
||||
}
|
||||
};
|
||||
|
||||
void Clocks::Initialize()
|
||||
{
|
||||
Result rc = 0;
|
||||
@@ -129,16 +161,7 @@ void Clocks::Initialize()
|
||||
|
||||
FileUtils::ParseLoaderKip();
|
||||
|
||||
if (!maxMemFreq) {
|
||||
uint32_t curr_mem_hz = GetCurrentHz(SysClkModule_MEM);
|
||||
SetHz(SysClkModule_MEM, MAX_MEM_CLOCK);
|
||||
svcSleepThread(1'000'000);
|
||||
if (uint32_t hz = GetCurrentHz(SysClkModule_MEM))
|
||||
maxMemFreq = hz;
|
||||
else
|
||||
maxMemFreq = MAX_MEM_CLOCK;
|
||||
SetHz(SysClkModule_MEM, curr_mem_hz);
|
||||
}
|
||||
UpdateFreqRange();
|
||||
}
|
||||
|
||||
void Clocks::Exit()
|
||||
@@ -371,25 +394,11 @@ std::uint32_t Clocks::GetCurrentHz(SysClkModule module)
|
||||
|
||||
std::uint32_t Clocks::GetNearestHz(SysClkModule module, SysClkProfile profile, std::uint32_t inHz)
|
||||
{
|
||||
uint32_t inMHz = inHz / 1000000U;
|
||||
if (module == SysClkModule_MEM && inMHz == MAX_MEM_CLOCK / 1000'000)
|
||||
return Clocks::maxMemFreq;
|
||||
|
||||
uint32_t* min = NULL;
|
||||
uint32_t* max = NULL;
|
||||
GetRange(module, profile, &min, &max);
|
||||
|
||||
if (!min || !max)
|
||||
uint32_t *min = nullptr, *max = nullptr;
|
||||
if (GetRange(module, profile, &min, &max))
|
||||
ERROR_THROW("table lookup failed for SysClkModule: %u", module);
|
||||
|
||||
uint32_t* p = min;
|
||||
while(p <= max) {
|
||||
if (inMHz == *p / 1000000U)
|
||||
return *p;
|
||||
p++;
|
||||
}
|
||||
|
||||
return *max;
|
||||
return *GetNearestHzPtr(min, max, inHz);
|
||||
}
|
||||
|
||||
std::int32_t Clocks::GetTsTemperatureMilli(TsLocation location)
|
||||
|
||||
@@ -20,13 +20,67 @@
|
||||
|
||||
class Clocks
|
||||
{
|
||||
public:
|
||||
public:
|
||||
static inline uint32_t boostCpuFreq = 1785000000;
|
||||
static inline uint32_t maxMemFreq = 0;
|
||||
|
||||
static void GetRange(SysClkModule module, SysClkProfile profile, uint32_t** min, uint32_t** max);
|
||||
static inline uint32_t* GetNearestHzPtr(uint32_t* hzListStart, uint32_t* hzListEnd, uint32_t freq) {
|
||||
uint32_t* p = hzListStart;
|
||||
while (p < hzListEnd) {
|
||||
if (freq <= *p)
|
||||
return p;
|
||||
p++;
|
||||
}
|
||||
return hzListEnd;
|
||||
}
|
||||
|
||||
static inline SysClkFrequencyTable freqTable[SysClkModule_EnumMax] = {
|
||||
{}, // CPU
|
||||
{}, // GPU
|
||||
{ // MEM
|
||||
665600000,
|
||||
800000000,
|
||||
1065600000,
|
||||
1331200000,
|
||||
1600000000,
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct FreqRange {
|
||||
uint32_t* first;
|
||||
uint32_t* last;
|
||||
uint32_t* min;
|
||||
uint32_t* max[SysClkProfile_EnumMax];
|
||||
|
||||
void InitDefault(SysClkModule module) {
|
||||
SysClkFrequencyTable* table_head = &freqTable[module];
|
||||
uint32_t* p = this->first = this->min = &table_head->freq[0];
|
||||
|
||||
// Get pointer to last value
|
||||
for (int i = 0; i < FREQ_TABLE_MAX_ENTRY_COUNT; i++) {
|
||||
if (!*(++p)) {
|
||||
--p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->last = p;
|
||||
for (auto& m: this->max) {
|
||||
m = p;
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t* FindFreq(uint32_t freq, SysClkProfile profile = SysClkProfile_Docked) {
|
||||
return GetNearestHzPtr(this->min, this->max[profile], freq);
|
||||
};
|
||||
} FreqRange;
|
||||
|
||||
static inline FreqRange freqRange[SysClkModule_EnumMax];
|
||||
static void UpdateFreqRange();
|
||||
|
||||
static Result GetRange(SysClkModule module, SysClkProfile profile, uint32_t** min, uint32_t** max);
|
||||
static Result GetTable(SysClkModule module, SysClkProfile profile, SysClkFrequencyTable* out_table);
|
||||
static void SetAllowUnsafe(bool allow) { allowUnsafe = allow; };
|
||||
static void SetAllowUnsafe(bool allow);
|
||||
static bool GetIsMariko() { return isMariko; };
|
||||
static void Exit();
|
||||
static void Initialize();
|
||||
@@ -42,7 +96,7 @@ class Clocks
|
||||
static std::uint32_t GetNearestHz(SysClkModule module, SysClkProfile profile, std::uint32_t inHz);
|
||||
static std::uint32_t GetTemperatureMilli(SysClkThermalSensor sensor);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
static inline bool allowUnsafe;
|
||||
static inline bool isMariko;
|
||||
static std::int32_t GetTsTemperatureMilli(TsLocation location);
|
||||
|
||||
@@ -392,6 +392,11 @@ int Config::BrowseIniFunc(const char* section, const char* key, const char* valu
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Mem freq > 1600'000'000 will be regarded as Clocks::maxMemFreq for consistency
|
||||
if (parsedModule == SysClkModule_MEM && mhz > 1600) {
|
||||
mhz = Clocks::maxMemFreq / 1000'000;
|
||||
}
|
||||
|
||||
config->profileMhzMap[std::make_tuple(tid, parsedProfile, parsedModule)] = mhz;
|
||||
std::map<std::uint64_t, std::uint8_t>::iterator it = config->profileCountMap.find(tid);
|
||||
if (it == config->profileCountMap.end())
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "clocks.h"
|
||||
#include <dirent.h>
|
||||
#include <nxExt.h>
|
||||
#include "errors.h"
|
||||
|
||||
static LockableMutex g_log_mutex;
|
||||
static LockableMutex g_csv_mutex;
|
||||
@@ -222,15 +223,13 @@ void FileUtils::ParseLoaderKip() {
|
||||
continue;
|
||||
|
||||
if (R_SUCCEEDED(CustParser(full_path, filesize))) {
|
||||
LogLine("Parsed cust config from \"%s\", maxMemFreq: %u MHz, boostCpuFreq: %u MHz",
|
||||
full_path,
|
||||
Clocks::maxMemFreq / 1'000'000,
|
||||
Clocks::boostCpuFreq / 1'000'000
|
||||
);
|
||||
LogLine("Parsed cust config from \"%s\"", full_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ERROR_THROW("Cannot locate loader.kip in /, /atmosphere/, /atmosphere/kips/ and /bootloader/");
|
||||
}
|
||||
|
||||
Result FileUtils::CustParser(const char* filepath, size_t filesize) {
|
||||
@@ -285,13 +284,17 @@ Result FileUtils::CustParser(const char* filepath, size_t filesize) {
|
||||
if (table.custRev != CUST_REV)
|
||||
return ParseError_WrongCustRev;
|
||||
|
||||
if (table.commonCpuBoostClock)
|
||||
Clocks::boostCpuFreq = table.commonCpuBoostClock * 1000;
|
||||
|
||||
CustomizeCpuDvfsTable* cpu_dvfs_table = nullptr;
|
||||
CustomizeGpuDvfsTable* gpu_dvfs_table = nullptr;
|
||||
|
||||
if (Clocks::GetIsMariko()) {
|
||||
if (table.marikoCpuBoostClock)
|
||||
Clocks::boostCpuFreq = table.marikoCpuBoostClock * 1000;
|
||||
if (table.marikoEmcMaxClock)
|
||||
Clocks::maxMemFreq = table.marikoEmcMaxClock * 1000;
|
||||
if (table.marikoEmcVolt && table.marikoEmcVolt >= 600'000 && table.marikoEmcVolt <= 650'000) {
|
||||
u32 mvolt = table.marikoEmcVolt / 1000;
|
||||
if (table.marikoEmcVddqVolt && table.marikoEmcVddqVolt >= 550'000 && table.marikoEmcVddqVolt <= 650'000) {
|
||||
u32 mvolt = table.marikoEmcVddqVolt / 1000;
|
||||
Result res = I2c_BuckConverter_SetMvOut(&I2c_Mariko_DRAM_VDDQ, mvolt);
|
||||
LogLine("Set EMC Vddq volt to %u mV: %s", mvolt, R_FAILED(res) ? "Failed" : "OK");
|
||||
}
|
||||
@@ -300,11 +303,37 @@ Result FileUtils::CustParser(const char* filepath, size_t filesize) {
|
||||
Result res = I2c_BuckConverter_SetMvOut(&I2c_Mariko_DRAM_VDD2, mvolt);
|
||||
LogLine("Set MEM Vdd2 volt to %u mV: %s", mvolt, R_FAILED(res) ? "Failed" : "OK");
|
||||
}
|
||||
|
||||
cpu_dvfs_table = &table.marikoCpuDvfsTable;
|
||||
gpu_dvfs_table = &table.marikoGpuDvfsTable;
|
||||
} else {
|
||||
if (table.eristaEmcMaxClock)
|
||||
Clocks::maxMemFreq = table.eristaEmcMaxClock * 1000;
|
||||
|
||||
cpu_dvfs_table = &table.eristaCpuDvfsTable;
|
||||
gpu_dvfs_table = &table.eristaGpuDvfsTable;
|
||||
}
|
||||
|
||||
// Fill Clocks::freqTable
|
||||
cvb_entry_t* cpu_dvfs_entry = reinterpret_cast<cvb_entry_t *>(cpu_dvfs_table);
|
||||
for (size_t i = 0, j = 0; i < FREQ_TABLE_MAX_ENTRY_COUNT; i++) {
|
||||
// Skip CPU frequencies < 408 MHz that are not usable
|
||||
uint32_t freq = cpu_dvfs_entry[i].freq;
|
||||
if (freq < 408'000)
|
||||
continue;
|
||||
Clocks::freqTable[SysClkModule_CPU].freq[j++] = freq * 1000;
|
||||
}
|
||||
|
||||
cvb_entry_t* gpu_dvfs_entry = reinterpret_cast<cvb_entry_t *>(gpu_dvfs_table);
|
||||
for (size_t i = 0; i < FREQ_TABLE_MAX_ENTRY_COUNT; i++) {
|
||||
Clocks::freqTable[SysClkModule_GPU].freq[i] = gpu_dvfs_entry[i].freq * 1000;
|
||||
}
|
||||
|
||||
// Appending maximum mem freq to freqTable
|
||||
uint32_t* mem_entry = &Clocks::freqTable[SysClkModule_MEM].freq[0];
|
||||
while (*(++mem_entry));
|
||||
*mem_entry = Clocks::maxMemFreq;
|
||||
|
||||
return ParseError_Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,48 @@
|
||||
#define FILE_LOG_FLAG_PATH FILE_CONFIG_DIR "/log.flag"
|
||||
#define FILE_LOG_FILE_PATH FILE_CONFIG_DIR "/log.txt"
|
||||
|
||||
typedef struct cvb_coefficients {
|
||||
s32 c0 = 0;
|
||||
s32 c1 = 0;
|
||||
s32 c2 = 0;
|
||||
s32 c3 = 0;
|
||||
s32 c4 = 0;
|
||||
s32 c5 = 0;
|
||||
} cvb_coefficients;
|
||||
|
||||
typedef struct cvb_entry_t {
|
||||
u64 freq;
|
||||
cvb_coefficients cvb_dfll_param;
|
||||
cvb_coefficients cvb_pll_param;
|
||||
} cvb_entry_t;
|
||||
static_assert(sizeof(cvb_entry_t) == 0x38);
|
||||
|
||||
using CustomizeCpuDvfsTable = cvb_entry_t[FREQ_TABLE_MAX_ENTRY_COUNT];
|
||||
using CustomizeGpuDvfsTable = cvb_entry_t[FREQ_TABLE_MAX_ENTRY_COUNT];
|
||||
|
||||
constexpr uint32_t CUST_REV = 4;
|
||||
|
||||
typedef struct CustTable {
|
||||
u8 cust[4] = {'C', 'U', 'S', 'T'};
|
||||
u32 custRev;
|
||||
u32 mtcConf;
|
||||
u32 commonCpuBoostClock;
|
||||
u32 commonEmcMemVolt;
|
||||
u32 eristaCpuMaxVolt;
|
||||
u32 eristaEmcMaxClock;
|
||||
u32 marikoCpuMaxVolt;
|
||||
u32 marikoEmcMaxClock;
|
||||
u32 marikoEmcVddqVolt;
|
||||
CustomizeCpuDvfsTable eristaCpuDvfsTable;
|
||||
CustomizeCpuDvfsTable marikoCpuDvfsTable;
|
||||
CustomizeGpuDvfsTable eristaGpuDvfsTable;
|
||||
CustomizeGpuDvfsTable marikoGpuDvfsTable;
|
||||
void* eristaMtcTable;
|
||||
void* marikoMtcTable;
|
||||
} CustTable;
|
||||
static_assert(sizeof(CustTable) == sizeof(u8) * 4 + sizeof(u32) * 9 + sizeof(CustomizeCpuDvfsTable) * 4 + sizeof(void*) * 2);
|
||||
static_assert(sizeof(CustTable) == 7000);
|
||||
|
||||
class FileUtils
|
||||
{
|
||||
public:
|
||||
@@ -36,22 +78,6 @@ class FileUtils
|
||||
static void ParseLoaderKip();
|
||||
static Result mkdir_p(const char* dirpath);
|
||||
protected:
|
||||
static const uint16_t CUST_REV = 3;
|
||||
typedef struct CustTable {
|
||||
uint8_t cust[4] = {'C', 'U', 'S', 'T'};
|
||||
uint16_t custRev;
|
||||
uint16_t mtcConf;
|
||||
uint32_t marikoCpuMaxClock;
|
||||
uint32_t marikoCpuBoostClock;
|
||||
uint32_t marikoCpuMaxVolt;
|
||||
uint32_t marikoGpuMaxClock;
|
||||
uint32_t marikoEmcMaxClock;
|
||||
uint32_t marikoEmcVolt;
|
||||
uint32_t eristaCpuMaxVolt;
|
||||
uint32_t eristaEmcMaxClock;
|
||||
uint32_t commonEmcMemVolt;
|
||||
} CustTable;
|
||||
|
||||
static void RefreshFlags(bool force);
|
||||
static Result CustParser(const char* path, size_t filesize);
|
||||
};
|
||||
|
||||
@@ -81,8 +81,8 @@ namespace GovernorImpl {
|
||||
class BaseGovernor {
|
||||
public:
|
||||
BaseGovernor(SysClkModule module) : m_module(module) {
|
||||
m_hz_list = GetModuleFreqTable(module);
|
||||
m_ref_hz = GetModuleMaximumFreq(module);
|
||||
m_hz_list = Clocks::freqTable[module].freq;
|
||||
m_ref_hz = *Clocks::freqRange[module].last;
|
||||
};
|
||||
|
||||
uint32_t RefreshContext() { return this->m_target_hz = Clocks::GetCurrentHz(this->m_module); };
|
||||
@@ -104,12 +104,6 @@ namespace GovernorImpl {
|
||||
Clocks::SetHz(m_module, hz);
|
||||
};
|
||||
|
||||
void ApplyBoost() {
|
||||
ApplyTargetFreq(
|
||||
(m_module == SysClkModule_CPU && max_hz > boost_hz) ? max_hz : boost_hz
|
||||
);
|
||||
};
|
||||
|
||||
SysClkModule m_module;
|
||||
uint32_t* m_hz_list;
|
||||
uint32_t m_target_hz, m_ref_hz;
|
||||
@@ -129,6 +123,10 @@ namespace GovernorImpl {
|
||||
|
||||
void Apply();
|
||||
|
||||
void ApplyBoost() {
|
||||
ApplyTargetFreq((max_hz > boost_hz) ? max_hz : boost_hz);
|
||||
};
|
||||
|
||||
bool auto_boost;
|
||||
|
||||
protected:
|
||||
@@ -204,7 +202,9 @@ namespace GovernorImpl {
|
||||
nvExit();
|
||||
};
|
||||
|
||||
void SetMaxHz(uint32_t maxHz);
|
||||
void ApplyBoost() {
|
||||
ApplyTargetFreq(boost_hz);
|
||||
};
|
||||
|
||||
void Apply();
|
||||
|
||||
@@ -317,7 +317,7 @@ namespace GovernorImpl {
|
||||
|
||||
class Governor {
|
||||
public:
|
||||
Governor() {
|
||||
Governor() {
|
||||
m_cpu_gov = new GovernorImpl::CpuGovernor(this);
|
||||
m_gpu_gov = new GovernorImpl::GpuGovernor();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user