@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -27,13 +27,18 @@
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define TABLE_FREQ_KHZ_OFFSET 0x40
|
||||
#define TABLE_LA_REGS_T210_OFFSET 0x1284
|
||||
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
|
||||
#define LA_SDMMC1_INDEX 6
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
|
||||
u32 minerva_init()
|
||||
{
|
||||
u32 curr_ram_idx = 0;
|
||||
u32 tbl_idx = 0;
|
||||
|
||||
minerva_cfg = NULL;
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
@@ -98,13 +103,13 @@ u32 minerva_init()
|
||||
|
||||
// Get current frequency
|
||||
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
||||
for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++)
|
||||
{
|
||||
if (current_emc_clk_src == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)
|
||||
if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
|
||||
break;
|
||||
}
|
||||
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
|
||||
mtc_cfg->rate_to = FREQ_204;
|
||||
mtc_cfg->train_mode = OP_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
@@ -140,6 +145,27 @@ void minerva_change_freq(minerva_freq_t freq)
|
||||
}
|
||||
}
|
||||
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01)
|
||||
{
|
||||
|
||||
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
|
||||
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
|
||||
|
||||
// Adjust SDMMC1 latency allowance.
|
||||
switch (freq)
|
||||
{
|
||||
case 204000:
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
|
||||
break;
|
||||
case 408000:
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
|
||||
break;
|
||||
default:
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void minerva_prep_boot_freq()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
@@ -157,23 +183,46 @@ void minerva_prep_boot_freq()
|
||||
minerva_change_freq(FREQ_800);
|
||||
}
|
||||
|
||||
void minerva_prep_boot_l4t(int oc_freq)
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Program SDMMC LA regs.
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||
|
||||
// Add OC frequency.
|
||||
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
|
||||
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
|
||||
sizeof(emc_table_t));
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
|
||||
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
|
||||
mtc_cfg->table_entries++;
|
||||
}
|
||||
|
||||
// Trim table.
|
||||
int entries = 0;
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
// Copy frequencies from 204/408/800 MHz and 1333+ MHz.
|
||||
int rate = mtc_cfg->mtc_table[i].rate_khz;
|
||||
if (rate == FREQ_204 ||
|
||||
rate == FREQ_408 ||
|
||||
rate == FREQ_800 ||
|
||||
rate >= FREQ_1333)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
mtc_cfg->table_entries = entries;
|
||||
|
||||
// Set init frequency.
|
||||
minerva_change_freq(FREQ_204);
|
||||
|
||||
@@ -181,35 +230,21 @@ void minerva_prep_boot_l4t(int oc_freq)
|
||||
mtc_cfg->train_mode = OP_TRAIN;
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
||||
// Skip already trained frequencies.
|
||||
if (mtc_cfg->rate_to == FREQ_204 || mtc_cfg->rate_to == FREQ_800 || mtc_cfg->rate_to == FREQ_1600)
|
||||
// Skip already trained frequencies and OC freq (Arachne handles it).
|
||||
if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
|
||||
continue;
|
||||
|
||||
// Train frequency.
|
||||
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
}
|
||||
|
||||
// Do FSP WAR and scale to 800 MHz as boot freq.
|
||||
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
|
||||
if (fsp_opwr_disabled)
|
||||
minerva_change_freq(FREQ_666);
|
||||
minerva_change_freq(FREQ_1333);
|
||||
minerva_change_freq(FREQ_800);
|
||||
|
||||
// Trim table.
|
||||
int entries = 0;
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
// Copy freqs from 204 MHz to 800 MHz and 1600 MHz and above.
|
||||
int rate = mtc_cfg->mtc_table[i].rate_khz;
|
||||
if ((rate >= FREQ_204 && rate <= FREQ_800) || rate >= FREQ_1600)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
mtc_cfg->table_entries = entries;
|
||||
|
||||
// Do not let other mtc ops.
|
||||
mtc_cfg->init_done = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user