EMC voltage for Mariko; Fix #60; Show battery & voltage info in overlay on Erista
- From previous analysis, EMC voltage is set before AMS loads on Mariko, and will not be set again or changed afterwards. - sys-clk-OC will take care of setting emc voltage on Mariko once it loads. - OS will not hang at boot as it always boots with EMC @ 1600 MHz.
This commit is contained in:
@@ -33,7 +33,8 @@ void SafetyCheck() {
|
||||
if (C.custRev != CUST_REV ||
|
||||
C.marikoCpuMaxVolt >= 1300 ||
|
||||
C.eristaCpuMaxVolt >= 1300 ||
|
||||
(C.eristaEmcVolt && (C.eristaEmcVolt < 600'000 || C.eristaEmcVolt > 1250'000)))
|
||||
(C.eristaEmcVolt && (C.eristaEmcVolt < 600'000 || C.eristaEmcVolt > 1250'000)) ||
|
||||
(C.marikoEmcVolt && (C.marikoEmcVolt < 600'000 || C.marikoEmcVolt > 650'000)))
|
||||
{
|
||||
CRASH("Triggered");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../oc_suite_common.hpp"
|
||||
#include "../oc_common.hpp"
|
||||
|
||||
namespace ams::ldr::oc::pcv {
|
||||
|
||||
@@ -88,6 +88,33 @@ typedef struct __attribute__((packed)) dvfs_rail {
|
||||
u32 unk_2[11];
|
||||
} dvfs_rail;
|
||||
|
||||
typedef struct __attribute__((packed)) regulator {
|
||||
u64 id;
|
||||
const char* name;
|
||||
u32 type;
|
||||
union {
|
||||
struct {
|
||||
u32 volt_reg;
|
||||
u32 step_uv;
|
||||
u32 min_uv;
|
||||
u32 default_uv;
|
||||
u32 max_uv;
|
||||
u32 unk_0[2];
|
||||
} type_1;
|
||||
struct {
|
||||
u32 unk_0;
|
||||
u32 step_uv;
|
||||
u32 unk_1;
|
||||
u32 min_uv;
|
||||
u32 max_uv;
|
||||
u32 unk_2;
|
||||
u32 default_uv;
|
||||
} type_2_3;
|
||||
};
|
||||
u32 unk_x[60];
|
||||
} regulator;
|
||||
static_assert(sizeof(regulator) == 0x120);
|
||||
|
||||
constexpr u32 CpuClkOSLimit = 1785'000;
|
||||
|
||||
constexpr u32 MemClkOSLimit = 1600'000;
|
||||
|
||||
@@ -27,11 +27,20 @@ Result CpuFreqCvbTable(u32* ptr) {
|
||||
bool validated = std::memcmp(cpu_cvb_table_head, CpuCvbTableDefault, sizeof(CpuCvbTableDefault)) == 0;
|
||||
R_UNLESS(validated, ldr::ResultInvalidCpuDvfs());
|
||||
|
||||
if (!C.eristaCpuOCEnabled)
|
||||
R_SKIP();
|
||||
|
||||
std::memcpy(reinterpret_cast<void *>(new_start), CpuCvbTableAppend, sizeof(CpuCvbTableAppend));
|
||||
|
||||
// Patch CPU max volt in existing and appended CPU dvfs table
|
||||
if (C.eristaCpuMaxVolt) {
|
||||
size_t table_size = sizeof(CpuCvbTableAppend) / sizeof(cpu_freq_cvb_table_t);
|
||||
cpu_freq_cvb_table_t* entry = new_start;
|
||||
for (size_t i = 0; i < table_size; i++) {
|
||||
if (entry->cvb_dfll_param.c0 == CpuVoltL4T) {
|
||||
PatchOffset(reinterpret_cast<u32 *>(&(entry->cvb_dfll_param.c0)), C.eristaCpuMaxVolt * 1000);
|
||||
}
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,10 +40,12 @@ constexpr cpu_freq_cvb_table_t CpuCvbTableDefault[] = {
|
||||
{ 1785000, { 1227500 }, { 5100873, -279186, 4747 } },
|
||||
};
|
||||
|
||||
constexpr u32 CpuVoltL4T = 1235'000;
|
||||
|
||||
constexpr cpu_freq_cvb_table_t CpuCvbTableAppend[] = {
|
||||
{ 1887000, { 1235000 }, { 5100873, -279186, 4747 } },
|
||||
{ 1963500, { 1235000 }, { 5100873, -279186, 4747 } },
|
||||
{ 2091000, { 1235000 }, { 5100873, -279186, 4747 } },
|
||||
{ 1887000, { CpuVoltL4T }, { 5100873, -279186, 4747 } },
|
||||
{ 1963500, { CpuVoltL4T }, { 5100873, -279186, 4747 } },
|
||||
{ 2091000, { CpuVoltL4T }, { 5100873, -279186, 4747 } },
|
||||
};
|
||||
|
||||
constexpr u32 CpuMinVolts[] = { 950, 850, 825, 810 };
|
||||
|
||||
@@ -149,6 +149,9 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
|
||||
* you'd better calculate timings yourself rather than relying on following algorithm.
|
||||
*/
|
||||
|
||||
if (C.mtcConf == NO_ADJ_ALL)
|
||||
return;
|
||||
|
||||
#define ADJUST_PROP(TARGET, REF) \
|
||||
(u32)(std::ceil(REF + ((C.marikoEmcMaxClock-MemClkOSAlt)*(TARGET-REF))/(MemClkOSLimit-MemClkOSAlt)))
|
||||
|
||||
@@ -186,7 +189,7 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
|
||||
ADJUST_PARAM_TABLE(table, la_scale_regs.mc_ptsa_grant_decrement, ref);
|
||||
|
||||
/* Timings that are available in or can be derived from LPDDR4X datasheet or TRM */
|
||||
const bool use_4266_spec = C.mtcConf == AUTO_ADJ_MARIKO_4266;
|
||||
const bool use_4266_spec = C.mtcConf == AUTO_ADJ_MARIKO_4266_NO_ADJ_ERISTA;
|
||||
// tCK_avg (average clock period) in ns
|
||||
const double tCK_avg = 1000'000. / C.marikoEmcMaxClock;
|
||||
// tRPpb (row precharge time per bank) in ns
|
||||
@@ -368,6 +371,29 @@ Result MemFreqMax(u32* ptr) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MemVoltHandler(u32* ptr) {
|
||||
u32 emc_uv = C.marikoEmcVolt;
|
||||
if (!emc_uv)
|
||||
R_SKIP();
|
||||
|
||||
regulator* entry = reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_2_3.default_uv));
|
||||
|
||||
constexpr u32 uv_step = 5'000;
|
||||
constexpr u32 uv_min = 250'000;
|
||||
|
||||
if (entry->id != 2 || entry->type != 3 ||
|
||||
entry->type_2_3.step_uv != uv_step ||
|
||||
entry->type_2_3.min_uv != uv_min)
|
||||
R_THROW(ldr::ResultInvalidRegulatorEntry());
|
||||
|
||||
if (emc_uv % uv_step)
|
||||
emc_uv = emc_uv / uv_step * uv_step; // rounding
|
||||
|
||||
PatchOffset(ptr, emc_uv);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Patch(uintptr_t mapped_nso, size_t nso_size) {
|
||||
PatcherEntry<u32> patches[] = {
|
||||
{ "CPU Freq Vdd", &CpuFreqVdd, 1, nullptr, CpuClkOSLimit },
|
||||
@@ -380,6 +406,7 @@ void Patch(uintptr_t mapped_nso, size_t nso_size) {
|
||||
{ "MEM Freq Dvb", &MemFreqDvbTable, 1, nullptr, MemClkOSLimit },
|
||||
{ "MEM Freq Max", &MemFreqMax, 0, nullptr, MemClkOSLimit },
|
||||
{ "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, MemClkPllmLimit },
|
||||
{ "MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltDefault }
|
||||
};
|
||||
|
||||
for (uintptr_t ptr = mapped_nso;
|
||||
|
||||
@@ -115,13 +115,9 @@ constexpr emc_dvb_dvfs_table_t EmcDvbTableDefault[] = {
|
||||
{ 1600000, { 675, 650, 637, } },
|
||||
};
|
||||
|
||||
constexpr emc_dvb_dvfs_table_t EmcDvbTableReplaced[] = {
|
||||
{ 1862400, { 675, 650, 637, } },
|
||||
{ 2133000, { 700, 675, 650, } },
|
||||
};
|
||||
|
||||
constexpr u32 MemClkOSAlt = 1331'200;
|
||||
constexpr u32 MemClkPllmLimit = 2133'000'000;
|
||||
constexpr u32 MemVoltDefault = 600'000;
|
||||
|
||||
constexpr u32 MTC_TABLE_REV = 3;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user