1*ff9112dfSStefan Roese /*
2*ff9112dfSStefan Roese * Copyright (C) Marvell International Ltd. and its affiliates
3*ff9112dfSStefan Roese *
4*ff9112dfSStefan Roese * SPDX-License-Identifier: GPL-2.0
5*ff9112dfSStefan Roese */
6*ff9112dfSStefan Roese
7*ff9112dfSStefan Roese #include <common.h>
8*ff9112dfSStefan Roese #include <i2c.h>
9*ff9112dfSStefan Roese #include <spl.h>
10*ff9112dfSStefan Roese #include <asm/io.h>
11*ff9112dfSStefan Roese #include <asm/arch/cpu.h>
12*ff9112dfSStefan Roese #include <asm/arch/soc.h>
13*ff9112dfSStefan Roese
14*ff9112dfSStefan Roese #include "ddr3_hw_training.h"
15*ff9112dfSStefan Roese
16*ff9112dfSStefan Roese /*
17*ff9112dfSStefan Roese * Debug
18*ff9112dfSStefan Roese */
19*ff9112dfSStefan Roese #define DEBUG_DFS_C(s, d, l) \
20*ff9112dfSStefan Roese DEBUG_DFS_S(s); DEBUG_DFS_D(d, l); DEBUG_DFS_S("\n")
21*ff9112dfSStefan Roese #define DEBUG_DFS_FULL_C(s, d, l) \
22*ff9112dfSStefan Roese DEBUG_DFS_FULL_S(s); DEBUG_DFS_FULL_D(d, l); DEBUG_DFS_FULL_S("\n")
23*ff9112dfSStefan Roese
24*ff9112dfSStefan Roese #ifdef MV_DEBUG_DFS
25*ff9112dfSStefan Roese #define DEBUG_DFS_S(s) puts(s)
26*ff9112dfSStefan Roese #define DEBUG_DFS_D(d, l) printf("%x", d)
27*ff9112dfSStefan Roese #else
28*ff9112dfSStefan Roese #define DEBUG_DFS_S(s)
29*ff9112dfSStefan Roese #define DEBUG_DFS_D(d, l)
30*ff9112dfSStefan Roese #endif
31*ff9112dfSStefan Roese
32*ff9112dfSStefan Roese #ifdef MV_DEBUG_DFS_FULL
33*ff9112dfSStefan Roese #define DEBUG_DFS_FULL_S(s) puts(s)
34*ff9112dfSStefan Roese #define DEBUG_DFS_FULL_D(d, l) printf("%x", d)
35*ff9112dfSStefan Roese #else
36*ff9112dfSStefan Roese #define DEBUG_DFS_FULL_S(s)
37*ff9112dfSStefan Roese #define DEBUG_DFS_FULL_D(d, l)
38*ff9112dfSStefan Roese #endif
39*ff9112dfSStefan Roese
40*ff9112dfSStefan Roese #if defined(MV88F672X)
41*ff9112dfSStefan Roese extern u8 div_ratio[CLK_VCO][CLK_DDR];
42*ff9112dfSStefan Roese extern void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps);
43*ff9112dfSStefan Roese #else
44*ff9112dfSStefan Roese extern u16 odt_dynamic[ODT_OPT][MAX_CS];
45*ff9112dfSStefan Roese extern u8 div_ratio1to1[CLK_CPU][CLK_DDR];
46*ff9112dfSStefan Roese extern u8 div_ratio2to1[CLK_CPU][CLK_DDR];
47*ff9112dfSStefan Roese #endif
48*ff9112dfSStefan Roese extern u16 odt_static[ODT_OPT][MAX_CS];
49*ff9112dfSStefan Roese
50*ff9112dfSStefan Roese extern u32 cpu_fab_clk_to_hclk[FAB_OPT][CLK_CPU];
51*ff9112dfSStefan Roese
52*ff9112dfSStefan Roese extern u32 ddr3_get_vco_freq(void);
53*ff9112dfSStefan Roese
54*ff9112dfSStefan Roese u32 ddr3_get_freq_parameter(u32 target_freq, int ratio_2to1);
55*ff9112dfSStefan Roese
56*ff9112dfSStefan Roese #ifdef MV_DEBUG_DFS
dfs_reg_write(u32 addr,u32 val)57*ff9112dfSStefan Roese static inline void dfs_reg_write(u32 addr, u32 val)
58*ff9112dfSStefan Roese {
59*ff9112dfSStefan Roese printf("\n write reg 0x%08x = 0x%08x", addr, val);
60*ff9112dfSStefan Roese writel(val, INTER_REGS_BASE + addr);
61*ff9112dfSStefan Roese }
62*ff9112dfSStefan Roese #else
dfs_reg_write(u32 addr,u32 val)63*ff9112dfSStefan Roese static inline void dfs_reg_write(u32 addr, u32 val)
64*ff9112dfSStefan Roese {
65*ff9112dfSStefan Roese writel(val, INTER_REGS_BASE + addr);
66*ff9112dfSStefan Roese }
67*ff9112dfSStefan Roese #endif
68*ff9112dfSStefan Roese
wait_refresh_op_complete(void)69*ff9112dfSStefan Roese static void wait_refresh_op_complete(void)
70*ff9112dfSStefan Roese {
71*ff9112dfSStefan Roese u32 reg;
72*ff9112dfSStefan Roese
73*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
74*ff9112dfSStefan Roese do {
75*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_OPERATION_ADDR) &
76*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CMD_RFRS_DONE;
77*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
78*ff9112dfSStefan Roese }
79*ff9112dfSStefan Roese
80*ff9112dfSStefan Roese /*
81*ff9112dfSStefan Roese * Name: ddr3_get_freq_parameter
82*ff9112dfSStefan Roese * Desc: Finds CPU/DDR frequency ratio according to Sample@reset and table.
83*ff9112dfSStefan Roese * Args: target_freq - target frequency
84*ff9112dfSStefan Roese * Notes:
85*ff9112dfSStefan Roese * Returns: freq_par - the ratio parameter
86*ff9112dfSStefan Roese */
ddr3_get_freq_parameter(u32 target_freq,int ratio_2to1)87*ff9112dfSStefan Roese u32 ddr3_get_freq_parameter(u32 target_freq, int ratio_2to1)
88*ff9112dfSStefan Roese {
89*ff9112dfSStefan Roese u32 ui_vco_freq, freq_par;
90*ff9112dfSStefan Roese
91*ff9112dfSStefan Roese ui_vco_freq = ddr3_get_vco_freq();
92*ff9112dfSStefan Roese
93*ff9112dfSStefan Roese #if defined(MV88F672X)
94*ff9112dfSStefan Roese freq_par = div_ratio[ui_vco_freq][target_freq];
95*ff9112dfSStefan Roese #else
96*ff9112dfSStefan Roese /* Find the ratio between PLL frequency and ddr-clk */
97*ff9112dfSStefan Roese if (ratio_2to1)
98*ff9112dfSStefan Roese freq_par = div_ratio2to1[ui_vco_freq][target_freq];
99*ff9112dfSStefan Roese else
100*ff9112dfSStefan Roese freq_par = div_ratio1to1[ui_vco_freq][target_freq];
101*ff9112dfSStefan Roese #endif
102*ff9112dfSStefan Roese
103*ff9112dfSStefan Roese return freq_par;
104*ff9112dfSStefan Roese }
105*ff9112dfSStefan Roese
106*ff9112dfSStefan Roese /*
107*ff9112dfSStefan Roese * Name: ddr3_dfs_high_2_low
108*ff9112dfSStefan Roese * Desc:
109*ff9112dfSStefan Roese * Args: freq - target frequency
110*ff9112dfSStefan Roese * Notes:
111*ff9112dfSStefan Roese * Returns: MV_OK - success, MV_FAIL - fail
112*ff9112dfSStefan Roese */
ddr3_dfs_high_2_low(u32 freq,MV_DRAM_INFO * dram_info)113*ff9112dfSStefan Roese int ddr3_dfs_high_2_low(u32 freq, MV_DRAM_INFO *dram_info)
114*ff9112dfSStefan Roese {
115*ff9112dfSStefan Roese #if defined(MV88F78X60) || defined(MV88F672X)
116*ff9112dfSStefan Roese /* This Flow is relevant for ArmadaXP A0 */
117*ff9112dfSStefan Roese u32 reg, freq_par, tmp;
118*ff9112dfSStefan Roese u32 cs = 0;
119*ff9112dfSStefan Roese
120*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - High To Low - Starting DFS procedure to Frequency - ",
121*ff9112dfSStefan Roese freq, 1);
122*ff9112dfSStefan Roese
123*ff9112dfSStefan Roese /* target frequency - 100MHz */
124*ff9112dfSStefan Roese freq_par = ddr3_get_freq_parameter(freq, 0);
125*ff9112dfSStefan Roese
126*ff9112dfSStefan Roese #if defined(MV88F672X)
127*ff9112dfSStefan Roese u32 hclk;
128*ff9112dfSStefan Roese u32 cpu_freq = ddr3_get_cpu_freq();
129*ff9112dfSStefan Roese get_target_freq(cpu_freq, &tmp, &hclk);
130*ff9112dfSStefan Roese #endif
131*ff9112dfSStefan Roese
132*ff9112dfSStefan Roese /* Configure - DRAM DLL final state after DFS is complete - Enable */
133*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
134*ff9112dfSStefan Roese /* [0] - DfsDllNextState - Disable */
135*ff9112dfSStefan Roese reg |= (1 << REG_DFS_DLLNEXTSTATE_OFFS);
136*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
137*ff9112dfSStefan Roese
138*ff9112dfSStefan Roese /*
139*ff9112dfSStefan Roese * Configure - XBAR Retry response during Block to enable internal
140*ff9112dfSStefan Roese * access - Disable
141*ff9112dfSStefan Roese */
142*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR);
143*ff9112dfSStefan Roese /* [0] - RetryMask - Disable */
144*ff9112dfSStefan Roese reg &= ~(1 << REG_METAL_MASK_RETRY_OFFS);
145*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
146*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
147*ff9112dfSStefan Roese
148*ff9112dfSStefan Roese /* Configure - Block new external transactions - Enable */
149*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
150*ff9112dfSStefan Roese reg |= (1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Enable */
151*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
152*ff9112dfSStefan Roese
153*ff9112dfSStefan Roese /* Registered DIMM support */
154*ff9112dfSStefan Roese if (dram_info->reg_dimm) {
155*ff9112dfSStefan Roese /*
156*ff9112dfSStefan Roese * Configure - Disable Register DIMM CKE Power
157*ff9112dfSStefan Roese * Down mode - CWA_RC
158*ff9112dfSStefan Roese */
159*ff9112dfSStefan Roese reg = (0x9 & REG_SDRAM_OPERATION_CWA_RC_MASK) <<
160*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_RC_OFFS;
161*ff9112dfSStefan Roese /*
162*ff9112dfSStefan Roese * Configure - Disable Register DIMM CKE Power
163*ff9112dfSStefan Roese * Down mode - CWA_DATA
164*ff9112dfSStefan Roese */
165*ff9112dfSStefan Roese reg |= ((0 & REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
166*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
167*ff9112dfSStefan Roese
168*ff9112dfSStefan Roese /*
169*ff9112dfSStefan Roese * Configure - Disable Register DIMM CKE Power
170*ff9112dfSStefan Roese * Down mode - Set Delay - tMRD
171*ff9112dfSStefan Roese */
172*ff9112dfSStefan Roese reg |= (0 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS);
173*ff9112dfSStefan Roese
174*ff9112dfSStefan Roese /* Configure - Issue CWA command with the above parameters */
175*ff9112dfSStefan Roese reg |= (REG_SDRAM_OPERATION_CMD_CWA &
176*ff9112dfSStefan Roese ~(0xF << REG_SDRAM_OPERATION_CS_OFFS));
177*ff9112dfSStefan Roese
178*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
179*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
180*ff9112dfSStefan Roese
181*ff9112dfSStefan Roese /* Poll - Wait for CWA operation completion */
182*ff9112dfSStefan Roese do {
183*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_OPERATION_ADDR) &
184*ff9112dfSStefan Roese (REG_SDRAM_OPERATION_CMD_MASK);
185*ff9112dfSStefan Roese } while (reg);
186*ff9112dfSStefan Roese
187*ff9112dfSStefan Roese /* Configure - Disable outputs floating during Self Refresh */
188*ff9112dfSStefan Roese reg = reg_read(REG_REGISTERED_DRAM_CTRL_ADDR);
189*ff9112dfSStefan Roese /* [15] - SRFloatEn - Disable */
190*ff9112dfSStefan Roese reg &= ~(1 << REG_REGISTERED_DRAM_CTRL_SR_FLOAT_OFFS);
191*ff9112dfSStefan Roese /* 0x16D0 - DDR3 Registered DRAM Control */
192*ff9112dfSStefan Roese dfs_reg_write(REG_REGISTERED_DRAM_CTRL_ADDR, reg);
193*ff9112dfSStefan Roese }
194*ff9112dfSStefan Roese
195*ff9112dfSStefan Roese /* Optional - Configure - DDR3_Rtt_nom_CS# */
196*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
197*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
198*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR1_CS_ADDR +
199*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS));
200*ff9112dfSStefan Roese reg &= REG_DDR3_MR1_RTT_MASK;
201*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR1_CS_ADDR +
202*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
203*ff9112dfSStefan Roese }
204*ff9112dfSStefan Roese }
205*ff9112dfSStefan Roese
206*ff9112dfSStefan Roese /* Configure - Move DRAM into Self Refresh */
207*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
208*ff9112dfSStefan Roese reg |= (1 << REG_DFS_SR_OFFS); /* [2] - DfsSR - Enable */
209*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
210*ff9112dfSStefan Roese
211*ff9112dfSStefan Roese /* Poll - Wait for Self Refresh indication */
212*ff9112dfSStefan Roese do {
213*ff9112dfSStefan Roese reg = ((reg_read(REG_DFS_ADDR)) & (1 << REG_DFS_ATSR_OFFS));
214*ff9112dfSStefan Roese } while (reg == 0x0); /* 0x1528 [3] - DfsAtSR - Wait for '1' */
215*ff9112dfSStefan Roese
216*ff9112dfSStefan Roese /* Start of clock change procedure (PLL) */
217*ff9112dfSStefan Roese #if defined(MV88F672X)
218*ff9112dfSStefan Roese /* avantaLP */
219*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_reset_mask */
220*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0);
221*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL0_MASK;
222*ff9112dfSStefan Roese /* 0xE8264[7:0] 0xff CPU Clock Dividers Reset mask */
223*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, (reg + 0xFF));
224*ff9112dfSStefan Roese
225*ff9112dfSStefan Roese /* Configure cpu_clkdiv_reload_smooth */
226*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CNTRL0);
227*ff9112dfSStefan Roese reg &= CPU_PLL_CNTRL0_RELOAD_SMOOTH_MASK;
228*ff9112dfSStefan Roese /* 0xE8260 [15:8] 0x2 CPU Clock Dividers Reload Smooth enable */
229*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CNTRL0,
230*ff9112dfSStefan Roese (reg + (2 << CPU_PLL_CNTRL0_RELOAD_SMOOTH_OFFS)));
231*ff9112dfSStefan Roese
232*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_relax_en */
233*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CNTRL0);
234*ff9112dfSStefan Roese reg &= CPU_PLL_CNTRL0_RELAX_EN_MASK;
235*ff9112dfSStefan Roese /* 0xE8260 [31:24] 0x2 Relax Enable */
236*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CNTRL0,
237*ff9112dfSStefan Roese (reg + (2 << CPU_PLL_CNTRL0_RELAX_EN_OFFS)));
238*ff9112dfSStefan Roese
239*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_ddr_clk_ratio */
240*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL1);
241*ff9112dfSStefan Roese /*
242*ff9112dfSStefan Roese * 0xE8268 [13:8] N Set Training clock:
243*ff9112dfSStefan Roese * APLL Out Clock (VCO freq) / N = 100 MHz
244*ff9112dfSStefan Roese */
245*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL1_MASK;
246*ff9112dfSStefan Roese reg |= (freq_par << 8); /* full Integer ratio from PLL-out to ddr-clk */
247*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL1, reg);
248*ff9112dfSStefan Roese
249*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_reload_ratio */
250*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0);
251*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK;
252*ff9112dfSStefan Roese /* 0xE8264 [8]=0x1 CPU Clock Dividers Reload Ratio trigger set */
253*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0,
254*ff9112dfSStefan Roese (reg + (1 << CPU_PLL_CLOCK_RELOAD_RATIO_OFFS)));
255*ff9112dfSStefan Roese
256*ff9112dfSStefan Roese udelay(1);
257*ff9112dfSStefan Roese
258*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_reload_ratio */
259*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0);
260*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK;
261*ff9112dfSStefan Roese /* 0xE8264 [8]=0x0 CPU Clock Dividers Reload Ratio trigger clear */
262*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, reg);
263*ff9112dfSStefan Roese
264*ff9112dfSStefan Roese udelay(5);
265*ff9112dfSStefan Roese
266*ff9112dfSStefan Roese #else
267*ff9112dfSStefan Roese /*
268*ff9112dfSStefan Roese * Initial Setup - assure that the "load new ratio" is clear (bit 24)
269*ff9112dfSStefan Roese * and in the same chance, block reassertions of reset [15:8] and
270*ff9112dfSStefan Roese * force reserved bits[7:0].
271*ff9112dfSStefan Roese */
272*ff9112dfSStefan Roese reg = 0x0000FDFF;
273*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 */
274*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
275*ff9112dfSStefan Roese
276*ff9112dfSStefan Roese /*
277*ff9112dfSStefan Roese * RelaX whenever reset is asserted to that channel
278*ff9112dfSStefan Roese * (good for any case)
279*ff9112dfSStefan Roese */
280*ff9112dfSStefan Roese reg = 0x0000FF00;
281*ff9112dfSStefan Roese /* 0x18704 - CPU Div CLK control 0 */
282*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg);
283*ff9112dfSStefan Roese
284*ff9112dfSStefan Roese reg = reg_read(REG_CPU_DIV_CLK_CTRL_2_ADDR) &
285*ff9112dfSStefan Roese REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK;
286*ff9112dfSStefan Roese
287*ff9112dfSStefan Roese /* full Integer ratio from PLL-out to ddr-clk */
288*ff9112dfSStefan Roese reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS);
289*ff9112dfSStefan Roese /* 0x1870C - CPU Div CLK control 3 register */
290*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_2_ADDR, reg);
291*ff9112dfSStefan Roese
292*ff9112dfSStefan Roese /*
293*ff9112dfSStefan Roese * Shut off clock enable to the DDRPHY clock channel (this is the "D").
294*ff9112dfSStefan Roese * All the rest are kept as is (forced, but could be read-modify-write).
295*ff9112dfSStefan Roese * This is done now by RMW above.
296*ff9112dfSStefan Roese */
297*ff9112dfSStefan Roese
298*ff9112dfSStefan Roese /* Clock is not shut off gracefully - keep it running */
299*ff9112dfSStefan Roese reg = 0x000FFF02;
300*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg);
301*ff9112dfSStefan Roese
302*ff9112dfSStefan Roese /* Wait before replacing the clock on the DDR Phy Channel. */
303*ff9112dfSStefan Roese udelay(1);
304*ff9112dfSStefan Roese
305*ff9112dfSStefan Roese /*
306*ff9112dfSStefan Roese * This for triggering the frequency update. Bit[24] is the
307*ff9112dfSStefan Roese * central control
308*ff9112dfSStefan Roese * bits [23:16] == which channels to change ==2 ==>
309*ff9112dfSStefan Roese * only DDR Phy (smooth transition)
310*ff9112dfSStefan Roese * bits [15:8] == mask reset reassertion due to clock modification
311*ff9112dfSStefan Roese * to these channels.
312*ff9112dfSStefan Roese * bits [7:0] == not in use
313*ff9112dfSStefan Roese */
314*ff9112dfSStefan Roese reg = 0x0102FDFF;
315*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
316*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
317*ff9112dfSStefan Roese
318*ff9112dfSStefan Roese udelay(1); /* Wait 1usec */
319*ff9112dfSStefan Roese
320*ff9112dfSStefan Roese /*
321*ff9112dfSStefan Roese * Poll Div CLK status 0 register - indication that the clocks
322*ff9112dfSStefan Roese * are active - 0x18718 [8]
323*ff9112dfSStefan Roese */
324*ff9112dfSStefan Roese do {
325*ff9112dfSStefan Roese reg = (reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR)) &
326*ff9112dfSStefan Roese (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS);
327*ff9112dfSStefan Roese } while (reg == 0);
328*ff9112dfSStefan Roese
329*ff9112dfSStefan Roese /*
330*ff9112dfSStefan Roese * Clean the CTRL0, to be ready for next resets and next requests
331*ff9112dfSStefan Roese * of ratio modifications.
332*ff9112dfSStefan Roese */
333*ff9112dfSStefan Roese reg = 0x000000FF;
334*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
335*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
336*ff9112dfSStefan Roese
337*ff9112dfSStefan Roese udelay(5);
338*ff9112dfSStefan Roese #endif
339*ff9112dfSStefan Roese /* End of clock change procedure (PLL) */
340*ff9112dfSStefan Roese
341*ff9112dfSStefan Roese /* Configure - Select normal clock for the DDR PHY - Enable */
342*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_INIT_CTRL_STATUS_ADDR);
343*ff9112dfSStefan Roese /* [16] - ddr_phy_trn_clk_sel - Enable */
344*ff9112dfSStefan Roese reg |= (1 << REG_DRAM_INIT_CTRL_TRN_CLK_OFFS);
345*ff9112dfSStefan Roese /* 0x18488 - DRAM Init control status register */
346*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg);
347*ff9112dfSStefan Roese
348*ff9112dfSStefan Roese /* Configure - Set Correct Ratio - 1:1 */
349*ff9112dfSStefan Roese /* [15] - Phy2UnitClkRatio = 0 - Set 1:1 Ratio between Dunit and Phy */
350*ff9112dfSStefan Roese
351*ff9112dfSStefan Roese reg = reg_read(REG_DDR_IO_ADDR) & ~(1 << REG_DDR_IO_CLK_RATIO_OFFS);
352*ff9112dfSStefan Roese dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Register */
353*ff9112dfSStefan Roese
354*ff9112dfSStefan Roese /* Configure - 2T Mode - Restore original configuration */
355*ff9112dfSStefan Roese reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR);
356*ff9112dfSStefan Roese /* [3:4] 2T - 1T Mode - low freq */
357*ff9112dfSStefan Roese reg &= ~(REG_DUNIT_CTRL_LOW_2T_MASK << REG_DUNIT_CTRL_LOW_2T_OFFS);
358*ff9112dfSStefan Roese /* 0x1404 - DDR Controller Control Low Register */
359*ff9112dfSStefan Roese dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg);
360*ff9112dfSStefan Roese
361*ff9112dfSStefan Roese /* Configure - Restore CL and CWL - MRS Commands */
362*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
363*ff9112dfSStefan Roese reg &= ~(REG_DFS_CL_NEXT_STATE_MASK << REG_DFS_CL_NEXT_STATE_OFFS);
364*ff9112dfSStefan Roese reg &= ~(REG_DFS_CWL_NEXT_STATE_MASK << REG_DFS_CWL_NEXT_STATE_OFFS);
365*ff9112dfSStefan Roese /* [8] - DfsCLNextState - MRS CL=6 after DFS (due to DLL-off mode) */
366*ff9112dfSStefan Roese reg |= (0x4 << REG_DFS_CL_NEXT_STATE_OFFS);
367*ff9112dfSStefan Roese /* [12] - DfsCWLNextState - MRS CWL=6 after DFS (due to DLL-off mode) */
368*ff9112dfSStefan Roese reg |= (0x1 << REG_DFS_CWL_NEXT_STATE_OFFS);
369*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
370*ff9112dfSStefan Roese
371*ff9112dfSStefan Roese /* Poll - Wait for APLL + ADLLs lock on new frequency */
372*ff9112dfSStefan Roese do {
373*ff9112dfSStefan Roese reg = (reg_read(REG_PHY_LOCK_STATUS_ADDR)) &
374*ff9112dfSStefan Roese REG_PHY_LOCK_APLL_ADLL_STATUS_MASK;
375*ff9112dfSStefan Roese /* 0x1674 [10:0] - Phy lock status Register */
376*ff9112dfSStefan Roese } while (reg != REG_PHY_LOCK_APLL_ADLL_STATUS_MASK);
377*ff9112dfSStefan Roese
378*ff9112dfSStefan Roese /* Configure - Reset the PHY Read FIFO and Write channels - Set Reset */
379*ff9112dfSStefan Roese reg = (reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK);
380*ff9112dfSStefan Roese /* [30:29] = 0 - Data Pup R/W path reset */
381*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
382*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
383*ff9112dfSStefan Roese
384*ff9112dfSStefan Roese /*
385*ff9112dfSStefan Roese * Configure - DRAM Data PHY Read [30], Write [29] path
386*ff9112dfSStefan Roese * reset - Release Reset
387*ff9112dfSStefan Roese */
388*ff9112dfSStefan Roese reg = (reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK);
389*ff9112dfSStefan Roese /* [30:29] = '11' - Data Pup R/W path reset */
390*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
391*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
392*ff9112dfSStefan Roese
393*ff9112dfSStefan Roese /* Registered DIMM support */
394*ff9112dfSStefan Roese if (dram_info->reg_dimm) {
395*ff9112dfSStefan Roese /*
396*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
397*ff9112dfSStefan Roese * (below 400MHz) - CWA_RC
398*ff9112dfSStefan Roese */
399*ff9112dfSStefan Roese reg = (0xA & REG_SDRAM_OPERATION_CWA_RC_MASK) <<
400*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_RC_OFFS;
401*ff9112dfSStefan Roese
402*ff9112dfSStefan Roese /*
403*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
404*ff9112dfSStefan Roese * (below 400MHz) - CWA_DATA
405*ff9112dfSStefan Roese */
406*ff9112dfSStefan Roese reg |= ((0x0 & REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
407*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
408*ff9112dfSStefan Roese
409*ff9112dfSStefan Roese /* Configure - Set Delay - tSTAB */
410*ff9112dfSStefan Roese reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS);
411*ff9112dfSStefan Roese
412*ff9112dfSStefan Roese /* Configure - Issue CWA command with the above parameters */
413*ff9112dfSStefan Roese reg |= (REG_SDRAM_OPERATION_CMD_CWA &
414*ff9112dfSStefan Roese ~(0xF << REG_SDRAM_OPERATION_CS_OFFS));
415*ff9112dfSStefan Roese
416*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
417*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
418*ff9112dfSStefan Roese
419*ff9112dfSStefan Roese /* Poll - Wait for CWA operation completion */
420*ff9112dfSStefan Roese do {
421*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_OPERATION_ADDR) &
422*ff9112dfSStefan Roese (REG_SDRAM_OPERATION_CMD_MASK);
423*ff9112dfSStefan Roese } while (reg);
424*ff9112dfSStefan Roese }
425*ff9112dfSStefan Roese
426*ff9112dfSStefan Roese /* Configure - Exit Self Refresh */
427*ff9112dfSStefan Roese /* [2] - DfsSR */
428*ff9112dfSStefan Roese reg = (reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS));
429*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
430*ff9112dfSStefan Roese
431*ff9112dfSStefan Roese /*
432*ff9112dfSStefan Roese * Poll - DFS Register - 0x1528 [3] - DfsAtSR - All DRAM devices
433*ff9112dfSStefan Roese * on all ranks are NOT in self refresh mode
434*ff9112dfSStefan Roese */
435*ff9112dfSStefan Roese do {
436*ff9112dfSStefan Roese reg = ((reg_read(REG_DFS_ADDR)) & (1 << REG_DFS_ATSR_OFFS));
437*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
438*ff9112dfSStefan Roese
439*ff9112dfSStefan Roese /* Configure - Issue Refresh command */
440*ff9112dfSStefan Roese /* [3-0] = 0x2 - Refresh Command, [11-8] - enabled Cs */
441*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_RFRS;
442*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
443*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs))
444*ff9112dfSStefan Roese reg &= ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
445*ff9112dfSStefan Roese }
446*ff9112dfSStefan Roese
447*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
448*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
449*ff9112dfSStefan Roese
450*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
451*ff9112dfSStefan Roese wait_refresh_op_complete();
452*ff9112dfSStefan Roese
453*ff9112dfSStefan Roese /* Configure - Block new external transactions - Disable */
454*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
455*ff9112dfSStefan Roese reg &= ~(1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Disable */
456*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
457*ff9112dfSStefan Roese
458*ff9112dfSStefan Roese /*
459*ff9112dfSStefan Roese * Configure - XBAR Retry response during Block to enable
460*ff9112dfSStefan Roese * internal access - Disable
461*ff9112dfSStefan Roese */
462*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR);
463*ff9112dfSStefan Roese /* [0] - RetryMask - Enable */
464*ff9112dfSStefan Roese reg |= (1 << REG_METAL_MASK_RETRY_OFFS);
465*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
466*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
467*ff9112dfSStefan Roese
468*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
469*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
470*ff9112dfSStefan Roese /* Configure - Set CL */
471*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR0_CS_ADDR +
472*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS)) &
473*ff9112dfSStefan Roese ~REG_DDR3_MR0_CL_MASK;
474*ff9112dfSStefan Roese tmp = 0x4; /* CL=6 - 0x4 */
475*ff9112dfSStefan Roese reg |= ((tmp & 0x1) << REG_DDR3_MR0_CL_OFFS);
476*ff9112dfSStefan Roese reg |= ((tmp & 0xE) << REG_DDR3_MR0_CL_HIGH_OFFS);
477*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR0_CS_ADDR +
478*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
479*ff9112dfSStefan Roese
480*ff9112dfSStefan Roese /* Configure - Set CWL */
481*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR2_CS_ADDR +
482*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS))
483*ff9112dfSStefan Roese & ~(REG_DDR3_MR2_CWL_MASK << REG_DDR3_MR2_CWL_OFFS);
484*ff9112dfSStefan Roese /* CWL=6 - 0x1 */
485*ff9112dfSStefan Roese reg |= ((0x1) << REG_DDR3_MR2_CWL_OFFS);
486*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR2_CS_ADDR +
487*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
488*ff9112dfSStefan Roese }
489*ff9112dfSStefan Roese }
490*ff9112dfSStefan Roese
491*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - High To Low - Ended successfuly - new Frequency - ",
492*ff9112dfSStefan Roese freq, 1);
493*ff9112dfSStefan Roese
494*ff9112dfSStefan Roese return MV_OK;
495*ff9112dfSStefan Roese #else
496*ff9112dfSStefan Roese /* This Flow is relevant for Armada370 A0 and ArmadaXP Z1 */
497*ff9112dfSStefan Roese
498*ff9112dfSStefan Roese u32 reg, freq_par;
499*ff9112dfSStefan Roese u32 cs = 0;
500*ff9112dfSStefan Roese
501*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - High To Low - Starting DFS procedure to Frequency - ",
502*ff9112dfSStefan Roese freq, 1);
503*ff9112dfSStefan Roese
504*ff9112dfSStefan Roese /* target frequency - 100MHz */
505*ff9112dfSStefan Roese freq_par = ddr3_get_freq_parameter(freq, 0);
506*ff9112dfSStefan Roese
507*ff9112dfSStefan Roese reg = 0x0000FF00;
508*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 */
509*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg);
510*ff9112dfSStefan Roese
511*ff9112dfSStefan Roese /* 0x1600 - ODPG_CNTRL_Control */
512*ff9112dfSStefan Roese reg = reg_read(REG_ODPG_CNTRL_ADDR);
513*ff9112dfSStefan Roese /* [21] = 1 - auto refresh disable */
514*ff9112dfSStefan Roese reg |= (1 << REG_ODPG_CNTRL_OFFS);
515*ff9112dfSStefan Roese dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg);
516*ff9112dfSStefan Roese
517*ff9112dfSStefan Roese /* 0x1670 - PHY lock mask register */
518*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_MASK_ADDR);
519*ff9112dfSStefan Roese reg &= REG_PHY_LOCK_MASK_MASK; /* [11:0] = 0 */
520*ff9112dfSStefan Roese dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg);
521*ff9112dfSStefan Roese
522*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR); /* 0x1528 - DFS register */
523*ff9112dfSStefan Roese
524*ff9112dfSStefan Roese /* Disable reconfig */
525*ff9112dfSStefan Roese reg &= ~0x10; /* [4] - Enable reconfig MR registers after DFS_ERG */
526*ff9112dfSStefan Roese reg |= 0x1; /* [0] - DRAM DLL disabled after DFS */
527*ff9112dfSStefan Roese
528*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
529*ff9112dfSStefan Roese
530*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR) & ~(1 << 0); /* [0] - disable */
531*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
532*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
533*ff9112dfSStefan Roese
534*ff9112dfSStefan Roese /* [1] - DFS Block enable */
535*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_BLOCK_OFFS);
536*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
537*ff9112dfSStefan Roese
538*ff9112dfSStefan Roese /* [2] - DFS Self refresh enable */
539*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_SR_OFFS);
540*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
541*ff9112dfSStefan Roese
542*ff9112dfSStefan Roese /*
543*ff9112dfSStefan Roese * Poll DFS Register - 0x1528 [3] - DfsAtSR -
544*ff9112dfSStefan Roese * All DRAM devices on all ranks are in self refresh mode -
545*ff9112dfSStefan Roese * DFS can be executed afterwards
546*ff9112dfSStefan Roese */
547*ff9112dfSStefan Roese do {
548*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS);
549*ff9112dfSStefan Roese } while (reg == 0x0); /* Wait for '1' */
550*ff9112dfSStefan Roese
551*ff9112dfSStefan Roese /* Disable ODT on DLL-off mode */
552*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR,
553*ff9112dfSStefan Roese REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK);
554*ff9112dfSStefan Roese
555*ff9112dfSStefan Roese /* [11:0] = 0 */
556*ff9112dfSStefan Roese reg = (reg_read(REG_PHY_LOCK_MASK_ADDR) & REG_PHY_LOCK_MASK_MASK);
557*ff9112dfSStefan Roese /* 0x1670 - PHY lock mask register */
558*ff9112dfSStefan Roese dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg);
559*ff9112dfSStefan Roese
560*ff9112dfSStefan Roese /* Add delay between entering SR and start ratio modification */
561*ff9112dfSStefan Roese udelay(1);
562*ff9112dfSStefan Roese
563*ff9112dfSStefan Roese /*
564*ff9112dfSStefan Roese * Initial Setup - assure that the "load new ratio" is clear (bit 24)
565*ff9112dfSStefan Roese * and in the same chance, block reassertions of reset [15:8] and
566*ff9112dfSStefan Roese * force reserved bits[7:0].
567*ff9112dfSStefan Roese */
568*ff9112dfSStefan Roese reg = 0x0000FDFF;
569*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 */
570*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
571*ff9112dfSStefan Roese
572*ff9112dfSStefan Roese /*
573*ff9112dfSStefan Roese * RelaX whenever reset is asserted to that channel (good for any case)
574*ff9112dfSStefan Roese */
575*ff9112dfSStefan Roese reg = 0x0000FF00;
576*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 */
577*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg);
578*ff9112dfSStefan Roese
579*ff9112dfSStefan Roese reg = reg_read(REG_CPU_DIV_CLK_CTRL_3_ADDR) &
580*ff9112dfSStefan Roese REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK;
581*ff9112dfSStefan Roese /* Full Integer ratio from PLL-out to ddr-clk */
582*ff9112dfSStefan Roese reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS);
583*ff9112dfSStefan Roese /* 0x1870C - CPU Div CLK control 3 register */
584*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_3_ADDR, reg);
585*ff9112dfSStefan Roese
586*ff9112dfSStefan Roese /*
587*ff9112dfSStefan Roese * Shut off clock enable to the DDRPHY clock channel (this is the "D").
588*ff9112dfSStefan Roese * All the rest are kept as is (forced, but could be read-modify-write).
589*ff9112dfSStefan Roese * This is done now by RMW above.
590*ff9112dfSStefan Roese */
591*ff9112dfSStefan Roese
592*ff9112dfSStefan Roese /* Clock is not shut off gracefully - keep it running */
593*ff9112dfSStefan Roese reg = 0x000FFF02;
594*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg);
595*ff9112dfSStefan Roese
596*ff9112dfSStefan Roese /* Wait before replacing the clock on the DDR Phy Channel. */
597*ff9112dfSStefan Roese udelay(1);
598*ff9112dfSStefan Roese
599*ff9112dfSStefan Roese /*
600*ff9112dfSStefan Roese * This for triggering the frequency update. Bit[24] is the
601*ff9112dfSStefan Roese * central control
602*ff9112dfSStefan Roese * bits [23:16] == which channels to change ==2 ==> only DDR Phy
603*ff9112dfSStefan Roese * (smooth transition)
604*ff9112dfSStefan Roese * bits [15:8] == mask reset reassertion due to clock modification
605*ff9112dfSStefan Roese * to these channels.
606*ff9112dfSStefan Roese * bits [7:0] == not in use
607*ff9112dfSStefan Roese */
608*ff9112dfSStefan Roese reg = 0x0102FDFF;
609*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
610*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
611*ff9112dfSStefan Roese
612*ff9112dfSStefan Roese udelay(1); /* Wait 1usec */
613*ff9112dfSStefan Roese
614*ff9112dfSStefan Roese /*
615*ff9112dfSStefan Roese * Poll Div CLK status 0 register - indication that the clocks
616*ff9112dfSStefan Roese * are active - 0x18718 [8]
617*ff9112dfSStefan Roese */
618*ff9112dfSStefan Roese do {
619*ff9112dfSStefan Roese reg = (reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR)) &
620*ff9112dfSStefan Roese (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS);
621*ff9112dfSStefan Roese } while (reg == 0);
622*ff9112dfSStefan Roese
623*ff9112dfSStefan Roese /*
624*ff9112dfSStefan Roese * Clean the CTRL0, to be ready for next resets and next requests of
625*ff9112dfSStefan Roese * ratio modifications.
626*ff9112dfSStefan Roese */
627*ff9112dfSStefan Roese reg = 0x000000FF;
628*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
629*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
630*ff9112dfSStefan Roese
631*ff9112dfSStefan Roese udelay(5);
632*ff9112dfSStefan Roese
633*ff9112dfSStefan Roese /* Switch HCLK Mux to training clk (100Mhz), keep DFS request bit */
634*ff9112dfSStefan Roese reg = 0x20050000;
635*ff9112dfSStefan Roese /* 0x18488 - DRAM Init control status register */
636*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg);
637*ff9112dfSStefan Roese
638*ff9112dfSStefan Roese reg = reg_read(REG_DDR_IO_ADDR) & ~(1 << REG_DDR_IO_CLK_RATIO_OFFS);
639*ff9112dfSStefan Roese /* [15] = 0 - Set 1:1 Ratio between Dunit and Phy */
640*ff9112dfSStefan Roese dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Regist */
641*ff9112dfSStefan Roese
642*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) & REG_DRAM_PHY_CONFIG_MASK;
643*ff9112dfSStefan Roese /* [31:30]] - reset pup data ctrl ADLL */
644*ff9112dfSStefan Roese /* 0x15EC - DRAM PHY Config register */
645*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
646*ff9112dfSStefan Roese
647*ff9112dfSStefan Roese reg = (reg_read(REG_DRAM_PHY_CONFIG_ADDR) | ~REG_DRAM_PHY_CONFIG_MASK);
648*ff9112dfSStefan Roese /* [31:30] - normal pup data ctrl ADLL */
649*ff9112dfSStefan Roese /* 0x15EC - DRAM PHY Config register */
650*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
651*ff9112dfSStefan Roese
652*ff9112dfSStefan Roese udelay(1); /* Wait 1usec */
653*ff9112dfSStefan Roese
654*ff9112dfSStefan Roese /* 0x1404 */
655*ff9112dfSStefan Roese reg = (reg_read(REG_DUNIT_CTRL_LOW_ADDR) & 0xFFFFFFE7);
656*ff9112dfSStefan Roese dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg);
657*ff9112dfSStefan Roese
658*ff9112dfSStefan Roese /* Poll Phy lock status register - APLL lock indication - 0x1674 */
659*ff9112dfSStefan Roese do {
660*ff9112dfSStefan Roese reg = (reg_read(REG_PHY_LOCK_STATUS_ADDR)) &
661*ff9112dfSStefan Roese REG_PHY_LOCK_STATUS_LOCK_MASK;
662*ff9112dfSStefan Roese } while (reg != REG_PHY_LOCK_STATUS_LOCK_MASK); /* Wait for '0xFFF' */
663*ff9112dfSStefan Roese
664*ff9112dfSStefan Roese reg = (reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK);
665*ff9112dfSStefan Roese /* [30:29] = 0 - Data Pup R/W path reset */
666*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
667*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
668*ff9112dfSStefan Roese
669*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK;
670*ff9112dfSStefan Roese /* [30:29] = '11' - Data Pup R/W path reset */
671*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
672*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
673*ff9112dfSStefan Roese
674*ff9112dfSStefan Roese udelay(1000); /* Wait 1msec */
675*ff9112dfSStefan Roese
676*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
677*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
678*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
679*ff9112dfSStefan Roese wait_refresh_op_complete();
680*ff9112dfSStefan Roese
681*ff9112dfSStefan Roese /* Config CL and CWL with MR0 and MR2 registers */
682*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR0_ADDR);
683*ff9112dfSStefan Roese reg &= ~0x74; /* CL [3:0]; [6:4],[2] */
684*ff9112dfSStefan Roese reg |= (1 << 5); /* CL = 4, CAS is 6 */
685*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR0_ADDR, reg);
686*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_MR0 &
687*ff9112dfSStefan Roese ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
688*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
689*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
690*ff9112dfSStefan Roese
691*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
692*ff9112dfSStefan Roese wait_refresh_op_complete();
693*ff9112dfSStefan Roese
694*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR2_ADDR);
695*ff9112dfSStefan Roese reg &= ~0x38; /* CWL [5:3] */
696*ff9112dfSStefan Roese reg |= (1 << 3); /* CWL = 1, CWL is 6 */
697*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR2_ADDR, reg);
698*ff9112dfSStefan Roese
699*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_MR2 &
700*ff9112dfSStefan Roese ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
701*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
702*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
703*ff9112dfSStefan Roese
704*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
705*ff9112dfSStefan Roese wait_refresh_op_complete();
706*ff9112dfSStefan Roese
707*ff9112dfSStefan Roese /* Set current rd_sample_delay */
708*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
709*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK <<
710*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
711*ff9112dfSStefan Roese reg |= (5 << (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
712*ff9112dfSStefan Roese dfs_reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg);
713*ff9112dfSStefan Roese
714*ff9112dfSStefan Roese /* Set current rd_ready_delay */
715*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
716*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_READY_DELAYS_MASK <<
717*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
718*ff9112dfSStefan Roese reg |= ((6) << (REG_READ_DATA_READY_DELAYS_OFFS * cs));
719*ff9112dfSStefan Roese dfs_reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
720*ff9112dfSStefan Roese }
721*ff9112dfSStefan Roese }
722*ff9112dfSStefan Roese
723*ff9112dfSStefan Roese /* [2] - DFS Self refresh disable */
724*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS);
725*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
726*ff9112dfSStefan Roese
727*ff9112dfSStefan Roese /* [1] - DFS Block enable */
728*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_BLOCK_OFFS);
729*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
730*ff9112dfSStefan Roese
731*ff9112dfSStefan Roese /*
732*ff9112dfSStefan Roese * Poll DFS Register - 0x1528 [3] - DfsAtSR -
733*ff9112dfSStefan Roese * All DRAM devices on all ranks are in self refresh mode - DFS can
734*ff9112dfSStefan Roese * be executed afterwards
735*ff9112dfSStefan Roese */
736*ff9112dfSStefan Roese do {
737*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS);
738*ff9112dfSStefan Roese } while (reg); /* Wait for '1' */
739*ff9112dfSStefan Roese
740*ff9112dfSStefan Roese reg = (reg_read(REG_METAL_MASK_ADDR) | (1 << 0));
741*ff9112dfSStefan Roese /* [0] - Enable Dunit to crossbar retry */
742*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
743*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
744*ff9112dfSStefan Roese
745*ff9112dfSStefan Roese /* 0x1600 - PHY lock mask register */
746*ff9112dfSStefan Roese reg = reg_read(REG_ODPG_CNTRL_ADDR);
747*ff9112dfSStefan Roese reg &= ~(1 << REG_ODPG_CNTRL_OFFS); /* [21] = 0 */
748*ff9112dfSStefan Roese dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg);
749*ff9112dfSStefan Roese
750*ff9112dfSStefan Roese /* 0x1670 - PHY lock mask register */
751*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_MASK_ADDR);
752*ff9112dfSStefan Roese reg |= ~REG_PHY_LOCK_MASK_MASK; /* [11:0] = FFF */
753*ff9112dfSStefan Roese dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg);
754*ff9112dfSStefan Roese
755*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - High To Low - Ended successfuly - new Frequency - ",
756*ff9112dfSStefan Roese freq, 1);
757*ff9112dfSStefan Roese
758*ff9112dfSStefan Roese return MV_OK;
759*ff9112dfSStefan Roese #endif
760*ff9112dfSStefan Roese }
761*ff9112dfSStefan Roese
762*ff9112dfSStefan Roese /*
763*ff9112dfSStefan Roese * Name: ddr3_dfs_low_2_high
764*ff9112dfSStefan Roese * Desc:
765*ff9112dfSStefan Roese * Args: freq - target frequency
766*ff9112dfSStefan Roese * Notes:
767*ff9112dfSStefan Roese * Returns: MV_OK - success, MV_FAIL - fail
768*ff9112dfSStefan Roese */
ddr3_dfs_low_2_high(u32 freq,int ratio_2to1,MV_DRAM_INFO * dram_info)769*ff9112dfSStefan Roese int ddr3_dfs_low_2_high(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info)
770*ff9112dfSStefan Roese {
771*ff9112dfSStefan Roese #if defined(MV88F78X60) || defined(MV88F672X)
772*ff9112dfSStefan Roese /* This Flow is relevant for ArmadaXP A0 */
773*ff9112dfSStefan Roese u32 reg, freq_par, tmp;
774*ff9112dfSStefan Roese u32 cs = 0;
775*ff9112dfSStefan Roese
776*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - Low To High - Starting DFS procedure to Frequency - ",
777*ff9112dfSStefan Roese freq, 1);
778*ff9112dfSStefan Roese
779*ff9112dfSStefan Roese /* target frequency - freq */
780*ff9112dfSStefan Roese freq_par = ddr3_get_freq_parameter(freq, ratio_2to1);
781*ff9112dfSStefan Roese
782*ff9112dfSStefan Roese #if defined(MV88F672X)
783*ff9112dfSStefan Roese u32 hclk;
784*ff9112dfSStefan Roese u32 cpu_freq = ddr3_get_cpu_freq();
785*ff9112dfSStefan Roese get_target_freq(cpu_freq, &tmp, &hclk);
786*ff9112dfSStefan Roese #endif
787*ff9112dfSStefan Roese
788*ff9112dfSStefan Roese /* Configure - DRAM DLL final state after DFS is complete - Enable */
789*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
790*ff9112dfSStefan Roese /* [0] - DfsDllNextState - Enable */
791*ff9112dfSStefan Roese reg &= ~(1 << REG_DFS_DLLNEXTSTATE_OFFS);
792*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
793*ff9112dfSStefan Roese
794*ff9112dfSStefan Roese /*
795*ff9112dfSStefan Roese * Configure - XBAR Retry response during Block to enable
796*ff9112dfSStefan Roese * internal access - Disable
797*ff9112dfSStefan Roese */
798*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR);
799*ff9112dfSStefan Roese /* [0] - RetryMask - Disable */
800*ff9112dfSStefan Roese reg &= ~(1 << REG_METAL_MASK_RETRY_OFFS);
801*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
802*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
803*ff9112dfSStefan Roese
804*ff9112dfSStefan Roese /* Configure - Block new external transactions - Enable */
805*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
806*ff9112dfSStefan Roese reg |= (1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Enable */
807*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
808*ff9112dfSStefan Roese
809*ff9112dfSStefan Roese /* Configure - Move DRAM into Self Refresh */
810*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
811*ff9112dfSStefan Roese reg |= (1 << REG_DFS_SR_OFFS); /* [2] - DfsSR - Enable */
812*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
813*ff9112dfSStefan Roese
814*ff9112dfSStefan Roese /* Poll - Wait for Self Refresh indication */
815*ff9112dfSStefan Roese do {
816*ff9112dfSStefan Roese reg = ((reg_read(REG_DFS_ADDR)) & (1 << REG_DFS_ATSR_OFFS));
817*ff9112dfSStefan Roese } while (reg == 0x0); /* 0x1528 [3] - DfsAtSR - Wait for '1' */
818*ff9112dfSStefan Roese
819*ff9112dfSStefan Roese /* Start of clock change procedure (PLL) */
820*ff9112dfSStefan Roese #if defined(MV88F672X)
821*ff9112dfSStefan Roese /* avantaLP */
822*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_reset_mask */
823*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0);
824*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL0_MASK;
825*ff9112dfSStefan Roese /* 0xE8264[7:0] 0xff CPU Clock Dividers Reset mask */
826*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, (reg + 0xFF));
827*ff9112dfSStefan Roese
828*ff9112dfSStefan Roese /* Configure cpu_clkdiv_reload_smooth */
829*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CNTRL0);
830*ff9112dfSStefan Roese reg &= CPU_PLL_CNTRL0_RELOAD_SMOOTH_MASK;
831*ff9112dfSStefan Roese /* 0xE8260 [15:8] 0x2 CPU Clock Dividers Reload Smooth enable */
832*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CNTRL0,
833*ff9112dfSStefan Roese reg + (2 << CPU_PLL_CNTRL0_RELOAD_SMOOTH_OFFS));
834*ff9112dfSStefan Roese
835*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_relax_en */
836*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CNTRL0);
837*ff9112dfSStefan Roese reg &= CPU_PLL_CNTRL0_RELAX_EN_MASK;
838*ff9112dfSStefan Roese /* 0xE8260 [31:24] 0x2 Relax Enable */
839*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CNTRL0,
840*ff9112dfSStefan Roese reg + (2 << CPU_PLL_CNTRL0_RELAX_EN_OFFS));
841*ff9112dfSStefan Roese
842*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_ddr_clk_ratio */
843*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL1);
844*ff9112dfSStefan Roese /*
845*ff9112dfSStefan Roese * 0xE8268 [13:8] N Set Training clock:
846*ff9112dfSStefan Roese * APLL Out Clock (VCO freq) / N = 100 MHz
847*ff9112dfSStefan Roese */
848*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL1_MASK;
849*ff9112dfSStefan Roese reg |= (freq_par << 8); /* full Integer ratio from PLL-out to ddr-clk */
850*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL1, reg);
851*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_reload_ratio */
852*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0);
853*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK;
854*ff9112dfSStefan Roese /* 0xE8264 [8]=0x1 CPU Clock Dividers Reload Ratio trigger set */
855*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0,
856*ff9112dfSStefan Roese reg + (1 << CPU_PLL_CLOCK_RELOAD_RATIO_OFFS));
857*ff9112dfSStefan Roese
858*ff9112dfSStefan Roese udelay(1);
859*ff9112dfSStefan Roese
860*ff9112dfSStefan Roese /* Configure cpupll_clkdiv_reload_ratio */
861*ff9112dfSStefan Roese reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0);
862*ff9112dfSStefan Roese reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK;
863*ff9112dfSStefan Roese /* 0xE8264 [8]=0x0 CPU Clock Dividers Reload Ratio trigger clear */
864*ff9112dfSStefan Roese dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, reg);
865*ff9112dfSStefan Roese
866*ff9112dfSStefan Roese udelay(5);
867*ff9112dfSStefan Roese
868*ff9112dfSStefan Roese #else
869*ff9112dfSStefan Roese /*
870*ff9112dfSStefan Roese * Initial Setup - assure that the "load new ratio" is clear (bit 24)
871*ff9112dfSStefan Roese * and in the same chance, block reassertions of reset [15:8]
872*ff9112dfSStefan Roese * and force reserved bits[7:0].
873*ff9112dfSStefan Roese */
874*ff9112dfSStefan Roese reg = 0x0000FFFF;
875*ff9112dfSStefan Roese
876*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 */
877*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
878*ff9112dfSStefan Roese
879*ff9112dfSStefan Roese /*
880*ff9112dfSStefan Roese * RelaX whenever reset is asserted to that channel (good for any case)
881*ff9112dfSStefan Roese */
882*ff9112dfSStefan Roese reg = 0x0000FF00;
883*ff9112dfSStefan Roese /* 0x18704 - CPU Div CLK control 0 */
884*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg);
885*ff9112dfSStefan Roese
886*ff9112dfSStefan Roese reg = reg_read(REG_CPU_DIV_CLK_CTRL_2_ADDR) &
887*ff9112dfSStefan Roese REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK;
888*ff9112dfSStefan Roese reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS);
889*ff9112dfSStefan Roese /* full Integer ratio from PLL-out to ddr-clk */
890*ff9112dfSStefan Roese /* 0x1870C - CPU Div CLK control 3 register */
891*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_2_ADDR, reg);
892*ff9112dfSStefan Roese
893*ff9112dfSStefan Roese /*
894*ff9112dfSStefan Roese * Shut off clock enable to the DDRPHY clock channel (this is the "D").
895*ff9112dfSStefan Roese * All the rest are kept as is (forced, but could be read-modify-write).
896*ff9112dfSStefan Roese * This is done now by RMW above.
897*ff9112dfSStefan Roese */
898*ff9112dfSStefan Roese reg = 0x000FFF02;
899*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg);
900*ff9112dfSStefan Roese
901*ff9112dfSStefan Roese /* Wait before replacing the clock on the DDR Phy Channel. */
902*ff9112dfSStefan Roese udelay(1);
903*ff9112dfSStefan Roese
904*ff9112dfSStefan Roese reg = 0x0102FDFF;
905*ff9112dfSStefan Roese /*
906*ff9112dfSStefan Roese * This for triggering the frequency update. Bit[24] is the
907*ff9112dfSStefan Roese * central control
908*ff9112dfSStefan Roese * bits [23:16] == which channels to change ==2 ==> only DDR Phy
909*ff9112dfSStefan Roese * (smooth transition)
910*ff9112dfSStefan Roese * bits [15:8] == mask reset reassertion due to clock modification
911*ff9112dfSStefan Roese * to these channels.
912*ff9112dfSStefan Roese * bits [7:0] == not in use
913*ff9112dfSStefan Roese */
914*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
915*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
916*ff9112dfSStefan Roese
917*ff9112dfSStefan Roese udelay(1);
918*ff9112dfSStefan Roese
919*ff9112dfSStefan Roese /*
920*ff9112dfSStefan Roese * Poll Div CLK status 0 register - indication that the clocks
921*ff9112dfSStefan Roese * are active - 0x18718 [8]
922*ff9112dfSStefan Roese */
923*ff9112dfSStefan Roese do {
924*ff9112dfSStefan Roese reg = reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR) &
925*ff9112dfSStefan Roese (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS);
926*ff9112dfSStefan Roese } while (reg == 0);
927*ff9112dfSStefan Roese
928*ff9112dfSStefan Roese reg = 0x000000FF;
929*ff9112dfSStefan Roese /*
930*ff9112dfSStefan Roese * Clean the CTRL0, to be ready for next resets and next requests
931*ff9112dfSStefan Roese * of ratio modifications.
932*ff9112dfSStefan Roese */
933*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
934*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
935*ff9112dfSStefan Roese #endif
936*ff9112dfSStefan Roese /* End of clock change procedure (PLL) */
937*ff9112dfSStefan Roese
938*ff9112dfSStefan Roese if (ratio_2to1) {
939*ff9112dfSStefan Roese /* Configure - Select normal clock for the DDR PHY - Disable */
940*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_INIT_CTRL_STATUS_ADDR);
941*ff9112dfSStefan Roese /* [16] - ddr_phy_trn_clk_sel - Disable */
942*ff9112dfSStefan Roese reg &= ~(1 << REG_DRAM_INIT_CTRL_TRN_CLK_OFFS);
943*ff9112dfSStefan Roese /* 0x18488 - DRAM Init control status register */
944*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg);
945*ff9112dfSStefan Roese }
946*ff9112dfSStefan Roese
947*ff9112dfSStefan Roese /*
948*ff9112dfSStefan Roese * Configure - Set Correct Ratio - according to target ratio
949*ff9112dfSStefan Roese * parameter - 2:1/1:1
950*ff9112dfSStefan Roese */
951*ff9112dfSStefan Roese if (ratio_2to1) {
952*ff9112dfSStefan Roese /*
953*ff9112dfSStefan Roese * [15] - Phy2UnitClkRatio = 1 - Set 2:1 Ratio between
954*ff9112dfSStefan Roese * Dunit and Phy
955*ff9112dfSStefan Roese */
956*ff9112dfSStefan Roese reg = reg_read(REG_DDR_IO_ADDR) |
957*ff9112dfSStefan Roese (1 << REG_DDR_IO_CLK_RATIO_OFFS);
958*ff9112dfSStefan Roese } else {
959*ff9112dfSStefan Roese /*
960*ff9112dfSStefan Roese * [15] - Phy2UnitClkRatio = 0 - Set 1:1 Ratio between
961*ff9112dfSStefan Roese * Dunit and Phy
962*ff9112dfSStefan Roese */
963*ff9112dfSStefan Roese reg = reg_read(REG_DDR_IO_ADDR) &
964*ff9112dfSStefan Roese ~(1 << REG_DDR_IO_CLK_RATIO_OFFS);
965*ff9112dfSStefan Roese }
966*ff9112dfSStefan Roese dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Register */
967*ff9112dfSStefan Roese
968*ff9112dfSStefan Roese /* Configure - 2T Mode - Restore original configuration */
969*ff9112dfSStefan Roese reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR);
970*ff9112dfSStefan Roese /* [3:4] 2T - Restore value */
971*ff9112dfSStefan Roese reg &= ~(REG_DUNIT_CTRL_LOW_2T_MASK << REG_DUNIT_CTRL_LOW_2T_OFFS);
972*ff9112dfSStefan Roese reg |= ((dram_info->mode_2t & REG_DUNIT_CTRL_LOW_2T_MASK) <<
973*ff9112dfSStefan Roese REG_DUNIT_CTRL_LOW_2T_OFFS);
974*ff9112dfSStefan Roese /* 0x1404 - DDR Controller Control Low Register */
975*ff9112dfSStefan Roese dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg);
976*ff9112dfSStefan Roese
977*ff9112dfSStefan Roese /* Configure - Restore CL and CWL - MRS Commands */
978*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
979*ff9112dfSStefan Roese reg &= ~(REG_DFS_CL_NEXT_STATE_MASK << REG_DFS_CL_NEXT_STATE_OFFS);
980*ff9112dfSStefan Roese reg &= ~(REG_DFS_CWL_NEXT_STATE_MASK << REG_DFS_CWL_NEXT_STATE_OFFS);
981*ff9112dfSStefan Roese
982*ff9112dfSStefan Roese if (freq == DDR_400) {
983*ff9112dfSStefan Roese if (dram_info->target_frequency == 0x8)
984*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(5);
985*ff9112dfSStefan Roese else
986*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(6);
987*ff9112dfSStefan Roese } else {
988*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(dram_info->cl);
989*ff9112dfSStefan Roese }
990*ff9112dfSStefan Roese
991*ff9112dfSStefan Roese /* [8] - DfsCLNextState */
992*ff9112dfSStefan Roese reg |= ((tmp & REG_DFS_CL_NEXT_STATE_MASK) << REG_DFS_CL_NEXT_STATE_OFFS);
993*ff9112dfSStefan Roese if (freq == DDR_400) {
994*ff9112dfSStefan Roese /* [12] - DfsCWLNextState */
995*ff9112dfSStefan Roese reg |= (((0) & REG_DFS_CWL_NEXT_STATE_MASK) <<
996*ff9112dfSStefan Roese REG_DFS_CWL_NEXT_STATE_OFFS);
997*ff9112dfSStefan Roese } else {
998*ff9112dfSStefan Roese /* [12] - DfsCWLNextState */
999*ff9112dfSStefan Roese reg |= (((dram_info->cwl) & REG_DFS_CWL_NEXT_STATE_MASK) <<
1000*ff9112dfSStefan Roese REG_DFS_CWL_NEXT_STATE_OFFS);
1001*ff9112dfSStefan Roese }
1002*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1003*ff9112dfSStefan Roese
1004*ff9112dfSStefan Roese /* Optional - Configure - DDR3_Rtt_nom_CS# */
1005*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1006*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
1007*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR1_CS_ADDR +
1008*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS));
1009*ff9112dfSStefan Roese reg &= REG_DDR3_MR1_RTT_MASK;
1010*ff9112dfSStefan Roese reg |= odt_static[dram_info->cs_ena][cs];
1011*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR1_CS_ADDR +
1012*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1013*ff9112dfSStefan Roese }
1014*ff9112dfSStefan Roese }
1015*ff9112dfSStefan Roese
1016*ff9112dfSStefan Roese /* Configure - Reset ADLLs - Set Reset */
1017*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) & REG_DRAM_PHY_CONFIG_MASK;
1018*ff9112dfSStefan Roese /* [31:30]] - reset pup data ctrl ADLL */
1019*ff9112dfSStefan Roese /* 0x15EC - DRAM PHY Config Register */
1020*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
1021*ff9112dfSStefan Roese
1022*ff9112dfSStefan Roese /* Configure - Reset ADLLs - Release Reset */
1023*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) | ~REG_DRAM_PHY_CONFIG_MASK;
1024*ff9112dfSStefan Roese /* [31:30] - normal pup data ctrl ADLL */
1025*ff9112dfSStefan Roese /* 0x15EC - DRAM PHY Config register */
1026*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
1027*ff9112dfSStefan Roese
1028*ff9112dfSStefan Roese /* Poll - Wait for APLL + ADLLs lock on new frequency */
1029*ff9112dfSStefan Roese do {
1030*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_STATUS_ADDR) &
1031*ff9112dfSStefan Roese REG_PHY_LOCK_APLL_ADLL_STATUS_MASK;
1032*ff9112dfSStefan Roese /* 0x1674 [10:0] - Phy lock status Register */
1033*ff9112dfSStefan Roese } while (reg != REG_PHY_LOCK_APLL_ADLL_STATUS_MASK);
1034*ff9112dfSStefan Roese
1035*ff9112dfSStefan Roese /* Configure - Reset the PHY SDR clock divider */
1036*ff9112dfSStefan Roese if (ratio_2to1) {
1037*ff9112dfSStefan Roese /* Pup Reset Divider B - Set Reset */
1038*ff9112dfSStefan Roese /* [28] - DataPupRdRST = 0 */
1039*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) &
1040*ff9112dfSStefan Roese ~(1 << REG_SDRAM_CONFIG_PUPRSTDIV_OFFS);
1041*ff9112dfSStefan Roese /* [28] - DataPupRdRST = 1 */
1042*ff9112dfSStefan Roese tmp = reg_read(REG_SDRAM_CONFIG_ADDR) |
1043*ff9112dfSStefan Roese (1 << REG_SDRAM_CONFIG_PUPRSTDIV_OFFS);
1044*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1045*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
1046*ff9112dfSStefan Roese
1047*ff9112dfSStefan Roese /* Pup Reset Divider B - Release Reset */
1048*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1049*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, tmp);
1050*ff9112dfSStefan Roese }
1051*ff9112dfSStefan Roese
1052*ff9112dfSStefan Roese /* Configure - Reset the PHY Read FIFO and Write channels - Set Reset */
1053*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK;
1054*ff9112dfSStefan Roese /* [30:29] = 0 - Data Pup R/W path reset */
1055*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1056*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
1057*ff9112dfSStefan Roese
1058*ff9112dfSStefan Roese /*
1059*ff9112dfSStefan Roese * Configure - DRAM Data PHY Read [30], Write [29] path reset -
1060*ff9112dfSStefan Roese * Release Reset
1061*ff9112dfSStefan Roese */
1062*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK;
1063*ff9112dfSStefan Roese /* [30:29] = '11' - Data Pup R/W path reset */
1064*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1065*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
1066*ff9112dfSStefan Roese
1067*ff9112dfSStefan Roese /* Registered DIMM support */
1068*ff9112dfSStefan Roese if (dram_info->reg_dimm) {
1069*ff9112dfSStefan Roese /*
1070*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
1071*ff9112dfSStefan Roese * (DDR3-1333 / DDR3-1600) - CWA_RC
1072*ff9112dfSStefan Roese */
1073*ff9112dfSStefan Roese reg = (0xA & REG_SDRAM_OPERATION_CWA_RC_MASK) <<
1074*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_RC_OFFS;
1075*ff9112dfSStefan Roese if (freq <= DDR_400) {
1076*ff9112dfSStefan Roese /*
1077*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
1078*ff9112dfSStefan Roese * (DDR3-800) - CWA_DATA
1079*ff9112dfSStefan Roese */
1080*ff9112dfSStefan Roese reg |= ((0x0 & REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
1081*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
1082*ff9112dfSStefan Roese } else if ((freq > DDR_400) && (freq <= DDR_533)) {
1083*ff9112dfSStefan Roese /*
1084*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
1085*ff9112dfSStefan Roese * (DDR3-1066) - CWA_DATA
1086*ff9112dfSStefan Roese */
1087*ff9112dfSStefan Roese reg |= ((0x1 & REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
1088*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
1089*ff9112dfSStefan Roese } else if ((freq > DDR_533) && (freq <= DDR_666)) {
1090*ff9112dfSStefan Roese /*
1091*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
1092*ff9112dfSStefan Roese * (DDR3-1333) - CWA_DATA
1093*ff9112dfSStefan Roese */
1094*ff9112dfSStefan Roese reg |= ((0x2 & REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
1095*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
1096*ff9112dfSStefan Roese } else {
1097*ff9112dfSStefan Roese /*
1098*ff9112dfSStefan Roese * Configure - Change register DRAM operating speed
1099*ff9112dfSStefan Roese * (DDR3-1600) - CWA_DATA
1100*ff9112dfSStefan Roese */
1101*ff9112dfSStefan Roese reg |= ((0x3 & REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
1102*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
1103*ff9112dfSStefan Roese }
1104*ff9112dfSStefan Roese
1105*ff9112dfSStefan Roese /* Configure - Set Delay - tSTAB */
1106*ff9112dfSStefan Roese reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS);
1107*ff9112dfSStefan Roese /* Configure - Issue CWA command with the above parameters */
1108*ff9112dfSStefan Roese reg |= (REG_SDRAM_OPERATION_CMD_CWA &
1109*ff9112dfSStefan Roese ~(0xF << REG_SDRAM_OPERATION_CS_OFFS));
1110*ff9112dfSStefan Roese
1111*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1112*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1113*ff9112dfSStefan Roese
1114*ff9112dfSStefan Roese /* Poll - Wait for CWA operation completion */
1115*ff9112dfSStefan Roese do {
1116*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_OPERATION_ADDR) &
1117*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CMD_MASK;
1118*ff9112dfSStefan Roese } while (reg);
1119*ff9112dfSStefan Roese }
1120*ff9112dfSStefan Roese
1121*ff9112dfSStefan Roese /* Configure - Exit Self Refresh */
1122*ff9112dfSStefan Roese /* [2] - DfsSR */
1123*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS);
1124*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1125*ff9112dfSStefan Roese
1126*ff9112dfSStefan Roese /*
1127*ff9112dfSStefan Roese * Poll - DFS Register - 0x1528 [3] - DfsAtSR - All DRAM
1128*ff9112dfSStefan Roese * devices on all ranks are NOT in self refresh mode
1129*ff9112dfSStefan Roese */
1130*ff9112dfSStefan Roese do {
1131*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS);
1132*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
1133*ff9112dfSStefan Roese
1134*ff9112dfSStefan Roese /* Configure - Issue Refresh command */
1135*ff9112dfSStefan Roese /* [3-0] = 0x2 - Refresh Command, [11-8] - enabled Cs */
1136*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_RFRS;
1137*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1138*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs))
1139*ff9112dfSStefan Roese reg &= ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
1140*ff9112dfSStefan Roese }
1141*ff9112dfSStefan Roese
1142*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1143*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1144*ff9112dfSStefan Roese
1145*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
1146*ff9112dfSStefan Roese wait_refresh_op_complete();
1147*ff9112dfSStefan Roese
1148*ff9112dfSStefan Roese /* Configure - Block new external transactions - Disable */
1149*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR);
1150*ff9112dfSStefan Roese reg &= ~(1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Disable */
1151*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1152*ff9112dfSStefan Roese
1153*ff9112dfSStefan Roese /*
1154*ff9112dfSStefan Roese * Configure - XBAR Retry response during Block to enable
1155*ff9112dfSStefan Roese * internal access - Disable
1156*ff9112dfSStefan Roese */
1157*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR);
1158*ff9112dfSStefan Roese /* [0] - RetryMask - Enable */
1159*ff9112dfSStefan Roese reg |= (1 << REG_METAL_MASK_RETRY_OFFS);
1160*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
1161*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
1162*ff9112dfSStefan Roese
1163*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1164*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
1165*ff9112dfSStefan Roese /* Configure - Set CL */
1166*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR0_CS_ADDR +
1167*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS)) &
1168*ff9112dfSStefan Roese ~REG_DDR3_MR0_CL_MASK;
1169*ff9112dfSStefan Roese if (freq == DDR_400)
1170*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(6);
1171*ff9112dfSStefan Roese else
1172*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(dram_info->cl);
1173*ff9112dfSStefan Roese reg |= ((tmp & 0x1) << REG_DDR3_MR0_CL_OFFS);
1174*ff9112dfSStefan Roese reg |= ((tmp & 0xE) << REG_DDR3_MR0_CL_HIGH_OFFS);
1175*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR0_CS_ADDR +
1176*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1177*ff9112dfSStefan Roese
1178*ff9112dfSStefan Roese /* Configure - Set CWL */
1179*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR2_CS_ADDR +
1180*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS)) &
1181*ff9112dfSStefan Roese ~(REG_DDR3_MR2_CWL_MASK << REG_DDR3_MR2_CWL_OFFS);
1182*ff9112dfSStefan Roese if (freq == DDR_400)
1183*ff9112dfSStefan Roese reg |= ((0) << REG_DDR3_MR2_CWL_OFFS);
1184*ff9112dfSStefan Roese else
1185*ff9112dfSStefan Roese reg |= ((dram_info->cwl) << REG_DDR3_MR2_CWL_OFFS);
1186*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR2_CS_ADDR +
1187*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1188*ff9112dfSStefan Roese }
1189*ff9112dfSStefan Roese }
1190*ff9112dfSStefan Roese
1191*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - Low To High - Ended successfuly - new Frequency - ",
1192*ff9112dfSStefan Roese freq, 1);
1193*ff9112dfSStefan Roese
1194*ff9112dfSStefan Roese return MV_OK;
1195*ff9112dfSStefan Roese
1196*ff9112dfSStefan Roese #else
1197*ff9112dfSStefan Roese
1198*ff9112dfSStefan Roese /* This Flow is relevant for Armada370 A0 and ArmadaXP Z1 */
1199*ff9112dfSStefan Roese
1200*ff9112dfSStefan Roese u32 reg, freq_par, tmp;
1201*ff9112dfSStefan Roese u32 cs = 0;
1202*ff9112dfSStefan Roese
1203*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - Low To High - Starting DFS procedure to Frequency - ",
1204*ff9112dfSStefan Roese freq, 1);
1205*ff9112dfSStefan Roese
1206*ff9112dfSStefan Roese /* target frequency - freq */
1207*ff9112dfSStefan Roese freq_par = ddr3_get_freq_parameter(freq, ratio_2to1);
1208*ff9112dfSStefan Roese
1209*ff9112dfSStefan Roese reg = 0x0000FF00;
1210*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg);
1211*ff9112dfSStefan Roese
1212*ff9112dfSStefan Roese /* 0x1600 - PHY lock mask register */
1213*ff9112dfSStefan Roese reg = reg_read(REG_ODPG_CNTRL_ADDR);
1214*ff9112dfSStefan Roese reg |= (1 << REG_ODPG_CNTRL_OFFS); /* [21] = 1 */
1215*ff9112dfSStefan Roese dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg);
1216*ff9112dfSStefan Roese
1217*ff9112dfSStefan Roese /* 0x1670 - PHY lock mask register */
1218*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_MASK_ADDR);
1219*ff9112dfSStefan Roese reg &= REG_PHY_LOCK_MASK_MASK; /* [11:0] = 0 */
1220*ff9112dfSStefan Roese dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg);
1221*ff9112dfSStefan Roese
1222*ff9112dfSStefan Roese /* Enable reconfig MR Registers after DFS */
1223*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR); /* 0x1528 - DFS register */
1224*ff9112dfSStefan Roese /* [4] - Disable - reconfig MR registers after DFS_ERG */
1225*ff9112dfSStefan Roese reg &= ~0x11;
1226*ff9112dfSStefan Roese /* [0] - Enable - DRAM DLL after DFS */
1227*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1228*ff9112dfSStefan Roese
1229*ff9112dfSStefan Roese /* Disable DRAM Controller to crossbar retry */
1230*ff9112dfSStefan Roese /* [0] - disable */
1231*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR) & ~(1 << 0);
1232*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
1233*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
1234*ff9112dfSStefan Roese
1235*ff9112dfSStefan Roese /* Enable DRAM Blocking */
1236*ff9112dfSStefan Roese /* [1] - DFS Block enable */
1237*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_BLOCK_OFFS);
1238*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1239*ff9112dfSStefan Roese
1240*ff9112dfSStefan Roese /* Enable Self refresh */
1241*ff9112dfSStefan Roese /* [2] - DFS Self refresh enable */
1242*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_SR_OFFS);
1243*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1244*ff9112dfSStefan Roese
1245*ff9112dfSStefan Roese /*
1246*ff9112dfSStefan Roese * Poll DFS Register - All DRAM devices on all ranks are in
1247*ff9112dfSStefan Roese * self refresh mode - DFS can be executed afterwards
1248*ff9112dfSStefan Roese */
1249*ff9112dfSStefan Roese /* 0x1528 [3] - DfsAtSR */
1250*ff9112dfSStefan Roese do {
1251*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS);
1252*ff9112dfSStefan Roese } while (reg == 0x0); /* Wait for '1' */
1253*ff9112dfSStefan Roese
1254*ff9112dfSStefan Roese /*
1255*ff9112dfSStefan Roese * Set Correct Ratio - if freq>MARGIN_FREQ use 2:1 ratio
1256*ff9112dfSStefan Roese * else use 1:1 ratio
1257*ff9112dfSStefan Roese */
1258*ff9112dfSStefan Roese if (ratio_2to1) {
1259*ff9112dfSStefan Roese /* [15] = 1 - Set 2:1 Ratio between Dunit and Phy */
1260*ff9112dfSStefan Roese reg = reg_read(REG_DDR_IO_ADDR) |
1261*ff9112dfSStefan Roese (1 << REG_DDR_IO_CLK_RATIO_OFFS);
1262*ff9112dfSStefan Roese } else {
1263*ff9112dfSStefan Roese /* [15] = 0 - Set 1:1 Ratio between Dunit and Phy */
1264*ff9112dfSStefan Roese reg = reg_read(REG_DDR_IO_ADDR) &
1265*ff9112dfSStefan Roese ~(1 << REG_DDR_IO_CLK_RATIO_OFFS);
1266*ff9112dfSStefan Roese }
1267*ff9112dfSStefan Roese dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Register */
1268*ff9112dfSStefan Roese
1269*ff9112dfSStefan Roese /* Switch HCLK Mux from (100Mhz) [16]=0, keep DFS request bit */
1270*ff9112dfSStefan Roese reg = 0x20040000;
1271*ff9112dfSStefan Roese /*
1272*ff9112dfSStefan Roese * [29] - training logic request DFS, [28:27] -
1273*ff9112dfSStefan Roese * preload patterns frequency [18]
1274*ff9112dfSStefan Roese */
1275*ff9112dfSStefan Roese
1276*ff9112dfSStefan Roese /* 0x18488 - DRAM Init control status register */
1277*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg);
1278*ff9112dfSStefan Roese
1279*ff9112dfSStefan Roese /* Add delay between entering SR and start ratio modification */
1280*ff9112dfSStefan Roese udelay(1);
1281*ff9112dfSStefan Roese
1282*ff9112dfSStefan Roese /*
1283*ff9112dfSStefan Roese * Initial Setup - assure that the "load new ratio" is clear (bit 24)
1284*ff9112dfSStefan Roese * and in the same chance, block reassertions of reset [15:8] and
1285*ff9112dfSStefan Roese * force reserved bits[7:0].
1286*ff9112dfSStefan Roese */
1287*ff9112dfSStefan Roese reg = 0x0000FFFF;
1288*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 */
1289*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
1290*ff9112dfSStefan Roese
1291*ff9112dfSStefan Roese /*
1292*ff9112dfSStefan Roese * RelaX whenever reset is asserted to that channel (good for any case)
1293*ff9112dfSStefan Roese */
1294*ff9112dfSStefan Roese reg = 0x0000FF00;
1295*ff9112dfSStefan Roese /* 0x18704 - CPU Div CLK control 0 */
1296*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg);
1297*ff9112dfSStefan Roese
1298*ff9112dfSStefan Roese reg = reg_read(REG_CPU_DIV_CLK_CTRL_3_ADDR) &
1299*ff9112dfSStefan Roese REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK;
1300*ff9112dfSStefan Roese reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS);
1301*ff9112dfSStefan Roese /* Full Integer ratio from PLL-out to ddr-clk */
1302*ff9112dfSStefan Roese /* 0x1870C - CPU Div CLK control 3 register */
1303*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_3_ADDR, reg);
1304*ff9112dfSStefan Roese
1305*ff9112dfSStefan Roese /*
1306*ff9112dfSStefan Roese * Shut off clock enable to the DDRPHY clock channel (this is the "D").
1307*ff9112dfSStefan Roese * All the rest are kept as is (forced, but could be read-modify-write).
1308*ff9112dfSStefan Roese * This is done now by RMW above.
1309*ff9112dfSStefan Roese */
1310*ff9112dfSStefan Roese
1311*ff9112dfSStefan Roese reg = 0x000FFF02;
1312*ff9112dfSStefan Roese
1313*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg);
1314*ff9112dfSStefan Roese
1315*ff9112dfSStefan Roese /* Wait before replacing the clock on the DDR Phy Channel. */
1316*ff9112dfSStefan Roese udelay(1);
1317*ff9112dfSStefan Roese
1318*ff9112dfSStefan Roese reg = 0x0102FDFF;
1319*ff9112dfSStefan Roese /*
1320*ff9112dfSStefan Roese * This for triggering the frequency update. Bit[24] is the
1321*ff9112dfSStefan Roese * central control
1322*ff9112dfSStefan Roese * bits [23:16] == which channels to change ==2 ==> only DDR Phy
1323*ff9112dfSStefan Roese * (smooth transition)
1324*ff9112dfSStefan Roese * bits [15:8] == mask reset reassertion due to clock modification
1325*ff9112dfSStefan Roese * to these channels.
1326*ff9112dfSStefan Roese * bits [7:0] == not in use
1327*ff9112dfSStefan Roese */
1328*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
1329*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
1330*ff9112dfSStefan Roese
1331*ff9112dfSStefan Roese udelay(1);
1332*ff9112dfSStefan Roese
1333*ff9112dfSStefan Roese /*
1334*ff9112dfSStefan Roese * Poll Div CLK status 0 register - indication that the clocks are
1335*ff9112dfSStefan Roese * active - 0x18718 [8]
1336*ff9112dfSStefan Roese */
1337*ff9112dfSStefan Roese do {
1338*ff9112dfSStefan Roese reg = reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR) &
1339*ff9112dfSStefan Roese (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS);
1340*ff9112dfSStefan Roese } while (reg == 0);
1341*ff9112dfSStefan Roese
1342*ff9112dfSStefan Roese reg = 0x000000FF;
1343*ff9112dfSStefan Roese /*
1344*ff9112dfSStefan Roese * Clean the CTRL0, to be ready for next resets and next requests of
1345*ff9112dfSStefan Roese * ratio modifications.
1346*ff9112dfSStefan Roese */
1347*ff9112dfSStefan Roese /* 0x18700 - CPU Div CLK control 0 register */
1348*ff9112dfSStefan Roese dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg);
1349*ff9112dfSStefan Roese
1350*ff9112dfSStefan Roese udelay(5);
1351*ff9112dfSStefan Roese
1352*ff9112dfSStefan Roese if (ratio_2to1) {
1353*ff9112dfSStefan Roese /* Pup Reset Divider B - Set Reset */
1354*ff9112dfSStefan Roese /* [28] = 0 - Pup Reset Divider B */
1355*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) & ~(1 << 28);
1356*ff9112dfSStefan Roese /* [28] = 1 - Pup Reset Divider B */
1357*ff9112dfSStefan Roese tmp = reg_read(REG_SDRAM_CONFIG_ADDR) | (1 << 28);
1358*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1359*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
1360*ff9112dfSStefan Roese
1361*ff9112dfSStefan Roese /* Pup Reset Divider B - Release Reset */
1362*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1363*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, tmp);
1364*ff9112dfSStefan Roese }
1365*ff9112dfSStefan Roese
1366*ff9112dfSStefan Roese /* DRAM Data PHYs ADLL Reset - Set Reset */
1367*ff9112dfSStefan Roese reg = (reg_read(REG_DRAM_PHY_CONFIG_ADDR) & REG_DRAM_PHY_CONFIG_MASK);
1368*ff9112dfSStefan Roese /* [31:30]] - reset pup data ctrl ADLL */
1369*ff9112dfSStefan Roese /* 0x15EC - DRAM PHY Config Register */
1370*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
1371*ff9112dfSStefan Roese
1372*ff9112dfSStefan Roese udelay(25);
1373*ff9112dfSStefan Roese
1374*ff9112dfSStefan Roese /* APLL lock indication - Poll Phy lock status Register - 0x1674 [9] */
1375*ff9112dfSStefan Roese do {
1376*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_STATUS_ADDR) &
1377*ff9112dfSStefan Roese (1 << REG_PHY_LOCK_STATUS_LOCK_OFFS);
1378*ff9112dfSStefan Roese } while (reg == 0);
1379*ff9112dfSStefan Roese
1380*ff9112dfSStefan Roese /* DRAM Data PHYs ADLL Reset - Release Reset */
1381*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) | ~REG_DRAM_PHY_CONFIG_MASK;
1382*ff9112dfSStefan Roese /* [31:30] - normal pup data ctrl ADLL */
1383*ff9112dfSStefan Roese /* 0x15EC - DRAM PHY Config register */
1384*ff9112dfSStefan Roese dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
1385*ff9112dfSStefan Roese
1386*ff9112dfSStefan Roese udelay(10000); /* Wait 10msec */
1387*ff9112dfSStefan Roese
1388*ff9112dfSStefan Roese /*
1389*ff9112dfSStefan Roese * APLL lock indication - Poll Phy lock status Register - 0x1674 [11:0]
1390*ff9112dfSStefan Roese */
1391*ff9112dfSStefan Roese do {
1392*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_STATUS_ADDR) &
1393*ff9112dfSStefan Roese REG_PHY_LOCK_STATUS_LOCK_MASK;
1394*ff9112dfSStefan Roese } while (reg != REG_PHY_LOCK_STATUS_LOCK_MASK);
1395*ff9112dfSStefan Roese
1396*ff9112dfSStefan Roese /* DRAM Data PHY Read [30], Write [29] path reset - Set Reset */
1397*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK;
1398*ff9112dfSStefan Roese /* [30:29] = 0 - Data Pup R/W path reset */
1399*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1400*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
1401*ff9112dfSStefan Roese
1402*ff9112dfSStefan Roese /* DRAM Data PHY Read [30], Write [29] path reset - Release Reset */
1403*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK;
1404*ff9112dfSStefan Roese /* [30:29] = '11' - Data Pup R/W path reset */
1405*ff9112dfSStefan Roese /* 0x1400 - SDRAM Configuration register */
1406*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg);
1407*ff9112dfSStefan Roese
1408*ff9112dfSStefan Roese /* Disable DFS Reconfig */
1409*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & ~(1 << 4);
1410*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1411*ff9112dfSStefan Roese
1412*ff9112dfSStefan Roese /* [2] - DFS Self refresh disable */
1413*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS);
1414*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1415*ff9112dfSStefan Roese
1416*ff9112dfSStefan Roese /*
1417*ff9112dfSStefan Roese * Poll DFS Register - 0x1528 [3] - DfsAtSR - All DRAM devices on
1418*ff9112dfSStefan Roese * all ranks are NOT in self refresh mode
1419*ff9112dfSStefan Roese */
1420*ff9112dfSStefan Roese do {
1421*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS);
1422*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
1423*ff9112dfSStefan Roese
1424*ff9112dfSStefan Roese /* 0x1404 */
1425*ff9112dfSStefan Roese reg = (reg_read(REG_DUNIT_CTRL_LOW_ADDR) & 0xFFFFFFE7) | 0x2;
1426*ff9112dfSStefan Roese
1427*ff9112dfSStefan Roese /* Configure - 2T Mode - Restore original configuration */
1428*ff9112dfSStefan Roese /* [3:4] 2T - Restore value */
1429*ff9112dfSStefan Roese reg &= ~(REG_DUNIT_CTRL_LOW_2T_MASK << REG_DUNIT_CTRL_LOW_2T_OFFS);
1430*ff9112dfSStefan Roese reg |= ((dram_info->mode_2t & REG_DUNIT_CTRL_LOW_2T_MASK) <<
1431*ff9112dfSStefan Roese REG_DUNIT_CTRL_LOW_2T_OFFS);
1432*ff9112dfSStefan Roese dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg);
1433*ff9112dfSStefan Roese
1434*ff9112dfSStefan Roese udelay(1); /* Wait 1us */
1435*ff9112dfSStefan Roese
1436*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1437*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
1438*ff9112dfSStefan Roese reg = (reg_read(REG_DDR3_MR1_ADDR));
1439*ff9112dfSStefan Roese /* DLL Enable */
1440*ff9112dfSStefan Roese reg &= ~(1 << REG_DDR3_MR1_DLL_ENA_OFFS);
1441*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR1_ADDR, reg);
1442*ff9112dfSStefan Roese
1443*ff9112dfSStefan Roese /* Issue MRS Command to current cs */
1444*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_MR1 &
1445*ff9112dfSStefan Roese ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
1446*ff9112dfSStefan Roese /*
1447*ff9112dfSStefan Roese * [3-0] = 0x4 - MR1 Command, [11-8] -
1448*ff9112dfSStefan Roese * enable current cs
1449*ff9112dfSStefan Roese */
1450*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1451*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1452*ff9112dfSStefan Roese
1453*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
1454*ff9112dfSStefan Roese wait_refresh_op_complete();
1455*ff9112dfSStefan Roese
1456*ff9112dfSStefan Roese /* DLL Reset - MR0 */
1457*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR0_ADDR);
1458*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR0_ADDR, reg);
1459*ff9112dfSStefan Roese
1460*ff9112dfSStefan Roese /* Issue MRS Command to current cs */
1461*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_MR0 &
1462*ff9112dfSStefan Roese ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
1463*ff9112dfSStefan Roese /*
1464*ff9112dfSStefan Roese * [3-0] = 0x4 - MR1 Command, [11-8] -
1465*ff9112dfSStefan Roese * enable current cs
1466*ff9112dfSStefan Roese */
1467*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1468*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1469*ff9112dfSStefan Roese
1470*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
1471*ff9112dfSStefan Roese wait_refresh_op_complete();
1472*ff9112dfSStefan Roese
1473*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR0_ADDR);
1474*ff9112dfSStefan Roese reg &= ~0x74; /* CL [3:0]; [6:4],[2] */
1475*ff9112dfSStefan Roese
1476*ff9112dfSStefan Roese if (freq == DDR_400)
1477*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(6) & 0xF;
1478*ff9112dfSStefan Roese else
1479*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(dram_info->cl) & 0xF;
1480*ff9112dfSStefan Roese
1481*ff9112dfSStefan Roese reg |= ((tmp & 0x1) << 2);
1482*ff9112dfSStefan Roese reg |= ((tmp >> 1) << 4); /* to bit 4 */
1483*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR0_ADDR, reg);
1484*ff9112dfSStefan Roese
1485*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_MR0 &
1486*ff9112dfSStefan Roese ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
1487*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1488*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1489*ff9112dfSStefan Roese
1490*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
1491*ff9112dfSStefan Roese wait_refresh_op_complete();
1492*ff9112dfSStefan Roese
1493*ff9112dfSStefan Roese reg = reg_read(REG_DDR3_MR2_ADDR);
1494*ff9112dfSStefan Roese reg &= ~0x38; /* CWL [5:3] */
1495*ff9112dfSStefan Roese /* CWL = 0 ,for 400 MHg is 5 */
1496*ff9112dfSStefan Roese if (freq != DDR_400)
1497*ff9112dfSStefan Roese reg |= dram_info->cwl << REG_DDR3_MR2_CWL_OFFS;
1498*ff9112dfSStefan Roese dfs_reg_write(REG_DDR3_MR2_ADDR, reg);
1499*ff9112dfSStefan Roese reg = REG_SDRAM_OPERATION_CMD_MR2 &
1500*ff9112dfSStefan Roese ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs));
1501*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1502*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1503*ff9112dfSStefan Roese
1504*ff9112dfSStefan Roese /* Poll - Wait for Refresh operation completion */
1505*ff9112dfSStefan Roese wait_refresh_op_complete();
1506*ff9112dfSStefan Roese
1507*ff9112dfSStefan Roese /* Set current rd_sample_delay */
1508*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
1509*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK <<
1510*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
1511*ff9112dfSStefan Roese reg |= (dram_info->cl <<
1512*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
1513*ff9112dfSStefan Roese dfs_reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg);
1514*ff9112dfSStefan Roese
1515*ff9112dfSStefan Roese /* Set current rd_ready_delay */
1516*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
1517*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_READY_DELAYS_MASK <<
1518*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
1519*ff9112dfSStefan Roese reg |= ((dram_info->cl + 1) <<
1520*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
1521*ff9112dfSStefan Roese dfs_reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
1522*ff9112dfSStefan Roese }
1523*ff9112dfSStefan Roese }
1524*ff9112dfSStefan Roese
1525*ff9112dfSStefan Roese /* Enable ODT on DLL-on mode */
1526*ff9112dfSStefan Roese dfs_reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, 0);
1527*ff9112dfSStefan Roese
1528*ff9112dfSStefan Roese /* [1] - DFS Block disable */
1529*ff9112dfSStefan Roese reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_BLOCK_OFFS);
1530*ff9112dfSStefan Roese dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */
1531*ff9112dfSStefan Roese
1532*ff9112dfSStefan Roese /* Change DDR frequency to 100MHz procedure: */
1533*ff9112dfSStefan Roese /* 0x1600 - PHY lock mask register */
1534*ff9112dfSStefan Roese reg = reg_read(REG_ODPG_CNTRL_ADDR);
1535*ff9112dfSStefan Roese reg &= ~(1 << REG_ODPG_CNTRL_OFFS); /* [21] = 0 */
1536*ff9112dfSStefan Roese dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg);
1537*ff9112dfSStefan Roese
1538*ff9112dfSStefan Roese /* Change DDR frequency to 100MHz procedure: */
1539*ff9112dfSStefan Roese /* 0x1670 - PHY lock mask register */
1540*ff9112dfSStefan Roese reg = reg_read(REG_PHY_LOCK_MASK_ADDR);
1541*ff9112dfSStefan Roese reg |= ~REG_PHY_LOCK_MASK_MASK; /* [11:0] = FFF */
1542*ff9112dfSStefan Roese dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg);
1543*ff9112dfSStefan Roese
1544*ff9112dfSStefan Roese reg = reg_read(REG_METAL_MASK_ADDR) | (1 << 0); /* [0] - disable */
1545*ff9112dfSStefan Roese /* 0x14B0 - Dunit MMask Register */
1546*ff9112dfSStefan Roese dfs_reg_write(REG_METAL_MASK_ADDR, reg);
1547*ff9112dfSStefan Roese
1548*ff9112dfSStefan Roese DEBUG_DFS_C("DDR3 - DFS - Low To High - Ended successfuly - new Frequency - ",
1549*ff9112dfSStefan Roese freq, 1);
1550*ff9112dfSStefan Roese return MV_OK;
1551*ff9112dfSStefan Roese #endif
1552*ff9112dfSStefan Roese }
1553