bpmpfw: cleanup makefile and split hpp/cpp
This commit is contained in:
1 parent
e5240d835f
commit
3352dffc39
15 files changed
+464
-266
No files matched your search
@@ -39,18 +39,23 @@ all: $(BIN_TARGET)
|
|||||||
|
|
||||||
$(BIN_TARGET): $(BUILDDIR)/$(TARGET).elf
|
$(BIN_TARGET): $(BUILDDIR)/$(TARGET).elf
|
||||||
@mkdir -p $(OUTPUTDIR)
|
@mkdir -p $(OUTPUTDIR)
|
||||||
$(OBJCOPY) -S -O binary $< $@
|
@echo "bpmpfw.bin"
|
||||||
|
@$(OBJCOPY) -S -O binary $< $@
|
||||||
|
|
||||||
$(BUILDDIR)/$(TARGET).elf: $(OBJS)
|
$(BUILDDIR)/$(TARGET).elf: $(OBJS)
|
||||||
|
@echo "linking $(TARGET).elf"
|
||||||
@$(CXX) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
|
@$(CXX) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.cpp | $(BUILDDIR)
|
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.cpp | $(BUILDDIR)
|
||||||
|
@echo "$(notdir $<)"
|
||||||
@$(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@
|
@$(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@
|
||||||
|
|
||||||
$(BUILDDIR)/libc/%.o: $(LIBCDIR)/src/%.c | $(BUILDDIR)/libc
|
$(BUILDDIR)/libc/%.o: $(LIBCDIR)/src/%.c | $(BUILDDIR)/libc
|
||||||
|
@echo "$(notdir $<)"
|
||||||
@$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
|
@$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
|
||||||
|
|
||||||
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.s | $(BUILDDIR)
|
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.s | $(BUILDDIR)
|
||||||
|
@echo "$(notdir $<)"
|
||||||
@$(CXX) $(ASFLAGS) $(INCLUDE) -c $< -o $@
|
@$(CXX) $(ASFLAGS) $(INCLUDE) -c $< -o $@
|
||||||
|
|
||||||
$(BUILDDIR):
|
$(BUILDDIR):
|
||||||
|
|||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "actmon.hpp"
|
||||||
|
|
||||||
|
namespace actmon {
|
||||||
|
|
||||||
|
u32 DevReg(ActmonDev dev, u32 off) {
|
||||||
|
return ActmonDevBase + (static_cast<u32>(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<u32>(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<u32>((static_cast<u64>(avgAll) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
|
||||||
|
info.emcLoadCpu = static_cast<u32>((static_cast<u64>(avgCpu) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
|
||||||
|
|
||||||
|
info.emcBwAll = static_cast<u32>((static_cast<u64>(emcFreqKhz) * 16 * info.emcLoadAll) / 1000000);
|
||||||
|
info.emcBwCpu = static_cast<u32>((static_cast<u64>(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
|
||||||
@@ -53,47 +53,12 @@ namespace actmon {
|
|||||||
constexpr u32 DevCountWeight = 0x18;
|
constexpr u32 DevCountWeight = 0x18;
|
||||||
constexpr u32 DevAvgCount = 0x20;
|
constexpr u32 DevAvgCount = 0x20;
|
||||||
|
|
||||||
inline u32 DevReg(ActmonDev dev, u32 off) {
|
u32 DevReg(ActmonDev dev, u32 off);
|
||||||
return ActmonDevBase + (static_cast<u32>(dev) * ActmonDevSize) + off;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight) {
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Init() {
|
void Init();
|
||||||
const u32 emcFreqKhz = static_cast<u32>(freq::MeasurePtoFreqHz(freq::ClkPtoEmc, 1) / 1000);
|
|
||||||
|
|
||||||
if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMcallMonAct)) {
|
void Update(HocClkBpmpSharedInfo &info);
|
||||||
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<u32>((static_cast<u64>(avgAll) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
|
|
||||||
info.emcLoadCpu = static_cast<u32>((static_cast<u64>(avgCpu) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
|
|
||||||
|
|
||||||
info.emcBwAll = static_cast<u32>((static_cast<u64>(emcFreqKhz) * 16 * info.emcLoadAll) / 1000000);
|
|
||||||
info.emcBwCpu = static_cast<u32>((static_cast<u64>(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
|
} // namespace actmon
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<s32>(abs) * 1000 + (frac ? 500 : 0);
|
||||||
|
if (negative) {
|
||||||
|
temp = -temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.tempAO = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aotag
|
||||||
@@ -34,24 +34,6 @@ namespace aotag {
|
|||||||
|
|
||||||
constexpr s32 InvalidSentinel = -125;
|
constexpr s32 InvalidSentinel = -125;
|
||||||
|
|
||||||
inline void Update(HocClkBpmpSharedInfo &info) {
|
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<s32>(abs) * 1000 + (frac ? 500 : 0);
|
|
||||||
if (negative) {
|
|
||||||
temp = -temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.tempAO = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace aotag
|
} // namespace aotag
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -77,76 +77,15 @@ namespace bpmpMmu {
|
|||||||
{ IramBase, IramEnd, MmuEnRead | MmuEnWrite | MmuEnExec | MmuEnCached },
|
{ IramBase, IramEnd, MmuEnRead | MmuEnWrite | MmuEnExec | MmuEnCached },
|
||||||
};
|
};
|
||||||
|
|
||||||
inline u32 AlignUp(u32 x, u32 a) {
|
u32 AlignUp(u32 x, u32 a);
|
||||||
return (x + a - 1) & ~(a - 1);
|
u32 AlignDown(u32 x, u32 a);
|
||||||
}
|
|
||||||
inline u32 AlignDown(u32 x, u32 a) {
|
|
||||||
return x & ~(a - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Maintenance(u32 op, bool force) {
|
void Maintenance(u32 op, bool force);
|
||||||
if (!force && !(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MMIO32(CacheBase + IntClear) = IntMaintDone;
|
void SetEntry(u32 idx, const MmuEntry &entry);
|
||||||
|
|
||||||
// Blocking operation.
|
void Enable();
|
||||||
MMIO32(CacheBase + MaintReq) = MaintReqWayBitmapAll | op;
|
|
||||||
|
|
||||||
while (!(MMIO32(CacheBase + IntRawEvent) & IntMaintDone))
|
void Disable();
|
||||||
;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace bpmpMmu
|
} // namespace bpmpMmu
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<u64>(cnt) * multiplier * osc) / win;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(HocClkBpmpSharedInfo &info) {
|
||||||
|
info.freqMem = static_cast<u32>(MeasurePtoFreqHz(ClkPtoEmc, 1) / 1000);
|
||||||
|
info.freqCpu = static_cast<u32>(MeasurePtoFreqHz(ClkPtoCclkGDiv2, 2) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace freq
|
||||||
@@ -37,43 +37,8 @@ namespace freq {
|
|||||||
constexpr u32 ClkPtoCclkGDiv2 = 0x13;
|
constexpr u32 ClkPtoCclkGDiv2 = 0x13;
|
||||||
constexpr u32 ClkPtoEmc = 0x24;
|
constexpr u32 ClkPtoEmc = 0x24;
|
||||||
|
|
||||||
inline u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier) {
|
u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier);
|
||||||
constexpr u32 win = 16;
|
|
||||||
constexpr u32 osc = 32768;
|
|
||||||
|
|
||||||
const u32 val = (srcId << PtoSrcSelShift) | PtoDivSelDiv1 | PtoClkEnable | (win - 1);
|
void Update(HocClkBpmpSharedInfo &info);
|
||||||
|
|
||||||
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<u64>(cnt) * multiplier * osc) / win;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Update(HocClkBpmpSharedInfo &info) {
|
|
||||||
info.freqMem = static_cast<u32>(MeasurePtoFreqHz(ClkPtoEmc, 1) / 1000);
|
|
||||||
info.freqCpu = static_cast<u32>(MeasurePtoFreqHz(ClkPtoCclkGDiv2, 2) / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace freq
|
} // namespace freq
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<u64>(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
|
||||||
@@ -32,64 +32,8 @@ namespace pllmb {
|
|||||||
|
|
||||||
constexpr u32 PtoCyclePeriod = (1u << 31); // PTO_CLK_CNT_STATUS busy bit
|
constexpr u32 PtoCyclePeriod = (1u << 31); // PTO_CLK_CNT_STATUS busy bit
|
||||||
|
|
||||||
inline u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask) {
|
u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask);
|
||||||
u32 preselOrigBit = 0;
|
|
||||||
|
|
||||||
if (preselReg) {
|
u64 MeasureRamClockHz();
|
||||||
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<u64>(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
|
} // namespace pllmb
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<u32>(static_cast<u8>(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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,20 +33,8 @@ constexpr u32 HaltMsec = (1u << 24);
|
|||||||
constexpr u32 HaltUsec = (1u << 25);
|
constexpr u32 HaltUsec = (1u << 25);
|
||||||
constexpr u32 HaltMaxCnt = 0xFF;
|
constexpr u32 HaltMaxCnt = 0xFF;
|
||||||
|
|
||||||
[[maybe_unused]] inline void usleep(u32 us) {
|
[[maybe_unused]] void usleep(u32 us);
|
||||||
while (us) {
|
[[maybe_unused]] void msleep(u32 ms);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr u32 TmrBase = 0x60005000;
|
constexpr u32 TmrBase = 0x60005000;
|
||||||
constexpr u32 TimerUsCntr1Us = 0x10;
|
constexpr u32 TimerUsCntr1Us = 0x10;
|
||||||
@@ -57,27 +45,10 @@ constexpr u32 UartLsr = 0x14;
|
|||||||
constexpr u32 UartLsrThre = (1u << 5);
|
constexpr u32 UartLsrThre = (1u << 5);
|
||||||
constexpr u32 UartLsrTmty = (1u << 6);
|
constexpr u32 UartLsrTmty = (1u << 6);
|
||||||
|
|
||||||
inline void UartPutc(char c) {
|
void UartPutc(char c);
|
||||||
while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre))
|
|
||||||
;
|
|
||||||
MMIO32(UartBBase + UartThr) = static_cast<u32>(static_cast<u8>(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Waits for the byte to be fully transmitted
|
void UartFlush();
|
||||||
inline void UartFlush() {
|
|
||||||
while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void UartPuts(const char *s) {
|
void UartPuts(const char *s);
|
||||||
while (*s) {
|
|
||||||
UartPutc(*s++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void UartPutHex32(u32 v) {
|
void UartPutHex32(u32 v);
|
||||||
static const char digits[] = "0123456789ABCDEF";
|
|
||||||
for (int i = 28; i >= 0; i -= 4) {
|
|
||||||
UartPutc(digits[(v >> i) & 0xF]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -22,13 +22,4 @@ constexpr u32 SocthermBase = 0x700E2000;
|
|||||||
constexpr u32 SocthermSensorTemp1 = 0x1C8;
|
constexpr u32 SocthermSensorTemp1 = 0x1C8;
|
||||||
constexpr u32 SocthermSensorTemp2 = 0x1CC;
|
constexpr u32 SocthermSensorTemp2 = 0x1CC;
|
||||||
|
|
||||||
inline s32 TranslateSocthermTemp(u16 val) {
|
s32 TranslateSocthermTemp(u16 val);
|
||||||
s32 t = ((val >> 8) & 0xFF) * 1000;
|
|
||||||
if (val & (1u << 7)) {
|
|
||||||
t += 500;
|
|
||||||
}
|
|
||||||
if (val & (1u << 0)) {
|
|
||||||
t = -t;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user