hocclk: some refactoring and commenting

This commit is contained in:
souldbminersmwc
2026-04-30 18:48:57 -04:00
parent 00cf05d9c5
commit 89418b7cd0
4 changed files with 34 additions and 38 deletions

View File

@@ -1,6 +1,7 @@
/*
* Copyright (c) 2020-2023 CTCaer
* Copyright (c) 2023 p-sam
* Copyright (c) 2023 Lineon
* Copyright (c) 2026 Souldbminer
*
* This program is free software; you can redistribute it and/or modify it
@@ -260,9 +261,13 @@ static void _clock_update_freqs(void)
g_emc_lall = (u64)_actmon_dev_get_count_avg(ACTMON_DEV_MC_ALL) * 10 * 100 / (emc_freq * ACTMON_PERIOD_MS);
g_emc_lcpu = (u64)_actmon_dev_get_count_avg(ACTMON_DEV_MC_CPU) * 10 * 100 / (emc_freq * ACTMON_PERIOD_MS);
// TODO: use PLL instead of actmon
// Avoid floating point arithematic
g_emc_bw_all = (u64)emc_freq * 16 * g_emc_lall / 1000000;
g_emc_bw_cpu = (u64)emc_freq * 16 * g_emc_lcpu / 1000000;
g_emc_bw_gpu = g_emc_bw_all > g_emc_bw_cpu ? g_emc_bw_all - g_emc_bw_cpu : 0;
// Not 100% accurate but should be enough
g_emc_bw_gpu = g_emc_bw_all - g_emc_bw_cpu;
}

View File

@@ -260,7 +260,7 @@ namespace board {
rgltrGetVoltage(&session, &out);
rgltrCloseSession(&session);
} else {
out = GetVoltage(HocClkVoltage_EMCVDD2);
out = GetVoltage(HocClkVoltage_EMCVDD2); // VDD2 and VDDQ are always connected to the same rail on Erista
}
break;
case HocClkVoltage_Display:
@@ -321,6 +321,7 @@ namespace board {
}
void CacheGpuVoltTable() {
// Likely CPU regulator?
UnkRegulator reg = {
.voltageMin = 600000,
.voltageStep = 12500,
@@ -386,6 +387,7 @@ namespace board {
svcCloseHandle(handle);
handle = INVALID_HANDLE;
// Print info AFTER we exit the handle to avoid hangs
for(int i = 0; i < (int)std::size(cpuVoltTable); ++i) {
fileUtils::LogLine("[dvfs] cpu volt %d: %u mV", i, cpuVoltTable[i]);
}
@@ -435,21 +437,21 @@ namespace board {
u32 GetMinimumGpuVmin(u32 freqMhz, u32 bracket) {
static const u32 ramTable[][22] = {
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, },
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, },
{ 2433, 2466, 2533, 2600, 2666, 2733, 2766, 2800, 2833, 2866, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3300, 3333, 3366, },
{ 2500, 2533, 2600, 2633, 2666, 2733, 2800, 2866, 2900, 2966, 3033, 3100, 3166, 3200, 3233, 3266, 3300, 3333, 3366, 3400, 3400, 3400, },
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, }, // Bracket 0
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, }, // Bracket 1
{ 2433, 2466, 2533, 2600, 2666, 2733, 2766, 2800, 2833, 2866, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3300, 3333, 3366, }, // Bracket 2
{ 2500, 2533, 2600, 2633, 2666, 2733, 2800, 2866, 2900, 2966, 3033, 3100, 3166, 3200, 3233, 3266, 3300, 3333, 3366, 3400, 3400, 3400, }, // Bracket 3
};
static const u32 gpuVoltArray[] = { 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800, };
if (freqMhz <= 1600) return 0;
if (freqMhz <= 1600) return 0; // DVFS doesnt work below 1600MHz, it will just use vMin
if (bracket >= std::size(ramTable)) bracket = 0;
u32 bracketStart = ramTable[bracket][0];
u32 rampStartVolt = (bracket == 0) ? 535 : 525;
u32 rampStartVolt = (bracket == 0) ? 535 : 525; // Do not touch!
u32 rampSpan = 590 - rampStartVolt;

View File

@@ -218,6 +218,7 @@ namespace clockManager {
void HandleMiscFeatures()
{
// these dont need to run that often, so dont bother
static u32 tick = 0;
if(++tick > 10) {
tick = 0;
@@ -225,9 +226,11 @@ namespace clockManager {
if (config::GetConfigValue(HocClkConfigValue_BatteryChargeCurrent)) {
I2c_Bq24193_SetFastChargeCurrentLimit(config::GetConfigValue(HocClkConfigValue_BatteryChargeCurrent));
}
I2c_BuckConverter_SetMvOut(&I2c_Display, config::GetConfigValue(HocClkConfigValue_DisplayVoltage));
AulaDisplay::SetDisplayColorMode((AulaColorMode)config::GetConfigValue(HocClkConfigValue_AulaDisplayColorPreset));
I2c_BuckConverter_SetMvOut(&I2c_Display, config::GetConfigValue(HocClkConfigValue_DisplayVoltage));
if(board::GetConsoleType() == HocClkConsoleType_Aula)
AulaDisplay::SetDisplayColorMode((AulaColorMode)config::GetConfigValue(HocClkConfigValue_AulaDisplayColorPreset));
}
}
@@ -235,7 +238,7 @@ namespace clockManager {
void DVFSBeforeSet(u32 targetHz)
{
s32 dvfsOffset = config::GetConfigValue(HocClkConfigValue_DVFSOffset);
u32 vmin = board::GetMinimumGpuVmin(targetHz / 1000000, board::GetGpuSpeedoBracket());
u32 vmin = board::GetMinimumGpuVmin(targetHz / 1000000, board::GetGpuSpeedoBracket()); // Get GPU vmin using the algorithm
if (vmin) {
vmin += dvfsOffset;
@@ -248,7 +251,9 @@ namespace clockManager {
I2c_BuckConverter_SetMvOut(&I2c_Mariko_GPU, vmin);
}
gContext.voltages[HocClkVoltage_GPU] = vmin * 1000;
svcSleepThread(25E6); // Wait for voltages to properly adjust
gContext.voltages[HocClkVoltage_GPU] = vmin * 1000; // Update the voltages in the context
}
void DVFSAfterSet(u32 targetHz)
@@ -265,8 +270,9 @@ namespace clockManager {
u32 nearestHz = GetNearestHz(HocClkModule_GPU, targetHz, maxHz);
board::PcvHijackGpuVolts(vmin);
// Voltage doesn't update properly unless you set gpu to max and set it to min
if (targetHz) {
board::SetHz(HocClkModule_GPU, ~0);
board::SetHz(HocClkModule_GPU, ~0); // This won't apply, it will set back to nearestHz before it can apply the higher freq
board::SetHz(HocClkModule_GPU, nearestHz);
} else {
board::SetHz(HocClkModule_GPU, ~0);
@@ -277,7 +283,7 @@ namespace clockManager {
void HandleCpuUv()
{
if (board::GetSocType() == HocClkSocType_Erista)
board::SetDfllTunings(config::GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000);
board::SetDfllTunings(config::GetConfigValue(KipConfigValue_eristaCpuUV), 0, 1581000000); // Erista tbreak is always 1581MHz
else
board::SetDfllTunings(config::GetConfigValue(KipConfigValue_marikoCpuUVLow), config::GetConfigValue(KipConfigValue_marikoCpuUVHigh), board::CalculateTbreak(config::GetConfigValue(KipConfigValue_tableConf)));
}
@@ -285,24 +291,9 @@ namespace clockManager {
void DVFSReset()
{
if (board::GetSocType() == HocClkSocType_Mariko && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) {
board::PcvHijackGpuVolts(0);
u32 targetHz = gContext.overrideFreqs[HocClkModule_GPU];
if (!targetHz) {
targetHz = config::GetAutoClockHz(gContext.applicationId, HocClkModule_GPU, gContext.profile, false);
if (!targetHz) {
targetHz = config::GetAutoClockHz(HOCCLK_GLOBAL_PROFILE_TID, HocClkModule_GPU, gContext.profile, false);
}
}
u32 maxHz = GetMaxAllowedHz(HocClkModule_GPU, gContext.profile);
u32 nearestHz = GetNearestHz(HocClkModule_GPU, targetHz, maxHz);
board::PcvHijackGpuVolts(0); // Reset to vMin
board::SetHz(HocClkModule_GPU, ~0);
if (targetHz) {
board::SetHz(HocClkModule_GPU, nearestHz);
} else {
board::ResetToStockGpu();
}
board::ResetToStockGpu();
}
}
@@ -385,7 +376,7 @@ namespace clockManager {
}
}
// Skip GPU and CPU if governors handle them
// The modules above MEM require special handling
if (module > HocClkModule_MEM) {
continue;
}
@@ -407,6 +398,7 @@ namespace clockManager {
targetHz / 1000000, targetHz / 100000 - targetHz / 1000000 * 10
);
// The logic MUST be done in this order otherwise you WILL get crashes
if (module == HocClkModule_MEM && board::GetSocType() == HocClkSocType_Mariko && targetHz > oldHz && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) {
DVFSBeforeSet(targetHz);
}
@@ -453,11 +445,7 @@ namespace clockManager {
// restore clocks to stock values on app or profile change
if (hasChanged) {
board::ResetToStock();
if (board::GetSocType() == HocClkSocType_Mariko && config::GetConfigValue(HocClkConfigValue_DVFSMode) == DVFSMode_Hijack) {
board::PcvHijackGpuVolts(0);
board::SetHz(HocClkModule_GPU, ~0);
board::ResetToStockGpu();
}
DVFSReset();
WaitForNextTick();
}

View File

@@ -31,10 +31,11 @@ namespace AulaDisplay {
DSI(DSI_TRIGGER) = DSI_TRIGGER_HOST;
if (wait)
svcSleepThread(wait * 1000);
svcSleepThread(wait * 1000); // usleep-equivalant
}
void SetDisplayColorMode(AulaColorMode mode) {
// send display command to change color mode.
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (mode << 8), 0);