This commit is contained in:
souldbminersmwc
2025-09-13 17:21:41 -04:00
parent f13cf8edcf
commit a1bfcebba8
13 changed files with 378 additions and 539 deletions

View File

@@ -43,6 +43,8 @@ volatile CustomizeTable C = {
.marikoEmcDvbShift = 0, .marikoEmcDvbShift = 0,
.latency = 0, .latency = 0,
.BL = 16, .BL = 16,
.WL = 32,
.RL = 14,
.tRFCpb = 140, .tRFCpb = 140,
.tRFCab = 280, .tRFCab = 280,
.tRAS = 42, .tRAS = 42,

View File

@@ -72,6 +72,8 @@ typedef struct CustomizeTable {
// RAM timings (u32) // RAM timings (u32)
u32 latency; u32 latency;
u32 BL; u32 BL;
u32 WL;
u32 RL;
u32 tRFCpb; u32 tRFCpb;
u32 tRFCab; u32 tRFCab;
u32 tRAS; u32 tRAS;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (c) 2023 hanai3Bi
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -12,38 +12,30 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* from GCC preprocessor output
*/ */
#pragma once #pragma once
#include "oc_common.hpp" #include "oc_common.hpp"
namespace ams::ldr::oc { namespace ams::ldr::oc {
#define MAX(A, B) std::max(A, B) #define MAX(A, B) std::max(A, B)
#define MIN(A, B) std::min(A, B) #define MIN(A, B) std::min(A, B)
#define CEIL(A) std::ceil(A) #define CEIL(A) std::ceil(A)
#define FLOOR(A) std::floor(A) #define FLOOR(A) std::floor(A)
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
//const u32 QUSE = RL + CEIL(C.tDQSCK_min/tCK_avg + C.tDQSQ);
namespace pcv::erista { namespace pcv::erista {
// tCK_avg (average clock period) in ns // tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.eristaEmcMaxClock; const double tCK_avg = 1000'000. / C.eristaEmcMaxClock;
// Write Latency
const u32 WL = 14 + C.latency;
// Read Latency
const u32 RL = 32 + C.latency;
// minimum number of cycles from any read command to any write command, irrespective of bank // minimum number of cycles from any read command to any write command, irrespective of bank
const u32 R2W = CEIL (RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - WL + C.tWPRE + FLOOR(C.tRPST)) + 6; const u32 R2W = CEIL (C.RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - C.WL + C.tWPRE + FLOOR(C.tRPST)) + 6;
// Delay Time From WRITE-to-READ // Delay Time From WRITE-to-READ
const u32 W2R = WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg) - 6; const u32 W2R = C.WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg) - 6;
// write-to-precharge time for commands to the same bank in cycles // write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg) - 8; const u32 WTP = C.WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg) - 8;
// #_of_rows per die for 8Gb density // #_of_rows per die for 8Gb density
const u32 numOfRows = 65536; const u32 numOfRows = 65536;
@@ -65,28 +57,23 @@ namespace ams::ldr::oc {
namespace pcv::mariko { namespace pcv::mariko {
// tCK_avg (average clock period) in ns // tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.marikoEmcMaxClock; const double tCK_avg = 1000'000. / C.marikoEmcMaxClock;
// Write Latency
const u32 WL = 14 + C.latency;
// Read Latency
const u32 RL = 32 + C.latency;
// minimum number of cycles from any read command to any write command, irrespective of bank // minimum number of cycles from any read command to any write command, irrespective of bank
const u32 R2W = CEIL (RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - WL + C.tWPRE + FLOOR(C.tRPST)); const u32 R2W = CEIL (C.RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - C.WL + C.tWPRE + FLOOR(C.tRPST));
// Delay Time From WRITE-to-READ // Delay Time From WRITE-to-READ
const u32 W2R = WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg); const u32 W2R = C.WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg);
// write-to-precharge time for commands to the same bank in cycles // write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg); const u32 WTP = C.WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg);
// Read-To-MRW delay // Read-To-MRW delay
const u32 RTM = RL + C.BL/2 + CEIL(C.tDQSCK_max/tCK_avg) + FLOOR(C.tRPST) + CEIL(7.5/tCK_avg); const u32 RTM = C.RL + C.BL/2 + CEIL(C.tDQSCK_max/tCK_avg) + FLOOR(C.tRPST) + CEIL(7.5/tCK_avg);
// Write-To-MRW/MRR delay // Write-To-MRW/MRR delay
const u32 WTM = WL + 1 + C.BL/2 + CEIL(7.5/tCK_avg); const u32 WTM = C.WL + 1 + C.BL/2 + CEIL(7.5/tCK_avg);
// Read With AP-To-MRW/MRR delay // Read With AP-To-MRW/MRR delay
const u32 RATM = RTM + CEIL(C.tRTP/ 1000/tCK_avg) - 8; const u32 RATM = RTM + CEIL(C.tRTP/tCK_avg) - 8;
// Write With AP-To-MRW/MRR delay // Write With AP-To-MRW/MRR delay
const u32 WATM = WTM + CEIL(C.tWR/tCK_avg); const u32 WATM = WTM + CEIL(C.tWR/tCK_avg);
@@ -109,3 +96,4 @@ namespace ams::ldr::oc {
const double tPDEX2MRR = C.tXP + tMRRI; const double tPDEX2MRR = C.tXP + tMRRI;
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -77,13 +77,13 @@ Result Test_PcvDvfsTable() {
// Customized table default // Customized table default
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaCpuDvfsTable)) == 19); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaCpuDvfsTable)) == 19);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTable)) == 22); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTable)) == 21);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTableSLT)) == 25); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTableSLT)) == 22);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaGpuDvfsTable)) == 12); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaGpuDvfsTable)) == 12);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTable)) == 18); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTable)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableSLT)) == 18); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableSLT)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableHiOPT)) == 18); assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableHiOPT)) == 17);
constexpr size_t limit = ams::ldr::oc::pcv::DvfsTableEntryLimit; constexpr size_t limit = ams::ldr::oc::pcv::DvfsTableEntryLimit;
cvb_entry_t customized_table[limit] = {}; cvb_entry_t customized_table[limit] = {};

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,7 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -19,11 +21,9 @@
#include "../oc_common.hpp" #include "../oc_common.hpp"
#include "pcv_common.hpp" #include "pcv_common.hpp"
namespace ams::ldr::oc::pcv namespace ams::ldr::oc::pcv {
{
namespace mariko namespace mariko {
{
constexpr cvb_entry_t CpuCvbTableDefault[] = { constexpr cvb_entry_t CpuCvbTableDefault[] = {
// CPUB01_CVB_TABLE // CPUB01_CVB_TABLE
{ 204000, { 721589, -12695, 27 }, {} }, { 204000, { 721589, -12695, 27 }, {} },
@@ -54,24 +54,12 @@ namespace ams::ldr::oc::pcv
constexpr cvb_entry_t GpuCvbTableDefault[] = { constexpr cvb_entry_t GpuCvbTableDefault[] = {
// GPUB01_NA_CVB_TABLE // GPUB01_NA_CVB_TABLE
{76800, {}, { { 76800, {}, { 610000, } },
610000, { 153600, {}, { 610000, } },
}}, { 230400, {}, { 610000, } },
{153600, {}, { { 307200, {}, { 610000, } },
610000, { 384000, {}, { 610000, } },
}}, { 460800, {}, { 610000, } },
{230400, {}, {
610000,
}},
{307200, {}, {
610000,
}},
{384000, {}, {
610000,
}},
{460800, {}, {
610000,
}},
{ 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } }, { 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } },
{ 614400, {}, { 824214, -5743, -452, 238, -6325, 81 } }, { 614400, {}, { 824214, -5743, -452, 238, -6325, 81 } },
{ 691200, {}, { 848830, -3903, -552, 119, -4030, -2 } }, { 691200, {}, { 848830, -3903, -552, 119, -4030, -2 } },
@@ -101,51 +89,22 @@ namespace ams::ldr::oc::pcv
* 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 * 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 constexpr u32 asm_pattern[] = { 0x52820000, 0x72A001C0 };
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) { return ((ins1 ^ ins2) >> 5) == 0; };
{ return ((ins1 ^ ins2) >> 5) == 0; }; inline auto asm_get_rd = [](u32 ins) { return ins & ((1 << 5) - 1); };
inline auto asm_get_rd = [](u32 ins) inline auto asm_set_rd = [](u32 ins, u8 rd) { return (ins & 0xFFFFFFE0) | (rd & 0x1F); };
{ return ins & ((1 << 5) - 1); }; inline auto asm_set_imm16 = [](u32 ins, u16 imm) { return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5); };
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) inline bool GpuMaxClockPatternFn(u32* ptr32) {
{
return asm_compare_no_rd(*ptr32, asm_pattern[0]); return asm_compare_no_rd(*ptr32, asm_pattern[0]);
} }
constexpr emc_dvb_dvfs_table_t EmcDvbTableDefault[] = { constexpr emc_dvb_dvfs_table_t EmcDvbTableDefault[] = {
{204000, { { 204000, { 637, 637, 637, } },
637, { 408000, { 637, 637, 637, } },
637, { 800000, { 637, 637, 637, } },
637, { 1065600, { 637, 637, 637, } },
}}, { 1331200, { 650, 637, 637, } },
{408000, { { 1600000, { 675, 650, 637, } },
637,
637,
637,
}},
{800000, {
637,
637,
637,
}},
{1065600, {
637,
637,
637,
}},
{1331200, {
650,
637,
637,
}},
{1600000, {
675,
650,
637,
}},
}; };
constexpr u32 EmcClkOSAlt = 1331'200; constexpr u32 EmcClkOSAlt = 1331'200;
@@ -159,8 +118,7 @@ namespace ams::ldr::oc::pcv
} }
namespace erista namespace erista {
{
constexpr cvb_entry_t CpuCvbTableDefault[] = { constexpr cvb_entry_t CpuCvbTableDefault[] = {
// CPU_PLL_CVB_TABLE_ODN // CPU_PLL_CVB_TABLE_ODN
{ 204000, { 721094 }, {} }, { 204000, { 721094 }, {} },
@@ -186,8 +144,7 @@ namespace ams::ldr::oc::pcv
constexpr u16 CpuMinVolts[] = { 950, 850, 825, 810 }; constexpr u16 CpuMinVolts[] = { 950, 850, 825, 810 };
inline bool CpuMaxVoltPatternFn(u32 *ptr32) inline bool CpuMaxVoltPatternFn(u32* ptr32) {
{
u32 val = *ptr32; u32 val = *ptr32;
return (val == 1132 || val == 1170 || val == 1227); return (val == 1132 || val == 1170 || val == 1227);
} }
@@ -207,17 +164,12 @@ namespace ams::ldr::oc::pcv
* 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 * 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 constexpr u32 asm_pattern[] = { 0x52820000, 0x72A001C0 };
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) { return ((ins1 ^ ins2) >> 5) == 0; };
{ return ((ins1 ^ ins2) >> 5) == 0; }; inline auto asm_get_rd = [](u32 ins) { return ins & ((1 << 5) - 1); };
inline auto asm_get_rd = [](u32 ins) inline auto asm_set_rd = [](u32 ins, u8 rd) { return (ins & 0xFFFFFFE0) | (rd & 0x1F); };
{ return ins & ((1 << 5) - 1); }; inline auto asm_set_imm16 = [](u32 ins, u16 imm) { return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5); };
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) inline bool GpuMaxClockPatternFn(u32* ptr32) {
{
return asm_compare_no_rd(*ptr32, asm_pattern[0]); return asm_compare_no_rd(*ptr32, asm_pattern[0]);
} }
@@ -247,19 +199,15 @@ namespace ams::ldr::oc::pcv
} }
template<bool isMariko> template<bool isMariko>
Result CpuFreqCvbTable(u32 *ptr) Result CpuFreqCvbTable(u32* ptr) {
{
cvb_entry_t* default_table = isMariko ? (cvb_entry_t *)(&mariko::CpuCvbTableDefault) : (cvb_entry_t *)(&erista::CpuCvbTableDefault); cvb_entry_t* default_table = isMariko ? (cvb_entry_t *)(&mariko::CpuCvbTableDefault) : (cvb_entry_t *)(&erista::CpuCvbTableDefault);
cvb_entry_t* customize_table = const_cast<cvb_entry_t *>(isMariko ? (C.marikoCpuUV ? C.marikoCpuDvfsTableSLT : C.marikoCpuDvfsTable) : C.eristaCpuDvfsTable); cvb_entry_t* customize_table = const_cast<cvb_entry_t *>(isMariko ? (C.marikoCpuUV ? C.marikoCpuDvfsTableSLT : C.marikoCpuDvfsTable) : C.eristaCpuDvfsTable);
u32 cpu_max_volt = isMariko ? C.marikoCpuMaxVolt : C.eristaCpuMaxVolt; u32 cpu_max_volt = isMariko ? C.marikoCpuMaxVolt : C.eristaCpuMaxVolt;
u32 cpu_freq_threshold = 1020'000; u32 cpu_freq_threshold = 1020'000;
if (isMariko) if (isMariko) {
{
cpu_freq_threshold = C.marikoCpuUV ? 2193'000 : 2091'000; cpu_freq_threshold = C.marikoCpuUV ? 2193'000 : 2091'000;
} } else {
else
{
cpu_freq_threshold = cpu_max_volt >= 1235 ? 1887'000 : 1428'000; cpu_freq_threshold = cpu_max_volt >= 1235 ? 1887'000 : 1428'000;
} }
@@ -277,19 +225,13 @@ namespace ams::ldr::oc::pcv
std::memcpy(cpu_cvb_table_head, static_cast<void *>(customize_table), customize_table_size); std::memcpy(cpu_cvb_table_head, static_cast<void *>(customize_table), customize_table_size);
// Patch CPU max volt // Patch CPU max volt
if (cpu_max_volt) if (cpu_max_volt) {
{
cvb_entry_t* entry = static_cast<cvb_entry_t *>(cpu_cvb_table_head); cvb_entry_t* entry = static_cast<cvb_entry_t *>(cpu_cvb_table_head);
for (size_t i = 0; i < customize_entry_count; i++) for (size_t i = 0; i < customize_entry_count; i++) {
{ if (entry->freq >= cpu_freq_threshold) {
if (entry->freq >= cpu_freq_threshold) if (isMariko) {
{
if (isMariko)
{
PATCH_OFFSET(&(entry->cvb_pll_param.c0), cpu_max_volt * 1000); PATCH_OFFSET(&(entry->cvb_pll_param.c0), cpu_max_volt * 1000);
} } else {
else
{
PATCH_OFFSET(&(entry->cvb_dfll_param.c0), cpu_max_volt * 1000); PATCH_OFFSET(&(entry->cvb_dfll_param.c0), cpu_max_volt * 1000);
} }
} }
@@ -301,14 +243,11 @@ namespace ams::ldr::oc::pcv
} }
template<bool isMariko> template<bool isMariko>
Result GpuFreqCvbTable(u32 *ptr) Result GpuFreqCvbTable(u32* ptr) {
{
cvb_entry_t* default_table = isMariko ? (cvb_entry_t *)(&mariko::GpuCvbTableDefault) : (cvb_entry_t *)(&erista::GpuCvbTableDefault); cvb_entry_t* default_table = isMariko ? (cvb_entry_t *)(&mariko::GpuCvbTableDefault) : (cvb_entry_t *)(&erista::GpuCvbTableDefault);
cvb_entry_t* customize_table; cvb_entry_t* customize_table;
if (isMariko) if (isMariko) {
{ switch (C.marikoGpuUV) {
switch (C.marikoGpuUV)
{
case 0: case 0:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable);
break; break;
@@ -322,9 +261,7 @@ namespace ams::ldr::oc::pcv
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable);
break; break;
} }
} } else {
else
{
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable);
} }
@@ -342,34 +279,30 @@ namespace ams::ldr::oc::pcv
std::memcpy(gpu_cvb_table_head, (void*)customize_table, customize_table_size); std::memcpy(gpu_cvb_table_head, (void*)customize_table, customize_table_size);
// Patch GPU volt // Patch GPU volt
if (isMariko && C.marikoGpuUV == 3) if (isMariko && C.marikoGpuUV == 3) {
{
cvb_entry_t* entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head); cvb_entry_t* entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head);
for (size_t i = 0; i < customize_entry_count; i++) for (size_t i = 0; i < customize_entry_count; i++) {
{ u32 patched_voltage = C.marikoGpuVoltArray[i];
if (C.marikoGpuVoltArray[i] < C.gpuVmin) if (C.marikoGpuVoltArray[i] < C.gpuVmin)
{ {
u32 patched_voltage = C.marikoGpuVoltArray[i]; patched_voltage = C.gpuVmin;
if(C.gpuVmax) { }
if(patched_voltage > C.gpuVmax) { if(C.marikoGpuVoltArray[i] > C.gpuVmax) {
patched_voltage = C.gpuVmax; patched_voltage = C.gpuVmax;
} }
}
PATCH_OFFSET(&(entry->cvb_pll_param.c0), patched_voltage * 1000); PATCH_OFFSET(&(entry->cvb_pll_param.c0), patched_voltage * 1000);
PATCH_OFFSET(&(entry->cvb_pll_param.c1), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c1), 0);
PATCH_OFFSET(&(entry->cvb_pll_param.c2), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c2), 0);
PATCH_OFFSET(&(entry->cvb_pll_param.c3), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c3), 0);
PATCH_OFFSET(&(entry->cvb_pll_param.c4), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c4), 0);
PATCH_OFFSET(&(entry->cvb_pll_param.c5), 0); PATCH_OFFSET(&(entry->cvb_pll_param.c5), 0);
}
entry++; entry++;
} }
} }
else if (C.commonGpuVoltOffset) else if (C.commonGpuVoltOffset) {
{
cvb_entry_t* entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head); cvb_entry_t* entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head);
for (size_t i = 0; i < customize_entry_count; i++) for (size_t i = 0; i < customize_entry_count; i++) {
{
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (entry->cvb_pll_param.c0 - C.commonGpuVoltOffset*1000)); PATCH_OFFSET(&(entry->cvb_pll_param.c0), (entry->cvb_pll_param.c0 - C.commonGpuVoltOffset*1000));
entry++; entry++;
} }
@@ -382,21 +315,18 @@ namespace ams::ldr::oc::pcv
Result MemVoltHandler(u32* ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2 Result MemVoltHandler(u32* ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2
template<typename T> template<typename T>
Result MemMtcCustomizeTable(T *dst, T *src) Result MemMtcCustomizeTable(T* dst, T* src) {
{
constexpr u32 mtc_magic = std::is_same_v<T, MarikoMtcTable> ? MARIKO_MTC_MAGIC : ERISTA_MTC_MAGIC; constexpr u32 mtc_magic = std::is_same_v<T, MarikoMtcTable> ? MARIKO_MTC_MAGIC : ERISTA_MTC_MAGIC;
R_UNLESS(src->rev == mtc_magic, ldr::ResultInvalidMtcMagic()); R_UNLESS(src->rev == mtc_magic, ldr::ResultInvalidMtcMagic());
constexpr u32 ZERO_VAL = UINT32_MAX; constexpr u32 ZERO_VAL = UINT32_MAX;
// Skip params from dvfs_ver to clock_src; // Skip params from dvfs_ver to clock_src;
for (size_t offset = offsetof(T, clk_src_emc); offset < sizeof(T); offset += sizeof(u32)) for (size_t offset = offsetof(T, clk_src_emc); offset < sizeof(T); offset += sizeof(u32)) {
{
u32* src_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(src) + offset); u32* src_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(src) + offset);
u32* dst_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(dst) + offset); u32* dst_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(dst) + offset);
u32 src_val = *src_ent; u32 src_val = *src_ent;
if (src_val) if (src_val) {
{
PATCH_OFFSET(dst_ent, src_val == ZERO_VAL ? 0 : src_val); PATCH_OFFSET(dst_ent, src_val == ZERO_VAL ? 0 : src_val);
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,7 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -16,7 +18,7 @@
#include "pcv.hpp" #include "pcv.hpp"
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
#include "../customize.hpp"
namespace ams::ldr::oc::pcv::erista { namespace ams::ldr::oc::pcv::erista {
Result CpuVoltRange(u32* ptr) { Result CpuVoltRange(u32* ptr) {
@@ -157,43 +159,6 @@ void MemMtcTableCustomAdjust(EristaMtcTable* table) {
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA); table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA);
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV - 2); table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV - 2);
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(C.tFAW));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(C.tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(C.tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(C.tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(C.tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
u32 DA_TURNS = 0; u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN

View File

@@ -1,5 +1,7 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -16,6 +18,7 @@
#include "pcv.hpp" #include "pcv.hpp"
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
#include "../customize.hpp"
namespace ams::ldr::oc::pcv::mariko { namespace ams::ldr::oc::pcv::mariko {
@@ -72,17 +75,13 @@ Result CpuVoltDfll(u32* ptr) {
if (C.marikoCpuUV) { if (C.marikoCpuUV) {
if (C.marikoCpuUV == 1) { if (C.marikoCpuUV == 1) {
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); //process_id 0 PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); //process_id 0
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF); } else if (C.marikoCpuUV == 2) {
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
}
else if (C.marikoCpuUV == 2) {
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); //process_id 1 PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); //process_id 1
}
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF); PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF); PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000); PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
} }
}
R_SUCCEED(); R_SUCCEED();
} }
@@ -109,9 +108,6 @@ Result GpuFreqMaxAsm(u32* ptr32) {
case 2: case 2:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq; max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq;
break; break;
case 3:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableUv3)->freq;
break;
default: default:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq; max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq;
break; break;
@@ -234,7 +230,7 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
BITS = BITS & ~( ((1u << HIGH) << 1u) - (1u << LOW) ); BITS = BITS & ~( ((1u << HIGH) << 1u) - (1u << LOW) );
#define ADJUST(TARGET) (u32)CEIL(TARGET * (C.marikoEmcMaxClock / EmcClkOSLimit)) #define ADJUST(TARGET) (u32)CEIL(TARGET * (C.marikoEmcMaxClock / EmcClkOSLimit))
#define ADJUST_INVERSE(TARGET) (u32)(TARGET * (EmcClkOSLimit / 1000) / (C.marikoEmcMaxClock)) #define ADJUST_INVERSE(TARGET) (u32)(TARGET * (EmcClkOSLimit / 1000) / (C.marikoEmcMaxClock / 1000))
// Burst MC Regs // Burst MC Regs
#define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE; #define WRITE_PARAM_BURST_MC_REG(TABLE, PARAM, VALUE) TABLE->burst_mc_regs.PARAM = VALUE;
@@ -350,50 +346,6 @@ void MemMtcTableCustomAdjust(MarikoMtcTable* table) {
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA; table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2;
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(C.tFAW));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(C.tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(C.tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(C.tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(C.tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(C.tXSR), (u32)0x3fe));
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_trtm, RTM);
WRITE_PARAM_ALL_REG(table, emc_twtm, WTM);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
u32 DA_TURNS = 0; u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) hanai3bi (meha) * Copyright (C) Switch-OC-Suite
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,