loader: patch gpu pll limit and hos limit for erista, add 998 gpu
This commit is contained in:
@@ -205,7 +205,7 @@ volatile CustomizeTable C = {
|
||||
{ 768000, { }, { 1191317, 8144, -940, 808, -21583, 226 } },
|
||||
{ 844800, { }, { 1233208, 8144, -940, 808, -21583, 226 } },
|
||||
{ 921600, { }, { 1275100, 8144, -940, 808, -21583, 226 } },
|
||||
// { 998400, { }, { 1316991, 8144, -940, 808, -21583, 226 } },
|
||||
{ 998400, { }, { 1316991, 8144, -940, 808, -21583, 226 } },
|
||||
},
|
||||
|
||||
/* - Mariko GPU DVFS Table:
|
||||
|
||||
@@ -147,6 +147,30 @@ namespace erista {
|
||||
return (val == 1132 || val == 1170 || val == 1227);
|
||||
}
|
||||
|
||||
constexpr u32 GpuClkPllLimit = 921'600'000;
|
||||
|
||||
/* GPU Max Clock asm Pattern:
|
||||
*
|
||||
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
|
||||
* sf | opc | | hw | imm16 | Rd
|
||||
* #31 |30 29|28 27 26 25 24 23|22 21|20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 |4 3 2 1 0
|
||||
* 0 | 1 0 | 1 0 0 1 0 1| 0 0| 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 |0 1 0 1 1
|
||||
*
|
||||
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
|
||||
* sf | opc | | hw | imm16 | Rd
|
||||
* #31 |30 29|28 27 26 25 24 23|22 21|20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 |4 3 2 1 0
|
||||
* 0 | 1 1 | 1 0 0 1 0 1| 0 1| 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 |0 1 0 1 1
|
||||
*/
|
||||
inline constexpr u32 asm_pattern[] = { 0x52820000, 0x72A001C0 };
|
||||
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) { return ((ins1 ^ ins2) >> 5) == 0; };
|
||||
inline auto asm_get_rd = [](u32 ins) { return ins & ((1 << 5) - 1); };
|
||||
inline auto asm_set_rd = [](u32 ins, u8 rd) { return (ins & 0xFFFFFFE0) | (rd & 0x1F); };
|
||||
inline auto asm_set_imm16 = [](u32 ins, u16 imm) { return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5); };
|
||||
|
||||
inline bool GpuMaxClockPatternFn(u32* ptr32) {
|
||||
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
|
||||
}
|
||||
|
||||
constexpr cvb_entry_t GpuCvbTableDefault[] = {
|
||||
// NA_FREQ_CVB_TABLE
|
||||
{ 76800, { }, { 814294, 8144, -940, 808, -21583, 226 } },
|
||||
|
||||
@@ -34,6 +34,43 @@ Result CpuVoltRange(u32* ptr) {
|
||||
R_THROW(ldr::ResultInvalidCpuMinVolt());
|
||||
}
|
||||
|
||||
Result GpuFreqMaxAsm(u32* ptr32) {
|
||||
// Check if both two instructions match the pattern
|
||||
u32 ins1 = *ptr32, ins2 = *(ptr32 + 1);
|
||||
if (!(asm_compare_no_rd(ins1, asm_pattern[0]) && asm_compare_no_rd(ins2, asm_pattern[1])))
|
||||
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
|
||||
|
||||
// Both instructions should operate on the same register
|
||||
u8 rd = asm_get_rd(ins1);
|
||||
if (rd != asm_get_rd(ins2))
|
||||
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
|
||||
|
||||
u32 max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq;
|
||||
|
||||
u32 asm_patch[2] = {
|
||||
asm_set_rd(asm_set_imm16(asm_pattern[0], max_clock), rd),
|
||||
asm_set_rd(asm_set_imm16(asm_pattern[1], max_clock >> 16), rd)
|
||||
};
|
||||
PATCH_OFFSET(ptr32, asm_patch[0]);
|
||||
PATCH_OFFSET(ptr32 + 1, asm_patch[1]);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GpuFreqPllLimit(u32* ptr) {
|
||||
clk_pll_param* entry = reinterpret_cast<clk_pll_param *>(ptr);
|
||||
|
||||
// All zero except for freq
|
||||
for (size_t i = 1; i < sizeof(clk_pll_param) / sizeof(u32); i++) {
|
||||
R_UNLESS(*(ptr + i) == 0, ldr::ResultInvalidGpuPllEntry());
|
||||
}
|
||||
|
||||
// Double the max clk simply
|
||||
u32 max_clk = entry->freq * 2;
|
||||
entry->freq = max_clk;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void MemMtcTableAutoAdjust(EristaMtcTable* table) {
|
||||
if (C.mtcConf != AUTO_ADJ_ALL)
|
||||
return;
|
||||
@@ -219,6 +256,8 @@ void Patch(uintptr_t mapped_nso, size_t nso_size) {
|
||||
{ "CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, CpuCvbDefaultMaxFreq },
|
||||
{ "CPU Volt Limit", &CpuVoltRange, 0, &CpuMaxVoltPatternFn },
|
||||
{ "GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, GpuCvbDefaultMaxFreq },
|
||||
{ "GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn },
|
||||
{ "GPU Freq PLL", &GpuFreqPllLimit, 1, nullptr, GpuClkPllLimit },
|
||||
{ "MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit },
|
||||
{ "MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
|
||||
{ "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
|
||||
|
||||
Reference in New Issue
Block a user