Path: blob/master/modules/hekate_libsys_minerva/sys_sdrammtc.c
1476 views
/*1* Minerva Training Cell2* DRAM Training for Tegra X1 SoC. Supports LPDDR4.3*4* Copyright (c) 2018-2022 CTCaer <[email protected]>5*6* This program is free software; you can redistribute it and/or modify it7* under the terms and conditions of the GNU General Public License,8* version 2, as published by the Free Software Foundation.9*10* This program is distributed in the hope it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for13* more details.14*15* You should have received a copy of the GNU General Public License16* along with this program. If not, see <http://www.gnu.org/licenses/>.17*/1819#include <string.h>20#include <stdlib.h>21#include "mtc.h"22#include "mtc_mc_emc_regs.h"23#include "mtc_switch_tables.h"24#include "types.h"25#include <module.h>2627#define EPRINTF(...)28#define EPRINTFARGS(...)2930#define MAX_FREQ_T210 160000031//#define OVERCLOCK_FREQ 186240032//#define OVERCLOCK_VOLTAGE 1200000 // Default is 1100mV and in HOS 1125mV.3334#define PERF_HACK3536bool train_ram_patterns;3738/*39* REF: PLL Input reference (OSC_FREQ).40* DIVN: PLL feedback divider.41* DIVM: PLL input divider.42* DIVP: PLL post divider.43* PLL_OUT = (REF / DIVM) * DIVN / DIVP44*45* DIVP | DIVP46* Encoded | Real47* ----------------------48* 0 | 1 (DIVP off)49* 1 | 250* 2 | 351* 3 | 452* 4 | 553* 5 | 654* 6 | 855* 7 | 1056* 8 | 1257* 9 | 1658* 10 | 1259* 11 | 1660* 12 | 2061* 13 | 2462* 14 | 3263*/64static pllm_clk_config_t pllm_clk_config_table[] =65{66// pll_osc_in, pll_out, pll_feedback_div, pll_input_div, pll_post_div.67// f_in, f_out, n, m, p.68// f_out = ((f_in / m) * n) / p. Example: 1600000 = (38400 / 2) * 97.69{38400, 297600, 93, 4, 2},70{38400, 400000, 125, 4, 2},71{38400, 408000, 85, 4, 1},72{38400, 532800, 111, 4, 1},73{38400, 665600, 104, 3, 1},74{38400, 800000, 125, 3, 1},75{38400, 931200, 97, 4, 0},76{38400, 1065600, 111, 4, 0},77{38400, 1200000, 125, 4, 0},78{38400, 1331200, 104, 3, 0},79{38400, 1459200, 76, 2, 0},80{38400, 1600000, 125, 3, 0},81{38400, 1728000, 90, 2, 0}, // Custom. Normalized 1733 MHz.82{38400, 1795200, 187, 4, 0}, // Custom. Normalized 1800 MHz.83{38400, 1862400, 97, 2, 0}, // JEDEC Standard. (T210 official max).84{38400, 1894400, 148, 3, 0}, // Custom. Normalized 1900 MHz.85{38400, 1932800, 151, 3, 0}, // Custom. Normalized 1933 MHz.86{38400, 1958400, 102, 2, 0}, // Custom. Normalized 1966 MHz.87{38400, 1996800, 104, 2, 0}, // Custom. Normalized 2000 MHz.88{38400, 2035200, 106, 2, 0}, // Custom. Normalized 2033 MHz.89{38400, 2064000, 215, 4, 0}, // Custom. Normalized 2066 MHz.90{38400, 2099200, 164, 3, 0}, // Custom. Normalized 2100 MHz.91{38400, 2131200, 111, 2, 0}, // JEDEC Standard. (T210B01 official max).92{38400, 2163200, 169, 3, 0}, // Custom. Normalized 2166 MHz.93{38400, 2188800, 114, 2, 0}, // Custom. Normalized 2200 MHz.94{38400, 2227200, 116, 2, 0}, // Custom. Normalized 2233 MHz.95{38400, 2265600, 118, 2, 0}, // Custom. Normalized 2266 MHz.96{38400, 2291200, 179, 3, 0}, // Custom. Normalized 2300 MHz.97{38400, 2329600, 182, 3, 0}, // Custom. Normalized 2333 MHz.98{38400, 2361600, 123, 2, 0}, // Custom. Normalized 2366 MHz.99{0, 0, 0, 0, 0}100};101102static const u32 burst_regs_emc_addr_table[221] = {103EMC_RC,104EMC_RFC,105EMC_RFCPB,106EMC_REFCTRL2,107EMC_RFC_SLR,108EMC_RAS,109EMC_RP,110EMC_R2W,111EMC_W2R,112EMC_R2P,113EMC_W2P,114EMC_R2R,115EMC_TPPD,116EMC_CCDMW,117EMC_RD_RCD,118EMC_WR_RCD,119EMC_RRD,120EMC_REXT,121EMC_WEXT,122EMC_WDV_CHK,123EMC_WDV,124EMC_WSV,125EMC_WEV,126EMC_WDV_MASK,127EMC_WS_DURATION,128EMC_WE_DURATION,129EMC_QUSE,130EMC_QUSE_WIDTH,131EMC_IBDLY,132EMC_OBDLY,133EMC_EINPUT,134EMC_MRW6,135EMC_EINPUT_DURATION,136EMC_PUTERM_EXTRA,137EMC_PUTERM_WIDTH,138EMC_QRST,139EMC_QSAFE,140EMC_RDV,141EMC_RDV_MASK,142EMC_RDV_EARLY,143EMC_RDV_EARLY_MASK,144EMC_REFRESH,145EMC_BURST_REFRESH_NUM,146EMC_PRE_REFRESH_REQ_CNT,147EMC_PDEX2WR,148EMC_PDEX2RD,149EMC_PCHG2PDEN,150EMC_ACT2PDEN,151EMC_AR2PDEN,152EMC_RW2PDEN,153EMC_CKE2PDEN,154EMC_PDEX2CKE,155EMC_PDEX2MRR,156EMC_TXSR,157EMC_TXSRDLL,158EMC_TCKE,159EMC_TCKESR,160EMC_TPD,161EMC_TFAW,162EMC_TRPAB,163EMC_TCLKSTABLE,164EMC_TCLKSTOP,165EMC_MRW7,166EMC_TREFBW,167EMC_ODT_WRITE,168EMC_FBIO_CFG5,169EMC_FBIO_CFG7,170EMC_CFG_DIG_DLL,171EMC_CFG_DIG_DLL_PERIOD,172EMC_PMACRO_IB_RXRT,173EMC_CFG_PIPE_1,174EMC_CFG_PIPE_2,175EMC_PMACRO_QUSE_DDLL_RANK0_4,176EMC_PMACRO_QUSE_DDLL_RANK0_5,177EMC_PMACRO_QUSE_DDLL_RANK1_4,178EMC_PMACRO_QUSE_DDLL_RANK1_5,179EMC_MRW8,180EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4,181EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5,182EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0,183EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1,184EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2,185EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3,186EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4,187EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5,188EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0,189EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1,190EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2,191EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3,192EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4,193EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5,194EMC_PMACRO_DDLL_LONG_CMD_0,195EMC_PMACRO_DDLL_LONG_CMD_1,196EMC_PMACRO_DDLL_LONG_CMD_2,197EMC_PMACRO_DDLL_LONG_CMD_3,198EMC_PMACRO_DDLL_LONG_CMD_4,199EMC_PMACRO_DDLL_SHORT_CMD_0,200EMC_PMACRO_DDLL_SHORT_CMD_1,201EMC_PMACRO_DDLL_SHORT_CMD_2,202EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3,203EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3,204EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3,205EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3,206EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3,207EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3,208EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3,209EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3,210EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3,211EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3,212EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3,213EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3,214EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3,215EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3,216EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3,217EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3,218EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3,219EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3,220EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3,221EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3,222EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0,223EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1,224EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2,225EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3,226EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0,227EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1,228EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2,229EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3,230EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0,231EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1,232EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2,233EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3,234EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0,235EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1,236EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2,237EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3,238EMC_TXDSRVTTGEN,239EMC_FDPD_CTRL_DQ,240EMC_FDPD_CTRL_CMD,241EMC_FBIO_SPARE,242EMC_ZCAL_INTERVAL,243EMC_ZCAL_WAIT_CNT,244EMC_MRS_WAIT_CNT,245EMC_MRS_WAIT_CNT2,246EMC_AUTO_CAL_CHANNEL,247EMC_DLL_CFG_0,248EMC_DLL_CFG_1,249EMC_PMACRO_AUTOCAL_CFG_COMMON,250EMC_PMACRO_ZCTRL,251EMC_CFG,252EMC_CFG_PIPE,253EMC_DYN_SELF_REF_CONTROL,254EMC_QPOP,255EMC_DQS_BRLSHFT_0,256EMC_DQS_BRLSHFT_1,257EMC_CMD_BRLSHFT_2,258EMC_CMD_BRLSHFT_3,259EMC_PMACRO_PAD_CFG_CTRL,260EMC_PMACRO_DATA_PAD_RX_CTRL,261EMC_PMACRO_CMD_PAD_RX_CTRL,262EMC_PMACRO_DATA_RX_TERM_MODE,263EMC_PMACRO_CMD_RX_TERM_MODE,264EMC_PMACRO_CMD_PAD_TX_CTRL,265EMC_PMACRO_DATA_PAD_TX_CTRL,266EMC_PMACRO_COMMON_PAD_TX_CTRL,267EMC_PMACRO_VTTGEN_CTRL_0,268EMC_PMACRO_VTTGEN_CTRL_1,269EMC_PMACRO_VTTGEN_CTRL_2,270EMC_PMACRO_BRICK_CTRL_RFU1,271EMC_PMACRO_CMD_BRICK_CTRL_FDPD,272EMC_PMACRO_BRICK_CTRL_RFU2,273EMC_PMACRO_DATA_BRICK_CTRL_FDPD,274EMC_PMACRO_BG_BIAS_CTRL_0,275EMC_CFG_3,276EMC_PMACRO_TX_PWRD_0,277EMC_PMACRO_TX_PWRD_1,278EMC_PMACRO_TX_PWRD_2,279EMC_PMACRO_TX_PWRD_3,280EMC_PMACRO_TX_PWRD_4,281EMC_PMACRO_TX_PWRD_5,282EMC_CONFIG_SAMPLE_DELAY,283EMC_PMACRO_TX_SEL_CLK_SRC_0,284EMC_PMACRO_TX_SEL_CLK_SRC_1,285EMC_PMACRO_TX_SEL_CLK_SRC_2,286EMC_PMACRO_TX_SEL_CLK_SRC_3,287EMC_PMACRO_TX_SEL_CLK_SRC_4,288EMC_PMACRO_TX_SEL_CLK_SRC_5,289EMC_PMACRO_DDLL_BYPASS,290EMC_PMACRO_DDLL_PWRD_0,291EMC_PMACRO_DDLL_PWRD_1,292EMC_PMACRO_DDLL_PWRD_2,293EMC_PMACRO_CMD_CTRL_0,294EMC_PMACRO_CMD_CTRL_1,295EMC_PMACRO_CMD_CTRL_2,296EMC_TR_TIMING_0,297EMC_TR_DVFS,298EMC_TR_CTRL_1,299EMC_TR_RDV,300EMC_TR_QPOP,301EMC_TR_RDV_MASK,302EMC_MRW14,303EMC_TR_QSAFE,304EMC_TR_QRST,305EMC_TRAINING_CTRL,306EMC_TRAINING_SETTLE,307EMC_TRAINING_VREF_SETTLE,308EMC_TRAINING_CA_FINE_CTRL,309EMC_TRAINING_CA_CTRL_MISC,310EMC_TRAINING_CA_CTRL_MISC1,311EMC_TRAINING_CA_VREF_CTRL,312EMC_TRAINING_QUSE_CORS_CTRL,313EMC_TRAINING_QUSE_FINE_CTRL,314EMC_TRAINING_QUSE_CTRL_MISC,315EMC_TRAINING_QUSE_VREF_CTRL,316EMC_TRAINING_READ_FINE_CTRL,317EMC_TRAINING_READ_CTRL_MISC,318EMC_TRAINING_READ_VREF_CTRL,319EMC_TRAINING_WRITE_FINE_CTRL,320EMC_TRAINING_WRITE_CTRL_MISC,321EMC_TRAINING_WRITE_VREF_CTRL,322EMC_TRAINING_MPC,323EMC_MRW15324};325326static const u32 burst_reg_per_ch_emc01_addr_table[8] = {327EMC0_MRW10,328EMC1_MRW10,329EMC0_MRW11,330EMC1_MRW11,331EMC0_MRW12,332EMC1_MRW12,333EMC0_MRW13,334EMC1_MRW13335};336337static const u32 vref_perch_regs_emc01_addr_table[4] = {338EMC0_TRAINING_OPT_DQS_IB_VREF_RANK0,339EMC1_TRAINING_OPT_DQS_IB_VREF_RANK0,340EMC0_TRAINING_OPT_DQS_IB_VREF_RANK1,341EMC1_TRAINING_OPT_DQS_IB_VREF_RANK1342};343344static const u32 training_mod_regs_emc01_addr_table[20] = {345EMC0_TRAINING_RW_OFFSET_IB_BYTE0,346EMC1_TRAINING_RW_OFFSET_IB_BYTE0,347EMC0_TRAINING_RW_OFFSET_IB_BYTE1,348EMC1_TRAINING_RW_OFFSET_IB_BYTE1,349EMC0_TRAINING_RW_OFFSET_IB_BYTE2,350EMC1_TRAINING_RW_OFFSET_IB_BYTE2,351EMC0_TRAINING_RW_OFFSET_IB_BYTE3,352EMC1_TRAINING_RW_OFFSET_IB_BYTE3,353EMC0_TRAINING_RW_OFFSET_IB_MISC,354EMC1_TRAINING_RW_OFFSET_IB_MISC,355EMC0_TRAINING_RW_OFFSET_OB_BYTE0,356EMC1_TRAINING_RW_OFFSET_OB_BYTE0,357EMC0_TRAINING_RW_OFFSET_OB_BYTE1,358EMC1_TRAINING_RW_OFFSET_OB_BYTE1,359EMC0_TRAINING_RW_OFFSET_OB_BYTE2,360EMC1_TRAINING_RW_OFFSET_OB_BYTE2,361EMC0_TRAINING_RW_OFFSET_OB_BYTE3,362EMC1_TRAINING_RW_OFFSET_OB_BYTE3,363EMC0_TRAINING_RW_OFFSET_OB_MISC,364EMC1_TRAINING_RW_OFFSET_OB_MISC365};366367static const u32 trim_regs_emc_addr_table[138] = {368EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0,369EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1,370EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2,371EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3,372EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0,373EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1,374EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2,375EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3,376EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0,377EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1,378EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2,379EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0,380EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1,381EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2,382EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0,383EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1,384EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2,385EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0,386EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1,387EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2,388EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0,389EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1,390EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2,391EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0,392EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1,393EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2,394EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0,395EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1,396EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2,397EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0,398EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1,399EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2,400EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0,401EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1,402EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2,403EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0,404EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1,405EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2,406EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0,407EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1,408EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2,409EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0,410EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1,411EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2,412EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0,413EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1,414EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2,415EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0,416EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1,417EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2,418EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0,419EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1,420EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2,421EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0,422EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1,423EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2,424EMC_PMACRO_IB_VREF_DQS_0,425EMC_PMACRO_IB_VREF_DQS_1,426EMC_PMACRO_IB_VREF_DQ_0,427EMC_PMACRO_IB_VREF_DQ_1,428EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,429EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,430EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2,431EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3,432EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4,433EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5,434EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0,435EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1,436EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2,437EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3,438EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0,439EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1,440EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2,441EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0,442EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1,443EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2,444EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0,445EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1,446EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2,447EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0,448EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1,449EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2,450EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0,451EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1,452EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2,453EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0,454EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1,455EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2,456EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0,457EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1,458EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2,459EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0,460EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1,461EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2,462EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0,463EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1,464EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2,465EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0,466EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1,467EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2,468EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0,469EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1,470EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2,471EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0,472EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1,473EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2,474EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0,475EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1,476EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2,477EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0,478EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1,479EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2,480EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0,481EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1,482EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2,483EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0,484EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1,485EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2,486EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0,487EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1,488EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2,489EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0,490EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1,491EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2,492EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0,493EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1,494EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2,495EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0,496EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1,497EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2,498EMC_PMACRO_QUSE_DDLL_RANK0_0,499EMC_PMACRO_QUSE_DDLL_RANK0_1,500EMC_PMACRO_QUSE_DDLL_RANK0_2,501EMC_PMACRO_QUSE_DDLL_RANK0_3,502EMC_PMACRO_QUSE_DDLL_RANK1_0,503EMC_PMACRO_QUSE_DDLL_RANK1_1,504EMC_PMACRO_QUSE_DDLL_RANK1_2,505EMC_PMACRO_QUSE_DDLL_RANK1_3506};507508static const u32 trim_perch_regs_emc01_addr_table[10] = {509EMC0_CMD_BRLSHFT_0,510EMC1_CMD_BRLSHFT_1,511EMC0_DATA_BRLSHFT_0,512EMC1_DATA_BRLSHFT_0,513EMC0_DATA_BRLSHFT_1,514EMC1_DATA_BRLSHFT_1,515EMC0_QUSE_BRLSHFT_0,516EMC1_QUSE_BRLSHFT_1,517EMC0_QUSE_BRLSHFT_2,518EMC1_QUSE_BRLSHFT_3519};520521static const u32 burst_mc_regs_addr_table[33] = {522MC_EMEM_ARB_CFG,523MC_EMEM_ARB_OUTSTANDING_REQ,524MC_EMEM_ARB_REFPB_HP_CTRL,525MC_EMEM_ARB_REFPB_BANK_CTRL,526MC_EMEM_ARB_TIMING_RCD,527MC_EMEM_ARB_TIMING_RP,528MC_EMEM_ARB_TIMING_RC,529MC_EMEM_ARB_TIMING_RAS,530MC_EMEM_ARB_TIMING_FAW,531MC_EMEM_ARB_TIMING_RRD,532MC_EMEM_ARB_TIMING_RAP2PRE,533MC_EMEM_ARB_TIMING_WAP2PRE,534MC_EMEM_ARB_TIMING_R2R,535MC_EMEM_ARB_TIMING_W2W,536MC_EMEM_ARB_TIMING_R2W,537MC_EMEM_ARB_TIMING_CCDMW,538MC_EMEM_ARB_TIMING_W2R,539MC_EMEM_ARB_TIMING_RFCPB,540MC_EMEM_ARB_DA_TURNS,541MC_EMEM_ARB_DA_COVERS,542MC_EMEM_ARB_MISC0,543MC_EMEM_ARB_MISC1,544MC_EMEM_ARB_MISC2,545MC_EMEM_ARB_RING1_THROTTLE,546MC_EMEM_ARB_DHYST_CTRL,547MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0,548MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1,549MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2,550MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3,551MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4,552MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5,553MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6,554MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7555};556557static const u32 la_scale_regs_mc_addr_table[24] = {558MC_MLL_MPCORER_PTSA_RATE,559MC_FTOP_PTSA_RATE,560MC_PTSA_GRANT_DECREMENT,561MC_LATENCY_ALLOWANCE_XUSB_0,562MC_LATENCY_ALLOWANCE_XUSB_1,563MC_LATENCY_ALLOWANCE_TSEC_0,564MC_LATENCY_ALLOWANCE_SDMMCA_0,565MC_LATENCY_ALLOWANCE_SDMMCAA_0,566MC_LATENCY_ALLOWANCE_SDMMC_0,567MC_LATENCY_ALLOWANCE_SDMMCAB_0,568MC_LATENCY_ALLOWANCE_PPCS_0,569MC_LATENCY_ALLOWANCE_PPCS_1,570MC_LATENCY_ALLOWANCE_MPCORE_0,571MC_LATENCY_ALLOWANCE_HC_0,572MC_LATENCY_ALLOWANCE_HC_1,573MC_LATENCY_ALLOWANCE_AVPC_0,574MC_LATENCY_ALLOWANCE_GPU_0,575MC_LATENCY_ALLOWANCE_GPU2_0,576MC_LATENCY_ALLOWANCE_NVENC_0,577MC_LATENCY_ALLOWANCE_NVDEC_0,578MC_LATENCY_ALLOWANCE_VIC_0,579MC_LATENCY_ALLOWANCE_VI2_0,580MC_LATENCY_ALLOWANCE_ISP2_0,581MC_LATENCY_ALLOWANCE_ISP2_1582};583584static const u32 periodic_training_addr[10] =585{586EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,587EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,588EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2,589EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3,590EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0,591EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1,592EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2,593EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3,594EMC_DATA_BRLSHFT_0,595EMC_DATA_BRLSHFT_1596};597598static const u32 ram_pattern_dq_table[0x500] = {599/* DQ RAM Patterns Table 0 */6000x18181818, 0x61616161, 0x85858585, 0x14141414, 0x51515151,6010x47474747, 0x1E1E1E1E, 0x79797979, 0xE5E5E5E5, 0x94949494,6020x51515151, 0x46464646, 0x19191919, 0x67676767, 0x9C9C9C9C,6030x71717171, 0xC5C5C5C5, 0x17171717, 0x5F5F5F5F, 0x7E7E7E7E,6040xFBFBFBFB, 0xEDEDEDED, 0xB4B4B4B4, 0xD2D2D2D2, 0x48484848,6050x21212121, 0x85858585, 0x16161616, 0x59595959, 0x66666666,6060x9A9A9A9A, 0x69696969, 0xA4A4A4A4, 0x93939393, 0x4F4F4F4F,6070x3F3F3F3F, 0xFCFCFCFC, 0xF3F3F3F3, 0xCDCDCDCD, 0x37373737,6080xDCDCDCDC, 0x70707070, 0xC3C3C3C3, 0x0F0F0F0F, 0x3E3E3E3E,6090xFAFAFAFA, 0xEBEBEBEB, 0xACACACAC, 0xB3B3B3B3, 0xCCCCCCCC,6100x31313131, 0xC5C5C5C5, 0x15151515, 0x57575757, 0x5F5F5F5F,6110x7F7F7F7F, 0xFDFDFDFD, 0xF4F4F4F4, 0xD0D0D0D0, 0x42424242,6120x08080808, 0x23232323, 0x8F8F8F8F, 0x3F3F3F3F, 0x18181818,6130x61616161, 0x85858585, 0x14141414, 0x51515151, 0x47474747,6140x1E1E1E1E, 0x79797979, 0xE5E5E5E5, 0x94949494, 0x51515151,6150x46464646, 0x19191919, 0x67676767, 0x9C9C9C9C, 0x71717171,6160xC5C5C5C5, 0x17171717, 0x5F5F5F5F, 0x7E7E7E7E, 0xFBFBFBFB,6170xEDEDEDED, 0xB4B4B4B4, 0xD2D2D2D2, 0x48484848, 0x21212121,6180x85858585, 0x16161616, 0x59595959, 0x66666666, 0x9A9A9A9A,6190x69696969, 0xA4A4A4A4, 0x93939393, 0x4F4F4F4F, 0x3F3F3F3F,6200xFCFCFCFC, 0xF3F3F3F3, 0xCDCDCDCD, 0x37373737, 0xDCDCDCDC,6210x70707070, 0xC3C3C3C3, 0x0F0F0F0F, 0x3E3E3E3E, 0xFAFAFAFA,6220xEBEBEBEB, 0xACACACAC, 0xB3B3B3B3, 0xCCCCCCCC, 0x31313131,6230xC5C5C5C5, 0x15151515, 0x57575757, 0x5F5F5F5F, 0x7F7F7F7F,6240xFDFDFDFD, 0xF4F4F4F4, 0xD0D0D0D0, 0x42424242, 0x08080808,6250x23232323, 0x8F8F8F8F, 0x3F3F3F3F, 0x06060606, 0x18181818,6260x21212121, 0x05050505, 0x14141414, 0x11111111, 0x07070707,6270x1E1E1E1E, 0x39393939, 0x25252525, 0x14141414, 0x11111111,6280x06060606, 0x19191919, 0x27272727, 0x1C1C1C1C, 0x31313131,6290x05050505, 0x17171717, 0x1F1F1F1F, 0x3E3E3E3E, 0x3B3B3B3B,6300x2D2D2D2D, 0x34343434, 0x12121212, 0x08080808, 0x21212121,6310x05050505, 0x16161616, 0x19191919, 0x26262626, 0x1A1A1A1A,6320x29292929, 0x24242424, 0x13131313, 0x0F0F0F0F, 0x3F3F3F3F,6330x3C3C3C3C, 0x33333333, 0x0D0D0D0D, 0x37373737, 0x1C1C1C1C,6340x30303030, 0x03030303, 0x0F0F0F0F, 0x3E3E3E3E, 0x3A3A3A3A,6350x2B2B2B2B, 0x2C2C2C2C, 0x33333333, 0x0C0C0C0C, 0x31313131,6360x05050505, 0x15151515, 0x17171717, 0x1F1F1F1F, 0x3F3F3F3F,6370x3D3D3D3D, 0x34343434, 0x10101010, 0x02020202, 0x08080808,6380x23232323, 0x0F0F0F0F, 0x06060606, 0x18181818, 0x21212121,6390x05050505, 0x14141414, 0x11111111, 0x07070707, 0x1E1E1E1E,6400x39393939, 0x25252525, 0x14141414, 0x11111111, 0x06060606,6410x19191919, 0x27272727, 0x1C1C1C1C, 0x31313131, 0x05050505,6420x17171717, 0x1F1F1F1F, 0x3E3E3E3E, 0x3B3B3B3B, 0x2D2D2D2D,6430x34343434, 0x12121212, 0x08080808, 0x21212121, 0x05050505,6440x16161616, 0x19191919, 0x26262626, 0x1A1A1A1A, 0x29292929,6450x24242424, 0x13131313, 0x0F0F0F0F, 0x3F3F3F3F, 0x3C3C3C3C,6460x33333333, 0x0D0D0D0D, 0x37373737, 0x1C1C1C1C, 0x30303030,6470x03030303, 0x0F0F0F0F, 0x3E3E3E3E, 0x3A3A3A3A, 0x2B2B2B2B,6480x2C2C2C2C, 0x33333333, 0x0C0C0C0C, 0x31313131, 0x05050505,6490x15151515, 0x17171717, 0x1F1F1F1F, 0x3F3F3F3F, 0x3D3D3D3D,6500x34343434, 0x10101010, 0x02020202, 0x08080808, 0x23232323,6510x0F0F0F0F,652653/* DQ RAM Patterns Table 1 */6540x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,6550x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,6560x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,6570x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,6580xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,6590x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,6600xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,6610x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,6620xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,6630xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,6640x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,6650x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,6660x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,6670x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,6680x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,6690x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000,6700xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,6710xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,6720xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,6730x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,6740xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,6750x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF,6760xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,6770xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,6780xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,6790x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,6800x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x00000000,6810x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000,6820x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,6830x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,6840x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F,6850x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000,6860x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F,6870x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,6880x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,6890x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,6900x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,6910x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000,6920x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,6930x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,6940x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000,6950x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,6960x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F,6970x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000,6980x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,6990x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,7000x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7010x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F,7020x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7030x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,7040x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,7050x00000000,706707/* DQ RAM Patterns Table 2 */7080x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7090xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7100x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7110xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7120x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7130xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7140x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7150xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7160x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7170xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7180x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7190xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7200x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7210xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7220x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7230xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7240x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7250xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7260x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7270xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7280x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7290xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7300x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7310xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,7320x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,7330xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x3F3F3F3F,7340x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7350x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7360x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7370x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7380x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7390x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7400x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7410x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7420x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7430x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7440x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7450x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7460x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7470x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7480x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7490x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7500x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7510x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7520x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7530x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7540x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7550x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7560x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7570x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,7580x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,7590x3F3F3F3F,760761/* DQ RAM Patterns Table 3 */7620x80808080, 0x00000000, 0x80808080, 0x00000000, 0x80808080,7630x00000000, 0x80808080, 0x40404040, 0x00000000, 0x40404040,7640x00000000, 0x40404040, 0x00000000, 0x40404040, 0x20202020,7650x00000000, 0x20202020, 0x00000000, 0x20202020, 0x00000000,7660x20202020, 0x10101010, 0x00000000, 0x10101010, 0x00000000,7670x10101010, 0x00000000, 0x10101010, 0x08080808, 0x00000000,7680x08080808, 0x00000000, 0x08080808, 0x00000000, 0x08080808,7690x04040404, 0x00000000, 0x04040404, 0x00000000, 0x04040404,7700x00000000, 0x04040404, 0x02020202, 0x00000000, 0x02020202,7710x00000000, 0x02020202, 0x00000000, 0x02020202, 0x01010101,7720x00000000, 0x01010101, 0x00000000, 0x01010101, 0x00000000,7730x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000,7740x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80808080,7750x00000000, 0x80808080, 0x00000000, 0x80808080, 0x00000000,7760x80808080, 0x40404040, 0x00000000, 0x40404040, 0x00000000,7770x40404040, 0x00000000, 0x40404040, 0x20202020, 0x00000000,7780x20202020, 0x00000000, 0x20202020, 0x00000000, 0x20202020,7790x10101010, 0x00000000, 0x10101010, 0x00000000, 0x10101010,7800x00000000, 0x10101010, 0x08080808, 0x00000000, 0x08080808,7810x00000000, 0x08080808, 0x00000000, 0x08080808, 0x04040404,7820x00000000, 0x04040404, 0x00000000, 0x04040404, 0x00000000,7830x04040404, 0x02020202, 0x00000000, 0x02020202, 0x00000000,7840x02020202, 0x00000000, 0x02020202, 0x01010101, 0x00000000,7850x01010101, 0x00000000, 0x01010101, 0x00000000, 0x01010101,7860x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,7870x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20202020,7880x00000000, 0x20202020, 0x00000000, 0x20202020, 0x00000000,7890x20202020, 0x00000000, 0x20202020, 0x00000000, 0x10101010,7900x00000000, 0x10101010, 0x00000000, 0x10101010, 0x00000000,7910x10101010, 0x00000000, 0x10101010, 0x00000000, 0x08080808,7920x00000000, 0x08080808, 0x00000000, 0x08080808, 0x00000000,7930x08080808, 0x00000000, 0x08080808, 0x00000000, 0x04040404,7940x00000000, 0x04040404, 0x00000000, 0x04040404, 0x00000000,7950x04040404, 0x00000000, 0x04040404, 0x00000000, 0x02020202,7960x00000000, 0x02020202, 0x00000000, 0x02020202, 0x00000000,7970x02020202, 0x00000000, 0x02020202, 0x00000000, 0x01010101,7980x00000000, 0x01010101, 0x00000000, 0x01010101, 0x00000000,7990x01010101, 0x00000000, 0x01010101, 0x00000000, 0x00000000,8000x00000000, 0x00000000, 0x00000000, 0x20202020, 0x00000000,8010x20202020, 0x00000000, 0x20202020, 0x00000000, 0x20202020,8020x00000000, 0x20202020, 0x00000000, 0x10101010, 0x00000000,8030x10101010, 0x00000000, 0x10101010, 0x00000000, 0x10101010,8040x00000000, 0x10101010, 0x00000000, 0x08080808, 0x00000000,8050x08080808, 0x00000000, 0x08080808, 0x00000000, 0x08080808,8060x00000000, 0x08080808, 0x00000000, 0x04040404, 0x00000000,8070x04040404, 0x00000000, 0x04040404, 0x00000000, 0x04040404,8080x00000000, 0x04040404, 0x00000000, 0x02020202, 0x00000000,8090x02020202, 0x00000000, 0x02020202, 0x00000000, 0x02020202,8100x00000000, 0x02020202, 0x00000000, 0x01010101, 0x00000000,8110x01010101, 0x00000000, 0x01010101, 0x00000000, 0x01010101,8120x00000000, 0x01010101, 0x00000000, 0x00000000, 0x00000000,8130x00000000,814815/* DQ RAM Patterns Table 4 */8160xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8170x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8180xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8190x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8200xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8210x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8220xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8230x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8240xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8250x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8260xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8270x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8280xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8290x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8300xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8310x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8320xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8330x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8340xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8350x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8360xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8370x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8380xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8390x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8400xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8410x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8420xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8430x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8440xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8450x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8460xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8470x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8480xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8490x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8500xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8510x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8520xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8530x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8540xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8550x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8560xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8570x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8580xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8590x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8600xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8610x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8620xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8630x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,8640xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,8650x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,8660xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,8670x33333333868};869870static const u32 ram_pattern_dmi_table[0x500] = {871/* DMI RAM Patterns Table 0 */8720xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,8730x0, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,8740xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0x0, 0x0,8750xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0x0,8760xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0x0,8770x0, 0xF, 0xF, 0x0, 0x0, 0xF, 0x0, 0xF,8780x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF,8790x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,8800xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,8810x0, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,8820xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0x0, 0x0,8830xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0x0,8840xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0x0,8850x0, 0xF, 0xF, 0x0, 0x0, 0xF, 0x0, 0xF,8860x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF,8870x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,8880x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8890x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8900x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8910x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8920x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8930x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8940x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8950x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8960x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8970x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8980x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,8990x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9000x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9010x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9020x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9030x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,904905/* DMI RAM Patterns Table 1 */9060x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0,9070xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0,9080xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF,9090x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,9100xF, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,9110xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF,9120xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0,9130xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,9140x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0,9150xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0,9160xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF,9170x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,9180xF, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,9190xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF,9200xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0,9210xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,9220x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9230x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9240x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9250x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9260x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9270x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9280x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9290x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9300x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9310x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9320x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9330x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9340x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9350x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9360x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9370x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,938939/* DMI RAM Patterns Table 2 */9400x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9410x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9420x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9430x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9440x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9450x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9460x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9470x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9480x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9490x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9500x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9510x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9520x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9530x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9540x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9550x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,9560x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9570x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9580x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9590x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9600x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9610x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9620x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9630x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9640x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9650x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9660x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9670x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9680x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9690x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9700x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9710x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,972973/* DMI RAM Patterns Table 3 */9740x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9750x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9760x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9770x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9780x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9790x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9800x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9810xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0,9820x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9830x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9840x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9850x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9860x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9870x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9880x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9890xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0,9900x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9910x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9920x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9930x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9940x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9950x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9960x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9970x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9980x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,9990x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10000x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10010x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10020x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10030x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10040x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10050x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,10061007/* DMI RAM Patterns Table 4 */10080xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10090xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10100xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10110xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10120xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10130xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10140xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10150xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10160xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10170xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10180xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10190xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10200xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10210xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10220xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10230xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10240xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10250xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10260xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10270xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10280xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10290xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10300xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10310xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10320xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10330xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10340xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10350xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10360xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10370xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10380xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,10390xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x31040};10411042static void _usleep(u32 microseconds)1043{1044u32 start = TMR(0x10);1045while ((u32)(TMR(0x10) - start) <= microseconds)1046;1047}10481049static u32 div_o3(u32 a, u32 b)1050{1051u32 result = a / b;10521053if ((b * result) < a)1054return result + 1;1055else1056return result;1057}10581059static u32 _actual_osc_clocks(u32 in)1060{1061u32 actual_clock;10621063actual_clock = 16 * in;1064if (in > 63)1065{1066actual_clock = 2048;1067if (in > 127)1068{1069if (in >= 192)1070actual_clock = 8192;1071else1072actual_clock = 4096;1073}1074}10751076return actual_clock;1077}10781079static void _ccfifo_write(u32 addr, u32 data_val, u32 delay) //addr and delay are u161080{1081EMC(EMC_CCFIFO_DATA) = data_val;1082EMC(EMC_CCFIFO_ADDR) = (addr & 0xffff) | ((delay & 0x7FFF) << 16) | (1 << 31);1083}10841085static bool _wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, u32 emc_channel)1086{1087bool err = true;10881089for (u32 i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++)1090{1091if (emc_channel)1092{1093if (emc_channel != 1)1094goto done;10951096if (((EMC_CH1(reg_offset) & bit_mask) != 0) == updated_state)1097{1098err = false;1099break;1100}1101}1102else if (((EMC(reg_offset) & bit_mask) != 0) == updated_state)1103{1104err = false;1105break;1106}1107_usleep(1);1108}11091110done:1111return err;1112}11131114static void _request_mmr_data(u32 data, bool dual_channel)1115{1116EMC(EMC_MRR) = data;1117_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, true, EMC_CHANNEL0);1118if (dual_channel)1119_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, true, EMC_CHANNEL1);1120}11211122static void _start_periodic_compensation()1123{1124EMC(EMC_MPC) = 0x4B;1125(void)EMC(EMC_MPC);1126}11271128static bool _timing_update(u32 dual_channel)1129{1130bool err = 0;11311132EMC(EMC_TIMING_CONTROL) = 1;1133err = _wait_emc_status(EMC_EMC_STATUS, TIMING_UPDATE_STALLED, false, EMC_CHANNEL0);1134if (dual_channel)1135err |= _wait_emc_status(EMC_EMC_STATUS, TIMING_UPDATE_STALLED, false, EMC_CHANNEL1);11361137return err;1138}11391140static u32 _get_dram_temperature()1141{1142u32 mr4_0 = 0;1143u32 mr4_1 = 0;11441145bool channel1_enabled = (EMC(EMC_FBIO_CFG7) >> 2) & 1;1146u32 emc_cfg_o = EMC(EMC_CFG);11471148_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, false, EMC_CHANNEL0);11491150if (emc_cfg_o & 0x20000000)1151{1152EMC(EMC_CFG) = emc_cfg_o & 0xDFFFFFFF;1153_timing_update(channel1_enabled);1154}11551156_request_mmr_data(0x80040000, EMC_CHANNEL0);1157mr4_0 = EMC(EMC_MRR) & 0xFFFF;11581159if (mr4_0 < 0xF001)1160mr4_0 &= 0x7;1161else1162{1163mr4_0 = -1;1164goto out;1165}11661167if (channel1_enabled)1168{1169_request_mmr_data(0x40040000, EMC_CHANNEL1);1170mr4_1 = EMC(EMC_MRR) & 0xFFFF;11711172if (mr4_1 < 0xF001)1173mr4_1 &= 0x7;1174else1175goto out;11761177if (mr4_1 > mr4_0)1178mr4_0 = mr4_1;1179}11801181out:1182if (emc_cfg_o & 0x20000000)1183{1184EMC(EMC_CFG) = emc_cfg_o;1185_timing_update(channel1_enabled);1186}11871188return mr4_0;1189}11901191static u32 _pllm_clk_base_cfg(u32 rate_KHz, u32 clk_src_emc, bool new_src_is_PLLMB)1192{1193u32 dividers = 0;1194u32 i = 0;1195u32 pll_ref = 38400; // Only 38.4MHz crystal is supported for T210.11961197pllm_clk_config_t *pllm_clk_config = NULL;11981199for (i = 0; pllm_clk_config_table[i].pll_osc_in; i++)1200{1201if (pllm_clk_config_table[i].pll_osc_in == pll_ref && (pllm_clk_config_table[i].pll_out - 19200) <= rate_KHz)1202pllm_clk_config = &pllm_clk_config_table[i];1203}12041205if (pllm_clk_config && pllm_clk_config->pll_osc_in)1206{1207dividers = pllm_clk_config->pll_input_div | (pllm_clk_config->pll_feedback_div << 8) | ((pllm_clk_config->pll_post_div & 0x1F) << 20);1208if (new_src_is_PLLMB)1209{1210CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) = dividers;1211CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) |= PLLM_ENABLE;12121213if ((clk_src_emc >> EMC_2X_CLK_SRC_SHIFT) == PLLM_UD)1214clk_src_emc = (clk_src_emc & 0x1FFFFFFF) | (PLLMB_UD << EMC_2X_CLK_SRC_SHIFT);1215else if (!(clk_src_emc >> EMC_2X_CLK_SRC_SHIFT))1216clk_src_emc |= (PLLMB_OUT0 << EMC_2X_CLK_SRC_SHIFT);12171218while (!(CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) & PLLM_LOCK))1219;1220}1221else1222{1223CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = dividers;1224CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) |= PLLM_EN_LCKDET;1225CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) |= PLLM_ENABLE;12261227if ((clk_src_emc >> EMC_2X_CLK_SRC_SHIFT) == PLLM_UD)1228clk_src_emc = (clk_src_emc & 0x1FFFFFFF) | (PLLM_UD << EMC_2X_CLK_SRC_SHIFT);1229while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & PLLM_LOCK))1230;1231}1232}1233return clk_src_emc;1234}12351236static void _change_dll_src(emc_table_t *mtc_table_entry, u32 clk_src_emc)1237{1238u32 emc_2x_clk_src = clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;12391240u32 dll_setting = ((((mtc_table_entry->dll_clk_src & 0x1FFFFFFF)1241| (emc_2x_clk_src << EMC_2X_CLK_SRC_SHIFT)) & 0xFFFFFF00)1242| (clk_src_emc & 0xFF)) & 0xFFFFF3FF;12431244if (emc_2x_clk_src == PLLMB_UD)1245dll_setting |= EMC_DLL_PLLM_VCOB;1246else if (emc_2x_clk_src != PLLM_UD)1247dll_setting |= EMC_DLL_SWITCH_OUT;12481249CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = dll_setting;12501251// Commit clock write.1252(void)CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X);1253_usleep(2);12541255// Enable/Disable EMC DLL.1256if (mtc_table_entry->clk_out_enb_x_0_clk_enb_emc_dll)1257CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (1 << 14);1258else1259CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_CLR) = (1 << 14);12601261// Commit clock write.1262(void)CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X);1263_usleep(2);1264}12651266static u32 _digital_dll_prelock(emc_table_t *mtc_table_entry, u32 needs_tristate_training, u32 selected_clk_src_emc)1267{1268u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);12691270EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFF824) | 0x3C8;12711272_timing_update(dual_channel);12731274while (EMC(EMC_CFG_DIG_DLL) & 1)1275;1276if (dual_channel)1277while (EMC_CH1(EMC_CFG_DIG_DLL) & 1)1278;12791280EMC(EMC_DLL_CFG_0) = mtc_table_entry->burst_regs.emc_dll_cfg_0;1281EMC(EMC_DLL_CFG_1) = mtc_table_entry->burst_regs.emc_dll_cfg_1;12821283_change_dll_src(mtc_table_entry, selected_clk_src_emc);12841285EMC(EMC_CFG_DIG_DLL) |= 1;12861287_timing_update(dual_channel);12881289while (!(EMC(EMC_CFG_DIG_DLL) & 1))1290;1291if (dual_channel)1292while (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))1293;12941295while ((((EMC(EMC_DIG_DLL_STATUS) >> 17) & 1) ^ 1) | (((EMC(EMC_DIG_DLL_STATUS) >> 15) & 1) ^ 1))1296;12971298if (needs_tristate_training)1299{1300EMC(EMC_DBG) |= 2u;1301EMC(EMC_CFG_DIG_DLL) &= 0xFFFFFFFE; //Disable CFG_DLL_EN: [PMC] Enable digital DLL.1302EMC(EMC_DBG) &= 0xFFFFFFFD;13031304while (EMC(EMC_CFG_DIG_DLL) & 1)1305;1306if (dual_channel)1307while (EMC_CH1(EMC_CFG_DIG_DLL) & 1)1308;1309}13101311return EMC(EMC_DIG_DLL_STATUS) & 0x7FF;1312}13131314static void _digital_dll_disable()1315{1316bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);13171318EMC(EMC_CFG_DIG_DLL) &= 0xFFFFFFFE;13191320_timing_update(dual_channel);13211322while (EMC(EMC_CFG_DIG_DLL) & 1)1323;1324if (dual_channel)1325while (EMC_CH1(EMC_CFG_DIG_DLL) & 1)1326;1327}13281329static void _digital_dll_enable_rs(u32 channel1_enabled)1330{1331EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF24) | 0x89;13321333_timing_update(channel1_enabled);13341335while (!(EMC(EMC_CFG_DIG_DLL) & 1))1336;1337if (channel1_enabled)1338while (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))1339;1340}13411342static u32 _dvfs_power_ramp_down(bool flip_backward, emc_table_t *src_emc_table_entry, emc_table_t *dst_emc_table_entry, u32 src_clock_period)1343{1344u32 pmacro_cmd_pad;1345u32 pmacro_rfu1;1346u32 pmacro_cfg5;1347u32 pmacro_common_tx;1348u32 pmacro_dq_pad;13491350u32 src_clk_per_pc = (100000 / src_clock_period) + 1;13511352if (flip_backward)1353{1354pmacro_cmd_pad = dst_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;1355pmacro_dq_pad = dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;1356pmacro_rfu1 = dst_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;1357pmacro_cfg5 = dst_emc_table_entry->burst_regs.emc_fbio_cfg5;1358pmacro_common_tx = dst_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;1359}1360else1361{1362pmacro_cmd_pad = src_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;1363pmacro_dq_pad = (dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0x101) | src_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;1364pmacro_rfu1 = src_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;1365pmacro_cfg5 = src_emc_table_entry->burst_regs.emc_fbio_cfg5;1366pmacro_common_tx = src_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;1367}13681369u32 pmacro_cmd_pad_drvforceon = pmacro_cmd_pad | 0x4000000;13701371u32 ramp_down_wait = src_clock_period * 12;13721373_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon, 0);1374_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 | 0x100, 12);13751376if (src_clock_period >= 1000) // Dvfs high speed threshold.1377{1378_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, (u32)(src_clk_per_pc + 19));1379ramp_down_wait += 100000 + (src_clock_period * 20);1380}1381else1382{1383if (src_clock_period >= 416) // Iobrick dcc threshold.1384_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, (u32)src_clk_per_pc);1385else1386{1387pmacro_dq_pad = (pmacro_dq_pad & 0xFEFEFDFD) | 0x10200;1388pmacro_cmd_pad_drvforceon = (pmacro_cmd_pad & 0xFAFEFDFD) | 0x4010200;1389_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon, (u32)src_clk_per_pc);1390_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad, 0);1391_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, 0);1392}1393ramp_down_wait += 300000;1394_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, (u32)src_clk_per_pc);13951396if (src_clock_period >= 416) // Iobrick dcc threshold.1397_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, (u32)src_clk_per_pc);1398else1399{1400_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon & 0xFEFEFDFD, (u32)src_clk_per_pc);1401_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad & 0xFEFEFDFD, 0);1402_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, 0);1403}1404}14051406if (src_clock_period >= 1666) // Dvfs mid speed threshold.1407_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xFFFFFFF0, (u32)src_clk_per_pc);1408else1409{1410ramp_down_wait += 400000;1411_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xFFFFFFFA, (u32)src_clk_per_pc);1412_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xFFFFFFF0, (u32)src_clk_per_pc);1413_ccfifo_write(EMC_INTSTATUS, 0, (u32)src_clk_per_pc);1414}14151416return ramp_down_wait;1417}14181419static u32 _dvfs_power_ramp_up(bool flip_backward, emc_table_t *src_emc_table_entry, emc_table_t *dst_emc_table_entry, u32 needs_training, u32 dst_clock_period)1420{1421u32 pmacro_cmd_pad;1422u32 pmacro_dq_pad;1423u32 pmacro_rfu1;1424u32 pmacro_cfg5;1425u32 pmacro_common_tx;1426u32 pmacro_cmd_pad_data;1427u32 ramp_up_wait = 0;14281429u32 dst_clk_per_pc = (100000 / dst_clock_period) + 1;14301431if (flip_backward)1432{1433pmacro_cmd_pad = src_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;1434pmacro_dq_pad = src_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;1435pmacro_rfu1 = src_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;1436pmacro_cfg5 = src_emc_table_entry->burst_regs.emc_fbio_cfg5;1437pmacro_common_tx = src_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;1438}1439else if (needs_training & NEEDS_TRAINING_CA_COMBO)1440{1441pmacro_cmd_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_cmd_pad_tx_ctrl;1442pmacro_dq_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_data_pad_tx_ctrl;1443pmacro_rfu1 = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_brick_ctrl_rfu1;1444pmacro_cfg5 = dst_emc_table_entry->shadow_regs_ca_train.emc_fbio_cfg5;1445pmacro_common_tx = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_common_pad_tx_ctrl;1446}1447else if (needs_training & NEEDS_TRAINING_QUSE_COMBO)1448{1449pmacro_cmd_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_cmd_pad_tx_ctrl;1450pmacro_dq_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_data_pad_tx_ctrl;1451pmacro_rfu1 = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_brick_ctrl_rfu1;1452pmacro_cfg5 = dst_emc_table_entry->shadow_regs_quse_train.emc_fbio_cfg5;1453pmacro_common_tx = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_common_pad_tx_ctrl;1454}1455else if (needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO))1456{1457pmacro_cmd_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_cmd_pad_tx_ctrl;1458pmacro_dq_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_data_pad_tx_ctrl;1459pmacro_rfu1 = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_brick_ctrl_rfu1;1460pmacro_cfg5 = dst_emc_table_entry->shadow_regs_rdwr_train.emc_fbio_cfg5;1461pmacro_common_tx = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_common_pad_tx_ctrl;1462}1463else1464{1465pmacro_cmd_pad = dst_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;1466pmacro_dq_pad = dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;1467pmacro_rfu1 = dst_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;1468pmacro_cfg5 = dst_emc_table_entry->burst_regs.emc_fbio_cfg5;1469pmacro_common_tx = dst_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;1470}14711472pmacro_cmd_pad_data = (pmacro_cmd_pad & 0xFAFEFDFD) | 0x4000000;14731474if (dst_clock_period >= 1666) // Dvfs mid speed threshold.1475{1476_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx | 8, 0);14771478_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x600, 0);1479_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, 12);14801481ramp_up_wait = (dst_clock_period * 12) + 0;1482}1483else1484{1485_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xA, 0);1486_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xF, dst_clk_per_pc);14871488if (dst_clock_period < 1000) // Dvfs high speed threshold.1489{1490if (dst_clock_period >= 416) // Iobrick dcc threshold.1491_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, dst_clk_per_pc);1492else1493{1494_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, (pmacro_cmd_pad & 0xFAFEFDFD) | 0x4010200, dst_clk_per_pc);1495_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, (pmacro_dq_pad & 0xFEFEFDFD) | 0x10200, 0);1496_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, 0);1497}14981499_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, dst_clk_per_pc);15001501if (dst_clock_period >= 416) // Iobrick dcc threshold.1502_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, dst_clk_per_pc);1503else1504{1505pmacro_cmd_pad_data = pmacro_cmd_pad | 0x5010202;1506_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data, dst_clk_per_pc);1507_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad | 0x1010202, 0);1508_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, 0);1509}15101511ramp_up_wait = 500000 + (dst_clock_period * 10);1512}1513else // 1000 > dst_clock_period < 1666.1514{1515_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x6000600, dst_clk_per_pc);15161517ramp_up_wait = 200000 + (dst_clock_period * 10);1518}15191520_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, dst_clk_per_pc + 9);1521}15221523_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data & 0xFBFFFFFF, 5);15241525return ramp_up_wait;1526}15271528static u32 _minerva_update_clock_tree_delay(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 dram_dev_num, u32 channel1_enabled, enum tree_update_mode_t update_type)1529{1530u32 cval = 0;1531u32 adelta = 0;1532s32 tdelta = 0;15331534u32 temp_ch0_0 = 0;1535u32 temp_ch0_1 = 0;1536u32 temp_ch1_0 = 0;1537u32 temp_ch1_1 = 0;15381539u32 upd_type_bits = 1 << update_type;1540u32 dst_rate_mhz = dst_emc_entry->rate_khz / 1000;1541u32 src_rate_mhz = src_emc_entry->rate_khz / 1000;15421543u32 tval = 1000000 * _actual_osc_clocks(src_emc_entry->run_clocks) / 2;15441545if (update_type > PERIODIC_TRAINING_UPDATE)1546return 0;15471548if (upd_type_bits & 0x5400)1549{1550_request_mmr_data(0x80130000, channel1_enabled); // Dev0 MRR 19.1551u32 mrr = EMC(EMC_MRR);1552temp_ch0_0 = (mrr & 0xFF) << 8;1553temp_ch0_1 = mrr & 0xFF00;1554if (channel1_enabled)1555{1556mrr = EMC_CH1(EMC_MRR);1557temp_ch1_0 = (mrr & 0xFF) << 8;1558temp_ch1_1 = mrr & 0xFF00;1559}15601561_request_mmr_data(0x80120000, channel1_enabled); // Dev0 MRR 18.1562mrr = EMC(EMC_MRR);1563temp_ch0_0 |= mrr & 0xFF;1564temp_ch0_1 |= (mrr & 0xFF00) >> 8;1565if (channel1_enabled)1566{1567mrr = EMC_CH1(EMC_MRR);1568temp_ch1_0 |= mrr & 0xFF;1569temp_ch1_1 |= (mrr & 0xFF00) >> 8;1570}1571}15721573cval = tval / (src_rate_mhz * temp_ch0_0);1574switch (update_type)1575{1576case DVFS_PT1:1577case TRAINING_PT1:1578dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 += 100 * cval;1579if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1580goto calc_td0_0;1581break;1582case DVFS_UPDATE:1583dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 =1584dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1585break;1586case TRAINING_UPDATE:1587dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 =1588dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;1589break;1590case PERIODIC_TRAINING_UPDATE:1591dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 =1592(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0)1593/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1594break;1595default:1596if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1597goto calc_td0_0;1598break;1599}16001601tdelta = dst_emc_entry->current_dram_clktree_c0d0u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / 100);1602if (tdelta < 0)1603tdelta *= -1;1604adelta = tdelta;1605if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1606dst_emc_entry->current_dram_clktree_c0d0u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / 100;16071608calc_td0_0:1609cval = tval / (src_rate_mhz * temp_ch0_1);1610switch (update_type)1611{1612case DVFS_PT1:1613case TRAINING_PT1:1614dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 += 100 * cval;1615if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1616goto calc_td1_0;1617break;1618case DVFS_UPDATE:1619dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 =1620dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1621break;1622case TRAINING_UPDATE:1623dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 =1624dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;1625break;1626case PERIODIC_TRAINING_UPDATE:1627dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 =1628(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1)1629/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1630break;1631default:1632if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1633goto calc_td1_0;1634break;1635}16361637tdelta = dst_emc_entry->current_dram_clktree_c0d0u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / 100);1638if (tdelta < 0)1639tdelta *= -1;1640if ((u32)tdelta > adelta)1641adelta = tdelta;1642if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1643dst_emc_entry->current_dram_clktree_c0d0u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / 100;16441645calc_td1_0:1646if (channel1_enabled)1647{1648cval = tval / (src_rate_mhz * temp_ch1_0);1649switch (update_type)1650{1651case DVFS_PT1:1652case TRAINING_PT1:1653dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 += 100 * cval;1654if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1655goto calc_td1_1;1656break;1657case DVFS_UPDATE:1658dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 =1659dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1660break;1661case TRAINING_UPDATE:1662dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 =1663dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;1664break;1665case PERIODIC_TRAINING_UPDATE:1666dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 =1667(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0)1668/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1669break;1670default:1671if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1672goto calc_td1_1;1673break;1674}16751676tdelta = dst_emc_entry->current_dram_clktree_c1d0u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / 100);1677if (tdelta < 0)1678tdelta *= -1;1679if ((u32)tdelta > adelta)1680adelta = tdelta;1681if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1682dst_emc_entry->current_dram_clktree_c1d0u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / 100;16831684calc_td1_1:1685cval = tval / (src_rate_mhz * temp_ch1_1);1686switch (update_type)1687{1688case DVFS_PT1:1689case TRAINING_PT1:1690dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 += 100 * cval;1691if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1692goto calc_dev2;1693break;1694case DVFS_UPDATE:1695dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 =1696dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1697break;1698case TRAINING_UPDATE:1699dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 =1700dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;1701break;1702case PERIODIC_TRAINING_UPDATE:1703dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 =1704(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1)1705/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1706break;1707default:1708if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1709goto calc_dev2;1710break;1711}17121713tdelta = dst_emc_entry->current_dram_clktree_c1d0u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / 100);1714if (tdelta < 0)1715tdelta *= -1;1716if ((u32)tdelta > adelta)1717adelta = tdelta;1718if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1719dst_emc_entry->current_dram_clktree_c1d0u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / 100;1720}17211722calc_dev2:1723if (dram_dev_num != TWO_RANK)1724goto out;17251726if (update_type <= PERIODIC_TRAINING_UPDATE && upd_type_bits & 0x5400)1727{1728_request_mmr_data(0x40130000, channel1_enabled); // Dev1 MRR 19.1729u32 mrr = EMC(EMC_MRR);1730temp_ch0_0 = (mrr& 0xFF) << 8;1731temp_ch0_1 = mrr & 0xFF00;1732if (channel1_enabled)1733{1734mrr = EMC_CH1(EMC_MRR);1735temp_ch1_0 = (mrr & 0xFF) << 8;1736temp_ch1_1 = mrr & 0xFF00;1737}17381739_request_mmr_data(0x40120000, channel1_enabled); // Dev1 MRR 181740mrr = EMC(EMC_MRR);1741temp_ch0_0 |= mrr & 0xFF;1742temp_ch0_1 |= ((mrr & 0xFF00) >> 8);1743if (channel1_enabled)1744{1745mrr = EMC_CH1(EMC_MRR);1746temp_ch1_0 |= mrr & 0xFF;1747temp_ch1_1 |= (mrr & 0xFF00) >> 8;1748}1749}17501751cval = tval / (src_rate_mhz * temp_ch0_0);1752switch (update_type )1753{1754case DVFS_PT1:1755case TRAINING_PT1:1756dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 += 100 * cval;1757if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1758goto calc_tmp_td0_1;1759break;1760case DVFS_UPDATE:1761dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 =1762dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1763break;1764case TRAINING_UPDATE:1765dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 =1766dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;1767break;1768case PERIODIC_TRAINING_UPDATE:1769dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 =1770(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0)1771/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1772break;1773default:1774if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1775goto calc_tmp_td0_1;1776break;1777}17781779tdelta = dst_emc_entry->current_dram_clktree_c0d1u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / 100);1780if (tdelta < 0)1781tdelta *= -1;1782if ((u32)tdelta > adelta)1783adelta = tdelta;1784if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1785dst_emc_entry->current_dram_clktree_c0d1u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / 100;17861787calc_tmp_td0_1:1788cval = tval / (src_rate_mhz * temp_ch0_1);1789switch (update_type)1790{1791case DVFS_PT1:1792case TRAINING_PT1:1793dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 += 100 * cval;1794if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1795goto calc_tmp_td1_0;1796break;1797case DVFS_UPDATE:1798dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 =1799dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1800break;1801case TRAINING_UPDATE:1802dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 =1803dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;1804break;1805case PERIODIC_TRAINING_UPDATE:1806dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 =1807(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1)1808/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1809break;1810default:1811if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1812goto calc_tmp_td1_0;1813break;1814}18151816tdelta = dst_emc_entry->current_dram_clktree_c0d1u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / 100);1817if (tdelta < 0)1818tdelta *= -1;1819if ((u32)tdelta > adelta)1820adelta = tdelta;1821if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1822dst_emc_entry->current_dram_clktree_c0d1u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / 100;18231824calc_tmp_td1_0:1825if (channel1_enabled)1826{1827cval = tval / (src_rate_mhz * temp_ch1_0);1828switch (update_type)1829{1830case DVFS_PT1:1831case TRAINING_PT1:1832dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 += 100 * cval;1833if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1834goto calc_tmp_td1_1;1835break;1836case DVFS_UPDATE:1837dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 =1838dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1839break;1840case TRAINING_UPDATE:1841dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 =1842dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;1843break;1844case PERIODIC_TRAINING_UPDATE:1845dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 =1846(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0)1847/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1848break;1849default:1850if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1851goto calc_tmp_td1_1;1852break;1853}18541855tdelta = dst_emc_entry->current_dram_clktree_c1d1u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / 100);1856if (tdelta < 0)1857tdelta *= -1;1858if ((u32)tdelta > adelta)1859adelta = tdelta;1860if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1861dst_emc_entry->current_dram_clktree_c1d1u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / 100;18621863calc_tmp_td1_1:1864cval = tval / (src_rate_mhz * temp_ch1_1);1865switch (update_type)1866{1867case DVFS_PT1:1868case TRAINING_PT1:1869dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 += 100 * cval;1870if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1871goto out;1872break;1873case DVFS_UPDATE:1874dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 =1875dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1876break;1877case TRAINING_UPDATE:1878dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 =1879dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;1880break;1881case PERIODIC_TRAINING_UPDATE:1882dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 =1883(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1)1884/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);1885break;1886default:1887if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))1888goto out;1889break;1890}18911892tdelta = dst_emc_entry->current_dram_clktree_c1d1u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / 100);1893if (tdelta < 0)1894tdelta *= -1;1895if ((u32)tdelta > adelta)1896adelta = tdelta;1897if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)1898dst_emc_entry->current_dram_clktree_c1d1u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / 100;1899}19001901out:1902if (update_type == TRAINING_UPDATE)1903{1904dst_emc_entry->trained_dram_clktree_c0d0u0 = dst_emc_entry->current_dram_clktree_c0d0u0;1905dst_emc_entry->trained_dram_clktree_c0d0u1 = dst_emc_entry->current_dram_clktree_c0d0u1;1906dst_emc_entry->trained_dram_clktree_c0d1u0 = dst_emc_entry->current_dram_clktree_c0d1u0;1907dst_emc_entry->trained_dram_clktree_c0d1u1 = dst_emc_entry->current_dram_clktree_c0d1u1;1908dst_emc_entry->trained_dram_clktree_c1d0u0 = dst_emc_entry->current_dram_clktree_c1d0u0;1909dst_emc_entry->trained_dram_clktree_c1d0u1 = dst_emc_entry->current_dram_clktree_c1d0u1;1910dst_emc_entry->trained_dram_clktree_c1d1u0 = dst_emc_entry->current_dram_clktree_c1d1u0;1911dst_emc_entry->trained_dram_clktree_c1d1u1 = dst_emc_entry->current_dram_clktree_c1d1u1;1912}19131914return (u32)adelta;1915}19161917static u32 _minerva_periodic_compensation_handler(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 dram_dev_num, u32 channel1_enabled, enum comp_seq_t seq_type)1918{1919if (!dst_emc_entry->periodic_training)1920return 0;19211922u32 delay = 1000 * _actual_osc_clocks(src_emc_entry->run_clocks) / src_emc_entry->rate_khz + 2;19231924if (seq_type == DVFS_SEQUENCE)1925{1926if (src_emc_entry->periodic_training && dst_emc_entry->ptfv_list.ptfv_config_ctrl & 1)1927{1928u32 samples = dst_emc_entry->ptfv_list.ptfv_dvfs_samples;1929dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 * samples;1930dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 * samples;1931dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 * samples;1932dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 * samples;1933dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 * samples;1934dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 * samples;1935dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 * samples;1936dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 * samples;1937}1938else1939{1940dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 = 0;1941dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 = 0;1942dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 = 0;1943dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 = 0;1944dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 = 0;1945dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 = 0;1946dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 = 0;1947dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 = 0;19481949for (u32 i = 0; i < dst_emc_entry->ptfv_list.ptfv_dvfs_samples; i++)1950{1951_start_periodic_compensation();1952_usleep(delay);1953_minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_PT1);1954}1955}19561957return _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_UPDATE);1958}1959else if (seq_type == WRITE_TRAINING_SEQUENCE)1960{1961dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 = 0;1962dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 = 0;1963dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 = 0;1964dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 = 0;1965dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 = 0;1966dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 = 0;1967dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 = 0;1968dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 = 0;19691970for (u32 i = 0; i < dst_emc_entry->ptfv_list.ptfv_write_samples; i++)1971{1972_start_periodic_compensation();1973_usleep(delay);1974_minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, TRAINING_PT1);1975}19761977return _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, TRAINING_UPDATE);1978}1979else if (seq_type == PERIODIC_TRAINING_SEQUENCE)1980{1981_start_periodic_compensation();1982_usleep(delay);1983return _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, PERIODIC_TRAINING_UPDATE);1984}19851986return seq_type;1987}19881989#define STORE_TRIM_VAL(chan, rank, reg, byte) \1990((mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank##rank##_##reg >> \1991EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE##byte##_SHIFT) & 0x7FF) \1992+ \1993(((mtc_table_entry->trim_perch_regs.emc##chan##_data_brlshft_##rank >> \1994EMC_DATA_BRLSHFT_##rank##_RANK##rank##_BYTE##byte##_DATA_BRLSHFT_SHIFT) & 0x7) << 6)19951996static u32 _minerva_apply_periodic_compensation_trimmer(emc_table_t *mtc_table_entry, u32 trim_emc_reg_addr)1997{1998u32 trimmer = 0;1999s32 tree_delta[4] = {0};2000s32 tree_delta_taps[4] = {0};2001s32 new_trim[] = {2002// chan, rank, reg, byte.2003STORE_TRIM_VAL(0, 0, 0, 0),2004STORE_TRIM_VAL(0, 0, 0, 1),2005STORE_TRIM_VAL(0, 0, 1, 2),2006STORE_TRIM_VAL(0, 0, 1, 3),20072008STORE_TRIM_VAL(1, 0, 2, 4),2009STORE_TRIM_VAL(1, 0, 2, 5),2010STORE_TRIM_VAL(1, 0, 3, 6),2011STORE_TRIM_VAL(1, 0, 3, 7),20122013STORE_TRIM_VAL(0, 1, 0, 0),2014STORE_TRIM_VAL(0, 1, 0, 1),2015STORE_TRIM_VAL(0, 1, 1, 2),2016STORE_TRIM_VAL(0, 1, 1, 3),20172018STORE_TRIM_VAL(1, 1, 2, 4),2019STORE_TRIM_VAL(1, 1, 2, 5),2020STORE_TRIM_VAL(1, 1, 3, 6),2021STORE_TRIM_VAL(1, 1, 3, 7)2022};20232024u32 dst_rate_mhz = mtc_table_entry->rate_khz / 1000;20252026switch (trim_emc_reg_addr)2027{2028case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0:2029case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1:2030case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2:2031case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3:2032case EMC_DATA_BRLSHFT_0:2033tree_delta[0] = (mtc_table_entry->current_dram_clktree_c0d0u0 - mtc_table_entry->trained_dram_clktree_c0d0u0) * 128;2034tree_delta[1] = (mtc_table_entry->current_dram_clktree_c0d0u1 - mtc_table_entry->trained_dram_clktree_c0d0u1) * 128;2035tree_delta[2] = (mtc_table_entry->current_dram_clktree_c1d0u0 - mtc_table_entry->trained_dram_clktree_c1d0u0) * 128;2036tree_delta[3] = (mtc_table_entry->current_dram_clktree_c1d0u1 - mtc_table_entry->trained_dram_clktree_c1d0u1) * 128;2037tree_delta_taps[0] = (tree_delta[0] * (s32)dst_rate_mhz) / 1000000;2038tree_delta_taps[1] = (tree_delta[1] * (s32)dst_rate_mhz) / 1000000;2039tree_delta_taps[2] = (tree_delta[2] * (s32)dst_rate_mhz) / 1000000;2040tree_delta_taps[3] = (tree_delta[3] * (s32)dst_rate_mhz) / 1000000;2041for (u32 i = 0; i < 4; i++)2042{2043// Check if tap exceeds margins and apply it.2044if ((tree_delta_taps[i] > (s32)mtc_table_entry->tree_margin) || (tree_delta_taps[i] < (-1 * (s32)mtc_table_entry->tree_margin)))2045{2046new_trim[i * 2] += tree_delta_taps[i];2047new_trim[i * 2 + 1] += tree_delta_taps[i];2048}2049}2050if (trim_emc_reg_addr == EMC_DATA_BRLSHFT_0)2051{2052for (u32 i = 0; i < 8; i++)2053new_trim[i] /= 64;2054}2055else2056{2057for (u32 i = 0; i < 8; i++)2058new_trim[i] %= 64;2059}2060break;2061case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0:2062case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1:2063case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2:2064case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3:2065case EMC_DATA_BRLSHFT_1:2066tree_delta[0] = (mtc_table_entry->current_dram_clktree_c0d1u0 - mtc_table_entry->trained_dram_clktree_c0d1u0) * 128;2067tree_delta[1] = (mtc_table_entry->current_dram_clktree_c0d1u1 - mtc_table_entry->trained_dram_clktree_c0d1u1) * 128;2068tree_delta[2] = (mtc_table_entry->current_dram_clktree_c1d1u0 - mtc_table_entry->trained_dram_clktree_c1d1u0) * 128;2069tree_delta[3] = (mtc_table_entry->current_dram_clktree_c1d1u1 - mtc_table_entry->trained_dram_clktree_c1d1u1) * 128;2070tree_delta_taps[0] = (tree_delta[0] * (s32)dst_rate_mhz) / 1000000;2071tree_delta_taps[1] = (tree_delta[1] * (s32)dst_rate_mhz) / 1000000;2072tree_delta_taps[2] = (tree_delta[2] * (s32)dst_rate_mhz) / 1000000;2073tree_delta_taps[3] = (tree_delta[3] * (s32)dst_rate_mhz) / 1000000;2074for (u32 i = 0; i < 4; i++)2075{2076// Check if tap exceeds margins and apply it.2077if ((tree_delta_taps[i] > (s32)mtc_table_entry->tree_margin) || (tree_delta_taps[i] < (-1 * (s32)mtc_table_entry->tree_margin)))2078{2079new_trim[8 + i * 2] += tree_delta_taps[i];2080new_trim[8 + i * 2 + 1] += tree_delta_taps[i];2081}2082}2083if (trim_emc_reg_addr == EMC_DATA_BRLSHFT_1)2084{2085for (u32 i = 0; i < 8; i++)2086new_trim[i + 8] /= 64;2087}2088else2089{2090for (u32 i = 0; i < 8; i++)2091new_trim[i + 8] %= 64;2092}2093break;2094default:2095break;2096}20972098switch (trim_emc_reg_addr)2099{2100case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0:2101trimmer = (new_trim[0] & 0x7FF) | ((new_trim[1] & 0x7FF) << 16);2102break;2103case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1:2104trimmer = (new_trim[2] & 0x7FF) | ((new_trim[3] & 0x7FF) << 16);2105break;2106case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2:2107trimmer = (new_trim[4] & 0x7FF) | ((new_trim[5] & 0x7FF) << 16);2108break;2109case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3:2110trimmer = (new_trim[6] & 0x7FF) | ((new_trim[7] & 0x7FF) << 16);2111break;2112case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0:2113trimmer = (new_trim[8] & 0x7FF) | ((new_trim[9] & 0x7FF) << 16);2114break;2115case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1:2116trimmer = (new_trim[10] & 0x7FF) | ((new_trim[11] & 0x7FF) << 16);2117break;2118case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2:2119trimmer = (new_trim[12] & 0x7FF) | ((new_trim[13] & 0x7FF) << 16);2120break;2121case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3:2122trimmer = (new_trim[14] & 0x7FF) | ((new_trim[15] & 0x7FF) << 16);2123break;2124case EMC_DATA_BRLSHFT_0:2125trimmer = ((new_trim[0] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)2126| ((new_trim[1] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)2127| ((new_trim[2] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)2128| ((new_trim[3] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)2129| ((new_trim[4] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)2130| ((new_trim[5] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)2131| ((new_trim[6] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)2132| ((new_trim[7] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT);2133break;2134case EMC_DATA_BRLSHFT_1:2135trimmer = ((new_trim[8] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)2136| ((new_trim[9] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)2137| ((new_trim[10] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)2138| ((new_trim[11] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)2139| ((new_trim[12] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)2140| ((new_trim[13] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)2141| ((new_trim[14] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)2142| ((new_trim[15] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT);2143break;2144default:2145break;2146}21472148return trimmer;2149}21502151static bool _check_freq_changed(u32 dst_entry_rate_KHz, u32 dst_entry_clk_src_emc, u32 src_entry_rate_KHz, u32 src_entry_clk_src_emc)2152{2153u64 dst_div_clock;2154u64 src_div_clock;2155u32 src_end_div_clk_ratio;21562157u32 src_entry_emc_2X_clk_src = src_entry_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;2158u32 dst_entry_emc_2X_clk_src = dst_entry_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;2159u32 src_entry_emc_2X_clk_src_div = src_entry_clk_src_emc & 0xFF;2160u32 dst_entry_emc_2X_clk_src_div = dst_entry_clk_src_emc & 0xFF;2161u32 pll_post_divider = 0;21622163switch (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) >> EMC_2X_CLK_SRC_SHIFT)2164{2165case PLLM_OUT0:2166case PLLM_UD:2167pll_post_divider = (CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) >> 20) & 0x1F;2168break;2169case PLLMB_UD:2170case PLLMB_OUT0:2171pll_post_divider = (CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) >> 20) & 0x1F;2172break;2173default:2174break;2175}21762177// Hang if post div is wrong.2178if (pll_post_divider > 5)2179while (true)2180;21812182if (src_entry_emc_2X_clk_src <= PLLMB_UD)2183src_entry_emc_2X_clk_src_div = 0;2184if (dst_entry_emc_2X_clk_src <= PLLMB_UD)2185dst_entry_emc_2X_clk_src_div = 0;21862187if (dst_entry_emc_2X_clk_src != src_entry_emc_2X_clk_src2188&& (dst_entry_emc_2X_clk_src & 0xFFFFFFFB || src_entry_emc_2X_clk_src & 0xFFFFFFFB))2189return true;21902191dst_div_clock = dst_entry_rate_KHz * (pll_post_divider + 1)2192* ((dst_entry_emc_2X_clk_src_div >> 1) * 10 + (dst_entry_emc_2X_clk_src_div & 1) * 5 + 10) / 10; // Accounting for 7.1 div.2193src_div_clock = src_entry_rate_KHz * (pll_post_divider + 1)2194* ((src_entry_emc_2X_clk_src_div >> 1) * 10 + (src_entry_emc_2X_clk_src_div & 1) * 5 + 10) / 10; // Accounting for 7.1 div.21952196src_end_div_clk_ratio = (src_div_clock * 1000) / dst_div_clock;21972198if (src_end_div_clk_ratio > 1010 || src_end_div_clk_ratio < 990)2199return true;2200else2201return false;2202}22032204static void _save_train_results(emc_table_t *mtc_table_entry, u32 needs_training, u32 dram_dev_num, bool channel1_enabled)2205{2206bool needs_ca_training = !!(needs_training & NEEDS_TRAINING_CA);2207bool needs_ca_vref_training = !!(needs_training & NEEDS_TRAINING_CA_VREF);2208bool needs_quse_training = !!(needs_training & NEEDS_TRAINING_QUSE);2209bool needs_quse_vref_training = !!(needs_training & NEEDS_TRAINING_QUSE_VREF);2210bool needs_wr_training = !!(needs_training & NEEDS_TRAINING_WR);2211bool needs_wr_vref_training = !!(needs_training & NEEDS_TRAINING_WR_VREF);2212bool needs_rd_training = !!(needs_training & NEEDS_TRAINING_RD);2213bool needs_rd_vref_training = !!(needs_training & NEEDS_TRAINING_RD_VREF);2214bool needs_training_in_self_refresh = !!(needs_training & NEEDS_TRAINING_IN_SELF_REFRESH);22152216if (needs_ca_training)2217{2218mtc_table_entry->trim_perch_regs.emc_cmd_brlshft_0 = EMC_CH0(EMC_CMD_BRLSHFT_0);2219mtc_table_entry->trim_perch_regs.emc_cmd_brlshft_1 = channel1_enabled ? EMC_CH1(EMC_CMD_BRLSHFT_1) : 0;2220mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_4 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4);2221mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_5 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) : 0;22222223if (needs_training_in_self_refresh)2224{2225mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0);2226mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1);2227mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2);2228mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0);2229mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1);2230mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2);2231mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0);2232mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1);2233mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2);2234mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0);2235mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1);2236mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2);2237}2238}22392240if (needs_ca_vref_training)2241{2242mtc_table_entry->burst_reg_per_ch.emc0_mrw10 = (EMC_CH0(EMC_TRAINING_OPT_CA_VREF) & 0xFFFF) | 0x880C0000;2243mtc_table_entry->burst_reg_per_ch.emc1_mrw10 = (channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) & 0xFFFF : 0) | 0x880C0000;22442245u32 mrw11_dev_selectn;2246if (dram_dev_num == TWO_RANK)2247mrw11_dev_selectn = 0x480C0000;2248else2249mrw11_dev_selectn = 0xC80C0000;22502251mtc_table_entry->burst_reg_per_ch.emc0_mrw11 =2252((EMC_CH0(EMC_TRAINING_OPT_CA_VREF) >> 16) & 0xFF)2253| (EMC_CH0(EMC_TRAINING_OPT_CA_VREF) >> 24 << 8)2254| (mrw11_dev_selectn & 0xFFFFFF00);22552256mtc_table_entry->burst_reg_per_ch.emc1_mrw11 =2257(((channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) : 0) >> 16) & 0xFF)2258| ((channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) : 0) >> 24 << 8)2259| (mrw11_dev_selectn & 0xFFFFFF00);2260}22612262if (needs_quse_training || needs_rd_training)2263{2264mtc_table_entry->trim_perch_regs.emc_quse_brlshft_0 = EMC_CH0(EMC_QUSE_BRLSHFT_0);2265mtc_table_entry->trim_perch_regs.emc_quse_brlshft_1 = channel1_enabled ? EMC_CH1(EMC_QUSE_BRLSHFT_1) : 0;22662267mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_0 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK0_0);2268mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_1 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK0_1);2269mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK0_2) : 0;2270mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK0_3) : 0;22712272if (dram_dev_num == TWO_RANK)2273{2274mtc_table_entry->trim_perch_regs.emc_quse_brlshft_2 = EMC_CH0(EMC_QUSE_BRLSHFT_2);2275mtc_table_entry->trim_perch_regs.emc_quse_brlshft_3 = channel1_enabled ? EMC_CH1(EMC_QUSE_BRLSHFT_3) : 0;22762277mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_0 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK1_0);2278mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_1 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK1_1);2279mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK1_2) : 0;2280mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK1_3) : 0;2281}2282}22832284if (needs_quse_vref_training)2285{2286if (dram_dev_num == TWO_RANK)2287{2288u32 emc0_opt_dqs_array[4] = {0};2289u32 emc1_opt_dqs_array[4] = {0};2290u32 emc1_training_opt_dqs_ib_vref_rank0_val = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQS_IB_VREF_RANK0) : 0;2291u32 emc1_training_opt_dqs_ib_vref_rank1_val = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQS_IB_VREF_RANK1) : 0;22922293for (u32 i = 0; i < 4; i++)2294{2295emc0_opt_dqs_array[i] = (EMC_CH0(EMC_TRAINING_OPT_DQS_IB_VREF_RANK0) >> (8 * i)) & 0xFF;2296emc1_opt_dqs_array[i] = (emc1_training_opt_dqs_ib_vref_rank0_val >> (8 * i)) & 0xFF;2297}22982299u32 ib_vref_dqs_0 = 0;2300u32 ib_vref_dqs_1 = 0;2301for (u32 i = 0; i < 4; i++)2302{2303ib_vref_dqs_0 |= (emc0_opt_dqs_array[i] + ((EMC_CH0(EMC_TRAINING_OPT_DQS_IB_VREF_RANK1) >> (8 * i)) & 0xFF)) >> 1 << (8 * i);2304ib_vref_dqs_1 |= (emc1_opt_dqs_array[i] + ((emc1_training_opt_dqs_ib_vref_rank1_val >> (8 * i)) & 0xFF)) >> 1 << (8 * i);2305}23062307mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_0 = ib_vref_dqs_0;2308mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_1 = ib_vref_dqs_1;2309}2310else2311{2312mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_0 = EMC(EMC_PMACRO_IB_VREF_DQS_0);2313mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_VREF_DQS_1) : 0;2314}2315}23162317if (needs_rd_training)2318{2319mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0);2320mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1);2321mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) : 0;2322mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) : 0;23232324if (dram_dev_num == TWO_RANK)2325{2326mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0);2327mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1);2328mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) : 0;2329mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) : 0;2330}23312332if (needs_training_in_self_refresh)2333{2334mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0);2335mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1);2336mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2);2337mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0);2338mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1);2339mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2);2340mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0);2341mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1);2342mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2);2343mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0);2344mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1);2345mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2);2346mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0) : 0;2347mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1) : 0;2348mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2) : 0;2349mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0) : 0;2350mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1) : 0;2351mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2) : 0;2352mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0) : 0;2353mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1) : 0;2354mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2) : 0;2355mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0) : 0;2356mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1) : 0;2357mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2) : 0;23582359if (dram_dev_num == TWO_RANK)2360{2361mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0);2362mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1);2363mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2);2364mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0);2365mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1);2366mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2);2367mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0);2368mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1);2369mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2);2370mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0);2371mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1);2372mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2);2373mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0) : 0;2374mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1) : 0;2375mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2) : 0;2376mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0) : 0;2377mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1) : 0;2378mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2) : 0;2379mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0) : 0;2380mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1) : 0;2381mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2) : 0;2382mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0) : 0;2383mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1) : 0;2384mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2) : 0;2385}2386}23872388if (needs_rd_vref_training)2389{2390char ib_vref_dq_byte0_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_0) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[0] & 0x7F);2391if (mtc_table_entry->save_restore_mod_regs[0] & 0x80000000) // < 0 check.2392ib_vref_dq_byte0_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_0) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[0] & 0x7F);23932394char ib_vref_dq_byte1_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 8) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[1] & 0x7F);2395if (mtc_table_entry->save_restore_mod_regs[1] & 0x80000000)2396ib_vref_dq_byte1_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 8) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[1] & 0x7F);23972398char ib_vref_dq_byte2_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 16) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[2] & 0x7F);2399if (mtc_table_entry->save_restore_mod_regs[2] & 0x80000000)2400ib_vref_dq_byte2_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 16) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[2] & 0x7F);24012402char ib_vref_dq_byte3_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 24) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[3] & 0x7F);2403if (mtc_table_entry->save_restore_mod_regs[3] & 0x80000000)2404ib_vref_dq_byte3_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 24) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[3] & 0x7F);24052406mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dq_0 =2407((ib_vref_dq_byte0_icr & 0x7F)2408| (ib_vref_dq_byte1_icr & 0x7F) << 8)2409| ((ib_vref_dq_byte2_icr & 0x7F) << 16)2410| ((ib_vref_dq_byte3_icr & 0x7F) << 24);24112412char ib_vref_dq_byte4_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_1) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[4] & 0x7F);2413if (mtc_table_entry->save_restore_mod_regs[4] & 0x80000000)2414ib_vref_dq_byte4_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_1) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[4] & 0x7F);24152416char ib_vref_dq_byte5_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 8) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[5] & 0x7F);2417if (mtc_table_entry->save_restore_mod_regs[5] & 0x80000000)2418ib_vref_dq_byte5_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 8) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[5] & 0x7F);24192420char ib_vref_dq_byte6_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 16) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[6] & 0x7F);2421if (mtc_table_entry->save_restore_mod_regs[6] & 0x80000000)2422ib_vref_dq_byte6_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 16) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[6] & 0x7F);24232424char ib_vref_dq_byte7_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 24) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[7] & 0x7F);2425if (mtc_table_entry->save_restore_mod_regs[7] & 0x80000000)2426ib_vref_dq_byte7_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 24) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[7] & 0x7F);24272428mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dq_1 =2429((ib_vref_dq_byte4_icr & 0x7F)2430| (ib_vref_dq_byte5_icr & 0x7F) << 8)2431| ((ib_vref_dq_byte6_icr & 0x7F) << 16)2432| ((ib_vref_dq_byte7_icr & 0x7F) << 24);2433}2434}24352436if (needs_wr_training)2437{2438mtc_table_entry->trim_perch_regs.emc0_data_brlshft_0 = EMC_CH0(EMC_DATA_BRLSHFT_0);2439mtc_table_entry->trim_perch_regs.emc1_data_brlshft_0 = channel1_enabled ? EMC_CH1(EMC_DATA_BRLSHFT_0) : 0;24402441if (dram_dev_num == TWO_RANK)2442{2443mtc_table_entry->trim_perch_regs.emc0_data_brlshft_1 = EMC_CH0(EMC_DATA_BRLSHFT_1);2444mtc_table_entry->trim_perch_regs.emc1_data_brlshft_1 = channel1_enabled ? EMC_CH1(EMC_DATA_BRLSHFT_1) : 0;2445}24462447mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0);2448mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1);2449mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) : 0;2450mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) : 0;24512452if (dram_dev_num == TWO_RANK)2453{2454mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0);2455mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1);2456mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) : 0;2457mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) : 0;2458}24592460if (needs_training_in_self_refresh)2461{2462mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0);2463mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1);2464mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2);2465mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0);2466mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1);2467mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2);2468mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0);2469mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1);2470mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2);2471mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0);2472mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1);2473mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2);2474mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0) : 0;2475mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1) : 0;2476mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2) : 0;2477mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0) : 0;2478mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1) : 0;2479mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2) : 0;2480mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0) : 0;2481mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1) : 0;2482mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2) : 0;2483mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0) : 0;2484mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1) : 0;2485mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2) : 0;24862487if (dram_dev_num == TWO_RANK)2488{2489mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0);2490mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1);2491mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2);2492mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0);2493mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1);2494mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2);2495mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0);2496mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1);2497mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2);2498mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0);2499mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1);2500mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2);2501mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0) : 0;2502mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1) : 0;2503mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2) : 0;2504mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0) : 0;2505mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1) : 0;2506mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2) : 0;2507mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0) : 0;2508mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1) : 0;2509mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2) : 0;2510mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0) : 0;2511mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1) : 0;2512mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2) : 0;2513}2514}25152516if (needs_wr_vref_training) // mode 12/13 (MRW).2517{2518u32 emc1_ranks_sub_partitions = 0;2519emc1_ranks_sub_partitions = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQ_OB_VREF) : 0;25202521u8 emc0_ib_vref_dq_byte8_modded_plus = mtc_table_entry->save_restore_mod_regs[8] + EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF);2522if (mtc_table_entry->save_restore_mod_regs[8] & 0x80000000) // < 0 check.2523emc0_ib_vref_dq_byte8_modded_plus = EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) - mtc_table_entry->save_restore_mod_regs[8];25242525u8 emc0_mrw12_op_sp1 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) & 0xFFFF) >> 8) + mtc_table_entry->save_restore_mod_regs[9];2526if (mtc_table_entry->save_restore_mod_regs[9] & 0x80000000)2527emc0_mrw12_op_sp1 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) & 0xFFFF) >> 8) - mtc_table_entry->save_restore_mod_regs[9];25282529u8 emc0_mrw13_op_sp0 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 16) & 0xFF) + mtc_table_entry->save_restore_mod_regs[8];2530if (mtc_table_entry->save_restore_mod_regs[8] & 0x80000000)2531emc0_mrw13_op_sp0 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 16) & 0xFF) - mtc_table_entry->save_restore_mod_regs[8];25322533u8 emc0_ib_vref_dq_byte9_modded_a_plus = mtc_table_entry->save_restore_mod_regs[9] + (EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 24);2534if (mtc_table_entry->save_restore_mod_regs[9] & 0x80000000)2535emc0_ib_vref_dq_byte9_modded_a_plus = (EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 24) - (u8)mtc_table_entry->save_restore_mod_regs[9];25362537u8 emc0_ib_vref_dq_byte10_modded_plus = emc1_ranks_sub_partitions + mtc_table_entry->save_restore_mod_regs[10];2538if (mtc_table_entry->save_restore_mod_regs[10] & 0x80000000)2539emc0_ib_vref_dq_byte10_modded_plus = emc1_ranks_sub_partitions - mtc_table_entry->save_restore_mod_regs[10];25402541u8 emc0_ib_vref_dq_byte11_modded_plus = ((emc1_ranks_sub_partitions & 0xFFFF) >> 8) + mtc_table_entry->save_restore_mod_regs[11];2542if (mtc_table_entry->save_restore_mod_regs[11] & 0x80000000)2543emc0_ib_vref_dq_byte11_modded_plus = ((emc1_ranks_sub_partitions & 0xFFFF) >> 8) - mtc_table_entry->save_restore_mod_regs[11];25442545u8 emc1_mrw13_op_sp0 = ((emc1_ranks_sub_partitions >> 16) & 0xFF) + mtc_table_entry->save_restore_mod_regs[10];2546if (mtc_table_entry->save_restore_mod_regs[10] & 0x80000000)2547emc1_mrw13_op_sp0 = ((emc1_ranks_sub_partitions >> 16) & 0xFF) - mtc_table_entry->save_restore_mod_regs[10];25482549u8 emc1_mrw13_op_sp1 = (emc1_ranks_sub_partitions >> 24) + mtc_table_entry->save_restore_mod_regs[11];2550if (mtc_table_entry->save_restore_mod_regs[11] & 0x80000000)2551emc1_mrw13_op_sp1 = (emc1_ranks_sub_partitions >> 24) - mtc_table_entry->save_restore_mod_regs[11];25522553u32 mr13_dev_ext_cnt_sp_addr = 0xC80E0000;2554if (dram_dev_num == TWO_RANK)2555mr13_dev_ext_cnt_sp_addr = 0x480E0000;25562557mtc_table_entry->burst_reg_per_ch.emc1_mrw12 = (u8)emc0_ib_vref_dq_byte10_modded_plus | 0x880E0000 | (emc0_ib_vref_dq_byte11_modded_plus << 8);2558mtc_table_entry->burst_reg_per_ch.emc0_mrw12 = emc0_ib_vref_dq_byte8_modded_plus | 0x880E0000 | (emc0_mrw12_op_sp1 << 8);2559mtc_table_entry->burst_reg_per_ch.emc0_mrw13 = emc0_ib_vref_dq_byte9_modded_a_plus << 8 | emc0_mrw13_op_sp0 | mr13_dev_ext_cnt_sp_addr;2560mtc_table_entry->burst_reg_per_ch.emc1_mrw13 = (emc1_mrw13_op_sp1 << 8) | emc1_mrw13_op_sp0 | mr13_dev_ext_cnt_sp_addr;2561}2562}2563}25642565static u32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 needs_training, u32 selected_clk_src_emc)2566{2567u32 emc_dbg_o;2568u32 emc_pin_o;2569u32 emc_cfg_pipe_clk_o;2570u32 emc_sel_dpd_ctrl;2571u32 emc_cfg;2572u32 emc_dbg_val;2573u32 emc_zq_cal = 0;2574u32 ramp_up_wait;2575u32 ramp_down_wait;2576u32 bg_regulator_mode_change;2577u32 mr13_flip_fspop;2578u32 mr13_flip_fspwr;2579u32 mr13_catr_enable;25802581/* needs_training flags */2582/*2583| bit | Description |2584|-----|----------------------------------|2585| 0 | Needs CA training |2586| 1 | Needs CA_VREF training |2587| 2 | Needs QUSE training |2588| 3 | Needs QUSE_VREF training |2589| 4 | Needs WR training |2590| 5 | Needs WR_VREF training |2591| 6 | Needs RD training |2592| 7 | Needs RD_VREF training |2593| 8 | Needs SWAP_RANK training |2594| 9 | Needs IN_SELF_REFRESH training |2595*/25962597bool compensate_trimmer_applicable = false;2598bool needs_ca_combo_training = !!(needs_training & NEEDS_TRAINING_CA_COMBO);2599bool needs_tristate_training = !!(needs_training & NEEDS_TRISTATE_TRAINING);26002601bool needs_ca_training = !!(needs_training & NEEDS_TRAINING_CA);2602bool needs_ca_vref_training = !!(needs_training & NEEDS_TRAINING_CA_VREF);2603bool needs_quse_training = !!(needs_training & NEEDS_TRAINING_QUSE);2604bool needs_quse_vref_training = !!(needs_training & NEEDS_TRAINING_QUSE_VREF);2605bool needs_wr_training = !!(needs_training & NEEDS_TRAINING_WR);2606bool needs_wr_vref_training = !!(needs_training & NEEDS_TRAINING_WR_VREF);2607bool needs_rd_training = !!(needs_training & NEEDS_TRAINING_RD);2608bool needs_rd_vref_training = !!(needs_training & NEEDS_TRAINING_RD_VREF);2609bool needs_swap_rank_training = !!(needs_training & NEEDS_TRAINING_SWAP_RANK);26102611bool zcal_resistor_shared = (src_emc_entry->burst_regs.emc_zcal_wait_cnt >> 31) & 1;2612bool enable_bg_regulator = (dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 1) ^ 1;2613bool channel1_enabled = (src_emc_entry->burst_regs.emc_fbio_cfg7 >> 2) & 1;2614u32 dram_type = EMC(EMC_FBIO_CFG5) & 3;2615u32 dram_dev_num = (MC(MC_EMEM_ADR_CFG) & 1) + 1;26162617u32 src_clock_period = 1000000000 / src_emc_entry->rate_khz; // In picoseconds.2618u32 dst_clock_period = 1000000000 / dst_emc_entry->rate_khz; // In picoseconds.26192620// Get current FSP op/write value.2621bool enable_fsp_opwr = !(EMC(EMC_MRW3) & 0xC0);26222623if (dram_type != DRAM_TYPE_LPDDR4)2624{2625EPRINTF("MTC Error: DRAM is not LPDDR4");2626return 5;2627}26282629u32 tFC_lpddr4 = dst_emc_entry->dram_timings.t_fc_lpddr4 * 1000;2630u32 tZQCAL_lpddr4 = 1000000;2631if (dst_clock_period <= 2000)2632tZQCAL_lpddr4 -= tFC_lpddr4;2633s32 tZQCAL_lpddr4_fc_adj = tZQCAL_lpddr4 / dst_clock_period;26342635(void)EMC(EMC_CFG);2636(void)EMC(EMC_AUTO_CAL_CONFIG);26372638// Step 1 - Pre DVFS SW sequence.2639EPRINTF("Step 1");2640emc_dbg_o = EMC(EMC_DBG);2641emc_pin_o = EMC(EMC_PIN);2642emc_cfg = dst_emc_entry->burst_regs.emc_cfg & 0xFFFFFFF;2643emc_sel_dpd_ctrl = dst_emc_entry->emc_sel_dpd_ctrl & 0xFFFFFEC3;2644emc_cfg_pipe_clk_o = EMC(EMC_CFG_PIPE_CLK);2645_digital_dll_disable();26462647// Step 1.2 - Disable AUTOCAL temporarily.2648EPRINTF("Step 1.2");2649EMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FF) | 0x600;2650(void)EMC(EMC_AUTO_CAL_CONFIG);26512652// Step 1.3 - Disable other power features.2653EPRINTF("Step 1.3");2654EMC(EMC_DBG) = emc_dbg_o | 2;2655EMC(EMC_CFG) = emc_cfg;2656EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl;2657EMC(EMC_DBG) = emc_dbg_o;26582659if (!needs_tristate_training && dst_emc_entry->periodic_training)2660{2661if (dram_dev_num == TWO_RANK)2662{2663_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_BOTH_MASK, false, EMC_CHANNEL0);2664if (channel1_enabled)2665_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_BOTH_MASK, false, EMC_CHANNEL1);2666}2667else2668{2669_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_1DEV_MASK, false, EMC_CHANNEL0);2670if (channel1_enabled)2671_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_1DEV_MASK, false, EMC_CHANNEL1);2672}26732674_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, false, EMC_CHANNEL0);2675if (channel1_enabled)2676_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, false, EMC_CHANNEL1);26772678// Reset clock tree delays.2679dst_emc_entry->current_dram_clktree_c0d0u0 = dst_emc_entry->trained_dram_clktree_c0d0u0;2680dst_emc_entry->current_dram_clktree_c0d0u1 = dst_emc_entry->trained_dram_clktree_c0d0u1;2681dst_emc_entry->current_dram_clktree_c0d1u0 = dst_emc_entry->trained_dram_clktree_c0d1u0;2682dst_emc_entry->current_dram_clktree_c0d1u1 = dst_emc_entry->trained_dram_clktree_c0d1u1;2683dst_emc_entry->current_dram_clktree_c1d0u0 = dst_emc_entry->trained_dram_clktree_c1d0u0;2684dst_emc_entry->current_dram_clktree_c1d0u1 = dst_emc_entry->trained_dram_clktree_c1d0u1;2685dst_emc_entry->current_dram_clktree_c1d1u0 = dst_emc_entry->trained_dram_clktree_c1d1u0;2686dst_emc_entry->current_dram_clktree_c1d1u1 = dst_emc_entry->trained_dram_clktree_c1d1u1;26872688u32 adelta = _minerva_periodic_compensation_handler(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_SEQUENCE);26892690if (((dst_emc_entry->rate_khz / 1000) * 128) * adelta / 1000000 > dst_emc_entry->tree_margin)2691compensate_trimmer_applicable = true;2692}26932694EMC(EMC_INTSTATUS) = CLKCHANGE_COMPLETE_INT;2695EMC(EMC_DBG) = emc_dbg_o | 2;2696EMC(EMC_CFG) = emc_cfg;2697EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl;2698EMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o | 1; // CLK_ALWAYS_ON.2699EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = dst_emc_entry->emc_fdpd_ctrl_cmd_no_ramp & 0xFFFFFFFE;27002701bg_regulator_mode_change = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 ^ dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0;2702bg_regulator_mode_change = (bg_regulator_mode_change | (bg_regulator_mode_change >> 2)) & 1;27032704if (bg_regulator_mode_change)2705{2706EMC(EMC_DBG) = emc_dbg_o | 2;2707if (enable_bg_regulator)2708EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFE;2709else2710EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFB;2711}27122713// Check if we need to turn on VREF generator.2714if ((!(src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0x100)2715&& (dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0x100))2716|| (!(src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 1)2717&& (dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 1)))2718{2719EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) =2720(((dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 1) | (src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0xFFFFFFFE)) & 0xFFFFFEFF)2721| (((dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl >> 8) & 0x1) << 8);2722}27232724_usleep(1);27252726EMC(EMC_DBG) = emc_dbg_o;27272728// Step 2 - Prelock the DLL.2729EPRINTF("Step 2");2730if (dst_emc_entry->burst_regs.emc_cfg_dig_dll & 1)2731_digital_dll_prelock(dst_emc_entry, needs_tristate_training, selected_clk_src_emc); // Prelock enabled for target frequency.2732else2733{2734_change_dll_src(dst_emc_entry, selected_clk_src_emc);2735_digital_dll_disable(); // Disabling DLL for target frequency.2736}27372738// Step 3 - Prepare autocal for the clock change.2739EPRINTF("Step 3");2740EMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FF) | 0x600;2741EMC(EMC_DBG) = emc_dbg_o | 2;2742EMC(EMC_AUTO_CAL_CONFIG2) = dst_emc_entry->emc_auto_cal_config2;2743EMC(EMC_AUTO_CAL_CONFIG3) = dst_emc_entry->emc_auto_cal_config3;2744EMC(EMC_AUTO_CAL_CONFIG4) = dst_emc_entry->emc_auto_cal_config4;2745EMC(EMC_AUTO_CAL_CONFIG5) = dst_emc_entry->emc_auto_cal_config5;2746EMC(EMC_AUTO_CAL_CONFIG6) = dst_emc_entry->emc_auto_cal_config6;2747EMC(EMC_AUTO_CAL_CONFIG7) = dst_emc_entry->emc_auto_cal_config7;2748EMC(EMC_AUTO_CAL_CONFIG8) = dst_emc_entry->emc_auto_cal_config8;2749EMC(EMC_DBG) = emc_dbg_o;2750EMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FE) | 0x601;27512752// Step 4 - Update EMC_CFG.2753EPRINTF("Step 4");2754if (src_clock_period <= 50000)2755EMC(EMC_CFG_2) = dst_emc_entry->emc_cfg_2;2756else2757_ccfifo_write(EMC_SELF_REF, 1, 0);27582759// Step 5 - Prepare reference variables for ZQCAL regs.2760EPRINTF("Step 5");2761// u32 zq_wait_long = 0;2762// u32 zq_wait_short = 0;27632764// zq_wait_long = _fceil(1000.0f / dst_clock_period);27652766// Step 7 - Bug 200024907 - Patch RP R2P.2767EPRINTF("Step 7");2768if (needs_ca_combo_training && dram_dev_num == TWO_RANK)2769EMC(EMC_PIN) = 0x107;27702771u32 R2P_war = 0;2772u32 TRPab_war = 0;2773u32 RP_war = 0;2774u32 W2P_war = 0;27752776u32 nRTP = 8; // <= 1066MHz.2777if ( src_clock_period < 1000000 / 2662778&& src_clock_period < 1000000 / 5332779&& src_clock_period < 1000000 / 8002780&& src_clock_period < 1000000 / 1066 )2781nRTP = 10; // 1067MHz < x <= 1333MHz.2782if (src_clock_period < 1000000 / 1333)2783nRTP = 12; // 1333MHz < x <= 1600MHz.2784if (src_clock_period < 1000000 / 1600)2785nRTP = 14; // 1600MHz < x <= 1866MHz.2786if (src_clock_period < 1000000 / 1866)2787nRTP = 16; // > 1866MHz27882789u32 tRPST = (src_emc_entry->emc_mrw >> 7) & 1;27902791u32 deltaTWATM = div_o3(7500, src_clock_period);2792if (deltaTWATM < 8)2793deltaTWATM = 8;27942795u32 tRTM = src_emc_entry->dram_timings.rl + div_o3(3600, src_clock_period) + deltaTWATM + tRPST + nRTP + 1;27962797if (tRTM <= src_emc_entry->burst_regs.emc_rp + src_emc_entry->burst_regs.emc_r2p)2798{2799TRPab_war = src_emc_entry->burst_regs.emc_trpab;2800R2P_war = src_emc_entry->burst_regs.emc_r2p;2801RP_war = src_emc_entry->burst_regs.emc_rp;2802}2803else2804{2805R2P_war = tRTM - src_emc_entry->burst_regs.emc_rp;2806TRPab_war = src_emc_entry->burst_regs.emc_trpab;2807RP_war = src_emc_entry->burst_regs.emc_rp;2808if (R2P_war > 63)2809{2810RP_war = tRTM - 63;2811R2P_war = 63;2812if (src_emc_entry->burst_regs.emc_trpab < tRTM - 63)2813TRPab_war = tRTM - 63;2814else2815TRPab_war = src_emc_entry->burst_regs.emc_trpab;2816}2817}28182819if (RP_war >= deltaTWATM)2820W2P_war = src_emc_entry->burst_regs.emc_w2p;2821else2822{2823u32 W2P_war_temp = deltaTWATM + src_emc_entry->burst_regs.emc_w2p;2824W2P_war = W2P_war_temp - RP_war;2825if (W2P_war > 63)2826{2827RP_war = W2P_war_temp - 63;2828W2P_war = 63;2829if (TRPab_war < RP_war)2830TRPab_war = RP_war;2831}2832}28332834if ( src_emc_entry->burst_regs.emc_w2p != W2P_war2835|| src_emc_entry->burst_regs.emc_rp != RP_war2836|| src_emc_entry->burst_regs.emc_r2p != R2P_war2837|| src_emc_entry->burst_regs.emc_trpab != TRPab_war)2838{2839EMC(EMC_DBG) = emc_dbg_o | 2;2840EMC(EMC_RP) = RP_war;2841EMC(EMC_R2P) = R2P_war;2842EMC(EMC_W2P) = W2P_war;2843EMC(EMC_TRPAB) = TRPab_war;2844EMC(EMC_DBG) = emc_dbg_o;2845(void)EMC(EMC_TRPAB);2846_usleep(1);2847}28482849// Step 7.2 - Program FSP reference registers and send MRWs to new FSPWR.2850EPRINTF("Step 7.2");2851if (enable_fsp_opwr)2852{2853mr13_flip_fspop = dst_emc_entry->emc_mrw3 | 0xC0;2854mr13_flip_fspwr = (dst_emc_entry->emc_mrw3 & 0xFFFFFF3F) | 0x40;2855}2856else2857{2858mr13_flip_fspop = dst_emc_entry->emc_mrw3 & 0xFFFFFF3F;2859mr13_flip_fspwr = mr13_flip_fspop | 0x80;2860}28612862if (dram_dev_num == TWO_RANK)2863{2864if (needs_swap_rank_training)2865mr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x40000001;2866else2867mr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x80000001;28682869if (needs_ca_combo_training)2870{2871if (needs_swap_rank_training)2872mr13_flip_fspop = (mr13_flip_fspop & 0x3FFFFFFF) | 0x80000000;2873else2874mr13_flip_fspop = (mr13_flip_fspop & 0x3FFFFFFF) | 0x40000000;2875}2876}2877else2878mr13_catr_enable = mr13_flip_fspwr | 1;28792880EMC(EMC_MRW3) = mr13_flip_fspwr;2881EMC(EMC_MRW) = dst_emc_entry->emc_mrw;2882EMC(EMC_MRW2) = dst_emc_entry->emc_mrw2;28832884// Step 8 - Program the shadow registers.2885EPRINTF("Step 8");2886// Writing burst_regs.2887u32 reg_addr = 0;2888u32 reg_val = 0;2889u32 reg_check = false;2890burst_regs_table_t *dst_burst_regs = (burst_regs_table_t *)&dst_emc_entry->burst_regs;28912892for (u32 i = 0; dst_emc_entry->num_burst > i; i++)2893{2894reg_check = false;2895reg_addr = burst_regs_emc_addr_table[i];2896if (needs_tristate_training)2897{2898if (needs_ca_combo_training)2899reg_val = dst_burst_regs->shadow_regs_ca_train[i];2900else if (needs_training & NEEDS_TRAINING_QUSE_COMBO)2901reg_val = dst_burst_regs->shadow_regs_quse_train[i];2902else if (needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO))2903reg_val = dst_burst_regs->shadow_regs_rdwr_train[i];2904else2905continue;2906}2907else2908reg_val = dst_burst_regs->burst_regs[i];29092910if ((reg_addr & 0xFFF7) != EMC_MRW62911&& (reg_addr - EMC_MRW7) & 0xFFFF72912//&& (reg_addr & 0xEFF7) != 0x34B4 // EMC_MRW10.2913&& ((reg_addr & 0xEFFF) - 0x34B8) & 0xFFF7 // EMC_MRW11.2914&& reg_addr != EMC_TRAINING_CTRL2915&& reg_addr != EMC_MRW142916&& reg_addr != EMC_MRW15)2917{2918reg_check = true;2919}29202921if (reg_check && reg_addr == EMC_CFG)2922{2923reg_val &= 0xFFFFFFF;29242925EMC(reg_addr) = reg_val;2926continue;2927}29282929if (reg_addr != EMC_CFG)// EMC_CFG2930{2931if (reg_addr != EMC_ZCAL_INTERVAL)2932{2933switch ( reg_addr )2934{2935case EMC_PMACRO_AUTOCAL_CFG_COMMON:2936reg_val |= 0x10000;2937break;2938case EMC_PMACRO_DATA_PAD_TX_CTRL:2939reg_val &= 0xFEFEFDFD;2940break;2941case EMC_PMACRO_CMD_PAD_TX_CTRL:2942reg_val = (reg_val & 0xFAFEFDFD) | 0x4000000;2943break;2944case EMC_PMACRO_BRICK_CTRL_RFU1:2945reg_val &= 0xF800F800;2946break;2947case EMC_PMACRO_COMMON_PAD_TX_CTRL:2948reg_val &= 0xFFFFFFF0;2949break;2950case EMC_TRAINING_CTRL:2951reg_val |= needs_swap_rank_training << 14;// bit15 is TR_IN_SELF_REFRESH2952break;2953}2954}2955else2956reg_val = 0;2957}2958else2959reg_val &= 0xFFFFFFF;29602961EMC(reg_addr) = reg_val;2962}29632964if (needs_tristate_training)2965EMC(EMC_MRW) = (src_emc_entry->run_clocks & 0xFF) | 0x170000;2966else2967EMC(EMC_MRW) = (dst_emc_entry->run_clocks & 0xFF) | 0x170000;29682969// Writing burst_regs_per_ch.2970for (u32 i = 0; dst_emc_entry->num_burst_per_ch > i; i++)2971{2972reg_addr = burst_reg_per_ch_emc01_addr_table[i];2973if (reg_addr && (channel1_enabled || ((reg_addr - 0x4000) > 0xFFF)))2974{2975EMC(reg_addr) = dst_burst_regs->burst_reg_per_ch[i];2976}2977}29782979// Writing vref_regs.2980trim_regs_table_t *trim_regs_table = (trim_regs_table_t *)&dst_emc_entry->trim_regs;2981for (u32 i = 0; dst_emc_entry->vref_num > i; i++)2982{2983reg_addr = vref_perch_regs_emc01_addr_table[i];2984if (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))2985EMC(reg_addr) = trim_regs_table->vref_perch_regs[i];2986}29872988// Writing training mod regs.2989if (needs_tristate_training)2990{2991for (u32 i = 0; dst_emc_entry->training_mod_num > i; i++)2992{2993reg_addr = training_mod_regs_emc01_addr_table[i];2994if (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))2995EMC(reg_addr) = dst_emc_entry->training_mod_regs[i];2996}2997}29982999// Writing trim_regs3000for (u32 i = 0; dst_emc_entry->num_trim > i; i++)3001{3002reg_addr = trim_regs_emc_addr_table[i];3003if (reg_addr)3004{3005if (((reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_03006|| (reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_03007|| (reg_addr & 0xFFFFFFFB) == EMC_DATA_BRLSHFT_0)3008&& compensate_trimmer_applicable)3009{3010EMC(reg_addr) = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr);3011}3012else3013EMC(reg_addr) = trim_regs_table->trim_regs[i];3014}3015}30163017// Writing trim_regs_per_ch3018reg_val = 0;3019for (u32 i = 0; dst_emc_entry->num_trim_per_ch > i; i++)3020{3021reg_addr = trim_perch_regs_emc01_addr_table[i];3022if (reg_addr && (channel1_enabled || reg_addr - 0x4000 > 0xFFF))3023{3024if (((reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_03025|| (reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_03026|| (reg_addr & 0xFFFFFFFB) == EMC_DATA_BRLSHFT_0)3027&& compensate_trimmer_applicable )3028{3029reg_val = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);3030}3031else if (((reg_addr & 0xFFFFFFFB) == 0x36603032|| (reg_addr & 0xFFFFFFDF) == 0x36483033|| (reg_addr & 0xFFFFFFF7) == 0x36443034|| reg_addr == 0x366C3035|| reg_addr == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_03036|| (reg_addr & 0xFFFFFFFB) == 0x3588)3037&& compensate_trimmer_applicable )3038{3039reg_val = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);3040}3041else if (((reg_addr & 0xFFFFFFF3) == 0x46603042|| (reg_addr & 0xFFFFFFF3) == 0x46403043|| (reg_addr & 0xFFFFFFFB) == 0x4588)3044&& compensate_trimmer_applicable)3045{3046reg_val = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);3047}3048else3049{3050reg_val = trim_regs_table->trim_perch_regs[i];3051}3052EMC(reg_addr) = reg_val;3053}3054}30553056if (needs_tristate_training)3057{3058// Check delta wrt previous values (save value if margin exceeds what is set in table).3059if (needs_wr_training && dst_emc_entry->periodic_training)3060_minerva_periodic_compensation_handler(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, WRITE_TRAINING_SEQUENCE);3061}3062else3063{3064// Writing burst_mc_regs.3065for (u32 i = 0; dst_emc_entry->num_mc_regs > i; i++)3066MC(burst_mc_regs_addr_table[i]) = dst_emc_entry->burst_mc_regs[i];30673068// Writing la_scale_regs.3069if (dst_emc_entry->rate_khz < src_emc_entry->rate_khz)3070{3071for (u32 i = 0; dst_emc_entry->num_up_down > i; i++)3072MC(la_scale_regs_mc_addr_table[i]) = dst_emc_entry->la_scale_regs[i];3073}3074}30753076// Step 9 - LPDDR4.3077EPRINTF("Step 9");3078EMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval & 0xFF000000;3079EMC(EMC_ZCAL_WAIT_CNT) = dst_emc_entry->burst_regs.emc_zcal_wait_cnt & 0xFFFFF800;3080EMC(EMC_DBG) = emc_dbg_o | 0x40000002;3081EMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval & 0xFF000000;3082EMC(EMC_DBG) = emc_dbg_o;30833084if (needs_tristate_training)3085{3086EMC(EMC_DBG) = emc_dbg_o | 2;3087EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = dst_emc_entry->burst_regs.emc_pmacro_autocal_cfg_common | 0x10000;30883089if (needs_ca_combo_training)3090EMC(EMC_FBIO_CFG5) = src_emc_entry->burst_regs.emc_fbio_cfg5 | 0x8000000;30913092EMC(EMC_DBG) = emc_dbg_o;30933094if (channel1_enabled)3095_ccfifo_write(EMC_CFG_SYNC, 0, 0);30963097_ccfifo_write(EMC_DBG, (emc_dbg_o & 0xF3FFFFFF) | 0x4000000, 0);3098}30993100// Step 10 - Self refresh3101EPRINTF("Step 10");3102_ccfifo_write(EMC_SELF_REF, 0x101, 0);31033104if (!needs_ca_combo_training && (dst_clock_period <= 2000))3105{3106_ccfifo_write(EMC_MRW3, mr13_flip_fspwr ^ 0x40, 0);3107_ccfifo_write(EMC_MRW6, (src_emc_entry->burst_regs.emc_mrw6 & 0xC0C0) | (dst_emc_entry->burst_regs.emc_mrw6 & 0xFFFF3F3F), 0);3108_ccfifo_write(EMC_MRW14, (src_emc_entry->burst_regs.emc_mrw14 & 0x3838) | (dst_emc_entry->burst_regs.emc_mrw14 & 0xFFFF0707), 0);3109if (dram_dev_num == TWO_RANK)3110{3111_ccfifo_write(EMC_MRW7, (src_emc_entry->burst_regs.emc_mrw7 & 0xC0C0) | (dst_emc_entry->burst_regs.emc_mrw7 & 0xFFFF3F3F), 0);3112_ccfifo_write(EMC_MRW15, (src_emc_entry->burst_regs.emc_mrw15 & 0x3838) | (dst_emc_entry->burst_regs.emc_mrw15 & 0xFFFF0707), 0);3113}31143115if (dram_dev_num == ONE_RANK || zcal_resistor_shared)3116emc_zq_cal = 0x80000001;3117else3118emc_zq_cal = 1;31193120_ccfifo_write(EMC_ZQ_CAL, emc_zq_cal, 0);3121}31223123emc_dbg_val = emc_dbg_o;3124u32 tRP_src_timing = (src_emc_entry->dram_timings.t_rp * 1000) / src_clock_period;3125bool in_self_refresh = false;3126u32 ref_delay = 0;31273128if (needs_tristate_training)3129{3130emc_dbg_val = (emc_dbg_o & 0xF3FFFFFF) | 0x44000000;3131_ccfifo_write(EMC_DBG, emc_dbg_val, 0);3132}31333134if (needs_ca_combo_training)3135{3136_ccfifo_write(EMC_PMACRO_DATA_RX_TERM_MODE, src_emc_entry->burst_regs.emc_pmacro_data_rx_term_mode & 0xFFFFFCCC, 0);31373138if (dram_dev_num == TWO_RANK && needs_swap_rank_training)3139{3140_ccfifo_write(EMC_MRW3, mr13_flip_fspop | 8, tRP_src_timing);3141_ccfifo_write(EMC_MRW3, mr13_catr_enable | 8, 0);3142}3143else3144_ccfifo_write(EMC_MRW3, mr13_catr_enable | 8, tRP_src_timing);31453146_ccfifo_write(EMC_TR_CTRL_0, 0x15A, 0);3147ref_delay = 1000000 / src_clock_period;3148}3149else3150{3151_ccfifo_write(EMC_MRW3, mr13_flip_fspop | 8, tRP_src_timing);3152ref_delay = tFC_lpddr4 / src_clock_period;3153}31543155_ccfifo_write(EMC_INTSTATUS, 0, ref_delay);3156_ccfifo_write(EMC_PIN, emc_pin_o & 0xFFFFFFF8, 30);31573158// Step 11 - Ramp down.3159EPRINTF("Step 11");3160_ccfifo_write(EMC_CFG_SYNC, 0, 0);3161_ccfifo_write(EMC_DBG, emc_dbg_val | 0x40000002, 0); // WRITE_MUX_ACTIVE | WRITE_ACTIVE_ONLY31623163ramp_down_wait = _dvfs_power_ramp_down(false, src_emc_entry, dst_emc_entry, src_clock_period);31643165// Step 12 - Trigger clock change.3166EPRINTF("Step 12");3167_ccfifo_write(EMC_STALL_THEN_EXE_AFTER_CLKCHANGE, 1, 0);3168if (!needs_tristate_training)3169_ccfifo_write(EMC_DBG, (emc_dbg_val & 0xBFFFFFFF) | 2, 0);31703171// Step 13 - Ramp up.3172EPRINTF("Step 13");3173ramp_up_wait = _dvfs_power_ramp_up(false, src_emc_entry, dst_emc_entry, needs_training, dst_clock_period);31743175_ccfifo_write(EMC_DBG, emc_dbg_val, 0);31763177// Step 14 - Bringup CKE pins.3178EPRINTF("Step 14");3179u32 emc_pin_val_final = 0;3180if (needs_ca_combo_training)3181{3182emc_pin_val_final = emc_pin_o & 0xFFFFFFF8;3183if (dram_dev_num == TWO_RANK)3184{3185if (needs_swap_rank_training)3186emc_pin_val_final |= 5;3187else3188emc_pin_val_final |= 6;3189}3190}3191else if (dram_dev_num == TWO_RANK)3192emc_pin_val_final = emc_pin_o | 7;3193else3194emc_pin_val_final = (emc_pin_o & 0xFFFFFFF8) | 1;31953196_ccfifo_write(EMC_PIN, emc_pin_val_final, 0);31973198// Step 15 - Zqlatch.3199EPRINTF("Step 15");3200if (!needs_ca_combo_training)3201{3202s32 zq_latch_dvfs_wait_time;3203u32 T_PDEX_timing = div_o3(dst_emc_entry->dram_timings.t_pdex * 1000, dst_clock_period);32043205if (dst_clock_period > 2000)3206zq_latch_dvfs_wait_time = (s32)tZQCAL_lpddr4_fc_adj - (s32)T_PDEX_timing;3207else3208zq_latch_dvfs_wait_time =3209(s32)tZQCAL_lpddr4_fc_adj - (ramp_up_wait + ramp_down_wait) / dst_clock_period;32103211if (dram_dev_num == ONE_RANK)3212{3213if (dst_clock_period > 2000)3214_ccfifo_write(EMC_ZQ_CAL, 0x80000001, T_PDEX_timing);32153216if (!needs_tristate_training)3217_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, T_PDEX_timing);32183219emc_zq_cal = 0x80000002;3220}3221else if (zcal_resistor_shared)3222{3223if (dst_clock_period > 2000)3224_ccfifo_write(EMC_ZQ_CAL, 0x80000001, T_PDEX_timing);32253226s32 T_PDEX_timing_final = zq_latch_dvfs_wait_time + (s32)T_PDEX_timing;32273228if (T_PDEX_timing_final < 0)3229T_PDEX_timing_final = 0;32303231_ccfifo_write(EMC_ZQ_CAL, 0x80000002, T_PDEX_timing_final);3232_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);32333234if (!needs_tristate_training)3235_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, 0);32363237emc_zq_cal = 0x40000002;3238zq_latch_dvfs_wait_time = 1000000 / dst_clock_period;3239}3240else3241{3242if (dst_clock_period > 2000)3243_ccfifo_write(EMC_ZQ_CAL, 1, T_PDEX_timing);32443245if (!needs_tristate_training)3246_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, T_PDEX_timing);32473248emc_zq_cal = 2;3249}32503251// Disable self-refresh.3252if (!needs_tristate_training)3253{3254#ifdef PERF_HACK3255// HACK: Setting ACTIVE_SELF_REF increases perf by 1-2%.3256_ccfifo_write(EMC_SELF_REF, 0x100, 0);3257#else3258_ccfifo_write(EMC_SELF_REF, 0, 0);3259#endif3260_ccfifo_write(EMC_REF, 0, 0);3261}32623263if (zq_latch_dvfs_wait_time < 0)3264zq_latch_dvfs_wait_time = 0;32653266_ccfifo_write(EMC_ZQ_CAL, emc_zq_cal, (u32)zq_latch_dvfs_wait_time);3267}32683269_ccfifo_write(EMC_INTSTATUS, 0, 10); // WAR: delay for zqlatch.32703271// Step 16 - LPDDR4 Conditional training kickoff.3272EPRINTF("Step 16");3273if (needs_tristate_training)3274{3275_ccfifo_write(EMC_INTSTATUS, 0, 1020000 / dst_clock_period);32763277u32 training_command = 0;32783279if (needs_ca_training)3280training_command |= (1 << 1); // CA: Initiates CA Training.3281if (needs_ca_vref_training)3282training_command |= (1 << 5); // CA_VREF: Initiates CA_VREF Training.3283if (needs_quse_training)3284training_command |= (1 << 4); // QUSE: Initiates QUSE Training.3285if (needs_quse_vref_training)3286training_command |= (1 << 8); // QUSE_VREF: Initiates DQS_VREF Training.3287if (needs_wr_training)3288training_command |= (1 << 3); // WR: Initiates WR Training.3289if (needs_wr_vref_training)3290training_command |= (1 << 6); // WR_VREF: Initiates OB (write) DRAM_VREF Training.3291if (needs_rd_training)3292training_command |= (1 << 2); // RD: Initiates RD Training.3293if (needs_rd_vref_training)3294training_command |= (1 << 7); // RD_VREF: Initiates IB_DQ_VREF Training.3295training_command |= (1 << 31); // GO: Start the Training.32963297_ccfifo_write(EMC_TRAINING_CMD, training_command, 0);32983299if (bg_regulator_mode_change)3300{3301if (enable_bg_regulator)3302_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,3303src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFE, 0);3304else3305_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,3306src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFB, 0);3307}33083309_ccfifo_write(EMC_SWITCH_BACK_CTRL, 1, 0);33103311if (!needs_ca_combo_training || needs_swap_rank_training)3312{3313_ccfifo_write(EMC_MRW3, mr13_flip_fspop ^ 0xC0, 0);3314_ccfifo_write(EMC_INTSTATUS, 0, 1000000 / dst_clock_period);3315}33163317_ccfifo_write(EMC_PIN, emc_pin_o & 0xFFFFFFF8, 0);3318_ccfifo_write(EMC_CFG_SYNC, 0, 0);3319_ccfifo_write(EMC_DBG, emc_dbg_val | 0x40000002, 0);33203321_dvfs_power_ramp_down(true, src_emc_entry, dst_emc_entry, dst_clock_period);33223323_ccfifo_write(EMC_STALL_THEN_EXE_AFTER_CLKCHANGE, 1, 0);3324_ccfifo_write(EMC_DBG, (emc_dbg_val & 0xBFFFFFFF) | 2, 0);33253326_dvfs_power_ramp_up(true, src_emc_entry, dst_emc_entry, needs_training, src_clock_period);33273328_ccfifo_write(EMC_DBG, emc_dbg_val, 0);33293330if (dram_dev_num == TWO_RANK)3331_ccfifo_write(EMC_PIN, emc_pin_o | 7, 0);3332else3333_ccfifo_write(EMC_PIN, (emc_pin_o & 0xFFFFFFF8) | 1, 0);33343335if (needs_ca_combo_training)3336{3337_ccfifo_write(EMC_TR_CTRL_0, 0x4A, 200000 / src_clock_period);3338_ccfifo_write(EMC_TR_CTRL_0, 0x40, 1000000 / src_clock_period);3339_ccfifo_write(EMC_MRW3, mr13_catr_enable & 0xFFFFFFFE, 0);3340_ccfifo_write(EMC_INTSTATUS, 0, 1000000 / src_clock_period);3341_ccfifo_write(EMC_PMACRO_DATA_RX_TERM_MODE, src_emc_entry->burst_regs.emc_pmacro_data_rx_term_mode, 0);3342}33433344_ccfifo_write(EMC_DBG, emc_dbg_o, 0);33453346_ccfifo_write(EMC_ZQ_CAL, 0x80000001, 0);3347_ccfifo_write(EMC_ZQ_CAL, 0x80000002, 1000000 / src_clock_period);33483349if ((!needs_ca_combo_training || needs_swap_rank_training) && dram_dev_num == TWO_RANK)3350{33513352_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);3353_ccfifo_write(EMC_ZQ_CAL, 0x40000002, 1000000 / src_clock_period);3354}33553356if (!needs_ca_combo_training)3357_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) ^ 0xC0000C0, 0);33583359_ccfifo_write(EMC_SELF_REF, 0, 0); // Was 0x100.3360}33613362// Step 19.2.3363EPRINTF("Step 19.2");3364if (bg_regulator_mode_change)3365{3366_ccfifo_write(EMC_DBG, emc_dbg_o | 2, 0);33673368u32 bg_regulator_switch_complete_wait_clks = 0;3369if (needs_tristate_training)3370{3371bg_regulator_switch_complete_wait_clks = 1250000 / src_clock_period;3372_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,3373src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0, bg_regulator_switch_complete_wait_clks);3374}3375else3376{3377if (ramp_up_wait <= 1250000)3378bg_regulator_switch_complete_wait_clks = (1250000 - ramp_up_wait) / dst_clock_period;3379_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,3380dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0, bg_regulator_switch_complete_wait_clks);3381}33823383_ccfifo_write(EMC_DBG, emc_dbg_o, 0);3384}33853386// Step 20 - Issue ref and optional QRST.3387EPRINTF("Step 20");3388if (needs_tristate_training)3389_ccfifo_write(EMC_REF, 0, 0);33903391// Step 21 - Restore ZCAL and ZCAL interval.3392EPRINTF("Step 21");3393_ccfifo_write(EMC_DBG, emc_dbg_o | 2, 0);33943395if (needs_tristate_training)3396_ccfifo_write(EMC_ZCAL_INTERVAL, src_emc_entry->burst_regs.emc_zcal_interval, 0);33973398_ccfifo_write(EMC_CFG, dst_emc_entry->burst_regs.emc_cfg & 0xEFFFFFFF, 0);33993400// Step 22 - Restore EMC_CFG_PIPE_CLK.3401EPRINTF("Step 22");3402//if (needs_tristate_training && dram_type == DRAM_TYPE_LPDDR4)////////////////3403if (needs_tristate_training)3404_ccfifo_write(EMC_SEL_DPD_CTRL, src_emc_entry->emc_sel_dpd_ctrl, 0);34053406_ccfifo_write(EMC_DBG, emc_dbg_o, 0);3407_ccfifo_write(EMC_CFG_PIPE_CLK, emc_cfg_pipe_clk_o, 0);34083409if (bg_regulator_mode_change)3410{3411if (enable_bg_regulator)3412EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFB;3413else3414EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFE;3415}34163417// Step 23 - Clock Change.3418EPRINTF("Step 23");3419// During training save current clock.3420if (needs_tristate_training)3421{3422u32 emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);3423CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_SAFE) = emc_clk_src;3424_change_dll_src(src_emc_entry, emc_clk_src);3425}34263427// Set CFG_DLL_MODE to RUN_PERIODIC.3428EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF24) | 0x88;3429(void)EMC(EMC_CFG_DIG_DLL);34303431(void)EMC(EMC_FBIO_CFG7);3432(void)MC(MC_EMEM_ADR_CFG);3433(void)EMC(EMC_INTSTATUS);34343435// Do clock change.3436CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = selected_clk_src_emc;3437(void)CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);34383439if (_wait_emc_status(EMC_INTSTATUS, CLKCHANGE_COMPLETE_INT, true, 0))3440return 4; // Clkchange handshake timeout error.34413442// Step 24 - Save training results.3443EPRINTF("Step 24");3444if (needs_tristate_training)3445{3446(void)MC(MC_EMEM_ADR_CFG);3447emc_dbg_val = EMC(EMC_DBG);3448EMC(EMC_DBG) |= 1;34493450_save_train_results(dst_emc_entry, needs_training, dram_dev_num, channel1_enabled);34513452EMC(EMC_DBG) = emc_dbg_val;3453}34543455// Step 25 - Program MC updown regs.3456EPRINTF("Step 25");3457if ((dst_emc_entry->rate_khz > src_emc_entry->rate_khz) && !needs_tristate_training)3458{3459for (u32 i = 0; dst_emc_entry->num_up_down > i; i++)3460MC(la_scale_regs_mc_addr_table[i]) = dst_emc_entry->la_scale_regs[i];34613462bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);3463if (_timing_update(dual_channel))3464return 4;3465}34663467// Step 26 - Restore ZCAL regs.3468EPRINTF("Step 26");3469if (!in_self_refresh)3470{3471EMC(EMC_DBG) = emc_dbg_o | 2;3472EMC(EMC_ZCAL_WAIT_CNT) = dst_emc_entry->burst_regs.emc_zcal_wait_cnt;3473EMC(EMC_ZCAL_INTERVAL) = dst_emc_entry->burst_regs.emc_zcal_interval;3474EMC(EMC_DBG) = emc_dbg_o;3475}34763477// Step 27 - Restore EMC_CFG, FDPD regs.3478EPRINTF("Step 27");3479EMC(EMC_DBG) = emc_dbg_o | 2;3480EMC(EMC_CFG) = dst_emc_entry->burst_regs.emc_cfg;3481EMC(EMC_DBG) = emc_dbg_o;3482EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = dst_emc_entry->emc_fdpd_ctrl_cmd_no_ramp;3483EMC(EMC_SEL_DPD_CTRL) = dst_emc_entry->emc_sel_dpd_ctrl;34843485// Step 28 - Training recover.3486EPRINTF("Step 28");3487if (needs_tristate_training)3488{3489EMC(EMC_DBG) = emc_dbg_o | 2;3490EMC(EMC_CFG) = dst_emc_entry->burst_regs.emc_cfg;3491EMC(EMC_SEL_DPD_CTRL) = dst_emc_entry->emc_sel_dpd_ctrl;3492EMC(EMC_ZCAL_WAIT_CNT) = src_emc_entry->burst_regs.emc_zcal_wait_cnt;3493EMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval;3494EMC(EMC_AUTO_CAL_CONFIG2) = src_emc_entry->emc_auto_cal_config2;3495EMC(EMC_AUTO_CAL_CONFIG3) = src_emc_entry->emc_auto_cal_config3;3496EMC(EMC_AUTO_CAL_CONFIG4) = src_emc_entry->emc_auto_cal_config4;3497EMC(EMC_AUTO_CAL_CONFIG5) = src_emc_entry->emc_auto_cal_config5;3498EMC(EMC_AUTO_CAL_CONFIG6) = src_emc_entry->emc_auto_cal_config6;3499EMC(EMC_AUTO_CAL_CONFIG7) = src_emc_entry->emc_auto_cal_config7;3500EMC(EMC_AUTO_CAL_CONFIG8) = src_emc_entry->emc_auto_cal_config8;3501EMC(EMC_DBG) = emc_dbg_o;3502EMC(EMC_TR_DVFS) = dst_emc_entry->burst_regs.emc_tr_dvfs & 0xFFFFFFFE;3503}35043505EMC(EMC_DBG) = emc_dbg_o | 2;3506EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = dst_emc_entry->burst_regs.emc_pmacro_autocal_cfg_common;3507EMC(EMC_DBG) = emc_dbg_o;35083509// Step 29 - Power fix WAR.3510EPRINTF("Step 29");3511EMC(EMC_PMACRO_CFG_PM_GLOBAL_0) = 0xFF0000;3512EMC(EMC_PMACRO_TRAINING_CTRL_0) = CH0_TRAINING_E_WRPTR;3513EMC(EMC_PMACRO_TRAINING_CTRL_1) = CH0_TRAINING_E_WRPTR;3514EMC(EMC_PMACRO_CFG_PM_GLOBAL_0) = 0;35153516// Step 30 - Re-enable autocal.3517EPRINTF("Step 30");3518if (needs_tristate_training)3519EMC(EMC_AUTO_CAL_CONFIG) = src_emc_entry->emc_auto_cal_config;3520else3521{3522if (dst_emc_entry->burst_regs.emc_cfg_dig_dll & 1)3523_digital_dll_enable_rs(channel1_enabled);3524EMC(EMC_AUTO_CAL_CONFIG) = dst_emc_entry->emc_auto_cal_config;3525}35263527return 0;3528}35293530static void _minerva_train_patterns(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, bool switch_rate, u32 selected_clk_src_emc)3531{3532u32 needs_training_num = 0;3533u32 emc_cfg_dig_dll_val = 0;3534u32 needs_training_emc_table[8] = {0};35353536u32 needs_training = dst_emc_entry->needs_training;35373538// Must start as true.3539if (train_ram_patterns)3540{3541u32 train_table_off = dst_emc_entry->training_pattern * 256;3542for (u32 i = 0; i < 256; i++)3543{3544EMC(EMC_TRAINING_PATRAM_DQ) = ram_pattern_dq_table[train_table_off + i];3545EMC(EMC_TRAINING_PATRAM_DMI) = ram_pattern_dmi_table[train_table_off + i] & 0xF;3546EMC(EMC_TRAINING_PATRAM_CTRL) = 0x80000000 + i;3547}3548train_ram_patterns = false;3549}35503551if (!dst_emc_entry->trained)3552{3553if (needs_training & NEEDS_TRAINING_CA_COMBO)3554{3555needs_training_emc_table[needs_training_num++] =3556needs_training & (NEEDS_TRAINING_CA_COMBO | NEEDS_TRAINING_IN_SELF_REFRESH);3557if (MC(MC_EMEM_ADR_CFG) & 1) // if mapping W8 (1KB page).3558needs_training_emc_table[needs_training_num++] =3559needs_training & (NEEDS_TRAINING_CA_COMBO | NEEDS_TRAINING_SWAP_RANK | NEEDS_TRAINING_IN_SELF_REFRESH);3560}35613562if (needs_training & NEEDS_TRAINING_QUSE_COMBO)3563{3564needs_training_emc_table[needs_training_num++] =3565needs_training & (NEEDS_TRAINING_QUSE_COMBO | NEEDS_TRAINING_IN_SELF_REFRESH);3566if (MC(MC_EMEM_ADR_CFG) & 1)3567needs_training_emc_table[needs_training_num++] =3568needs_training & (NEEDS_TRAINING_QUSE | NEEDS_TRAINING_IN_SELF_REFRESH);3569}35703571if (needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO))3572needs_training_emc_table[needs_training_num++] =3573needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO | NEEDS_TRAINING_IN_SELF_REFRESH);35743575for (u32 i = 0; needs_training_num > i; i++) // Runs more than once for needs_training CA/QUSE/WR/RD.3576{3577_minerva_set_clock(src_emc_entry, dst_emc_entry, needs_training_emc_table[i], selected_clk_src_emc);35783579bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);35803581EMC(EMC_DBG) = (EMC(EMC_DBG) & 0xF3FFFFFF) | 0x8000000;3582EMC(EMC_CFG_UPDATE) = (EMC(EMC_CFG_UPDATE) & 0xFFFFFFF9) | 4;3583_timing_update(dual_channel);35843585EMC(EMC_CFG_UPDATE) &= 0xFFFFFFF9;3586EMC(EMC_DBG) &= 0xF3FFFFFF;3587EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF3E) | 0x80;3588_timing_update(dual_channel);35893590emc_cfg_dig_dll_val = EMC(EMC_CFG_DIG_DLL) & 0xFFFFFFFE;3591if (dst_emc_entry->burst_regs.emc_cfg_dig_dll == 1)3592emc_cfg_dig_dll_val = EMC(EMC_CFG_DIG_DLL) | 1;3593EMC(EMC_CFG_DIG_DLL) = (emc_cfg_dig_dll_val & 0xFFFFFF3F) | 0x80;3594_timing_update(dual_channel);35953596while (!(EMC(EMC_DIG_DLL_STATUS) & 0x8000))3597;35983599// Bug 200024907.3600EMC(EMC_RP) = src_emc_entry->burst_regs.emc_rp;3601EMC(EMC_R2P) = src_emc_entry->burst_regs.emc_r2p;3602EMC(EMC_W2P) = src_emc_entry->burst_regs.emc_w2p;3603EMC(EMC_TRPAB) = src_emc_entry->burst_regs.emc_trpab;36043605_timing_update(dual_channel);3606}36073608EPRINTF("Trained");3609dst_emc_entry->trained = 1;3610}36113612if (switch_rate)3613_minerva_set_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);3614}36153616void _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg)3617{3618u32 dram_type = EMC(EMC_FBIO_CFG5) & 3;36193620// Only LPDDR chips are supported.3621if (dram_type != DRAM_TYPE_LPDDR4)3622return;36233624s32 dram_temp = _get_dram_temperature();36253626if (dram_temp < 0 || mtc_cfg->prev_temp == (u32)dram_temp)3627return;36283629u32 refr = mtc_cfg->current_emc_table->burst_regs.emc_refresh;3630u32 pre_refr = mtc_cfg->current_emc_table->burst_regs.emc_pre_refresh_req_cnt;3631u32 dyn_self_ref = mtc_cfg->current_emc_table->burst_regs.emc_dyn_self_ref_control;36323633switch (dram_temp)3634{3635// Normal temp (<= 85 oC).3636case 0:3637case 1:3638case 2:3639case 3:3640if (mtc_cfg->prev_temp < 4)3641{3642mtc_cfg->prev_temp = (u32)dram_temp;3643return;3644}3645break;3646// Over temp (> 85 oC).3647case 4: // 2x refresh.3648refr = (refr & 0xFFFF0000) | ((refr & 0xFFFF) >> REFRESH_X2);3649pre_refr = (pre_refr & 0xFFFF0000) | ((pre_refr & 0xFFFF) >> REFRESH_X2);3650dyn_self_ref = (dyn_self_ref & 0xFFFF0000) | ((dyn_self_ref & 0xFFFF) >> REFRESH_X2);3651break;3652case 5: // 4x refresh.3653case 6: // Temp 6 normally needs a derating emc table.3654refr = (refr & 0xFFFF0000) | ((refr & 0xFFFF) >> REFRESH_X4);3655pre_refr = (pre_refr & 0xFFFF0000) | ((pre_refr & 0xFFFF) >> REFRESH_X4);3656dyn_self_ref = (dyn_self_ref & 0xFFFF0000) | ((dyn_self_ref & 0xFFFF) >> REFRESH_X4);3657break;3658default:3659break;3660}36613662mtc_cfg->prev_temp = dram_temp;36633664EMC(EMC_REFRESH) = refr;3665EMC(EMC_PRE_REFRESH_REQ_CNT) = pre_refr;3666EMC(EMC_DYN_SELF_REF_CONTROL) = dyn_self_ref;3667}36683669u32 _minerva_do_periodic_compensation(emc_table_t *mtc_table_entry)3670{3671if (mtc_table_entry && mtc_table_entry->periodic_training)3672{3673u32 dram_dev_num = (MC(MC_EMEM_ADR_CFG) & 1) + 1;3674u32 pd_mask = (dram_dev_num == TWO_RANK) ? IN_POWERDOWN_BOTH_MASK : IN_POWERDOWN_1DEV_MASK;3675bool channel1_enabled = (mtc_table_entry->burst_regs.emc_fbio_cfg7 >> 2) & 1;36763677(void)EMC(EMC_DBG);36783679// Safekeep current config.3680u32 emc_cfg_o = EMC(EMC_CFG);3681u32 emc_cfg_dig_dll_o = EMC(EMC_CFG_DIG_DLL);3682u32 emc_cfg_update_o = EMC(EMC_CFG_UPDATE);36833684// Step 1 - Disable digital DLL.3685EMC(EMC_CFG_DIG_DLL) = emc_cfg_dig_dll_o & 0xFFFFFFFE;36863687// Step 1.2 - Always update auto cal in clock change.3688EMC(EMC_CFG_UPDATE) = (emc_cfg_update_o & 0xFFFFF9FF) | 0x400;36893690// Step 1.3 - Disable other power features.3691EMC(EMC_CFG) = emc_cfg_o & 0xFFFFFFF;36923693// Timing update and wait for everything to power down.3694_timing_update(channel1_enabled);36953696_wait_emc_status(EMC_EMC_STATUS, pd_mask, 0, EMC_CHANNEL0);3697if (channel1_enabled)3698_wait_emc_status(EMC_EMC_STATUS, pd_mask, 0, EMC_CHANNEL1);36993700_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, 0, EMC_CHANNEL0);3701if (channel1_enabled)3702_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, 0, EMC_CHANNEL1);37033704_wait_emc_status(EMC_CFG_DIG_DLL, 1, 0, EMC_CHANNEL0);3705if (channel1_enabled)3706_wait_emc_status(EMC_CFG_DIG_DLL, 1, 0, EMC_CHANNEL1);37073708// Step 2 - Osc kick off - this assumes training and dvfs have set correct MR23.3709_start_periodic_compensation();37103711// Step 3 - Let dram capture its clock tree delays.3712_usleep(1000 * _actual_osc_clocks(mtc_table_entry->run_clocks) / mtc_table_entry->rate_khz + 2);37133714// Step 4 - Check delta wrt previous values (save value if margin exceeds what is set in table).3715u32 adelta = _minerva_update_clock_tree_delay(mtc_table_entry, mtc_table_entry, dram_dev_num, channel1_enabled, PERIODIC_TRAINING_UPDATE);37163717// Step 5 - Apply compensation w.r.t. trained values (if clock tree has drifted more than the set margin).3718if (adelta && ((mtc_table_entry->rate_khz / 1000) * 128) * adelta / 1000000 > mtc_table_entry->tree_margin)3719{3720for (u32 i = 0; i < 10; i++)3721{3722EMC(periodic_training_addr[i]) =3723_minerva_apply_periodic_compensation_trimmer(mtc_table_entry, periodic_training_addr[i]);3724}3725}37263727// Step 6 - Restore other power features.3728EMC(EMC_CFG) = emc_cfg_o;37293730// Step 6.1 - Restore the DLL.3731EMC(EMC_CFG_DIG_DLL) = emc_cfg_dig_dll_o;37323733// Step 6.2 - Timing update for applying the new trimmers.3734_timing_update(channel1_enabled);37353736// Step 6.3 - Restore the UPDATE_DLL_IN_UPDATE field.3737EMC(EMC_CFG_UPDATE) = emc_cfg_update_o;3738}37393740return 0;3741}37423743static u32 _minerva_set_rate(mtc_config_t *mtc_cfg)3744{3745u32 src_emc_entry_idx = 999;3746u32 dst_emc_entry_idx = 999;3747u32 selected_clk_src_emc;3748u32 emc_clk_src;3749bool freq_changed = false;3750bool src_is_pllmb;3751emc_table_t *src_emc_entry;3752emc_table_t *dst_emc_entry;37533754if (mtc_cfg->table_entries > 900)3755return 4;37563757for (u32 i = 0; i < mtc_cfg->table_entries; i++)3758{3759u32 table_entry_rate = mtc_cfg->mtc_table[i].rate_khz;3760if (mtc_cfg->rate_from == table_entry_rate)3761src_emc_entry_idx = i;3762if (mtc_cfg->rate_to == table_entry_rate)3763dst_emc_entry_idx = i;3764}37653766if (src_emc_entry_idx >= mtc_cfg->table_entries)3767return 4;37683769if (dst_emc_entry_idx >= mtc_cfg->table_entries)3770return 4;37713772src_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[src_emc_entry_idx];3773dst_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[dst_emc_entry_idx];37743775u32 src_rate_khz = src_emc_entry->rate_khz;3776u32 dst_rate_khz = dst_emc_entry->rate_khz;3777u32 src_clk_src_emc = src_emc_entry->clk_src_emc;3778u32 dst_clk_src_emc = dst_emc_entry->clk_src_emc;37793780freq_changed = _check_freq_changed(dst_rate_khz, dst_clk_src_emc, src_rate_khz, src_clk_src_emc);3781EPRINTFARGS("Requested freq change from %d to %d.", src_rate_khz, dst_rate_khz);37823783// Get current clock source.3784emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) >> EMC_2X_CLK_SRC_SHIFT;3785src_is_pllmb = emc_clk_src == PLLMB_UD || emc_clk_src == PLLMB_OUT0;37863787if (freq_changed)3788{3789if (emc_clk_src == PLLM_UD ||3790emc_clk_src == PLLM_OUT0) // Clock source is PLLM. Switch based on src_is_pllmb.3791{3792src_is_pllmb = !src_is_pllmb;3793}3794else if (emc_clk_src == PLLMB_UD ||3795emc_clk_src == PLLMB_OUT0) // Clock source is PLLMB. Switch to PLLM.3796{3797src_is_pllmb = false;3798}3799selected_clk_src_emc = _pllm_clk_base_cfg(dst_rate_khz, dst_clk_src_emc, src_is_pllmb);3800}3801else3802{3803selected_clk_src_emc = dst_clk_src_emc;3804emc_clk_src = selected_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;3805if (src_is_pllmb)3806{3807if (emc_clk_src == PLLM_UD || emc_clk_src == PLLMB_UD)3808selected_clk_src_emc = (selected_clk_src_emc & 0x1FFFFFFF) | (PLLMB_UD << EMC_2X_CLK_SRC_SHIFT);3809else if (emc_clk_src == PLLM_OUT0 || emc_clk_src == PLLMB_OUT0)3810selected_clk_src_emc = (selected_clk_src_emc & 0x1FFFFFFF) | (PLLMB_OUT0 << EMC_2X_CLK_SRC_SHIFT);3811}3812}38133814switch (mtc_cfg->train_mode)3815{3816case OP_SWITCH:3817_minerva_set_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);3818mtc_cfg->current_emc_table = dst_emc_entry;3819mtc_cfg->rate_from = dst_emc_entry->rate_khz;3820if (dst_emc_entry->periodic_training)3821_minerva_do_periodic_compensation(dst_emc_entry);3822return 0;3823case OP_TRAIN:3824_minerva_train_patterns(src_emc_entry, dst_emc_entry, false, selected_clk_src_emc);3825return 0;3826case OP_TRAIN_SWITCH:3827_minerva_train_patterns(src_emc_entry, dst_emc_entry, true, selected_clk_src_emc);3828mtc_cfg->current_emc_table = dst_emc_entry;3829mtc_cfg->rate_from = dst_emc_entry->rate_khz;3830if (dst_emc_entry->periodic_training)3831_minerva_do_periodic_compensation(dst_emc_entry);3832return 0;3833default:3834return 4;3835}3836}38373838static void _minerva_get_table(mtc_config_t *mtc_cfg)3839{3840memset(mtc_cfg->mtc_table, 0, EMC_TABLE_ENTRY_SIZE_R7 * 10);38413842switch (mtc_cfg->sdram_id)3843{3844case DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN:3845memcpy(mtc_cfg->mtc_table, nx_abca2_2_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_R7);3846break;3847case DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH:3848case DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT:3849case DRAM_4GB_COPPER_SAMSUNG:3850case DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH:3851case DRAM_8GB_SAMSUNG_K4FBE3D4HM_MGXX:3852default:3853memcpy(mtc_cfg->mtc_table, nx_abca2_0_3_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_R7);3854if (mtc_cfg->sdram_id == DRAM_8GB_SAMSUNG_K4FBE3D4HM_MGXX)3855{3856for (u32 i = 0; i < EMC_TABLE_SIZE_R7 / EMC_TABLE_ENTRY_SIZE_R7; i++)3857{3858emc_table_t *table = &mtc_cfg->mtc_table[i];3859u32 period = 1000000000 / table->rate_khz;38603861table->burst_regs.emc_rfc = 280000 / period;3862table->shadow_regs_ca_train.emc_rfc = 280000 / period;3863table->shadow_regs_quse_train.emc_rfc = 280000 / period;3864table->shadow_regs_rdwr_train.emc_rfc = 280000 / period;38653866table->burst_regs.emc_rfcpb = 140000 / period;3867table->shadow_regs_ca_train.emc_rfcpb = 140000 / period;3868table->shadow_regs_quse_train.emc_rfcpb = 140000 / period;3869table->shadow_regs_rdwr_train.emc_rfcpb = 140000 / period;38703871table->burst_regs.emc_txsr = 287500 / period;3872table->shadow_regs_ca_train.emc_txsr = 287500 / period;3873table->shadow_regs_quse_train.emc_txsr = 287500 / period;3874table->shadow_regs_rdwr_train.emc_txsr = 287500 / period;38753876table->burst_regs.emc_txsrdll = table->burst_regs.emc_txsr;3877table->shadow_regs_ca_train.emc_txsrdll = table->shadow_regs_ca_train.emc_txsr;3878table->shadow_regs_quse_train.emc_txsrdll = table->shadow_regs_quse_train.emc_txsr;3879table->shadow_regs_rdwr_train.emc_txsrdll = table->shadow_regs_rdwr_train.emc_txsr;38803881table->burst_regs.emc_dyn_self_ref_control &= 0x7FFFFFFF;3882table->shadow_regs_ca_train.emc_dyn_self_ref_control &= 0x7FFFFFFF;3883table->shadow_regs_quse_train.emc_dyn_self_ref_control &= 0x7FFFFFFF;3884table->shadow_regs_rdwr_train.emc_dyn_self_ref_control &= 0x7FFFFFFF;38853886table->dram_timings.t_rfc = 280;3887}3888}3889break;3890}38913892mtc_cfg->table_entries = EMC_TABLE_SIZE_R7 / EMC_TABLE_ENTRY_SIZE_R7;3893mtc_cfg->rate_to = 0;3894mtc_cfg->rate_from = 0;3895mtc_cfg->train_mode = 0;3896mtc_cfg->prev_temp = 0;3897mtc_cfg->current_emc_table = NULL;38983899// Important!3900mtc_cfg->train_ram_patterns = true;3901mtc_cfg->init_done = MTC_INIT_MAGIC;3902}39033904void _minerva_init(mtc_config_t *mtc_cfg, bdkParams_t bp)3905{3906EPRINTF("-- Minerva Training Cell --");39073908train_ram_patterns = mtc_cfg->train_ram_patterns;39093910if (mtc_cfg->init_done != MTC_INIT_MAGIC)3911{3912if (mtc_cfg->init_done == MTC_NEW_MAGIC)3913{3914_minerva_get_table(mtc_cfg);3915#ifdef OVERCLOCK_VOLTAGE3916// Set SD1 regulator voltage.3917if ((bp->extension_magic & 0xF0FFFFFF) == IANOS_EXT0)3918bp->reg_voltage_set(1, OVERCLOCK_VOLTAGE);3919#endif3920}3921return;3922}39233924#ifdef OVERCLOCK_FREQ3925// Change max rate in table.3926mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz = OVERCLOCK_FREQ;39273928// Change rates for OC RAM.3929if (mtc_cfg->rate_from == MAX_FREQ_T210)3930mtc_cfg->rate_from = OVERCLOCK_FREQ;3931if (mtc_cfg->rate_to == MAX_FREQ_T210)3932mtc_cfg->rate_to = OVERCLOCK_FREQ;3933#endif39343935switch (mtc_cfg->train_mode)3936{3937case OP_SWITCH:3938EPRINTF("Switching..");3939_minerva_set_rate(mtc_cfg);3940break;3941case OP_TRAIN:3942EPRINTF("Training..");3943_minerva_set_rate(mtc_cfg);3944break;3945case OP_TRAIN_SWITCH:3946EPRINTF("Training and switching..");3947_minerva_set_rate(mtc_cfg);3948break;3949case OP_PERIODIC_TRAIN:3950EPRINTF("Periodic training..");3951_minerva_do_periodic_compensation(mtc_cfg->current_emc_table);3952break;3953case OP_TEMP_COMP:3954EPRINTF("Over temperature compensation..");3955_minerva_do_over_temp_compensation(mtc_cfg);3956break;3957}39583959#ifdef OVERCLOCK_FREQ3960// Restore rates for OC RAM.3961if (mtc_cfg->rate_from == OVERCLOCK_FREQ)3962mtc_cfg->rate_from = MAX_FREQ_T210;3963if (mtc_cfg->rate_to == OVERCLOCK_FREQ)3964mtc_cfg->rate_to = MAX_FREQ_T210;3965#endif39663967mtc_cfg->train_ram_patterns = train_ram_patterns;3968}396939703971