diff --git a/Source/hoc-clk/sysmodule/src/tsensor/soctherm.cpp b/Source/hoc-clk/sysmodule/src/tsensor/soctherm.cpp index 26a1b43d..b483e8cf 100644 --- a/Source/hoc-clk/sysmodule/src/tsensor/soctherm.cpp +++ b/Source/hoc-clk/sysmodule/src/tsensor/soctherm.cpp @@ -24,6 +24,7 @@ #include #include "../board/board.hpp" +#include "../board/board_volt.hpp" #include "../file/file_utils.hpp" #include "../mapping/mem_map.hpp" #include "soctherm.hpp" @@ -480,8 +481,32 @@ namespace tsensor { if (!IsSensorEnabled()) { StartSensors(); + } + + /* Workaround for potential HW bug */ + /* Refer to TRM 40.3.1.3 TSOSC Vmin limitations */ + /* Vmins estimated. TODO: find the correct ones via community testing */ + + /* Get the CPU voltage*/ + u32 cpuVoltage = board::GetVoltage(HocClkVoltage_CPU) / 1000; + + /* Infered from stock voltage. We know that below stock is unreliable */ + constexpr u32 kEristaTSOSCVmin = 825; + constexpr u32 kMarikoTSOSCVmin = 620; + + /* Get the correct vmin for the hardware type currently used */ + u32 TSOSCVmin = board::GetSocType() == HocClkSocType_Mariko ? kMarikoTSOSCVmin : kEristaTSOSCVmin; + + /* Mark the sensor as invalid so HW can recalibrate it */ + if(cpuVoltage >= TSOSCVmin) { + WriteReg(socthermVa, SENSOR_VALID, 1); + } else { + WriteReg(socthermVa, SENSOR_VALID, 0); } + /* Wait for HW recalibration */ + svcSleepThread(25'000); + temps.cpu = TranslateTemp(ReadReg(socthermVa, SENSOR_TEMP1) >> 16); temps.gpu = TranslateTemp(ReadReg(socthermVa, SENSOR_TEMP1) & SENSOR_TEMP1_GPU_TEMP_MASK); temps.pllx = TranslateTemp(ReadReg(socthermVa, SENSOR_TEMP2) & SENSOR_TEMP2_PLLX_TEMP_MASK);