GPU Max frequency is now 1497.6MHz; RAM clocks could be set in sys-clk-OC (1331 and Max); DRAM manu as suffixes in loader.kip file names for references; README

This commit is contained in:
KazushiM
2021-12-03 23:46:43 +08:00
parent 6826fafe16
commit c66c836ae3
26 changed files with 113 additions and 93 deletions

View File

@@ -100,7 +100,7 @@ namespace pcv {
0xF1E94,
0xF1EE4,
};
constexpr u32 NewGpuVoltageLimit = 1050; // default max 1050mV
constexpr u32 NewGpuVoltageLimit = 1170; // default max 1050mV
constexpr u32 GpuTablesFreeSpace[] = {
0xE3410,
@@ -122,11 +122,11 @@ namespace pcv {
// { 1228800, {}, { 1277303, -11675, -859, 0, 3722, 313 } },
// { 1267200, {}, { 1335531, -12567, -867, 0, 3681, 559 } },
{ 1305600, {}, { 955000 } },
{ 1344000, {}, { 995000 } },
// { 1382400, {}, { 1040000 } },
// { 1420800, {}, { 1090000 } },
// { 1459200, {}, { 1145000 } },
// { 1497600, {}, { 1200000 } },
{ 1344000, {}, { 990000 } },
{ 1382400, {}, { 1030000 } },
{ 1420800, {}, { 1075000 } },
{ 1459200, {}, { 1120000 } },
{ 1497600, {}, { 1170000 } },
// { 1536000, {}, { 1250000 } },
};
static_assert(sizeof(NewGpuTables) <= sizeof(gpu_cvb_pll_table_t)*15);

View File

@@ -197,11 +197,11 @@ namespace ams::ldr {
ADJUST_PROPORTIONAL(TARGET_TABLE, REF_TABLE, shadow_regs_ca_train.PARAM) \
ADJUST_PROPORTIONAL(TARGET_TABLE, REF_TABLE, shadow_regs_rdwr_train.PARAM)
/* Calculate DIVM and DIVN */
/* Calculate DIVM and DIVN (clock DIVisors) */
/* Assume oscillator (PLLMB_IN) is 38.4 MHz */
/* PLLMB_OUT = PLLMB_IN / DIVM * DIVN */
u32 divn = GetEmcClock() / 38400;
u32 divm = 1;
u32 divn = GetEmcClock() / 38400;
if (GetEmcClock() - divn * 38400 >= 38400 / 2) {
divm = 2;
divn = divn * 2 + 1;
@@ -212,7 +212,7 @@ namespace ams::ldr {
pcv::MarikoMtcTable* mtc_table_1600 = reinterpret_cast<pcv::MarikoMtcTable *>(mapped_nso + pcv::MtcTable_1600[j]);
pcv::MarikoMtcTable* mtc_table_1331 = reinterpret_cast<pcv::MarikoMtcTable *>(mapped_nso + pcv::MtcTable_1600[j] - pcv::MtcTableOffset);
/* Normal and reasonable values */
/* Patch parameters that seem like timings */
ADJUST_PROP_WITHIN_ALL_REG(mtc_table_1600, mtc_table_1331, emc_rc);
ADJUST_PROP_WITHIN_ALL_REG(mtc_table_1600, mtc_table_1331, emc_rfc);
ADJUST_PROP_WITHIN_ALL_REG(mtc_table_1600, mtc_table_1331, emc_rfcpb);
@@ -280,6 +280,7 @@ namespace ams::ldr {
ADJUST_PROPORTIONAL(mtc_table_1600, mtc_table_1331, min_mrs_wait);
ADJUST_PROPORTIONAL(mtc_table_1600, mtc_table_1331, latency);
/* Patch clock divisors */
mtc_table_1600->pllmb_divm = divm;
mtc_table_1600->pllmb_divn = divn;
}
@@ -288,16 +289,16 @@ namespace ams::ldr {
}
}
EmcClock = GetEmcClock() * 1000;
// u32 PtmEmcClock = GetEmcClock() * 1000;
u32 CpuBoostClock = GetCpuBoostClock() * 1000;
for (u32 i = 0; i < sizeof(PtmModuleId)/sizeof(ro::ModuleId); i++) {
if (std::memcmp(std::addressof(PtmModuleId[i]), std::addressof(module_id), sizeof(module_id)) == 0) {
for (u32 j = 0; j < 16; j++) {
std::memcpy(reinterpret_cast<void *>(mapped_nso + ptm::EmcOffsetStart[i] + ptm::OffsetInterval * j), &EmcClock, sizeof(EmcClock));
std::memcpy(reinterpret_cast<void *>(mapped_nso + ptm::EmcOffsetStart[i] + ptm::OffsetInterval * j + 0x4), &EmcClock, sizeof(EmcClock));
}
// for (u32 j = 0; j < 16; j++) {
// std::memcpy(reinterpret_cast<void *>(mapped_nso + ptm::EmcOffsetStart[i] + ptm::OffsetInterval * j), &PtmEmcClock, sizeof(PtmEmcClock));
// std::memcpy(reinterpret_cast<void *>(mapped_nso + ptm::EmcOffsetStart[i] + ptm::OffsetInterval * j + 0x4), &PtmEmcClock, sizeof(PtmEmcClock));
// }
for (u32 j = 0; j < 2; j++) {
std::memcpy(reinterpret_cast<void *>(mapped_nso + ptm::EmcOffsetStart[i] + ptm::CpuBoostOffset + ptm::OffsetInterval * j), &CpuBoostClock, sizeof(CpuBoostClock));
std::memcpy(reinterpret_cast<void *>(mapped_nso + ptm::EmcOffsetStart[i] + ptm::CpuBoostOffset + ptm::OffsetInterval * j + 0x4), &CpuBoostClock, sizeof(CpuBoostClock));

1
Source/sys-clk-OC/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
dist

View File

@@ -2,10 +2,6 @@
Switch sysmodule allowing you to set cpu/gpu clocks according to the running application and docked state.
### Notes:
- **No GPU capping on Mariko** (Hoag/Iowa/Aula)
- Ability to **set RAM clocks is removed**, please use sys-clk-OC with **[ptm patch](https://github.com/KazushiMe/Switch-OC-Suite/blob/master/Source/Patch/13-ptm.pchtxt)** or prebuilt loader.kip
## Clock table (MHz)
@@ -33,6 +29,10 @@ Switch sysmodule allowing you to set cpu/gpu clocks according to the running app
### GPU clocks
* 1??? → unknown max for Mariko
* 1497
* 1459
* 1420
* 1382
* 1344
* 1305
* 1267 → official max for Mariko
@@ -53,17 +53,19 @@ Switch sysmodule allowing you to set cpu/gpu clocks according to the running app
* 153
* 76 → boost mode
### MEM clocks (only for reference)
### MEM clocks
**Only 1331 and Max could be set in sys-clk-OC.**
From Hekate Minerva module [sys_sdrammtc.c](https://github.com/CTCaer/hekate/blob/197ed8c319bd4132e4d7571ce037d4a27f806bba/modules/hekate_libsys_minerva/sys_sdrammtc.c#L67)
- 2131 → max for Erista & Mariko (with overvolting)
- 2131 → max for Erista (requires I/O bus overvolting); official max for Mariko (requires proper timings)
- 2099
- 2064
- 1996
- 1932
- 1894
- 1862 → stable max for Mariko (stable on most DRAM chips except Hynix ones) (without overvolting capped at 600 mV)
- 1862 → official max for Erista; Mariko (stable on most DRAM chips except Hynix ones) (with timings for 1600MHz and no overvolting capped at 600 mV)
- 1795
- 1728
- 1600 → official docked & official boost mode
@@ -72,6 +74,17 @@ From Hekate Minerva module [sys_sdrammtc.c](https://github.com/CTCaer/hekate/blo
- 800
- 665
## Capping
To protect the battery from excessive strain, clocks requested from config may be capped before applying, depending on your current profile:
| | Handheld | Charging (USB) | Charging (Official) | Docked |
|:-------:|:--------:|:--------------:|:-------------------:|:------:|
| **MEM** | - | - | - | - |
| **CPU** | - | - | - | - |
| **GPU** | 1344 | 1344 | - | - |
## Installation
The following instructions assumes you have a Nintendo Switch running Atmosphère, updated to at least the latest stable version.
@@ -118,14 +131,19 @@ Presets can be customized by adding them to the ini config file located at `/con
[Application Title ID]
docked_cpu=
docked_gpu=
docked_mem=
handheld_charging_cpu=
handheld_charging_gpu=
handheld_charging_mem=
handheld_charging_usb_cpu=
handheld_charging_usb_gpu=
handheld_charging_usb_mem=
handheld_charging_official_cpu=
handheld_charging_official_gpu=
handheld_charging_official_mem=
handheld_cpu=
handheld_gpu=
handheld_mem=
```
* Replace `Application Title ID` with the title id of the game/application you're interested in customizing.
@@ -147,6 +165,7 @@ Leads to a smoother framerate overall (ex: in the korok forest)
[01007EF00011E000]
docked_cpu=1224
handheld_charging_cpu=1224
handheld_mem=1600
```
### Example 2: Picross

View File

@@ -12,20 +12,20 @@
uint32_t sysclk_g_freq_table_mem_hz[] = {
// From Hekate Minerva module
665600000,
800000000,
1065600000,
// 665600000,
// 800000000,
// 1065600000,
1331200000,
1600000000,
1728000000,
1795200000,
1862400000,
1894400000,
1932800000,
1996800000,
2064000000,
2099200000,
2131200000,
// 1728000000,
// 1795200000,
// 1862400000,
// 1894400000,
// 1932800000,
// 1996800000,
// 2064000000,
// 2099200000,
// 2131200000,
0,
};
@@ -71,7 +71,10 @@ uint32_t sysclk_g_freq_table_gpu_hz[] = {
1267200000,
1305600000,
1344000000,
//1382400000,
//1420800000,
1382400000,
1420800000,
1459200000,
1497600000,
// 1536000000,
0,
};

View File

@@ -77,7 +77,7 @@ AdvancedSettingsTab::AdvancedSettingsTab()
});
// MEM
/*brls::SelectListItem *memFreqListItem = createFreqListItem(SysClkModule_MEM, context.overrideFreqs[SysClkModule_MEM] / 1000000);
brls::SelectListItem *memFreqListItem = createFreqListItem(SysClkModule_MEM, context.overrideFreqs[SysClkModule_MEM] / 1000000);
memFreqListItem->getValueSelectedEvent()->subscribe([](int result)
{
Result rc = result == 0 ?
@@ -90,7 +90,7 @@ AdvancedSettingsTab::AdvancedSettingsTab()
errorResult(result == 0 ? "sysclkIpcRemoveOverride" : "sysclkIpcSetOverride", rc);
// TODO: Reset selected value
}
});*/
});
this->addView(cpuFreqListItem);
this->addView(gpuFreqListItem);

View File

@@ -116,7 +116,7 @@ void AppProfileFrame::addFreqs(brls::List* list, SysClkProfile profile)
list->addView(gpuListItem);
// MEM
/*brls::SelectListItem* memListItem = createFreqListItem(SysClkModule_MEM, this->profiles.mhzMap[profile][SysClkModule_MEM]);
brls::SelectListItem* memListItem = createFreqListItem(SysClkModule_MEM, this->profiles.mhzMap[profile][SysClkModule_MEM]);
this->profiles.mhzMap[profile][SysClkModule_MEM] *= 1000000;
@@ -126,7 +126,7 @@ void AppProfileFrame::addFreqs(brls::List* list, SysClkProfile profile)
brls::Logger::debug("Caching freq for module %d and profile %d to %" PRIu32, SysClkModule_MEM, profile, this->profiles.mhzMap[profile][SysClkModule_MEM]);
});
list->addView(memListItem);*/
list->addView(memListItem);
}
void AppProfileFrame::onProfileChanged()

View File

@@ -30,7 +30,7 @@ CheatSheetTab::CheatSheetTab()
this->addView(new brls::Header("CPU Clocks"));
brls::Table *cpuTable = new brls::Table();
cpuTable->addRow(brls::TableRowType::BODY, "OC Suite Maximum", "2397.0 MHz");
cpuTable->addRow(brls::TableRowType::BODY, "Tegra X1+ Official Max", "1963.5 MHz");
cpuTable->addRow(brls::TableRowType::BODY, "Official Boost", "1785.0 MHz");
cpuTable->addRow(brls::TableRowType::BODY, "Official Docked and Handheld", "1020.0 MHz");
@@ -40,7 +40,7 @@ CheatSheetTab::CheatSheetTab()
this->addView(new brls::Header("GPU Clocks"));
brls::Table *gpuTable = new brls::Table();
gpuTable->addRow(brls::TableRowType::BODY, "OC Suite Maximum", "1344.0 MHz");
gpuTable->addRow(brls::TableRowType::BODY, "Tegra X1+ Official Max", "1267.2 MHz");
gpuTable->addRow(brls::TableRowType::BODY, "Official Maximum", "921.6 MHz");
gpuTable->addRow(brls::TableRowType::BODY, "Official Docked", "768.0 MHz");
gpuTable->addRow(brls::TableRowType::BODY, "Official Handheld", "384.0/460.8 MHz");
@@ -63,7 +63,7 @@ CheatSheetTab::CheatSheetTab()
return;
}
memTable->addRow(brls::TableRowType::BODY, "OC Suite", formatFreq(context.freqs[SysClkModule_MEM]));
memTable->addRow(brls::TableRowType::BODY, "Tegra X1+ Official Max", "2131.2 MHz");
memTable->addRow(brls::TableRowType::BODY, "Official", "1331.2/1600.0 MHz");
this->addView(memTable);

View File

@@ -110,7 +110,10 @@ brls::SelectListItem* createFreqListItem(SysClkModule module, uint32_t selectedF
selected = i + 1;
char clock[16];
snprintf(clock, sizeof(clock), "%d MHz", freq / 1000000);
if (freq == 1600000000)
snprintf(clock, sizeof(clock), "Max MHz");
else
snprintf(clock, sizeof(clock), "%d MHz", freq / 1000000);
clocks.push_back(std::string(clock));

View File

@@ -20,9 +20,13 @@ static inline std::string formatListFreqMhz(std::uint32_t mhz)
{
return FREQ_DEFAULT_TEXT;
}
else if (mhz == 1600)
{
return "Max MHz";
}
char buf[10];
return std::string(buf, snprintf(buf, sizeof(buf), "%u Mhz", 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); }

View File

@@ -62,7 +62,7 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true)));
this->addModuleListItem(profile, SysClkModule_CPU, &sysclk_g_freq_table_cpu_hz[0]);
this->addModuleListItem(profile, SysClkModule_GPU, &sysclk_g_freq_table_gpu_hz[0]);
//this->addModuleListItem(profile, SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
this->addModuleListItem(profile, SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
}
void AppProfileGui::listUI()

View File

@@ -62,7 +62,7 @@ void GlobalOverrideGui::listUI()
{
this->addModuleListItem(SysClkModule_CPU, &sysclk_g_freq_table_cpu_hz[0]);
this->addModuleListItem(SysClkModule_GPU, &sysclk_g_freq_table_gpu_hz[0]);
//this->addModuleListItem(SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
this->addModuleListItem(SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
}
void GlobalOverrideGui::refresh()

View File

@@ -247,15 +247,23 @@ void ClockManager::Tick()
if (hz)
{
hz = Clocks::GetNearestHz((SysClkModule)module, isEnabledReverseNX ? RealProfile : this->context->profile, hz);
if (module == SysClkModule_MEM && hz == 1600'000'000 && this->context->freqs[module] >= hz)
{
continue;
}
if (hz != this->context->freqs[module] && this->context->enabled)
{
if (cpuBoost)
{
// Skip setting CPU or GPU clocks in CpuBoostMode if CPU < 1963.5MHz or GPU > 76.8MHz
if (module == SysClkModule_CPU && hz < MAX_CPU)
{
hz = MAX_CPU;
FileUtils::LogLine("[mgr] CpuBoostMode detected, bump CPU to max");
continue;
}
if (module == SysClkModule_GPU && hz > 76'800'000)
{
continue;
}
}
FileUtils::LogLine("[mgr] %s clock set : %u.%u Mhz", Clocks::GetModuleName((SysClkModule)module, true), hz/1000000, hz/100000 - hz/1000000*10);
@@ -265,19 +273,6 @@ void ClockManager::Tick()
}
}
}
else if (FileUtils::IsBoostEnabled())
{
// If user doesn't set any freq but with sys-clk enabled, then boost CPU in CpuBoostMode
if(cpuBoost && this->GetConfig()->Enabled())
{
if(this->context->freqs[SysClkModule_CPU] != MAX_CPU)
{
FileUtils::LogLine("[mgr] CpuBoostMode detected, bump CPU to max");
Clocks::SetHz(SysClkModule_CPU, MAX_CPU);
this->context->freqs[SysClkModule_CPU] = MAX_CPU;
}
}
}
}
}
@@ -450,13 +445,6 @@ bool ClockManager::RefreshContext()
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
{
hz = Clocks::GetCurrentHz((SysClkModule)module);
// Skip MEM freq check
if (module == SysClkModule_MEM)
{
this->context->freqs[module] = hz;
break;
}
// Round to MHz
uint32_t cur_mhz = hz/1000'000;

View File

@@ -179,8 +179,10 @@ void Clocks::ResetToStock(unsigned int module)
{
Clocks::SetHz(SysClkModule_GPU, apmConfiguration->gpu_hz);
}
// We don't need to set MEM freqs any more
//Clocks::SetHz(SysClkModule_MEM, apmConfiguration->mem_hz);
if (module == SysClkModule_EnumMax || module == SysClkModule_MEM)
{
Clocks::SetHz(SysClkModule_MEM, apmConfiguration->mem_hz);
}
}
else
{
@@ -223,10 +225,6 @@ SysClkProfile Clocks::GetCurrentProfile()
void Clocks::SetHz(SysClkModule module, std::uint32_t hz)
{
// We don't need to set MEM freqs any more
if (module == SysClkModule_MEM)
return;
Result rc = 0;
if(hosversionAtLeast(8,0,0))
@@ -292,11 +290,11 @@ std::uint32_t Clocks::GetMaxAllowedHz(SysClkModule module, SysClkProfile profile
{
if(profile < SysClkProfile_HandheldCharging)
{
return isMariko ? 1536000000 : SYSCLK_GPU_HANDHELD_MAX_HZ;
return isMariko ? 1344000000 : SYSCLK_GPU_HANDHELD_MAX_HZ;
}
else if(profile <= SysClkProfile_HandheldChargingUSB)
{
return isMariko ? 1536000000 : SYSCLK_GPU_UNOFFICIAL_CHARGER_MAX_HZ;
return isMariko ? 1344000000 : SYSCLK_GPU_UNOFFICIAL_CHARGER_MAX_HZ;
}
}
@@ -305,7 +303,7 @@ std::uint32_t Clocks::GetMaxAllowedHz(SysClkModule module, SysClkProfile profile
std::uint32_t Clocks::GetNearestHz(SysClkModule module, std::uint32_t inHz)
{
// Hardcoded values to return, I don't know why it will bump to max when excessive OC
// Hardcoded values to return, or the frequency will ramp up to max as dvfs table is not correct
if(module == SysClkModule_MEM)
{
switch(inHz)
@@ -381,6 +379,10 @@ std::uint32_t Clocks::GetNearestHz(SysClkModule module, std::uint32_t inHz)
return 1382400000;
case 1420000000:
return 1420800000;
case 1459000000:
return 1459200000;
case 1497000000:
return 1497600000;
default:
return inHz;
}