diff --git a/Source/hoc-clk/bpmpfw/source/main.cpp b/Source/hoc-clk/bpmpfw/source/main.cpp index 5dc4023b..b3f49cea 100644 --- a/Source/hoc-clk/bpmpfw/source/main.cpp +++ b/Source/hoc-clk/bpmpfw/source/main.cpp @@ -23,6 +23,7 @@ #include "bpmp_mmu.hpp" #include "freq.hpp" #include "libc_platform.hpp" +#include "pllmb.hpp" #include "regs.hpp" #include "sensors.hpp" @@ -55,6 +56,7 @@ void MainLoop(HocClkBpmpSharedInfo &info) { freq::Update(info); actmon::Update(info); aotag::Update(info); + info.freqMemPll = static_cast(pllmb::MeasureRamClockHz() / 1000); msleep(250); } diff --git a/Source/hoc-clk/bpmpfw/source/pllmb.hpp b/Source/hoc-clk/bpmpfw/source/pllmb.hpp new file mode 100644 index 00000000..706b2993 --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/pllmb.hpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) Souldbminer + * Copyright (c) KazushiMe + * 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 . + * + */ + +#pragma once +#include "freq.hpp" +#include "regs.hpp" + +namespace pllmb { + + constexpr u32 PtoPllm = 2; + constexpr u32 PtoPllmb = 37; + + constexpr u32 PllmMisc2 = 0x9C; + constexpr u32 PllmMisc2PllmBit = (1u << 8); + constexpr u32 PllmMisc2PllmbBit = (1u << 9); + + constexpr u32 PtoCyclePeriod = (1u << 31); // PTO_CLK_CNT_STATUS busy bit + + inline u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask) { + u32 preselOrigBit = 0; + + if (preselReg) { + u32 val = MMIO32(freq::CarBase + preselReg); + usleep(10); + preselOrigBit = val & preselMask; + val &= ~preselMask; + val |= preselMask; + MMIO32(freq::CarBase + preselReg) = val; + usleep(10); + } + + constexpr u32 cycleCount = 16; + const u32 savedCntl = MMIO32(freq::CarBase + freq::CarPtoClkCntCntl); + + u32 val = freq::PtoDivSelDiv1 | freq::PtoClkEnable | (cycleCount - 1); + val |= ptoId << freq::PtoSrcSelShift; + + MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val; + usleep(10); + MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val | freq::PtoCntRst; + usleep(10); + MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val; + usleep(10); + MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val | freq::PtoCntEn; + usleep(500); + + while (MMIO32(freq::CarBase + freq::CarPtoClkCntStatus) & PtoCyclePeriod) + ; + + u32 cnt = MMIO32(freq::CarBase + freq::CarPtoClkCntStatus) & freq::PtoClkCntMask; + cnt *= divider; + + const u64 rateHz = (static_cast(cnt) * 32768) / cycleCount; + + usleep(10); + MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = savedCntl; + usleep(10); + + if (preselReg) { + u32 val2 = MMIO32(freq::CarBase + preselReg); + usleep(10); + val2 &= ~preselMask; + val2 |= preselOrigBit; + MMIO32(freq::CarBase + preselReg) = val2; + usleep(10); + } + + return rateHz; + } + + inline u64 MeasureRamClockHz() { + const u64 pllmbHz = MeasurePtoHz(PtoPllmb, 2, PllmMisc2, PllmMisc2PllmbBit); + if (pllmbHz != 0) { + return pllmbHz; + } + return MeasurePtoHz(PtoPllm, 2, PllmMisc2, PllmMisc2PllmBit); + } + +} // namespace pllmb diff --git a/Source/hoc-clk/common/include/hocclk/bpmp.h b/Source/hoc-clk/common/include/hocclk/bpmp.h index 30c82ccd..016719c6 100644 --- a/Source/hoc-clk/common/include/hocclk/bpmp.h +++ b/Source/hoc-clk/common/include/hocclk/bpmp.h @@ -35,6 +35,7 @@ typedef struct { s32 tempPllx; u32 freqCpu; // kHz u32 freqMem; // kHz + u32 freqMemPll; // kHz u32 emcLoadAll; u32 emcLoadCpu; u32 emcBwAll; @@ -44,4 +45,4 @@ typedef struct { s32 tempAO; } HocClkBpmpSharedInfo; -static_assert(sizeof(HocClkBpmpSharedInfo) == 0x3C); +static_assert(sizeof(HocClkBpmpSharedInfo) == 0x40); diff --git a/Source/hoc-clk/overlay/src/ui/gui/config_info_strings.cpp b/Source/hoc-clk/overlay/src/ui/gui/config_info_strings.cpp index ea290e95..e6fbcc31 100644 --- a/Source/hoc-clk/overlay/src/ui/gui/config_info_strings.cpp +++ b/Source/hoc-clk/overlay/src/ui/gui/config_info_strings.cpp @@ -76,15 +76,6 @@ std::vector ConfigInfoStrings(HocClkConfigValue val, bool isMariko, "Default: INI" }; - case HocClkConfigValue_MemoryFrequencyMeasurementMode: - return { - "How the RAM real frequency is measured", - "Options:", - "- PLL: Measure from PLLMB and PLLM (more accurate)", - "- Actmon: Measure from Actmon (less accurate)", - "Default: PLL" - }; - case HocClkConfigValue_BatteryChargeCurrent: return { "Overrides the charge current to the battery. Use with caution!", diff --git a/Source/hoc-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/hoc-clk/overlay/src/ui/gui/misc_gui.cpp index 3a5682fc..a5be9c83 100644 --- a/Source/hoc-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/hoc-clk/overlay/src/ui/gui/misc_gui.cpp @@ -857,13 +857,6 @@ class ExperimentalSettingsSubMenuGui : public MiscGui { addConfigButton(HocClkConfigValue_GPUSchedulingMethod, "GPU Scheduling Override Method", ValueRange(0, 0, 1, "", 0), "GPU Scheduling Override Method", &thresholdsDisabled, {}, gpuSchedMethodValues, false); - std::vector ramRFMeasurementMethods = { - NamedValue("PLL", MemoryFrequencyMeasurementMode_PLL), - NamedValue("Actmon", MemoryFrequencyMeasurementMode_Actmon), - }; - addConfigButton(HocClkConfigValue_MemoryFrequencyMeasurementMode, "Memory Frequency Measurement Mode", ValueRange(0, 0, 1, "", 0), - "Memory Frequency Measurement Mode", &thresholdsDisabled, {}, ramRFMeasurementMethods, false); - tsl::elm::CustomDrawer *chargeWarningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { renderer->drawString("\uE150 Overriding the charge current", false, x + 20, y + 30, 18, tsl::style::color::ColorText); renderer->drawString("can be dangerous and may cause", false, x + 20, y + 50, 18, tsl::style::color::ColorText); diff --git a/Source/hoc-clk/sysmodule/src/board/board_freq.cpp b/Source/hoc-clk/sysmodule/src/board/board_freq.cpp index 16e0f98c..7436e60c 100644 --- a/Source/hoc-clk/sysmodule/src/board/board_freq.cpp +++ b/Source/hoc-clk/sysmodule/src/board/board_freq.cpp @@ -37,7 +37,6 @@ #include "../hos/apm_ext.h" #include "../i2c/i2cDrv.h" #include "../soc/gm20b.hpp" -#include "../soc/pllmb.hpp" #include "board.hpp" #include "board_name.hpp" #include @@ -202,9 +201,7 @@ namespace board { return static_cast((static_cast(38400000) * divn) / (divm * divp) / 2); } case HocClkModule_MEM: - return config::GetConfigValue(HocClkConfigValue_MemoryFrequencyMeasurementMode) == MemoryFrequencyMeasurementMode_PLL - ? pllmb::getRamClockRatePLLMB() - : bpmp::GetSharedInfo()->freqMem * 1000; + return bpmp::GetSharedInfo()->freqMemPll * 1000; case HocClkModule_Display: return GetDisplayRate(hz); default: diff --git a/Source/hoc-clk/sysmodule/src/soc/pllmb.cpp b/Source/hoc-clk/sysmodule/src/soc/pllmb.cpp deleted file mode 100644 index c9ad36bb..00000000 --- a/Source/hoc-clk/sysmodule/src/soc/pllmb.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) Souldbminer - * - * Copyright (c) KazushiMe - * - * 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 . - * - */ - -#include "pllmb.hpp" - -namespace pllmb { -#define GET_BITS(VAL, HIGH, LOW) ((VAL & ((1UL << (HIGH + 1UL)) - 1UL)) >> LOW) -#define GET_BIT(VAL, BIT) GET_BITS(VAL, BIT, BIT) - - static inline volatile u32 ®(uintptr_t addr) { - return *reinterpret_cast(addr); - } - - // 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(board::clkVirtAddr + presel_reg); - usleep(10); - presel_val = val & presel_mask; - val &= ~presel_mask; - val |= presel_mask; - REG(board::clkVirtAddr + presel_reg) = val; - usleep(10); - } - - constexpr u32 cycle_count = 16; - pre_val = REG(board::clkVirtAddr + 0x60); - val = BIT(23) | BIT(13) | (cycle_count - 1); - val |= pto_id << 14; - - REG(board::clkVirtAddr + 0x60) = val; - usleep(10); - REG(board::clkVirtAddr + 0x60) = val | BIT(10); - usleep(10); - REG(board::clkVirtAddr + 0x60) = val; - usleep(10); - REG(board::clkVirtAddr + 0x60) = val | BIT(9); - usleep(500); - - while (REG(board::clkVirtAddr + 0x64) & BIT(31)) - ; - - val = REG(board::clkVirtAddr + 0x64); - val &= 0xFFFFFF; - val *= divider; - - double rate_hz = (u64)val * 32768. / cycle_count; - usleep(10); - REG(board::clkVirtAddr + 0x60) = pre_val; - usleep(10); - - if (presel_reg) { - val = REG(board::clkVirtAddr + presel_reg); - usleep(10); - val &= ~presel_mask; - val |= presel_val; - REG(board::clkVirtAddr + presel_reg) = val; - usleep(10); - } - - return rate_hz; - } - - u64 getRamClockRatePLLMB() { - // 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)) - // ); - - u32 pllmb = ptoGetMHz(CLK_PLLMB, 2, PLLM_MISC2, BIT(9)); - u32 pllm = ptoGetMHz(CLK_PLLM, 2, PLLM_MISC2, BIT(8)); - return pllmb == 0 ? pllm : pllmb; // pllmb is zeroed out at times, fallback to pllm - } -} // namespace pllmb \ No newline at end of file diff --git a/Source/hoc-clk/sysmodule/src/soc/pllmb.hpp b/Source/hoc-clk/sysmodule/src/soc/pllmb.hpp deleted file mode 100644 index e65472fd..00000000 --- a/Source/hoc-clk/sysmodule/src/soc/pllmb.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) Souldbminer - * - * Copyright (c) KazushiMe - * - * 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 . - * - */ - -#pragma once -#include -#include -#include -#include - -#include "../board/board.hpp" - -namespace pllmb { - - u64 getRamClockRatePLLMB(); -} \ No newline at end of file