sysclk: make dvfs work
This commit is contained in:
17
Source/sys-clk/common/include/memmem.h
Normal file
17
Source/sys-clk/common/include/memmem.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef MEMMEM_IMPL_H
|
||||||
|
#define MEMMEM_IMPL_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *memmem_impl(void *haystack, size_t haystacklen,
|
||||||
|
const void *needle, size_t needlelen);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -132,6 +132,14 @@ typedef enum {
|
|||||||
GPUUVLevel_EnumMax,
|
GPUUVLevel_EnumMax,
|
||||||
} GPUUndervoltLevel;
|
} GPUUndervoltLevel;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DVFSMode_Disabled,
|
||||||
|
DVFSMode_Hijack,
|
||||||
|
// DVFSMode_OfficialService,
|
||||||
|
// DVFSMode_Hack,
|
||||||
|
DVFSMode_EnumMax,
|
||||||
|
};
|
||||||
|
|
||||||
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
|
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
|
||||||
|
|
||||||
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
|
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ typedef enum {
|
|||||||
|
|
||||||
HorizonOCConfigValue_OverwriteRefreshRate,
|
HorizonOCConfigValue_OverwriteRefreshRate,
|
||||||
HorizonOCConfigValue_EnableUnsafeDisplayFreqs,
|
HorizonOCConfigValue_EnableUnsafeDisplayFreqs,
|
||||||
|
|
||||||
|
HorizonOCConfigValue_DVFSMode,
|
||||||
|
|
||||||
HocClkConfigValue_FixCpuVoltBug,
|
HocClkConfigValue_FixCpuVoltBug,
|
||||||
|
|
||||||
KipConfigValue_custRev,
|
KipConfigValue_custRev,
|
||||||
@@ -226,6 +229,9 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
|
|||||||
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
|
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
|
||||||
return pretty ? "Enable Unsafe Display Frequencies" : "drr_unsafe";
|
return pretty ? "Enable Unsafe Display Frequencies" : "drr_unsafe";
|
||||||
|
|
||||||
|
case HorizonOCConfigValue_DVFSMode:
|
||||||
|
return pretty ? "DVFS Mode" : "dvfs_mode";
|
||||||
|
|
||||||
// KIP config values
|
// KIP config values
|
||||||
case KipConfigValue_custRev:
|
case KipConfigValue_custRev:
|
||||||
return pretty ? "Custom Revision" : "kip_cust_rev";
|
return pretty ? "Custom Revision" : "kip_cust_rev";
|
||||||
@@ -411,6 +417,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
|
|||||||
case HocClkConfigValue_EnforceBoardLimit:
|
case HocClkConfigValue_EnforceBoardLimit:
|
||||||
case HocClkConfigValue_FixCpuVoltBug:
|
case HocClkConfigValue_FixCpuVoltBug:
|
||||||
case HocClkConfigValue_IsFirstLoad:
|
case HocClkConfigValue_IsFirstLoad:
|
||||||
|
case HorizonOCConfigValue_DVFSMode:
|
||||||
return 1ULL;
|
return 1ULL;
|
||||||
case HocClkConfigValue_ThermalThrottleThreshold:
|
case HocClkConfigValue_ThermalThrottleThreshold:
|
||||||
return 70ULL;
|
return 70ULL;
|
||||||
@@ -542,6 +549,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
|
|||||||
case KipConfigValue_t6_tRTW_fine_tune:
|
case KipConfigValue_t6_tRTW_fine_tune:
|
||||||
case KipConfigValue_t7_tWTR_fine_tune:
|
case KipConfigValue_t7_tWTR_fine_tune:
|
||||||
case KipCrc32:
|
case KipCrc32:
|
||||||
|
case HorizonOCConfigValue_DVFSMode:
|
||||||
return true;
|
return true;
|
||||||
case HorizonOCConfigValue_BatteryChargeCurrent:
|
case HorizonOCConfigValue_BatteryChargeCurrent:
|
||||||
return ((input >= 1024) && (input <= 3072)) || !input;
|
return ((input >= 1024) && (input <= 3072)) || !input;
|
||||||
|
|||||||
59
Source/sys-clk/common/src/memmem.c
Normal file
59
Source/sys-clk/common/src/memmem.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "memmem.h"
|
||||||
|
|
||||||
|
void *memmem_impl(void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
|
||||||
|
{
|
||||||
|
const unsigned char *cmpp;
|
||||||
|
const unsigned char *p;
|
||||||
|
const unsigned char *endp;
|
||||||
|
const unsigned char *q;
|
||||||
|
const unsigned char *endq;
|
||||||
|
unsigned char found;
|
||||||
|
|
||||||
|
if(haystack == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(needle == NULL)
|
||||||
|
{
|
||||||
|
return haystack;
|
||||||
|
}
|
||||||
|
if(haystacklen == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(needlelen == 0)
|
||||||
|
{
|
||||||
|
return haystack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(needlelen > haystacklen)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
endp = haystack + haystacklen - needlelen;
|
||||||
|
endq = needle + needlelen;
|
||||||
|
for(p = haystack; p <= endp; p++)
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
cmpp = p;
|
||||||
|
for(q = needle; q < endq; q++)
|
||||||
|
{
|
||||||
|
if(*cmpp != *q)
|
||||||
|
{
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmpp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
return (void*)p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -344,8 +344,26 @@ void MiscGui::listUI()
|
|||||||
});
|
});
|
||||||
this->listElement->addItem(gpuSubmenu);
|
this->listElement->addItem(gpuSubmenu);
|
||||||
|
|
||||||
|
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
|
||||||
|
std::vector<NamedValue> dvfsValues = {
|
||||||
|
NamedValue("Disabled", DVFSMode_Disabled),
|
||||||
|
NamedValue("PCV Hijack", DVFSMode_Hijack),
|
||||||
|
// NamedValue("Official Service", DVFSMode_OfficialService),
|
||||||
|
// NamedValue("Hack", DVFSMode_Hack),
|
||||||
|
};
|
||||||
|
|
||||||
|
addConfigButton(
|
||||||
|
HorizonOCConfigValue_DVFSMode,
|
||||||
|
"GPU DVFS Mode",
|
||||||
|
ValueRange(0, 0, 1, "", 0),
|
||||||
|
"GPU DVFS Mode",
|
||||||
|
&thresholdsDisabled,
|
||||||
|
{},
|
||||||
|
dvfsValues,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
#if IS_MINIMAL == 0
|
#if IS_MINIMAL == 0
|
||||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
|
|
||||||
std::vector<NamedValue> chargerCurrents = {
|
std::vector<NamedValue> chargerCurrents = {
|
||||||
NamedValue("Disabled", 0),
|
NamedValue("Disabled", 0),
|
||||||
NamedValue("1024mA", 1024),
|
NamedValue("1024mA", 1024),
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <registers.h>
|
#include <registers.h>
|
||||||
#include <notification.h>
|
#include <notification.h>
|
||||||
|
#include <memmem.h>
|
||||||
|
|
||||||
#define MAX(A, B) std::max(A, B)
|
#define MAX(A, B) std::max(A, B)
|
||||||
#define MIN(A, B) std::min(A, B)
|
#define MIN(A, B) std::min(A, B)
|
||||||
@@ -1050,7 +1051,7 @@ void Board::CacheDvfsTable() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *resultPattern = static_cast<u8 *>(memmem(buffer, sizeof(buffer), voltagePattern, sizeof(voltagePattern)));
|
u8 *resultPattern = static_cast<u8 *>(memmem_impl(buffer, sizeof(buffer), voltagePattern, sizeof(voltagePattern)));
|
||||||
u32 index = resultPattern - buffer;
|
u32 index = resultPattern - buffer;
|
||||||
|
|
||||||
if (!resultPattern) {
|
if (!resultPattern) {
|
||||||
@@ -1104,6 +1105,7 @@ void Board::PcvHijackDvfs(u32 vmin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
svcCloseHandle(handle);
|
svcCloseHandle(handle);
|
||||||
|
FileUtils::LogLine("[dvfs] voltage set to %u mV", vmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MC_REGISTER_BASE 0x70019000
|
#define MC_REGISTER_BASE 0x70019000
|
||||||
|
|||||||
@@ -47,8 +47,9 @@ bool hasChanged = true;
|
|||||||
ClockManager *ClockManager::instance = NULL;
|
ClockManager *ClockManager::instance = NULL;
|
||||||
Thread governorTHREAD;
|
Thread governorTHREAD;
|
||||||
u32 initialConfigValues[SysClkConfigValue_EnumMax]; // initial config. used for safety checks
|
u32 initialConfigValues[SysClkConfigValue_EnumMax]; // initial config. used for safety checks
|
||||||
|
u64 previousRamHz;
|
||||||
bool kipAvailable = false;
|
bool kipAvailable = false;
|
||||||
|
|
||||||
ClockManager *ClockManager::GetInstance()
|
ClockManager *ClockManager::GetInstance()
|
||||||
{
|
{
|
||||||
return instance;
|
return instance;
|
||||||
@@ -110,6 +111,7 @@ ClockManager::ClockManager()
|
|||||||
|
|
||||||
this->context->dramID = Board::GetDramID();
|
this->context->dramID = Board::GetDramID();
|
||||||
this->context->isDram8GB = Board::IsDram8GB();
|
this->context->isDram8GB = Board::IsDram8GB();
|
||||||
|
previousRamHz = Board::GetHz(SysClkModule_MEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -196,7 +198,7 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
|
|||||||
{
|
{
|
||||||
if (this->config->GetConfigValue(HocClkConfigValue_UncappedClocks))
|
if (this->config->GetConfigValue(HocClkConfigValue_UncappedClocks))
|
||||||
{
|
{
|
||||||
return 4294967294; // Integer limit, uncapped clocks ON
|
return ~0; // Integer limit, uncapped clocks ON
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -246,7 +248,7 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
|
|||||||
if(profile < SysClkProfile_HandheldCharging && Board::GetSocType() == SysClkSocType_Erista) {
|
if(profile < SysClkProfile_HandheldCharging && Board::GetSocType() == SysClkSocType_Erista) {
|
||||||
return 1581000000;
|
return 1581000000;
|
||||||
} else {
|
} else {
|
||||||
return 4294967294;
|
return ~0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -441,7 +443,6 @@ void ClockManager::GovernorThread(void* arg)
|
|||||||
|
|
||||||
bool prevBoostMode = true;
|
bool prevBoostMode = true;
|
||||||
|
|
||||||
|
|
||||||
void ClockManager::Tick()
|
void ClockManager::Tick()
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{this->contextMutex};
|
std::scoped_lock lock{this->contextMutex};
|
||||||
@@ -485,6 +486,7 @@ void ClockManager::Tick()
|
|||||||
|
|
||||||
if (this->RefreshContext() || this->config->Refresh())
|
if (this->RefreshContext() || this->config->Refresh())
|
||||||
{
|
{
|
||||||
|
|
||||||
if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) {
|
if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) {
|
||||||
I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent));
|
I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent));
|
||||||
}
|
}
|
||||||
@@ -496,10 +498,13 @@ void ClockManager::Tick()
|
|||||||
// ResetToStockClocks();
|
// ResetToStockClocks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
previousRamHz = Board::GetHz(SysClkModule_MEM);
|
||||||
|
|
||||||
bool returnRaw = false;
|
bool returnRaw = false;
|
||||||
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||||
{
|
{
|
||||||
|
u32 oldHz = Board::GetHz((SysClkModule)module);
|
||||||
|
|
||||||
if(module > SysClkModule_MEM)
|
if(module > SysClkModule_MEM)
|
||||||
returnRaw = true;
|
returnRaw = true;
|
||||||
else
|
else
|
||||||
@@ -559,16 +564,48 @@ void ClockManager::Tick()
|
|||||||
nearestHz / 1000000, nearestHz / 100000 - nearestHz / 1000000 * 10,
|
nearestHz / 1000000, nearestHz / 100000 - nearestHz / 1000000 * 10,
|
||||||
targetHz / 1000000, targetHz / 100000 - targetHz / 1000000 * 10
|
targetHz / 1000000, targetHz / 100000 - targetHz / 1000000 * 10
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Dvfs here. */
|
/* Dvfs here. */
|
||||||
|
if(module == SysClkModule_MEM && Board::GetSocType() == SysClkSocType_Mariko && targetHz > oldHz) {
|
||||||
|
Board::PcvHijackDvfs(Board::GetMinimumGpuVoltage(targetHz / 1000000));
|
||||||
|
I2c_BuckConverter_SetMvOut(&I2c_Mariko_GPU, Board::GetMinimumGpuVoltage(targetHz / 1000000));
|
||||||
|
this->context->voltages[HocClkVoltage_GPU] = Board::GetMinimumGpuVoltage(targetHz / 1000000) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
Board::SetHz((SysClkModule)module, nearestHz);
|
Board::SetHz((SysClkModule)module, nearestHz);
|
||||||
this->context->freqs[module] = nearestHz;
|
this->context->freqs[module] = nearestHz;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(module == SysClkModule_MEM && Board::GetSocType() == SysClkSocType_Mariko && targetHz < oldHz) {
|
||||||
|
Board::PcvHijackDvfs(0);
|
||||||
|
// I2c_BuckConverter_SetMvOut(&I2c_Mariko_GPU, 0);
|
||||||
|
|
||||||
|
targetHz = this->context->overrideFreqs[SysClkModule_GPU];
|
||||||
|
if (!targetHz)
|
||||||
|
{
|
||||||
|
targetHz = this->config->GetAutoClockHz(this->context->applicationId, SysClkModule_GPU, this->context->profile, false);
|
||||||
|
if(!targetHz)
|
||||||
|
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, SysClkModule_GPU, this->context->profile, false);
|
||||||
|
}
|
||||||
|
if(targetHz) {
|
||||||
|
Board::SetHz(SysClkModule_GPU, ~0);
|
||||||
|
Board::SetHz(SysClkModule_GPU, targetHz);
|
||||||
|
} else {
|
||||||
|
Board::SetHz(SysClkModule_GPU, ~0);
|
||||||
|
Board::ResetToStockGpu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(module == SysClkModule_CPU && this->config->GetConfigValue(HocClkConfigValue_FixCpuVoltBug)) {
|
if(module == SysClkModule_CPU && this->config->GetConfigValue(HocClkConfigValue_FixCpuVoltBug)) {
|
||||||
FixCpuBug();
|
FixCpuBug();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// if(module == SysClkModule_MEM && Board::GetSocType() == SysClkSocType_Mariko) {
|
||||||
|
// Board::PcvHijackDvfs(0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -713,7 +750,7 @@ bool ClockManager::RefreshContext()
|
|||||||
|
|
||||||
for (unsigned int voltageSource = 0; voltageSource < HocClkVoltage_EnumMax; voltageSource++)
|
for (unsigned int voltageSource = 0; voltageSource < HocClkVoltage_EnumMax; voltageSource++)
|
||||||
{
|
{
|
||||||
this->context->voltages[voltageSource] = Board::GetVoltage(HocClkVoltage_GPU);
|
this->context->voltages[voltageSource] = Board::GetVoltage((HocClkVoltage)voltageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->ConfigIntervalTimeout(SysClkConfigValue_CsvWriteIntervalMs, ns, &this->lastCsvWriteNs))
|
if (this->ConfigIntervalTimeout(SysClkConfigValue_CsvWriteIntervalMs, ns, &this->lastCsvWriteNs))
|
||||||
|
|||||||
Reference in New Issue
Block a user