diff --git a/Source/hoc-clk/sysmodule/lib/nxExt/src/t210.c b/Source/hoc-clk/sysmodule/lib/nxExt/src/t210.c index e7e8966e..0934a79f 100644 --- a/Source/hoc-clk/sysmodule/lib/nxExt/src/t210.c +++ b/Source/hoc-clk/sysmodule/lib/nxExt/src/t210.c @@ -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; } diff --git a/Source/hoc-clk/sysmodule/src/board/board_volt.cpp b/Source/hoc-clk/sysmodule/src/board/board_volt.cpp index 7d6b16c9..215981bd 100644 --- a/Source/hoc-clk/sysmodule/src/board/board_volt.cpp +++ b/Source/hoc-clk/sysmodule/src/board/board_volt.cpp @@ -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; diff --git a/Source/hoc-clk/sysmodule/src/clock_manager.cpp b/Source/hoc-clk/sysmodule/src/clock_manager.cpp index e2ce4e6b..106b088c 100644 --- a/Source/hoc-clk/sysmodule/src/clock_manager.cpp +++ b/Source/hoc-clk/sysmodule/src/clock_manager.cpp @@ -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(); } diff --git a/Source/hoc-clk/sysmodule/src/display/aula.cpp b/Source/hoc-clk/sysmodule/src/display/aula.cpp index a9e68f9c..d14b152b 100644 --- a/Source/hoc-clk/sysmodule/src/display/aula.cpp +++ b/Source/hoc-clk/sysmodule/src/display/aula.cpp @@ -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);