wip sleep fix

This commit is contained in:
souldbminersmwc
2026-03-31 19:34:54 -04:00
parent 4103777f48
commit 4358df0308
12 changed files with 157 additions and 81 deletions

View File

@@ -49,7 +49,6 @@ extern "C" {
#include "sysclk/config.h" #include "sysclk/config.h"
#include "sysclk/errors.h" #include "sysclk/errors.h"
#include "sysclk/psm_ext.h" #include "sysclk/psm_ext.h"
#include "sysclk/soctherm.hpp"
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -87,6 +87,9 @@ typedef enum
SysClkThermalSensor_Skin, SysClkThermalSensor_Skin,
HorizonOCThermalSensor_Battery, HorizonOCThermalSensor_Battery,
HorizonOCThermalSensor_PMIC, HorizonOCThermalSensor_PMIC,
HorizonOCThermalSensor_CPU,
HorizonOCThermalSensor_GPU,
HorizonOCThermalSensor_MEM,
SysClkThermalSensor_EnumMax SysClkThermalSensor_EnumMax
} SysClkThermalSensor; } SysClkThermalSensor;
@@ -209,7 +212,12 @@ static inline const char* sysclkFormatThermalSensor(SysClkThermalSensor thermSen
return pretty ? "BAT" : "battery"; return pretty ? "BAT" : "battery";
case HorizonOCThermalSensor_PMIC: case HorizonOCThermalSensor_PMIC:
return pretty ? "PMIC" : "pmic"; return pretty ? "PMIC" : "pmic";
case HorizonOCThermalSensor_CPU:
return pretty ? "CPU" : "cpu";
case HorizonOCThermalSensor_GPU:
return pretty ? "GPU" : "gpu";
case HorizonOCThermalSensor_MEM:
return pretty ? "MEM" : "mem";
default: default:
return NULL; return NULL;
} }

View File

@@ -1,46 +0,0 @@
/*
* Copyright (c) 2014 - 2019, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Mikko Perttunen <mperttunen@nvidia.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
* 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 <switch.h>
#include <sysclk.h>
namespace soctherm {
struct TSensorTemps {
s32 cpu;
s32 gpu;
s32 mem;
s32 pllx;
};
}

View File

@@ -3,7 +3,7 @@
"title_id": "0x00FF0000636C6BFF", "title_id": "0x00FF0000636C6BFF",
"title_id_range_min": "0x00FF0000636C6BFF", "title_id_range_min": "0x00FF0000636C6BFF",
"title_id_range_max": "0x00FF0000636C6BFF", "title_id_range_max": "0x00FF0000636C6BFF",
"main_thread_stack_size": "0x0000D000", "main_thread_stack_size": "0x0000C000",
"main_thread_priority": 16, "main_thread_priority": 16,
"default_cpu_id": 3, "default_cpu_id": 3,
"process_category": 1, "process_category": 1,

View File

@@ -40,7 +40,8 @@
#include "board_volt.hpp" #include "board_volt.hpp"
#include "board_misc.hpp" #include "board_misc.hpp"
#include "../soctherm.hpp" #include "../soctherm.hpp"
#include "../integrations.hpp"
#include "../file_utils.hpp"
namespace board { namespace board {
SysClkSocType gSocType; SysClkSocType gSocType;
@@ -52,6 +53,46 @@ namespace board {
u32 fd = 0, fd2 = 0; u32 fd = 0, fd2 = 0;
constexpr u32 pscDependencies[] = {PscPmModuleId_Display}; // Our dependencies
constexpr PscPmModuleId pscModuleId = (PscPmModuleId)692; // Our ID
static PscPmModule pscModule; // Module to listen for events with
Thread SleepWakeListener;
void SleepWakeEventListener(void *ptr) {
while (true) {
Result rc = eventWait(&pscModule.event, 10'000'000);
if (R_VALUE(rc) == KERNELRESULT(TimedOut))
continue;
if (R_VALUE(rc) == KERNELRESULT(Cancelled))
break;
PscPmState eventState;
u32 flags;
if (R_FAILED(pscPmModuleGetRequest(&pscModule, &eventState, &flags)))
break;
switch (eventState) {
case PscPmState_ReadySleep:
fileUtils::LogLine("Sleep");
soctherm::StopSensors();
break;
case PscPmState_ReadyAwaken:
fileUtils::LogLine("Wake");
soctherm::StartSensors();
break;
case PscPmState_ReadyShutdown:
fileUtils::LogLine("Shutdown");
soctherm::StopSensors();
break;
default:
break;
}
pscPmModuleAcknowledge(&pscModule, eventState);
}
}
void FetchHardwareInfos() { void FetchHardwareInfos() {
ReadFuses(fuseData); ReadFuses(fuseData);
SetGpuBracket(fuseData.gpuSpeedo, speedoBracket); SetGpuBracket(fuseData.gpuSpeedo, speedoBracket);
@@ -115,13 +156,13 @@ namespace board {
Result nvCheck = 1; Result nvCheck = 1;
if (R_SUCCEEDED(nvInitialize())) { if (R_SUCCEEDED(nvInitialize())) {
nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
Result nvCheck_sched = nvOpen(&fd2, "/dev/nvsched-ctrl"); // Result nvCheck_sched = nvOpen(&fd2, "/dev/nvsched-ctrl");
/* This can be improved. */ // /* This can be improved. */
NvSchedSucceed(nvCheck_sched); // NvSchedSucceed(nvCheck_sched);
if (R_SUCCEEDED(nvCheck_sched)) { // if (R_SUCCEEDED(nvCheck_sched)) {
SchedSetFD2(fd2); // SchedSetFD2(fd2);
} // }
} }
rc = rgltrInitialize(); rc = rgltrInitialize();
@@ -130,6 +171,16 @@ namespace board {
rc = pmdmntInitialize(); rc = pmdmntInitialize();
ASSERT_RESULT_OK(rc, "pmdmntInitialize"); ASSERT_RESULT_OK(rc, "pmdmntInitialize");
rc = pscmInitialize();
ASSERT_RESULT_OK(rc, "pscmInitialize");
rc = pscmGetPmModule(&pscModule, pscModuleId, pscDependencies, sizeof(pscDependencies)/sizeof(u32), true);
ASSERT_RESULT_OK(rc, "pscmGetPmModule");
threadCreate(&SleepWakeListener, SleepWakeEventListener, NULL, NULL, 0x1000, 0x0, 3);
threadStart(&SleepWakeListener);
StartLoad(nvCheck, fd); StartLoad(nvCheck, fd);
batteryInfoInitialize(); batteryInfoInitialize();
@@ -152,13 +203,16 @@ namespace board {
rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000); rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)"); ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr}; display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = (GetConsoleType() == HorizonOCConsoleType_Hoag), .isRetroSUPER = integrations::GetRETROSuperStatus()};
display::Initialize(&cfg); display::Initialize(&cfg);
CacheDfllData(); CacheDfllData();
} }
void Exit() { void Exit() {
soctherm::StopSensors();
if (HOSSVC_HAS_CLKRST) { if (HOSSVC_HAS_CLKRST) {
clkrstExit(); clkrstExit();
} else { } else {
@@ -184,9 +238,12 @@ namespace board {
rgltrExit(); rgltrExit();
batteryInfoExit(); batteryInfoExit();
pmdmntExit(); pmdmntExit();
nvExit();
display::Shutdown(); display::Shutdown();
nvExit();
threadClose(&SleepWakeListener);
pscPmModuleFinalize(&pscModule);
pscPmModuleClose(&pscModule);
pscmExit();
} }
SysClkSocType GetSocType() { SysClkSocType GetSocType() {
@@ -233,5 +290,4 @@ namespace board {
bool IsUsingRetroSuperDisplay() { bool IsUsingRetroSuperDisplay() {
return false; /* stub for now. */ return false; /* stub for now. */
} }
} }

View File

@@ -31,6 +31,7 @@
#include <battery.h> #include <battery.h>
#include <pwm.h> #include <pwm.h>
#include "board.hpp" #include "board.hpp"
#include "../soctherm.hpp"
namespace board { namespace board {
@@ -38,23 +39,50 @@ namespace board {
s32 millis = 0; s32 millis = 0;
BatteryChargeInfo info; BatteryChargeInfo info;
if (sensor == SysClkThermalSensor_SOC) { soctherm::TSensorTemps temps;
millis = tmp451TempSoc(); soctherm::ReadSensors(temps);
} else if (sensor == SysClkThermalSensor_PCB) {
millis = tmp451TempPcb(); switch(sensor) {
} else if (sensor == SysClkThermalSensor_Skin) { case SysClkThermalSensor_SOC: {
if (HOSSVC_HAS_TC) { millis = tmp451TempSoc();
Result rc; break;
rc = tcGetSkinTemperatureMilliC(&millis); }
ASSERT_RESULT_OK(rc, "tcGetSkinTemperatureMilliC"); case SysClkThermalSensor_PCB: {
millis = tmp451TempPcb();
break;
}
case SysClkThermalSensor_Skin: {
if (HOSSVC_HAS_TC) {
Result rc;
rc = tcGetSkinTemperatureMilliC(&millis);
ASSERT_RESULT_OK(rc, "tcGetSkinTemperatureMilliC");
}
break;
}
case HorizonOCThermalSensor_Battery: {
batteryInfoGetChargeInfo(&info);
millis = batteryInfoGetTemperatureMiliCelsius(&info);
break;
}
case HorizonOCThermalSensor_PMIC: {
millis = 50000;
break;
}
case HorizonOCThermalSensor_CPU: {
millis = temps.cpu;
break;
}
case HorizonOCThermalSensor_GPU: {
millis = temps.gpu;
break;
}
case HorizonOCThermalSensor_MEM: {
millis = board::GetSocType() == SysClkSocType_Mariko ? temps.pllx : temps.mem;
break;
}
default: {
ASSERT_ENUM_VALID(SysClkThermalSensor, sensor);
} }
} else if (sensor == HorizonOCThermalSensor_Battery) {
batteryInfoGetChargeInfo(&info);
millis = batteryInfoGetTemperatureMiliCelsius(&info);
/* } else if (sensor == HorizonOCThermalSensor_PMIC) {
millis = 50000; */
} else {
ASSERT_ENUM_VALID(SysClkThermalSensor, sensor);
} }
return std::max(0, millis); return std::max(0, millis);

View File

@@ -580,7 +580,7 @@ namespace clockManager {
integrations::LoadSaltyNX(); integrations::LoadSaltyNX();
} }
gContext.isUsingRetroSuper = board::IsUsingRetroSuperDisplay(); gContext.isUsingRetroSuper = integrations::GetRETROSuperStatus();
governor::startThreads(); governor::startThreads();
} }
@@ -616,6 +616,7 @@ namespace clockManager {
void Tick() void Tick()
{ {
fileUtils::LogLine("CPU Temp: %d", board::GetTemperatureMilli(HorizonOCThermalSensor_CPU));
std::scoped_lock lock{gContextMutex}; std::scoped_lock lock{gContextMutex};
std::uint32_t mode = 0; std::uint32_t mode = 0;
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode); Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
@@ -633,7 +634,7 @@ namespace clockManager {
void WaitForNextTick() void WaitForNextTick()
{ {
if (!(board::GetHz(SysClkModule_MEM) < 665000000)) if (board::GetHz(SysClkModule_MEM) > 665000000)
svcSleepThread(config::GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL); svcSleepThread(config::GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL);
else else
svcSleepThread(5000 * 1000000ULL); // 5 seconds in sleep mode svcSleepThread(5000 * 1000000ULL); // 5 seconds in sleep mode

View File

@@ -95,6 +95,11 @@ namespace integrations {
return stat("sdmc:/atmosphere/contents/0000000000534C56/flags/boot2.flag", &st) == 0; return stat("sdmc:/atmosphere/contents/0000000000534C56/flags/boot2.flag", &st) == 0;
} }
bool GetRETROSuperStatus() {
struct stat st = {0};
return stat("sdmc:/config/horizon-oc/retro.flag", &st) == 0;
}
void LoadSaltyNX() { void LoadSaltyNX() {
if (!CheckSaltyNXPort()) if (!CheckSaltyNXPort())
return; return;

View File

@@ -70,6 +70,7 @@ namespace integrations {
bool GetSysDockState(); bool GetSysDockState();
bool GetSaltyNXState(); bool GetSaltyNXState();
bool GetRETROSuperStatus();
void LoadSaltyNX(); void LoadSaltyNX();
u8 GetSaltyNXFPS(); u8 GetSaltyNXFPS();
u16 GetSaltyNXResolutionHeight(); u16 GetSaltyNXResolutionHeight();

View File

@@ -37,7 +37,7 @@
#include "clock_manager.hpp" #include "clock_manager.hpp"
#include "ipc_service.hpp" #include "ipc_service.hpp"
#include "config.hpp" #include "config.hpp"
#define INNER_HEAP_SIZE 0x40000 #define INNER_HEAP_SIZE 0x45000
extern "C" extern "C"

View File

@@ -418,7 +418,7 @@ namespace soctherm {
}; };
u32 calib[SocthermTSensor_EnumMax] = {}; u32 calib[SocthermTSensor_EnumMax] = {};
u64 socthermVa; u64 socthermVa, carVa, fuseVa;
bool isMariko; bool isMariko;
} }
@@ -509,6 +509,22 @@ namespace soctherm {
} }
} }
void StopSensors() {
const TSensor *sensors = isMariko ? marikoTSensors : eristaTSensors;
u32 count = isMariko ? std::size(marikoTSensors) : std::size(eristaTSensors);
for (u32 i = 0; i < count; ++i) {
SetBits(socthermVa, sensors[i].base + SENSOR_CONFIG0, SENSOR_CONFIG0_STOP);
ClearBits(socthermVa, sensors[i].base + SENSOR_CONFIG1, SENSOR_CONFIG1_TEMP_ENABLE);
WriteReg(socthermVa, sensors[i].base + SENSOR_CONFIG2, 0);
}
WriteReg(socthermVa, TSENSOR_TSENSOR_CLKEN, 0);
WriteReg(carVa, CAR_CLK_SOURCE_TSENSOR, 0);
SetBits(carVa, CAR_CLK_OUT_ENB_V, 0);
}
void StartSensors() { void StartSensors() {
if (!ReadReg(socthermVa, TSENSOR_TSENSOR_CLKEN)) { if (!ReadReg(socthermVa, TSENSOR_TSENSOR_CLKEN)) {
u32 pdiv, hotspot; u32 pdiv, hotspot;
@@ -597,7 +613,6 @@ namespace soctherm {
} }
void Initialize() { void Initialize() {
u64 carVa, fuseVa;
isMariko = board::GetSocType() == SysClkSocType_Mariko; isMariko = board::GetSocType() == SysClkSocType_Mariko;
constexpr u64 SocthermPa = 0x700E2000, FusePa = 0x7000F000, CarPa = 0x60006000; constexpr u64 SocthermPa = 0x700E2000, FusePa = 0x7000F000, CarPa = 0x60006000;

View File

@@ -122,7 +122,16 @@ namespace soctherm {
SocthermTSensor_EnumMax = 8, SocthermTSensor_EnumMax = 8,
}; };
struct TSensorTemps {
s32 cpu;
s32 gpu;
s32 mem;
s32 pllx;
};
void Initialize(); void Initialize();
void StartSensors();
void StopSensors();
void ReadSensors(TSensorTemps &temps); void ReadSensors(TSensorTemps &temps);
} }