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();
|
||||
|
||||
46
dist/README.md
vendored
46
dist/README.md
vendored
@@ -32,7 +32,7 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
## Default clocks
|
||||
|
||||
* **CPU:** Up to 1963MHz (Mariko) / 1785MHz (Erista)
|
||||
* **GPU:** Up to 1075MHz (Mariko) / 921MHz (Erista)
|
||||
@@ -93,7 +93,8 @@ Refer to COMPILATION.md
|
||||
* 665
|
||||
|
||||
### CPU clocks
|
||||
* 2601 → mariko absolute max, very dangerous
|
||||
* 2703 → mariko absolute max, dangerous
|
||||
* 2601 → unsafe
|
||||
* 2499
|
||||
* 2397 → mariko safe max with UV (low speedo)
|
||||
* 2295
|
||||
@@ -113,9 +114,6 @@ Refer to COMPILATION.md
|
||||
* 816
|
||||
* 714
|
||||
* 612 → sleep mode
|
||||
|
||||
**Notes:**
|
||||
1. On Erista, CPU in handheld is capped to 1581MHz
|
||||
|
||||
### GPU clocks
|
||||
* 1536 → absolute max clock on mariko. very dangerous
|
||||
@@ -142,27 +140,33 @@ Refer to COMPILATION.md
|
||||
* 76 → boost mode
|
||||
|
||||
**Notes:**
|
||||
1. GPU overclock is capped at 460MHz on erista in handheld
|
||||
2. On Mariko, cap with No uv is 614MHz, with SLT it is 691MHz and with HiOPT it's 768MHz
|
||||
3. Clocks higher than 768MHz on erista need the official charger is plugged in.
|
||||
4. On Mariko, cap with No uv is 844MHz, with SLT it is 921MHz and with HiOPT it's 998MHz
|
||||
1. On Erista, CPU in handheld is capped to 1581MHz
|
||||
2. GPU overclock is capped at 460MHz on erista in handheld
|
||||
3. On Mariko, cap with No uv is 614MHz, with SLT it is 691MHz and with HiOPT it's 768MHz
|
||||
4. Clocks higher than 768MHz on erista need the official charger is plugged in.
|
||||
5. On Mariko, cap with No uv is 844MHz, with SLT it is 921MHz and with HiOPT it's 998MHz
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Credits
|
||||
* **Lightos's Cat** - Cat
|
||||
|
||||
* **Souldbminer** – hoc-clk and loader development
|
||||
* **Lightos** – loader patches development
|
||||
* **Souldbminer** - hoc-clk and loader development
|
||||
* **Lightos** - Loader patches development, hoc-clk development, guides
|
||||
* **SciresM** - Atmosphere CFW
|
||||
* **CTCaer** - L4T, Hekate, perfect ram timings
|
||||
* **KazushiMe** – Switch OC Suite
|
||||
* **hanai3bi (meha)** – Switch OC Suite, EOS, sys-clk-eos
|
||||
* **NaGaa95** – L4T-OC-kernel
|
||||
* **B3711 (halop)** – EOS
|
||||
* **sys-clk team (m4xw, p-sam, natinusala)** – sys-clk
|
||||
* **b0rd2death** – Ultrahand sys-clk & Status Monitor fork
|
||||
* **CTCaer** - L4T, Hekate, proper RAM timings
|
||||
* **KazushiMe** - Switch OC Suite
|
||||
* **Hanai3bi (Meha)** - Switch OC Suite, EOS, sys-clk-eos
|
||||
* **NaGaa95** - L4T-OC kernel, Status Monitor fork
|
||||
* **B3711 (halop)** - EOS
|
||||
* **sys-clk team (m4xw, p-sam, natinusala)** - sys-clk
|
||||
* **Dominatorul** - Soctherm driver, guides, general help
|
||||
* **b0rd2death** - Ultrahand sys-clk & Status Monitor fork
|
||||
* **MasaGratoR and ZachyCatGames** - General help
|
||||
* **MasaGratoR** - Status Monitor & Display Refresh Rate Driver
|
||||
* **Dom, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh, frost, letum00 and Xenshen** - Testing
|
||||
* **Samybigio2011** - Italian translations
|
||||
* **MasaGratoR** - Status Monitor & Display Refresh Rate driver
|
||||
* **Dominatorul, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh, frost, letum00, and Xenshen** - Testing
|
||||
* **Samybigio2011, Miki** - Italian translations
|
||||
* **angelblaster** - Korean translations
|
||||
* **q1332348216-glitch** - Chinese translations
|
||||
* **Nvidia** - [Tegra X1 Technical Reference Manual](https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual), soctherm driver, L4T
|
||||
|
||||
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
BIN
dist/atmosphere/contents/00FF0000636C6BFF/exefs.nsp
vendored
Binary file not shown.
148
dist/config/horizon-oc/lang/lang/it.json
vendored
148
dist/config/horizon-oc/lang/lang/it.json
vendored
@@ -2,140 +2,140 @@
|
||||
"Information": "Informazioni",
|
||||
"IDDQ:": "IDDQ:",
|
||||
"Module: ": "Modulo:",
|
||||
"sys-dock status:": "stato del dock di sistema:",
|
||||
"sys-dock status:": "stato di sys-dock",
|
||||
"SaltyNX status:": "Stato di SaltyNX:",
|
||||
"RR Display status:": "Stato di visualizzazione RR:",
|
||||
"Wafer Position:": "Posizione del wafer:",
|
||||
"RR Display status:": "Stato del RR:",
|
||||
"Wafer Position:": "Posizione nel Wafer:",
|
||||
"Credits": "Crediti",
|
||||
"Developers": "Sviluppatori",
|
||||
"Contributors": "Collaboratori",
|
||||
"Testers": "Tester",
|
||||
"Special Thanks": "Un ringraziamento speciale",
|
||||
"Special Thanks": "Un Ringraziamento Speciale",
|
||||
"Unknown": "Sconosciuto",
|
||||
"Installed": "Installato",
|
||||
"Not Installed": "Non installato",
|
||||
"X: %u Y: %u": "X: %u Y: %u",
|
||||
"THE BEER-WARE LICENSE": "LA LICENZA PER GLI ARTICOLI DI BIRRA",
|
||||
"THE BEER-WARE LICENSE": "THE BEER-WARE LICENSE",
|
||||
"Default": "Predefinito",
|
||||
"Do Not Override": "Non sovrascrivere",
|
||||
"Do Not Override": "Non Sovrascrivere",
|
||||
"Disabled": "Disabilitato",
|
||||
"Enabled": "Abilitato",
|
||||
" \\ue0e3 Reset": "\\ue0e3 Ripristina",
|
||||
"Display": "Visualizzazione",
|
||||
"Display": "Schermo",
|
||||
"Application changed\\n\\n": "Applicazione modificata\\n\\n",
|
||||
"The running application changed\\n\\n": "L'applicazione in esecuzione è cambiata\\n\\n",
|
||||
"while editing was going on.": "mentre era in corso la modifica.",
|
||||
"Board": "Consiglio",
|
||||
"Board": "Scheda",
|
||||
"%u.%u%u mV": "%u.%u%u mV",
|
||||
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossibile connettersi al modulo di sistema hoc-clk.\\n\\n",
|
||||
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossibile connettersi al sysmodule hoc-clk.\\n\\n",
|
||||
"Please make sure everything is\\n\\n": "Assicurati che tutto sia\\n\\n",
|
||||
"correctly installed and enabled.": "correttamente installato e abilitato.",
|
||||
"Fatal error": "Errore fatale",
|
||||
"Temporary Overrides ": "Sostituzioni temporanee",
|
||||
"Sleep Mode": "Modalità di sospensione",
|
||||
"Stock": "Magazzino",
|
||||
"Dev OC": "OC di sviluppo",
|
||||
"Boost Mode": "Modalità potenziamento",
|
||||
"Safe Max": "Sicuro massimo",
|
||||
"Unsafe Max": "Non sicuro Max",
|
||||
"Absolute Max": "Massimo assoluto",
|
||||
"Handheld Safe Max": "Cassaforte portatile max",
|
||||
"Temporary Overrides ": "Sostituzioni Temporanee",
|
||||
"Sleep Mode": "Modalità di Sospensione",
|
||||
"Stock": "Originale",
|
||||
"Dev OC": "OC dev",
|
||||
"Boost Mode": "Modalità Boost",
|
||||
"Safe Max": "Massimo Sicuro",
|
||||
"Unsafe Max": "Massimo Non Sicuro",
|
||||
"Absolute Max": "Massimo Assoluto",
|
||||
"Handheld Safe Max": "Massimo Sicuro Modalità Portatile",
|
||||
"Enable": "Abilita",
|
||||
"Edit App Profile": "Modifica profilo dell'app",
|
||||
"Edit Global Profile": "Modifica profilo globale",
|
||||
"Temporary Overrides": "Sostituzioni temporanee",
|
||||
"Edit App Profile": "Modifica Profilo Dell'App",
|
||||
"Edit Global Profile": "Modifica Profilo Globale",
|
||||
"Temporary Overrides": "Sostituzioni Temporanee",
|
||||
"Settings": "Impostazioni",
|
||||
"About": "Circa",
|
||||
"About": "A Riguardo Di",
|
||||
"Compiling with minimal features": "Compilazione con funzionalità minime",
|
||||
"General Settings": "Impostazioni generali",
|
||||
"Governor Settings": "Impostazioni del governatore",
|
||||
"Safety Settings": "Impostazioni di sicurezza",
|
||||
"Save KIP Settings": "Salva le impostazioni KIP",
|
||||
"General Settings": "Impostazioni Generali",
|
||||
"Governor Settings": "Impostazioni Del Governor",
|
||||
"Safety Settings": "Impostazioni Di Sicurezza",
|
||||
"Save KIP Settings": "Salva le impostazioni del KIP",
|
||||
"RAM Settings": "Impostazioni della RAM",
|
||||
"CPU Settings": "Impostazioni della CPU",
|
||||
"GPU Settings": "Impostazioni della GPU",
|
||||
"Display Settings": "Impostazioni di visualizzazione",
|
||||
"Display Settings": "Impostazioni dello Schermo",
|
||||
"Experimental": "Sperimentale",
|
||||
"GPU Scheduling Override Method": "Metodo di override della pianificazione GPU",
|
||||
"GPU Scheduling Override Method": "Metodo di override dello scheduling GPU",
|
||||
"can be dangerous and may cause": "può essere pericoloso e può causare",
|
||||
"damage to your battery or charger!": "danni alla batteria o al caricabatterie!",
|
||||
"Charge Current Override": "Override della corrente di carica",
|
||||
"RAM Voltage Display Mode": "Modalità di visualizzazione della tensione RAM",
|
||||
"Charge Current Override": "Override della Corrente di Carica",
|
||||
"RAM Voltage Display Mode": "Modalità di Visualizzazione della Tensione RAM",
|
||||
"Polling Interval": "Intervallo di polling",
|
||||
"CPU Governor Minimum Frequency": "Frequenza minima del governatore della CPU",
|
||||
"CPU Governor Minimum Frequency": "Frequenza minima del Governor della CPU",
|
||||
"refresh rates may cause stress": "le frequenze di aggiornamento possono causare stress",
|
||||
"or damage to your display! ": "o danni al display!",
|
||||
"Proceed at your own risk!": "Procedi a tuo rischio e pericolo!",
|
||||
"Max Handheld Display": "Display portatile massimo",
|
||||
"Display Clock": "Visualizza orologio",
|
||||
"Official Rating": "Valutazione ufficiale",
|
||||
"Max Handheld Display": "Display Massimo in Modalità Portatile",
|
||||
"Display Clock": "Frequenza del Display",
|
||||
"Official Rating": "Rating Ufficiale",
|
||||
"TDP Threshold": "Soglia TDP",
|
||||
"Power": "Potenza",
|
||||
"Thermal Throttle Limit": "Limite della valvola termica",
|
||||
"Thermal Throttle Limit": "Limite Termico",
|
||||
"HP Mode": "Modalità HP",
|
||||
"Default (Mariko)": "Predefinito (Mariko)",
|
||||
"Default (Erista)": "Predefinito (Erista)",
|
||||
"Rating": "Valutazione",
|
||||
"Safe Max (Mariko)": "Safe Max (Mariko)",
|
||||
"Safe Max (Erista)": "Safe Max (Erista)",
|
||||
"Safe Max (Mariko)": "Massimo Sicuro (Mariko)",
|
||||
"Safe Max (Erista)": "Massimo Sicuro (Erista)",
|
||||
"RAM VDD2 Voltage": "Tensione RAM VDD2",
|
||||
"Voltage": "Voltaggio",
|
||||
"RAM VDDQ Voltage": "Voltaggio VDDQ della RAM",
|
||||
"RAM Frequency Editor": "Editor della frequenza RAM",
|
||||
"JEDEC.": "JEDEC.",
|
||||
"High speedo needed!": "È necessaria l'alta velocità!",
|
||||
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (richiede Speedo/PLL estremo)",
|
||||
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (richiede Speedo/PLL estremo)",
|
||||
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (richiede Speedo/PLL estremo)",
|
||||
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (è necessario un ridicolo Speedo/PLL)",
|
||||
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (è necessario un ridicolo Speedo/PLL)",
|
||||
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (è necessario un ridicolo Speedo/PLL)",
|
||||
"Ram Max Clock": "Orologio Ram Max",
|
||||
"RAM Latency Editor": "Editor della latenza RAM",
|
||||
"RAM Timing Reductions": "Riduzioni della temporizzazione della RAM",
|
||||
"Memory Timings": "Tempi di memoria",
|
||||
"High speedo needed!": "Alto Valore Speedo Necessario!",
|
||||
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (richiede Speedo/PLL altissimo)",
|
||||
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (richiede Speedo/PLL altissimo)",
|
||||
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (richiede Speedo/PLL altissimo)",
|
||||
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (richiede Speedo/PLL estremo)",
|
||||
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (richiede Speedo/PLL estremo)",
|
||||
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (richiede Speedo/PLL estremo)",
|
||||
"Ram Max Clock": "Frequenza Massima Ram",
|
||||
"RAM Latency Editor": "Editor della Latenza RAM",
|
||||
"RAM Timing Reductions": "Riduzioni dei Timing della RAM",
|
||||
"Memory Timings": "Timing di Memoria",
|
||||
"Advanced": "Avanzato",
|
||||
"t6 tRTW Fine Tune": "t6 tRTW Sintonia fine",
|
||||
"tRTW Fine Tune": "tRTW Sintonia fine",
|
||||
"t7 tWTR Fine Tune": "t7 tWTR Sintonia fine",
|
||||
"tWTR Fine Tune": "tWTR Sintonia fine",
|
||||
"Memory Latencies": "Latenza della memoria",
|
||||
"Read Latency": "Leggi latenza",
|
||||
"Write Latency": "Scrivi latenza",
|
||||
"CPU Boost Clock": "Orologio di potenziamento della CPU",
|
||||
"CPU UV": "UV della CPU",
|
||||
"t6 tRTW Fine Tune": "Regolazione Fine t6 tRTW",
|
||||
"tRTW Fine Tune": "Regolazione Fine tRTW",
|
||||
"t7 tWTR Fine Tune": "Regolazione Fine t7 tWTR",
|
||||
"tWTR Fine Tune": "Regolazione Fine tWTR",
|
||||
"Memory Latencies": "Latenza della Memoria",
|
||||
"Read Latency": "Latenza di Lettura",
|
||||
"Write Latency": "Latenza di Scrittura",
|
||||
"CPU Boost Clock": "Frequenza CPU in Boost",
|
||||
"CPU UV": "Undervolt CPU",
|
||||
"CPU Unlock": "Sblocco della CPU",
|
||||
"CPU VMIN": "CPUVMIN",
|
||||
"CPU VMIN": "CPU VMIN",
|
||||
"CPU Max Voltage": "Voltaggio massimo della CPU",
|
||||
"CPU Max Clock": "Orologio massimo della CPU",
|
||||
"Extreme UV Table": "Tavolo UV estremo",
|
||||
"CPU Max Clock": "Frequenza massima della CPU",
|
||||
"Extreme UV Table": "Tabella UV estremo",
|
||||
"CPU UV Table": "Tabella UV della CPU",
|
||||
"CPU Low UV": "CPU con raggi UV bassi",
|
||||
"CPU High UV": "UV elevato della CPU",
|
||||
"CPU Low VMIN": "VMIN CPU basso",
|
||||
"CPU High VMIN": "CPU alta VMIN",
|
||||
"No Undervolt": "Nessuna sottotensione",
|
||||
"CPU Low UV": "CPU UV Bassa Frequenza",
|
||||
"CPU High UV": "CPU UV Alta Frequenza",
|
||||
"CPU Low VMIN": "CPU VMIN Bassa Frequenza",
|
||||
"CPU High VMIN": "CPU VMIN Alta Frequenza",
|
||||
"No Undervolt": "Nessun Undervolt",
|
||||
"SLT Table": "Tabella SLT",
|
||||
"HiOPT Table": "Tabella HiOPT",
|
||||
"GPU Undervolt Table": "Tabella di sottotensione GPU",
|
||||
"GPU Minimum Voltage": "Voltaggio minimo della GPU",
|
||||
"GPU Undervolt Table": "Tabella di Undervolt GPU",
|
||||
"GPU Minimum Voltage": "Voltaggio Minimo della GPU",
|
||||
"Calculate GPU Vmin": "Calcola GPU Vmin",
|
||||
"GPU VMIN": "GPUVMIN",
|
||||
"GPU VMIN": "GPU VMIN",
|
||||
"GPU Maximum Voltage": "Voltaggio massimo della GPU",
|
||||
"GPU Voltage Offset": "Offset di tensione della GPU",
|
||||
"GPU Voltage Offset": "Offset di Voltaggio della GPU",
|
||||
"Do not override": "Non sovrascrivere",
|
||||
"Enabled (Default)": "Abilitato (impostazione predefinita)",
|
||||
"96.6% limit": "Limite del 96,6%.",
|
||||
"99.7% limit": "Limite del 99,7%.",
|
||||
"GPU Scheduling Override": "Override della pianificazione GPU",
|
||||
"GPU Scheduling Override": "Override dello Scheduling GPU",
|
||||
"Official Service": "Servizio ufficiale",
|
||||
"GPU DVFS Mode": "Modalità DVFS GPU",
|
||||
"GPU DVFS Offset": "Offset DVFS della GPU",
|
||||
"GPU Voltage Table": "Tabella delle tensioni della GPU",
|
||||
"GPU Custom Table (mV)": "Tabella personalizzata GPU (mV)",
|
||||
"GPU Voltage Table": "Tabella delle Tensioni della GPU",
|
||||
"GPU Custom Table (mV)": "Tabella GPU Personalizzata (mV)",
|
||||
"1075MHz without UV, 1152MHz on SLT": "1075 MHz senza UV, 1152 MHz su SLT",
|
||||
"or 1228MHz on HiOPT can cause ": "o 1228 MHz su HiOPT possono causare",
|
||||
"permanent damage to your Switch!": "danni permanenti al tuo Switch!",
|
||||
"921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz attivi",
|
||||
"permanent damage to your Switch!": "danni permanenti alla tua Switch!",
|
||||
"921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz su",
|
||||
"SLT or HiOPT can cause ": "SLT o HiOPT possono causare"
|
||||
}
|
||||
|
||||
BIN
dist/switch/.overlays/horizon-oc-overlay.ovl
vendored
BIN
dist/switch/.overlays/horizon-oc-overlay.ovl
vendored
Binary file not shown.
Reference in New Issue
Block a user