sysclk: finish display refresh rate change support
This commit is contained in:
@@ -229,15 +229,14 @@ void Board::Initialize()
|
||||
}
|
||||
|
||||
u64 clkVirtAddr, dsiVirtAddr, outsize;
|
||||
Result rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000);
|
||||
rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000);
|
||||
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (clk)");
|
||||
Result rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
|
||||
rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
|
||||
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
|
||||
|
||||
DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr};
|
||||
|
||||
DisplayRefresh_Initialize(&cfg);
|
||||
|
||||
FetchHardwareInfos();
|
||||
}
|
||||
|
||||
@@ -308,6 +307,11 @@ void Board::SetHz(SysClkModule module, std::uint32_t hz)
|
||||
{
|
||||
Result rc = 0;
|
||||
|
||||
if(module == HorizonOCModule_Display) {
|
||||
DisplayRefresh_SetRate(hz);
|
||||
return;
|
||||
}
|
||||
|
||||
if(HOSSVC_HAS_CLKRST)
|
||||
{
|
||||
ClkrstSession session = {0};
|
||||
@@ -332,6 +336,11 @@ std::uint32_t Board::GetHz(SysClkModule module)
|
||||
Result rc = 0;
|
||||
std::uint32_t hz = 0;
|
||||
|
||||
if(module == HorizonOCModule_Display) {
|
||||
DisplayRefresh_GetRate(&hz, false);
|
||||
return hz;
|
||||
}
|
||||
|
||||
if(HOSSVC_HAS_CLKRST)
|
||||
{
|
||||
ClkrstSession session = {0};
|
||||
@@ -355,6 +364,7 @@ std::uint32_t Board::GetHz(SysClkModule module)
|
||||
|
||||
std::uint32_t Board::GetRealHz(SysClkModule module)
|
||||
{
|
||||
u32 hz = 0;
|
||||
switch(module)
|
||||
{
|
||||
case SysClkModule_CPU:
|
||||
@@ -363,6 +373,9 @@ std::uint32_t Board::GetRealHz(SysClkModule module)
|
||||
return t210ClkGpuFreq();
|
||||
case SysClkModule_MEM:
|
||||
return t210ClkMemFreq();
|
||||
case HorizonOCModule_Display:
|
||||
DisplayRefresh_GetRate(&hz, false);
|
||||
return hz;
|
||||
default:
|
||||
ASSERT_ENUM_VALID(SysClkModule, module);
|
||||
}
|
||||
@@ -377,6 +390,8 @@ void Board::GetFreqList(SysClkModule module, std::uint32_t* outList, std::uint32
|
||||
s32 tmpInMaxCount = maxCount;
|
||||
s32 tmpOutCount = 0;
|
||||
|
||||
|
||||
|
||||
if(HOSSVC_HAS_CLKRST)
|
||||
{
|
||||
ClkrstSession session = {0};
|
||||
@@ -552,6 +567,11 @@ void Board::ResetToStockGpu()
|
||||
ASSERT_RESULT_OK(rc, "apmExtSysRequestPerformanceMode");
|
||||
}
|
||||
}
|
||||
|
||||
void Board::ResetToStockDisplay() {
|
||||
DisplayRefresh_SetRate(60);
|
||||
}
|
||||
|
||||
std::uint32_t Board::GetTemperatureMilli(SysClkThermalSensor sensor)
|
||||
{
|
||||
std::int32_t millis = 0;
|
||||
|
||||
@@ -43,6 +43,7 @@ class Board
|
||||
static void ResetToStockCpu();
|
||||
static void ResetToStockMem();
|
||||
static void ResetToStockGpu();
|
||||
static void ResetToStockDisplay();
|
||||
|
||||
static SysClkProfile GetProfile();
|
||||
static void SetHz(SysClkModule module, std::uint32_t hz);
|
||||
|
||||
@@ -312,7 +312,8 @@ void ClockManager::GovernorThread(void* arg)
|
||||
targetHz = mgr->config->GetAutoClockHz(
|
||||
mgr->context->applicationId,
|
||||
SysClkModule_GPU,
|
||||
mgr->context->profile
|
||||
mgr->context->profile,
|
||||
false
|
||||
);
|
||||
|
||||
if (!targetHz)
|
||||
@@ -320,7 +321,8 @@ void ClockManager::GovernorThread(void* arg)
|
||||
targetHz = mgr->config->GetAutoClockHz(
|
||||
GLOBAL_PROFILE_ID,
|
||||
SysClkModule_GPU,
|
||||
mgr->context->profile
|
||||
mgr->context->profile,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -410,15 +412,19 @@ void ClockManager::Tick()
|
||||
ResetToStockClocks();
|
||||
return;
|
||||
}
|
||||
|
||||
bool returnRaw = false;
|
||||
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
{
|
||||
if(module > SysClkModule_MEM)
|
||||
returnRaw = true;
|
||||
else
|
||||
returnRaw = false;
|
||||
targetHz = this->context->overrideFreqs[module];
|
||||
if (!targetHz)
|
||||
{
|
||||
targetHz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile);
|
||||
targetHz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile, returnRaw);
|
||||
if(!targetHz)
|
||||
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, (SysClkModule)module, this->context->profile);
|
||||
targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, (SysClkModule)module, this->context->profile, returnRaw);
|
||||
}
|
||||
|
||||
if(module == HorizonOCModule_Governor) {
|
||||
@@ -427,14 +433,20 @@ void ClockManager::Tick()
|
||||
FileUtils::LogLine("[mgr] Governor state changed: %s", newGovernorState ? "enabled" : "disabled");
|
||||
lastGovernorState = newGovernorState;
|
||||
|
||||
// Force a "context refresh" like on app/profile change
|
||||
hasChanged = true;
|
||||
this->context->enabled = this->GetConfig()->Enabled();
|
||||
Board::ResetToStock(); // optional: reset clocks before re-applying
|
||||
Board::ResetToStock();
|
||||
}
|
||||
isGovernorEnabled = newGovernorState;
|
||||
}
|
||||
|
||||
if(module == HorizonOCModule_Display) {
|
||||
if(targetHz)
|
||||
Board::SetHz(HorizonOCModule_Display, targetHz);
|
||||
else
|
||||
Board::ResetToStockDisplay();
|
||||
}
|
||||
|
||||
// Skip GPU if governor handles it
|
||||
if(module > SysClkModule_MEM) {
|
||||
continue;
|
||||
|
||||
@@ -138,7 +138,7 @@ std::uint32_t Config::FindClockMHz(std::uint64_t tid, SysClkModule module, SysCl
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::uint32_t Config::FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles)
|
||||
std::uint32_t Config::FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles, u32 mhzMultiplier)
|
||||
{
|
||||
std::uint32_t mhz = 0;
|
||||
|
||||
@@ -155,23 +155,23 @@ std::uint32_t Config::FindClockHzFromProfiles(std::uint64_t tid, SysClkModule mo
|
||||
}
|
||||
}
|
||||
|
||||
return std::max((std::uint32_t)0, mhz * 1000000);
|
||||
return std::max((std::uint32_t)0, mhz * mhzMultiplier);
|
||||
}
|
||||
|
||||
std::uint32_t Config::GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile)
|
||||
std::uint32_t Config::GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile, bool returnRaw)
|
||||
{
|
||||
std::scoped_lock lock{this->configMutex};
|
||||
switch(profile)
|
||||
{
|
||||
case SysClkProfile_Handheld:
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Handheld});
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Handheld}, returnRaw ? 1 : 1000000);
|
||||
case SysClkProfile_HandheldCharging:
|
||||
case SysClkProfile_HandheldChargingUSB:
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingUSB, SysClkProfile_HandheldCharging, SysClkProfile_Handheld});
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingUSB, SysClkProfile_HandheldCharging, SysClkProfile_Handheld}, returnRaw ? 1 : 1000000);
|
||||
case SysClkProfile_HandheldChargingOfficial:
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingOfficial, SysClkProfile_HandheldCharging, SysClkProfile_Handheld});
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_HandheldChargingOfficial, SysClkProfile_HandheldCharging, SysClkProfile_Handheld}, returnRaw ? 1 : 1000000);
|
||||
case SysClkProfile_Docked:
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Docked});
|
||||
return FindClockHzFromProfiles(tid, module, {SysClkProfile_Docked}, returnRaw ? 1 : 1000000);
|
||||
default:
|
||||
ERROR_THROW("Unhandled SysClkProfile: %u", profile);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class Config
|
||||
std::uint8_t GetProfileCount(std::uint64_t tid);
|
||||
void GetProfiles(std::uint64_t tid, SysClkTitleProfileList* out_profiles);
|
||||
bool SetProfiles(std::uint64_t tid, SysClkTitleProfileList* profiles, bool immediate);
|
||||
std::uint32_t GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile);
|
||||
std::uint32_t GetAutoClockHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile, bool returnRaw);
|
||||
|
||||
void SetEnabled(bool enabled);
|
||||
bool Enabled();
|
||||
@@ -76,7 +76,7 @@ class Config
|
||||
bool kipOverride[SysClkConfigValue_EnumMax];
|
||||
time_t CheckModificationTime();
|
||||
std::uint32_t FindClockMHz(std::uint64_t tid, SysClkModule module, SysClkProfile profile);
|
||||
std::uint32_t FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles);
|
||||
std::uint32_t FindClockHzFromProfiles(std::uint64_t tid, SysClkModule module, std::initializer_list<SysClkProfile> profiles, u32 mhzMultiplier = 1000000);
|
||||
static int BrowseIniFunc(const char* section, const char* key, const char* value, void* userdata);
|
||||
|
||||
std::map<std::tuple<std::uint64_t, SysClkProfile, SysClkModule>, std::uint32_t> profileMHzMap;
|
||||
|
||||
Reference in New Issue
Block a user