]>
Commit | Line | Data |
---|---|---|
42d1f039 | 1 | /* |
beba93ed | 2 | * Copyright 2004,2007-2011 Freescale Semiconductor, Inc. |
42d1f039 WD |
3 | * (C) Copyright 2002, 2003 Motorola Inc. |
4 | * Xianghua Xiao (X.Xiao@motorola.com) | |
5 | * | |
6 | * (C) Copyright 2000 | |
7 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
8 | * | |
1a459660 | 9 | * SPDX-License-Identifier: GPL-2.0+ |
42d1f039 WD |
10 | */ |
11 | ||
75b9d4ae | 12 | #include <config.h> |
42d1f039 WD |
13 | #include <common.h> |
14 | #include <watchdog.h> | |
15 | #include <command.h> | |
80522dc8 | 16 | #include <fsl_esdhc.h> |
42d1f039 | 17 | #include <asm/cache.h> |
740280e6 | 18 | #include <asm/io.h> |
199e262e | 19 | #include <asm/mmu.h> |
d789b5f5 | 20 | #include <asm/fsl_ifc.h> |
199e262e | 21 | #include <asm/fsl_law.h> |
38dba0c2 | 22 | #include <asm/fsl_lbc.h> |
ebbe11dd YS |
23 | #include <post.h> |
24 | #include <asm/processor.h> | |
25 | #include <asm/fsl_ddr_sdram.h> | |
42d1f039 | 26 | |
591933ca JY |
27 | DECLARE_GLOBAL_DATA_PTR; |
28 | ||
c18de0d7 IS |
29 | /* |
30 | * Default board reset function | |
31 | */ | |
32 | static void | |
33 | __board_reset(void) | |
34 | { | |
35 | /* Do nothing */ | |
36 | } | |
37 | void board_reset(void) __attribute__((weak, alias("__board_reset"))); | |
38 | ||
42d1f039 WD |
39 | int checkcpu (void) |
40 | { | |
97d80fc3 | 41 | sys_info_t sysinfo; |
97d80fc3 WD |
42 | uint pvr, svr; |
43 | uint ver; | |
44 | uint major, minor; | |
4dbdb768 | 45 | struct cpu_type *cpu; |
08ef89ec | 46 | char buf1[32], buf2[32]; |
98ffa190 YS |
47 | #if (defined(CONFIG_DDR_CLK_FREQ) || \ |
48 | defined(CONFIG_FSL_CORENET)) && !defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) | |
6d0f6bcf | 49 | volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
9ce3c228 | 50 | #endif /* CONFIG_FSL_CORENET */ |
98ffa190 YS |
51 | |
52 | /* | |
53 | * Cornet platforms use ddr sync bit in RCW to indicate sync vs async | |
54 | * mode. Previous platform use ddr ratio to do the same. This | |
55 | * information is only for display here. | |
56 | */ | |
39aaca1f | 57 | #ifdef CONFIG_FSL_CORENET |
379c5145 | 58 | #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 |
98ffa190 | 59 | u32 ddr_sync = 0; /* only async mode is supported */ |
379c5145 | 60 | #else |
98ffa190 | 61 | u32 ddr_sync = ((gur->rcwsr[5]) & FSL_CORENET_RCWSR5_DDR_SYNC) |
ab48ca1a | 62 | >> FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT; |
379c5145 | 63 | #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ |
98ffa190 YS |
64 | #else /* CONFIG_FSL_CORENET */ |
65 | #ifdef CONFIG_DDR_CLK_FREQ | |
66 | u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) | |
67 | >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; | |
ee1e35be KG |
68 | #else |
69 | u32 ddr_ratio = 0; | |
39aaca1f | 70 | #endif /* CONFIG_DDR_CLK_FREQ */ |
98ffa190 YS |
71 | #endif /* CONFIG_FSL_CORENET */ |
72 | ||
fbb9ecf7 TT |
73 | unsigned int i, core, nr_cores = cpu_numcores(); |
74 | u32 mask = cpu_mask(); | |
97d80fc3 | 75 | |
97d80fc3 | 76 | svr = get_svr(); |
97d80fc3 WD |
77 | major = SVR_MAJ(svr); |
78 | minor = SVR_MIN(svr); | |
42d1f039 | 79 | |
0e870980 | 80 | if (cpu_numcores() > 1) { |
21170c80 PA |
81 | #ifndef CONFIG_MP |
82 | puts("Unicore software on multiprocessor system!!\n" | |
83 | "To enable mutlticore build define CONFIG_MP\n"); | |
84 | #endif | |
680c613a | 85 | volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR); |
0e870980 PA |
86 | printf("CPU%d: ", pic->whoami); |
87 | } else { | |
88 | puts("CPU: "); | |
89 | } | |
1ced1216 | 90 | |
67ac13b1 | 91 | cpu = gd->arch.cpu; |
1ced1216 | 92 | |
58442dc0 PA |
93 | puts(cpu->name); |
94 | if (IS_E_PROCESSOR(svr)) | |
95 | puts("E"); | |
1ced1216 | 96 | |
97d80fc3 WD |
97 | printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr); |
98 | ||
6c9e789e WD |
99 | pvr = get_pvr(); |
100 | ver = PVR_VER(pvr); | |
101 | major = PVR_MAJ(pvr); | |
102 | minor = PVR_MIN(pvr); | |
103 | ||
104 | printf("Core: "); | |
8992738d KG |
105 | switch(ver) { |
106 | case PVR_VER_E500_V1: | |
107 | case PVR_VER_E500_V2: | |
6770c5e2 | 108 | puts("e500"); |
8992738d KG |
109 | break; |
110 | case PVR_VER_E500MC: | |
6770c5e2 | 111 | puts("e500mc"); |
8992738d KG |
112 | break; |
113 | case PVR_VER_E5500: | |
6770c5e2 | 114 | puts("e5500"); |
8992738d | 115 | break; |
5b6b85ae | 116 | case PVR_VER_E6500: |
6770c5e2 | 117 | puts("e6500"); |
5b6b85ae | 118 | break; |
8992738d | 119 | default: |
2a3a96ca | 120 | puts("Unknown"); |
8992738d | 121 | break; |
6c9e789e | 122 | } |
0f060c3b | 123 | |
6c9e789e WD |
124 | printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr); |
125 | ||
2f1712b2 YS |
126 | if (nr_cores > CONFIG_MAX_CPUS) { |
127 | panic("\nUnexpected number of cores: %d, max is %d\n", | |
128 | nr_cores, CONFIG_MAX_CPUS); | |
129 | } | |
130 | ||
97d80fc3 WD |
131 | get_sys_info(&sysinfo); |
132 | ||
b29dee3c | 133 | puts("Clock Configuration:"); |
fbb9ecf7 | 134 | for_each_cpu(i, core, nr_cores, mask) { |
1bba30ef WD |
135 | if (!(i & 3)) |
136 | printf ("\n "); | |
fbb9ecf7 TT |
137 | printf("CPU%d:%-4s MHz, ", core, |
138 | strmhz(buf1, sysinfo.freqProcessor[core])); | |
b29dee3c KG |
139 | } |
140 | printf("\n CCB:%-4s MHz,\n", strmhz(buf1, sysinfo.freqSystemBus)); | |
ee1e35be | 141 | |
39aaca1f KG |
142 | #ifdef CONFIG_FSL_CORENET |
143 | if (ddr_sync == 1) { | |
144 | printf(" DDR:%-4s MHz (%s MT/s data rate) " | |
145 | "(Synchronous), ", | |
146 | strmhz(buf1, sysinfo.freqDDRBus/2), | |
147 | strmhz(buf2, sysinfo.freqDDRBus)); | |
148 | } else { | |
149 | printf(" DDR:%-4s MHz (%s MT/s data rate) " | |
150 | "(Asynchronous), ", | |
151 | strmhz(buf1, sysinfo.freqDDRBus/2), | |
152 | strmhz(buf2, sysinfo.freqDDRBus)); | |
153 | } | |
154 | #else | |
d4357932 KG |
155 | switch (ddr_ratio) { |
156 | case 0x0: | |
08ef89ec WD |
157 | printf(" DDR:%-4s MHz (%s MT/s data rate), ", |
158 | strmhz(buf1, sysinfo.freqDDRBus/2), | |
159 | strmhz(buf2, sysinfo.freqDDRBus)); | |
d4357932 KG |
160 | break; |
161 | case 0x7: | |
39aaca1f KG |
162 | printf(" DDR:%-4s MHz (%s MT/s data rate) " |
163 | "(Synchronous), ", | |
08ef89ec WD |
164 | strmhz(buf1, sysinfo.freqDDRBus/2), |
165 | strmhz(buf2, sysinfo.freqDDRBus)); | |
d4357932 KG |
166 | break; |
167 | default: | |
39aaca1f KG |
168 | printf(" DDR:%-4s MHz (%s MT/s data rate) " |
169 | "(Asynchronous), ", | |
08ef89ec WD |
170 | strmhz(buf1, sysinfo.freqDDRBus/2), |
171 | strmhz(buf2, sysinfo.freqDDRBus)); | |
d4357932 KG |
172 | break; |
173 | } | |
39aaca1f | 174 | #endif |
97d80fc3 | 175 | |
beba93ed | 176 | #if defined(CONFIG_FSL_LBC) |
39aaca1f | 177 | if (sysinfo.freqLocalBus > LCRR_CLKDIV) { |
ada591d2 | 178 | printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus)); |
39aaca1f | 179 | } else { |
ada591d2 TP |
180 | printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n", |
181 | sysinfo.freqLocalBus); | |
39aaca1f | 182 | } |
beba93ed | 183 | #endif |
42d1f039 | 184 | |
800c73c4 KG |
185 | #if defined(CONFIG_FSL_IFC) |
186 | printf("IFC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus)); | |
187 | #endif | |
188 | ||
1ced1216 | 189 | #ifdef CONFIG_CPM2 |
08ef89ec | 190 | printf("CPM: %s MHz\n", strmhz(buf1, sysinfo.freqSystemBus)); |
1ced1216 | 191 | #endif |
97d80fc3 | 192 | |
b3d7f20f HW |
193 | #ifdef CONFIG_QE |
194 | printf(" QE:%-4s MHz\n", strmhz(buf1, sysinfo.freqQE)); | |
195 | #endif | |
196 | ||
39aaca1f KG |
197 | #ifdef CONFIG_SYS_DPAA_FMAN |
198 | for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) { | |
7eda1f8e | 199 | printf(" FMAN%d: %s MHz\n", i + 1, |
39aaca1f KG |
200 | strmhz(buf1, sysinfo.freqFMan[i])); |
201 | } | |
202 | #endif | |
203 | ||
990e1a8c HW |
204 | #ifdef CONFIG_SYS_DPAA_QBMAN |
205 | printf(" QMAN: %s MHz\n", strmhz(buf1, sysinfo.freqQMAN)); | |
206 | #endif | |
207 | ||
39aaca1f KG |
208 | #ifdef CONFIG_SYS_DPAA_PME |
209 | printf(" PME: %s MHz\n", strmhz(buf1, sysinfo.freqPME)); | |
210 | #endif | |
211 | ||
6c9e789e | 212 | puts("L1: D-cache 32 kB enabled\n I-cache 32 kB enabled\n"); |
42d1f039 WD |
213 | |
214 | return 0; | |
215 | } | |
216 | ||
217 | ||
218 | /* ------------------------------------------------------------------------- */ | |
219 | ||
882b7d72 | 220 | int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
42d1f039 | 221 | { |
c348322a KG |
222 | /* Everything after the first generation of PQ3 parts has RSTCR */ |
223 | #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ | |
224 | defined(CONFIG_MPC8555) || defined(CONFIG_MPC8560) | |
793670c3 SP |
225 | unsigned long val, msr; |
226 | ||
42d1f039 WD |
227 | /* |
228 | * Initiate hard reset in debug control register DBCR0 | |
c348322a | 229 | * Make sure MSR[DE] = 1. This only resets the core. |
42d1f039 | 230 | */ |
793670c3 SP |
231 | msr = mfmsr (); |
232 | msr |= MSR_DE; | |
233 | mtmsr (msr); | |
234 | ||
235 | val = mfspr(DBCR0); | |
236 | val |= 0x70000000; | |
237 | mtspr(DBCR0,val); | |
c348322a KG |
238 | #else |
239 | volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
c18de0d7 IS |
240 | |
241 | /* Attempt board-specific reset */ | |
242 | board_reset(); | |
243 | ||
244 | /* Next try asserting HRESET_REQ */ | |
245 | out_be32(&gur->rstcr, 0x2); | |
c348322a KG |
246 | udelay(100); |
247 | #endif | |
df90968b | 248 | |
42d1f039 WD |
249 | return 1; |
250 | } | |
251 | ||
252 | ||
253 | /* | |
254 | * Get timebase clock frequency | |
255 | */ | |
66412c63 KG |
256 | #ifndef CONFIG_SYS_FSL_TBCLK_DIV |
257 | #define CONFIG_SYS_FSL_TBCLK_DIV 8 | |
258 | #endif | |
42d1f039 WD |
259 | unsigned long get_tbclk (void) |
260 | { | |
66412c63 KG |
261 | unsigned long tbclk_div = CONFIG_SYS_FSL_TBCLK_DIV; |
262 | ||
263 | return (gd->bus_clk + (tbclk_div >> 1)) / tbclk_div; | |
42d1f039 WD |
264 | } |
265 | ||
266 | ||
267 | #if defined(CONFIG_WATCHDOG) | |
42d1f039 WD |
268 | void |
269 | reset_85xx_watchdog(void) | |
270 | { | |
271 | /* | |
272 | * Clear TSR(WIS) bit by writing 1 | |
273 | */ | |
320d53da | 274 | mtspr(SPRN_TSR, TSR_WIS); |
42d1f039 | 275 | } |
df616cae HK |
276 | |
277 | void | |
278 | watchdog_reset(void) | |
279 | { | |
280 | int re_enable = disable_interrupts(); | |
281 | ||
282 | reset_85xx_watchdog(); | |
283 | if (re_enable) | |
284 | enable_interrupts(); | |
285 | } | |
42d1f039 WD |
286 | #endif /* CONFIG_WATCHDOG */ |
287 | ||
80522dc8 AF |
288 | /* |
289 | * Initializes on-chip MMC controllers. | |
290 | * to override, implement board_mmc_init() | |
291 | */ | |
292 | int cpu_mmc_init(bd_t *bis) | |
293 | { | |
294 | #ifdef CONFIG_FSL_ESDHC | |
295 | return fsl_esdhc_mmc_init(bis); | |
296 | #else | |
297 | return 0; | |
298 | #endif | |
299 | } | |
199e262e BB |
300 | |
301 | /* | |
302 | * Print out the state of various machine registers. | |
d789b5f5 DD |
303 | * Currently prints out LAWs, BR0/OR0 for LBC, CSPR/CSOR/Timing |
304 | * parameters for IFC and TLBs | |
199e262e BB |
305 | */ |
306 | void mpc85xx_reginfo(void) | |
307 | { | |
308 | print_tlbcam(); | |
309 | print_laws(); | |
beba93ed | 310 | #if defined(CONFIG_FSL_LBC) |
199e262e | 311 | print_lbc_regs(); |
beba93ed | 312 | #endif |
d789b5f5 DD |
313 | #ifdef CONFIG_FSL_IFC |
314 | print_ifc_regs(); | |
315 | #endif | |
beba93ed | 316 | |
199e262e | 317 | } |
ebbe11dd | 318 | |
38dba0c2 BB |
319 | /* Common ddr init for non-corenet fsl 85xx platforms */ |
320 | #ifndef CONFIG_FSL_CORENET | |
c97cd1ba SW |
321 | #if (defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)) && \ |
322 | !defined(CONFIG_SYS_INIT_L2_ADDR) | |
c1fc2d4f ZC |
323 | phys_size_t initdram(int board_type) |
324 | { | |
325 | #if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD) | |
326 | return fsl_ddr_sdram_size(); | |
327 | #else | |
76d354f4 | 328 | return (phys_size_t)CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; |
c1fc2d4f ZC |
329 | #endif |
330 | } | |
331 | #else /* CONFIG_SYS_RAMBOOT */ | |
38dba0c2 BB |
332 | phys_size_t initdram(int board_type) |
333 | { | |
334 | phys_size_t dram_size = 0; | |
335 | ||
810c4427 | 336 | #if defined(CONFIG_SYS_FSL_ERRATUM_DDR_MSYNC_IN) |
38dba0c2 BB |
337 | { |
338 | ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
339 | unsigned int x = 10; | |
340 | unsigned int i; | |
341 | ||
342 | /* | |
343 | * Work around to stabilize DDR DLL | |
344 | */ | |
345 | out_be32(&gur->ddrdllcr, 0x81000000); | |
346 | asm("sync;isync;msync"); | |
347 | udelay(200); | |
348 | while (in_be32(&gur->ddrdllcr) != 0x81000100) { | |
349 | setbits_be32(&gur->devdisr, 0x00010000); | |
350 | for (i = 0; i < x; i++) | |
351 | ; | |
352 | clrbits_be32(&gur->devdisr, 0x00010000); | |
353 | x++; | |
354 | } | |
355 | } | |
356 | #endif | |
357 | ||
1b3e3c4f YS |
358 | #if defined(CONFIG_SPD_EEPROM) || \ |
359 | defined(CONFIG_DDR_SPD) || \ | |
360 | defined(CONFIG_SYS_DDR_RAW_TIMING) | |
38dba0c2 BB |
361 | dram_size = fsl_ddr_sdram(); |
362 | #else | |
363 | dram_size = fixed_sdram(); | |
364 | #endif | |
365 | dram_size = setup_ddr_tlbs(dram_size / 0x100000); | |
366 | dram_size *= 0x100000; | |
367 | ||
368 | #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) | |
369 | /* | |
370 | * Initialize and enable DDR ECC. | |
371 | */ | |
372 | ddr_enable_ecc(dram_size); | |
373 | #endif | |
374 | ||
beba93ed | 375 | #if defined(CONFIG_FSL_LBC) |
38dba0c2 | 376 | /* Some boards also have sdram on the lbc */ |
70961ba4 | 377 | lbc_sdram_init(); |
beba93ed | 378 | #endif |
38dba0c2 | 379 | |
21cd5815 | 380 | debug("DDR: "); |
38dba0c2 BB |
381 | return dram_size; |
382 | } | |
c1fc2d4f | 383 | #endif /* CONFIG_SYS_RAMBOOT */ |
38dba0c2 BB |
384 | #endif |
385 | ||
ebbe11dd YS |
386 | #if CONFIG_POST & CONFIG_SYS_POST_MEMORY |
387 | ||
388 | /* Board-specific functions defined in each board's ddr.c */ | |
389 | void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, | |
390 | unsigned int ctrl_num); | |
391 | void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn, | |
392 | phys_addr_t *rpn); | |
393 | unsigned int | |
394 | setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg); | |
395 | ||
9cdfe281 BB |
396 | void clear_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg); |
397 | ||
ebbe11dd YS |
398 | static void dump_spd_ddr_reg(void) |
399 | { | |
400 | int i, j, k, m; | |
401 | u8 *p_8; | |
402 | u32 *p_32; | |
403 | ccsr_ddr_t *ddr[CONFIG_NUM_DDR_CONTROLLERS]; | |
404 | generic_spd_eeprom_t | |
405 | spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR]; | |
406 | ||
407 | for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) | |
408 | fsl_ddr_get_spd(spd[i], i); | |
409 | ||
410 | puts("SPD data of all dimms (zero vaule is omitted)...\n"); | |
411 | puts("Byte (hex) "); | |
412 | k = 1; | |
413 | for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { | |
414 | for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) | |
415 | printf("Dimm%d ", k++); | |
416 | } | |
417 | puts("\n"); | |
418 | for (k = 0; k < sizeof(generic_spd_eeprom_t); k++) { | |
419 | m = 0; | |
420 | printf("%3d (0x%02x) ", k, k); | |
421 | for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { | |
422 | for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { | |
423 | p_8 = (u8 *) &spd[i][j]; | |
424 | if (p_8[k]) { | |
425 | printf("0x%02x ", p_8[k]); | |
426 | m++; | |
427 | } else | |
428 | puts(" "); | |
429 | } | |
430 | } | |
431 | if (m) | |
432 | puts("\n"); | |
433 | else | |
434 | puts("\r"); | |
435 | } | |
436 | ||
437 | for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { | |
438 | switch (i) { | |
439 | case 0: | |
e76cd5d4 | 440 | ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR; |
ebbe11dd | 441 | break; |
e76cd5d4 | 442 | #if defined(CONFIG_SYS_MPC8xxx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) |
ebbe11dd | 443 | case 1: |
e76cd5d4 | 444 | ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR; |
ebbe11dd | 445 | break; |
a4c66509 | 446 | #endif |
e76cd5d4 | 447 | #if defined(CONFIG_SYS_MPC8xxx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) |
a4c66509 | 448 | case 2: |
e76cd5d4 | 449 | ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR3_ADDR; |
a4c66509 YS |
450 | break; |
451 | #endif | |
e76cd5d4 | 452 | #if defined(CONFIG_SYS_MPC8xxx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) |
a4c66509 | 453 | case 3: |
e76cd5d4 | 454 | ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR4_ADDR; |
a4c66509 | 455 | break; |
ebbe11dd YS |
456 | #endif |
457 | default: | |
458 | printf("%s unexpected controller number = %u\n", | |
459 | __func__, i); | |
460 | return; | |
461 | } | |
462 | } | |
463 | printf("DDR registers dump for all controllers " | |
464 | "(zero vaule is omitted)...\n"); | |
465 | puts("Offset (hex) "); | |
466 | for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) | |
467 | printf(" Base + 0x%04x", (u32)ddr[i] & 0xFFFF); | |
468 | puts("\n"); | |
469 | for (k = 0; k < sizeof(ccsr_ddr_t)/4; k++) { | |
470 | m = 0; | |
471 | printf("%6d (0x%04x)", k * 4, k * 4); | |
472 | for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { | |
473 | p_32 = (u32 *) ddr[i]; | |
474 | if (p_32[k]) { | |
475 | printf(" 0x%08x", p_32[k]); | |
476 | m++; | |
477 | } else | |
478 | puts(" "); | |
479 | } | |
480 | if (m) | |
481 | puts("\n"); | |
482 | else | |
483 | puts("\r"); | |
484 | } | |
485 | puts("\n"); | |
486 | } | |
487 | ||
488 | /* invalid the TLBs for DDR and setup new ones to cover p_addr */ | |
489 | static int reset_tlb(phys_addr_t p_addr, u32 size, phys_addr_t *phys_offset) | |
490 | { | |
491 | u32 vstart = CONFIG_SYS_DDR_SDRAM_BASE; | |
492 | unsigned long epn; | |
493 | u32 tsize, valid, ptr; | |
ebbe11dd YS |
494 | int ddr_esel; |
495 | ||
9cdfe281 | 496 | clear_ddr_tlbs_phys(p_addr, size>>20); |
ebbe11dd YS |
497 | |
498 | /* Setup new tlb to cover the physical address */ | |
499 | setup_ddr_tlbs_phys(p_addr, size>>20); | |
500 | ||
501 | ptr = vstart; | |
502 | ddr_esel = find_tlb_idx((void *)ptr, 1); | |
503 | if (ddr_esel != -1) { | |
504 | read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, phys_offset); | |
505 | } else { | |
506 | printf("TLB error in function %s\n", __func__); | |
507 | return -1; | |
508 | } | |
509 | ||
510 | return 0; | |
511 | } | |
512 | ||
513 | /* | |
514 | * slide the testing window up to test another area | |
515 | * for 32_bit system, the maximum testable memory is limited to | |
516 | * CONFIG_MAX_MEM_MAPPED | |
517 | */ | |
518 | int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset) | |
519 | { | |
520 | phys_addr_t test_cap, p_addr; | |
521 | phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED); | |
522 | ||
523 | #if !defined(CONFIG_PHYS_64BIT) || \ | |
524 | !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \ | |
525 | (CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull) | |
526 | test_cap = p_size; | |
527 | #else | |
528 | test_cap = gd->ram_size; | |
529 | #endif | |
530 | p_addr = (*vstart) + (*size) + (*phys_offset); | |
531 | if (p_addr < test_cap - 1) { | |
532 | p_size = min(test_cap - p_addr, CONFIG_MAX_MEM_MAPPED); | |
533 | if (reset_tlb(p_addr, p_size, phys_offset) == -1) | |
534 | return -1; | |
535 | *vstart = CONFIG_SYS_DDR_SDRAM_BASE; | |
536 | *size = (u32) p_size; | |
537 | printf("Testing 0x%08llx - 0x%08llx\n", | |
538 | (u64)(*vstart) + (*phys_offset), | |
539 | (u64)(*vstart) + (*phys_offset) + (*size) - 1); | |
540 | } else | |
541 | return 1; | |
542 | ||
543 | return 0; | |
544 | } | |
545 | ||
546 | /* initialization for testing area */ | |
547 | int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset) | |
548 | { | |
549 | phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED); | |
550 | ||
551 | *vstart = CONFIG_SYS_DDR_SDRAM_BASE; | |
552 | *size = (u32) p_size; /* CONFIG_MAX_MEM_MAPPED < 4G */ | |
553 | *phys_offset = 0; | |
554 | ||
555 | #if !defined(CONFIG_PHYS_64BIT) || \ | |
556 | !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \ | |
557 | (CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull) | |
558 | if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) { | |
559 | puts("Cannot test more than "); | |
560 | print_size(CONFIG_MAX_MEM_MAPPED, | |
561 | " without proper 36BIT support.\n"); | |
562 | } | |
563 | #endif | |
564 | printf("Testing 0x%08llx - 0x%08llx\n", | |
565 | (u64)(*vstart) + (*phys_offset), | |
566 | (u64)(*vstart) + (*phys_offset) + (*size) - 1); | |
567 | ||
568 | return 0; | |
569 | } | |
570 | ||
571 | /* invalid TLBs for DDR and remap as normal after testing */ | |
572 | int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset) | |
573 | { | |
574 | unsigned long epn; | |
575 | u32 tsize, valid, ptr; | |
576 | phys_addr_t rpn = 0; | |
577 | int ddr_esel; | |
578 | ||
579 | /* disable the TLBs for this testing */ | |
580 | ptr = *vstart; | |
581 | ||
582 | while (ptr < (*vstart) + (*size)) { | |
583 | ddr_esel = find_tlb_idx((void *)ptr, 1); | |
584 | if (ddr_esel != -1) { | |
585 | read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn); | |
586 | disable_tlb(ddr_esel); | |
587 | } | |
588 | ptr += TSIZE_TO_BYTES(tsize); | |
589 | } | |
590 | ||
591 | puts("Remap DDR "); | |
592 | setup_ddr_tlbs(gd->ram_size>>20); | |
593 | puts("\n"); | |
594 | ||
595 | return 0; | |
596 | } | |
597 | ||
598 | void arch_memory_failure_handle(void) | |
599 | { | |
600 | dump_spd_ddr_reg(); | |
601 | } | |
602 | #endif |