1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2008-2014 Freescale Semiconductor, Inc.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #ifdef CONFIG_PPC
9*4882a593Smuzhiyun #include <asm/fsl_law.h>
10*4882a593Smuzhiyun #endif
11*4882a593Smuzhiyun #include <div64.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <fsl_ddr.h>
14*4882a593Smuzhiyun #include <fsl_immap.h>
15*4882a593Smuzhiyun #include <asm/io.h>
16*4882a593Smuzhiyun #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
17*4882a593Smuzhiyun defined(CONFIG_ARM)
18*4882a593Smuzhiyun #include <asm/arch/clock.h>
19*4882a593Smuzhiyun #endif
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /* To avoid 64-bit full-divides, we factor this here */
22*4882a593Smuzhiyun #define ULL_2E12 2000000000000ULL
23*4882a593Smuzhiyun #define UL_5POW12 244140625UL
24*4882a593Smuzhiyun #define UL_2POW13 (1UL << 13)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define ULL_8FS 0xFFFFFFFFULL
27*4882a593Smuzhiyun
fsl_ddr_get_version(unsigned int ctrl_num)28*4882a593Smuzhiyun u32 fsl_ddr_get_version(unsigned int ctrl_num)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun struct ccsr_ddr __iomem *ddr;
31*4882a593Smuzhiyun u32 ver_major_minor_errata;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun switch (ctrl_num) {
34*4882a593Smuzhiyun case 0:
35*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
36*4882a593Smuzhiyun break;
37*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
38*4882a593Smuzhiyun case 1:
39*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
40*4882a593Smuzhiyun break;
41*4882a593Smuzhiyun #endif
42*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
43*4882a593Smuzhiyun case 2:
44*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
45*4882a593Smuzhiyun break;
46*4882a593Smuzhiyun #endif
47*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
48*4882a593Smuzhiyun case 3:
49*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
50*4882a593Smuzhiyun break;
51*4882a593Smuzhiyun #endif
52*4882a593Smuzhiyun default:
53*4882a593Smuzhiyun printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
54*4882a593Smuzhiyun return 0;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
57*4882a593Smuzhiyun ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun return ver_major_minor_errata;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /*
63*4882a593Smuzhiyun * Round up mclk_ps to nearest 1 ps in memory controller code
64*4882a593Smuzhiyun * if the error is 0.5ps or more.
65*4882a593Smuzhiyun *
66*4882a593Smuzhiyun * If an imprecise data rate is too high due to rounding error
67*4882a593Smuzhiyun * propagation, compute a suitably rounded mclk_ps to compute
68*4882a593Smuzhiyun * a working memory controller configuration.
69*4882a593Smuzhiyun */
get_memory_clk_period_ps(const unsigned int ctrl_num)70*4882a593Smuzhiyun unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun unsigned int data_rate = get_ddr_freq(ctrl_num);
73*4882a593Smuzhiyun unsigned int result;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* Round to nearest 10ps, being careful about 64-bit multiply/divide */
76*4882a593Smuzhiyun unsigned long long rem, mclk_ps = ULL_2E12;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* Now perform the big divide, the result fits in 32-bits */
79*4882a593Smuzhiyun rem = do_div(mclk_ps, data_rate);
80*4882a593Smuzhiyun result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun return result;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
picos_to_mclk(const unsigned int ctrl_num,unsigned int picos)86*4882a593Smuzhiyun unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun unsigned long long clks, clks_rem;
89*4882a593Smuzhiyun unsigned long data_rate = get_ddr_freq(ctrl_num);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* Short circuit for zero picos */
92*4882a593Smuzhiyun if (!picos)
93*4882a593Smuzhiyun return 0;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* First multiply the time by the data rate (32x32 => 64) */
96*4882a593Smuzhiyun clks = picos * (unsigned long long)data_rate;
97*4882a593Smuzhiyun /*
98*4882a593Smuzhiyun * Now divide by 5^12 and track the 32-bit remainder, then divide
99*4882a593Smuzhiyun * by 2*(2^12) using shifts (and updating the remainder).
100*4882a593Smuzhiyun */
101*4882a593Smuzhiyun clks_rem = do_div(clks, UL_5POW12);
102*4882a593Smuzhiyun clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12;
103*4882a593Smuzhiyun clks >>= 13;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /* If we had a remainder greater than the 1ps error, then round up */
106*4882a593Smuzhiyun if (clks_rem > data_rate)
107*4882a593Smuzhiyun clks++;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /* Clamp to the maximum representable value */
110*4882a593Smuzhiyun if (clks > ULL_8FS)
111*4882a593Smuzhiyun clks = ULL_8FS;
112*4882a593Smuzhiyun return (unsigned int) clks;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
mclk_to_picos(const unsigned int ctrl_num,unsigned int mclk)115*4882a593Smuzhiyun unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun return get_memory_clk_period_ps(ctrl_num) * mclk;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun #ifdef CONFIG_PPC
121*4882a593Smuzhiyun void
__fsl_ddr_set_lawbar(const common_timing_params_t * memctl_common_params,unsigned int law_memctl,unsigned int ctrl_num)122*4882a593Smuzhiyun __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
123*4882a593Smuzhiyun unsigned int law_memctl,
124*4882a593Smuzhiyun unsigned int ctrl_num)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun unsigned long long base = memctl_common_params->base_address;
127*4882a593Smuzhiyun unsigned long long size = memctl_common_params->total_mem;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /*
130*4882a593Smuzhiyun * If no DIMMs on this controller, do not proceed any further.
131*4882a593Smuzhiyun */
132*4882a593Smuzhiyun if (!memctl_common_params->ndimms_present) {
133*4882a593Smuzhiyun return;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #if !defined(CONFIG_PHYS_64BIT)
137*4882a593Smuzhiyun if (base >= CONFIG_MAX_MEM_MAPPED)
138*4882a593Smuzhiyun return;
139*4882a593Smuzhiyun if ((base + size) >= CONFIG_MAX_MEM_MAPPED)
140*4882a593Smuzhiyun size = CONFIG_MAX_MEM_MAPPED - base;
141*4882a593Smuzhiyun #endif
142*4882a593Smuzhiyun if (set_ddr_laws(base, size, law_memctl) < 0) {
143*4882a593Smuzhiyun printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num,
144*4882a593Smuzhiyun law_memctl);
145*4882a593Smuzhiyun return ;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n",
148*4882a593Smuzhiyun base, size, law_memctl);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun __attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void
152*4882a593Smuzhiyun fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
153*4882a593Smuzhiyun unsigned int memctl_interleaved,
154*4882a593Smuzhiyun unsigned int ctrl_num);
155*4882a593Smuzhiyun #endif
156*4882a593Smuzhiyun
fsl_ddr_set_intl3r(const unsigned int granule_size)157*4882a593Smuzhiyun void fsl_ddr_set_intl3r(const unsigned int granule_size)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun #ifdef CONFIG_E6500
160*4882a593Smuzhiyun u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
161*4882a593Smuzhiyun *mcintl3r = 0x80000000 | (granule_size & 0x1f);
162*4882a593Smuzhiyun debug("Enable MCINTL3R with granule size 0x%x\n", granule_size);
163*4882a593Smuzhiyun #endif
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
fsl_ddr_get_intl3r(void)166*4882a593Smuzhiyun u32 fsl_ddr_get_intl3r(void)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun u32 val = 0;
169*4882a593Smuzhiyun #ifdef CONFIG_E6500
170*4882a593Smuzhiyun u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
171*4882a593Smuzhiyun val = *mcintl3r;
172*4882a593Smuzhiyun #endif
173*4882a593Smuzhiyun return val;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
print_ddr_info(unsigned int start_ctrl)176*4882a593Smuzhiyun void print_ddr_info(unsigned int start_ctrl)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun struct ccsr_ddr __iomem *ddr =
179*4882a593Smuzhiyun (struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR);
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun #if defined(CONFIG_E6500) && (CONFIG_SYS_NUM_DDR_CTLRS == 3)
182*4882a593Smuzhiyun u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
183*4882a593Smuzhiyun #endif
184*4882a593Smuzhiyun #if (CONFIG_SYS_NUM_DDR_CTLRS > 1)
185*4882a593Smuzhiyun uint32_t cs0_config = ddr_in32(&ddr->cs0_config);
186*4882a593Smuzhiyun #endif
187*4882a593Smuzhiyun uint32_t sdram_cfg = ddr_in32(&ddr->sdram_cfg);
188*4882a593Smuzhiyun int cas_lat;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun #if CONFIG_SYS_NUM_DDR_CTLRS >= 2
191*4882a593Smuzhiyun if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
192*4882a593Smuzhiyun (start_ctrl == 1)) {
193*4882a593Smuzhiyun ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR;
194*4882a593Smuzhiyun sdram_cfg = ddr_in32(&ddr->sdram_cfg);
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun #endif
197*4882a593Smuzhiyun #if CONFIG_SYS_NUM_DDR_CTLRS >= 3
198*4882a593Smuzhiyun if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
199*4882a593Smuzhiyun (start_ctrl == 2)) {
200*4882a593Smuzhiyun ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR;
201*4882a593Smuzhiyun sdram_cfg = ddr_in32(&ddr->sdram_cfg);
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun #endif
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
206*4882a593Smuzhiyun puts(" (DDR not enabled)\n");
207*4882a593Smuzhiyun return;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun puts(" (DDR");
211*4882a593Smuzhiyun switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >>
212*4882a593Smuzhiyun SDRAM_CFG_SDRAM_TYPE_SHIFT) {
213*4882a593Smuzhiyun case SDRAM_TYPE_DDR1:
214*4882a593Smuzhiyun puts("1");
215*4882a593Smuzhiyun break;
216*4882a593Smuzhiyun case SDRAM_TYPE_DDR2:
217*4882a593Smuzhiyun puts("2");
218*4882a593Smuzhiyun break;
219*4882a593Smuzhiyun case SDRAM_TYPE_DDR3:
220*4882a593Smuzhiyun puts("3");
221*4882a593Smuzhiyun break;
222*4882a593Smuzhiyun case SDRAM_TYPE_DDR4:
223*4882a593Smuzhiyun puts("4");
224*4882a593Smuzhiyun break;
225*4882a593Smuzhiyun default:
226*4882a593Smuzhiyun puts("?");
227*4882a593Smuzhiyun break;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (sdram_cfg & SDRAM_CFG_32_BE)
231*4882a593Smuzhiyun puts(", 32-bit");
232*4882a593Smuzhiyun else if (sdram_cfg & SDRAM_CFG_16_BE)
233*4882a593Smuzhiyun puts(", 16-bit");
234*4882a593Smuzhiyun else
235*4882a593Smuzhiyun puts(", 64-bit");
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* Calculate CAS latency based on timing cfg values */
238*4882a593Smuzhiyun cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
239*4882a593Smuzhiyun if (fsl_ddr_get_version(0) <= 0x40400)
240*4882a593Smuzhiyun cas_lat += 1;
241*4882a593Smuzhiyun else
242*4882a593Smuzhiyun cas_lat += 2;
243*4882a593Smuzhiyun cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4;
244*4882a593Smuzhiyun printf(", CL=%d", cas_lat >> 1);
245*4882a593Smuzhiyun if (cas_lat & 0x1)
246*4882a593Smuzhiyun puts(".5");
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun if (sdram_cfg & SDRAM_CFG_ECC_EN)
249*4882a593Smuzhiyun puts(", ECC on)");
250*4882a593Smuzhiyun else
251*4882a593Smuzhiyun puts(", ECC off)");
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun #if (CONFIG_SYS_NUM_DDR_CTLRS == 3)
254*4882a593Smuzhiyun #ifdef CONFIG_E6500
255*4882a593Smuzhiyun if (*mcintl3r & 0x80000000) {
256*4882a593Smuzhiyun puts("\n");
257*4882a593Smuzhiyun puts(" DDR Controller Interleaving Mode: ");
258*4882a593Smuzhiyun switch (*mcintl3r & 0x1f) {
259*4882a593Smuzhiyun case FSL_DDR_3WAY_1KB_INTERLEAVING:
260*4882a593Smuzhiyun puts("3-way 1KB");
261*4882a593Smuzhiyun break;
262*4882a593Smuzhiyun case FSL_DDR_3WAY_4KB_INTERLEAVING:
263*4882a593Smuzhiyun puts("3-way 4KB");
264*4882a593Smuzhiyun break;
265*4882a593Smuzhiyun case FSL_DDR_3WAY_8KB_INTERLEAVING:
266*4882a593Smuzhiyun puts("3-way 8KB");
267*4882a593Smuzhiyun break;
268*4882a593Smuzhiyun default:
269*4882a593Smuzhiyun puts("3-way UNKNOWN");
270*4882a593Smuzhiyun break;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun #endif
274*4882a593Smuzhiyun #endif
275*4882a593Smuzhiyun #if (CONFIG_SYS_NUM_DDR_CTLRS >= 2)
276*4882a593Smuzhiyun if ((cs0_config & 0x20000000) && (start_ctrl == 0)) {
277*4882a593Smuzhiyun puts("\n");
278*4882a593Smuzhiyun puts(" DDR Controller Interleaving Mode: ");
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun switch ((cs0_config >> 24) & 0xf) {
281*4882a593Smuzhiyun case FSL_DDR_256B_INTERLEAVING:
282*4882a593Smuzhiyun puts("256B");
283*4882a593Smuzhiyun break;
284*4882a593Smuzhiyun case FSL_DDR_CACHE_LINE_INTERLEAVING:
285*4882a593Smuzhiyun puts("cache line");
286*4882a593Smuzhiyun break;
287*4882a593Smuzhiyun case FSL_DDR_PAGE_INTERLEAVING:
288*4882a593Smuzhiyun puts("page");
289*4882a593Smuzhiyun break;
290*4882a593Smuzhiyun case FSL_DDR_BANK_INTERLEAVING:
291*4882a593Smuzhiyun puts("bank");
292*4882a593Smuzhiyun break;
293*4882a593Smuzhiyun case FSL_DDR_SUPERBANK_INTERLEAVING:
294*4882a593Smuzhiyun puts("super-bank");
295*4882a593Smuzhiyun break;
296*4882a593Smuzhiyun default:
297*4882a593Smuzhiyun puts("invalid");
298*4882a593Smuzhiyun break;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun #endif
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun if ((sdram_cfg >> 8) & 0x7f) {
304*4882a593Smuzhiyun puts("\n");
305*4882a593Smuzhiyun puts(" DDR Chip-Select Interleaving Mode: ");
306*4882a593Smuzhiyun switch(sdram_cfg >> 8 & 0x7f) {
307*4882a593Smuzhiyun case FSL_DDR_CS0_CS1_CS2_CS3:
308*4882a593Smuzhiyun puts("CS0+CS1+CS2+CS3");
309*4882a593Smuzhiyun break;
310*4882a593Smuzhiyun case FSL_DDR_CS0_CS1:
311*4882a593Smuzhiyun puts("CS0+CS1");
312*4882a593Smuzhiyun break;
313*4882a593Smuzhiyun case FSL_DDR_CS2_CS3:
314*4882a593Smuzhiyun puts("CS2+CS3");
315*4882a593Smuzhiyun break;
316*4882a593Smuzhiyun case FSL_DDR_CS0_CS1_AND_CS2_CS3:
317*4882a593Smuzhiyun puts("CS0+CS1 and CS2+CS3");
318*4882a593Smuzhiyun break;
319*4882a593Smuzhiyun default:
320*4882a593Smuzhiyun puts("invalid");
321*4882a593Smuzhiyun break;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
detail_board_ddr_info(void)326*4882a593Smuzhiyun void __weak detail_board_ddr_info(void)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun print_ddr_info(0);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
board_add_ram_info(int use_default)331*4882a593Smuzhiyun void board_add_ram_info(int use_default)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun detail_board_ddr_info();
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun #ifdef CONFIG_FSL_DDR_SYNC_REFRESH
337*4882a593Smuzhiyun #define DDRC_DEBUG20_INIT_DONE 0x80000000
338*4882a593Smuzhiyun #define DDRC_DEBUG2_RF 0x00000040
fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,unsigned int last_ctrl)339*4882a593Smuzhiyun void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
340*4882a593Smuzhiyun unsigned int last_ctrl)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun unsigned int i;
343*4882a593Smuzhiyun u32 ddrc_debug20;
344*4882a593Smuzhiyun u32 ddrc_debug2[CONFIG_SYS_NUM_DDR_CTLRS] = {};
345*4882a593Smuzhiyun u32 *ddrc_debug2_p[CONFIG_SYS_NUM_DDR_CTLRS] = {};
346*4882a593Smuzhiyun struct ccsr_ddr __iomem *ddr;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun for (i = first_ctrl; i <= last_ctrl; i++) {
349*4882a593Smuzhiyun switch (i) {
350*4882a593Smuzhiyun case 0:
351*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
352*4882a593Smuzhiyun break;
353*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
354*4882a593Smuzhiyun case 1:
355*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
356*4882a593Smuzhiyun break;
357*4882a593Smuzhiyun #endif
358*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
359*4882a593Smuzhiyun case 2:
360*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
361*4882a593Smuzhiyun break;
362*4882a593Smuzhiyun #endif
363*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
364*4882a593Smuzhiyun case 3:
365*4882a593Smuzhiyun ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
366*4882a593Smuzhiyun break;
367*4882a593Smuzhiyun #endif
368*4882a593Smuzhiyun default:
369*4882a593Smuzhiyun printf("%s unexpected ctrl = %u\n", __func__, i);
370*4882a593Smuzhiyun return;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun ddrc_debug20 = ddr_in32(&ddr->debug[19]);
373*4882a593Smuzhiyun ddrc_debug2_p[i] = &ddr->debug[1];
374*4882a593Smuzhiyun while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
375*4882a593Smuzhiyun /* keep polling until DDRC init is done */
376*4882a593Smuzhiyun udelay(100);
377*4882a593Smuzhiyun ddrc_debug20 = ddr_in32(&ddr->debug[19]);
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun /*
382*4882a593Smuzhiyun * Sync refresh
383*4882a593Smuzhiyun * This is put together to make sure the refresh reqeusts are sent
384*4882a593Smuzhiyun * closely to each other.
385*4882a593Smuzhiyun */
386*4882a593Smuzhiyun for (i = first_ctrl; i <= last_ctrl; i++)
387*4882a593Smuzhiyun ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun #endif /* CONFIG_FSL_DDR_SYNC_REFRESH */
390*4882a593Smuzhiyun
remove_unused_controllers(fsl_ddr_info_t * info)391*4882a593Smuzhiyun void remove_unused_controllers(fsl_ddr_info_t *info)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun #ifdef CONFIG_FSL_LSCH3
394*4882a593Smuzhiyun int i;
395*4882a593Smuzhiyun u64 nodeid;
396*4882a593Smuzhiyun void *hnf_sam_ctrl = (void *)(CCI_HN_F_0_BASE + CCN_HN_F_SAM_CTL);
397*4882a593Smuzhiyun bool ddr0_used = false;
398*4882a593Smuzhiyun bool ddr1_used = false;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun for (i = 0; i < 8; i++) {
401*4882a593Smuzhiyun nodeid = in_le64(hnf_sam_ctrl) & CCN_HN_F_SAM_NODEID_MASK;
402*4882a593Smuzhiyun if (nodeid == CCN_HN_F_SAM_NODEID_DDR0) {
403*4882a593Smuzhiyun ddr0_used = true;
404*4882a593Smuzhiyun } else if (nodeid == CCN_HN_F_SAM_NODEID_DDR1) {
405*4882a593Smuzhiyun ddr1_used = true;
406*4882a593Smuzhiyun } else {
407*4882a593Smuzhiyun printf("Unknown nodeid in HN-F SAM control: 0x%llx\n",
408*4882a593Smuzhiyun nodeid);
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun hnf_sam_ctrl += (CCI_HN_F_1_BASE - CCI_HN_F_0_BASE);
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun if (!ddr0_used && !ddr1_used) {
413*4882a593Smuzhiyun printf("Invalid configuration in HN-F SAM control\n");
414*4882a593Smuzhiyun return;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun if (!ddr0_used && info->first_ctrl == 0) {
418*4882a593Smuzhiyun info->first_ctrl = 1;
419*4882a593Smuzhiyun info->num_ctrls = 1;
420*4882a593Smuzhiyun debug("First DDR controller disabled\n");
421*4882a593Smuzhiyun return;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun if (!ddr1_used && info->first_ctrl + info->num_ctrls > 1) {
425*4882a593Smuzhiyun info->num_ctrls = 1;
426*4882a593Smuzhiyun debug("Second DDR controller disabled\n");
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun #endif
429*4882a593Smuzhiyun }
430