Add mrf for erista
This commit is contained in:
@@ -36,6 +36,8 @@ volatile CustomizeTable C = {
|
||||
|
||||
.commonEmcMemVolt = 1175000, /* LPDDR4X JEDEC Specification */
|
||||
.eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */
|
||||
.eristaEmcMaxClock1 = 1600000,
|
||||
.eristaEmcMaxClock2 = 1600000,
|
||||
|
||||
.marikoEmcMaxClock = 1866000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */
|
||||
.marikoEmcVddqVolt = 600000, /* Micron: 600mV, other manafacturers: 640mV */
|
||||
|
||||
@@ -80,6 +80,8 @@ typedef struct CustomizeTable {
|
||||
|
||||
u32 commonEmcMemVolt;
|
||||
u32 eristaEmcMaxClock;
|
||||
u32 eristaEmcMaxClock1;
|
||||
u32 eristaEmcMaxClock2;
|
||||
u32 marikoEmcMaxClock;
|
||||
u32 marikoEmcVddqVolt;
|
||||
u32 emcDvbShift;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Lightos_
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../oc_common.hpp"
|
||||
#include "../mtc_timing_value.hpp"
|
||||
|
||||
namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
void CalculateTimings(double tCK_avg) {
|
||||
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL_DBI - (C.t6_tRTW * 3) + finetRTW;
|
||||
tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL_DBI + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
|
||||
tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL_DBI)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
|
||||
|
||||
pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));
|
||||
tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;
|
||||
|
||||
const double tMMRI = tRCD + (tCK_avg * 3);
|
||||
pdex2mrr = tMMRI + 10;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Lightos_
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
void CalculateTimings(double tCK_avg);
|
||||
|
||||
}
|
||||
@@ -30,14 +30,7 @@ namespace ams::ldr::hoc {
|
||||
#define PACK_U32(high, low) ((static_cast<u32>(high) << 16) | (static_cast<u32>(low) & 0xFFFF))
|
||||
#define PACK_U32_NIBBLE_HIGH_BYTE_LOW(high, low) ((static_cast<u32>(high & 0xF) << 28) | (static_cast<u32>(low) & 0xFF))
|
||||
|
||||
/* Primary timings. */
|
||||
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
|
||||
const std::array<double, 7> tRRD_values = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? 8gb uses 7.5 tRRD on >=1331. */
|
||||
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
|
||||
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
|
||||
|
||||
|
||||
/* Burst latency, not to be confused with base latency (tWRL). */
|
||||
const u32 BL = 16;
|
||||
@@ -75,9 +68,14 @@ namespace ams::ldr::hoc {
|
||||
/* Write recovery time. */
|
||||
const u32 tWR = 18;
|
||||
|
||||
/* TOOD: Fix erista */
|
||||
namespace pcv::erista {
|
||||
const double tCK_avg = 1000'000.0 / C.eristaEmcMaxClock;
|
||||
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
|
||||
const std::array<double, 8> tRRD_values = { 10.0, 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 };
|
||||
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
|
||||
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
|
||||
|
||||
const u32 tRCD = tRCD_values[C.t1_tRCD];
|
||||
const u32 tRPpb = tRP_values[C.t2_tRP];
|
||||
@@ -95,43 +93,29 @@ namespace ams::ldr::hoc {
|
||||
const double tRPab = tRPpb + 3;
|
||||
|
||||
const u32 tR2P = CEIL((RL_DBI * 0.426) - 2.0);
|
||||
const u32 tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL_DBI - (C.t6_tRTW * 3) + finetRTW;
|
||||
inline u32 tR2W;
|
||||
inline u32 rext;
|
||||
|
||||
const u32 rdv = RL_DBI + FLOOR((5.105 / tCK_avg) + 17.017);
|
||||
const u32 qpop = rdv - 14;
|
||||
const u32 quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782);
|
||||
const u32 quse = FLOOR(RL_DBI + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg);
|
||||
const u32 einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width;
|
||||
const u32 einput = quse - CEIL(9.928 / tCK_avg);
|
||||
const u32 qrst_duration = FLOOR(8.399 - tCK_avg);
|
||||
const u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0));
|
||||
const u32 qrst = PACK_U32(qrst_duration, qrstLow);
|
||||
const u32 ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
|
||||
const u32 qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
|
||||
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
const u32 tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL_DBI + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
|
||||
const u32 tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL_DBI)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
|
||||
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
|
||||
inline u32 tWTPDEN;
|
||||
inline u32 tW2R;
|
||||
|
||||
const u32 wdv = WL;
|
||||
const u32 wsv = WL - 2;
|
||||
const u32 wev = 0xA + (WL - 14);
|
||||
inline u32 pdex2rw;
|
||||
|
||||
const u32 obdlyHigh = 3 / FLOOR(MIN(static_cast<double>(2), tCK_avg * (WL - 7)));
|
||||
const u32 obdlyLow = MAX(WL - FLOOR((126.0 / CEIL(tCK_avg + 8.601))), 0.0);
|
||||
const u32 obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow);
|
||||
inline u32 tCLKSTOP;
|
||||
|
||||
const u32 pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));
|
||||
|
||||
const u32 tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;
|
||||
|
||||
const double tMMRI = tRCD + (tCK_avg * 3);
|
||||
const double pdex2mrr = tMMRI + 10; /* Do this properly? */
|
||||
|
||||
inline u8 mrw2;
|
||||
inline double pdex2mrr;
|
||||
}
|
||||
|
||||
namespace pcv::mariko {
|
||||
const std::array<u32, 8> tRCD_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 8> tRP_values = { 18, 17, 16, 15, 14, 13, 12, 11 };
|
||||
const std::array<u32, 10> tRAS_values = { 42, 36, 34, 32, 30, 28, 26, 24, 22, 20 };
|
||||
const std::array<double, 7> tRRD_values = { /*10.0,*/ 7.5, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }; /* 10.0 is used for <2133mhz; do we care? 8gb uses 7.5 tRRD on >=1331. */
|
||||
const std::array<u32, 11> tRFC_values = { 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40 };
|
||||
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
|
||||
|
||||
const double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock;
|
||||
|
||||
const u32 tRCD = tRCD_values[C.t1_tRCD];
|
||||
|
||||
@@ -138,19 +138,20 @@ void SafetyCheck() {
|
||||
break;
|
||||
}
|
||||
|
||||
using namespace ams::ldr::hoc::pcv;
|
||||
sValidator validators[] = {
|
||||
{ C.eristaCpuBoostClock, 1020'000, 2295'000, true },
|
||||
{ C.marikoCpuBoostClock, 1020'000, 2703'000, true },
|
||||
{ C.commonEmcMemVolt, 912'500, 1350'000 }, // Official burst vmax for the RAMs is 1500mV
|
||||
{ C.eristaCpuMaxVolt, 1000, 1257 },
|
||||
{ C.eristaEmcMaxClock, 1600'000, 2600'000 },
|
||||
{ C.marikoCpuMaxVolt, 1000, 1235 },
|
||||
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
|
||||
{ C.marikoEmcVddqVolt, 250'000, 700'000 },
|
||||
{ eristaCpuDvfsMaxFreq, 1785'000, 2295'000 },
|
||||
{ marikoCpuDvfsMaxFreq, 1785'000, 2703'000 },
|
||||
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000 },
|
||||
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000 },
|
||||
{ C.commonEmcMemVolt, 912'500, 1350'000 }, // Official burst vmax for the RAMs is 1500mV
|
||||
{ C.eristaCpuMaxVolt, 1000, 1257 },
|
||||
{ GET_MAX_OF_ARR(erista::maxClocks), 1600'000, 2600'000 },
|
||||
{ C.marikoCpuMaxVolt, 1000, 1235 },
|
||||
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
|
||||
{ C.marikoEmcVddqVolt, 250'000, 700'000 },
|
||||
{ eristaCpuDvfsMaxFreq, 1785'000, 2295'000 },
|
||||
{ marikoCpuDvfsMaxFreq, 1785'000, 2703'000 },
|
||||
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000 },
|
||||
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000 },
|
||||
};
|
||||
|
||||
for (auto& i : validators) {
|
||||
|
||||
@@ -178,6 +178,9 @@ namespace ams::ldr::hoc::pcv {
|
||||
}
|
||||
|
||||
namespace erista {
|
||||
const u32 maxClocks[] = { C.eristaEmcMaxClock2, C.eristaEmcMaxClock1, C.eristaEmcMaxClock, };
|
||||
#define GET_MAX_OF_ARR(ARR) (*std::max_element(ARR, ARR + std::size(ARR)))
|
||||
|
||||
constexpr cvb_entry_t CpuCvbTableDefault[] = {
|
||||
// CPU_PLL_CVB_TABLE_ODN
|
||||
{ 204000, {721094}, { } },
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "pcv.hpp"
|
||||
#include "../mtc_timing_value.hpp"
|
||||
#include "../erista/calculate_timings_erista.hpp"
|
||||
|
||||
namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
@@ -184,12 +185,15 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
/* However, it may still achieve a slightly higher frequency, but not as much as it could be. */
|
||||
/* I'm certainly not insane enough to attempt this pain again, so this will have to do *for now*. */
|
||||
void MemMtcTableAutoAdjust(EristaMtcTable *table) {
|
||||
const double tCK_avg = 1000'000.0 / table->rate_khz;
|
||||
|
||||
#define WRITE_PARAM_ALL_REG(TABLE, PARAM, VALUE) \
|
||||
TABLE->burst_regs.PARAM = VALUE; \
|
||||
TABLE->shadow_regs_ca_train.PARAM = VALUE; \
|
||||
TABLE->shadow_regs_rdwr_train.PARAM = VALUE;
|
||||
|
||||
#define GET_CYCLE_CEIL(PARAM) u32(CEIL(double(PARAM) / tCK_avg))
|
||||
|
||||
/* Ram power down */
|
||||
/* B31: DRAM_CLKSTOP_PD */
|
||||
/* B30: DRAM_CLKSTOP_SR */
|
||||
@@ -206,10 +210,9 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
refresh_raw = MIN(refresh_raw, static_cast<u32>(0xFFFF));
|
||||
}
|
||||
|
||||
u32 rext;
|
||||
if (C.eristaEmcMaxClock > 3200000) {
|
||||
if (table->rate_khz > 3200000) {
|
||||
rext = 30;
|
||||
} else if (C.eristaEmcMaxClock >= 2133001) {
|
||||
} else if (table->rate_khz >= 2133001) {
|
||||
rext = 28;
|
||||
} else {
|
||||
rext = 26;
|
||||
@@ -218,6 +221,8 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
u32 trefbw = refresh_raw + 0x40;
|
||||
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
|
||||
|
||||
CalculateTimings(tCK_avg);
|
||||
|
||||
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
|
||||
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
|
||||
WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB8)));
|
||||
@@ -239,7 +244,7 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
WRITE_PARAM_ALL_REG(table, emc_w2p, tW2P);
|
||||
WRITE_PARAM_ALL_REG(table, emc_w2r, tW2R);
|
||||
WRITE_PARAM_ALL_REG(table, emc_rext, rext);
|
||||
WRITE_PARAM_ALL_REG(table, emc_wext, (C.eristaEmcMaxClock >= 2533000) ? 0x19 : 0x16);
|
||||
WRITE_PARAM_ALL_REG(table, emc_wext, (table->rate_khz >= 2533000) ? 0x19 : 0x16);
|
||||
WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
|
||||
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4);
|
||||
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
|
||||
@@ -286,7 +291,7 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
constexpr double MC_ARB_DIV = 4.0;
|
||||
constexpr u32 MC_ARB_SFA = 2;
|
||||
|
||||
table->burst_mc_regs.mc_emem_arb_cfg = C.eristaEmcMaxClock / (33.3 * 1000) / MC_ARB_DIV;
|
||||
table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV;
|
||||
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2;
|
||||
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1;
|
||||
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
|
||||
@@ -319,24 +324,24 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
|
||||
table->burst_mc_regs.mc_emem_arb_misc0 = (table->burst_mc_regs.mc_emem_arb_misc0 & 0xFFE08000) | (table->burst_mc_regs.mc_emem_arb_timing_rc + 1);
|
||||
|
||||
u32 mpcorer_ptsa_rate = MAX(static_cast<u32>(227), (C.eristaEmcMaxClock / 1600000) * 208);
|
||||
u32 mpcorer_ptsa_rate = MAX(static_cast<u32>(227), (table->rate_khz / 1600000) * 208);
|
||||
table->la_scale_regs.mc_mll_mpcorer_ptsa_rate = mpcorer_ptsa_rate;
|
||||
|
||||
u32 ftop_ptsa_rate = MAX(static_cast<u32>(31), (C.eristaEmcMaxClock / 1600000) * 24);
|
||||
u32 ftop_ptsa_rate = MAX(static_cast<u32>(31), (table->rate_khz / 1600000) * 24);
|
||||
table->la_scale_regs.mc_ftop_ptsa_rate = ftop_ptsa_rate;
|
||||
|
||||
u32 grant_decrement = MAX(static_cast<u32>(6143), (C.eristaEmcMaxClock / 1600000) * 4611);
|
||||
u32 grant_decrement = MAX(static_cast<u32>(6143), (table->rate_khz / 1600000) * 4611);
|
||||
table->la_scale_regs.mc_ptsa_grant_decrement = grant_decrement;
|
||||
|
||||
constexpr u32 MaskHigh = 0xFF00FFFF;
|
||||
constexpr u32 Mask2 = 0xFFFFFF00;
|
||||
constexpr u32 Mask3 = 0xFF00FF00;
|
||||
|
||||
const u32 allowance1 = static_cast<u32>(0x32000 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance2 = static_cast<u32>(0x9C40 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance3 = static_cast<u32>(0xB540 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance4 = static_cast<u32>(0x9600 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance5 = static_cast<u32>(0x8980 / (C.eristaEmcMaxClock / 0x3E8)) & 0xFF;
|
||||
const u32 allowance1 = static_cast<u32>(0x32000 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance2 = static_cast<u32>(0x9C40 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance3 = static_cast<u32>(0xB540 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance4 = static_cast<u32>(0x9600 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
const u32 allowance5 = static_cast<u32>(0x8980 / (table->rate_khz / 0x3E8)) & 0xFF;
|
||||
|
||||
table->la_scale_regs.mc_latency_allowance_xusb_0 = (table->la_scale_regs.mc_latency_allowance_xusb_0 & MaskHigh) | (allowance1 << 16);
|
||||
table->la_scale_regs.mc_latency_allowance_xusb_1 = (table->la_scale_regs.mc_latency_allowance_xusb_1 & MaskHigh) | (allowance1 << 16);
|
||||
@@ -377,25 +382,32 @@ namespace ams::ldr::hoc::pcv::erista {
|
||||
R_UNLESS(table_list[i]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
|
||||
}
|
||||
|
||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
|
||||
if (GET_MAX_OF_ARR(maxClocks) <= EmcClkOSLimit) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
// Make room for new mtc table, discarding useless 40.8 MHz table
|
||||
// 40800 overwritten by 68000, ..., 1331200 overwritten by 1600000, leaving table_list[0] not overwritten
|
||||
for (u32 i = khz_list_size - 1; i > 0; i--)
|
||||
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - 1]), sizeof(EristaMtcTable));
|
||||
// Make room for new mtc table, discarding useless 40.8, 68000 and 102000 MHz table
|
||||
// 40800 overwritten by 68000, ..., 1331200 overwritten by 1600000, leaving table_list[0], table_list[1] and table_list[2] not overwritten
|
||||
for (u32 i = khz_list_size - 1; i > 2; --i) {
|
||||
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - 3]), sizeof(EristaMtcTable));
|
||||
}
|
||||
|
||||
MemMtcTableAutoAdjust(table_list[0]);
|
||||
for (u32 i = 0; i < std::size(maxClocks); ++i) {
|
||||
if (maxClocks[i] > EmcClkOSLimit) {
|
||||
table_list[i]->rate_khz = maxClocks[i];
|
||||
MemMtcTableAutoAdjust(table_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MemFreqMax(u32 *ptr) {
|
||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
|
||||
if (GET_MAX_OF_ARR(maxClocks) <= EmcClkOSLimit) {
|
||||
R_SKIP();
|
||||
}
|
||||
|
||||
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
|
||||
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxClocks));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ typedef enum {
|
||||
|
||||
KipConfigValue_commonEmcMemVolt,
|
||||
KipConfigValue_eristaEmcMaxClock,
|
||||
KipConfigValue_eristaEmcMaxClock1,
|
||||
KipConfigValue_eristaEmcMaxClock2,
|
||||
KipConfigValue_marikoEmcMaxClock,
|
||||
KipConfigValue_marikoEmcVddqVolt,
|
||||
KipConfigValue_emcDvbShift,
|
||||
@@ -242,7 +244,11 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
|
||||
case KipConfigValue_commonEmcMemVolt:
|
||||
return pretty ? "Common EMC/MEM Voltage" : "common_emc_mem_volt";
|
||||
case KipConfigValue_eristaEmcMaxClock:
|
||||
return pretty ? "Erista EMC Max Clock" : "erista_emc_max_clock";
|
||||
return pretty ? "Erista EMC Max Clock 1" : "erista_emc_max_clock";
|
||||
case KipConfigValue_eristaEmcMaxClock1:
|
||||
return pretty ? "Erista EMC Max Clock 2" : "erista_emc_max_clock1";
|
||||
case KipConfigValue_eristaEmcMaxClock2:
|
||||
return pretty ? "Erista EMC Max Clock 3" : "erista_emc_max_clock2";
|
||||
case KipConfigValue_marikoEmcMaxClock:
|
||||
return pretty ? "Mariko EMC Max Clock" : "mariko_emc_max_clock";
|
||||
case KipConfigValue_marikoEmcVddqVolt:
|
||||
@@ -457,6 +463,8 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
|
||||
case KipConfigValue_hpMode:
|
||||
case KipConfigValue_commonEmcMemVolt:
|
||||
case KipConfigValue_eristaEmcMaxClock:
|
||||
case KipConfigValue_eristaEmcMaxClock1:
|
||||
case KipConfigValue_eristaEmcMaxClock2:
|
||||
case KipConfigValue_marikoEmcMaxClock:
|
||||
case KipConfigValue_marikoEmcVddqVolt:
|
||||
case KipConfigValue_emcDvbShift:
|
||||
|
||||
@@ -242,8 +242,6 @@ void MiscGui::listUI()
|
||||
ValueThresholds thresholdsDisabled(0, 0);
|
||||
std::vector<NamedValue> noNamedValues = {};
|
||||
|
||||
|
||||
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Settings"));
|
||||
|
||||
addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr);
|
||||
@@ -278,7 +276,6 @@ void MiscGui::listUI()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ValueThresholds throttleThresholds(70, 80);
|
||||
addConfigButton(
|
||||
HocClkConfigValue_ThermalThrottleThreshold,
|
||||
@@ -395,7 +392,7 @@ void MiscGui::listUI()
|
||||
// NamedValue("3072mA", 3072),
|
||||
// };
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
|
||||
|
||||
|
||||
std::vector<NamedValue> gpuSchedValues = {
|
||||
NamedValue("Do not override", GpuSchedulingMode_DoNotOverride),
|
||||
NamedValue("Enabled", GpuSchedulingMode_Enabled, "96.5% limit"),
|
||||
@@ -603,16 +600,9 @@ protected:
|
||||
};
|
||||
|
||||
if(IsErista()) {
|
||||
addConfigButton(
|
||||
KipConfigValue_eristaEmcMaxClock,
|
||||
"RAM Max Clock",
|
||||
ValueRange(0, 1, 1, "", 1),
|
||||
"RAM Max Clock",
|
||||
&eristaRamThresholds,
|
||||
{},
|
||||
eristaMaxEmcClock,
|
||||
false
|
||||
);
|
||||
addConfigButton(KipConfigValue_eristaEmcMaxClock, "RAM Max Clock", ValueRange(0, 1, 1, "", 1), "RAM Max Clock", &eristaRamThresholds, {}, eristaMaxEmcClock, false);
|
||||
addConfigButton(KipConfigValue_eristaEmcMaxClock1, "RAM Max Clock", ValueRange(0, 1, 1, "", 1), "RAM Max Clock", &eristaRamThresholds, {}, eristaMaxEmcClock, false);
|
||||
addConfigButton(KipConfigValue_eristaEmcMaxClock2, "RAM Max Clock", ValueRange(0, 1, 1, "", 1), "RAM Max Clock", &eristaRamThresholds, {}, eristaMaxEmcClock, false);
|
||||
} else {
|
||||
addConfigButton(
|
||||
KipConfigValue_marikoEmcMaxClock,
|
||||
|
||||
@@ -115,7 +115,7 @@ ClockManager::ClockManager()
|
||||
previousRamHz = Board::GetHz(SysClkModule_MEM);
|
||||
Board::SetGpuSchedulingMode((GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling));
|
||||
this->context->gpuSchedulingMode = (GpuSchedulingMode)this->config->GetConfigValue(HorizonOCConfigValue_GPUScheduling);
|
||||
|
||||
|
||||
struct stat st = {0};
|
||||
if (stat("sdmc:/atmosphere/contents/42000000000000A0", &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
this->context->isSysDockInstalled = true;
|
||||
@@ -811,6 +811,8 @@ void ClockManager::SetKipData() {
|
||||
|
||||
CUST_WRITE_FIELD_BATCH(&table, commonEmcMemVolt, this->config->GetConfigValue(KipConfigValue_commonEmcMemVolt));
|
||||
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock, this->config->GetConfigValue(KipConfigValue_eristaEmcMaxClock));
|
||||
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock1, this->config->GetConfigValue(KipConfigValue_eristaEmcMaxClock1));
|
||||
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock2, this->config->GetConfigValue(KipConfigValue_eristaEmcMaxClock2));
|
||||
CUST_WRITE_FIELD_BATCH(&table, marikoEmcMaxClock, this->config->GetConfigValue(KipConfigValue_marikoEmcMaxClock));
|
||||
CUST_WRITE_FIELD_BATCH(&table, marikoEmcVddqVolt, this->config->GetConfigValue(KipConfigValue_marikoEmcVddqVolt));
|
||||
CUST_WRITE_FIELD_BATCH(&table, emcDvbShift, this->config->GetConfigValue(KipConfigValue_emcDvbShift));
|
||||
@@ -934,6 +936,8 @@ void ClockManager::GetKipData() {
|
||||
|
||||
initialConfigValues[KipConfigValue_commonEmcMemVolt] = cust_get_common_emc_volt(&table);
|
||||
initialConfigValues[KipConfigValue_eristaEmcMaxClock] = cust_get_erista_emc_max(&table);
|
||||
initialConfigValues[KipConfigValue_eristaEmcMaxClock1] = cust_get_erista_emc_max1(&table);
|
||||
initialConfigValues[KipConfigValue_eristaEmcMaxClock2] = cust_get_erista_emc_max2(&table);
|
||||
initialConfigValues[KipConfigValue_marikoEmcMaxClock] = cust_get_mariko_emc_max(&table);
|
||||
initialConfigValues[KipConfigValue_marikoEmcVddqVolt] = cust_get_mariko_emc_vddq(&table);
|
||||
initialConfigValues[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table);
|
||||
@@ -980,6 +984,8 @@ void ClockManager::GetKipData() {
|
||||
|
||||
configValues.values[KipConfigValue_commonEmcMemVolt] = cust_get_common_emc_volt(&table);
|
||||
configValues.values[KipConfigValue_eristaEmcMaxClock] = cust_get_erista_emc_max(&table);
|
||||
configValues.values[KipConfigValue_eristaEmcMaxClock1] = cust_get_erista_emc_max1(&table);
|
||||
configValues.values[KipConfigValue_eristaEmcMaxClock2] = cust_get_erista_emc_max2(&table);
|
||||
configValues.values[KipConfigValue_marikoEmcMaxClock] = cust_get_mariko_emc_max(&table);
|
||||
configValues.values[KipConfigValue_marikoEmcVddqVolt] = cust_get_mariko_emc_vddq(&table);
|
||||
configValues.values[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table);
|
||||
|
||||
@@ -32,6 +32,8 @@ typedef struct {
|
||||
u32 hpMode;
|
||||
u32 commonEmcMemVolt;
|
||||
u32 eristaEmcMaxClock;
|
||||
u32 eristaEmcMaxClock1;
|
||||
u32 eristaEmcMaxClock2;
|
||||
u32 marikoEmcMaxClock;
|
||||
u32 marikoEmcVddqVolt;
|
||||
u32 emcDvbShift;
|
||||
@@ -192,6 +194,8 @@ static inline bool cust_set_hp_mode(const char* p, u32 v) { CUST_WRITE_FIELD(p,
|
||||
|
||||
static inline bool cust_set_common_emc_volt(const char* p, u32 v) { CUST_WRITE_FIELD(p, commonEmcMemVolt, v); }
|
||||
static inline bool cust_set_erista_emc_max(const char* p, u32 v) { CUST_WRITE_FIELD(p, eristaEmcMaxClock, v); }
|
||||
static inline bool cust_set_erista_emc_max1(const char* p, u32 v) { CUST_WRITE_FIELD(p, eristaEmcMaxClock1, v); }
|
||||
static inline bool cust_set_erista_emc_max2(const char* p, u32 v) { CUST_WRITE_FIELD(p, eristaEmcMaxClock2, v); }
|
||||
static inline bool cust_set_mariko_emc_max(const char* p, u32 v) { CUST_WRITE_FIELD(p, marikoEmcMaxClock, v); }
|
||||
static inline bool cust_set_mariko_emc_vddq(const char* p, u32 v) { CUST_WRITE_FIELD(p, marikoEmcVddqVolt, v); }
|
||||
static inline bool cust_set_emc_dvb_shift(const char* p, u32 v) { CUST_WRITE_FIELD(p, emcDvbShift, v); }
|
||||
@@ -261,6 +265,8 @@ static inline u32 cust_get_hp_mode(const CustomizeTable* t) { return CUST_GET_FI
|
||||
|
||||
static inline u32 cust_get_common_emc_volt(const CustomizeTable* t) { return CUST_GET_FIELD(t, commonEmcMemVolt); }
|
||||
static inline u32 cust_get_erista_emc_max(const CustomizeTable* t) { return CUST_GET_FIELD(t, eristaEmcMaxClock); }
|
||||
static inline u32 cust_get_erista_emc_max1(const CustomizeTable* t) { return CUST_GET_FIELD(t, eristaEmcMaxClock1); }
|
||||
static inline u32 cust_get_erista_emc_max2(const CustomizeTable* t) { return CUST_GET_FIELD(t, eristaEmcMaxClock2); }
|
||||
static inline u32 cust_get_mariko_emc_max(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoEmcMaxClock); }
|
||||
static inline u32 cust_get_mariko_emc_vddq(const CustomizeTable* t) { return CUST_GET_FIELD(t, marikoEmcVddqVolt); }
|
||||
static inline u32 cust_get_emc_dvb_shift(const CustomizeTable* t) { return CUST_GET_FIELD(t, emcDvbShift); }
|
||||
|
||||
Reference in New Issue
Block a user