From 5ef56bed2545f6800f4707fccbf55a69c29f6e5f Mon Sep 17 00:00:00 2001 From: souldbminersmwc Date: Thu, 12 Feb 2026 16:15:25 -0500 Subject: [PATCH] sysclk: remove live timing update and fix profile change dvfs bug --- Source/sys-clk/common/include/sysclk/ipc.h | 2 - Source/sys-clk/common/src/client/ipc.c | 11 -- .../sys-clk/overlay/src/ui/gui/misc_gui.cpp | 31 ---- Source/sys-clk/sysmodule/src/board.cpp | 156 ------------------ Source/sys-clk/sysmodule/src/board.h | 1 - .../sys-clk/sysmodule/src/clock_manager.cpp | 43 +---- Source/sys-clk/sysmodule/src/clock_manager.h | 1 - Source/sys-clk/sysmodule/src/ipc_service.cpp | 13 +- Source/sys-clk/sysmodule/src/ipc_service.h | 2 - 9 files changed, 9 insertions(+), 251 deletions(-) diff --git a/Source/sys-clk/common/include/sysclk/ipc.h b/Source/sys-clk/common/include/sysclk/ipc.h index 600a6ad8..f5f0016b 100644 --- a/Source/sys-clk/common/include/sysclk/ipc.h +++ b/Source/sys-clk/common/include/sysclk/ipc.h @@ -51,8 +51,6 @@ enum SysClkIpcCmd SysClkIpcCmd_SetReverseNXRTMode = 12, HocClkIpcCmd_SetKipData = 13, HocClkIpcCmd_GetKipData = 14, - HocClkIpcCmd_UpdateEmcRegs = 15, - HocClkIpcCmd_CalculateGpuVmin = 16, }; diff --git a/Source/sys-clk/common/src/client/ipc.c b/Source/sys-clk/common/src/client/ipc.c index 74014a1f..ed3fa55f 100644 --- a/Source/sys-clk/common/src/client/ipc.c +++ b/Source/sys-clk/common/src/client/ipc.c @@ -169,15 +169,4 @@ Result hocClkIpcGetKipData() { u32 temp = 0; return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_GetKipData, temp); -} - -Result hocClkIpcUpdateEmcRegs() -{ - u32 temp = 0; - return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_UpdateEmcRegs, temp); -} -Result hocClkIpcCalculateGpuVmin() -{ - u32 temp = 0; - return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_CalculateGpuVmin, temp); } \ No newline at end of file diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp index 7aeda2fa..9f38c408 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -713,37 +713,6 @@ protected: this->listElement->addItem(new tsl::elm::CategoryHeader("Advanced")); addConfigButton(KipConfigValue_t6_tRTW_fine_tune, "t6 tRTW Fine Tune", ValueRange(0, 4, 1, "", 0), "tRTW Fine Tune", &thresholdsDisabled, {}, t6_tRTW_fine_tune, false); addConfigButton(KipConfigValue_t7_tWTR_fine_tune, "t7 tWTR Fine Tune", ValueRange(0, 6, 1, "", 0), "tWTR Fine Tune", &thresholdsDisabled, {}, t7_tWTR_fine_tune, false); - - #if IS_MINIMAL == 0 - if(IsMariko()) { - this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); - - tsl::elm::ListItem* emcUpdBtn = new tsl::elm::ListItem("Update RAM Timings"); - emcUpdBtn->setClickListener([this](u64 keys) { - if (keys & HidNpadButton_A) { - if(this->context->freqs[SysClkModule_MEM] > 1600000000) { - Result rc = hocClkIpcUpdateEmcRegs(); - if (R_FAILED(rc)) { - FatalGui::openWithResultCode("hocClkIpcUpdateEmcRegs", rc); - return false; - } - return true; - } else { - writeNotification("Horizon OC\nSet your ram frequency to max\nbefore applying timings!"); - } - } - return false; - }); - - this->listElement->addItem(emcUpdBtn); - tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { - renderer->drawString("\uE150 This feature is EXPERIMENTAL", false, x + 20, y + 30, 18, tsl::style::color::ColorText); - renderer->drawString("and should only be used for testing!", false, x + 20, y + 50, 18, tsl::style::color::ColorText); - }); - warningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 70); - this->listElement->addItem(warningText); - } - #endif } }; diff --git a/Source/sys-clk/sysmodule/src/board.cpp b/Source/sys-clk/sysmodule/src/board.cpp index 42134190..1848fd07 100644 --- a/Source/sys-clk/sysmodule/src/board.cpp +++ b/Source/sys-clk/sysmodule/src/board.cpp @@ -1111,162 +1111,6 @@ void Board::PcvHijackDvfs(u32 vmin) { #define MC_REGISTER_BASE 0x70019000 #define MC_REGISTER_REGION_SIZE 0x1000 -#define EMC_REGISTER_BASE 0x7001b000 -#define EMC_REGISTER_REGION_SIZE 0x1000 - -#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg)) - -#define WRITE_REGISTER_EMC(TIMING_OFFSET, VALUE) \ - do { \ - args = {}; \ - args.X[0] = 0xF0000002; \ - args.X[1] = EMC_REGISTER_BASE + (TIMING_OFFSET); \ - args.X[2] = 0xFFFFFFFF; \ - args.X[3] = (VALUE); \ - svcCallSecureMonitor(&args); \ - } while (false) - -#define WRITE_REGISTER_MC(TIMING_OFFSET, VALUE) \ - do { \ - args = {}; \ - args.X[0] = 0xF0000002; \ - args.X[1] = MC_REGISTER_BASE + (TIMING_OFFSET); \ - args.X[2] = 0xFFFFFFFF; \ - args.X[3] = (VALUE); \ - svcCallSecureMonitor(&args); \ - } while (false) - - -// NOTE: needs patch to exosphere to expose emc region to secmon. MC does NOT need this patch - -u32 tRCD_values[] = { 18, 17, 16, 15, 14, 13, 12, 11 }; -u32 tRP_values[] = { 18, 17, 16, 15, 14, 13, 12, 11 }; -u32 tRAS_values[] = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 }; -double tRRD_values[] = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? */ -u32 tRFC_values[] = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 }; -u32 tWTR_values[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; -u32 tREFpb_values[] = { 3900, 5850, 7800, 11700, 15600, 99999 }; - -// Credit to Lightos for these timings! - - -void Board::UpdateShadowRegs(u32 tRCD_i, u32 tRP_i, u32 tRAS_i, u32 tRRD_i, u32 tRFC_i, u32 tRTW_i, u32 tWTR_i, u32 tREFpb_i, u32 ramFreq, u32 rlAdd, u32 wlAdd, bool hpMode) { - // timing stuff - - SecmonArgs args = {}; - - constexpr double MC_ARB_DIV = 4.0; - constexpr u32 MC_ARB_SFA = 2; - - double tCK_avg = 1000'000.0 / ramFreq; - u32 BL = 16; - u32 RL = 28 + rlAdd; - u32 WL = 14 + wlAdd; - u32 RL_DBI = RL + 4; - - u32 tRCD = tRCD_values[tRCD_i]; - u32 tRPpb = tRP_values[tRP_i]; - u32 tRAS = tRAS_values[tRAS_i]; - double tRRD = tRRD_values[tRRD_i]; - u32 tRFCpb = tRFC_values[tRFC_i]; - u32 tWTR = 10 - tWTR_values[tWTR_i]; - u32 tFAW = static_cast(tRRD * 4.0); - - double tDQSCK_max = 3.5; - u32 tWPRE = 2; - - double tRPST = 0.5; - - u32 tR2W = CEIL(RL_DBI + (tDQSCK_max / tCK_avg) + (BL / 2) - WL + tWPRE + FLOOR(tRPST) + 9.0) - (tRTW_i * 3); - - u32 tRC = tRAS + tRPpb; - u32 tRFCab = tRFCpb * 2; - u32 tRPab = tRPpb + 3; - - u32 tW2R = CEIL(MAX(WL + (0.010322547033278747 * (ramFreq / 1000.0)), (WL * -0.2067922202979121) + FLOOR(((RL_DBI * -0.1331159971685554) + WL) * 3.654131957826108)) - (tWTR / tCK_avg)); - - double tMMRI = tRCD + (tCK_avg * 3); - double pdex2mrr = tMMRI + 10; - u32 emc_cfg = hpMode ? 0x13200000 : 0xF3200000; - - u32 refresh_raw = 0xFFFF; - if (tREFpb_i != 6) { - refresh_raw = CEIL(tREFpb_values[tREFpb_i] / tCK_avg) - 0x40; - refresh_raw = MIN(refresh_raw, static_cast(0xFFFF)); - } - - u32 trefbw = refresh_raw + 0x40; - trefbw = MIN(trefbw, static_cast(0x3FFF)); - - u32 tR2P = 12 + (rlAdd / 2); - u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5; - - double tXSR = (double) (tRFCab + 7.5); - - args = {}; - args.X[0] = 0xF0000002; - args.X[1] = EMC_REGISTER_BASE + EMC_INTSTATUS_0; - svcCallSecureMonitor(&args); - - if(args.X[1] == (EMC_REGISTER_BASE + EMC_INTSTATUS_0)) { // if param 1 is identical read failed, exosphere needs patch! - writeNotification("Horizon OC\nExosphere not patched\nfor EMC r/w"); - return; - } - - // actually write the timings - WRITE_REGISTER_EMC(EMC_CFG_0, emc_cfg); - WRITE_REGISTER_EMC(EMC_RD_RCD_0, GET_CYCLE_CEIL(tRCD)); - WRITE_REGISTER_EMC(EMC_WR_RCD_0, GET_CYCLE_CEIL(tRCD)); - WRITE_REGISTER_EMC(EMC_RC_0, MIN(GET_CYCLE_CEIL(tRC), static_cast(0xB8))); - WRITE_REGISTER_EMC(EMC_RAS_0, MIN(GET_CYCLE_CEIL(tRAS), static_cast(0x7F))); - WRITE_REGISTER_EMC(EMC_RRD_0, GET_CYCLE_CEIL(tRRD)); - WRITE_REGISTER_EMC(EMC_RFCPB_0, GET_CYCLE_CEIL(tRFCpb)); - WRITE_REGISTER_EMC(EMC_RFC_0, GET_CYCLE_CEIL(tRFCab)); - WRITE_REGISTER_EMC(EMC_RP_0, GET_CYCLE_CEIL(tRPpb)); - WRITE_REGISTER_EMC(EMC_TRPAB_0, MIN(GET_CYCLE_CEIL(tRPab), static_cast(0x3F))); - WRITE_REGISTER_EMC(EMC_R2W_0, tR2W); - WRITE_REGISTER_EMC(EMC_W2R_0, tW2R); - WRITE_REGISTER_EMC(EMC_REFRESH_0, refresh_raw); - WRITE_REGISTER_EMC(EMC_PRE_REFRESH_REQ_CNT_0, refresh_raw / 4); - WRITE_REGISTER_EMC(EMC_TREFBW_0, trefbw); - WRITE_REGISTER_EMC(EMC_PDEX2MRR_0, GET_CYCLE_CEIL(pdex2mrr)); - WRITE_REGISTER_EMC(EMC_TXSR_0, MIN(GET_CYCLE_CEIL(tXSR), static_cast(0x3fe))); - WRITE_REGISTER_EMC(EMC_TXSRDLL_0, MIN(GET_CYCLE_CEIL(tXSR), static_cast(0x3fe))); - - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RCD_0, CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RP_0, CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RC_0, CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RAS_0, CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_FAW_0, CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RRD_0, CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RFCPB_0, CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1); - - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_R2W_0, CEIL(tR2W / MC_ARB_DIV) - 1 + MC_ARB_SFA); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_W2R_0, CEIL(tW2R / MC_ARB_DIV) - 1 + MC_ARB_SFA); - - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_RAP2PRE_0, CEIL(tR2P / MC_ARB_DIV)); - WRITE_REGISTER_MC(MC_EMEM_ARB_TIMING_WAP2PRE_0, CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA); - - u32 da_turns = 0; - da_turns |= u8((CEIL(tR2W / MC_ARB_DIV) - 1 + MC_ARB_SFA) / 2) << 16; - da_turns |= u8((CEIL(tW2R / MC_ARB_DIV) - 1 + MC_ARB_SFA) / 2) << 24; - WRITE_REGISTER_MC(MC_EMEM_ARB_DA_TURNS_0, da_turns); - - u32 da_covers = 0; - u8 r_cover = ((CEIL(tR2P / MC_ARB_DIV)) + (CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1) + (CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2)) / 2; - u8 w_cover = ((CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA) + (CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1) + (CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2)) / 2; - da_covers |= ((u32)(CEIL(GET_CYCLE_CEIL(tRC) / (u32)MC_ARB_DIV) - 1) / 2); - da_covers |= (r_cover << 8); - da_covers |= (w_cover << 16); - - WRITE_REGISTER_MC(MC_EMEM_ARB_DA_COVERS_0, da_covers); - // TODO: modify mc_emem_arb_misc0 - - WRITE_REGISTER_MC(MC_TIMING_CONTROL_0, 0x1); // update timing regs as they are shadowed - WRITE_REGISTER_EMC(EMC_TIMING_CONTROL_0, 0x1); -} - - bool Board::IsDram8GB() { SecmonArgs args = {}; args.X[0] = 0xF0000002; diff --git a/Source/sys-clk/sysmodule/src/board.h b/Source/sys-clk/sysmodule/src/board.h index 07e1d8ba..5f515797 100644 --- a/Source/sys-clk/sysmodule/src/board.h +++ b/Source/sys-clk/sysmodule/src/board.h @@ -63,7 +63,6 @@ class Board static std::uint32_t GetVoltage(HocClkVoltage voltage); static u8 GetFanRotationLevel(); static u8 GetDramID(); - static void UpdateShadowRegs(u32 tRCD_i, u32 tRP_i, u32 tRAS_i, u32 tRRD_i, u32 tRFC_i, u32 tRTW_i, u32 tWTR_i, u32 tREFpb_i, u32 ramFreq, u32 rlAdd, u32 wlAdd, bool hpMode); static bool IsDram8GB(); protected: static void FetchHardwareInfos(); diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index 2ef83dc9..c74ff44c 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -656,6 +656,11 @@ bool ClockManager::RefreshContext() { // this->rnxSync->ToggleSync(this->GetConfig()->GetConfigValue(HocClkConfigValue_SyncReverseNXMode)); Board::ResetToStock(); + if (Board::GetSocType() == SysClkSocType_Mariko && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) { + Board::PcvHijackDvfs(0); + Board::SetHz(SysClkModule_GPU, ~0); + Board::ResetToStockGpu(); + } this->WaitForNextTick(); } @@ -694,21 +699,8 @@ bool ClockManager::RefreshContext() if (Board::GetSocType() == SysClkSocType_Mariko && this->config->GetConfigValue(HorizonOCConfigValue_DVFSMode) == DVFSMode_Hijack) { Board::PcvHijackDvfs(0); - - u32 targetHz = this->context->overrideFreqs[SysClkModule_GPU]; - if (!targetHz) - { - targetHz = this->config->GetAutoClockHz(this->context->applicationId, SysClkModule_GPU, this->context->profile, false); - if(!targetHz) - targetHz = this->config->GetAutoClockHz(GLOBAL_PROFILE_ID, SysClkModule_GPU, this->context->profile, false); - } - if(targetHz) { - Board::SetHz(SysClkModule_GPU, ~0); - Board::SetHz(SysClkModule_GPU, targetHz); - } else { - Board::SetHz(SysClkModule_GPU, ~0); - Board::ResetToStockGpu(); - } + Board::SetHz(SysClkModule_GPU, ~0); + Board::ResetToStockGpu(); } break; @@ -1070,23 +1062,4 @@ void ClockManager::GetKipData() { FileUtils::LogLine("[clock_manager] Config refresh error in GetKipData!"); writeNotification("Horizon OC\nConfig refresh failed"); } -} - -void ClockManager::UpdateRamTimings() { - u32 t1_tRCD = this->config->GetConfigValue(KipConfigValue_t1_tRCD); - u32 t2_tRP = this->config->GetConfigValue(KipConfigValue_t2_tRP); - u32 t3_tRAS = this->config->GetConfigValue(KipConfigValue_t3_tRAS); - u32 t4_tRRD = this->config->GetConfigValue(KipConfigValue_t4_tRRD); - u32 t5_tRFC = this->config->GetConfigValue(KipConfigValue_t5_tRFC); - u32 t6_tRTW = this->config->GetConfigValue(KipConfigValue_t6_tRTW); - u32 t7_tWTR = this->config->GetConfigValue(KipConfigValue_t7_tWTR); - u32 t8_tREFI = this->config->GetConfigValue(KipConfigValue_t8_tREFI); - bool hpMode = (bool)this->config->GetConfigValue(KipConfigValue_hpMode); - - u64 ramFreq = initialConfigValues[KipConfigValue_marikoEmcMaxClock]; - u32 rlAdd = initialConfigValues[KipConfigValue_mem_burst_read_latency]; - u32 wlAdd = initialConfigValues[KipConfigValue_mem_burst_write_latency]; - - - Board::UpdateShadowRegs(t1_tRCD, t2_tRP, t3_tRAS, t4_tRRD, t5_tRFC, t6_tRTW, t7_tWTR, t8_tREFI, ramFreq, rlAdd, wlAdd, hpMode); -} +} \ No newline at end of file diff --git a/Source/sys-clk/sysmodule/src/clock_manager.h b/Source/sys-clk/sysmodule/src/clock_manager.h index 408053c6..7af5c539 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.h +++ b/Source/sys-clk/sysmodule/src/clock_manager.h @@ -63,7 +63,6 @@ class ClockManager void SetKipData(); void GetKipData(); static void GovernorThread(void* arg); - void UpdateRamTimings(); struct { std::uint32_t count; std::uint32_t list[SYSCLK_FREQ_LIST_MAX]; diff --git a/Source/sys-clk/sysmodule/src/ipc_service.cpp b/Source/sys-clk/sysmodule/src/ipc_service.cpp index 34a4aa08..0877882c 100644 --- a/Source/sys-clk/sysmodule/src/ipc_service.cpp +++ b/Source/sys-clk/sysmodule/src/ipc_service.cpp @@ -209,11 +209,6 @@ Result IpcService::ServiceHandlerFunc(void* arg, const IpcServerRequest* r, u8* return ipcSrv->SetKipData(); } break; - case HocClkIpcCmd_UpdateEmcRegs: - if (r->data.size >= 0) { - return ipcSrv->UpdateEmcRegs(); - } - break; } return SYSCLK_ERROR(Generic); @@ -380,10 +375,4 @@ Result IpcService::GetKipData() { this->clockMgr->GetKipData(); return 0; -} - -Result IpcService::UpdateEmcRegs() { - this->clockMgr->UpdateRamTimings(); - - return 0; -} +} \ No newline at end of file diff --git a/Source/sys-clk/sysmodule/src/ipc_service.h b/Source/sys-clk/sysmodule/src/ipc_service.h index 757d8442..32150912 100644 --- a/Source/sys-clk/sysmodule/src/ipc_service.h +++ b/Source/sys-clk/sysmodule/src/ipc_service.h @@ -57,8 +57,6 @@ class IpcService Result SetReverseNXRTMode(ReverseNXMode mode); Result SetKipData(); Result GetKipData(); - Result UpdateEmcRegs(); - Result CalculateGPUVmin(); bool running; Thread thread; LockableMutex threadMutex;