From eaed085697fe799e655dedc65b7dca5c8eaf8839 Mon Sep 17 00:00:00 2001 From: KazushiM <85604869+KazushiMe@users.noreply.github.com> Date: Sat, 12 Feb 2022 19:56:24 +0800 Subject: [PATCH] Read PTO (PLL test output) regs; Prevent CPU clock from being stuck at boost freq when "Auto CPU Boost" is toggled off --- Source/clkrst_query.cpp | 169 +++++++++++++++--- .../sysmodule/src/clock_manager.cpp | 8 +- Source/sys-clk-OC/sysmodule/src/file_utils.h | 1 - 3 files changed, 151 insertions(+), 27 deletions(-) diff --git a/Source/clkrst_query.cpp b/Source/clkrst_query.cpp index edf4ed25..4f53a784 100644 --- a/Source/clkrst_query.cpp +++ b/Source/clkrst_query.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include /* Recompile nx-hbloader with following added in config.json "kernel_capabilities" @@ -18,16 +19,103 @@ } */ -void waitForKeyA(PadState pad) { - while (appletMainLoop()) { +void waitForKey(PadState pad) { + while (appletMainLoop()) + { padUpdate(&pad); + u64 kDown = padGetButtonsDown(&pad); + if (kDown & HidNpadButton_A) break; + + if (kDown & HidNpadButton_Plus || kDown & HidNpadButton_B) { + consoleExit(NULL); + exit(0); + } + consoleUpdate(NULL); } } +#define CLK_RST_IO_BASE 0x60006000 +#define CLK_RST_IO_SIZE 0x1000 + +#define REG(OFFSET) (*reinterpret_cast(OFFSET)) +#define GET_BITS(VAL, HIGH, LOW) ((VAL & ((1UL << (HIGH + 1UL)) - 1UL)) >> LOW) +#define GET_BIT(VAL, BIT) GET_BITS(VAL, BIT, BIT) + +static u64 clkrst_base = 0; +static u64 clkrst_size = 0; + +// From jetson nano kernel +typedef enum { + /* divider = 2 */ + CLK_PLLX = 5, + CLK_PLLM = 2, + CLK_PLLMB = 37, + /* PLLX & PLLG are backup PLLs for CPU & GPU */ + /* divider = 1 */ + CLK_CCLK_G = 18, // A57 CPU cluster + CLK_EMC = 36, +} PTO_ID; // PLL Test Output Register ID + +/* See if GM20B clock GPC PLL regs are accessible. */ + +#define PLLX_MISC0 0xE4 +#define PLLM_MISC2 0x9C + +double ptoGetMHz(PTO_ID pto_id, u32 divider = 1, u32 presel_reg = 0, u32 presel_mask = 0) { + u32 pre_val, val, presel_val; + + if (presel_reg) { + val = REG(clkrst_base + presel_reg); + usleep(10); + presel_val = val & presel_mask; + val &= ~presel_mask; + val |= presel_mask; + REG(clkrst_base + presel_reg) = val; + usleep(10); + } + + constexpr u32 cycle_count = 16; + pre_val = REG(clkrst_base + 0x60); + val = BIT(23) | BIT(13) | (cycle_count - 1); + val |= pto_id << 14; + + REG(clkrst_base + 0x60) = val; + usleep(10); + REG(clkrst_base + 0x60) = val | BIT(10); + usleep(10); + REG(clkrst_base + 0x60) = val; + usleep(10); + REG(clkrst_base + 0x60) = val | BIT(9); + usleep(500); + + while(REG(clkrst_base + 0x64) & BIT(31)) + ; + + val = REG(clkrst_base + 0x64); + val &= 0xFFFFFF; + val *= divider; + + double rate_mhz = (u64)val * 32768. / cycle_count / 1000. / 1000.; + usleep(10); + REG(clkrst_base + 0x60) = pre_val; + usleep(10); + + if (presel_reg) { + val = REG(clkrst_base + presel_reg); + usleep(10); + val &= ~presel_mask; + val |= presel_val; + REG(clkrst_base + presel_reg) = val; + usleep(10); + } + + return rate_mhz; +} + int main() { consoleInit(NULL); PadState pad; @@ -35,28 +123,19 @@ int main() { padInitializeDefault(&pad); // Get clkrst MMIO virtual address - #define CLK_RST_IO_BASE 0x60006000 - #define CLK_RST_IO_SIZE 0x1000 - u64 virtaddr_base = 0; - u64 virtaddr_size = 0; - Result rc = svcQueryIoMapping(&virtaddr_base, &virtaddr_size, CLK_RST_IO_BASE, CLK_RST_IO_SIZE); + Result rc = svcQueryIoMapping(&clkrst_base, &clkrst_size, CLK_RST_IO_BASE, CLK_RST_IO_SIZE); if (R_FAILED(rc)) { printf("[ERROR] svcQueryIoMapping: 0x%X\n", rc); consoleUpdate(NULL); - waitForKeyA(pad); + waitForKey(pad); consoleExit(NULL); - return -1; } - printf("virtaddr_base: 0x%lX\nvirtaddr_size: 0x%lX\n", virtaddr_base, virtaddr_size); - - #define READ_REG(OFFSET) (*reinterpret_cast(OFFSET)) - #define GET_BITS(VAL, HIGH, LOW) ((VAL & ((1UL << (HIGH + 1UL)) - 1UL)) >> LOW) - #define GET_BIT(VAL, BIT) GET_BITS(VAL, BIT, BIT) + printf("clkrst_base: 0x%lX\nclkrst_size: 0x%lX\n", clkrst_base, clkrst_size); { #define CLKRST_PLLX_BASE 0xE0 - u32 pllx_base = READ_REG(virtaddr_base + CLKRST_PLLX_BASE); + u32 pllx_base = REG(clkrst_base + CLKRST_PLLX_BASE); printf("\n"\ "PLLX_BASE: 0x%X\n"\ "PLLX_ENABLE: %lu\n"\ @@ -64,7 +143,7 @@ int main() { "PLLX_LOCK: %lu\n"\ "PLLX_DIVP: %lu\n"\ "PLLX_DIVN: %lu\n"\ - "PLLX_DIVM: %lu", + "PLLX_DIVM: %lu\n", pllx_base, GET_BIT(pllx_base, 30), GET_BIT(pllx_base, 29), @@ -76,12 +155,12 @@ int main() { { #define CLKRST_PLLX_MISC 0xE4 - u32 pllx_misc = READ_REG(virtaddr_base + CLKRST_PLLX_MISC); + u32 pllx_misc = REG(clkrst_base + CLKRST_PLLX_MISC); printf("\n"\ "PLLX_MISC: 0x%X\n"\ "PLLX_FO_G_DISABLE: %lu\n"\ "PLLX_PTS: %lu\n"\ - "PLLX_LOCK_ENABLE: %lu", + "PLLX_LOCK_ENABLE: %lu\n", pllx_misc, GET_BIT(pllx_misc, 28), GET_BITS(pllx_misc, 23, 22), @@ -90,11 +169,11 @@ int main() { { #define CLKRST_PLLMB_SS_CFG 0x780 - u32 pllmb_ss_cfg = READ_REG(virtaddr_base + CLKRST_PLLMB_SS_CFG); + u32 pllmb_ss_cfg = REG(clkrst_base + CLKRST_PLLMB_SS_CFG); printf("\n"\ "PLLMB_SS_CFG: 0x%X\n"\ "PLLMB_EN_SDM: %lu\n"\ - "PLLMB_EN_SSC: %lu", + "PLLMB_EN_SSC: %lu\n", pllmb_ss_cfg, GET_BIT(pllmb_ss_cfg, 31), GET_BIT(pllmb_ss_cfg, 30)); @@ -102,18 +181,60 @@ int main() { { #define CLKRST_PLLMB_SS_CTRL1 0x784 - u32 pllmb_ss_ctrl1 = READ_REG(virtaddr_base + CLKRST_PLLMB_SS_CTRL1); + u32 pllmb_ss_ctrl1 = REG(clkrst_base + CLKRST_PLLMB_SS_CTRL1); printf("\n"\ "PLLMB_SS_CTRL1: 0x%X\n"\ "PLLMB_SDM_SSC_MAX: %lu\n"\ - "PLLMB_SDM_SSC_MIN: %lu", + "PLLMB_SDM_SSC_MIN: %lu\n", pllmb_ss_ctrl1, GET_BITS(pllmb_ss_ctrl1, 31, 16), GET_BITS(pllmb_ss_ctrl1, 15, 0)); } - consoleUpdate(NULL); - waitForKeyA(pad); + + { + #define CLKRST_PLLM_BASE 0x90 + u32 pllm_base = REG(clkrst_base + CLKRST_PLLM_BASE); + printf("\n"\ + "PLLM_BASE: 0x%X\n"\ + "PLLM_DIVP: %lu\n"\ + "PLLM_DIVN: %lu\n"\ + "PLLM_DIVM: %lu\n", + pllm_base, + GET_BITS(pllm_base, 24, 20), + GET_BITS(pllm_base, 15, 8), + GET_BITS(pllm_base, 7, 0)); + } + + { + #define CLKRST_PLLMB_BASE 0x5e8 + u32 pllmb_base = REG(clkrst_base + CLKRST_PLLMB_BASE); + printf("\n"\ + "PLLMB_BASE: 0x%X\n"\ + "PLLMB_DIVP: %lu\n"\ + "PLLMB_DIVN: %lu\n"\ + "PLLMB_DIVM: %lu\n", + pllmb_base, + GET_BITS(pllmb_base, 24, 20), + GET_BITS(pllmb_base, 15, 8), + GET_BITS(pllmb_base, 7, 0)); + } + + printf("\n"\ + "EMC: %6.1f MHz\n"\ + "CCLK_G: %6.1f MHz\n"\ + "PLLX: %6.1f MHz\n"\ + "PLLM: %6.1f MHz\n"\ + "PLLMB: %6.1f MHz\n", + ptoGetMHz(CLK_EMC), + ptoGetMHz(CLK_CCLK_G), + ptoGetMHz(CLK_PLLX, 2, PLLX_MISC0, BIT(22)), + ptoGetMHz(CLK_PLLM, 2, PLLM_MISC2, BIT(8)), + ptoGetMHz(CLK_PLLMB, 2, PLLM_MISC2, BIT(9)) + ); + + waitForKey(pad); + consoleExit(NULL); return 0; diff --git a/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp b/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp index 98178a62..6756de69 100644 --- a/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp @@ -200,7 +200,7 @@ void ClockManager::WaitForNextTick() uint64_t tickWaitTimeMs = this->GetConfig()->GetConfigValue(SysClkConfigValue_PollingIntervalMs); uint64_t tickWaitTimeNs = tickWaitTimeMs * 1000000ULL; - uint64_t isAutoBoostEnabled = this->GetConfig()->GetConfigValue(SysClkConfigValue_AutoCPUBoost); + bool isAutoBoostEnabled = this->GetConfig()->GetConfigValue(SysClkConfigValue_AutoCPUBoost); if ( isAutoBoostEnabled && this->context->realProfile != SysClkProfile_Handheld && this->context->enabled @@ -242,6 +242,10 @@ void ClockManager::WaitForNextTick() } else { + if (this->oc->systemCoreBoostCPU) { + this->oc->systemCoreBoostCPU = false; + Clocks::SetHz(SysClkModule_CPU, GetHz(SysClkModule_CPU)); + } svcSleepThread(tickWaitTimeNs); } } @@ -341,7 +345,7 @@ bool ClockManager::RefreshContext() { bool hasChanged = false; bool enabled = this->GetConfig()->Enabled(); - uint64_t isReverseNXSyncEnabled = this->GetConfig()->GetConfigValue(SysClkConfigValue_SyncReverseNXMode); + bool isReverseNXSyncEnabled = this->GetConfig()->GetConfigValue(SysClkConfigValue_SyncReverseNXMode); if(enabled != this->context->enabled) { this->context->enabled = enabled; diff --git a/Source/sys-clk-OC/sysmodule/src/file_utils.h b/Source/sys-clk-OC/sysmodule/src/file_utils.h index 6b13e5d9..eead6a34 100644 --- a/Source/sys-clk-OC/sysmodule/src/file_utils.h +++ b/Source/sys-clk-OC/sysmodule/src/file_utils.h @@ -23,7 +23,6 @@ #define FILE_LOG_FLAG_PATH FILE_CONFIG_DIR "/log.flag" #define FILE_LOG_FILE_PATH FILE_CONFIG_DIR "/log.txt" #define FILE_SALTYNX_PATH "/atmosphere/contents/0000000000534C56/flags/boot2.flag" // Just check for SaltyNX boot flag -#define FILE_REVERSENX_RT_CONF_PATH FILE_CONFIG_DIR "/ReverseNX-RT.conf" class FileUtils {