From 2dbd4363077e990de577b725901fd9ac9372e532 Mon Sep 17 00:00:00 2001 From: Lightos1 <124387232+Lightos1@users.noreply.github.com> Date: Fri, 20 Mar 2026 20:43:08 +0100 Subject: [PATCH] rewrite: add freq functions --- .../sysmodule/src/board/board.cpp | 4 + .../sysmodule/src/board/board.hpp | 1 + .../sysmodule/src/board/board_freq.cpp | 231 ++++++++++++++++++ .../sysmodule/src/board/board_freq.hpp | 89 +++++++ .../sysmodule/src/board/board_name.cpp | 47 ++++ .../sysmodule/src/board/board_name.hpp | 38 +++ .../sysmodule/src/old_board.cpp | 1 - 7 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.cpp create mode 100644 Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.hpp create mode 100644 Source/rewrite-hoc-clk/sysmodule/src/board/board_name.cpp create mode 100644 Source/rewrite-hoc-clk/sysmodule/src/board/board_name.hpp diff --git a/Source/rewrite-hoc-clk/sysmodule/src/board/board.cpp b/Source/rewrite-hoc-clk/sysmodule/src/board/board.cpp index f9702023..36a377e2 100644 --- a/Source/rewrite-hoc-clk/sysmodule/src/board/board.cpp +++ b/Source/rewrite-hoc-clk/sysmodule/src/board/board.cpp @@ -186,4 +186,8 @@ namespace board { return gSocType; } + HorizonOCConsoleType GetConsoleType() { + return gConsoleType; + } + } diff --git a/Source/rewrite-hoc-clk/sysmodule/src/board/board.hpp b/Source/rewrite-hoc-clk/sysmodule/src/board/board.hpp index d12f161e..17d755a3 100644 --- a/Source/rewrite-hoc-clk/sysmodule/src/board/board.hpp +++ b/Source/rewrite-hoc-clk/sysmodule/src/board/board.hpp @@ -36,5 +36,6 @@ namespace board { void Initialize(); void Exit(); SysClkSocType GetSocType(); + HorizonOCConsoleType GetConsoleType(); } diff --git a/Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.cpp b/Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.cpp new file mode 100644 index 00000000..0d16ca8e --- /dev/null +++ b/Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "board.hpp" +#include "board_name.hpp" +#include "../error.h" + +namespace board { + + PcvModuleId GetPcvModuleId(SysClkModule sysclkModule) { + PcvModuleId pcvModuleId; + Result rc = pcvGetModuleId(&pcvModuleId, GetPcvModule(sysclkModule)); + ASSERT_RESULT_OK(rc, "pcvGetModuleId"); + + return pcvModuleId; + } + + PcvModule GetPcvModule(SysClkModule sysclkModule) { + switch (sysclkModule) { + case SysClkModule_CPU: + return PcvModule_CpuBus; + case SysClkModule_GPU: + return PcvModule_GPU; + case SysClkModule_MEM: + return PcvModule_EMC; + default: + ASSERT_ENUM_VALID(SysClkModule, sysclkModule); + } + + return (PcvModule)0; + } + + void ClkrstSetHz(ClkrstSession &session, u32 hz) { + ASSERT_RESULT_OK(clkrstSetClockRate(&session, hz), "clkrstSetClockRate"); + } + + void PcvSetHz(PcvModuleId moduleID, u32 hz) { + ASSERT_RESULT_OK(pcvSetClockRate(moduleID, hz), "pcvSetClockRate"); + } + + void SetHz(SysClkModule module, u32 hz) { + Result rc = 0; + bool usesGovenor = module > SysClkModule_MEM; + + + if (module == HorizonOCModule_Display && HorizonOCConsoleType() != HorizonOCConsoleType_Hoag) { + DisplayRefresh_SetRate(hz); + return; + } + + if (usesGovenor) { + return; + } + + if (HOSSVC_HAS_CLKRST) { + ClkrstSession session = {}; + rc = clkrstOpenSession(&session, GetPcvModuleId(module), 3); + ASSERT_RESULT_OK(rc, "clkrstOpenSession"); + ClkrstSetHz(session, hz); + + /* Voltage bug workaround. */ + if (module == SysClkModule_CPU) { + svcSleepThread(200'000); + ClkrstSetHz(session, hz); + } + + clkrstCloseSession(&session); + } else { + PcvSetHz(GetPcvModule(module), hz); + + if (module == SysClkModule_CPU) { + svcSleepThread(200'000); + PcvSetHz(GetPcvModule(module), hz); + } + } + } + + u32 GetDisplayRate(u32 hz) { + if (GetConsoleType() != HorizonOCConsoleType_Hoag) { + DisplayRefresh_GetRate(&hz, false); + return hz; + } + return 60; + } + + u32 GetHz(SysClkModule module) { + Result rc = 0; + u32 hz = 0; + + if (module == HorizonOCModule_Display) { + return GetDisplayRate(); + } + + if (HOSSVC_HAS_CLKRST) { + ClkrstSession session = {}; + + rc = clkrstOpenSession(&session, GetPcvModuleId(module), 3); + ASSERT_RESULT_OK(rc, "clkrstOpenSession"); + + rc = clkrstGetClockRate(&session, &hz); + ASSERT_RESULT_OK(rc, "clkrstGetClockRate"); + + clkrstCloseSession(&session); + } else { + rc = pcvGetClockRate(GetPcvModule(module), &hz); + ASSERT_RESULT_OK(rc, "pcvGetClockRate"); + } + + return hz; + } + + u32 GetRealHz(SysClkModule module) { + u32 hz = 0; + switch(module) { + case SysClkModule_CPU: + return t210ClkCpuFreq(); + case SysClkModule_GPU: + return t210ClkGpuFreq(); + case SysClkModule_MEM: + return t210ClkMemFreq(); + case HorizonOCModule_Display: + return GetDisplayRate(); + return hz; + default: + ASSERT_ENUM_VALID(SysClkModule, module); + } + + return 0; + } + + void GetFreqList(SysClkModule module, u32 *outList, u32 maxCount, u32 *outCount) { + Result rc = 0; + PcvClockRatesListType type; + s32 tmpInMaxCount = maxCount; + s32 tmpOutCount = 0; + + + if (HOSSVC_HAS_CLKRST) { + ClkrstSession session = {}; + + rc = clkrstOpenSession(&session, GetPcvModuleId(module), 3); + ASSERT_RESULT_OK(rc, "clkrstOpenSession"); + + rc = clkrstGetPossibleClockRates(&session, outList, tmpInMaxCount, &type, &tmpOutCount); + ASSERT_RESULT_OK(rc, "clkrstGetPossibleClockRates"); + + clkrstCloseSession(&session); + } else { + rc = pcvGetPossibleClockRates(GetPcvModule(module), outList, tmpInMaxCount, &type, &tmpOutCount); + ASSERT_RESULT_OK(rc, "pcvGetPossibleClockRates"); + } + + if (type != PcvClockRatesListType_Discrete) { + ERROR_THROW("Unexpected PcvClockRatesListType: %u (module = %s)", type, GetModuleName(module, false)); + } + + *outCount = tmpOutCount; + } + + u32 GetHighestDockedDisplayRate() { + if (GetConsoleType() != HorizonOCConsoleType_Hoag) { + return DisplayRefresh_GetDockedHighestAllowed(); + } + + return 60; + } + + void ResetToStock() { + if(hosversionAtLeast(9,0,0)) { + std::uint32_t confId = 0; + rc = apmExtGetCurrentPerformanceConfiguration(&confId); + ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration"); + + SysClkApmConfiguration* apmConfiguration = nullptr; + for (size_t i = 0; sysclk_g_apm_configurations[i].id; ++i) { + if(sysclk_g_apm_configurations[i].id == confId) { + apmConfiguration = &sysclk_g_apm_configurations[i]; + break; + } + } + + if(!apmConfiguration) { + ERROR_THROW("Unknown apm configuration: %x", confId); + } + + SetHz(SysClkModule_CPU, apmConfiguration->cpu_hz); + SetHz(SysClkModule_GPU, apmConfiguration->gpu_hz); + SetHz(SysClkModule_MEM, apmConfiguration->mem_hz); + } else { + u32 mode = 0; + rc = apmExtGetPerformanceMode(&mode); + ASSERT_RESULT_OK(rc, "apmExtGetPerformanceMode"); + + rc = apmExtSysRequestPerformanceMode(mode); + ASSERT_RESULT_OK(rc, "apmExtSysRequestPerformanceMode"); + } + } + + void ResetToStockDisplay() { + if (GetConsoleType != HorizonOCConsoleType_Hoag) { + DisplayRefresh_SetRate(60); + } + } + +} diff --git a/Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.hpp b/Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.hpp new file mode 100644 index 00000000..30f42a66 --- /dev/null +++ b/Source/rewrite-hoc-clk/sysmodule/src/board/board_freq.hpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + +#pragma once +#include +#include +#include + +namespace board { + + void SetHz(SysClkModule module, u32 hz); + + u32 GetHz(SysClkModule module); + u32 GetRealHz(SysClkModule module); + u32 GetFreqList(SysClkModule module, u32 *outList, u32 maxCount, u32 *outCount); + u32 GetHighestDockedDisplayRate(); + + void ResetToStock(); + void ResetToStockDisplay(); + + template + void ResetToStockModule(Getter getHzFunc, SysClkModule module) { + Result rc = 0; + + if (hosversionAtLeast(9, 0, 0)) { + u32 confId = 0; + rc = apmExtGetCurrentPerformanceConfiguration(&confId); + ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration"); + + SysClkApmConfiguration* apmConfiguration = nullptr; + for (size_t i = 0; sysclk_g_apm_configurations[i].id; ++i) { + + if (sysclk_g_apm_configurations[i].id == confId) { + apmConfiguration = &sysclk_g_apm_configurations[i]; + break; + } + } + + if (!apmConfiguration) { + ERROR_THROW("Unknown apm configuration: %x", confId); + } + + SetHz(module, getHzFunc(*apmConfiguration)); + } else { + u32 mode = 0; + rc = apmExtGetPerformanceMode(&mode); + ASSERT_RESULT_OK(rc, "apmExtGetPerformanceMode"); + + rc = apmExtSysRequestPerformanceMode(mode); + ASSERT_RESULT_OK(rc, "apmExtSysRequestPerformanceMode"); + } + } + + inline void ResetToStockCpu() { + ResetToStockModule([](const SysClkApmConfiguration& cfg) {return cfg.cpu_hz; }, SysClkModule_CPU); + } + + inline void ResetToStockGpu() { + ResetToStockModule([](const SysClkApmConfiguration& cfg){ return cfg.gpu_hz; }, SysClkModule_GPU); + } + + inline void ResetToStockMem() { + ResetToStockModule([](const SysClkApmConfiguration& cfg){ return cfg.mem_hz; }, SysClkModule_MEM); + } + +} diff --git a/Source/rewrite-hoc-clk/sysmodule/src/board/board_name.cpp b/Source/rewrite-hoc-clk/sysmodule/src/board/board_name.cpp new file mode 100644 index 00000000..ca1e51d5 --- /dev/null +++ b/Source/rewrite-hoc-clk/sysmodule/src/board/board_name.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + +#include +#include + +namespace board { + + const char *GetModuleName(SysClkModule module, bool pretty) { + ASSERT_ENUM_VALID(SysClkModule, module); + return sysclkFormatModule(module, pretty); + } + + const char *GetProfileName(SysClkProfile profile, bool pretty) { + ASSERT_ENUM_VALID(SysClkProfile, profile); + return sysclkFormatProfile(profile, pretty); + } + + const char *GetThermalSensorName(SysClkThermalSensor sensor, bool pretty) { + ASSERT_ENUM_VALID(SysClkThermalSensor, sensor); + return sysclkFormatThermalSensor(sensor, pretty); + } + +} diff --git a/Source/rewrite-hoc-clk/sysmodule/src/board/board_name.hpp b/Source/rewrite-hoc-clk/sysmodule/src/board/board_name.hpp new file mode 100644 index 00000000..88a811be --- /dev/null +++ b/Source/rewrite-hoc-clk/sysmodule/src/board/board_name.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + +#pragma once + +#include +#include + +namespace board { + + const char *GetModuleName(SysClkModule module, bool pretty); + const char *GetProfileName(SysClkProfile profile, bool pretty); + const char *GetThermalSensorName(SysClkThermalSensor sensor, bool pretty); + +} diff --git a/Source/rewrite-hoc-clk/sysmodule/src/old_board.cpp b/Source/rewrite-hoc-clk/sysmodule/src/old_board.cpp index ef65b227..7c59fdb3 100644 --- a/Source/rewrite-hoc-clk/sysmodule/src/old_board.cpp +++ b/Source/rewrite-hoc-clk/sysmodule/src/old_board.cpp @@ -263,7 +263,6 @@ void Board::Initialize() threadCreate(&gpuLThread, gpuLoadThread, NULL, NULL, 0x1000, 0x3F, -2); threadStart(&gpuLThread); - leventClear(&threadexit); threadCreate(&cpuCore0Thread, CheckCore, &idletick0, NULL, 0x1000, 0x10, 0); threadCreate(&cpuCore1Thread, CheckCore, &idletick1, NULL, 0x1000, 0x10, 1);