Public multiple ram freqs for erista
First ever release of public multiple ram freqs You get three extra frequencies on erista
This commit is contained in:
@@ -56,7 +56,13 @@ volatile CustomizeTable C = {
|
|||||||
* - System instabilities
|
* - System instabilities
|
||||||
* - NAND corruption
|
* - NAND corruption
|
||||||
*/
|
*/
|
||||||
.eristaEmcMaxClock = 2240000,
|
|
||||||
|
.eristaEmcClock1 = 1862400, // Lowest
|
||||||
|
|
||||||
|
.eristaEmcClock2 = 1996800, // Middle
|
||||||
|
|
||||||
|
.eristaEmcClock3 = 2132640, // Highest
|
||||||
|
|
||||||
|
|
||||||
/* Mariko CPU:
|
/* Mariko CPU:
|
||||||
* - Max Voltage in mV:
|
* - Max Voltage in mV:
|
||||||
|
|||||||
@@ -50,7 +50,9 @@
|
|||||||
u32 commonCpuBoostClock;
|
u32 commonCpuBoostClock;
|
||||||
u32 commonEmcMemVolt;
|
u32 commonEmcMemVolt;
|
||||||
u32 eristaCpuMaxVolt;
|
u32 eristaCpuMaxVolt;
|
||||||
u32 eristaEmcMaxClock;
|
u32 eristaEmcClock1;
|
||||||
|
u32 eristaEmcClock2;
|
||||||
|
u32 eristaEmcClock3;
|
||||||
u32 marikoCpuMaxVolt;
|
u32 marikoCpuMaxVolt;
|
||||||
u32 marikoEmcMaxClock;
|
u32 marikoEmcMaxClock;
|
||||||
u32 marikoEmcVddqVolt;
|
u32 marikoEmcVddqVolt;
|
||||||
|
|||||||
@@ -155,9 +155,9 @@
|
|||||||
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
|
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
|
||||||
//const u32 QUSE = RL + CEIL(tDQSCK_min/tCK_avg + tDQSQ);
|
//const u32 QUSE = RL + CEIL(tDQSCK_min/tCK_avg + tDQSQ);
|
||||||
|
|
||||||
namespace pcv::erista {
|
namespace pcv::erista { // TODO: Adjust timings properly for all freqs
|
||||||
// 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.eristaEmcClock3;
|
||||||
|
|
||||||
// Write Latency
|
// Write Latency
|
||||||
const u32 WL = 14 + C.mem_burst_latency;
|
const u32 WL = 14 + C.mem_burst_latency;
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
|
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
|
||||||
// emc_clk_period = dram_clk / 2;
|
// emc_clk_period = dram_clk / 2;
|
||||||
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
|
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
|
||||||
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
|
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.eristaEmcClock3 / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
|
||||||
const u32 REFBW = MIN((u32)65536, REFRESH+64);
|
const u32 REFBW = MIN((u32)65536, REFRESH+64);
|
||||||
|
|
||||||
// Write With Auto Precharge to to Power-Down Entry
|
// Write With Auto Precharge to to Power-Down Entry
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ void SafetyCheck() {
|
|||||||
{ C.commonCpuBoostClock, 1020'000, 3000'000, true },
|
{ C.commonCpuBoostClock, 1020'000, 3000'000, true },
|
||||||
{ C.commonEmcMemVolt, 1100'000, 1500'000 }, // Official burst vmax for the RAMs
|
{ C.commonEmcMemVolt, 1100'000, 1500'000 }, // Official burst vmax for the RAMs
|
||||||
{ C.eristaCpuMaxVolt, 1100, 1300 },
|
{ C.eristaCpuMaxVolt, 1100, 1300 },
|
||||||
{ C.eristaEmcMaxClock, 1600'000, 2600'200 },
|
{ C.eristaEmcClock3, 1600'000, 2600'200 },
|
||||||
{ C.marikoCpuMaxVolt, 1100, 1300 },
|
{ C.marikoCpuMaxVolt, 1100, 1300 },
|
||||||
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
|
{ C.marikoEmcMaxClock, 1600'000, 3500'000 },
|
||||||
{ C.marikoEmcVddqVolt, 550'000, 700'000 },
|
{ C.marikoEmcVddqVolt, 550'000, 700'000 },
|
||||||
|
|||||||
@@ -246,7 +246,7 @@
|
|||||||
{
|
{
|
||||||
u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800};
|
u32 khz_list[] = {1600000, 1331200, 1065600, 800000, 665600, 408000, 204000, 102000, 68000, 40800};
|
||||||
u32 khz_list_size = sizeof(khz_list) / sizeof(u32);
|
u32 khz_list_size = sizeof(khz_list) / sizeof(u32);
|
||||||
|
|
||||||
// Generate list for mtc table pointers
|
// Generate list for mtc table pointers
|
||||||
EristaMtcTable *table_list[khz_list_size];
|
EristaMtcTable *table_list[khz_list_size];
|
||||||
for (u32 i = 0; i < khz_list_size; i++)
|
for (u32 i = 0; i < khz_list_size; i++)
|
||||||
@@ -256,32 +256,49 @@
|
|||||||
R_UNLESS(table_list[i]->rate_khz == khz_list[i], ldr::ResultInvalidMtcTable());
|
R_UNLESS(table_list[i]->rate_khz == khz_list[i], ldr::ResultInvalidMtcTable());
|
||||||
R_UNLESS(table_list[i]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
|
R_UNLESS(table_list[i]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
|
if (C.eristaEmcClock1 <= EmcClkOSLimit ||
|
||||||
|
C.eristaEmcClock2 <= EmcClkOSLimit ||
|
||||||
|
C.eristaEmcClock3 <= EmcClkOSLimit)
|
||||||
R_SKIP();
|
R_SKIP();
|
||||||
|
|
||||||
// Make room for new mtc table, discarding useless 40.8 MHz table
|
// Make room for three new mtc tables, discarding useless 40.8, 68.0, and 102 MHz tables
|
||||||
// 40800 overwritten by 68000, ..., 1331200 overwritten by 1600000, leaving table_list[0] not overwritten
|
for (u32 i = khz_list_size - 1; i > 2; i--)
|
||||||
for (u32 i = khz_list_size - 1; i > 0; i--)
|
std::memcpy(static_cast<void *>(table_list[i]),
|
||||||
std::memcpy(static_cast<void *>(table_list[i]), static_cast<void *>(table_list[i - 1]), sizeof(EristaMtcTable));
|
static_cast<void *>(table_list[i - 3]),
|
||||||
|
sizeof(EristaMtcTable));
|
||||||
|
|
||||||
|
// Adjust all three new tables
|
||||||
MemMtcTableAutoAdjust(table_list[0]);
|
MemMtcTableAutoAdjust(table_list[0]);
|
||||||
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
|
MemMtcTableAutoAdjust(table_list[1]);
|
||||||
|
MemMtcTableAutoAdjust(table_list[2]);
|
||||||
|
|
||||||
|
// Patch pointers for 3 custom clocks
|
||||||
|
u32 *patch_ptr1 = ptr;
|
||||||
|
u32 *patch_ptr2 = ptr - sizeof(EristaMtcTable) / sizeof(u32);
|
||||||
|
u32 *patch_ptr3 = ptr - 2 * (sizeof(EristaMtcTable) / sizeof(u32));
|
||||||
|
|
||||||
|
if (C.eristaEmcClock3 > EmcClkOSLimit)
|
||||||
|
PATCH_OFFSET(patch_ptr1, C.eristaEmcClock3);
|
||||||
|
if (C.eristaEmcClock2 > EmcClkOSLimit)
|
||||||
|
PATCH_OFFSET(patch_ptr2, C.eristaEmcClock2);
|
||||||
|
if (C.eristaEmcClock3 > EmcClkOSLimit)
|
||||||
|
PATCH_OFFSET(patch_ptr3, C.eristaEmcClock1);
|
||||||
|
|
||||||
// Handle customize table replacement
|
// Handle customize table replacement
|
||||||
// if (C.mtcConf == CUSTOMIZED_ALL) {
|
// if (C.mtcConf == CUSTOMIZED_ALL) {
|
||||||
// MemMtcCustomizeTable(table_list[0], const_cast<EristaMtcTable *>(C.eristaMtcTable));
|
// MemMtcCustomizeTable(table_list[0], const_cast<EristaMtcTable *>(C.eristaMtcTable));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MemFreqMax(u32 *ptr)
|
Result MemFreqMax(u32 *ptr)
|
||||||
{
|
{
|
||||||
if (C.eristaEmcMaxClock <= EmcClkOSLimit)
|
if (C.eristaEmcClock3 <= EmcClkOSLimit)
|
||||||
R_SKIP();
|
R_SKIP();
|
||||||
|
|
||||||
PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
|
PATCH_OFFSET(ptr, C.eristaEmcClock3);
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user