hocclk: peak emc bw and mem display unit option

also correct bw reading to keep it accurate
This commit is contained in:
souldbminersmwc
2026-04-11 20:56:35 -04:00
parent d2a46e1202
commit 037f011c9b
13 changed files with 199 additions and 44 deletions

View File

@@ -112,6 +112,7 @@ typedef enum
HocClkPartLoad_RamBWAll,
HocClkPartLoad_RamBWCpu,
HocClkPartLoad_RamBWGpu,
HocClkPartLoad_RamBWPeak,
HocClkPartLoad_EnumMax
} HocClkPartLoad;
@@ -167,6 +168,13 @@ typedef enum {
MemoryFrequencyMeasurementMode_EnumMax,
} MemoryFrequencyMeasurementMode;
typedef enum {
MemDisplayUnit_MHz = 0,
MemDisplayUnit_MTs,
MemDisplayUnit_Both,
MemDisplayUnit_EnumMax,
} MemDisplayUnit;
#define HOCCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
// Packed u32

View File

@@ -29,7 +29,7 @@
#include <stdint.h>
#include <stddef.h>
#include "board.h"
typedef enum {
HocClkConfigValue_PollingIntervalMs = 0,
HocClkConfigValue_TempLogIntervalMs,
@@ -69,6 +69,7 @@ typedef enum {
HocClkConfigValue_DisplayVoltage,
HocClkConfigValue_MemoryFrequencyMeasurementMode,
HocClkConfigValue_MemDisplayUnit,
KipConfigValue_custRev,
// KipConfigValue_mtcConf,
@@ -262,6 +263,9 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
return pretty ? "Memory Frequency Measurement Mode" : "mem_freq_measurement_mode";
case HocClkConfigValue_MemDisplayUnit:
return pretty ? "Memory Frequency Display Unit" : "mem_display_unit";
// KIP config values
case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev";
@@ -443,6 +447,8 @@ static inline uint64_t hocclkDefaultConfigValue(HocClkConfigValue val)
case HocClkConfigValue_GPUSchedulingMethod:
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
return 0ULL;
case HocClkConfigValue_MemDisplayUnit:
return (uint64_t)MemDisplayUnit_MHz;
case HocClkConfigValue_EristaMaxCpuClock:
return 1785ULL;
@@ -599,6 +605,7 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case HocClkConfigValue_RAMVoltDisplayMode:
case HocClkConfigValue_CpuGovernorMinimumFreq:
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
case HocClkConfigValue_MemDisplayUnit:
return true;
case HocClkConfigValue_BatteryChargeCurrent:
return ((input >= 1024) && (input <= 3072)) || !input;

View File

@@ -30,6 +30,7 @@
#include <cstdio>
#include <string>
#include <cstdint>
#include <hocclk/board.h>
#define FREQ_DEFAULT_TEXT "Do not override"
@@ -44,4 +45,53 @@ static inline std::string formatListFreqMHz(std::uint32_t mhz)
return std::string(buf, snprintf(buf, sizeof(buf), "%u MHz", mhz));
}
static inline std::string formatListFreqHz(std::uint32_t hz) { return formatListFreqMHz(hz / 1000000); }
static inline std::string formatListFreqHz(uint32_t hz) { return formatListFreqMHz(hz / 1000000); }
static inline std::string formatListFreqMem(uint32_t mhz, MemDisplayUnit unit)
{
if(mhz == 0)
return FREQ_DEFAULT_TEXT;
uint32_t mts = mhz * 2;
char buf[24];
switch(unit)
{
case MemDisplayUnit_MHz:
snprintf(buf, sizeof(buf), "%u MHz", mhz);
break;
case MemDisplayUnit_Both:
snprintf(buf, sizeof(buf), "%u MHz (%u MT/s)", mhz, mts);
break;
case MemDisplayUnit_MTs:
default:
snprintf(buf, sizeof(buf), "%u MT/s", mts);
break;
}
return buf;
}
static inline std::string formatListFreqHzMem(uint32_t hz, MemDisplayUnit unit)
{
return formatListFreqMem(hz / 1000000, unit);
}
static inline std::string formatMemClockKhzLabel(uint32_t khz, MemDisplayUnit unit)
{
uint32_t mhz = khz / 1000;
uint32_t mts = khz / 500;
char buf[32];
switch(unit)
{
case MemDisplayUnit_MHz:
snprintf(buf, sizeof(buf), "%u MHz", mhz);
break;
case MemDisplayUnit_Both:
snprintf(buf, sizeof(buf), "%u MHz (%u MT/s)", mhz, mts);
break;
case MemDisplayUnit_MTs:
default:
snprintf(buf, sizeof(buf), "%u MT/s", mts);
break;
}
return buf;
}

View File

@@ -35,6 +35,7 @@ tsl::elm::ListItem* dispVoltItem = NULL;
tsl::elm::ListItem* ramBWItemAll = NULL;
tsl::elm::ListItem* ramBWItemCpu = NULL;
tsl::elm::ListItem* ramBWItemGpu = NULL;
tsl::elm::ListItem* ramBWItemMax = NULL;
ImageElement* CatImage = NULL;
HideableCategoryHeader* CatHeader = NULL;
@@ -75,17 +76,21 @@ void AboutGui::listUI()
this->listElement->addItem(
new tsl::elm::CategoryHeader("RAM Bandwidth")
);
ramBWItemMax =
new tsl::elm::ListItem("RAM BW (Peak):");
this->listElement->addItem(ramBWItemMax);
ramBWItemAll =
new tsl::elm::ListItem("Ram BW (All):");
new tsl::elm::ListItem("RAM BW (All):");
this->listElement->addItem(ramBWItemAll);
ramBWItemCpu =
new tsl::elm::ListItem("Ram BW (CPU):");
new tsl::elm::ListItem("RAM BW (CPU):");
this->listElement->addItem(ramBWItemCpu);
ramBWItemGpu =
new tsl::elm::ListItem("Ram BW (GPU):");
new tsl::elm::ListItem("RAM BW (GPU):");
this->listElement->addItem(ramBWItemGpu);
@@ -374,5 +379,7 @@ void AboutGui::refresh()
sprintf(strings[8], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWGpu]);
ramBWItemGpu->setValue(strings[8]);
sprintf(strings[9], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWPeak]);
ramBWItemMax->setValue(strings[9]);
}

View File

@@ -59,9 +59,11 @@ void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, HocClkProfil
} else if (module == HocClkModule_GPU) {
labels = IsMariko() ? *(marikoUV[configList.values[KipConfigValue_marikoGpuUV]]) : *(eristaUV[configList.values[KipConfigValue_eristaGpuUV]]);
}
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module](std::uint32_t hz) {
MemDisplayUnit memUnit = (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit];
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module, memUnit](std::uint32_t hz) {
this->profileList->mhzMap[profile][module] = hz / 1000000;
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
std::uint32_t mhz = this->profileList->mhzMap[profile][module];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(mhz, memUnit) : formatListFreqMHz(mhz));
Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))
{
@@ -104,8 +106,10 @@ void AppProfileGui::openValueChoiceGui(
void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module)
{
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(hocclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
listItem->setClickListener([this, listItem, profile, module](u64 keys) {
MemDisplayUnit memUnit = (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit];
std::uint32_t mhz = this->profileList->mhzMap[profile][module];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(mhz, memUnit) : formatListFreqMHz(mhz));
listItem->setClickListener([this, listItem, profile, module, memUnit](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A)
{
this->openFreqChoiceGui(listItem, profile, module);
@@ -115,7 +119,7 @@ void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module
{
// Reset to "Default" (0 MHz)
this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(formatListFreqMHz(0));
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, memUnit) : formatListFreqMHz(0));
Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))

View File

@@ -27,6 +27,7 @@
#include "base_menu_gui.h"
#include "fatal_gui.h"
#include "../format.h"
// Cache hardware model to avoid repeated syscalls
@@ -229,7 +230,21 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[HocClkModule_MEM]; // MEM
sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
std::uint32_t unit = configList.values[HocClkConfigValue_MemDisplayUnit];
std::uint32_t mhz = hz / 1000000U;
std::uint32_t mts = mhz * 2;
std::uint32_t tenth = (hz / 100000U) % 10U;
if(unit == MemDisplayUnit_MTs)
sprintf(displayStrings[4], "%u MT/s", mts);
else if(unit == MemDisplayUnit_MHz)
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
else if(unit == MemDisplayUnit_Both) {
hz = context->realFreqs[HocClkModule_MEM];
mhz = hz / 1000000U;
mhz * 2;
tenth = (hz / 100000U) % 10U;
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
}
// Real frequencies
hz = context->realFreqs[HocClkModule_CPU]; // CPU
@@ -239,7 +254,14 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[HocClkModule_MEM]; // MEM
sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
std::uint32_t unit = configList.values[HocClkConfigValue_MemDisplayUnit];
std::uint32_t mhz = hz / 1000000U;
std::uint32_t mts = mhz * 2;
std::uint32_t tenth = (hz / 100000U) % 10U;
if(unit == MemDisplayUnit_MTs || unit == MemDisplayUnit_Both)
sprintf(displayStrings[7], "%u MT/s", mts);
else
sprintf(displayStrings[7], "%u.%u MHz", mhz, tenth);
// Voltages
sprintf(displayStrings[8], "%.1f mV", context->voltages[HocClkVoltage_CPU] / 1000.0);

View File

@@ -55,10 +55,11 @@ FreqChoiceGui::~FreqChoiceGui()
tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety)
{
std::string text = formatListFreqHz(hz);
if(module == HocClkModule_MEM && hz != 0)
text += " (" + std::to_string(hz / 500000) + " MT/s)";
std::string text;
if(module == HocClkModule_MEM)
text = formatListFreqHzMem(hz, (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit]);
else
text = formatListFreqHz(hz);
std::string rightText = "";
auto it = labels.find(hz);

View File

@@ -246,7 +246,8 @@ void GlobalOverrideGui::addModuleListItem(HocClkModule module)
{
tsl::elm::ListItem *listItem =
new tsl::elm::ListItem(hocclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(0));
MemDisplayUnit memUnit = (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, memUnit) : formatListFreqMHz(0));
listItem->setClickListener([this, module](u64 keys) {
if ((keys & HidNpadButton_A) == HidNpadButton_A) {
this->openFreqChoiceGui(module);
@@ -262,7 +263,7 @@ void GlobalOverrideGui::addModuleListItem(HocClkModule module)
this->context->overrideFreqs[module] = 0;
this->listHz[module] = 0;
this->listItems[module]->setValue(formatListFreqHz(0));
this->listItems[module]->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit]) : formatListFreqHz(0));
return true;
}
@@ -409,7 +410,9 @@ void GlobalOverrideGui::refresh()
}
} else {
this->listItems[m]->setValue(
formatListFreqHz(this->context->overrideFreqs[m]));
m == HocClkModule_MEM
? formatListFreqHzMem(this->context->overrideFreqs[m], (MemDisplayUnit)configList.values[HocClkConfigValue_MemDisplayUnit])
: formatListFreqHz(this->context->overrideFreqs[m]));
}
this->listHz[m] = this->context->overrideFreqs[m];

View File

@@ -147,13 +147,18 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
ValueThresholds thresholdsCopy = (thresholds ? *thresholds : ValueThresholds{});
listItem->setClickListener(
[this, configVal, range, categoryName, thresholdsCopy, labels, namedValues, showDefaultValue, kip](u64 keys)
[this, configVal, range, categoryName, thresholdsCopy, labels, showDefaultValue, kip](u64 keys)
{
if ((keys & HidNpadButton_A) == 0)
return false;
std::uint32_t currentValue = this->configList->values[configVal];
// Look up live namedValues so relabeling in refresh() is reflected
auto nvIt = this->configNamedValues.find(configVal);
const std::vector<NamedValue>& liveNamedValues = (nvIt != this->configNamedValues.end())
? nvIt->second : std::vector<NamedValue>();
if (thresholdsCopy.warning != 0 || thresholdsCopy.danger != 0) {
tsl::changeTo<ValueChoiceGui>(
@@ -176,7 +181,7 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
thresholdsCopy,
true,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
} else {
@@ -201,7 +206,7 @@ void MiscGui::addConfigButton(HocClkConfigValue configVal,
ValueThresholds(),
false,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
}
@@ -260,13 +265,18 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
ValueThresholds thresholdsCopy = (thresholds ? *thresholds : ValueThresholds{});
listItem->setClickListener(
[this, configVal, range, categoryName, thresholdsCopy, labels, namedValues, showDefaultValue, kip](u64 keys)
[this, configVal, range, categoryName, thresholdsCopy, labels, showDefaultValue, kip](u64 keys)
{
if ((keys & HidNpadButton_A) == 0)
return false;
std::uint32_t currentValue = this->configList->values[configVal];
// Look up live namedValues so relabeling in refresh() is reflected
auto nvIt = this->configNamedValues.find(configVal);
const std::vector<NamedValue>& liveNamedValues = (nvIt != this->configNamedValues.end())
? nvIt->second : std::vector<NamedValue>();
if (thresholdsCopy.warning != 0 || thresholdsCopy.danger != 0) {
tsl::changeTo<ValueChoiceGui>(
@@ -289,7 +299,7 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
thresholdsCopy,
true,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
} else {
@@ -314,7 +324,7 @@ void MiscGui::addConfigButtonS(HocClkConfigValue configVal,
ValueThresholds(),
false,
labels,
namedValues,
liveNamedValues,
showDefaultValue
);
}
@@ -530,6 +540,22 @@ protected:
addConfigButton(HocClkConfigValue_RAMVoltDisplayMode, "RAM Voltage Display Mode", ValueRange(0, 12, 1, "", 0), "RAM Voltage Display Mode", &thresholdsDisabled, {}, ramVoltDispModes, false);
}
std::vector<NamedValue> memDisplayUnitValues = {
NamedValue("MHz", MemDisplayUnit_MHz),
NamedValue("MT/s", MemDisplayUnit_MTs),
NamedValue("Both", MemDisplayUnit_Both),
};
addConfigButton(
HocClkConfigValue_MemDisplayUnit,
"RAM Display Unit",
ValueRange(0, 0, 2, "", 0),
"RAM Display Unit",
&thresholdsDisabled,
{},
memDisplayUnitValues,
false
);
addConfigButton(
HocClkConfigValue_PollingIntervalMs,
"Polling Interval",
@@ -594,7 +620,6 @@ protected:
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);
@@ -865,7 +890,7 @@ protected:
this->listElement->addItem(freqSubmenu);
} else {
std::vector<NamedValue> marikoMaxEmcClock = {
NamedValue("Disabled", 1600000),
NamedValue("1600 MHz", 1600000),
NamedValue("1633 MHz", 1633000),
NamedValue("1666 MHz", 1666000),
NamedValue("1700 MHz", 1700000),
@@ -926,6 +951,11 @@ protected:
// NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000),
};
MemDisplayUnit unit = (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit];
for (auto& nv : marikoMaxEmcClock)
if (nv.name != "Disabled")
nv.name = formatMemClockKhzLabel(nv.value, unit);
addConfigButton(KipConfigValue_marikoEmcMaxClock, "Ram Max Clock", ValueRange(0, 1, 1, "", 1), "Ram Max Clock", &thresholdsDisabled, {}, marikoMaxEmcClock, false, true);
}
@@ -1291,21 +1321,13 @@ protected:
ValueThresholds thresholdsDisabled(0, 0);
// 1600000, 1331200, 1065600, 800000, 665600, 408000, 204000
MemDisplayUnit unit = (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit];
tsl::elm::ListItem* ramItem665 = new tsl::elm::ListItem("665 MHz");
this->listElement->addItem(ramItem665);
tsl::elm::ListItem* ramItem800 = new tsl::elm::ListItem("800 MHz");
this->listElement->addItem(ramItem800);
tsl::elm::ListItem* ramItem1065 = new tsl::elm::ListItem("1065 MHz");
this->listElement->addItem(ramItem1065);
tsl::elm::ListItem* ramItem1331 = new tsl::elm::ListItem("1331 MHz");
this->listElement->addItem(ramItem1331);
tsl::elm::ListItem* ramItem1600 = new tsl::elm::ListItem("1600 MHz");
this->listElement->addItem(ramItem1600);
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(665600, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(800000, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(1065600, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(1331200, unit)));
this->listElement->addItem(new tsl::elm::ListItem(formatMemClockKhzLabel(1600000, unit)));
ValueThresholds eristaRamThresholds(2208000, 2304000);
@@ -1349,6 +1371,10 @@ protected:
NamedValue("2400 MHz", 2400000, "JEDEC."),
};
for (auto& nv : eristaMaxEmcClock)
if (nv.name != "Disabled")
nv.name = formatMemClockKhzLabel(nv.value, unit);
addConfigButtonS(KipConfigValue_eristaEmcMaxClock, "", ValueRange(0, 1, 1, "", 1), "", &eristaRamThresholds, {}, eristaMaxEmcClock, false, A_BTN, true);
addConfigButtonS(KipConfigValue_eristaEmcMaxClock1, "", ValueRange(0, 1, 1, "", 1), "", &eristaRamThresholds, {}, eristaMaxEmcClock, false, A_BTN, true);
addConfigButtonS(KipConfigValue_eristaEmcMaxClock2, "", ValueRange(0, 1, 1, "", 1), "", &eristaRamThresholds, {}, eristaMaxEmcClock, false, A_BTN, true);
@@ -1829,6 +1855,23 @@ void MiscGui::refresh() {
}
updateConfigToggles();
// relabel when display unit changes
MemDisplayUnit unit = (MemDisplayUnit)this->configList->values[HocClkConfigValue_MemDisplayUnit];
constexpr HocClkConfigValue emcKeys[] = {
KipConfigValue_marikoEmcMaxClock,
KipConfigValue_eristaEmcMaxClock,
KipConfigValue_eristaEmcMaxClock1,
KipConfigValue_eristaEmcMaxClock2,
};
for (auto key : emcKeys) {
auto it = this->configNamedValues.find(key);
if (it != this->configNamedValues.end()) {
for (auto& nv : it->second)
if (nv.value != 1600000)
nv.name = formatMemClockKhzLabel(nv.value, unit);
}
}
for (const auto& [configVal, button] : this->configButtons) {
uint64_t currentValue = this->configList->values[configVal];
const ValueRange& range = this->configRanges[configVal];

View File

@@ -41,6 +41,7 @@ protected:
std::map<HocClkConfigValue, std::tuple<tsl::elm::TrackBar*, tsl::elm::ListItem*, std::vector<uint64_t>>> configTrackbars;
std::set<HocClkConfigValue> configButtonSKeys;
std::map<HocClkConfigValue, std::string> configButtonSSubtext;
std::set<HocClkConfigValue> emcClockConfigs;
void addConfigToggle(HocClkConfigValue configVal, const char* altName, bool kip = false);
void addConfigButton(HocClkConfigValue configVal,

View File

@@ -42,6 +42,7 @@ u32 t210EmcLoadCpu(void);
u32 t210EmcBwAll(void);
u32 t210EmcBwCpu(void);
u32 t210EmcBwGpu(void);
u32 t210EmcBwPeak(void);
#ifdef __cplusplus
}

View File

@@ -260,8 +260,8 @@ static void _clock_update_freqs(void)
g_emc_lall = (u64)_actmon_dev_get_count_avg(ACTMON_DEV_MC_ALL) * 10 * 100 / (emc_freq * ACTMON_PERIOD_MS);
g_emc_lcpu = (u64)_actmon_dev_get_count_avg(ACTMON_DEV_MC_CPU) * 10 * 100 / (emc_freq * ACTMON_PERIOD_MS);
g_emc_bw_all = (u64)emc_freq * 8 * g_emc_lall / 1000 / 1000;
g_emc_bw_cpu = (u64)emc_freq * 8 * g_emc_lcpu / 1000 / 1000;
g_emc_bw_all = (u64)emc_freq * 16 * g_emc_lall / 1000000;
g_emc_bw_cpu = (u64)emc_freq * 16 * g_emc_lcpu / 1000000;
g_emc_bw_gpu = g_emc_bw_all > g_emc_bw_cpu ? g_emc_bw_all - g_emc_bw_cpu : 0;
}
@@ -312,4 +312,10 @@ u32 t210EmcBwGpu()
{
_clock_update_freqs();
return g_emc_bw_gpu;
}
u32 t210EmcBwPeak()
{
_clock_update_freqs();
return ((u64)g_mem_freq * 16) / 1000000;
}

View File

@@ -126,6 +126,8 @@ namespace board {
return t210EmcBwCpu();
case HocClkPartLoad_RamBWGpu:
return t210EmcBwGpu();
case HocClkPartLoad_RamBWPeak:
return t210EmcBwPeak();
default:
ASSERT_ENUM_VALID(HocClkPartLoad, loadSource);
}