From 3352dffc3955de0eb0d51334048ea14bb93f1c2e Mon Sep 17 00:00:00 2001 From: souldbminersmwc Date: Thu, 27 Aug 2026 18:57:15 -0400 Subject: [PATCH] bpmpfw: cleanup makefile and split hpp/cpp --- Source/hoc-clk/bpmpfw/Makefile | 7 +- Source/hoc-clk/bpmpfw/source/actmon.cpp | 65 +++++++++++++++ Source/hoc-clk/bpmpfw/source/actmon.hpp | 43 +--------- Source/hoc-clk/bpmpfw/source/aotag.cpp | 43 ++++++++++ Source/hoc-clk/bpmpfw/source/aotag.hpp | 20 +---- Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp | 96 +++++++++++++++++++++++ Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp | 73 ++--------------- Source/hoc-clk/bpmpfw/source/freq.cpp | 61 ++++++++++++++ Source/hoc-clk/bpmpfw/source/freq.hpp | 39 +-------- Source/hoc-clk/bpmpfw/source/pllmb.cpp | 84 ++++++++++++++++++++ Source/hoc-clk/bpmpfw/source/pllmb.hpp | 60 +------------- Source/hoc-clk/bpmpfw/source/regs.cpp | 58 ++++++++++++++ Source/hoc-clk/bpmpfw/source/regs.hpp | 41 ++-------- Source/hoc-clk/bpmpfw/source/sensors.cpp | 29 +++++++ Source/hoc-clk/bpmpfw/source/sensors.hpp | 11 +-- 15 files changed, 464 insertions(+), 266 deletions(-) create mode 100644 Source/hoc-clk/bpmpfw/source/actmon.cpp create mode 100644 Source/hoc-clk/bpmpfw/source/aotag.cpp create mode 100644 Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp create mode 100644 Source/hoc-clk/bpmpfw/source/freq.cpp create mode 100644 Source/hoc-clk/bpmpfw/source/pllmb.cpp create mode 100644 Source/hoc-clk/bpmpfw/source/regs.cpp create mode 100644 Source/hoc-clk/bpmpfw/source/sensors.cpp diff --git a/Source/hoc-clk/bpmpfw/Makefile b/Source/hoc-clk/bpmpfw/Makefile index ddfe3882..b855a056 100644 --- a/Source/hoc-clk/bpmpfw/Makefile +++ b/Source/hoc-clk/bpmpfw/Makefile @@ -39,18 +39,23 @@ all: $(BIN_TARGET) $(BIN_TARGET): $(BUILDDIR)/$(TARGET).elf @mkdir -p $(OUTPUTDIR) - $(OBJCOPY) -S -O binary $< $@ + @echo "bpmpfw.bin" + @$(OBJCOPY) -S -O binary $< $@ $(BUILDDIR)/$(TARGET).elf: $(OBJS) + @echo "linking $(TARGET).elf" @$(CXX) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ $(BUILDDIR)/%.o: $(SOURCEDIR)/%.cpp | $(BUILDDIR) + @echo "$(notdir $<)" @$(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@ $(BUILDDIR)/libc/%.o: $(LIBCDIR)/src/%.c | $(BUILDDIR)/libc + @echo "$(notdir $<)" @$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ $(BUILDDIR)/%.o: $(SOURCEDIR)/%.s | $(BUILDDIR) + @echo "$(notdir $<)" @$(CXX) $(ASFLAGS) $(INCLUDE) -c $< -o $@ $(BUILDDIR): diff --git a/Source/hoc-clk/bpmpfw/source/actmon.cpp b/Source/hoc-clk/bpmpfw/source/actmon.cpp new file mode 100644 index 00000000..f6faa312 --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/actmon.cpp @@ -0,0 +1,65 @@ +/* + * 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 . + * + */ + +#include "actmon.hpp" + +namespace actmon { + + u32 DevReg(ActmonDev dev, u32 off) { + return ActmonDevBase + (static_cast(dev) * ActmonDevSize) + off; + } + + void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight) { + MMIO32(DevReg(dev, DevInitAvg)) = freqKhz * ActmonPeriodMs / 2; + MMIO32(DevReg(dev, DevCountWeight)) = weight; + MMIO32(DevReg(dev, DevCtrl)) = ActmonDevCtrlEnb | ActmonDevCtrlEnbPeriodic | ActmonDevCtrlKVal3; + } + + void Init() { + const u32 emcFreqKhz = static_cast(freq::MeasurePtoFreqHz(freq::ClkPtoEmc, 1) / 1000); + + if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMcallMonAct)) { + MMIO32(ActmonBase + ActmonGlbPeriodCtrl) = (ActmonPeriodMs - 1) & 0xFF; + EnableDev(DevMcAll, emcFreqKhz, 256 * 4); + } + + if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMccpuMonAct)) { + EnableDev(DevMcCpu, emcFreqKhz, 256 * 4); + } + } + + void Update(HocClkBpmpSharedInfo &info) { + const u32 emcFreqKhz = info.freqMem; + if (emcFreqKhz == 0) { + return; + } + + const u32 avgAll = MMIO32(DevReg(DevMcAll, DevAvgCount)); + const u32 avgCpu = MMIO32(DevReg(DevMcCpu, DevAvgCount)); + + // Get 1000 -> 100.0. + info.emcLoadAll = static_cast((static_cast(avgAll) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs)); + info.emcLoadCpu = static_cast((static_cast(avgCpu) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs)); + + info.emcBwAll = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadAll) / 1000000); + info.emcBwCpu = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadCpu) / 1000000); + + // Not 100% accurate but should be enough. + info.emcBwGpu = (info.emcBwAll > info.emcBwCpu) ? (info.emcBwAll - info.emcBwCpu) : 0; + } + +} // namespace actmon diff --git a/Source/hoc-clk/bpmpfw/source/actmon.hpp b/Source/hoc-clk/bpmpfw/source/actmon.hpp index 9a607c4e..42e935f6 100644 --- a/Source/hoc-clk/bpmpfw/source/actmon.hpp +++ b/Source/hoc-clk/bpmpfw/source/actmon.hpp @@ -53,47 +53,12 @@ namespace actmon { constexpr u32 DevCountWeight = 0x18; constexpr u32 DevAvgCount = 0x20; - inline u32 DevReg(ActmonDev dev, u32 off) { - return ActmonDevBase + (static_cast(dev) * ActmonDevSize) + off; - } + u32 DevReg(ActmonDev dev, u32 off); - inline void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight) { - MMIO32(DevReg(dev, DevInitAvg)) = freqKhz * ActmonPeriodMs / 2; - MMIO32(DevReg(dev, DevCountWeight)) = weight; - MMIO32(DevReg(dev, DevCtrl)) = ActmonDevCtrlEnb | ActmonDevCtrlEnbPeriodic | ActmonDevCtrlKVal3; - } + void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight); - inline void Init() { - const u32 emcFreqKhz = static_cast(freq::MeasurePtoFreqHz(freq::ClkPtoEmc, 1) / 1000); + void Init(); - if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMcallMonAct)) { - MMIO32(ActmonBase + ActmonGlbPeriodCtrl) = (ActmonPeriodMs - 1) & 0xFF; - EnableDev(DevMcAll, emcFreqKhz, 256 * 4); - } - - if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMccpuMonAct)) { - EnableDev(DevMcCpu, emcFreqKhz, 256 * 4); - } - } - - inline void Update(HocClkBpmpSharedInfo &info) { - const u32 emcFreqKhz = info.freqMem; - if (emcFreqKhz == 0) { - return; - } - - const u32 avgAll = MMIO32(DevReg(DevMcAll, DevAvgCount)); - const u32 avgCpu = MMIO32(DevReg(DevMcCpu, DevAvgCount)); - - // Get 1000 -> 100.0. - info.emcLoadAll = static_cast((static_cast(avgAll) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs)); - info.emcLoadCpu = static_cast((static_cast(avgCpu) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs)); - - info.emcBwAll = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadAll) / 1000000); - info.emcBwCpu = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadCpu) / 1000000); - - // Not 100% accurate but should be enough. - info.emcBwGpu = (info.emcBwAll > info.emcBwCpu) ? (info.emcBwAll - info.emcBwCpu) : 0; - } + void Update(HocClkBpmpSharedInfo &info); } // namespace actmon diff --git a/Source/hoc-clk/bpmpfw/source/aotag.cpp b/Source/hoc-clk/bpmpfw/source/aotag.cpp new file mode 100644 index 00000000..da71c08d --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/aotag.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 - 2017, NVIDIA CORPORATION. All rights reserved. + * 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 . + * + */ + +#include "aotag.hpp" + +namespace aotag { + + void Update(HocClkBpmpSharedInfo &info) { + const u32 regval = MMIO32(PmcBase + PmcTsensorStatus1); + + if (!(regval & Status1ValidBit)) { + info.tempAO = InvalidSentinel; + return; + } + + const u32 abs = (regval >> Status1AbsShift) & Status1AbsMask; + const bool frac = (regval & Status1FracBit) != 0; + const bool negative = (regval & Status1SignBit) != 0; + + s32 temp = static_cast(abs) * 1000 + (frac ? 500 : 0); + if (negative) { + temp = -temp; + } + + info.tempAO = temp; + } + +} // namespace aotag diff --git a/Source/hoc-clk/bpmpfw/source/aotag.hpp b/Source/hoc-clk/bpmpfw/source/aotag.hpp index 1e159139..25e18a0a 100644 --- a/Source/hoc-clk/bpmpfw/source/aotag.hpp +++ b/Source/hoc-clk/bpmpfw/source/aotag.hpp @@ -34,24 +34,6 @@ namespace aotag { constexpr s32 InvalidSentinel = -125; - inline void Update(HocClkBpmpSharedInfo &info) { - const u32 regval = MMIO32(PmcBase + PmcTsensorStatus1); - - if (!(regval & Status1ValidBit)) { - info.tempAO = InvalidSentinel; - return; - } - - const u32 abs = (regval >> Status1AbsShift) & Status1AbsMask; - const bool frac = (regval & Status1FracBit) != 0; - const bool negative = (regval & Status1SignBit) != 0; - - s32 temp = static_cast(abs) * 1000 + (frac ? 500 : 0); - if (negative) { - temp = -temp; - } - - info.tempAO = temp; - } + void Update(HocClkBpmpSharedInfo &info); } // namespace aotag diff --git a/Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp new file mode 100644 index 00000000..ad457560 --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019-2025 CTCaer + * 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 . + * + */ + +#include "bpmp_mmu.hpp" + +namespace bpmpMmu { + + u32 AlignUp(u32 x, u32 a) { + return (x + a - 1) & ~(a - 1); + } + + u32 AlignDown(u32 x, u32 a) { + return x & ~(a - 1); + } + + void Maintenance(u32 op, bool force) { + if (!force && !(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) { + return; + } + + MMIO32(CacheBase + IntClear) = IntMaintDone; + + // Blocking operation. + MMIO32(CacheBase + MaintReq) = MaintReqWayBitmapAll | op; + + while (!(MMIO32(CacheBase + IntRawEvent) & IntMaintDone)) + ; + + MMIO32(CacheBase + IntClear) = MMIO32(CacheBase + IntRawEvent); + } + + void SetEntry(u32 idx, const MmuEntry &entry) { + MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x0) = AlignUp(entry.startAddr, CacheLineSize); + MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x4) = AlignDown(entry.endAddr, CacheLineSize); + MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x8) = entry.attr; + + MMIO32(CacheBase + MmuShadowCopyMask) |= (1u << idx); + } + + void Enable() { + if (MMIO32(CacheBase + CacheConfig) & CfgEnableCache) { + return; + } + + // Init BPMP MMU. + MMIO32(CacheBase + MmuCmd) = MmuCmdInit; + MMIO32(CacheBase + MmuFallbackEntry) = MmuEnRead | MmuEnWrite | MmuEnExec; // RWX for non-defined regions. + MMIO32(CacheBase + MmuCfg) = MmuCfgSeqEn | MmuCfgTlbEn | MmuCfgAbortStoreLast; + + // Init BPMP MMU entries. + MMIO32(CacheBase + MmuShadowCopyMask) = 0; + for (u32 idx = 0; idx < sizeof(Entries) / sizeof(Entries[0]); idx++) { + SetEntry(idx, Entries[idx]); + } + + MMIO32(CacheBase + MmuCmd) = MmuCmdCopyShadow; + + // Invalidate cache. + Maintenance(MaintInvalidWay, true); + + // Enable cache. + MMIO32(CacheBase + CacheConfig) = CfgEnableCache | CfgForceWriteThrough | + (TagModeParallel << CfgMmuTagModeShift) | CfgTagChkAbrtOnErr; + + // HW bug. Invalidate cache again. + Maintenance(MaintInvalidWay, false); + } + + void Disable() { + if (!(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) { + return; + } + + // Clean and invalidate cache. + Maintenance(MaintCleanInvalidWay, false); + + // Disable cache. + MMIO32(CacheBase + CacheConfig) = 0; + } + +} // namespace bpmpMmu diff --git a/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp index ca106eb8..9e4f2ea9 100644 --- a/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp +++ b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp @@ -77,76 +77,15 @@ namespace bpmpMmu { { IramBase, IramEnd, MmuEnRead | MmuEnWrite | MmuEnExec | MmuEnCached }, }; - inline u32 AlignUp(u32 x, u32 a) { - return (x + a - 1) & ~(a - 1); - } - inline u32 AlignDown(u32 x, u32 a) { - return x & ~(a - 1); - } + u32 AlignUp(u32 x, u32 a); + u32 AlignDown(u32 x, u32 a); - inline void Maintenance(u32 op, bool force) { - if (!force && !(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) { - return; - } + void Maintenance(u32 op, bool force); - MMIO32(CacheBase + IntClear) = IntMaintDone; + void SetEntry(u32 idx, const MmuEntry &entry); - // Blocking operation. - MMIO32(CacheBase + MaintReq) = MaintReqWayBitmapAll | op; + void Enable(); - while (!(MMIO32(CacheBase + IntRawEvent) & IntMaintDone)) - ; - - MMIO32(CacheBase + IntClear) = MMIO32(CacheBase + IntRawEvent); - } - - inline void SetEntry(u32 idx, const MmuEntry &entry) { - MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x0) = AlignUp(entry.startAddr, CacheLineSize); - MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x4) = AlignDown(entry.endAddr, CacheLineSize); - MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x8) = entry.attr; - - MMIO32(CacheBase + MmuShadowCopyMask) |= (1u << idx); - } - - inline void Enable() { - if (MMIO32(CacheBase + CacheConfig) & CfgEnableCache) { - return; - } - - // Init BPMP MMU. - MMIO32(CacheBase + MmuCmd) = MmuCmdInit; - MMIO32(CacheBase + MmuFallbackEntry) = MmuEnRead | MmuEnWrite | MmuEnExec; // RWX for non-defined regions. - MMIO32(CacheBase + MmuCfg) = MmuCfgSeqEn | MmuCfgTlbEn | MmuCfgAbortStoreLast; - - // Init BPMP MMU entries. - MMIO32(CacheBase + MmuShadowCopyMask) = 0; - for (u32 idx = 0; idx < sizeof(Entries) / sizeof(Entries[0]); idx++) { - SetEntry(idx, Entries[idx]); - } - - MMIO32(CacheBase + MmuCmd) = MmuCmdCopyShadow; - - // Invalidate cache. - Maintenance(MaintInvalidWay, true); - - // Enable cache. - MMIO32(CacheBase + CacheConfig) = CfgEnableCache | CfgForceWriteThrough | - (TagModeParallel << CfgMmuTagModeShift) | CfgTagChkAbrtOnErr; - - // HW bug. Invalidate cache again. - Maintenance(MaintInvalidWay, false); - } - - inline void Disable() { - if (!(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) { - return; - } - - // Clean and invalidate cache. - Maintenance(MaintCleanInvalidWay, false); - - // Disable cache. - MMIO32(CacheBase + CacheConfig) = 0; - } + void Disable(); } // namespace bpmpMmu diff --git a/Source/hoc-clk/bpmpfw/source/freq.cpp b/Source/hoc-clk/bpmpfw/source/freq.cpp new file mode 100644 index 00000000..de97caaf --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/freq.cpp @@ -0,0 +1,61 @@ +/* + * 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 . + * + */ + +#include "freq.hpp" + +namespace freq { + + u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier) { + constexpr u32 win = 16; + constexpr u32 osc = 32768; + + const u32 val = (srcId << PtoSrcSelShift) | PtoDivSelDiv1 | PtoClkEnable | (win - 1); + + MMIO32(CarBase + CarPtoClkCntCntl) = val; + (void)MMIO32(CarBase + CarPtoClkCntCntl); + usleep(2); + + MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntRst; + (void)MMIO32(CarBase + CarPtoClkCntCntl); + usleep(2); + + MMIO32(CarBase + CarPtoClkCntCntl) = val; + (void)MMIO32(CarBase + CarPtoClkCntCntl); + usleep(2); + + MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntEn; + (void)MMIO32(CarBase + CarPtoClkCntCntl); + usleep((1000000u * win / osc) + 12 + 2); // 502us + + while (MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntBusy) + ; + + const u32 cnt = MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntMask; + + MMIO32(CarBase + CarPtoClkCntCntl) = 0; + (void)MMIO32(CarBase + CarPtoClkCntCntl); + usleep(2); + + return (static_cast(cnt) * multiplier * osc) / win; + } + + void Update(HocClkBpmpSharedInfo &info) { + info.freqMem = static_cast(MeasurePtoFreqHz(ClkPtoEmc, 1) / 1000); + info.freqCpu = static_cast(MeasurePtoFreqHz(ClkPtoCclkGDiv2, 2) / 1000); + } + +} // namespace freq diff --git a/Source/hoc-clk/bpmpfw/source/freq.hpp b/Source/hoc-clk/bpmpfw/source/freq.hpp index eea8e9a4..95c24c65 100644 --- a/Source/hoc-clk/bpmpfw/source/freq.hpp +++ b/Source/hoc-clk/bpmpfw/source/freq.hpp @@ -37,43 +37,8 @@ namespace freq { constexpr u32 ClkPtoCclkGDiv2 = 0x13; constexpr u32 ClkPtoEmc = 0x24; - inline u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier) { - constexpr u32 win = 16; - constexpr u32 osc = 32768; + u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier); - const u32 val = (srcId << PtoSrcSelShift) | PtoDivSelDiv1 | PtoClkEnable | (win - 1); - - MMIO32(CarBase + CarPtoClkCntCntl) = val; - (void)MMIO32(CarBase + CarPtoClkCntCntl); - usleep(2); - - MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntRst; - (void)MMIO32(CarBase + CarPtoClkCntCntl); - usleep(2); - - MMIO32(CarBase + CarPtoClkCntCntl) = val; - (void)MMIO32(CarBase + CarPtoClkCntCntl); - usleep(2); - - MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntEn; - (void)MMIO32(CarBase + CarPtoClkCntCntl); - usleep((1000000u * win / osc) + 12 + 2); // 502us - - while (MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntBusy) - ; - - const u32 cnt = MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntMask; - - MMIO32(CarBase + CarPtoClkCntCntl) = 0; - (void)MMIO32(CarBase + CarPtoClkCntCntl); - usleep(2); - - return (static_cast(cnt) * multiplier * osc) / win; - } - - inline void Update(HocClkBpmpSharedInfo &info) { - info.freqMem = static_cast(MeasurePtoFreqHz(ClkPtoEmc, 1) / 1000); - info.freqCpu = static_cast(MeasurePtoFreqHz(ClkPtoCclkGDiv2, 2) / 1000); - } + void Update(HocClkBpmpSharedInfo &info); } // namespace freq diff --git a/Source/hoc-clk/bpmpfw/source/pllmb.cpp b/Source/hoc-clk/bpmpfw/source/pllmb.cpp new file mode 100644 index 00000000..559e149e --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/pllmb.cpp @@ -0,0 +1,84 @@ +/* + * 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 . + * + */ + +#include "pllmb.hpp" + +namespace pllmb { + + 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; + } + + 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/bpmpfw/source/pllmb.hpp b/Source/hoc-clk/bpmpfw/source/pllmb.hpp index 706b2993..5e296b76 100644 --- a/Source/hoc-clk/bpmpfw/source/pllmb.hpp +++ b/Source/hoc-clk/bpmpfw/source/pllmb.hpp @@ -32,64 +32,8 @@ namespace pllmb { 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; + u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask); - 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); - } + u64 MeasureRamClockHz(); } // namespace pllmb diff --git a/Source/hoc-clk/bpmpfw/source/regs.cpp b/Source/hoc-clk/bpmpfw/source/regs.cpp new file mode 100644 index 00000000..3b80f9af --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/regs.cpp @@ -0,0 +1,58 @@ +/* + * 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 . + * + */ + +#include "regs.hpp" + +[[maybe_unused]] void usleep(u32 us) { + while (us) { + const u32 delay = (us > HaltMaxCnt) ? HaltMaxCnt : us; + us -= delay; + MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltUsec | delay; + } +} + +[[maybe_unused]] void msleep(u32 ms) { + while (ms) { + const u32 delay = (ms > HaltMaxCnt) ? HaltMaxCnt : ms; + ms -= delay; + MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltMsec | delay; + } +} + +void UartPutc(char c) { + while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre)) + ; + MMIO32(UartBBase + UartThr) = static_cast(static_cast(c)); +} + +void UartFlush() { + while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty)) + ; +} + +void UartPuts(const char *s) { + while (*s) { + UartPutc(*s++); + } +} + +void UartPutHex32(u32 v) { + static const char digits[] = "0123456789ABCDEF"; + for (int i = 28; i >= 0; i -= 4) { + UartPutc(digits[(v >> i) & 0xF]); + } +} diff --git a/Source/hoc-clk/bpmpfw/source/regs.hpp b/Source/hoc-clk/bpmpfw/source/regs.hpp index b287c27b..9e0b1d9c 100644 --- a/Source/hoc-clk/bpmpfw/source/regs.hpp +++ b/Source/hoc-clk/bpmpfw/source/regs.hpp @@ -33,20 +33,8 @@ constexpr u32 HaltMsec = (1u << 24); constexpr u32 HaltUsec = (1u << 25); constexpr u32 HaltMaxCnt = 0xFF; -[[maybe_unused]] inline void usleep(u32 us) { - while (us) { - const u32 delay = (us > HaltMaxCnt) ? HaltMaxCnt : us; - us -= delay; - MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltUsec | delay; - } -} -[[maybe_unused]] inline void msleep(u32 ms) { - while (ms) { - const u32 delay = (ms > HaltMaxCnt) ? HaltMaxCnt : ms; - ms -= delay; - MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltMsec | delay; - } -} +[[maybe_unused]] void usleep(u32 us); +[[maybe_unused]] void msleep(u32 ms); constexpr u32 TmrBase = 0x60005000; constexpr u32 TimerUsCntr1Us = 0x10; @@ -57,27 +45,10 @@ constexpr u32 UartLsr = 0x14; constexpr u32 UartLsrThre = (1u << 5); constexpr u32 UartLsrTmty = (1u << 6); -inline void UartPutc(char c) { - while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre)) - ; - MMIO32(UartBBase + UartThr) = static_cast(static_cast(c)); -} +void UartPutc(char c); -// Waits for the byte to be fully transmitted -inline void UartFlush() { - while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty)) - ; -} +void UartFlush(); -inline void UartPuts(const char *s) { - while (*s) { - UartPutc(*s++); - } -} +void UartPuts(const char *s); -inline void UartPutHex32(u32 v) { - static const char digits[] = "0123456789ABCDEF"; - for (int i = 28; i >= 0; i -= 4) { - UartPutc(digits[(v >> i) & 0xF]); - } -} +void UartPutHex32(u32 v); diff --git a/Source/hoc-clk/bpmpfw/source/sensors.cpp b/Source/hoc-clk/bpmpfw/source/sensors.cpp new file mode 100644 index 00000000..bd2af778 --- /dev/null +++ b/Source/hoc-clk/bpmpfw/source/sensors.cpp @@ -0,0 +1,29 @@ +/* + * 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 . + * + */ + +#include "sensors.hpp" + +s32 TranslateSocthermTemp(u16 val) { + s32 t = ((val >> 8) & 0xFF) * 1000; + if (val & (1u << 7)) { + t += 500; + } + if (val & (1u << 0)) { + t = -t; + } + return t; +} diff --git a/Source/hoc-clk/bpmpfw/source/sensors.hpp b/Source/hoc-clk/bpmpfw/source/sensors.hpp index 64aad219..1c101a5d 100644 --- a/Source/hoc-clk/bpmpfw/source/sensors.hpp +++ b/Source/hoc-clk/bpmpfw/source/sensors.hpp @@ -22,13 +22,4 @@ constexpr u32 SocthermBase = 0x700E2000; constexpr u32 SocthermSensorTemp1 = 0x1C8; constexpr u32 SocthermSensorTemp2 = 0x1CC; -inline s32 TranslateSocthermTemp(u16 val) { - s32 t = ((val >> 8) & 0xFF) * 1000; - if (val & (1u << 7)) { - t += 500; - } - if (val & (1u << 0)) { - t = -t; - } - return t; -} +s32 TranslateSocthermTemp(u16 val);