minerva: update tov1.6_T210/v0.1_T21X
T21X v0.1: - Add IRB/no table support T210 v1.6/Common: - Add a proper table for 8GB T210 config instead of editing a 4GB one - Increase timeout to 2ms - Generally improve checks and guard against unknown SoCs/SKUs - Remove the long ago obsolete OVERCLOCK_FREQ/OVERCLOCK_VOLTAGE ifdefs
This commit is contained in:
@@ -26,7 +26,7 @@ $(BUILD)/%.o: ./%.c
|
||||
@$(CC) $(CFLAGS) $(BDKINC) -c $< -o $@
|
||||
|
||||
$(TARGET).bso: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -e _minerva_init $^ -o $(OUTPUT)/$(TARGET).bso
|
||||
@$(CC) $(LDFLAGS) -e minerva_entry $^ -o $(OUTPUT)/$(TARGET).bso
|
||||
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
|
||||
@echo -e "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minerva Training Cell
|
||||
* DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.
|
||||
* DRAM Training for Tegra X1 SoC. Supports LPDDR4.
|
||||
*
|
||||
* Copyright (c) 2018-2025 CTCaer <ctcaer@gmail.com>
|
||||
*
|
||||
@@ -24,30 +24,38 @@
|
||||
#include "types.h"
|
||||
|
||||
/* Address bases and access macros - Change these for mapped access */
|
||||
#define TMR_BASE 0x60005000
|
||||
#define CLOCK_BASE 0x60006000
|
||||
#define MC_BASE 0x70019000
|
||||
#define EMC_BASE 0x7001B000
|
||||
#define EMC0_BASE 0x7001E000
|
||||
#define EMC1_BASE 0x7001F000
|
||||
#define TMR_BASE 0x60005000
|
||||
#define CLOCK_BASE 0x60006000
|
||||
#define APB_MISC_BASE 0x70000000
|
||||
#define FUSE_BASE 0x7000F800
|
||||
#define MC_BASE 0x70019000
|
||||
#define EMC_BASE 0x7001B000
|
||||
#define EMC0_BASE 0x7001E000
|
||||
#define EMC1_BASE 0x7001F000
|
||||
|
||||
#define MTC_INIT_MAGIC 0x3043544D
|
||||
#define MTC_NEW_MAGIC 0x5243544D
|
||||
#define MTC_IRB_MAGIC 0x4943544D
|
||||
|
||||
#define MTC_INIT_FREQUENCY 204000
|
||||
|
||||
#define _REG(base, off) *(vu32 *)((base) + (off))
|
||||
|
||||
#define TMR(off) _REG(TMR_BASE, off)
|
||||
#define CLOCK(off) _REG(CLOCK_BASE, off)
|
||||
#define MC(off) _REG(MC_BASE, off)
|
||||
#define EMC(off) _REG(EMC_BASE, off)
|
||||
#define EMC_CH0(off) _REG(EMC0_BASE, off)
|
||||
#define EMC_CH1(off) _REG(EMC1_BASE, off)
|
||||
#define TMR(off) _REG(TMR_BASE, off)
|
||||
#define CLOCK(off) _REG(CLOCK_BASE, off)
|
||||
#define APB_MISC(off) _REG(APB_MISC_BASE, off)
|
||||
#define FUSE(off) _REG(FUSE_BASE, off)
|
||||
#define MC(off) _REG(MC_BASE, off)
|
||||
#define EMC(off) _REG(EMC_BASE, off)
|
||||
#define EMC_CH0(off) _REG(EMC0_BASE, off)
|
||||
#define EMC_CH1(off) _REG(EMC1_BASE, off)
|
||||
/* End of addresses and access macros */
|
||||
|
||||
#define EMC_TABLE_ENTRY_SIZE_R7 4928
|
||||
#define EMC_TABLE_ENTRY_SIZE_R3 4300
|
||||
#define EMC_TABLE_SIZE_R7 (EMC_TABLE_ENTRY_SIZE_R7 * 7)
|
||||
#define EMC_STATUS_UPDATE_TIMEOUT 1000
|
||||
#define EMC_TABLE_SIZE_ODINX02_R7 (EMC_TABLE_ENTRY_SIZE_R7 * 7)
|
||||
|
||||
#define EMC_STATUS_UPDATE_TIMEOUT 2000
|
||||
#define EMC_PERIODIC_TRAIN_MS 100
|
||||
#define EMC_TEMP_COMP_MS 1000
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minerva Training Cell
|
||||
* DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.
|
||||
* DRAM Training for Tegra X1 SoC. Supports LPDDR4.
|
||||
*
|
||||
* Copyright (c) 2018-2025 CTCaer <ctcaer@gmail.com>
|
||||
*
|
||||
@@ -20,6 +20,16 @@
|
||||
#ifndef _MTC_MC_EMC_REGS_H_
|
||||
#define _MTC_MC_EMC_REGS_H_
|
||||
|
||||
/* APB misc registers */
|
||||
#define APB_MISC_GP_HIDREV 0x804
|
||||
#define HIDREV_MAJOR_T210 0x1
|
||||
#define HIDREV_MAJOR_T210B01 0x2
|
||||
#define HIDREV_CHIPID_T210 0x21
|
||||
|
||||
/* Fuse registers */
|
||||
#define FUSE_SKU_INFO 0x110
|
||||
#define SKU_ODIN 0x83
|
||||
|
||||
/* Clock controller registers */
|
||||
#define CLK_RST_CONTROLLER_PLLM_BASE 0x90
|
||||
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
||||
@@ -110,7 +120,7 @@
|
||||
#define CLKCHANGE_COMPLETE_INT (1 << 4)
|
||||
|
||||
#define EMC_DBG 0x8
|
||||
#define EMC_DBG_READ_MUX_ACTIVE BIT(0)
|
||||
#define EMC_DBG_READ_MUX_ASSEMBLY BIT(0)
|
||||
#define EMC_DBG_WRITE_MUX_ACTIVE BIT(1)
|
||||
#define EMC_DBG_CFG_SWAP_ACTIVE_ONLY (0 << 26u)
|
||||
#define EMC_DBG_CFG_SWAP_SWAP (1 << 26u)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,16 +25,12 @@
|
||||
#include "types.h"
|
||||
#include <module.h>
|
||||
|
||||
#define DVFS_CLOCK_CHANGE_VERSION "Minerva Training Cell v1.5_lpddr4"
|
||||
#define EMC_PRELOCK_VERSION 2101
|
||||
#define DVFS_T21X_CC_VERSION "Minerva Training Cell v0.1_T21X"
|
||||
#define DVFS_T210_CC_VERSION "Minerva Training Cell v1.6_T210"
|
||||
|
||||
#define EPRINTF(...)
|
||||
#define EPRINTFARGS(...)
|
||||
|
||||
#define MAX_FREQ_T210 1600000
|
||||
//#define OVERCLOCK_FREQ 1862400
|
||||
//#define OVERCLOCK_VOLTAGE 1200000 // Default is 1100mV and in HOS 1125mV.
|
||||
|
||||
bool train_ram_patterns;
|
||||
|
||||
/*
|
||||
@@ -1048,7 +1044,7 @@ static void _usleep(u32 microseconds)
|
||||
;
|
||||
}
|
||||
|
||||
static u32 div_o3(u32 a, u32 b)
|
||||
static u32 _div_o3(u32 a, u32 b)
|
||||
{
|
||||
u32 result = a / b;
|
||||
|
||||
@@ -2564,7 +2560,7 @@ static void _save_train_results(emc_table_t *mtc_table_entry, u32 needs_training
|
||||
}
|
||||
}
|
||||
|
||||
static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 needs_training, u32 selected_clk_src_emc)
|
||||
static u32 _minerva_change_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 needs_training, u32 selected_clk_src_emc)
|
||||
{
|
||||
u32 emc_dbg_o;
|
||||
u32 emc_pin_o;
|
||||
@@ -2788,11 +2784,11 @@ static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_e
|
||||
|
||||
u32 tRPST = (src_emc_entry->emc_mrw >> 7) & 1;
|
||||
|
||||
u32 deltaTWATM = div_o3(7500, src_clock_period);
|
||||
u32 deltaTWATM = _div_o3(7500, src_clock_period);
|
||||
if (deltaTWATM < 8)
|
||||
deltaTWATM = 8;
|
||||
|
||||
u32 tRTM = src_emc_entry->dram_timings.rl + div_o3(3600, src_clock_period) + deltaTWATM + tRPST + nRTP + 1;
|
||||
u32 tRTM = src_emc_entry->dram_timings.rl + _div_o3(3600, src_clock_period) + deltaTWATM + tRPST + nRTP + 1;
|
||||
|
||||
if (tRTM <= src_emc_entry->burst_regs.emc_rp + src_emc_entry->burst_regs.emc_r2p)
|
||||
{
|
||||
@@ -3153,7 +3149,7 @@ static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_e
|
||||
if (!needs_ca_combo_training)
|
||||
{
|
||||
s32 zq_latch_dvfs_wait_time;
|
||||
u32 T_PDEX_timing = div_o3(dst_emc_entry->dram_timings.t_pdex * 1000, dst_clock_period);
|
||||
u32 T_PDEX_timing = _div_o3(dst_emc_entry->dram_timings.t_pdex * 1000, dst_clock_period);
|
||||
|
||||
if (dst_clock_period > 2000)
|
||||
zq_latch_dvfs_wait_time = (s32)tZQCAL_lpddr4_fc_adj - (s32)T_PDEX_timing;
|
||||
@@ -3393,7 +3389,7 @@ static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_e
|
||||
{
|
||||
(void)MC(MC_EMEM_ADR_CFG);
|
||||
emc_dbg_val = EMC(EMC_DBG);
|
||||
EMC(EMC_DBG) |= EMC_DBG_READ_MUX_ACTIVE;
|
||||
EMC(EMC_DBG) |= EMC_DBG_READ_MUX_ASSEMBLY;
|
||||
|
||||
_save_train_results(dst_emc_entry, needs_training, dram_dev_num, channel1_enabled);
|
||||
|
||||
@@ -3472,7 +3468,7 @@ static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_e
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _minerva_train_patterns(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, bool switch_rate, u32 selected_clk_src_emc)
|
||||
static void _minerva_train(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, bool switch_rate, u32 selected_clk_src_emc)
|
||||
{
|
||||
u32 needs_training_num = 0;
|
||||
u32 emc_cfg_dig_dll_val = 0;
|
||||
@@ -3519,7 +3515,7 @@ static void _minerva_train_patterns(emc_table_t *src_emc_entry, emc_table_t *dst
|
||||
|
||||
for (u32 i = 0; needs_training_num > i; i++) // Runs more than once for needs_training CA/QUSE/WR/RD.
|
||||
{
|
||||
_minerva_set_clock(src_emc_entry, dst_emc_entry, needs_training_emc_table[i], selected_clk_src_emc);
|
||||
_minerva_change_clock(src_emc_entry, dst_emc_entry, needs_training_emc_table[i], selected_clk_src_emc);
|
||||
|
||||
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);
|
||||
|
||||
@@ -3555,11 +3551,14 @@ static void _minerva_train_patterns(emc_table_t *src_emc_entry, emc_table_t *dst
|
||||
}
|
||||
|
||||
if (switch_rate)
|
||||
_minerva_set_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);
|
||||
_minerva_change_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);
|
||||
}
|
||||
|
||||
void _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg)
|
||||
{
|
||||
if (!mtc_cfg->current_emc_table)
|
||||
return;
|
||||
|
||||
u32 dram_type = EMC(EMC_FBIO_CFG5) & 3;
|
||||
|
||||
// Only LPDDR chips are supported.
|
||||
@@ -3685,10 +3684,162 @@ u32 _minerva_do_periodic_compensation(emc_table_t *mtc_table_entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 _minerva_set_rate(mtc_config_t *mtc_cfg)
|
||||
static int _minerva_set_ir_boost(mtc_config_t *mtc_cfg)
|
||||
{
|
||||
u32 src_emc_entry_idx = 999;
|
||||
u32 dst_emc_entry_idx = 999;
|
||||
switch (mtc_cfg->train_mode)
|
||||
{
|
||||
case OP_SWITCH:
|
||||
break;
|
||||
case OP_TRAIN:
|
||||
return 4;
|
||||
case OP_TRAIN_SWITCH:
|
||||
break;
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
|
||||
EPRINTFARGS("Requested op %d from %d to %d.", OP_SWITCH, src_rate_khz, dst_rate_khz);
|
||||
|
||||
bool boost = mtc_cfg->rate_to > MTC_INIT_FREQUENCY;
|
||||
|
||||
u32 clk_new = (PLLP_OUT0 << 29u) | 0x188000 | (boost ? 0 : 2);
|
||||
u32 clk_cur = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||
u32 clk_cur_src = clk_cur >> 29u;
|
||||
if (clk_new == clk_cur || clk_cur_src != PLLP_OUT0)
|
||||
return 3;
|
||||
|
||||
// Clear clock change interrupt.
|
||||
EMC(EMC_INTSTATUS) = CLKCHANGE_COMPLETE_INT;
|
||||
|
||||
u32 emc_dbg_o = EMC(EMC_DBG);
|
||||
u32 emc_dbg_c = emc_dbg_o & ~(EMC_DBG_WRITE_MUX_ACTIVE | EMC_DBG_READ_MUX_ASSEMBLY);
|
||||
EMC(EMC_DBG) = emc_dbg_c;
|
||||
(void)EMC(EMC_DBG);
|
||||
|
||||
// Save registers.
|
||||
u32 emc_cfg_o = EMC(EMC_CFG);
|
||||
u32 emc_auto_cal_cfg_o = EMC(EMC_AUTO_CAL_CONFIG);
|
||||
u32 emc_sel_dpd_ctrl_o = EMC(EMC_SEL_DPD_CTRL);
|
||||
u32 emc_cfg_pipe_clk_o = EMC(EMC_CFG_PIPE_CLK);
|
||||
u32 emc_fdpd_ctl_cmd_o = EMC(EMC_FDPD_CTRL_CMD_NO_RAMP);
|
||||
|
||||
EMC(EMC_DBG) = emc_dbg_c | EMC_DBG_WRITE_MUX_ACTIVE;
|
||||
(void)EMC(EMC_DBG);
|
||||
|
||||
// Disable autocal.
|
||||
EMC(EMC_AUTO_CAL_CONFIG) = (emc_auto_cal_cfg_o & 0x7FFFF9FE) | 0x601;
|
||||
(void)EMC(EMC_AUTO_CAL_CONFIG);
|
||||
|
||||
// Disable other power features.
|
||||
EMC(EMC_CFG) = emc_cfg_o & 0xFFFFFFF;
|
||||
EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl_o & 0xFFFFFEC3;
|
||||
EMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o | BIT(0);
|
||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = emc_fdpd_ctl_cmd_o & ~BIT(0);
|
||||
|
||||
EMC(EMC_DBG) = emc_dbg_c;
|
||||
(void)EMC(EMC_DBG);
|
||||
_usleep(5);
|
||||
|
||||
if (boost)
|
||||
{
|
||||
// Program arbiter regs.
|
||||
MC(MC_EMEM_ARB_CFG) = 0x1000003;
|
||||
MC(MC_EMEM_ARB_TIMING_RP) = 1;
|
||||
MC(MC_EMEM_ARB_TIMING_RC) = 6;
|
||||
MC(MC_EMEM_ARB_TIMING_RAS) = 3;
|
||||
MC(MC_EMEM_ARB_TIMING_FAW) = 4;
|
||||
MC(MC_EMEM_ARB_TIMING_RFCPB) = 0xE;
|
||||
MC(MC_EMEM_ARB_DA_COVERS) = 0x30203;
|
||||
MC(MC_EMEM_ARB_MISC0) = 0x73C30507;
|
||||
|
||||
// Program base timings.
|
||||
EMC(EMC_RP) = 8;
|
||||
EMC(EMC_TRPAB) = 9;
|
||||
EMC(EMC_RC) = 25;
|
||||
EMC(EMC_RAS) = 18;
|
||||
EMC(EMC_R2W) = 15;
|
||||
EMC(EMC_RD_RCD) = 8;
|
||||
EMC(EMC_WR_RCD) = 8;
|
||||
EMC(EMC_TFAW) = 17; // 13 on 2133 MHz modules.
|
||||
|
||||
// ZQ calibration.
|
||||
EMC(EMC_ZCAL_WAIT_CNT) = 0xE0198;
|
||||
|
||||
// Set refresh timings.
|
||||
EMC(EMC_RFC) = 115;
|
||||
EMC(EMC_RFCPB) = 58;
|
||||
EMC(EMC_TREFBW) = 0x18DD; // 0x638.
|
||||
EMC(EMC_REFRESH) = 0x181E; // 0x607.
|
||||
EMC(EMC_PRE_REFRESH_REQ_CNT) = 0x607; // 0x181.
|
||||
EMC(EMC_DYN_SELF_REF_CONTROL) = (EMC(EMC_DYN_SELF_REF_CONTROL) & 0xFFFF0000) | 0xD22;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Program arbiter regs.
|
||||
MC(MC_EMEM_ARB_CFG) = 0x8000001;
|
||||
MC(MC_EMEM_ARB_TIMING_RP) = 0;
|
||||
MC(MC_EMEM_ARB_TIMING_RC) = 3;
|
||||
MC(MC_EMEM_ARB_TIMING_RAS) = 1;
|
||||
MC(MC_EMEM_ARB_TIMING_FAW) = 2;
|
||||
MC(MC_EMEM_ARB_TIMING_RFCPB) = 7;
|
||||
MC(MC_EMEM_ARB_DA_COVERS) = 0x30201;
|
||||
MC(MC_EMEM_ARB_MISC0) = 0x72A30504;
|
||||
|
||||
// Program base timings.
|
||||
EMC(EMC_RP) = 4;
|
||||
EMC(EMC_TRPAB) = 5;
|
||||
EMC(EMC_RC) = 13;
|
||||
EMC(EMC_RAS) = 9;
|
||||
EMC(EMC_R2W) = 11;
|
||||
EMC(EMC_RD_RCD) = 6;
|
||||
EMC(EMC_WR_RCD) = 6;
|
||||
EMC(EMC_TFAW) = 9; // 8 on 2133 MHz modules.
|
||||
|
||||
// Program ZQ calibration.
|
||||
EMC(EMC_ZCAL_WAIT_CNT) = 0x900CC;
|
||||
|
||||
// Program refresh timings.
|
||||
EMC(EMC_RFC) = 58;
|
||||
EMC(EMC_RFCPB) = 29;
|
||||
EMC(EMC_TREFBW) = 0x31C;
|
||||
EMC(EMC_REFRESH) = 0x304;
|
||||
EMC(EMC_PRE_REFRESH_REQ_CNT) = 0xC1;
|
||||
EMC(EMC_DYN_SELF_REF_CONTROL) = (EMC(EMC_DYN_SELF_REF_CONTROL) & 0xFFFF0000) | 0x713;
|
||||
}
|
||||
|
||||
// Restore power features and pipe clock.
|
||||
EMC(EMC_CFG) = emc_cfg_o & 0xEFFFFFFF;
|
||||
EMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o;
|
||||
EMC(EMC_DBG) = emc_dbg_o;
|
||||
(void)EMC(EMC_DBG);
|
||||
|
||||
// Do clock change.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_new;
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||
|
||||
// Clock change handshake.
|
||||
_wait_emc_status(EMC_INTSTATUS, CLKCHANGE_COMPLETE_INT, true, 0);
|
||||
|
||||
// Restore regs.
|
||||
EMC(EMC_CFG) = emc_cfg_o;
|
||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = emc_fdpd_ctl_cmd_o;
|
||||
EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl_o;
|
||||
EMC(EMC_AUTO_CAL_CONFIG) = emc_auto_cal_cfg_o;
|
||||
|
||||
EMC(EMC_TIMING_CONTROL) = 1;
|
||||
|
||||
// Min 20us before next clock change.
|
||||
_usleep(20);
|
||||
|
||||
mtc_cfg->rate_from = mtc_cfg->rate_to;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 _minerva_do_training_switch(mtc_config_t *mtc_cfg)
|
||||
{
|
||||
u32 src_emc_entry_idx = 100;
|
||||
u32 dst_emc_entry_idx = 100;
|
||||
u32 selected_clk_src_emc;
|
||||
u32 emc_clk_src;
|
||||
bool freq_changed = false;
|
||||
@@ -3696,22 +3847,25 @@ static u32 _minerva_set_rate(mtc_config_t *mtc_cfg)
|
||||
emc_table_t *src_emc_entry;
|
||||
emc_table_t *dst_emc_entry;
|
||||
|
||||
if (mtc_cfg->table_entries > 900)
|
||||
if (mtc_cfg->table_entries > 32)
|
||||
return 4;
|
||||
|
||||
if (mtc_cfg->mtc_table[0].rev == MTC_IRB_MAGIC)
|
||||
return _minerva_set_ir_boost(mtc_cfg);
|
||||
|
||||
// Find tables.
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
u32 table_entry_rate = mtc_cfg->mtc_table[i].rate_khz;
|
||||
if (mtc_cfg->rate_from == table_entry_rate)
|
||||
src_emc_entry_idx = i;
|
||||
if (mtc_cfg->rate_to == table_entry_rate)
|
||||
if (mtc_cfg->rate_to == table_entry_rate)
|
||||
dst_emc_entry_idx = i;
|
||||
}
|
||||
|
||||
if (src_emc_entry_idx >= mtc_cfg->table_entries)
|
||||
return 4;
|
||||
|
||||
if (dst_emc_entry_idx >= mtc_cfg->table_entries)
|
||||
// Check if tables were found.
|
||||
if (src_emc_entry_idx >= mtc_cfg->table_entries ||
|
||||
dst_emc_entry_idx >= mtc_cfg->table_entries)
|
||||
return 4;
|
||||
|
||||
src_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[src_emc_entry_idx];
|
||||
@@ -3759,17 +3913,17 @@ static u32 _minerva_set_rate(mtc_config_t *mtc_cfg)
|
||||
switch (mtc_cfg->train_mode)
|
||||
{
|
||||
case OP_SWITCH:
|
||||
_minerva_set_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);
|
||||
_minerva_change_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);
|
||||
mtc_cfg->current_emc_table = dst_emc_entry;
|
||||
mtc_cfg->rate_from = dst_emc_entry->rate_khz;
|
||||
if (dst_emc_entry->periodic_training)
|
||||
_minerva_do_periodic_compensation(dst_emc_entry);
|
||||
return 0;
|
||||
case OP_TRAIN:
|
||||
_minerva_train_patterns(src_emc_entry, dst_emc_entry, false, selected_clk_src_emc);
|
||||
_minerva_train(src_emc_entry, dst_emc_entry, false, selected_clk_src_emc);
|
||||
return 0;
|
||||
case OP_TRAIN_SWITCH:
|
||||
_minerva_train_patterns(src_emc_entry, dst_emc_entry, true, selected_clk_src_emc);
|
||||
_minerva_train(src_emc_entry, dst_emc_entry, true, selected_clk_src_emc);
|
||||
mtc_cfg->current_emc_table = dst_emc_entry;
|
||||
mtc_cfg->rate_from = dst_emc_entry->rate_khz;
|
||||
if (dst_emc_entry->periodic_training)
|
||||
@@ -3782,71 +3936,75 @@ static u32 _minerva_set_rate(mtc_config_t *mtc_cfg)
|
||||
|
||||
static void _minerva_get_table(mtc_config_t *mtc_cfg)
|
||||
{
|
||||
u32 hidrev = APB_MISC(APB_MISC_GP_HIDREV);
|
||||
u32 chip_id = (hidrev >> 8) & 0xFF;
|
||||
u32 major = (hidrev >> 4) & 0xF;
|
||||
|
||||
// Check that SoC is T210/T210B01.
|
||||
if (chip_id != HIDREV_CHIPID_T210)
|
||||
goto error;
|
||||
|
||||
// Check if SoC SKU is ODIN.
|
||||
if (FUSE(FUSE_SKU_INFO) != SKU_ODIN)
|
||||
goto error;
|
||||
|
||||
// Clear table storage.
|
||||
memcpy(mtc_cfg->mtc_table, DVFS_T21X_CC_VERSION, sizeof(DVFS_T21X_CC_VERSION));
|
||||
memcpy(mtc_cfg->mtc_table, DVFS_T210_CC_VERSION, sizeof(DVFS_T210_CC_VERSION));
|
||||
memset(mtc_cfg->mtc_table, 0, EMC_TABLE_ENTRY_SIZE_R7 * 10);
|
||||
|
||||
// Check if init rate boost mode.
|
||||
if (mtc_cfg->init_done == MTC_IRB_MAGIC)
|
||||
{
|
||||
mtc_cfg->mtc_table[0].rev = MTC_IRB_MAGIC;
|
||||
mtc_cfg->table_entries = 1; // Avoid OOB.
|
||||
|
||||
goto init_cfg;
|
||||
}
|
||||
|
||||
// Check if ODINX02.
|
||||
if (major != HIDREV_MAJOR_T210)
|
||||
goto error;
|
||||
|
||||
// ODINX02 table: 204, 408, 666, 800, 1066, 1333, 1600 MHz.
|
||||
mtc_cfg->table_entries = EMC_TABLE_SIZE_ODINX02_R7 / EMC_TABLE_ENTRY_SIZE_R7;
|
||||
|
||||
switch (mtc_cfg->sdram_id)
|
||||
{
|
||||
case DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN:
|
||||
memcpy(mtc_cfg->mtc_table, nx_abca2_2_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_R7);
|
||||
memcpy(mtc_cfg->mtc_table, odinx02_a2_2_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_ODINX02_R7);
|
||||
break;
|
||||
case DRAM_8GB_SAMSUNG_K4FBE3D4HM_MGXX:
|
||||
memcpy(mtc_cfg->mtc_table, odinx02_a2_7_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_ODINX02_R7);
|
||||
break;
|
||||
case DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH:
|
||||
case DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT:
|
||||
case DRAM_4GB_COPPER_SAMSUNG:
|
||||
case DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH:
|
||||
case DRAM_8GB_SAMSUNG_K4FBE3D4HM_MGXX:
|
||||
default:
|
||||
memcpy(mtc_cfg->mtc_table, nx_abca2_0_3_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_R7);
|
||||
if (mtc_cfg->sdram_id == DRAM_8GB_SAMSUNG_K4FBE3D4HM_MGXX)
|
||||
{
|
||||
for (u32 i = 0; i < EMC_TABLE_SIZE_R7 / EMC_TABLE_ENTRY_SIZE_R7; i++)
|
||||
{
|
||||
emc_table_t *table = &mtc_cfg->mtc_table[i];
|
||||
u32 period = 1000000000 / table->rate_khz;
|
||||
|
||||
table->burst_regs.emc_rfc = 280000 / period;
|
||||
table->shadow_regs_ca_train.emc_rfc = 280000 / period;
|
||||
table->shadow_regs_quse_train.emc_rfc = 280000 / period;
|
||||
table->shadow_regs_rdwr_train.emc_rfc = 280000 / period;
|
||||
|
||||
table->burst_regs.emc_rfcpb = 140000 / period;
|
||||
table->shadow_regs_ca_train.emc_rfcpb = 140000 / period;
|
||||
table->shadow_regs_quse_train.emc_rfcpb = 140000 / period;
|
||||
table->shadow_regs_rdwr_train.emc_rfcpb = 140000 / period;
|
||||
|
||||
table->burst_regs.emc_txsr = 287500 / period;
|
||||
table->shadow_regs_ca_train.emc_txsr = 287500 / period;
|
||||
table->shadow_regs_quse_train.emc_txsr = 287500 / period;
|
||||
table->shadow_regs_rdwr_train.emc_txsr = 287500 / period;
|
||||
|
||||
table->burst_regs.emc_txsrdll = table->burst_regs.emc_txsr;
|
||||
table->shadow_regs_ca_train.emc_txsrdll = table->shadow_regs_ca_train.emc_txsr;
|
||||
table->shadow_regs_quse_train.emc_txsrdll = table->shadow_regs_quse_train.emc_txsr;
|
||||
table->shadow_regs_rdwr_train.emc_txsrdll = table->shadow_regs_rdwr_train.emc_txsr;
|
||||
|
||||
table->burst_regs.emc_dyn_self_ref_control &= 0x7FFFFFFF;
|
||||
table->shadow_regs_ca_train.emc_dyn_self_ref_control &= 0x7FFFFFFF;
|
||||
table->shadow_regs_quse_train.emc_dyn_self_ref_control &= 0x7FFFFFFF;
|
||||
table->shadow_regs_rdwr_train.emc_dyn_self_ref_control &= 0x7FFFFFFF;
|
||||
|
||||
table->dram_timings.t_rfc = 280;
|
||||
}
|
||||
}
|
||||
memcpy(mtc_cfg->mtc_table, odinx02_a2_0_3_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_ODINX02_R7);
|
||||
break;
|
||||
}
|
||||
|
||||
mtc_cfg->table_entries = EMC_TABLE_SIZE_R7 / EMC_TABLE_ENTRY_SIZE_R7;
|
||||
init_cfg:
|
||||
mtc_cfg->rate_to = 0;
|
||||
mtc_cfg->rate_from = 0;
|
||||
mtc_cfg->train_mode = 0;
|
||||
mtc_cfg->train_mode = -1;
|
||||
mtc_cfg->prev_temp = 0;
|
||||
mtc_cfg->current_emc_table = NULL;
|
||||
|
||||
// Important!
|
||||
mtc_cfg->train_ram_patterns = true;
|
||||
mtc_cfg->init_done = MTC_INIT_MAGIC;
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
mtc_cfg->init_done = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void _minerva_init(mtc_config_t *mtc_cfg, bdkParams_t bp)
|
||||
void minerva_entry(mtc_config_t *mtc_cfg, bdkParams_t bp)
|
||||
{
|
||||
EPRINTF("-- Minerva Training Cell --");
|
||||
|
||||
@@ -3854,42 +4012,26 @@ void _minerva_init(mtc_config_t *mtc_cfg, bdkParams_t bp)
|
||||
|
||||
if (mtc_cfg->init_done != MTC_INIT_MAGIC)
|
||||
{
|
||||
if (mtc_cfg->init_done == MTC_NEW_MAGIC)
|
||||
{
|
||||
if (mtc_cfg->init_done == MTC_NEW_MAGIC ||
|
||||
mtc_cfg->init_done == MTC_IRB_MAGIC)
|
||||
_minerva_get_table(mtc_cfg);
|
||||
#ifdef OVERCLOCK_VOLTAGE
|
||||
// Set SD1 regulator voltage.
|
||||
if ((bp->extension_magic & 0xF0FFFFFF) == IANOS_EXT0)
|
||||
bp->reg_voltage_set(1, OVERCLOCK_VOLTAGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef OVERCLOCK_FREQ
|
||||
// Change max rate in table.
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz = OVERCLOCK_FREQ;
|
||||
|
||||
// Change rates for OC RAM.
|
||||
if (mtc_cfg->rate_from == MAX_FREQ_T210)
|
||||
mtc_cfg->rate_from = OVERCLOCK_FREQ;
|
||||
if (mtc_cfg->rate_to == MAX_FREQ_T210)
|
||||
mtc_cfg->rate_to = OVERCLOCK_FREQ;
|
||||
#endif
|
||||
|
||||
switch (mtc_cfg->train_mode)
|
||||
{
|
||||
case OP_SWITCH:
|
||||
EPRINTF("Switching..");
|
||||
_minerva_set_rate(mtc_cfg);
|
||||
_minerva_do_training_switch(mtc_cfg);
|
||||
break;
|
||||
case OP_TRAIN:
|
||||
EPRINTF("Training..");
|
||||
_minerva_set_rate(mtc_cfg);
|
||||
_minerva_do_training_switch(mtc_cfg);
|
||||
break;
|
||||
case OP_TRAIN_SWITCH:
|
||||
EPRINTF("Training and switching..");
|
||||
_minerva_set_rate(mtc_cfg);
|
||||
_minerva_do_training_switch(mtc_cfg);
|
||||
break;
|
||||
case OP_PERIODIC_TRAIN:
|
||||
EPRINTF("Periodic training..");
|
||||
@@ -3901,13 +4043,5 @@ void _minerva_init(mtc_config_t *mtc_cfg, bdkParams_t bp)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef OVERCLOCK_FREQ
|
||||
// Restore rates for OC RAM.
|
||||
if (mtc_cfg->rate_from == OVERCLOCK_FREQ)
|
||||
mtc_cfg->rate_from = MAX_FREQ_T210;
|
||||
if (mtc_cfg->rate_to == OVERCLOCK_FREQ)
|
||||
mtc_cfg->rate_to = MAX_FREQ_T210;
|
||||
#endif
|
||||
|
||||
mtc_cfg->train_ram_patterns = train_ram_patterns;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user