1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2020 Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <common.h>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD)
9*4882a593Smuzhiyun #include <debug_uart.h>
10*4882a593Smuzhiyun #include <dm.h>
11*4882a593Smuzhiyun #include <dm/root.h>
12*4882a593Smuzhiyun #include <dt-structs.h>
13*4882a593Smuzhiyun #include <ram.h>
14*4882a593Smuzhiyun #include <regmap.h>
15*4882a593Smuzhiyun #include <asm/io.h>
16*4882a593Smuzhiyun #include <asm/types.h>
17*4882a593Smuzhiyun #include <asm/arch/hardware.h>
18*4882a593Smuzhiyun #include <asm/arch/sdram_rv1108_pctl_phy.h>
19*4882a593Smuzhiyun #include <asm/arch/timer.h>
20*4882a593Smuzhiyun #include <asm/arch/sdram.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #if defined(CONFIG_ROCKCHIP_RV1108)
23*4882a593Smuzhiyun #include <asm/arch/sdram_rv1108.h>
24*4882a593Smuzhiyun #elif defined(CONFIG_ROCKCHIP_RK3308)
25*4882a593Smuzhiyun #include <asm/arch/sdram_rk3308.h>
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * we can not fit the code to access the device tree in SPL
30*4882a593Smuzhiyun * (due to 6K SRAM size limits), so these are hard-coded
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun
copy_to_reg(u32 * dest,const u32 * src,u32 n)33*4882a593Smuzhiyun void copy_to_reg(u32 *dest, const u32 *src, u32 n)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun int i;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun for (i = 0; i < n / sizeof(u32); i++) {
38*4882a593Smuzhiyun writel(*src, dest);
39*4882a593Smuzhiyun src++;
40*4882a593Smuzhiyun dest++;
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
phy_pctrl_reset(struct dram_info * priv)44*4882a593Smuzhiyun static void phy_pctrl_reset(struct dram_info *priv)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun phy_pctrl_reset_cru(priv);
47*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg0,
48*4882a593Smuzhiyun RESET_DIGITAL_CORE_MASK | RESET_ANALOG_LOGIC_MASK,
49*4882a593Smuzhiyun RESET_DIGITAL_CORE_ACT << RESET_DIGITAL_CORE_SHIFT |
50*4882a593Smuzhiyun RESET_ANALOG_LOGIC_ACT << RESET_ANALOG_LOGIC_SHIFT);
51*4882a593Smuzhiyun udelay(1);
52*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg0,
53*4882a593Smuzhiyun RESET_ANALOG_LOGIC_MASK,
54*4882a593Smuzhiyun RESET_ANALOG_LOGIC_DIS << RESET_ANALOG_LOGIC_SHIFT);
55*4882a593Smuzhiyun udelay(5);
56*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg0,
57*4882a593Smuzhiyun RESET_DIGITAL_CORE_MASK,
58*4882a593Smuzhiyun RESET_DIGITAL_CORE_DIS << RESET_DIGITAL_CORE_SHIFT);
59*4882a593Smuzhiyun udelay(1);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun
phy_dll_bypass_set(struct dram_info * priv,unsigned int freq)62*4882a593Smuzhiyun static void phy_dll_bypass_set(struct dram_info *priv, unsigned int freq)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg13,
65*4882a593Smuzhiyun CMD_DLL_BYPASS_MASK << CMD_DLL_BYPASS_SHIFT,
66*4882a593Smuzhiyun CMD_DLL_BYPASS << CMD_DLL_BYPASS_SHIFT);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun writel(CK_DLL_BYPASS_DISABLE << CK_DLL_BYPASS_SHIFT,
69*4882a593Smuzhiyun &priv->phy->phy_reg14);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg26,
72*4882a593Smuzhiyun LEFT_CHN_A_DQ_DLL_BYPASS_MASK << LEFT_CHN_A_DQ_DLL_SHIFT,
73*4882a593Smuzhiyun LEFT_CHN_A_DQ_DLL_BYPASS << LEFT_CHN_A_DQ_DLL_SHIFT);
74*4882a593Smuzhiyun writel(LEFT_CHN_A_DQS_DLL_BYPASS_DIS << LEFT_CHN_A_DQS_DLL_SHIFT,
75*4882a593Smuzhiyun &priv->phy->phy_reg27);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg36,
78*4882a593Smuzhiyun RIGHT_CHN_A_DQ_DLL_BYPASS_MASK << RIGHT_CHN_A_DQ_DLL_SHIFT,
79*4882a593Smuzhiyun RIGHT_CHN_A_DQ_DLL_BYPASS << RIGHT_CHN_A_DQ_DLL_SHIFT);
80*4882a593Smuzhiyun writel(RIGHT_CHN_A_DQS_DLL_BYPASS_DIS <<
81*4882a593Smuzhiyun RIGHT_CHN_A_DQS_DLL_SHIFT, &priv->phy->phy_reg37);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun if (freq <= PHY_LOW_SPEED_MHZ) {
84*4882a593Smuzhiyun writel(RIGHT_CHN_A_TX_DQ_BYPASS_SET <<
85*4882a593Smuzhiyun RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT |
86*4882a593Smuzhiyun LEFT_CHN_A_TX_DQ_BYPASS_SET <<
87*4882a593Smuzhiyun LEFT_CHN_A_TX_DQ_BYPASS_SHIFT |
88*4882a593Smuzhiyun CMD_CK_DLL_BYPASS_SET << CMD_CK_DLL_BYPASS_SHIFT,
89*4882a593Smuzhiyun &priv->phy->phy_regdll);
90*4882a593Smuzhiyun } else {
91*4882a593Smuzhiyun writel(RIGHT_CHN_A_TX_DQ_BYPASS_DIS <<
92*4882a593Smuzhiyun RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT |
93*4882a593Smuzhiyun LEFT_CHN_A_TX_DQ_BYPASS_DIS <<
94*4882a593Smuzhiyun LEFT_CHN_A_TX_DQ_BYPASS_SHIFT |
95*4882a593Smuzhiyun CMD_CK_DLL_BYPASS_DIS << CMD_CK_DLL_BYPASS_SHIFT,
96*4882a593Smuzhiyun &priv->phy->phy_regdll);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun ddr_phy_dqs_rx_dll_cfg(priv, freq);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
send_command(struct dram_info * priv,u32 rank,u32 cmd,u32 arg)102*4882a593Smuzhiyun static void send_command(struct dram_info *priv,
103*4882a593Smuzhiyun u32 rank, u32 cmd, u32 arg)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun writel((START_CMD | (rank << RANK_SEL_SHIFT) | arg | cmd),
106*4882a593Smuzhiyun &priv->pctl->mcmd);
107*4882a593Smuzhiyun while (readl(&priv->pctl->mcmd) & START_CMD)
108*4882a593Smuzhiyun ;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
memory_init(struct dram_info * priv,struct sdram_params * params_priv)111*4882a593Smuzhiyun static void memory_init(struct dram_info *priv,
112*4882a593Smuzhiyun struct sdram_params *params_priv)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun u32 mr0;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (params_priv->ddr_config_t.ddr_type == DDR3 ||
117*4882a593Smuzhiyun params_priv->ddr_config_t.ddr_type == DDR2) {
118*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, DESELECT_CMD, 0);
119*4882a593Smuzhiyun udelay(1);
120*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, PREA_CMD, 0);
121*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, DESELECT_CMD, 0);
122*4882a593Smuzhiyun udelay(1);
123*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
124*4882a593Smuzhiyun (MR2 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
125*4882a593Smuzhiyun (params_priv->ddr_timing_t.phy_timing.mr[2] &
126*4882a593Smuzhiyun CMD_ADDR_MASK) << CMD_ADDR_SHIFT);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
129*4882a593Smuzhiyun (MR3 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
130*4882a593Smuzhiyun (params_priv->ddr_timing_t.phy_timing.mr[3] &
131*4882a593Smuzhiyun CMD_ADDR_MASK) << CMD_ADDR_SHIFT);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
134*4882a593Smuzhiyun (MR1 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
135*4882a593Smuzhiyun (params_priv->ddr_timing_t.phy_timing.mr[1] &
136*4882a593Smuzhiyun CMD_ADDR_MASK) << CMD_ADDR_SHIFT);
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun mr0 = params_priv->ddr_timing_t.phy_timing.mr[0];
139*4882a593Smuzhiyun if (params_priv->ddr_config_t.ddr_type == DDR3) {
140*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
141*4882a593Smuzhiyun (MR0 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
142*4882a593Smuzhiyun (((mr0 | DDR3_DLL_RESET) &
143*4882a593Smuzhiyun CMD_ADDR_MASK) << CMD_ADDR_SHIFT));
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, ZQCL_CMD, 0);
146*4882a593Smuzhiyun } else {
147*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
148*4882a593Smuzhiyun (MR0 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
149*4882a593Smuzhiyun (((mr0 | DDR3_DLL_RESET) &
150*4882a593Smuzhiyun CMD_ADDR_MASK) << CMD_ADDR_SHIFT));
151*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, PREA_CMD, 0);
152*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, REF_CMD, 0);
153*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, REF_CMD, 0);
154*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
155*4882a593Smuzhiyun (MR0 & BANK_ADDR_MASK) <<
156*4882a593Smuzhiyun BANK_ADDR_SHIFT |
157*4882a593Smuzhiyun ((mr0 & CMD_ADDR_MASK) <<
158*4882a593Smuzhiyun CMD_ADDR_SHIFT));
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun } else {
161*4882a593Smuzhiyun /* reset */
162*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
163*4882a593Smuzhiyun (63 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
164*4882a593Smuzhiyun (0 & LPDDR23_OP_MASK) <<
165*4882a593Smuzhiyun LPDDR23_OP_SHIFT);
166*4882a593Smuzhiyun /* tINIT5 */
167*4882a593Smuzhiyun udelay(10);
168*4882a593Smuzhiyun /* ZQ calibration Init */
169*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0, MRS_CMD,
170*4882a593Smuzhiyun (10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
171*4882a593Smuzhiyun (0xFF & LPDDR23_OP_MASK) <<
172*4882a593Smuzhiyun LPDDR23_OP_SHIFT);
173*4882a593Smuzhiyun /* tZQINIT */
174*4882a593Smuzhiyun udelay(1);
175*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS1, MRS_CMD,
176*4882a593Smuzhiyun (10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
177*4882a593Smuzhiyun (0xFF & LPDDR23_OP_MASK) <<
178*4882a593Smuzhiyun LPDDR23_OP_SHIFT);
179*4882a593Smuzhiyun /* tZQINIT */
180*4882a593Smuzhiyun udelay(1);
181*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
182*4882a593Smuzhiyun (1 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
183*4882a593Smuzhiyun (params_priv->ddr_timing_t.phy_timing.mr[1] &
184*4882a593Smuzhiyun LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
185*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
186*4882a593Smuzhiyun (2 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
187*4882a593Smuzhiyun (params_priv->ddr_timing_t.phy_timing.mr[2] &
188*4882a593Smuzhiyun LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
189*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, MRS_CMD,
190*4882a593Smuzhiyun (3 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
191*4882a593Smuzhiyun (params_priv->ddr_timing_t.phy_timing.mr[3] &
192*4882a593Smuzhiyun LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
move_to_config_state(struct dram_info * priv)196*4882a593Smuzhiyun void move_to_config_state(struct dram_info *priv)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun unsigned int state;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun while (1) {
201*4882a593Smuzhiyun state = readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK;
202*4882a593Smuzhiyun switch (state) {
203*4882a593Smuzhiyun case LOW_POWER:
204*4882a593Smuzhiyun writel(WAKEUP_STATE, &priv->pctl->sctl);
205*4882a593Smuzhiyun while ((readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK)
206*4882a593Smuzhiyun != ACCESS)
207*4882a593Smuzhiyun ;
208*4882a593Smuzhiyun /*
209*4882a593Smuzhiyun * If at low power state, need wakeup first, and then
210*4882a593Smuzhiyun * enter the config, so fallthrough
211*4882a593Smuzhiyun */
212*4882a593Smuzhiyun case ACCESS:
213*4882a593Smuzhiyun case INIT_MEM:
214*4882a593Smuzhiyun writel(CFG_STATE, &priv->pctl->sctl);
215*4882a593Smuzhiyun while ((readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK)
216*4882a593Smuzhiyun != CONFIG)
217*4882a593Smuzhiyun ;
218*4882a593Smuzhiyun break;
219*4882a593Smuzhiyun case CONFIG:
220*4882a593Smuzhiyun return;
221*4882a593Smuzhiyun default:
222*4882a593Smuzhiyun break;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
move_to_access_state(struct dram_info * priv)227*4882a593Smuzhiyun void move_to_access_state(struct dram_info *priv)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun unsigned int state;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun while (1) {
232*4882a593Smuzhiyun state = readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK;
233*4882a593Smuzhiyun switch (state) {
234*4882a593Smuzhiyun case LOW_POWER:
235*4882a593Smuzhiyun writel(WAKEUP_STATE, &priv->pctl->sctl);
236*4882a593Smuzhiyun while ((readl(&priv->pctl->stat) &
237*4882a593Smuzhiyun PCTL_CTL_STAT_MASK) != ACCESS)
238*4882a593Smuzhiyun ;
239*4882a593Smuzhiyun break;
240*4882a593Smuzhiyun case INIT_MEM:
241*4882a593Smuzhiyun writel(CFG_STATE, &priv->pctl->sctl);
242*4882a593Smuzhiyun while ((readl(&priv->pctl->stat) &
243*4882a593Smuzhiyun PCTL_CTL_STAT_MASK) != CONFIG)
244*4882a593Smuzhiyun ;
245*4882a593Smuzhiyun /* fallthrough */
246*4882a593Smuzhiyun case CONFIG:
247*4882a593Smuzhiyun writel(GO_STATE, &priv->pctl->sctl);
248*4882a593Smuzhiyun while ((readl(&priv->pctl->stat) &
249*4882a593Smuzhiyun PCTL_CTL_STAT_MASK) != ACCESS)
250*4882a593Smuzhiyun ;
251*4882a593Smuzhiyun break;
252*4882a593Smuzhiyun case ACCESS:
253*4882a593Smuzhiyun return;
254*4882a593Smuzhiyun default:
255*4882a593Smuzhiyun break;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
pctl_cfg(struct dram_info * priv,struct sdram_params * params_priv)260*4882a593Smuzhiyun static void pctl_cfg(struct dram_info *priv,
261*4882a593Smuzhiyun struct sdram_params *params_priv)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun u32 reg;
264*4882a593Smuzhiyun u32 burstlen;
265*4882a593Smuzhiyun u32 bl_mddr_lpddr2;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /* DFI config */
268*4882a593Smuzhiyun writel(DFI_DATA_BYTE_DISABLE_EN << DFI_DATA_BYTE_DISABLE_EN_SHIFT |
269*4882a593Smuzhiyun DFI_INIT_START_EN << DFI_INIT_START_SHIFT,
270*4882a593Smuzhiyun &priv->pctl->dfistcfg0);
271*4882a593Smuzhiyun writel(DFI_DRAM_CLK_DISABLE_EN_DPD <<
272*4882a593Smuzhiyun DFI_DRAM_CLK_DISABLE_EN_DPD_SHIFT |
273*4882a593Smuzhiyun DFI_DRAM_CLK_DISABLE_EN << DFI_DRAM_CLK_DISABLE_EN_SHIFT,
274*4882a593Smuzhiyun &priv->pctl->dfistcfg1);
275*4882a593Smuzhiyun writel(PARITY_EN << PARITY_EN_SHIFT |
276*4882a593Smuzhiyun PARITY_INTR_EN << PARITY_INTR_EN_SHIFT, &priv->pctl->dfistcfg2);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun writel(TPHYUPD_TYPE0, &priv->pctl->dfitphyupdtype0);
279*4882a593Smuzhiyun writel(TPHY_RDLAT, &priv->pctl->dfitphyrdlat);
280*4882a593Smuzhiyun writel(TPHY_WRDATA, &priv->pctl->dfitphywrdata);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun writel(DFI_PHYUPD_DISABLE | DFI_CTRLUPD_DISABLE,
283*4882a593Smuzhiyun &priv->pctl->dfiupdcfg);
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun copy_to_reg(&priv->pctl->togcnt1u,
286*4882a593Smuzhiyun ¶ms_priv->ddr_timing_t.pctl_timing.togcnt1u,
287*4882a593Smuzhiyun sizeof(struct pctl_timing));
288*4882a593Smuzhiyun /*
289*4882a593Smuzhiyun * rv1108 phy is 1:2 mode, noc_timing.b.burstlen
290*4882a593Smuzhiyun * have divide by scheuler clock, so need to * 4
291*4882a593Smuzhiyun */
292*4882a593Smuzhiyun burstlen = params_priv->ddr_timing_t.noc_timing.b.burstlen * 4;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun if (params_priv->ddr_config_t.ddr_type == DDR3 ||
295*4882a593Smuzhiyun params_priv->ddr_config_t.ddr_type == DDR2) {
296*4882a593Smuzhiyun writel((RANK0_ODT_WRITE_SEL << RANK0_ODT_WRITE_SEL_SHIFT |
297*4882a593Smuzhiyun RANK1_ODT_WRITE_SEL << RANK1_ODT_WRITE_SEL_SHIFT),
298*4882a593Smuzhiyun &priv->pctl->dfiodtcfg);
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun writel(ODT_LEN_BL8_W << ODT_LEN_BL8_W_SHIFT,
301*4882a593Smuzhiyun &priv->pctl->dfiodtcfg1);
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun writel(params_priv->ddr_timing_t.pctl_timing.trsth,
304*4882a593Smuzhiyun &priv->pctl->trsth);
305*4882a593Smuzhiyun if (params_priv->ddr_config_t.ddr_type == DDR3)
306*4882a593Smuzhiyun writel(MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS | DDR3_EN |
307*4882a593Smuzhiyun MEM_BL_8 | TFAW_CFG_5_TDDR |
308*4882a593Smuzhiyun PD_EXIT_SLOW_EXIT_MODE | PD_TYPE_ACT_PD |
309*4882a593Smuzhiyun PD_IDLE_DISABLE |
310*4882a593Smuzhiyun params_priv->ddr_2t_en << TWO_T_SHIFT,
311*4882a593Smuzhiyun &priv->pctl->mcfg);
312*4882a593Smuzhiyun else if (burstlen == 8)
313*4882a593Smuzhiyun writel(MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS | DDR2_EN |
314*4882a593Smuzhiyun MEM_BL_8 | TFAW_CFG_5_TDDR |
315*4882a593Smuzhiyun PD_EXIT_SLOW_EXIT_MODE | PD_TYPE_ACT_PD |
316*4882a593Smuzhiyun PD_IDLE_DISABLE |
317*4882a593Smuzhiyun params_priv->ddr_2t_en << TWO_T_SHIFT,
318*4882a593Smuzhiyun &priv->pctl->mcfg);
319*4882a593Smuzhiyun else
320*4882a593Smuzhiyun writel(MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS | DDR2_EN |
321*4882a593Smuzhiyun MEM_BL_4 | TFAW_CFG_5_TDDR |
322*4882a593Smuzhiyun PD_EXIT_SLOW_EXIT_MODE | PD_TYPE_ACT_PD |
323*4882a593Smuzhiyun PD_IDLE_DISABLE |
324*4882a593Smuzhiyun params_priv->ddr_2t_en << TWO_T_SHIFT,
325*4882a593Smuzhiyun &priv->pctl->mcfg);
326*4882a593Smuzhiyun writel(DFI_LP_EN_SR << DFI_LP_EN_SR_SHIFT |
327*4882a593Smuzhiyun DFI_LP_WAKEUP_SR_32_CYCLES << DFI_LP_WAKEUP_SR_SHIFT |
328*4882a593Smuzhiyun DFI_TLP_RESP << DFI_TLP_RESP_SHIFT,
329*4882a593Smuzhiyun &priv->pctl->dfilpcfg0);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun reg = readl(&priv->pctl->tcl);
332*4882a593Smuzhiyun writel((reg - 1) / 2 - 1, &priv->pctl->dfitrddataen);
333*4882a593Smuzhiyun reg = readl(&priv->pctl->tcwl);
334*4882a593Smuzhiyun writel((reg - 1) / 2 - 1, &priv->pctl->dfitphywrlat);
335*4882a593Smuzhiyun } else {
336*4882a593Smuzhiyun if (burstlen == 4)
337*4882a593Smuzhiyun bl_mddr_lpddr2 = MDDR_LPDDR2_BL_4;
338*4882a593Smuzhiyun else
339*4882a593Smuzhiyun bl_mddr_lpddr2 = MDDR_LPDDR2_BL_8;
340*4882a593Smuzhiyun writel((RANK0_ODT_WRITE_DIS << RANK0_ODT_WRITE_SEL_SHIFT |
341*4882a593Smuzhiyun RANK1_ODT_WRITE_DIS << RANK1_ODT_WRITE_SEL_SHIFT),
342*4882a593Smuzhiyun &priv->pctl->dfiodtcfg);
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun writel(ODT_LEN_BL8_W_0 << ODT_LEN_BL8_W_SHIFT,
345*4882a593Smuzhiyun &priv->pctl->dfiodtcfg1);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun writel(0, &priv->pctl->trsth);
348*4882a593Smuzhiyun writel(MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS | LPDDR2_EN |
349*4882a593Smuzhiyun LPDDR2_S4 | bl_mddr_lpddr2 |
350*4882a593Smuzhiyun TFAW_CFG_6_TDDR | PD_EXIT_FAST_EXIT_MODE |
351*4882a593Smuzhiyun PD_TYPE_ACT_PD | PD_IDLE_DISABLE, &priv->pctl->mcfg);
352*4882a593Smuzhiyun writel(DFI_LP_EN_SR << DFI_LP_EN_SR_SHIFT |
353*4882a593Smuzhiyun DFI_LP_WAKEUP_SR_32_CYCLES << DFI_LP_WAKEUP_SR_SHIFT |
354*4882a593Smuzhiyun DFI_TLP_RESP << DFI_TLP_RESP_SHIFT |
355*4882a593Smuzhiyun DFI_LP_WAKEUP_PD_32_CYCLES << DFI_LP_WAKEUP_PD_SHIFT |
356*4882a593Smuzhiyun DFI_LP_EN_PD,
357*4882a593Smuzhiyun &priv->pctl->dfilpcfg0);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun reg = readl(&priv->pctl->tcl);
360*4882a593Smuzhiyun writel(reg / 2 - 1, &priv->pctl->dfitrddataen);
361*4882a593Smuzhiyun reg = readl(&priv->pctl->tcwl);
362*4882a593Smuzhiyun writel(reg / 2 - 1, &priv->pctl->dfitphywrlat);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun pctl_cfg_grf(priv, params_priv);
365*4882a593Smuzhiyun setbits_le32(&priv->pctl->scfg, HW_LOW_POWER_EN);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun /* only support x16 memory */
368*4882a593Smuzhiyun clrsetbits_le32(&priv->pctl->ppcfg, PPMEM_EN_MASK, PPMEM_EN);
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
phy_cfg(struct dram_info * priv,struct sdram_params * params_priv)371*4882a593Smuzhiyun static void phy_cfg(struct dram_info *priv,
372*4882a593Smuzhiyun struct sdram_params *params_priv)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun u32 burstlen;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun burstlen = params_priv->ddr_timing_t.noc_timing.b.burstlen * 4;
377*4882a593Smuzhiyun burstlen = (burstlen == 4) ? PHY_BL_4 : PHY_BL_8;
378*4882a593Smuzhiyun ddr_msch_cfg(priv, params_priv);
379*4882a593Smuzhiyun ddr_phy_skew_cfg(priv);
380*4882a593Smuzhiyun switch (params_priv->ddr_config_t.ddr_type) {
381*4882a593Smuzhiyun case DDR2:
382*4882a593Smuzhiyun writel(MEMORY_SELECT_DDR2 | PHY_BL_8, &priv->phy->phy_reg1);
383*4882a593Smuzhiyun break;
384*4882a593Smuzhiyun case DDR3:
385*4882a593Smuzhiyun writel(MEMORY_SELECT_DDR3 | PHY_BL_8, &priv->phy->phy_reg1);
386*4882a593Smuzhiyun break;
387*4882a593Smuzhiyun case LPDDR2:
388*4882a593Smuzhiyun default:
389*4882a593Smuzhiyun writel(MEMORY_SELECT_LPDDR2 | burstlen, &priv->phy->phy_reg1);
390*4882a593Smuzhiyun break;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun writel(params_priv->ddr_timing_t.phy_timing.cl_al,
394*4882a593Smuzhiyun &priv->phy->phy_regb);
395*4882a593Smuzhiyun writel(params_priv->ddr_timing_t.pctl_timing.tcwl,
396*4882a593Smuzhiyun &priv->phy->phy_regc);
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun set_ds_odt(priv, params_priv);
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun /* only support x16 memory */
401*4882a593Smuzhiyun clrsetbits_le32(&priv->phy->phy_reg0, DQ_16BIT_EN_MASK,
402*4882a593Smuzhiyun DQ_16BIT_EN);
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
dram_cfg_rbc(struct dram_info * priv,struct sdram_params * params_priv)405*4882a593Smuzhiyun static void dram_cfg_rbc(struct dram_info *priv,
406*4882a593Smuzhiyun struct sdram_params *params_priv)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun move_to_config_state(priv);
409*4882a593Smuzhiyun ddr_msch_cfg_rbc(params_priv, priv);
410*4882a593Smuzhiyun move_to_access_state(priv);
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
data_training(struct dram_info * priv)413*4882a593Smuzhiyun static void data_training(struct dram_info *priv)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun u32 value;
416*4882a593Smuzhiyun u32 tmp = 0;
417*4882a593Smuzhiyun u32 tmp1 = 0;
418*4882a593Smuzhiyun u32 timeout = 1000;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun /* disable auto refresh */
421*4882a593Smuzhiyun value = readl(&priv->pctl->trefi);
422*4882a593Smuzhiyun writel(UPD_REF, &priv->pctl->trefi);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun tmp1 = readl(&priv->phy->phy_reg2);
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_DIS | tmp1,
427*4882a593Smuzhiyun &priv->phy->phy_reg2);
428*4882a593Smuzhiyun writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_ACT | tmp1,
429*4882a593Smuzhiyun &priv->phy->phy_reg2);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun /* delay until data training done */
432*4882a593Smuzhiyun while (tmp != (CHN_A_HIGH_8BIT_TRAINING_DONE |
433*4882a593Smuzhiyun CHN_A_LOW_8BIT_TRAINING_DONE)) {
434*4882a593Smuzhiyun udelay(1);
435*4882a593Smuzhiyun tmp = (readl(&priv->phy->phy_regff) & CHN_A_TRAINING_DONE_MASK);
436*4882a593Smuzhiyun timeout--;
437*4882a593Smuzhiyun if (!timeout)
438*4882a593Smuzhiyun break;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_DIS | tmp1,
442*4882a593Smuzhiyun &priv->phy->phy_reg2);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun send_command(priv, RANK_SEL_CS0_CS1, PREA_CMD, 0);
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun writel(value | UPD_REF, &priv->pctl->trefi);
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
sdram_detect(struct dram_info * priv,struct sdram_params * params_priv)449*4882a593Smuzhiyun static int sdram_detect(struct dram_info *priv,
450*4882a593Smuzhiyun struct sdram_params *params_priv)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun u32 row, col, row_max, col_max, bank_max;
453*4882a593Smuzhiyun u32 bw = 1;
454*4882a593Smuzhiyun phys_addr_t test_addr;
455*4882a593Smuzhiyun struct ddr_schedule ddr_sch;
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun /* if col detect wrong,row needs initial */
458*4882a593Smuzhiyun row = 0;
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun /* detect col */
461*4882a593Smuzhiyun move_to_config_state(priv);
462*4882a593Smuzhiyun ddr_msch_get_max_col(priv, &ddr_sch);
463*4882a593Smuzhiyun col_max = ddr_sch.col;
464*4882a593Smuzhiyun bank_max = ddr_sch.bank;
465*4882a593Smuzhiyun move_to_access_state(priv);
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun for (col = col_max; col >= 10; col--) {
468*4882a593Smuzhiyun writel(0, CONFIG_SYS_SDRAM_BASE);
469*4882a593Smuzhiyun test_addr = (phys_addr_t)(CONFIG_SYS_SDRAM_BASE +
470*4882a593Smuzhiyun (1ul << (col + bw - 1ul)));
471*4882a593Smuzhiyun writel(PATTERN, test_addr);
472*4882a593Smuzhiyun if ((readl(test_addr) == PATTERN) &&
473*4882a593Smuzhiyun (readl(CONFIG_SYS_SDRAM_BASE) == 0))
474*4882a593Smuzhiyun break;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun if (col <= 9)
477*4882a593Smuzhiyun goto cap_err;
478*4882a593Smuzhiyun params_priv->ddr_config_t.col = col;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun if (params_priv->ddr_config_t.ddr_type == DDR3) {
481*4882a593Smuzhiyun params_priv->ddr_config_t.bank = 3;
482*4882a593Smuzhiyun } else {
483*4882a593Smuzhiyun writel(0, CONFIG_SYS_SDRAM_BASE);
484*4882a593Smuzhiyun test_addr = (phys_addr_t)(CONFIG_SYS_SDRAM_BASE +
485*4882a593Smuzhiyun (1ul << (bank_max + col_max +
486*4882a593Smuzhiyun bw - 1ul)));
487*4882a593Smuzhiyun writel(PATTERN, test_addr);
488*4882a593Smuzhiyun if ((readl(test_addr) == PATTERN) &&
489*4882a593Smuzhiyun (readl(CONFIG_SYS_SDRAM_BASE) == 0))
490*4882a593Smuzhiyun params_priv->ddr_config_t.bank = 3;
491*4882a593Smuzhiyun else
492*4882a593Smuzhiyun params_priv->ddr_config_t.bank = 2;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun /* detect row */
496*4882a593Smuzhiyun move_to_config_state(priv);
497*4882a593Smuzhiyun ddr_msch_get_max_row(priv, &ddr_sch);
498*4882a593Smuzhiyun move_to_access_state(priv);
499*4882a593Smuzhiyun col_max = ddr_sch.col;
500*4882a593Smuzhiyun row_max = ddr_sch.row;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun for (row = row_max; row >= 12; row--) {
503*4882a593Smuzhiyun writel(0, CONFIG_SYS_SDRAM_BASE);
504*4882a593Smuzhiyun test_addr = (phys_addr_t)(CONFIG_SYS_SDRAM_BASE +
505*4882a593Smuzhiyun (1ul << (row + bank_max +
506*4882a593Smuzhiyun col_max + bw - 1ul)));
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun writel(PATTERN, test_addr);
509*4882a593Smuzhiyun if ((readl(test_addr) == PATTERN) &&
510*4882a593Smuzhiyun (readl(CONFIG_SYS_SDRAM_BASE) == 0))
511*4882a593Smuzhiyun break;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun if (row <= 11)
514*4882a593Smuzhiyun goto cap_err;
515*4882a593Smuzhiyun params_priv->ddr_config_t.cs0_row = row;
516*4882a593Smuzhiyun return 0;
517*4882a593Smuzhiyun cap_err:
518*4882a593Smuzhiyun return -EAGAIN;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun #define DDR_VERSION 0x2
522*4882a593Smuzhiyun
sdram_all_config(struct dram_info * priv,struct sdram_params * params_priv)523*4882a593Smuzhiyun static void sdram_all_config(struct dram_info *priv,
524*4882a593Smuzhiyun struct sdram_params *params_priv)
525*4882a593Smuzhiyun {
526*4882a593Smuzhiyun u32 version = DDR_VERSION;
527*4882a593Smuzhiyun u32 os_reg = 0;
528*4882a593Smuzhiyun u32 row_12 = 0;
529*4882a593Smuzhiyun u32 ddr_info = 0;
530*4882a593Smuzhiyun /* rk3308,rv1108 only support 1 channel, x16 ddr bus, x16 memory */
531*4882a593Smuzhiyun u32 chn_cnt = 0;
532*4882a593Smuzhiyun u32 rank = 1;
533*4882a593Smuzhiyun u32 bw = 1;
534*4882a593Smuzhiyun u32 dbw = 1;
535*4882a593Smuzhiyun size_t size = 0;
536*4882a593Smuzhiyun struct ddr_param ddr_param;
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun /* os_reg2 */
539*4882a593Smuzhiyun os_reg = (params_priv->ddr_config_t.ddr_type & SYS_REG_DDRTYPE_MASK) <<
540*4882a593Smuzhiyun SYS_REG_DDRTYPE_SHIFT |
541*4882a593Smuzhiyun (chn_cnt & SYS_REG_NUM_CH_MASK) <<
542*4882a593Smuzhiyun SYS_REG_NUM_CH_SHIFT |
543*4882a593Smuzhiyun ((rank - 1) & SYS_REG_RANK_MASK) <<
544*4882a593Smuzhiyun SYS_REG_RANK_SHIFT(0) |
545*4882a593Smuzhiyun ((params_priv->ddr_config_t.col - 9) & SYS_REG_COL_MASK) <<
546*4882a593Smuzhiyun SYS_REG_COL_SHIFT(0) |
547*4882a593Smuzhiyun ((params_priv->ddr_config_t.bank == 3 ? 0 : 1) &
548*4882a593Smuzhiyun SYS_REG_BK_MASK) << SYS_REG_BK_SHIFT(0) |
549*4882a593Smuzhiyun ((params_priv->ddr_config_t.cs0_row - 13) &
550*4882a593Smuzhiyun SYS_REG_CS0_ROW_MASK) << SYS_REG_CS0_ROW_SHIFT(0) |
551*4882a593Smuzhiyun (bw & SYS_REG_BW_MASK) <<
552*4882a593Smuzhiyun SYS_REG_BW_SHIFT(0) |
553*4882a593Smuzhiyun (dbw & SYS_REG_DBW_MASK) <<
554*4882a593Smuzhiyun SYS_REG_DBW_SHIFT(0);
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun writel(os_reg, &priv->grf->os_reg2);
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun /* os_reg3 */
559*4882a593Smuzhiyun if (params_priv->ddr_config_t.cs0_row == 12)
560*4882a593Smuzhiyun row_12 = 1;
561*4882a593Smuzhiyun os_reg = (version & SYS_REG1_VERSION_MASK) <<
562*4882a593Smuzhiyun SYS_REG1_VERSION_SHIFT | (row_12 &
563*4882a593Smuzhiyun SYS_REG1_EXTEND_CS0_ROW_MASK) <<
564*4882a593Smuzhiyun SYS_REG1_EXTEND_CS0_ROW_SHIFT(0);
565*4882a593Smuzhiyun writel(os_reg, &priv->grf->os_reg3);
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun printascii("In\n");
568*4882a593Smuzhiyun printdec(params_priv->ddr_timing_t.freq);
569*4882a593Smuzhiyun printascii("MHz\n");
570*4882a593Smuzhiyun switch (params_priv->ddr_config_t.ddr_type & SYS_REG_DDRTYPE_MASK) {
571*4882a593Smuzhiyun case 2:
572*4882a593Smuzhiyun printascii("DDR2\n");
573*4882a593Smuzhiyun break;
574*4882a593Smuzhiyun case 5:
575*4882a593Smuzhiyun printascii("LPDDR2\n");
576*4882a593Smuzhiyun break;
577*4882a593Smuzhiyun case 3:
578*4882a593Smuzhiyun default:
579*4882a593Smuzhiyun printascii("DDR3\n");
580*4882a593Smuzhiyun break;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun printascii(" Col=");
583*4882a593Smuzhiyun printdec(params_priv->ddr_config_t.col);
584*4882a593Smuzhiyun printascii(" Bank=");
585*4882a593Smuzhiyun printdec(params_priv->ddr_config_t.bank);
586*4882a593Smuzhiyun printascii(" Row=");
587*4882a593Smuzhiyun printdec(params_priv->ddr_config_t.cs0_row);
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun size = 1llu << (bw +
590*4882a593Smuzhiyun params_priv->ddr_config_t.col +
591*4882a593Smuzhiyun params_priv->ddr_config_t.cs0_row +
592*4882a593Smuzhiyun params_priv->ddr_config_t.bank);
593*4882a593Smuzhiyun ddr_info = size >> 20;
594*4882a593Smuzhiyun printascii(" Size=");
595*4882a593Smuzhiyun printdec(ddr_info);
596*4882a593Smuzhiyun printascii("MB\n");
597*4882a593Smuzhiyun printascii("msch:");
598*4882a593Smuzhiyun ddr_info = readl(&priv->service_msch->ddrconf);
599*4882a593Smuzhiyun printdec(ddr_info);
600*4882a593Smuzhiyun printascii("\n");
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun priv->info.base = CONFIG_SYS_SDRAM_BASE;
603*4882a593Smuzhiyun priv->info.size = size;
604*4882a593Smuzhiyun ddr_param.count = 1;
605*4882a593Smuzhiyun ddr_param.para[0] = priv->info.base;
606*4882a593Smuzhiyun ddr_param.para[1] = priv->info.size;
607*4882a593Smuzhiyun rockchip_setup_ddr_param(&ddr_param);
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun
rv1108_sdram_init(struct dram_info * sdram_priv,struct sdram_params * params_priv)610*4882a593Smuzhiyun int rv1108_sdram_init(struct dram_info *sdram_priv,
611*4882a593Smuzhiyun struct sdram_params *params_priv)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun /* pmu enable ddr io retention */
614*4882a593Smuzhiyun enable_ddr_io_ret(sdram_priv);
615*4882a593Smuzhiyun rkdclk_init(sdram_priv, params_priv);
616*4882a593Smuzhiyun phy_pctrl_reset(sdram_priv);
617*4882a593Smuzhiyun phy_dll_bypass_set(sdram_priv, params_priv->ddr_timing_t.freq);
618*4882a593Smuzhiyun pctl_cfg(sdram_priv, params_priv);
619*4882a593Smuzhiyun phy_cfg(sdram_priv, params_priv);
620*4882a593Smuzhiyun writel(POWER_UP_START, &sdram_priv->pctl->powctl);
621*4882a593Smuzhiyun while (!(readl(&sdram_priv->pctl->powstat) & POWER_UP_DONE))
622*4882a593Smuzhiyun ;
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun memory_init(sdram_priv, params_priv);
625*4882a593Smuzhiyun re_training:
626*4882a593Smuzhiyun move_to_config_state(sdram_priv);
627*4882a593Smuzhiyun data_training(sdram_priv);
628*4882a593Smuzhiyun move_to_access_state(sdram_priv);
629*4882a593Smuzhiyun if (sdram_detect(sdram_priv, params_priv)) {
630*4882a593Smuzhiyun while (1)
631*4882a593Smuzhiyun ;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun if (check_rd_gate(sdram_priv))
634*4882a593Smuzhiyun goto re_training;
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun /* workaround data training not in middle */
637*4882a593Smuzhiyun modify_data_training(sdram_priv, params_priv);
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun dram_cfg_rbc(sdram_priv, params_priv);
640*4882a593Smuzhiyun sdram_all_config(sdram_priv, params_priv);
641*4882a593Smuzhiyun enable_low_power(sdram_priv, params_priv);
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun return 0;
644*4882a593Smuzhiyun }
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun #endif /* CONFIG_TPL_BUILD */
647