stuff
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,100 +12,88 @@
|
|||||||
*
|
*
|
||||||
* 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 {
|
||||||
|
#define MAX(A, B) std::max(A, B)
|
||||||
|
#define MIN(A, B) std::min(A, B)
|
||||||
|
#define CEIL(A) std::ceil(A)
|
||||||
|
#define FLOOR(A) std::floor(A)
|
||||||
|
namespace pcv::erista {
|
||||||
|
// tCK_avg (average clock period) in ns
|
||||||
|
const double tCK_avg = 1000'000. / C.eristaEmcMaxClock;
|
||||||
|
|
||||||
namespace ams::ldr::oc {
|
// minimum number of cycles from any read command to any write command, irrespective of bank
|
||||||
#define MAX(A, B) std::max(A, B)
|
const u32 R2W = CEIL (C.RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - C.WL + C.tWPRE + FLOOR(C.tRPST)) + 6;
|
||||||
#define MIN(A, B) std::min(A, B)
|
|
||||||
#define CEIL(A) std::ceil(A)
|
|
||||||
#define FLOOR(A) std::floor(A)
|
|
||||||
|
|
||||||
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
|
// Delay Time From WRITE-to-READ
|
||||||
//const u32 QUSE = RL + CEIL(C.tDQSCK_min/tCK_avg + C.tDQSQ);
|
const u32 W2R = C.WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg) - 6;
|
||||||
|
|
||||||
namespace pcv::erista {
|
// write-to-precharge time for commands to the same bank in cycles
|
||||||
// tCK_avg (average clock period) in ns
|
const u32 WTP = C.WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg) - 8;
|
||||||
const double tCK_avg = 1000'000. / C.eristaEmcMaxClock;
|
|
||||||
|
|
||||||
// Write Latency
|
// #_of_rows per die for 8Gb density
|
||||||
const u32 WL = 14 + C.latency;
|
const u32 numOfRows = 65536;
|
||||||
// Read Latency
|
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
|
||||||
const u32 RL = 32 + C.latency;
|
// emc_clk_period = dram_clk / 2;
|
||||||
|
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
|
||||||
|
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
|
||||||
|
const u32 REFBW = MIN((u32)65536, REFRESH+64);
|
||||||
|
|
||||||
// minimum number of cycles from any read command to any write command, irrespective of bank
|
// Write With Auto Precharge to to Power-Down Entry
|
||||||
const u32 R2W = CEIL (RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - WL + C.tWPRE + FLOOR(C.tRPST)) + 6;
|
const u32 WTPDEN = WTP + 1 + CEIL(C.tDQSS_max/tCK_avg) + CEIL(C.tDQS2DQ_max/tCK_avg) + 6;
|
||||||
|
|
||||||
// Delay Time From WRITE-to-READ
|
// Additional time after t XP hasexpired until the MRR commandmay be issued
|
||||||
const u32 W2R = WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg) - 6;
|
const double tMRRI = C.tRCD + 3 * tCK_avg;
|
||||||
|
|
||||||
// write-to-precharge time for commands to the same bank in cycles
|
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
|
||||||
const u32 WTP = WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg) - 8;
|
const double tPDEX2MRR = C.tXP + tMRRI;
|
||||||
|
}
|
||||||
|
namespace pcv::mariko {
|
||||||
|
// tCK_avg (average clock period) in ns
|
||||||
|
const double tCK_avg = 1000'000. / C.marikoEmcMaxClock;
|
||||||
|
// minimum number of cycles from any read command to any write command, irrespective of bank
|
||||||
|
const u32 R2W = CEIL (C.RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - C.WL + C.tWPRE + FLOOR(C.tRPST));
|
||||||
|
|
||||||
// #_of_rows per die for 8Gb density
|
// Delay Time From WRITE-to-READ
|
||||||
const u32 numOfRows = 65536;
|
const u32 W2R = C.WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg);
|
||||||
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
|
|
||||||
// emc_clk_period = dram_clk / 2;
|
|
||||||
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
|
|
||||||
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
|
|
||||||
const u32 REFBW = MIN((u32)65536, REFRESH+64);
|
|
||||||
|
|
||||||
// Write With Auto Precharge to to Power-Down Entry
|
// write-to-precharge time for commands to the same bank in cycles
|
||||||
const u32 WTPDEN = WTP + 1 + CEIL(C.tDQSS_max/tCK_avg) + CEIL(C.tDQS2DQ_max/tCK_avg) + 6;
|
const u32 WTP = C.WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg);
|
||||||
|
|
||||||
// Additional time after t XP hasexpired until the MRR commandmay be issued
|
// Read-To-MRW delay
|
||||||
const double tMRRI = C.tRCD + 3 * tCK_avg;
|
const u32 RTM = C.RL + C.BL/2 + CEIL(C.tDQSCK_max/tCK_avg) + FLOOR(C.tRPST) + CEIL(7.5/tCK_avg);
|
||||||
|
|
||||||
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
|
// Write-To-MRW/MRR delay
|
||||||
const double tPDEX2MRR = C.tXP + tMRRI;
|
const u32 WTM = C.WL + 1 + C.BL/2 + CEIL(7.5/tCK_avg);
|
||||||
}
|
|
||||||
namespace pcv::mariko {
|
|
||||||
// tCK_avg (average clock period) in ns
|
|
||||||
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
|
// Read With AP-To-MRW/MRR delay
|
||||||
const u32 R2W = CEIL (RL + CEIL(C.tDQSCK_max/tCK_avg) + C.BL/2 - WL + C.tWPRE + FLOOR(C.tRPST));
|
const u32 RATM = RTM + CEIL(C.tRTP/tCK_avg) - 8;
|
||||||
|
|
||||||
// Delay Time From WRITE-to-READ
|
// Write With AP-To-MRW/MRR delay
|
||||||
const u32 W2R = WL + C.BL/2 + 1 + CEIL(C.tWTR/tCK_avg);
|
const u32 WATM = WTM + CEIL(C.tWR/tCK_avg);
|
||||||
|
|
||||||
// write-to-precharge time for commands to the same bank in cycles
|
// #_of_rows per die for 8Gb density
|
||||||
const u32 WTP = WL + C.BL/2 + 1 + CEIL(C.tWR/tCK_avg);
|
const u32 numOfRows = 65536;
|
||||||
|
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
|
||||||
|
// emc_clk_period = dram_clk / 2;
|
||||||
|
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
|
||||||
|
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
|
||||||
|
const u32 REFBW = MIN((u32)65536, REFRESH+64);
|
||||||
|
|
||||||
// Read-To-MRW delay
|
// Write With Auto Precharge to to Power-Down Entry
|
||||||
const u32 RTM = RL + C.BL/2 + CEIL(C.tDQSCK_max/tCK_avg) + FLOOR(C.tRPST) + CEIL(7.5/tCK_avg);
|
const u32 WTPDEN = WTP + 1 + CEIL(C.tDQSS_max/tCK_avg) + CEIL(C.tDQS2DQ_max/tCK_avg) + 6;
|
||||||
|
|
||||||
// Write-To-MRW/MRR delay
|
// Additional time after t XP hasexpired until the MRR commandmay be issued
|
||||||
const u32 WTM = WL + 1 + C.BL/2 + CEIL(7.5/tCK_avg);
|
const double tMRRI = C.tRCD + 3 * tCK_avg;
|
||||||
|
|
||||||
// Read With AP-To-MRW/MRR delay
|
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
|
||||||
const u32 RATM = RTM + CEIL(C.tRTP/ 1000/tCK_avg) - 8;
|
const double tPDEX2MRR = C.tXP + tMRRI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write With AP-To-MRW/MRR delay
|
|
||||||
const u32 WATM = WTM + CEIL(C.tWR/tCK_avg);
|
|
||||||
|
|
||||||
// #_of_rows per die for 8Gb density
|
|
||||||
const u32 numOfRows = 65536;
|
|
||||||
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
|
|
||||||
// emc_clk_period = dram_clk / 2;
|
|
||||||
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
|
|
||||||
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
|
|
||||||
const u32 REFBW = MIN((u32)65536, REFRESH+64);
|
|
||||||
|
|
||||||
// Write With Auto Precharge to to Power-Down Entry
|
|
||||||
const u32 WTPDEN = WTP + 1 + CEIL(C.tDQSS_max/tCK_avg) + CEIL(C.tDQS2DQ_max/tCK_avg) + 6;
|
|
||||||
|
|
||||||
// Additional time after t XP hasexpired until the MRR commandmay be issued
|
|
||||||
const double tMRRI = C.tRCD + 3 * tCK_avg;
|
|
||||||
|
|
||||||
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
|
|
||||||
const double tPDEX2MRR = C.tXP + tMRRI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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] = {};
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,296 +21,233 @@
|
|||||||
#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}, {}},
|
{ 306000, { 747134, -14195, 27 }, {} },
|
||||||
{306000, {747134, -14195, 27}, {}},
|
{ 408000, { 776324, -15705, 27 }, {} },
|
||||||
{408000, {776324, -15705, 27}, {}},
|
{ 510000, { 809160, -17205, 27 }, {} },
|
||||||
{510000, {809160, -17205, 27}, {}},
|
{ 612000, { 845641, -18715, 27 }, {} },
|
||||||
{612000, {845641, -18715, 27}, {}},
|
{ 714000, { 885768, -20215, 27 }, {} },
|
||||||
{714000, {885768, -20215, 27}, {}},
|
{ 816000, { 929540, -21725, 27 }, {} },
|
||||||
{816000, {929540, -21725, 27}, {}},
|
{ 918000, { 976958, -23225, 27 }, {} },
|
||||||
{918000, {976958, -23225, 27}, {}},
|
{ 1020000, { 1028021, -24725, 27 }, { 1120000 } },
|
||||||
{1020000, {1028021, -24725, 27}, {1120000}},
|
{ 1122000, { 1082730, -26235, 27 }, { 1120000 } },
|
||||||
{1122000, {1082730, -26235, 27}, {1120000}},
|
{ 1224000, { 1141084, -27735, 27 }, { 1120000 } },
|
||||||
{1224000, {1141084, -27735, 27}, {1120000}},
|
{ 1326000, { 1203084, -29245, 27 }, { 1120000 } },
|
||||||
{1326000, {1203084, -29245, 27}, {1120000}},
|
{ 1428000, { 1268729, -30745, 27 }, { 1120000 } },
|
||||||
{1428000, {1268729, -30745, 27}, {1120000}},
|
{ 1581000, { 1374032, -33005, 27 }, { 1120000 } },
|
||||||
{1581000, {1374032, -33005, 27}, {1120000}},
|
{ 1683000, { 1448791, -34505, 27 }, { 1120000 } },
|
||||||
{1683000, {1448791, -34505, 27}, {1120000}},
|
{ 1785000, { 1527196, -36015, 27 }, { 1120000 } },
|
||||||
{1785000, {1527196, -36015, 27}, {1120000}},
|
{ 1887000, { 1609246, -37515, 27 }, { 1120000 } },
|
||||||
{1887000, {1609246, -37515, 27}, {1120000}},
|
{ 1963500, { 1675751, -38635, 27 }, { 1120000 } },
|
||||||
{1963500, {1675751, -38635, 27}, {1120000}},
|
{ },
|
||||||
{},
|
};
|
||||||
};
|
|
||||||
|
|
||||||
constexpr u16 CpuMinVolts[] = {800, 637, 620, 610};
|
constexpr u16 CpuMinVolts[] = { 800, 637, 620, 610 };
|
||||||
|
|
||||||
constexpr u32 CpuClkOfficial = 1963'500;
|
constexpr u32 CpuClkOfficial = 1963'500;
|
||||||
constexpr u32 CpuVoltOfficial = 1120;
|
constexpr u32 CpuVoltOfficial = 1120;
|
||||||
|
|
||||||
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, {}, {
|
{ 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } },
|
||||||
610000,
|
{ 614400, {}, { 824214, -5743, -452, 238, -6325, 81 } },
|
||||||
}},
|
{ 691200, {}, { 848830, -3903, -552, 119, -4030, -2 } },
|
||||||
{307200, {}, {
|
{ 768000, {}, { 891575, -4409, -584, 0, -2849, 39 } },
|
||||||
610000,
|
{ 844800, {}, { 940071, -5367, -602, -60, -63, -93 } },
|
||||||
}},
|
{ 921600, {}, { 986765, -6637, -614, -179, 1905, -13 } },
|
||||||
{384000, {}, {
|
{ 998400, {}, { 1098475, -13529, -497, -179, 3626, 9 } },
|
||||||
610000,
|
{ 1075200, {}, { 1163644, -12688, -648, 0, 1077, 40 } },
|
||||||
}},
|
{ 1152000, {}, { 1204812, -9908, -830, 0, 1469, 110 } },
|
||||||
{460800, {}, {
|
{ 1228800, {}, { 1277303, -11675, -859, 0, 3722, 313 } },
|
||||||
610000,
|
{ 1267200, {}, { 1335531, -12567, -867, 0, 3681, 559 } },
|
||||||
}},
|
{ },
|
||||||
{537600, {}, {801688, -10900, -163, 298, -10599, 162}},
|
};
|
||||||
{614400, {}, {824214, -5743, -452, 238, -6325, 81}},
|
|
||||||
{691200, {}, {848830, -3903, -552, 119, -4030, -2}},
|
|
||||||
{768000, {}, {891575, -4409, -584, 0, -2849, 39}},
|
|
||||||
{844800, {}, {940071, -5367, -602, -60, -63, -93}},
|
|
||||||
{921600, {}, {986765, -6637, -614, -179, 1905, -13}},
|
|
||||||
{998400, {}, {1098475, -13529, -497, -179, 3626, 9}},
|
|
||||||
{1075200, {}, {1163644, -12688, -648, 0, 1077, 40}},
|
|
||||||
{1152000, {}, {1204812, -9908, -830, 0, 1469, 110}},
|
|
||||||
{1228800, {}, {1277303, -11675, -859, 0, 3722, 313}},
|
|
||||||
{1267200, {}, {1335531, -12567, -867, 0, 3681, 559}},
|
|
||||||
{},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr u32 GpuClkPllLimit = 1300'000'000;
|
constexpr u32 GpuClkPllLimit = 1300'000'000;
|
||||||
|
|
||||||
/* GPU Max Clock asm Pattern:
|
/* GPU Max Clock asm Pattern:
|
||||||
*
|
*
|
||||||
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
|
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
|
||||||
* sf | opc | | hw | imm16 | Rd
|
* 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
|
* #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
|
* 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)
|
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
|
||||||
* sf | opc | | hw | imm16 | Rd
|
* 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
|
* #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
|
* 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)
|
|
||||||
{
|
|
||||||
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr emc_dvb_dvfs_table_t EmcDvbTableDefault[] = {
|
|
||||||
{204000, {
|
|
||||||
637,
|
|
||||||
637,
|
|
||||||
637,
|
|
||||||
}},
|
|
||||||
{408000, {
|
|
||||||
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 EmcClkPllmLimit = 2133'000'000;
|
|
||||||
constexpr u32 EmcVddqDefault = 600'000;
|
|
||||||
constexpr u32 MemVdd2Default = 1100'000;
|
|
||||||
|
|
||||||
constexpr u32 MTC_TABLE_REV = 3;
|
|
||||||
|
|
||||||
void Patch(uintptr_t mapped_nso, size_t nso_size);
|
|
||||||
|
|
||||||
|
inline bool GpuMaxClockPatternFn(u32* ptr32) {
|
||||||
|
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace erista
|
constexpr emc_dvb_dvfs_table_t EmcDvbTableDefault[] = {
|
||||||
{
|
{ 204000, { 637, 637, 637, } },
|
||||||
constexpr cvb_entry_t CpuCvbTableDefault[] = {
|
{ 408000, { 637, 637, 637, } },
|
||||||
// CPU_PLL_CVB_TABLE_ODN
|
{ 800000, { 637, 637, 637, } },
|
||||||
{204000, {721094}, {}},
|
{ 1065600, { 637, 637, 637, } },
|
||||||
{306000, {754040}, {}},
|
{ 1331200, { 650, 637, 637, } },
|
||||||
{408000, {786986}, {}},
|
{ 1600000, { 675, 650, 637, } },
|
||||||
{510000, {819932}, {}},
|
};
|
||||||
{612000, {852878}, {}},
|
|
||||||
{714000, {885824}, {}},
|
|
||||||
{816000, {918770}, {}},
|
|
||||||
{918000, {951716}, {}},
|
|
||||||
{1020000, {984662}, {-2875621, 358099, -8585}},
|
|
||||||
{1122000, {1017608}, {-52225, 104159, -2816}},
|
|
||||||
{1224000, {1050554}, {1076868, 8356, -727}},
|
|
||||||
{1326000, {1083500}, {2208191, -84659, 1240}},
|
|
||||||
{1428000, {1116446}, {2519460, -105063, 1611}},
|
|
||||||
{1581000, {1130000}, {2889664, -122173, 1834}},
|
|
||||||
{1683000, {1168000}, {5100873, -279186, 4747}},
|
|
||||||
{1785000, {1227500}, {5100873, -279186, 4747}},
|
|
||||||
{},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr u32 CpuVoltL4T = 1235'000;
|
constexpr u32 EmcClkOSAlt = 1331'200;
|
||||||
|
constexpr u32 EmcClkPllmLimit = 2133'000'000;
|
||||||
|
constexpr u32 EmcVddqDefault = 600'000;
|
||||||
|
constexpr u32 MemVdd2Default = 1100'000;
|
||||||
|
|
||||||
constexpr u16 CpuMinVolts[] = {950, 850, 825, 810};
|
constexpr u32 MTC_TABLE_REV = 3;
|
||||||
|
|
||||||
inline bool CpuMaxVoltPatternFn(u32 *ptr32)
|
void Patch(uintptr_t mapped_nso, size_t nso_size);
|
||||||
{
|
|
||||||
u32 val = *ptr32;
|
|
||||||
return (val == 1132 || val == 1170 || val == 1227);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr u32 GpuClkPllLimit = 921'600'000;
|
}
|
||||||
|
|
||||||
/* GPU Max Clock asm Pattern:
|
namespace erista {
|
||||||
*
|
constexpr cvb_entry_t CpuCvbTableDefault[] = {
|
||||||
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
|
// CPU_PLL_CVB_TABLE_ODN
|
||||||
* sf | opc | | hw | imm16 | Rd
|
{ 204000, { 721094 }, {} },
|
||||||
* #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
|
{ 306000, { 754040 }, {} },
|
||||||
* 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
|
{ 408000, { 786986 }, {} },
|
||||||
*
|
{ 510000, { 819932 }, {} },
|
||||||
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
|
{ 612000, { 852878 }, {} },
|
||||||
* sf | opc | | hw | imm16 | Rd
|
{ 714000, { 885824 }, {} },
|
||||||
* #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
|
{ 816000, { 918770 }, {} },
|
||||||
* 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
|
{ 918000, { 951716 }, {} },
|
||||||
*/
|
{ 1020000, { 984662 }, { -2875621, 358099, -8585 } },
|
||||||
inline constexpr u32 asm_pattern[] = {0x52820000, 0x72A001C0};
|
{ 1122000, { 1017608 }, { -52225, 104159, -2816 } },
|
||||||
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2)
|
{ 1224000, { 1050554 }, { 1076868, 8356, -727 } },
|
||||||
{ return ((ins1 ^ ins2) >> 5) == 0; };
|
{ 1326000, { 1083500 }, { 2208191, -84659, 1240 } },
|
||||||
inline auto asm_get_rd = [](u32 ins)
|
{ 1428000, { 1116446 }, { 2519460, -105063, 1611 } },
|
||||||
{ return ins & ((1 << 5) - 1); };
|
{ 1581000, { 1130000 }, { 2889664, -122173, 1834 } },
|
||||||
inline auto asm_set_rd = [](u32 ins, u8 rd)
|
{ 1683000, { 1168000 }, { 5100873, -279186, 4747 } },
|
||||||
{ return (ins & 0xFFFFFFE0) | (rd & 0x1F); };
|
{ 1785000, { 1227500 }, { 5100873, -279186, 4747 } },
|
||||||
inline auto asm_set_imm16 = [](u32 ins, u16 imm)
|
{ },
|
||||||
{ return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5); };
|
};
|
||||||
|
|
||||||
inline bool GpuMaxClockPatternFn(u32 *ptr32)
|
constexpr u32 CpuVoltL4T = 1235'000;
|
||||||
{
|
|
||||||
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr cvb_entry_t GpuCvbTableDefault[] = {
|
constexpr u16 CpuMinVolts[] = { 950, 850, 825, 810 };
|
||||||
// NA_FREQ_CVB_TABLE
|
|
||||||
{76800, {}, {814294, 8144, -940, 808, -21583, 226}},
|
|
||||||
{153600, {}, {856185, 8144, -940, 808, -21583, 226}},
|
|
||||||
{230400, {}, {898077, 8144, -940, 808, -21583, 226}},
|
|
||||||
{307200, {}, {939968, 8144, -940, 808, -21583, 226}},
|
|
||||||
{384000, {}, {981860, 8144, -940, 808, -21583, 226}},
|
|
||||||
{460800, {}, {1023751, 8144, -940, 808, -21583, 226}},
|
|
||||||
{537600, {}, {1065642, 8144, -940, 808, -21583, 226}},
|
|
||||||
{614400, {}, {1107534, 8144, -940, 808, -21583, 226}},
|
|
||||||
{691200, {}, {1149425, 8144, -940, 808, -21583, 226}},
|
|
||||||
{768000, {}, {1191317, 8144, -940, 808, -21583, 226}},
|
|
||||||
{844800, {}, {1233208, 8144, -940, 808, -21583, 226}},
|
|
||||||
{921600, {}, {1275100, 8144, -940, 808, -21583, 226}},
|
|
||||||
{},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr u32 MemVoltHOS = 1125'000;
|
inline bool CpuMaxVoltPatternFn(u32* ptr32) {
|
||||||
constexpr u32 EmcClkPllmLimit = 1866'000'000;
|
u32 val = *ptr32;
|
||||||
|
return (val == 1132 || val == 1170 || val == 1227);
|
||||||
constexpr u32 MTC_TABLE_REV = 7;
|
|
||||||
|
|
||||||
void Patch(uintptr_t mapped_nso, size_t nso_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool isMariko>
|
constexpr u32 GpuClkPllLimit = 921'600'000;
|
||||||
Result CpuFreqCvbTable(u32 *ptr)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
u32 cpu_max_volt = isMariko ? C.marikoCpuMaxVolt : C.eristaCpuMaxVolt;
|
/* GPU Max Clock asm Pattern:
|
||||||
u32 cpu_freq_threshold = 1020'000;
|
*
|
||||||
if (isMariko)
|
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
|
||||||
{
|
* sf | opc | | hw | imm16 | Rd
|
||||||
cpu_freq_threshold = C.marikoCpuUV ? 2193'000 : 2091'000;
|
* #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
|
||||||
else
|
*
|
||||||
{
|
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
|
||||||
cpu_freq_threshold = cpu_max_volt >= 1235 ? 1887'000 : 1428'000;
|
* 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); };
|
||||||
|
|
||||||
size_t default_entry_count = GetDvfsTableEntryCount(default_table);
|
inline bool GpuMaxClockPatternFn(u32* ptr32) {
|
||||||
size_t default_table_size = default_entry_count * sizeof(cvb_entry_t);
|
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
|
||||||
size_t customize_entry_count = GetDvfsTableEntryCount(customize_table);
|
}
|
||||||
size_t customize_table_size = customize_entry_count * sizeof(cvb_entry_t);
|
|
||||||
|
|
||||||
// Validate existing table
|
constexpr cvb_entry_t GpuCvbTableDefault[] = {
|
||||||
cvb_entry_t *table_free = reinterpret_cast<cvb_entry_t *>(ptr) + 1;
|
// NA_FREQ_CVB_TABLE
|
||||||
void *cpu_cvb_table_head = reinterpret_cast<u8 *>(table_free) - default_table_size;
|
{ 76800, { }, { 814294, 8144, -940, 808, -21583, 226 } },
|
||||||
bool validated = std::memcmp(cpu_cvb_table_head, default_table, default_table_size) == 0;
|
{ 153600, { }, { 856185, 8144, -940, 808, -21583, 226 } },
|
||||||
R_UNLESS(validated, ldr::ResultInvalidCpuDvfs());
|
{ 230400, { }, { 898077, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 307200, { }, { 939968, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 384000, { }, { 981860, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 460800, { }, { 1023751, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 537600, { }, { 1065642, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 614400, { }, { 1107534, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 691200, { }, { 1149425, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 768000, { }, { 1191317, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 844800, { }, { 1233208, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ 921600, { }, { 1275100, 8144, -940, 808, -21583, 226 } },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
std::memcpy(cpu_cvb_table_head, static_cast<void *>(customize_table), customize_table_size);
|
constexpr u32 MemVoltHOS = 1125'000;
|
||||||
|
constexpr u32 EmcClkPllmLimit = 1866'000'000;
|
||||||
|
|
||||||
// Patch CPU max volt
|
constexpr u32 MTC_TABLE_REV = 7;
|
||||||
if (cpu_max_volt)
|
|
||||||
{
|
void Patch(uintptr_t mapped_nso, size_t nso_size);
|
||||||
cvb_entry_t *entry = static_cast<cvb_entry_t *>(cpu_cvb_table_head);
|
}
|
||||||
for (size_t i = 0; i < customize_entry_count; i++)
|
|
||||||
{
|
template<bool isMariko>
|
||||||
if (entry->freq >= cpu_freq_threshold)
|
Result CpuFreqCvbTable(u32* ptr) {
|
||||||
{
|
cvb_entry_t* default_table = isMariko ? (cvb_entry_t *)(&mariko::CpuCvbTableDefault) : (cvb_entry_t *)(&erista::CpuCvbTableDefault);
|
||||||
if (isMariko)
|
cvb_entry_t* customize_table = const_cast<cvb_entry_t *>(isMariko ? (C.marikoCpuUV ? C.marikoCpuDvfsTableSLT : C.marikoCpuDvfsTable) : C.eristaCpuDvfsTable);
|
||||||
{
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c0), cpu_max_volt * 1000);
|
u32 cpu_max_volt = isMariko ? C.marikoCpuMaxVolt : C.eristaCpuMaxVolt;
|
||||||
}
|
u32 cpu_freq_threshold = 1020'000;
|
||||||
else
|
if (isMariko) {
|
||||||
{
|
cpu_freq_threshold = C.marikoCpuUV ? 2193'000 : 2091'000;
|
||||||
PATCH_OFFSET(&(entry->cvb_dfll_param.c0), cpu_max_volt * 1000);
|
} else {
|
||||||
}
|
cpu_freq_threshold = cpu_max_volt >= 1235 ? 1887'000 : 1428'000;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t default_entry_count = GetDvfsTableEntryCount(default_table);
|
||||||
|
size_t default_table_size = default_entry_count * sizeof(cvb_entry_t);
|
||||||
|
size_t customize_entry_count = GetDvfsTableEntryCount(customize_table);
|
||||||
|
size_t customize_table_size = customize_entry_count * sizeof(cvb_entry_t);
|
||||||
|
|
||||||
|
// Validate existing table
|
||||||
|
cvb_entry_t* table_free = reinterpret_cast<cvb_entry_t *>(ptr) + 1;
|
||||||
|
void* cpu_cvb_table_head = reinterpret_cast<u8 *>(table_free) - default_table_size;
|
||||||
|
bool validated = std::memcmp(cpu_cvb_table_head, default_table, default_table_size) == 0;
|
||||||
|
R_UNLESS(validated, ldr::ResultInvalidCpuDvfs());
|
||||||
|
|
||||||
|
std::memcpy(cpu_cvb_table_head, static_cast<void *>(customize_table), customize_table_size);
|
||||||
|
|
||||||
|
// Patch CPU max volt
|
||||||
|
if (cpu_max_volt) {
|
||||||
|
cvb_entry_t* entry = static_cast<cvb_entry_t *>(cpu_cvb_table_head);
|
||||||
|
for (size_t i = 0; i < customize_entry_count; i++) {
|
||||||
|
if (entry->freq >= cpu_freq_threshold) {
|
||||||
|
if (isMariko) {
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c0), cpu_max_volt * 1000);
|
||||||
|
} else {
|
||||||
|
PATCH_OFFSET(&(entry->cvb_dfll_param.c0), cpu_max_volt * 1000);
|
||||||
}
|
}
|
||||||
entry++;
|
|
||||||
}
|
}
|
||||||
|
entry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool isMariko>
|
R_SUCCEED();
|
||||||
Result GpuFreqCvbTable(u32 *ptr)
|
}
|
||||||
{
|
|
||||||
cvb_entry_t *default_table = isMariko ? (cvb_entry_t *)(&mariko::GpuCvbTableDefault) : (cvb_entry_t *)(&erista::GpuCvbTableDefault);
|
template<bool isMariko>
|
||||||
cvb_entry_t *customize_table;
|
Result GpuFreqCvbTable(u32* ptr) {
|
||||||
if (isMariko)
|
cvb_entry_t* default_table = isMariko ? (cvb_entry_t *)(&mariko::GpuCvbTableDefault) : (cvb_entry_t *)(&erista::GpuCvbTableDefault);
|
||||||
{
|
cvb_entry_t* customize_table;
|
||||||
switch (C.marikoGpuUV)
|
if (isMariko) {
|
||||||
{
|
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;
|
||||||
@@ -321,90 +260,81 @@ namespace ams::ldr::oc::pcv
|
|||||||
default:
|
default:
|
||||||
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable);
|
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable);
|
||||||
|
}
|
||||||
|
|
||||||
size_t default_entry_count = GetDvfsTableEntryCount(default_table);
|
size_t default_entry_count = GetDvfsTableEntryCount(default_table);
|
||||||
size_t default_table_size = default_entry_count * sizeof(cvb_entry_t);
|
size_t default_table_size = default_entry_count * sizeof(cvb_entry_t);
|
||||||
size_t customize_entry_count = GetDvfsTableEntryCount(customize_table);
|
size_t customize_entry_count = GetDvfsTableEntryCount(customize_table);
|
||||||
size_t customize_table_size = customize_entry_count * sizeof(cvb_entry_t);
|
size_t customize_table_size = customize_entry_count * sizeof(cvb_entry_t);
|
||||||
|
|
||||||
// Validate existing table
|
// Validate existing table
|
||||||
cvb_entry_t *table_free = reinterpret_cast<cvb_entry_t *>(ptr) + 1;
|
cvb_entry_t* table_free = reinterpret_cast<cvb_entry_t *>(ptr) + 1;
|
||||||
void *gpu_cvb_table_head = reinterpret_cast<u8 *>(table_free) - default_table_size;
|
void* gpu_cvb_table_head = reinterpret_cast<u8 *>(table_free) - default_table_size;
|
||||||
bool validated = std::memcmp(gpu_cvb_table_head, default_table, default_table_size) == 0;
|
bool validated = std::memcmp(gpu_cvb_table_head, default_table, default_table_size) == 0;
|
||||||
R_UNLESS(validated, ldr::ResultInvalidGpuDvfs());
|
R_UNLESS(validated, ldr::ResultInvalidGpuDvfs());
|
||||||
|
|
||||||
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)
|
patched_voltage = C.gpuVmin;
|
||||||
{
|
|
||||||
u32 patched_voltage = C.marikoGpuVoltArray[i];
|
|
||||||
if(C.gpuVmax) {
|
|
||||||
if(patched_voltage > C.gpuVmax) {
|
|
||||||
patched_voltage = C.gpuVmax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c0), patched_voltage * 1000);
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c1), 0);
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c2), 0);
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c3), 0);
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c4), 0);
|
|
||||||
PATCH_OFFSET(&(entry->cvb_pll_param.c5), 0);
|
|
||||||
}
|
|
||||||
entry++;
|
|
||||||
}
|
}
|
||||||
}
|
if(C.marikoGpuVoltArray[i] > C.gpuVmax) {
|
||||||
else if (C.commonGpuVoltOffset)
|
patched_voltage = C.gpuVmax;
|
||||||
{
|
|
||||||
cvb_entry_t *entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head);
|
|
||||||
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));
|
|
||||||
entry++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c0), patched_voltage * 1000);
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c1), 0);
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c2), 0);
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c3), 0);
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c4), 0);
|
||||||
|
PATCH_OFFSET(&(entry->cvb_pll_param.c5), 0);
|
||||||
|
entry++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
R_SUCCEED();
|
else if (C.commonGpuVoltOffset) {
|
||||||
};
|
cvb_entry_t* entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head);
|
||||||
|
for (size_t i = 0; i < customize_entry_count; i++) {
|
||||||
Result MemFreqPllmLimit(u32 *ptr);
|
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (entry->cvb_pll_param.c0 - C.commonGpuVoltOffset*1000));
|
||||||
Result MemVoltHandler(u32 *ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2
|
entry++;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Result MemMtcCustomizeTable(T *dst, T *src)
|
|
||||||
{
|
|
||||||
constexpr u32 mtc_magic = std::is_same_v<T, MarikoMtcTable> ? MARIKO_MTC_MAGIC : ERISTA_MTC_MAGIC;
|
|
||||||
R_UNLESS(src->rev == mtc_magic, ldr::ResultInvalidMtcMagic());
|
|
||||||
|
|
||||||
constexpr u32 ZERO_VAL = UINT32_MAX;
|
|
||||||
// Skip params from dvfs_ver to clock_src;
|
|
||||||
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 *dst_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(dst) + offset);
|
|
||||||
u32 src_val = *src_ent;
|
|
||||||
|
|
||||||
if (src_val)
|
|
||||||
{
|
|
||||||
PATCH_OFFSET(dst_ent, src_val == ZERO_VAL ? 0 : src_val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
};
|
};
|
||||||
|
|
||||||
void SafetyCheck();
|
Result MemFreqPllmLimit(u32* ptr);
|
||||||
void Patch(uintptr_t mapped_nso, size_t nso_size);
|
Result MemVoltHandler(u32* ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Result MemMtcCustomizeTable(T* dst, T* src) {
|
||||||
|
constexpr u32 mtc_magic = std::is_same_v<T, MarikoMtcTable> ? MARIKO_MTC_MAGIC : ERISTA_MTC_MAGIC;
|
||||||
|
R_UNLESS(src->rev == mtc_magic, ldr::ResultInvalidMtcMagic());
|
||||||
|
|
||||||
|
constexpr u32 ZERO_VAL = UINT32_MAX;
|
||||||
|
// Skip params from dvfs_ver to clock_src;
|
||||||
|
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* dst_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(dst) + offset);
|
||||||
|
u32 src_val = *src_ent;
|
||||||
|
|
||||||
|
if (src_val) {
|
||||||
|
PATCH_OFFSET(dst_ent, src_val == ZERO_VAL ? 0 : src_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
};
|
||||||
|
|
||||||
|
void SafetyCheck();
|
||||||
|
void Patch(uintptr_t mapped_nso, size_t nso_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,16 +75,12 @@ 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->tune1_low), 0x021107FF);
|
|
||||||
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
|
|
||||||
}
|
}
|
||||||
|
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
|
||||||
|
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
|
||||||
|
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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user