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,
|
||||
} GPUUndervoltLevel;
|
||||
|
||||
enum {
|
||||
DVFSMode_Disabled,
|
||||
DVFSMode_Hijack,
|
||||
// DVFSMode_OfficialService,
|
||||
// DVFSMode_Hack,
|
||||
DVFSMode_EnumMax,
|
||||
};
|
||||
|
||||
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
|
||||
|
||||
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
|
||||
|
||||
@@ -57,6 +57,9 @@ typedef enum {
|
||||
|
||||
HorizonOCConfigValue_OverwriteRefreshRate,
|
||||
HorizonOCConfigValue_EnableUnsafeDisplayFreqs,
|
||||
|
||||
HorizonOCConfigValue_DVFSMode,
|
||||
|
||||
HocClkConfigValue_FixCpuVoltBug,
|
||||
|
||||
KipConfigValue_custRev,
|
||||
@@ -226,6 +229,9 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
|
||||
case HorizonOCConfigValue_EnableUnsafeDisplayFreqs:
|
||||
return pretty ? "Enable Unsafe Display Frequencies" : "drr_unsafe";
|
||||
|
||||
case HorizonOCConfigValue_DVFSMode:
|
||||
return pretty ? "DVFS Mode" : "dvfs_mode";
|
||||
|
||||
// KIP config values
|
||||
case KipConfigValue_custRev:
|
||||
return pretty ? "Custom Revision" : "kip_cust_rev";
|
||||
@@ -411,6 +417,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
|
||||
case HocClkConfigValue_EnforceBoardLimit:
|
||||
case HocClkConfigValue_FixCpuVoltBug:
|
||||
case HocClkConfigValue_IsFirstLoad:
|
||||
case HorizonOCConfigValue_DVFSMode:
|
||||
return 1ULL;
|
||||
case HocClkConfigValue_ThermalThrottleThreshold:
|
||||
return 70ULL;
|
||||
@@ -542,6 +549,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
|
||||
case KipConfigValue_t6_tRTW_fine_tune:
|
||||
case KipConfigValue_t7_tWTR_fine_tune:
|
||||
case KipCrc32:
|
||||
case HorizonOCConfigValue_DVFSMode:
|
||||
return true;
|
||||
case HorizonOCConfigValue_BatteryChargeCurrent:
|
||||
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(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
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
|
||||
std::vector<NamedValue> chargerCurrents = {
|
||||
NamedValue("Disabled", 0),
|
||||
NamedValue("1024mA", 1024),
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <cstring>
|
||||
#include <registers.h>
|
||||
#include <notification.h>
|
||||
#include <memmem.h>
|
||||
|
||||
#define MAX(A, B) std::max(A, B)
|
||||
#define MIN(A, B) std::min(A, B)
|
||||
@@ -1050,7 +1051,7 @@ void Board::CacheDvfsTable() {
|
||||
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;
|
||||
|
||||
if (!resultPattern) {
|
||||
@@ -1104,6 +1105,7 @@ void Board::PcvHijackDvfs(u32 vmin) {
|
||||
}
|
||||
|
||||
svcCloseHandle(handle);
|
||||
FileUtils::LogLine("[dvfs] voltage set to %u mV", vmin);
|
||||
}
|
||||
|
||||
#define MC_REGISTER_BASE 0x70019000
|
||||
|
||||
@@ -47,8 +47,9 @@ bool hasChanged = true;
|
||||
ClockManager *ClockManager::instance = NULL;
|
||||
Thread governorTHREAD;
|
||||
u32 initialConfigValues[SysClkConfigValue_EnumMax]; // initial config. used for safety checks
|
||||
|
||||
u64 previousRamHz;
|
||||
bool kipAvailable = false;
|
||||
|
||||
ClockManager *ClockManager::GetInstance()
|
||||
{
|
||||
return instance;
|
||||
@@ -110,6 +111,7 @@ ClockManager::ClockManager()
|
||||
|
||||
this->context->dramID = Board::GetDramID();
|
||||
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))
|
||||
{
|
||||
return 4294967294; // Integer limit, uncapped clocks ON
|
||||
return ~0; // Integer limit, uncapped clocks ON
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -246,7 +248,7 @@ std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile p
|
||||
if(profile < SysClkProfile_HandheldCharging && Board::GetSocType() == SysClkSocType_Erista) {
|
||||
return 1581000000;
|
||||
} else {
|
||||
return 4294967294;
|
||||
return ~0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,7 +443,6 @@ void ClockManager::GovernorThread(void* arg)
|
||||
|
||||
bool prevBoostMode = true;
|
||||
|
||||
|
||||
void ClockManager::Tick()
|
||||
{
|
||||
std::scoped_lock lock{this->contextMutex};
|
||||
@@ -485,6 +486,7 @@ void ClockManager::Tick()
|
||||
|
||||
if (this->RefreshContext() || this->config->Refresh())
|
||||
{
|
||||
|
||||
if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) {
|
||||
I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent));
|
||||
}
|
||||
@@ -496,10 +498,13 @@ void ClockManager::Tick()
|
||||
// ResetToStockClocks();
|
||||
return;
|
||||
}
|
||||
previousRamHz = Board::GetHz(SysClkModule_MEM);
|
||||
|
||||
bool returnRaw = false;
|
||||
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
{
|
||||
u32 oldHz = Board::GetHz((SysClkModule)module);
|
||||
|
||||
if(module > SysClkModule_MEM)
|
||||
returnRaw = true;
|
||||
else
|
||||
@@ -559,16 +564,48 @@ void ClockManager::Tick()
|
||||
nearestHz / 1000000, nearestHz / 100000 - nearestHz / 1000000 * 10,
|
||||
targetHz / 1000000, targetHz / 100000 - targetHz / 1000000 * 10
|
||||
);
|
||||
|
||||
/* 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);
|
||||
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)) {
|
||||
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++)
|
||||
{
|
||||
this->context->voltages[voltageSource] = Board::GetVoltage(HocClkVoltage_GPU);
|
||||
this->context->voltages[voltageSource] = Board::GetVoltage((HocClkVoltage)voltageSource);
|
||||
}
|
||||
|
||||
if (this->ConfigIntervalTimeout(SysClkConfigValue_CsvWriteIntervalMs, ns, &this->lastCsvWriteNs))
|
||||
|
||||
Reference in New Issue
Block a user