hocclk: refactoring and ram pll measurement
This commit is contained in:
@@ -158,6 +158,12 @@ typedef enum {
|
||||
RamDisplayMode_EnumMax,
|
||||
} RamDisplayMode;
|
||||
|
||||
typedef enum {
|
||||
MemoryFrequencyMeasurementMode_Actmon = 0,
|
||||
MemoryFrequencyMeasurementMode_PLL,
|
||||
MemoryFrequencyMeasurementMode_EnumMax,
|
||||
} MemoryFrequencyMeasurementMode;
|
||||
|
||||
#define HOCCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
|
||||
|
||||
// Packed u32
|
||||
|
||||
@@ -68,6 +68,8 @@ typedef enum {
|
||||
HocClkConfigValue_CpuGovernorMinimumFreq,
|
||||
HocClkConfigValue_DisplayVoltage,
|
||||
|
||||
HocClkConfigValue_MemoryFrequencyMeasurementMode,
|
||||
|
||||
KipConfigValue_custRev,
|
||||
// KipConfigValue_mtcConf,
|
||||
KipConfigValue_hpMode,
|
||||
@@ -257,6 +259,9 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
|
||||
case HocClkConfigValue_DisplayVoltage:
|
||||
return pretty ? "Display Voltage" : "display_voltage";
|
||||
|
||||
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
|
||||
return pretty ? "Memory Frequency Measurement Mode" : "mem_freq_measurement_mode";
|
||||
|
||||
// KIP config values
|
||||
case KipConfigValue_custRev:
|
||||
return pretty ? "Custom Revision" : "kip_cust_rev";
|
||||
@@ -436,6 +441,7 @@ static inline uint64_t hocclkDefaultConfigValue(HocClkConfigValue val)
|
||||
case HocClkConfigValue_GPUScheduling:
|
||||
case HocClkConfigValue_LiveCpuUv:
|
||||
case HocClkConfigValue_GPUSchedulingMethod:
|
||||
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
|
||||
return 0ULL;
|
||||
case HocClkConfigValue_EristaMaxCpuClock:
|
||||
return 1785ULL;
|
||||
@@ -592,6 +598,7 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
|
||||
case HocClkConfigValue_GPUScheduling:
|
||||
case HocClkConfigValue_RAMVoltDisplayMode:
|
||||
case HocClkConfigValue_CpuGovernorMinimumFreq:
|
||||
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
|
||||
return true;
|
||||
case HocClkConfigValue_BatteryChargeCurrent:
|
||||
return ((input >= 1024) && (input <= 3072)) || !input;
|
||||
|
||||
@@ -525,3 +525,24 @@
|
||||
#define CL_DVFS_I2C_STS_0 0x48
|
||||
#define CL_DVFS_INTR_STS_0 0x5C
|
||||
#define CL_DVFS_I2C_CLK_DIVISOR_REGISTER_0 0x16C
|
||||
|
||||
#define CLK_SOURCE_EMC 0x19c
|
||||
|
||||
#define PLLC_BASE 0x080
|
||||
#define PLLM_BASE 0x090
|
||||
#define PLLP_BASE 0x0a0
|
||||
#define PLLA_BASE 0x0b0
|
||||
#define PLLU_BASE 0x0c0
|
||||
#define _PLLD_BASE 0x0d0
|
||||
#define PLLX_BASE 0x0e0
|
||||
#define PLLE_BASE 0x0e8
|
||||
#define PLLC2_BASE 0x4e8
|
||||
#define PLLC3_BASE 0x4fc
|
||||
#define PLLD2_BASE 0x4b8
|
||||
#define PLLRE_BASE 0x4c4
|
||||
#define PLLC4_BASE 0x5a4
|
||||
#define PLLMB_BASE 0x5e8
|
||||
#define PLLA1_BASE 0x6a4
|
||||
#define PLLDP_BASE 0x590
|
||||
|
||||
#define OSC_HZ 38400000ULL
|
||||
@@ -121,7 +121,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
|
||||
|
||||
// === VOLTAGES ===
|
||||
renderer->drawString(displayStrings[8], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU voltage
|
||||
renderer->drawString(displayStrings[9], false, dataPositions[1] + 9, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage
|
||||
renderer->drawString(displayStrings[9], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage
|
||||
|
||||
renderer->drawStringWithColoredSections(displayStrings[10], false, {""}, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor, tsl::separatorColor);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ class CpuSubmenuGui;
|
||||
class GpuSubmenuGui;
|
||||
class GpuCustomTableSubmenuGui;
|
||||
class RamTableEditor;
|
||||
class ExperimentalSettingsSubMenuGui;
|
||||
|
||||
MiscGui::MiscGui()
|
||||
{
|
||||
@@ -458,100 +459,19 @@ void MiscGui::listUI()
|
||||
displaySubMenu->setValue(R_ARROW);
|
||||
this->listElement->addItem(displaySubMenu);
|
||||
|
||||
#if IS_MINIMAL == 0
|
||||
// std::vector<NamedValue> chargerCurrents = {
|
||||
// NamedValue("Disabled", 0),
|
||||
// NamedValue("1024mA", 1024),
|
||||
// NamedValue("1280mA", 1280),
|
||||
// NamedValue("1536mA", 1536),
|
||||
// NamedValue("1792mA", 1792),
|
||||
// NamedValue("2048mA", 2048),
|
||||
// NamedValue("2304mA", 2304),
|
||||
// NamedValue("2560mA", 2560),
|
||||
// NamedValue("2816mA", 2816),
|
||||
// NamedValue("3072mA", 3072),
|
||||
// };
|
||||
if(this->configList->values[HocClkConfigValue_EnableExperimentalSettings]) {
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
|
||||
|
||||
addConfigToggle(HocClkConfigValue_LiveCpuUv, nullptr);
|
||||
std::vector<NamedValue> gpuSchedMethodValues = {
|
||||
NamedValue("INI", GpuSchedulingOverrideMethod_Ini),
|
||||
NamedValue("NV Service", GpuSchedulingOverrideMethod_NvService),
|
||||
};
|
||||
addConfigButton(
|
||||
HocClkConfigValue_GPUSchedulingMethod,
|
||||
"GPU Scheduling Override Method",
|
||||
ValueRange(0, 0, 1, "", 0),
|
||||
"GPU Scheduling Override Method",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
gpuSchedMethodValues,
|
||||
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);
|
||||
renderer->drawString("damage to your battery or charger!", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
});
|
||||
chargeWarningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 90);
|
||||
this->listElement->addItem(chargeWarningText);
|
||||
|
||||
if(!IsHoag()) {
|
||||
std::vector<NamedValue> chargerCurrents = {
|
||||
NamedValue("Disabled", 0),
|
||||
NamedValue("1024mA", 1024),
|
||||
NamedValue("1280mA", 1280),
|
||||
NamedValue("1536mA", 1536),
|
||||
NamedValue("1792mA", 1792),
|
||||
NamedValue("2048mA", 2048),
|
||||
NamedValue("2304mA", 2304),
|
||||
NamedValue("2560mA", 2560),
|
||||
NamedValue("2816mA", 2816),
|
||||
NamedValue("3072mA", 3072),
|
||||
};
|
||||
|
||||
ValueThresholds chargerThresholds(2048, 2049);
|
||||
|
||||
addConfigButton(
|
||||
HocClkConfigValue_BatteryChargeCurrent,
|
||||
"Charge Current Override",
|
||||
ValueRange(0, 0, 1, "", 0),
|
||||
"Charge Current Override",
|
||||
&chargerThresholds,
|
||||
{},
|
||||
chargerCurrents,
|
||||
false
|
||||
);
|
||||
if(this->configList->values[HocClkConfigValue_EnableExperimentalSettings]) {
|
||||
tsl::elm::ListItem* experimentalSubMenu = new tsl::elm::ListItem("Experimental Settings");
|
||||
experimentalSubMenu->setClickListener([](u64 keys) {
|
||||
if (keys & HidNpadButton_A) {
|
||||
tsl::changeTo<ExperimentalSettingsSubMenuGui>();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
std::vector<NamedValue> chargerCurrents = {
|
||||
NamedValue("Disabled", 0),
|
||||
NamedValue("1024mA", 1024),
|
||||
NamedValue("1280mA", 1280),
|
||||
NamedValue("1536mA", 1536),
|
||||
NamedValue("1792mA", 1792),
|
||||
NamedValue("2048mA", 2048),
|
||||
NamedValue("2304mA", 2304),
|
||||
NamedValue("2560mA", 2560),
|
||||
};
|
||||
return false;
|
||||
});
|
||||
experimentalSubMenu->setValue(R_ARROW);
|
||||
this->listElement->addItem(experimentalSubMenu);
|
||||
}
|
||||
|
||||
ValueThresholds chargerThresholds(1792, 1793);
|
||||
|
||||
addConfigButton(
|
||||
HocClkConfigValue_BatteryChargeCurrent,
|
||||
"Charge Current Override",
|
||||
ValueRange(0, 0, 1, "", 0),
|
||||
"Charge Current Override",
|
||||
&chargerThresholds,
|
||||
{},
|
||||
chargerCurrents,
|
||||
false
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
class GeneralSettingsSubMenuGui : public MiscGui {
|
||||
@@ -579,9 +499,125 @@ protected:
|
||||
{},
|
||||
false
|
||||
);
|
||||
|
||||
tsl::elm::CustomDrawer* exSetWarning = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
|
||||
renderer->drawString("\uE150 Experimental Settings", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("are a work in progress! Use with caution!", false, x + 20, y + 50, 18, tsl::style::color::ColorText);
|
||||
renderer->drawString("Here be dragons!", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
});
|
||||
exSetWarning->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 90);
|
||||
this->listElement->addItem(exSetWarning);
|
||||
|
||||
addConfigToggle(HocClkConfigValue_EnableExperimentalSettings, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
class ExperimentalSettingsSubMenuGui : public MiscGui {
|
||||
public:
|
||||
ExperimentalSettingsSubMenuGui() { }
|
||||
|
||||
protected:
|
||||
void listUI() override {
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental Settings"));
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
|
||||
addConfigToggle(HocClkConfigValue_LiveCpuUv, nullptr);
|
||||
std::vector<NamedValue> gpuSchedMethodValues = {
|
||||
NamedValue("INI", GpuSchedulingOverrideMethod_Ini),
|
||||
NamedValue("NV Service", GpuSchedulingOverrideMethod_NvService),
|
||||
};
|
||||
addConfigButton(
|
||||
HocClkConfigValue_GPUSchedulingMethod,
|
||||
"GPU Scheduling Override Method",
|
||||
ValueRange(0, 0, 1, "", 0),
|
||||
"GPU Scheduling Override Method",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
gpuSchedMethodValues,
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
std::vector<NamedValue> ramRFMeasurementMethods = {
|
||||
NamedValue("Actmon", MemoryFrequencyMeasurementMode_Actmon),
|
||||
NamedValue("PLL", MemoryFrequencyMeasurementMode_PLL),
|
||||
};
|
||||
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);
|
||||
renderer->drawString("damage to your battery or charger!", false, x + 20, y + 70, 18, tsl::style::color::ColorText);
|
||||
});
|
||||
chargeWarningText->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 90);
|
||||
this->listElement->addItem(chargeWarningText);
|
||||
|
||||
if(!IsHoag()) {
|
||||
std::vector<NamedValue> chargerCurrents = {
|
||||
NamedValue("Disabled", 0),
|
||||
NamedValue("1024mA", 1024),
|
||||
NamedValue("1280mA", 1280),
|
||||
NamedValue("1536mA", 1536),
|
||||
NamedValue("1792mA", 1792),
|
||||
NamedValue("2048mA", 2048),
|
||||
NamedValue("2304mA", 2304),
|
||||
NamedValue("2560mA", 2560),
|
||||
NamedValue("2816mA", 2816),
|
||||
NamedValue("3072mA", 3072),
|
||||
};
|
||||
|
||||
ValueThresholds chargerThresholds(2048, 2049);
|
||||
|
||||
addConfigButton(
|
||||
HocClkConfigValue_BatteryChargeCurrent,
|
||||
"Charge Current Override",
|
||||
ValueRange(0, 0, 1, "", 0),
|
||||
"Charge Current Override",
|
||||
&chargerThresholds,
|
||||
{},
|
||||
chargerCurrents,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
std::vector<NamedValue> chargerCurrents = {
|
||||
NamedValue("Disabled", 0),
|
||||
NamedValue("1024mA", 1024),
|
||||
NamedValue("1280mA", 1280),
|
||||
NamedValue("1536mA", 1536),
|
||||
NamedValue("1792mA", 1792),
|
||||
NamedValue("2048mA", 2048),
|
||||
NamedValue("2304mA", 2304),
|
||||
NamedValue("2560mA", 2560),
|
||||
};
|
||||
|
||||
ValueThresholds chargerThresholds(1792, 1793);
|
||||
|
||||
addConfigButton(
|
||||
HocClkConfigValue_BatteryChargeCurrent,
|
||||
"Charge Current Override",
|
||||
ValueRange(0, 0, 1, "", 0),
|
||||
"Charge Current Override",
|
||||
&chargerThresholds,
|
||||
{},
|
||||
chargerCurrents,
|
||||
false
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GovernorSettingsSubMenuGui : public MiscGui {
|
||||
public:
|
||||
GovernorSettingsSubMenuGui() { }
|
||||
@@ -1314,7 +1350,7 @@ protected:
|
||||
addConfigButton(
|
||||
KipConfigValue_eristaGpuVmin,
|
||||
"GPU Minimum Voltage",
|
||||
ValueRange(700, 875, 5, "mV", 1),
|
||||
ValueRange(675, 875, 5, "mV", 1),
|
||||
"GPU Minimum Voltage",
|
||||
&thresholdsDisabled,
|
||||
{},
|
||||
|
||||
@@ -86,7 +86,8 @@
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcUnknown": "0x00",
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "../file_utils.hpp"
|
||||
namespace board {
|
||||
|
||||
u64 clkVirtAddr, dsiVirtAddr;
|
||||
|
||||
HocClkSocType gSocType;
|
||||
u8 gDramID;
|
||||
HocClkConsoleType gConsoleType = HocClkConsoleType_Iowa;
|
||||
@@ -145,14 +147,12 @@ namespace board {
|
||||
|
||||
StartMiscThread(pwmCheck, &iCon);
|
||||
|
||||
u64 clkVirtAddr, dsiVirtAddr;
|
||||
|
||||
rc = QueryMemoryMapping(&clkVirtAddr, 0x60006000, 0x1000);
|
||||
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (clk)");
|
||||
|
||||
rc = QueryMemoryMapping(&dsiVirtAddr, 0x54300000, 0x40000);
|
||||
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (dsi)");
|
||||
|
||||
|
||||
display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = (GetConsoleType() == HocClkConsoleType_Hoag), .isRetroSUPER = integrations::GetRETROSuperStatus()};
|
||||
display::Initialize(&cfg);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define HOSSVC_HAS_TC (hosversionAtLeast(5,0,0))
|
||||
|
||||
namespace board {
|
||||
|
||||
extern u64 clkVirtAddr, dsiVirtAddr;
|
||||
void Initialize();
|
||||
void Exit();
|
||||
HocClkSocType GetSocType();
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
#include "board.hpp"
|
||||
#include "board_name.hpp"
|
||||
#include "../errors.hpp"
|
||||
|
||||
#include "pllmb.hpp"
|
||||
#include "../config.hpp"
|
||||
namespace board {
|
||||
|
||||
PcvModule GetPcvModule(HocClkModule hocclkModule) {
|
||||
@@ -141,10 +142,9 @@ namespace board {
|
||||
case HocClkModule_GPU:
|
||||
return t210ClkGpuFreq();
|
||||
case HocClkModule_MEM:
|
||||
return t210ClkMemFreq();
|
||||
return config::GetConfigValue(HocClkConfigValue_MemoryFrequencyMeasurementMode) == MemoryFrequencyMeasurementMode_PLL ? pllmb::getRamClockRatePLLMB() : t210ClkMemFreq();
|
||||
case HocClkModule_Display:
|
||||
return GetDisplayRate(hz);
|
||||
return hz;
|
||||
default:
|
||||
ASSERT_ENUM_VALID(HocClkModule, module);
|
||||
}
|
||||
|
||||
132
Source/hoc-clk/sysmodule/src/board/pllmb.cpp
Normal file
132
Source/hoc-clk/sysmodule/src/board/pllmb.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include "pllmb.hpp"
|
||||
|
||||
namespace pllmb {
|
||||
static const u8 qlin_hw_to_pdiv[17] = {
|
||||
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 30, 32
|
||||
};
|
||||
|
||||
enum pdiv_type {
|
||||
PDIV_QLIN,
|
||||
PDIV_POW2
|
||||
};
|
||||
|
||||
struct pll_desc_t {
|
||||
u32 base_offset;
|
||||
u8 divm_shift;
|
||||
u8 divm_width;
|
||||
u8 divn_shift;
|
||||
u8 divn_width;
|
||||
u8 divp_shift;
|
||||
u8 divp_width;
|
||||
pdiv_type ptype;
|
||||
};
|
||||
|
||||
static const pll_desc_t pll_table[] = {
|
||||
{ PLLM_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLMB_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLP_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ PLLA_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ PLLU_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ _PLLD_BASE, 0, 8, 8, 8, 20, 5, PDIV_POW2 },
|
||||
{ PLLX_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLA1_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLDP_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLD2_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLC4_BASE, 0, 8, 8, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLRE_BASE, 0, 8, 8, 8, 16, 4, PDIV_QLIN },
|
||||
{ PLLC_BASE, 0, 8, 10, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLC2_BASE, 0, 8, 10, 8, 20, 5, PDIV_QLIN },
|
||||
{ PLLC3_BASE, 0, 8, 10, 8, 20, 5, PDIV_QLIN },
|
||||
};
|
||||
|
||||
static inline u32 clk_read32(u32 offset)
|
||||
{
|
||||
return *(volatile u32 *)(uintptr_t)(board::clkVirtAddr + offset);
|
||||
}
|
||||
|
||||
static inline u32 extract(u32 val, u8 shift, u8 width)
|
||||
{
|
||||
return (val >> shift) & ((1u << width) - 1u);
|
||||
}
|
||||
|
||||
static u64 pll_rate_from_desc(const pll_desc_t &pll, u64 osc_hz,
|
||||
bool undivided)
|
||||
{
|
||||
u32 base = clk_read32(pll.base_offset);
|
||||
u32 divm = extract(base, pll.divm_shift, pll.divm_width);
|
||||
u32 divn = extract(base, pll.divn_shift, pll.divn_width);
|
||||
|
||||
if (divm == 0 || divn == 0)
|
||||
return 0;
|
||||
|
||||
u64 vco = osc_hz * divn / divm;
|
||||
|
||||
if (undivided)
|
||||
return vco;
|
||||
|
||||
u32 hw_p = extract(base, pll.divp_shift, pll.divp_width);
|
||||
u32 pdiv;
|
||||
|
||||
if (pll.ptype == PDIV_QLIN)
|
||||
pdiv = (hw_p < 17) ? qlin_hw_to_pdiv[hw_p] : 1;
|
||||
else
|
||||
pdiv = 1u << hw_p;
|
||||
|
||||
return vco / pdiv;
|
||||
}
|
||||
|
||||
static u64 pll_rate_by_offset(u32 base_offset, u64 osc_hz,
|
||||
bool undivided)
|
||||
{
|
||||
for (const auto &pll : pll_table) {
|
||||
if (pll.base_offset == base_offset)
|
||||
return pll_rate_from_desc(pll, osc_hz, undivided);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 getRamClockRatePLLMB()
|
||||
{
|
||||
u32 clk_src = clk_read32(CLK_SOURCE_EMC);
|
||||
u32 src = (clk_src >> 29) & 0x7;
|
||||
u32 div = (clk_src >> 0) & 0xff;
|
||||
|
||||
u32 pll_off;
|
||||
bool undivided = false;
|
||||
|
||||
switch (src) {
|
||||
case EMC_SRC_PLLM:
|
||||
pll_off = PLLM_BASE;
|
||||
break;
|
||||
case EMC_SRC_PLLM_UD:
|
||||
pll_off = PLLM_BASE;
|
||||
undivided = true;
|
||||
break;
|
||||
case EMC_SRC_PLLMB:
|
||||
pll_off = PLLMB_BASE;
|
||||
break;
|
||||
case EMC_SRC_PLLMB_UD:
|
||||
pll_off = PLLMB_BASE;
|
||||
undivided = true;
|
||||
break;
|
||||
case EMC_SRC_PLLP:
|
||||
pll_off = PLLP_BASE;
|
||||
break;
|
||||
case EMC_SRC_PLLP_UD:
|
||||
pll_off = PLLP_BASE;
|
||||
undivided = true;
|
||||
break;
|
||||
case EMC_SRC_PLLC:
|
||||
pll_off = PLLC_BASE;
|
||||
break;
|
||||
case EMC_SRC_CLK_M:
|
||||
return OSC_HZ;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 pll_hz = pll_rate_by_offset(pll_off, OSC_HZ, undivided);
|
||||
return pll_hz / (div + 2) * 2;
|
||||
}
|
||||
|
||||
}
|
||||
21
Source/hoc-clk/sysmodule/src/board/pllmb.hpp
Normal file
21
Source/hoc-clk/sysmodule/src/board/pllmb.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <switch.h>
|
||||
#include <hocclk.h>
|
||||
#include "board.hpp"
|
||||
#include <registers.h>
|
||||
namespace pllmb {
|
||||
|
||||
typedef enum PLLSource {
|
||||
EMC_SRC_PLLM = 0,
|
||||
EMC_SRC_PLLC = 1,
|
||||
EMC_SRC_PLLP = 2,
|
||||
EMC_SRC_CLK_M = 3,
|
||||
EMC_SRC_PLLM_UD = 4,
|
||||
EMC_SRC_PLLMB_UD = 5,
|
||||
EMC_SRC_PLLMB = 6,
|
||||
EMC_SRC_PLLP_UD = 7
|
||||
} PLLSource;
|
||||
|
||||
u64 getRamClockRatePLLMB();
|
||||
}
|
||||
@@ -545,8 +545,6 @@ namespace clockManager {
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
config::Initialize();
|
||||
|
||||
gContext = {};
|
||||
gContext.applicationId = 0;
|
||||
gContext.profile = HocClkProfile_Handheld;
|
||||
@@ -592,7 +590,6 @@ namespace clockManager {
|
||||
void Exit()
|
||||
{
|
||||
governor::exitThreads();
|
||||
config::Exit();
|
||||
}
|
||||
|
||||
HocClkContext GetCurrentContext()
|
||||
|
||||
@@ -134,6 +134,7 @@ int main(int argc, char** argv)
|
||||
fatalThrow(rc);
|
||||
return 1;
|
||||
}
|
||||
config::Initialize();
|
||||
|
||||
board::Initialize();
|
||||
processManagement::Initialize();
|
||||
@@ -164,7 +165,7 @@ int main(int argc, char** argv)
|
||||
clockManager::Exit();
|
||||
processManagement::Exit();
|
||||
board::Exit();
|
||||
|
||||
config::Exit();
|
||||
fileUtils::LogLine("Exit");
|
||||
svcSleepThread(1000000ULL);
|
||||
fileUtils::Exit();
|
||||
|
||||
Reference in New Issue
Block a user